Date:2010-08-22 22:03:06 (2 years 9 months ago)
Author:Bas Wijnen
Commit:04ed743042ce62ea481d13e54c68e24bdd8ba924
Message:booting from nand works

Files: init.config (1 diff)
invoke.ccp (1 diff)
iris.hhp (4 diffs)
kernel.hhp (1 diff)
mips/arch.hhp (1 diff)
mips/boot.S (3 diffs)
mips/nand.hhp (1 diff)
mips/nanonote/Makefile.arch (1 diff)
mips/nanonote/board.ccp (4 diffs)
mips/nanonote/nand-boot.ccp (4 diffs)
mips/start.S (1 diff)
panic.ccp (1 diff)
source/nand.ccp (3 diffs)

Change Details

init.config
11    # driver <name> = '<filename>' load a file into memory to be run priviledged.
22    # program <name> = '<filename>' load a file into memory to be run normally.
3    #driver driver_lcd = "lcd.elf"
4    #driver driver_buzzer = "buzzer.elf"
3    # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
4    # sysreq <cap> use a capability as the system request keyboard.
5    # give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
6    # include <file> include a file as another config file.
7    # at end of file, the initial threads are killed and the drivers and programs are run as soon as all their dependencies are provided.
8
59    driver driver_gpio = "gpio.elf"
6    #program alarm = "alarm.elf"
7    #program gui = "gui.elf"
10    receive driver_gpio / Keyboard , 0 = keyboard
11    receive driver_gpio / Keyboard , 1 = sysreq
12    receive driver_gpio / Event = sdmmc_gpio
13    sysreq sysreq
14
815    driver nand = "nand.elf"
9    #driver sdmmc = "sd+mmc.elf"
10    #program partition = "partition.elf"
11    #program fat = "fat.elf"
12    #program test = "test.elf"
13    #driver rtc = "rtc.elf"
1416
15    # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
17    #driver driver_lcd = "lcd.elf"
1618    #receive driver_lcd / Display = display
1719    #receive driver_lcd / Setting = display_bright
20
21    #driver driver_buzzer = "buzzer.elf"
1822    #receive driver_buzzer / Buzzer = buzzer
19    receive driver_gpio / Keyboard , 0 = keyboard
20    receive driver_gpio / Keyboard , 1 = sysreq
21    receive driver_gpio / Event = sdmmc_gpio
22    #receive alarm / UI = ui
23    #receive sdmmc / WString = sdmmc
24    #receive partition / WString, 0 = p0
25    #receive partition / WString, 1 = p1
26    #receive partition / WString, 2 = p2
27    #receive partition / WString, 3 = p3
28    #receive fat / Directory = root
2923
30    # sysreq <cap> use a capability as the system request keyboard.
31    sysreq sysreq
24    #program alarm = "alarm.elf"
25    #receive alarm / UI = ui
3226
33    # give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
27    #program gui = "gui.elf"
3428    #give gui / UI = ui
3529    #give gui / Display = display
3630    #give gui / Setting = display_bright
3731    #give gui / Buzzer = buzzer
3832    #give gui / Keyboard = keyboard
33
34    #driver sdmmc = "sd+mmc.elf"
35    #receive sdmmc / WString = sdmmc
3936    #give sdmmc / Event = sdmmc_gpio
37
38    #program partition = "partition.elf"
39    #receive partition / WString, 0 = p0
40    #receive partition / WString, 1 = p1
41    #receive partition / WString, 2 = p2
42    #receive partition / WString, 3 = p3
4043    #give partition / WString = sdmmc
44
45    #program fat = "fat.elf"
46    #receive fat / Directory = root
4147    #give fat / WString = p0
42    #give test / Directory = root
4348
44    # include <file> include a file as another config file.
49    #program test = "test.elf"
50    #give test / Directory = root
4551
46    # at end of file, the initial threads are killed and the drivers and programs are run as soon as all their dependencies are provided.
52    #driver rtc = "rtc.elf"
invoke.ccp
558558                    arch_reboot ()
559559                case Iris::Thread::PRIV_POWEROFF & REQUEST_MASK:
560560                    arch_poweroff ()
561                case Iris::Thread::PRIV_BOOT & REQUEST_MASK:
562                    arch_boot (c->data[1].l)
561563                case Iris::Thread::PRIV_PANIC & REQUEST_MASK:
562564                    if c->data[1].l == 0xdeaddead:
563565                        dbg_code.l = 1
iris.hhp
323323            DBG_SEND
324324            PRIV_REBOOT
325325            PRIV_POWEROFF
326            PRIV_BOOT
326327            PRIV_PANIC
327328        // These get/set_info are not arch-specific.
328329        enum info_type:
...... 
581582        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_REBOOT)
582583    inline void poweroff ():
583584        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_POWEROFF)
585    inline void boot (unsigned address):
586        my_thread.call (CAP_MASTER_DIRECT | Thread::PRIV_BOOT, address)
584587
585588    void Receiver::sleep (unsigned value):
586589        set_alarm (value)
...... 
612615namespace Iris:
613616    inline void panic (unsigned code, char const *message = NULL):
614617        if message:
615            kdebug ("**********************************************************************\n")
616618            kdebug_num (code)
617619            kdebug_char ('\n')
618620            kdebug (message)
...... 
626628    inline void debug_num (unsigned num, unsigned base):
627629        char const *encode = "0123456789abcdef"
628630        unsigned digits = 1
629        unsigned power = base
630        while power <= num:
631        unsigned power = 1
632        while power <= num / base:
631633            power *= base
632634            ++digits
633635        for unsigned i = 0; i < digits; ++i:
634            power /= base
635636            unsigned d = num / power
636637            kdebug_char (encode[d])
637638            num -= d * power
639            power /= base
638640
639641    inline void debug (const char *f, ...):
640642        unsigned *last = (unsigned *)&f
kernel.hhp
323323void arch_register_interrupt (unsigned num, kReceiverP r)
324324void arch_reboot ()
325325void arch_poweroff ()
326void arch_boot (unsigned address)
326327void arch_uncache_page (unsigned page)
327328
328329#define assert(x) do { if (!(x)) panic (__LINE__, "assertion failed"); } while (0)
mips/arch.hhp
8888#ifndef ASM
8989
9090void flush_tlb (unsigned asid)
91void arch_flush_cache ()
9192
9293struct kThread_arch:
9394    unsigned at, v[2], a[4], t[10], s[8], gp, fp, ra, hi, lo, k[2]
mips/boot.S
2525    .globl __start
2626    .set noreorder
2727
28// Note that this code starts at 0xa0000000, even though it is linked for
29// 0x80000000. This means that until the jump below, it must be PIC.
3028__start:
3129    bal 1f
3230// For some reason the disassembler considers everything
...... 
3634    .word _gp
37351: lw $gp, 0($ra)
3836
39    la $sp, kernel_stack + KERNEL_STACK_SIZE
40
4137    // Flush cache.
38    mtc0 $zero, $CP0_TAG_LO
4239    lui $v1, 0x8000
4340    ori $v0, $v1, 0x8000
44411:
42    // i-cache index invalidate.
4543    cache 0, 0($v1)
46    cache 1, 0($v1)
44    // d-cache store tag. TagLo has the valid bit cleared, so this clears the d-cache.
45    cache 9, 0($v1)
4746    bne $v1, $v0, 1b
4847    addiu $v1, $v1, 32
4948
...... 
5150    li $k0, 0x3
5251    mtc0 $k0, $CP0_CONFIG, 0
5352
54    // Jump into cached code.
55    la $t9, 1f
56    jr $t9
57    nop
581:
59    // From here, the code no longer needs to be PIC.
53    la $sp, kernel_stack + KERNEL_STACK_SIZE
6054
6155    // Clear .bss
6256    la $a0, _edata
6357    la $a1, _end
64581: sw $zero, 0($a0)
6559    bne $a1, $a0, 1b
66    addu $a0, 4
60    addiu $a0, 4
6761
6862    // First argument is the memory size.
6963    la $t9, init
mips/nand.hhp
1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// mips/nand.hhp: NAND driver functions, split off to be used in two places.
4// The functions are not inline, so this file must be included exactly once per executable that needs it.
5// Copyright 2009 Bas Wijnen <wijnen@debian.org>
6//
7// This program is free software: you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation, either version 3 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20// The following defines are taken from mtd/nand.h in the Linux source.
21// Everything not in the nand datasheet is thrown out.
22
23// Standard NAND flash commands
24#define CMD_READ0 0
25#define CMD_READSTART 0x30
26
27#define CMD_READID 0x90
28
29#define CMD_RESET 0xff
30
31#define CMD_SEQIN 0x80
32#define CMD_PAGEPROG 0x10
33
34#define CMD_ERASE1 0x60
35#define CMD_ERASE2 0xd0
36
37#define CMD_RNDIN 0x85
38
39#define CMD_RNDOUT 5
40#define CMD_RNDOUTSTART 0xe0
41
42#define CMD_STATUS 0x70
43
44// Status bits
45#define STATUS_FAIL 0x01
46#define STATUS_READY 0x40
47#define STATUS_WRITABLE 0x80
48
49static volatile char *command
50static volatile char *address
51static volatile char *data
52
53static unsigned page_bits
54static unsigned redundant_bits
55static unsigned block_bits
56static unsigned word_size
57
58static void unbusy ():
59    while !(gpio_get_port (2) & (1 << 30)):
60        DELAY ()
61
62static void addr (unsigned d):
63    unbusy ()
64    *address = d
65
66static void cmd (unsigned d):
67    unbusy ()
68    *command = d
69
70static void wdata (unsigned d):
71    unbusy ()
72    *data = d
73
74static unsigned rdata ():
75    unbusy ()
76    unsigned ret = *data
77    return ret
78
79static void reset ():
80    // Set up.
81    gpio_as_nand ()
82    EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1
83
84    // Reset nand.
85    cmd (CMD_RESET)
86
87    cmd (CMD_READID)
88    addr (0)
89    unsigned d = rdata ()
90    //unsigned maker = d
91    d = rdata ()
92    //unsigned device = d
93    d = rdata ()
94    //unsigned internal_chip_number = 1 << (d & 0x3)
95    //unsigned cell_type = 2 << ((d >> 2) & 0x3)
96    //unsigned simultaneously_programmed_pages = 1 << ((d >> 4) & 0x3)
97    //bool can_interleave_program_between_chips = d & 0x40
98    //bool can_cache_program = d & 0x80
99    d = rdata ()
100    page_bits = 10 + (d & 3)
101    debug ("page bits: %d\n", page_bits)
102    redundant_bits = (d & 4 ? 4 : 3)
103    debug ("redundant bits: %d\n", redundant_bits)
104    block_bits = 16 + ((d >> 4) & 3)
105    debug ("block bits: %d\n", block_bits)
106    word_size = (d & 0x40 ? 16 : 8)
107    debug ("word size: %d\n", word_size)
108    //unsigned serial_access_minimum = (d & 0x80 ? 25 : 50)
109    d = rdata ()
110    //unsigned num_planes = 1 << ((d >> 2) & 3)
111    //unsigned plane_bits = 26 + ((d >> 4) & 7)
112
113static bool read (unsigned a, char *buffer):
114    unsigned column = a & ((1 << page_bits) - 1)
115    unsigned row = a >> page_bits
116    debug ("reading %x:", a)
117    // Read oob information first.
118    char error[12]
119    // Spare space (starts at 1 << page_bits)
120    // 0: unused
121    // 2: detect valid data (at least 1 byte == 0 means valid)
122    // 5: unused
123    // 6: 9-byte ecc of 1st 512 bytes
124    // 15: 9-byte ecc of 2nd 512 bytes
125    // 24: 9-byte ecc of 3rd 512 bytes
126    // 33: 9-byte ecc of 4th 512 bytes
127    // 42: unused
128    // 64: end of space
129    unsigned col = (1 << page_bits) + 2
130    cmd (CMD_READ0)
131    addr (col)
132    addr (col >> 8)
133    addr (row)
134    addr (row >> 8)
135    addr (row >> 16)
136    cmd (CMD_READSTART)
137    bool valid = false
138    for unsigned t = 0; t < 3; ++t:
139        if rdata () == 0:
140            valid = true
141            break
142    if !valid:
143        debug ("invalid page for nand read: %x\n", a)
144        return false
145    col = (1 << page_bits) + 6 + 9 * (column >> 9)
146    cmd (CMD_RNDOUT)
147    addr (col)
148    addr (col >> 8)
149    cmd (CMD_RNDOUTSTART)
150    //debug ("parity data:")
151    for unsigned t = 0; t < 9; ++t:
152        error[t] = rdata ()
153        //debug (" %x", error[t] & 0xff)
154    //debug ("\n")
155    cmd (CMD_RNDOUT)
156    addr (column)
157    addr (column >> 8)
158    cmd (CMD_RNDOUTSTART)
159    EMC_NFINTS = 0
160    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST
161    for unsigned t = 0; t < 0x200; ++t:
162        buffer[t] = rdata ()
163    for unsigned t = 0; t < 9; ++t:
164        ((volatile char *)&EMC_NFPAR (0))[t] = error[t]
165    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
166    while !(EMC_NFINTS & EMC_NFINTS_DECF):
167        DELAY ()
168    unsigned ints = EMC_NFINTS
169    if ints & EMC_NFINTS_UNCOR:
170        debug ("uncorrectable error in nand at %x\n", a)
171        return false
172    unsigned errs = (ints & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
173    for unsigned i = 0; i < errs; ++i:
174        unsigned err = EMC_NFERR (i)
175        unsigned index = (err >> 16) - 1
176        unsigned mask = err & 0x1ff
177        unsigned bit = index * 9
178        unsigned offset= bit & 7
179        unsigned byte = bit / 8
180        debug ("correcting %x on %x+%d\n", mask, byte, offset)
181        unsigned data = buffer[byte] | buffer[byte + 1] << 8
182        data ^= mask << offset
183        buffer[byte] = data
184        buffer[byte + 1] = data >> 8
185    for unsigned i = 0; i < 0x10; ++i:
186        if (buffer[i] & 0xff) < 0x10:
187            debug (" 0")
188        else:
189            debug (" ")
190        debug ("%x", buffer[i] & 0xff)
191    debug ("\n")
192    return true
193
194static void write (unsigned a, char *buffer):
195    unsigned row = a >> page_bits
196    //debug ("writing: %x/%x: ", a, row)
197    cmd (CMD_SEQIN)
198    addr (0)
199    addr (0)
200    addr (row)
201    addr (row >> 8)
202    addr (row >> 16)
203    char ecc[4][12]
204    for unsigned i = 0; i < 0x4; ++i:
205        bool all_ff = true
206        EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING | EMC_NFECR_ERST
207        //debug ("writing data from %x\n", (unsigned)buffer + i * 0x200)
208        for unsigned j = 0; j < 0x200; ++j:
209            wdata (buffer[i * 0x200 + j])
210            if all_ff && (buffer[i * 0x200 + j] & 0xff) != 0xff:
211                all_ff = false
212        if !all_ff:
213            while !(EMC_NFINTS & EMC_NFINTS_ENCF):
214                DELAY ()
215            for unsigned t = 0; t < 9; ++t:
216                ecc[i][t] = ((volatile char *)&EMC_NFPAR (0))[t]
217            //debug ("parity for %x:", i * 0x200 + a)
218            //for unsigned t = 0; t < 9; ++t:
219                //debug (" %x", ecc[i][t] & 0xff)
220            //kdebug ("\n")
221        else:
222            for unsigned t = 0; t < 9; ++t:
223                ecc[i][t] = 0xff
224    // Spare space (starts at 1 << page_bits)
225    // 0: unused
226    // 2: detect valid data (at least 1 byte == 0 means valid)
227    // 5: unused
228    // 6: 9-byte ecc of 1st 512 bytes
229    // 15: 9-byte ecc of 2nd 512 bytes
230    // 24: 9-byte ecc of 3rd 512 bytes
231    // 33: 9-byte ecc of 4th 512 bytes
232    // 42: unused
233    // 64: end of space
234    for unsigned i = 0; i < 6; ++i:
235        wdata (0)
236    for unsigned i = 0; i < 4; ++i:
237        for unsigned j = 0; j < 9; ++j:
238            wdata (ecc[i][j])
239    cmd (CMD_PAGEPROG)
240    // Wait at least 100 ns.
241    DELAY ()
242    cmd (CMD_READ0)
243    addr (0)
244    addr (0)
245    addr (row)
246    addr (row >> 8)
247    addr (row >> 16)
248    cmd (CMD_READSTART)
249    for unsigned i = 0; i < 4; ++i:
250        EMC_NFINTS = 0
251        EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST
252        for unsigned t = 0; t < 0x200; ++t:
253            unsigned r = rdata () & 0xff
254            if r != (buffer[i * 0x200 + t] & 0xff):
255                debug ("program error at %x: %x != %x\n", i * 0x200 + t, buffer[i * 0x200 + t] & 0xff, r)
256        for unsigned t = 0; t < 9; ++t:
257            ((volatile char *)&EMC_NFPAR (0))[t] = ecc[i][t]
258        EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
259        while !(EMC_NFINTS & EMC_NFINTS_DECF):
260            DELAY ()
261        unsigned ints = EMC_NFINTS
262        if ints & EMC_NFINTS_UNCOR:
263            debug ("uncorrectable error during verify\n")
264            continue
265        unsigned errs = (ints & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
266        for unsigned i = 0; i < errs; ++i:
267            unsigned err = EMC_NFERR (i)
268            unsigned index = (err >> 16) - 1
269            unsigned mask = err & 0x1ff
270            unsigned bit = index * 9
271            unsigned offset= bit & 7
272            unsigned byte = bit / 8
273            debug ("error detected by parity: %x on %x+%d\n", mask, byte, offset)
274    for unsigned i = 0; i < 6; ++i:
275        if rdata () != 0:
276            debug ("extra data not 0 at byte %d\n", i)
277    for unsigned i = 0; i < 4; ++i:
278        for unsigned j = 0; j < 9; ++j:
279            unsigned r = rdata () & 0xff
280            if r != (ecc[i][j] & 0xff):
281                debug ("ecc doesn't match: %x != %x\n", r, ecc[i][j] & 0xff)
282    debug ("nand program %x:", a)
283    for unsigned i = 0; i < 0x10; ++i:
284        if (buffer[i] & 0xff) < 0x10:
285            debug (" 0")
286        else:
287            debug (" ")
288        debug ("%x", buffer[i] & 0xff)
289    debug ("\n")
290
291static void erase (unsigned a):
292    unsigned row = a >> page_bits
293    cmd (CMD_ERASE1)
294    addr (row)
295    addr (row >> 8)
296    addr (row >> 16)
297    cmd (CMD_ERASE2)
298    debug ("nand erase %d done\n", a)
mips/nanonote/Makefile.arch
1515# You should have received a copy of the GNU General Public License
1616# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
18start_load = 0xa0600000
18start_load = 0x80600000
1919load = 0x80000000
20UDC_BOOT = comment this out for nand boot
20UDC_BOOT = comment this out for sd boot
21
22arch_iris_sources = mips/interrupts.cc mips/arch.cc
23boot_sources = mips/init.cc mips/nanonote/board.cc
24arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh mips/nand.hh
25udc_boot_programs = udc
26sd_boot_programs = sd+mmc partition fat
27standard_boot_programs = bootinit
28
29programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs)
30
31ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
32CROSS = mipsel-linux-gnu-
33OBJDUMP = $(CROSS)objdump
34junk = mdebug.abi32 reginfo comment pdr
35OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
2136
2237ifdef UDC_BOOT
2338boot_threads = $(standard_boot_programs) $(udc_boot_programs)
2439threadlist = mips/nanonote/threadlist-udc
2540ARCH_CXXFLAGS = -DNUM_THREADS=2
2641all: mips/nanonote/nand-boot.raw test
42mips/start.o: TARGET =
2743else
2844boot_threads = $(standard_boot_programs) $(sd_boot_programs)
2945threadlist = mips/nanonote/threadlist-sd
3046ARCH_CXXFLAGS = -DNUM_THREADS=4
3147all: mips/nanonote/nand-boot.raw iris-sd.tar
48mips/start.o: TARGET = -DWRAPPED
3249iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs/init.config
33    mkimage -A mips -T kernel -a $(start_load) -e a$(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b2-8') -n Iris -d mips/start.raw.gz fs/uimage | sed -e 's/:/;/g'
50    mkimage -A mips -T kernel -a $(start_load) -e $(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b1-8') -n Iris -d mips/start.raw.gz fs/uimage | sed -e 's/:/;/g'
3451    cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference
3552endif
3653
37ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
38CROSS = mipsel-linux-gnu-
39OBJDUMP = $(CROSS)objdump
40junk = mdebug.abi32 reginfo comment pdr
41OBJCOPYFLAGS = $(addprefix --remove-section=.,$(junk))
4254iris.elf: LDFLAGS = --omagic -Ttext $(load)
4355mips/start.elf: LDFLAGS = --omagic -Ttext $(start_load)
4456mips/nanonote/nand-boot.elf: LDFLAGS = --omagic -Ttext 0x80000000
57mips/nanonote/nand-boot.o: mips/nand.hh
4558
46source/nand.o: mips/nanonote/nand-boot.raw
47
48arch_iris_sources = mips/interrupts.cc mips/arch.cc
49boot_sources = mips/init.cc mips/nanonote/board.cc
50arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
51udc_boot_programs = udc
52sd_boot_programs = sd+mmc partition fat
53standard_boot_programs = bootinit
54
55programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs)
59source/nand.o: mips/nand.hh mips/nanonote/nand-boot.raw iris-sd.raw
5660
5761mips/start.o:mips/start.S Makefile Makefile.arch iris.raw
58    $(CC) $(CPPFLAGS) -DSTART=0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8') -c $< -o $@
62    $(CC) $(CPPFLAGS) $(TARGET) -DSTART=0x$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b1-8') -c $< -o $@
5963
6064test: mips/start.raw mips/start.elf mips/nanonote/server/usb-server mips/nanonote/sdram-setup.raw $(addsuffix .elf,$(addprefix fs/,$(programs))) fs/init.config
61    echo "reboot $(start_load) 0xa$(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b2-8') $<" | nc localhost 5050
65    echo "reboot $(start_load) 0x$(shell /bin/sh -c '$(OBJDUMP) -t mips/start.elf | grep __start$$ | cut -b1-8') $<" | nc localhost 5050
6266
6367mips/nanonote/server/usb-server: mips/nanonote/server/usb-server.ccp mips/nanonote/server/Makefile.am mips/nanonote/server/configure.ac devices.hh
6468    $(MAKE) -C mips/nanonote/server
mips/nanonote/board.ccp
7272    UART0_MCR = 0
7373    UART0_SIRCR = 0
7474    UART0_UACR = 0
75    UART0_UMR = 1
75    UART0_UMR = 16
7676    UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1 | UARTLCR_DLAB
7777    unsigned const baud = 57600
78    unsigned uart_div = 12000000 / baud
78    unsigned uart_div = 12000000 / 16 / baud
7979    UART0_DLHR = (uart_div >> 8) & 0xff
8080    UART0_DLLR = uart_div & 0xff
8181    UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1
...... 
8383    kdebug ("\n\nSerial port initialized\n")
8484    #endif
8585
86void arch_reboot ():
86static void sync_serial ():
87    #ifndef NDEBUG
8788    // Wait for serial port to be done.
8889    while !(UART0_LSR & UARTLSR_TEMT):
90    #endif
91
92void arch_reboot ():
93    sync_serial ()
8994    // Reboot.
9095    wdt_select_extalclk ()
9196    wdt_select_clk_div1 ()
...... 
96101    while true:
97102
98103void arch_poweroff ():
99    // Wait for serial port to be done.
100    while !(UART0_LSR & UARTLSR_TEMT):
104    sync_serial ()
101105    // Power off.
102106    // Make sure the rtc is running.
103107    cpm_start_rtc ()
...... 
113117    // Fall back to reboot.
114118    kdebug ("Power down failed! Rebooting instead.\n")
115119    arch_reboot ()
120
121void arch_boot (unsigned address):
122    sync_serial ()
123    // Boot into another kernel.
124    arch_flush_cache ()
125    return ((void (*)())address) ()
mips/nanonote/nand-boot.ccp
1616// You should have received a copy of the GNU General Public License
1717// along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
19// The following defines are taken from mtd/nand.h in the Linux source.
20
2119asm volatile ("\t.set noreorder\n"
2220    "\t.text\n"
2321    "\t.globl __start\n"
...... 
2826    "\tnop\n"
2927    "\t.word _gp\n"
3028    "1:\n"
29    "\tori $t0, $zero, 0x0006\n"
30    "\tmtc0 $t0, $12\n"
3131    "\tlw $gp, 0($ra)\n"
3232    "\tla $sp, stack + 0x1000\n"
3333    "\tla $t9, nandboot_start\n"
...... 
3838#define __KERNEL__
3939#include <jz4740.hh>
4040
41// Standard NAND flash commands
42#define CMD_READ0 0
43#define CMD_READ1 1
44#define CMD_RNDOUT 5
45#define CMD_PAGEPROG 0x10
46#define CMD_READOOB 0x50
47#define CMD_ERASE1 0x60
48#define CMD_STATUS 0x70
49#define CMD_STATUS_MULTI 0x71
50#define CMD_SEQIN 0x80
51#define CMD_RNDIN 0x85
52#define CMD_READID 0x90
53#define CMD_ERASE2 0xd0
54#define CMD_RESET 0xff
55
56// Extended commands for large page devices
57#define CMD_READSTART 0x30
58#define CMD_RNDOUTSTART 0xE0
59#define CMD_CACHEDPROG 0x15
60
61// Status bits
62#define STATUS_FAIL 0x01
63#define STATUS_FAIL_N1 0x02
64#define STATUS_TRUE_READY 0x20
65#define STATUS_READY 0x40
66#define STATUS_WP 0x80
67
68static volatile char *command
69static volatile char *address
70static volatile char *data
71
72static unsigned page_bits
73static unsigned redundant_bits
74static unsigned block_bits
75static unsigned word_size
76
77static void unbusy ():
78    while !(gpio_get_port (2) & (1 << 30)):
79        // Do nothing.
80    // Delay.
81    for unsigned i = 0; i < 1000; ++i:
82        gpio_set (0, 0)
83
84static void addr (unsigned d):
85    unbusy ()
86    *address = d
87    unbusy ()
88
89static void cmd (unsigned d):
90    unbusy ()
91    *command = d
92    unbusy ()
93
94static void wdata (unsigned d):
95    unbusy ()
96    *data = d
97    unbusy ()
98
99static unsigned rdata ():
100    unbusy ()
101    unsigned ret = *data
102    unbusy ()
103    return ret
104
105// Reset nand controller.
106static void reset ():
107    unsigned base = 0xa0000000 + 0x18000000
108    data = (volatile char *)base
109    command = (volatile char *)(base + 0x8000)
110    address = (volatile char *)(base + 0x10000)
111
112    // Set up.
113    gpio_as_nand ()
114    EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1
115
116    // Reset nand.
117    cmd (CMD_RESET)
118
119    cmd (CMD_READID)
120    addr (0)
121    unsigned d = rdata ()
122    //unsigned maker = d
123    d = rdata ()
124    //unsigned device = d
125    d = rdata ()
126    //unsigned internal_chip_number = 1 << (d & 0x3)
127    //unsigned cell_type = 2 << ((d >> 2) & 0x3)
128    //unsigned simultaneously_programmed_pages = 1 << ((d >> 4) & 0x3)
129    //bool can_interleave_program_between_chips = d & 0x40
130    //bool can_cache_program = d & 0x80
131    d = rdata ()
132    page_bits = 10 + (d & 3)
133    redundant_bits = (d & 4 ? 4 : 3)
134    block_bits = 16 + ((d >> 4) & 3)
135    word_size = (d & 0x40 ? 16 : 8)
136    //unsigned serial_access_minimum = (d & 0x80 ? 25 : 50)
137    d = rdata ()
138    //unsigned num_planes = 1 << ((d >> 2) & 3)
139    //unsigned plane_bits = 26 + ((d >> 4) & 7)
140
141// Read 512 bytes from nand and store them into buffer. a must be aligned.
142// Return value is true if the oob claims there is valid data.
143static bool read (unsigned a, char *buffer):
144    unsigned column = a & ((1 << page_bits) - 1)
145    unsigned row = a >> page_bits
146    cmd (CMD_READ0)
147    addr (column)
148    addr (column >> 8)
149    addr (row)
150    addr (row >> 8)
151    addr (row >> 16)
152    cmd (CMD_READSTART)
153    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST
154    for unsigned t = 0; t < 0x200; ++t:
155        buffer[t] = rdata ()
156    EMC_NFECR = EMC_NFECR_RS | EMC_NFECR_RS_DECODING
157    char error[9]
158    // Spare space (starts at 1 << page_bits)
159    // 0: unused
160    // 2: detect valid data (at least 1 byte == 0 means valid)
161    // 5: unused
162    // 6: 9-byte ecc of 1st 512 bytes
163    // 15: 9-byte ecc of 2nd 512 bytes
164    // 24: 9-byte ecc of 3rd 512 bytes
165    // 33: 9-byte ecc of 4th 512 bytes
166    // 42: unused
167    // 64: end of space
168    unsigned validcol = (1 << page_bits) + 2
169    bool valid = false
170    cmd (CMD_RNDOUT)
171    addr (validcol)
172    addr (validcol >> 8)
173    cmd (CMD_RNDOUTSTART)
174    for unsigned t = 0; t < 3; ++t:
175        valid = rdata () == 0 || valid
176    unsigned errcol = (1 << page_bits) + (column >> 9) * 9 + 6
177    cmd (CMD_RNDOUT)
178    addr (errcol)
179    addr (errcol >> 8)
180    cmd (CMD_RNDOUTSTART)
181    for unsigned t = 0; t < 9; ++t:
182        error[t] = rdata ()
183    EMC_NFPAR (0) = ((unsigned *)error)[0]
184    EMC_NFPAR (1) = ((unsigned *)error)[1]
185    EMC_NFPAR (2) = error[9]
186    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
187    while !(EMC_NFINTS & EMC_NFINTS_DECF):
188        // Do nothing.
189    unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
190    for unsigned i = 0; i < errs; ++i:
191        buffer[EMC_NFERR (i) >> 16] ^= EMC_NFERR (i) & 0xff
41#define DELAY()
42
43static void debug (unsigned ch):
44    while !(UART0_LSR & UARTLSR_TDRQ):
45    UART0_TDR = ch
46
47static void debug_num (unsigned num, unsigned base, unsigned min_digits = 1):
48    char const *encode = "0123456789abcdef"
49    unsigned digits = 1
50    unsigned power = 1
51    while power <= num / base || min_digits > digits:
52        power *= base
53        ++digits
54    for unsigned i = 0; i < digits; ++i:
55        unsigned d = num / power
56        debug (encode[d])
57        num -= d * power
58        power /= base
59
60static void debug (char const *f, ...):
61    unsigned *last = (unsigned *)&f
62    while *f:
63        if *f == '%':
64            ++f
65            switch *f:
66                case '%':
67                    debug ('%')
68                    break
69                case 'd':
70                    ++last
71                    debug_num (*last, 10)
72                    break
73                case 'x':
74                    ++last
75                    debug_num (*last, 0x10)
76                    break
77                case 's':
78                    ++last
79                    char *str = (char*)*last
80                    while *str:
81                        debug (*str++)
82                    break
83                default:
84                    debug ("warning: invalid character in dbg format string\n")
85                    break
86        else:
87            debug (*f)
88        ++f
89
90#define debug_line() debug ("nand-boot line %d\n", __LINE__)
91
92#include "nand.hh"
93
94static void setup_uart ():
95    cpm_start_uart0 ()
96    gpio_as_uart0 ()
97    UART0_IER = 0
98    UART0_FCR = 0
99    UART0_MCR = 0
100    UART0_SIRCR = 0
101    UART0_UACR = 0
102    UART0_UMR = 16
103    UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1 | UARTLCR_DLAB
104    unsigned const baud = 57600
105    unsigned uart_div = 12000000 / 16 / baud
106    UART0_DLHR = (uart_div >> 8) & 0xff
107    UART0_DLLR = uart_div & 0xff
108    UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1
109    UART0_FCR = UARTFCR_UUE | UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS
110    debug ("\n\nNand-boot: serial port initialized\n")
192111
193112extern "C":
194113    void nandboot_start ():
114        unsigned base = 0x18000000 + 0xa0000000
115        data = (volatile char *)base
116        command = (volatile char *)(base + 0x8000)
117        address = (volatile char *)(base + 0x10000)
118        pll_init ()
119        cpm_start_all ()
120        gpio_as_sdram_16bit ()
121        gpio_as_nand ()
122        setup_sdram ()
123        setup_uart ()
195124        reset ()
196125        // Load contents of nand flash (from 0x4000) into 0xa0600000;
197126        unsigned a = 0x4000
...... 
199128        while read (a, (char *)target):
200129            a += 0x200
201130            target += 0x200
131        // Tell about what'll happen.
132        debug ("Jumping to a0600000:\n")
133        for unsigned d = 0; d < 0x40; ++d:
134            debug (" ")
135            debug_num (((char *)0xa0600000)[d] & 0xff, 16, 2)
136        debug ('\n')
137        // Wait for the serial port to finish.
138        while !(UART0_LSR & UARTLSR_TEMT):
202139        // Then jump to 0xa0600000.
203        return ((void (*)())0xa0600000) ()
140        ((void (*)())0xa0600000) ()
204141
205142unsigned char stack[0x1000]
206143
mips/start.S
1515// You should have received a copy of the GNU General Public License
1616// along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
18// This program is a wrapper around the kernel.
19// It is linked for loading at 0x80600000; however, it it position-independant and may be loaded anywhere.
20// It does not use gp. This means that li and la must not be used.
1821    .globl __start
1922    .set noreorder
2023
2124__start:
25    // Set t0 to uart0 txd
26    lui $t0, 0xb003
27
2228    bal 1f
2329// For some reason the disassembler considers everything
2430// after __start non-code until the next label. So I add a label.
2531start_hack_for_disassembler:
26    nop
27    .word _gp
281: lw $gp, 0($ra)
32    lui $a0, 0x8000
33base:
34    .word image_end - image
351:
36    // Set kseg0 to uncachable.
37    ori $t0, $zero, 2
38    mtc0 $t0, $16, 0
2939
30    li $a0, 0xa0000000
31    la $a1, image
32    la $a2, image_end
40    // Flush cache.
41    lui $v1, 0x8000
42    ori $v0, $v1, 0x8000
431:
44    // i-cache index invalidate.
45    cache 0, 0($v1)
46    // d-cache index write-back invalidate.
47    cache 1, 0($v1)
48    bne $v1, $v0, 1b
49    addiu $v1, $v1, 32
3350
341: lw $a3, 0($a1)
35    sw $a3, 0($a0)
36    addiu $a1, 4
37    bne $a1, $a2, 1b
38    addiu $a0, 4
51    // Set a1 to start address of image.
52    addiu $a1, $ra, image - base
3953
40    li $t9, START
41    jr $t9
54    // Set a2 to end address of image.
55    lw $a2, 0($ra)
56    add $a2, $a2, $a1
57
58    // Set t9 to the entry point.
59    lui $t9, START >> 16
60    ori $t9, $t9, START & 0xffff
61
62    // Put the copying code at the end, to prevent overwriting itself.
63    // The copy goes to the start of RAM, so the target is never larger than the source.
64    jr $a2
4265    nop
4366
4467image:
4568    .incbin "iris.raw"
4669image_end:
70    // Copy the image to the start of RAM.
71    // a0 is the destination: 0x80000000, counting up.
72    // a1 is the start of the image, counting up.
73    // a2 is the end of the image, not changing.
74    // a3 is the working register to do the move.
751: lw $a3, 0($a1)
76    addiu $a1, $a1, 4
77    sw $a3, 0($a0)
78    bne $a1, $a2, 1b
79    addiu $a0, $a0, 4
80    // Done copying.
81
82    // Make the jump to the new code.
83    jr $t9
84    nop
panic.ccp
8787    #endif
8888
8989static void panic_message (unsigned n, const char *line, char const *name, char const *message):
90    kdebug ("**********************************************************************\n")
9091    unsigned vaddr, epc
9192    cp0_get (CP0_BAD_V_ADDR, vaddr)
9293    cp0_get (CP0_EPC, epc)
source/nand.ccp
1616// You should have received a copy of the GNU General Public License
1717// along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
19#define DELAY Iris::schedule
20
1921#include "devices.hh"
2022#define ARCH
2123#include "arch.hh"
24#define debug Iris::debug
25#include "nand.hh"
2226
23// The following defines are taken from mtd/nand.h in the Linux source.
24
25// Standard NAND flash commands
26#define CMD_READ0 0
27#define CMD_READSTART 0x30
28
29#define CMD_READID 0x90
30
31#define CMD_RESET 0xff
32
33#define CMD_SEQIN 0x80
34#define CMD_PAGEPROG 0x10
35
36#define CMD_ERASE1 0x60
37#define CMD_ERASE2 0xd0
38
39#define CMD_RNDIN 0x85
40
41#define CMD_RNDOUT 5
42#define CMD_RNDOUTSTART 0xE0
43
44#define CMD_STATUS 0x70
45
46// Status bits
47#define STATUS_FAIL 0x01
48#define STATUS_READY 0x40
49#define STATUS_WRITABLE 0x80
50
51static volatile char *command
52static volatile char *address
53static volatile char *data
54
55static unsigned page_bits
56static unsigned redundant_bits
57static unsigned block_bits
58static unsigned word_size
59
60static void unbusy ():
61    while !(gpio_get_port (2) & (1 << 30)):
62        Iris::schedule ()
63    Iris::schedule ()
64
65static void addr (unsigned d):
66    unbusy ()
67    *address = d
68    unbusy ()
27extern "C":
28    extern char file_start, file_mid, file_end
6929
70static void cmd (unsigned d):
71    unbusy ()
72    *command = d
73    unbusy ()
30Iris::Num start ():
31    //kdebug ("starting nand operation in 10 seconds\n")
32    //Iris::sleep (10 * HZ)
7433
75static void wdata (unsigned d):
76    unbusy ()
77    *data = d
78    unbusy ()
34    map_emc ()
35    map_gpio ()
7936
80static unsigned rdata ():
81    unbusy ()
82    unsigned ret = *data
83    unbusy ()
84    return ret
37    // Arbitrary addresses where the pages are mapped.
38    command = (volatile char *)0x15000
39    address = (volatile char *)0x16000
40    data = (volatile char *)0x17000
8541
86static void reset ():
8742    Iris::Page data_page = Iris::my_memory.create_page ()
8843    Iris::Page command_page = Iris::my_memory.create_page ()
8944    Iris::Page address_page = Iris::my_memory.create_page ()
...... 
10156    Iris::free_cap (command_page)
10257    Iris::free_cap (address_page)
10358
104    // Set up.
105    gpio_as_nand ()
106    EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1
107
108    // Reset nand.
109    cmd (CMD_RESET)
110
111    cmd (CMD_READID)
112    addr (0)
113    unsigned d = rdata ()
114    //unsigned maker = d
115    d = rdata ()
116    //unsigned device = d
117    d = rdata ()
118    //unsigned internal_chip_number = 1 << (d & 0x3)
119    //unsigned cell_type = 2 << ((d >> 2) & 0x3)
120    //unsigned simultaneously_programmed_pages = 1 << ((d >> 4) & 0x3)
121    //bool can_interleave_program_between_chips = d & 0x40
122    //bool can_cache_program = d & 0x80
123    d = rdata ()
124    page_bits = 10 + (d & 3)
125    Iris::debug ("page bits: %d\n", page_bits)
126    redundant_bits = (d & 4 ? 4 : 3)
127    Iris::debug ("redundant bits: %d\n", redundant_bits)
128    block_bits = 16 + ((d >> 4) & 3)
129    Iris::debug ("block bits: %d\n", block_bits)
130    word_size = (d & 0x40 ? 16 : 8)
131    Iris::debug ("word size: %d\n", word_size)
132    //unsigned serial_access_minimum = (d & 0x80 ? 25 : 50)
133    d = rdata ()
134    //unsigned num_planes = 1 << ((d >> 2) & 3)
135    //unsigned plane_bits = 26 + ((d >> 4) & 7)
136
137static bool read (unsigned a, char *buffer):
138    unsigned column = a & ((1 << page_bits) - 1)
139    unsigned row = a >> page_bits
140    //Iris::debug ("reading: %x/%x/%x: ", a, row, column)
141    // Read oob information first.
142    char error[12]
143    // Spare space (starts at 1 << page_bits)
144    // 0: unused
145    // 2: detect valid data (at least 1 byte == 0 means valid)
146    // 5: unused
147    // 6: 9-byte ecc of 1st 512 bytes
148    // 15: 9-byte ecc of 2nd 512 bytes
149    // 24: 9-byte ecc of 3rd 512 bytes
150    // 33: 9-byte ecc of 4th 512 bytes
151    // 42: unused
152    // 64: end of space
153    unsigned col = (1 << page_bits) + 2
154    cmd (CMD_READ0)
155    addr (col)
156    addr (col >> 8)
157    addr (row)
158    addr (row >> 8)
159    addr (row >> 16)
160    cmd (CMD_READSTART)
161    bool valid = false
162    for unsigned t = 0; t < 3; ++t:
163        if rdata () == 0:
164            valid = true
165            break
166    if !valid:
167        return false
168    col = (1 << page_bits) + 6 + 9 * (column >> 9)
169    cmd (CMD_RNDOUT)
170    addr (col)
171    addr (col >> 8)
172    cmd (CMD_RNDOUTSTART)
173    for unsigned t = 0; t < 9; ++t:
174        error[t] = rdata ()
175    cmd (CMD_RNDOUT)
176    addr (column)
177    addr (column >> 8)
178    cmd (CMD_RNDOUTSTART)
179    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST
180    for unsigned t = 0; t < 0x200; ++t:
181        buffer[t] = rdata ()
182    EMC_NFPAR (0) = ((unsigned *)error)[0]
183    EMC_NFPAR (1) = ((unsigned *)error)[1]
184    EMC_NFPAR (2) = error[9]
185    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
186    while !(EMC_NFINTS & EMC_NFINTS_DECF):
187        Iris::schedule ()
188    unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
189    for unsigned i = 0; i < errs; ++i:
190        Iris::debug ("correcting %x on %x\n", EMC_NFERR (i) & 0xff, EMC_NFERR (i) >> 16)
191        buffer[EMC_NFERR (i) >> 16] ^= EMC_NFERR (i) & 0xff
192
193static void write (unsigned a, char *buffer):
194    kdebug_line ()
195    unsigned row = a >> page_bits
196    kdebug_line ()
197    //Iris::debug ("writing: %x/%x: ", a, row)
198    cmd (CMD_SEQIN)
199    kdebug_line ()
200    addr (0)
201    kdebug_line ()
202    addr (0)
203    kdebug_line ()
204    addr (row)
205    kdebug_line ()
206    addr (row >> 8)
207    kdebug_line ()
208    addr (row >> 16)
209    kdebug_line ()
210    char ecc[4][12]
211    for unsigned i = 0; i < 0x4; ++i:
212        kdebug_line ()
213        EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_ENCODING | EMC_NFECR_ERST
214        Iris::debug ("writing data from %x\n", (unsigned)buffer + i * 0x200)
215        for unsigned j = 0; j < 0x200; ++j:
216            wdata (buffer[i * 0x200 + j])
217        kdebug_line ()
218        while !(EMC_NFINTS & EMC_NFINTS_ENCF):
219            Iris::schedule ()
220        kdebug_line ()
221        ((unsigned *)ecc[i])[0] = EMC_NFPAR (0)
222        kdebug_line ()
223        ((unsigned *)ecc[i])[1] = EMC_NFPAR (1)
224        kdebug_line ()
225        ecc[i][9] = EMC_NFPAR (2)
226        kdebug_line ()
227    // Spare space (starts at 1 << page_bits)
228    // 0: unused
229    // 2: detect valid data (at least 1 byte == 0 means valid)
230    // 5: unused
231    // 6: 9-byte ecc of 1st 512 bytes
232    // 15: 9-byte ecc of 2nd 512 bytes
233    // 24: 9-byte ecc of 3rd 512 bytes
234    // 33: 9-byte ecc of 4th 512 bytes
235    // 42: unused
236    // 64: end of space
237    for unsigned i = 0; i < 6; ++i:
238        wdata (0)
239    kdebug_line ()
240    for unsigned i = 0; i < 4; ++i:
241        for unsigned j = 0; j < 9; ++j:
242            wdata (ecc[i][j])
243    kdebug_line ()
244    cmd (CMD_PAGEPROG)
245    kdebug_line ()
246    Iris::debug ("nand program %d done\n", a)
247
248static void erase (unsigned a):
249    unsigned row = a >> page_bits
250    cmd (CMD_ERASE1)
251    addr (row)
252    addr (row >> 8)
253    addr (row >> 16)
254    cmd (CMD_ERASE2)
255    Iris::debug ("nand erase %d done\n", a)
256
257extern "C":
258    extern char file_start, file_end
259
260Iris::Num start ():
261    //kdebug ("starting nand operation in 10 seconds\n")
262    //Iris::sleep (10 * HZ)
263    map_emc ()
264    map_gpio ()
265
266    // Arbitrary addresses where the pages are mapped.
267    command = (volatile char *)0x15000
268    address = (volatile char *)0x16000
269    data = (volatile char *)0x17000
270
27159    reset ()
27260
273
274    #if 0
61    #if 1
27562    erase (0)
276    kdebug_line ()
27763    char *source = &file_start
278    kdebug_line ()
279    unsigned a = 0x0000
280    kdebug_line ()
64    unsigned a = 0
65    while source < &file_mid:
66        write (a, source)
67        a += 0x800
68        source += 0x800
69    source = &file_mid
70    a = 0x4000
28171    while source < &file_end:
282        kdebug_line ()
28372        write (a, source)
28473        a += 0x800
28574        source += 0x800
286    kdebug_line ()
28775    #endif
28876
289    char buffer[0x800]
290
291    kdebug_line ()
77    char buffer[0x200]
29278    // Send nand contents to serial port.
293    for unsigned a = 0; a < 0x2000; a += 0x200:
79    for unsigned a = 0; a < 0x400; a += 0x200:
29480        read (a, buffer)
29581        for unsigned s = 0; s < 0x8; ++s:
29682            for unsigned t = 0; t < 0x40; ++t:
...... 
30389
30490asm volatile ("\t.set noreorder\n"
30591    "\t.globl file_start\n"
92    "\t.globl file_mid\n"
30693    "\t.globl file_end\n"
30794    "\t.text\n"
30895    "file_start:\n"
30996    "\t.incbin \"mips/nanonote/nand-boot.raw\"\n"
97    "file_mid:\n"
98    "\t.incbin \"iris-sd.raw\"\n"
31099    "file_end:\n"
311100    ".set reorder")

Archive Download the corresponding diff file

Branches:
master



interactive