Date:2010-07-08 12:38:36 (13 years 5 months ago)
Author:Bas Wijnen
Commit:19f1d128d05c9e269d17fcfa907f958dc1476493
Message:make booting from sd work

Files: devices.hhp (1 diff)
init.config (2 diffs)
mips/nanonote/Makefile.arch (1 diff)
source/bootinit.ccp (1 diff)
source/crt0.ccp (2 diffs)
source/fat.ccp (8 diffs)
source/init.ccp (2 diffs)
source/nand.ccp (1 diff)
source/sd+mmc.ccp (10 diffs)

Change Details

devices.hhp
7878        /// Set the size of the string. Strings may have a limit to this setting.
7979        void truncate (Num size):
8080            call (CAP_MASTER_DIRECT | TRUNCATE, size)
81        /// Set exactly 4 characters. The index must be word-aligned.
81        /// Set exactly 4 characters. The index must be aligned. This need not be supported for strings with align larger than 4 bytes.
8282        void set_chars (Num idx, char buffer[4]):
8383            call (Num (CAP_MASTER_DIRECT | SET_CHARS, *(unsigned *)buffer), idx)
8484        /// Overwrite a block from the string with data at offset on the page. This need not be implemented for strings smaller than PAGE_SIZE. The all arguments must be aligned. The caller may lose the frame in the transaction. Only the specified part of the page is used for overwriting data.
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    driver driver_lcd = "lcd.elf"
4    driver driver_buzzer = "buzzer.elf"
55    driver driver_gpio = "gpio.elf"
6    #program alarm = "alarm.elf"
7    #program gui = "gui.elf"
8    #driver nand = "nand.elf"
6    program alarm = "alarm.elf"
7    program gui = "gui.elf"
8    driver nand = "nand.elf"
99    driver sdmmc = "sd+mmc.elf"
1010    program partition = "partition.elf"
1111    program fat = "fat.elf"
1212    program test = "test.elf"
1313
1414    # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
15    #receive driver_lcd / Display = display
16    #receive driver_lcd / Setting = display_bright
17    #receive driver_buzzer / Buzzer = buzzer
15    receive driver_lcd / Display = display
16    receive driver_lcd / Setting = display_bright
17    receive driver_buzzer / Buzzer = buzzer
1818    receive driver_gpio / Keyboard , 0 = keyboard
1919    receive driver_gpio / Keyboard , 1 = sysreq
2020    receive driver_gpio / Event = sdmmc_gpio
21    #receive alarm / UI = ui
21    receive alarm / UI = ui
2222    receive sdmmc / WString = sdmmc
2323    receive partition / WString, 0 = p0
2424    receive partition / WString, 1 = p1
...... 
3030    sysreq sysreq
3131
3232    # give <name> / <type> [, <index>] = <cap> give this capability to this program when it requests it.
33    #give gui / UI = ui
34    #give gui / Display = display
35    #give gui / Setting = display_bright
36    #give gui / Buzzer = buzzer
37    #give gui / Keyboard = keyboard
33    give gui / UI = ui
34    give gui / Display = display
35    give gui / Setting = display_bright
36    give gui / Buzzer = buzzer
37    give gui / Keyboard = keyboard
3838    give sdmmc / Event = sdmmc_gpio
3939    give partition / WString = sdmmc
4040    give fat / WString = p0
mips/nanonote/Makefile.arch
1616# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
1818load = 0x80000000
19UDC_BOOT=1
19#UDC_BOOT = set
2020
2121ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
2222CROSS = mipsel-linux-gnu-
source/bootinit.ccp
2323#define ELFRUN_NAME "elfrun.elf"
2424#define INIT_NAME "init.elf"
2525
26// These numbers are only used for elfrun.
2627#define NUM_SLOTS 8
2728#define NUM_CAPS 32
2829
source/crt0.ccp
4040    __recv_data_t recv
4141
4242    void print_caps ():
43        // Assume __caps to be 32.
44        bool used[32]
45        for unsigned i = 0; i < 32; ++i:
43        // __caps cannot be larger than 63.
44        bool used[63]
45        for unsigned i = 0; i < __caps; ++i:
4646            used[i] = true
4747        unsigned num = 0
4848        for list *i = __first_free_cap; i; i = i->next:
...... 
5252            ++num
5353        kdebug_num (num, 2)
5454        kdebug (":")
55        for unsigned i = 0; i < 32; ++i:
55        for unsigned i = 0; i < __caps; ++i:
5656            kdebug_char (used[i] ? '#' : '.')
5757        kdebug_char ('\n')
5858
source/fat.ccp
296296            else if bits == 12 && fat[c] == 0xfff || bits == 16 && fat[c] == 0xffff || bits == 32 && fat[c] == 0xfffffff:
297297                // Last cluster in chain.
298298                fat[c] = ~0
299                kdebug ("last cluster: ")
300                kdebug_num (c)
301                kdebug ("\n")
299                //kdebug ("last cluster: ")
300                //kdebug_num (c)
301                //kdebug ("\n")
302302            else if bits == 12 && fat[c] == 0xff7 || bits == 16 && fat[c] == 0xfff7 || bits == 32 && fat[c] == 0xffffff7:
303303                // Bad cluster.
304304                fat[c] = first_bad_cluster
...... 
307307            else:
308308                // Non-last cluster in chain.
309309                fat[c] -= 2
310                kdebug_num (c)
311                kdebug (" -> ")
312                kdebug_num (fat[c])
313                kdebug ("\n")
310                //kdebug_num (c)
311                //kdebug (" -> ")
312                //kdebug_num (fat[c])
313                //kdebug ("\n")
314314    unsigned fat_lookup (unsigned first_cluster, unsigned cluster):
315315        //kdebug ("looking up ")
316316        //kdebug_num (first_cluster)
...... 
334334        bool archive, readonly, system, hidden, directory, volume
335335        unsigned create_second, create_minute_hour, create_date, access_date, time, date
336336        unsigned checksum
337        void load_cluster (unsigned idx, Iris::Page p = page, unsigned offset = 0):
337        void load_cluster (unsigned idx, unsigned offset_in_cluster, Iris::Page p = page, unsigned offset = 0):
338338            unsigned cluster = fat->fat_lookup (first_cluster, idx >> fat->cluster_size_bits)
339339            //kdebug ("loading cluster ")
340340            //kdebug_num (idx)
341            //kdebug ("+")
342            //kdebug_num (offset_in_cluster)
341343            //kdebug ("@")
342344            //kdebug_num (cluster)
343345            //kdebug (" from file\n")
344346            if cluster == ~0:
345347                kdebug ("invalid cluster requested from file\n")
346348                return
347            read_block ((fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits)) << fat->sector_size_bits, p, 1 << fat->cluster_size_bits, offset)
348            //kdebug ("sector ")
349            //kdebug_num (fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits))
350            //kdebug ("\n")
349            read_block (((fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits)) << fat->sector_size_bits) + offset_in_cluster, p, fat->cluster_size_bits < PAGE_BITS ? 1 << fat->cluster_size_bits : PAGE_SIZE, offset)
351350    char *load_dir_entry (unsigned dir, unsigned idx):
352351        unsigned sector = idx >> (sector_size_bits - 5)
353352        unsigned num = (idx << 5) & ~BLOCK_MASK
...... 
398397            kdebug ("unable to load dir entry\n")
399398            return false
400399        f->fat = this
400        //kdebug ("loading dir entry for ")
401401        for unsigned i = 0; i < 11; ++i:
402402            f->name[i] = e[i]
403            //kdebug_char (f->name[i])
404        //kdebug ("\n")
403405        f->readonly = e[0xb] & 0x1
404406        f->system = e[0xb] & 0x2
405407        f->hidden = e[0xb] & 0x4
...... 
589591            unsigned size = Iris::recv.data[0].h >> 16
590592            unsigned offset = Iris::recv.data[0].h & 0xffff
591593            unsigned cmd = Iris::recv.data[0].l
592            if !fat.find_idx (dir, &idx):
593                Iris::panic (0, "file not found")
594594            Fat::File f
595595            fat.get_dir_entry (dir, idx, &f)
596596            switch cmd:
...... 
600600                    break
601601                case Iris::String::GET_CHARS:
602602                    //kdebug ("file chars requested\n")
603                    unsigned mask = 1 << (fat.cluster_size_bits) - 1
604                    f.load_cluster (num.l & ~mask)
603                    unsigned mask = (1 << fat.cluster_size_bits) - 1
604                    f.load_cluster (num.l & ~mask, num.l & mask)
605605                    unsigned n = num.l & mask & ~0xf
606606                    unsigned *dat = (unsigned *)(data + n)
607607                    reply.invoke (Iris::Num (dat[0], dat[1]), Iris::Num (dat[2], dat[3]))
608608                    break
609609                case Iris::String::GET_ALIGN_BITS:
610610                    //kdebug ("file align requested\n")
611                    reply.invoke (fat.cluster_size_bits)
611                    reply.invoke (fat.cluster_size_bits <= PAGE_BITS ? fat.cluster_size_bits : PAGE_BITS)
612612                    break
613613                case Iris::String::GET_BLOCK:
614614                    //kdebug ("file block requested\n")
615                    unsigned mask = 1 << (fat.cluster_size_bits) - 1
615                    unsigned mask = (1 << fat.cluster_size_bits) - 1
616                    //kdebug ("mask = ")
617                    //kdebug_num (mask)
618                    //kdebug ("\n")
616619                    if offset > PAGE_SIZE:
617620                        //kdebug ("invalid offset requested\n")
618621                        break
619622                    if size + offset > PAGE_SIZE:
623                        Iris::panic (size, "invalid size requested")
620624                        size = PAGE_SIZE - offset
621625                    for unsigned i = 0; i < size; i += 1 << fat.cluster_size_bits:
622                        f.load_cluster ((num.l & ~mask) + i, arg, i + offset)
626                        f.load_cluster ((num.l & ~mask) + i, num.l & mask, arg, i + offset)
623627                    reply.invoke ()
624628                    break
625629                case Iris::WString::TRUNCATE:
...... 
652656                    Iris::Cap reply = Iris::get_reply ()
653657                    dir = Iris::recv.protected_data.l
654658                    unsigned idx = Iris::recv.data[1].l
659                    unsigned oldidx = idx
655660                    if !fat.find_idx (dir, &idx):
656                        Iris::panic (0, "file not found")
661                        kdebug_num (oldidx)
662                        kdebug ("\n")
663                        Iris::panic (1, "file not found")
657664                    Fat::File f
658665                    fat.get_dir_entry (dir, idx, &f)
659666                    Iris::Cap ret
660667                    if f.directory:
668                        //kdebug ("dir provided: ")
669                        //kdebug_num (f.first_cluster)
670                        //kdebug ("\n")
661671                        ret = Iris::my_receiver.create_capability (Iris::Num (f.first_cluster, 0))
662672                    else:
663673                        ret = Iris::my_receiver.create_capability (Iris::Num (idx, dir))
...... 
670680                    Iris::Cap reply = Iris::get_reply ()
671681                    dir = Iris::recv.protected_data.l
672682                    unsigned idx = Iris::recv.data[1].l
683                    unsigned oldidx = idx
673684                    if !fat.find_idx (dir, &idx):
674                        Iris::panic (0, "file not found")
685                        kdebug_num (oldidx)
686                        kdebug ("\n")
687                        Iris::panic (2, "file not found")
675688                    unsigned type = Iris::recv.data[0].h
676689                    Fat::File f
677690                    fat.get_dir_entry (dir, idx, &f)
source/init.ccp
143143        Iris::free_cap (cap)
144144        thread = caps.get (__thread_num)
145145        memory = caps.get (__memory_num)
146        Iris::free_cap (caps)
146147        if priv:
147148            thread.make_priv ()
148149        thread.run ()
...... 
471472        if Iris::recv.protected_data.l == SYSREQ:
472473            if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
473474                continue
474            kdebug ("sysreq event\n")
475            kdebug ("sysreq event: rebooting device\n")
476            Iris::reboot ()
475477            continue
476478        Program *caller = (Program *)Iris::recv.protected_data.l
477479        switch Iris::recv.data[0].l:
source/nand.ccp
173173    unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
174174
175175Iris::Num start ():
176    for unsigned i = 0; i < 30; ++i:
177        Iris::schedule ()
176    kdebug ("reading nand in 10 seconds\n")
177    Iris::sleep (10 * HZ)
178178    map_emc ()
179179    map_gpio ()
180180
source/sd+mmc.ccp
2424    public:
2525    enum Response_type:
2626        NONE = MSC_CMDAT_RESPONSE_NONE
27        DATA = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_DATA_EN
27        RD_DATA = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_DATA_EN | MSC_CMDAT_READ
28        WR_DATA = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_DATA_EN | MSC_CMDAT_WRITE
2829        R1 = MSC_CMDAT_RESPONSE_R1
2930        R1B = MSC_CMDAT_RESPONSE_R1 | MSC_CMDAT_BUSY
3031        R2 = MSC_CMDAT_RESPONSE_R2
...... 
6869    unsigned get_block_bits ():
6970        return hc ? 9 : csd.read_bl_len > csd.write_bl_len ? csd.read_bl_len : csd.write_bl_len
7071    void fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset)
72    void write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset)
73    void wait_write ()
7174    private:
7275    unsigned rca
7376    bool have_sdmem, have_io
...... 
8285    MSC_CMD = cmd
8386    MSC_ARG = arg
8487    MSC_CMDAT = response_type
88    MSC_IMASK = ~MSC_IMASK_END_CMD_RES
8589    Iris::register_interrupt (IRQ_MSC)
8690    msc_start_op ()
8791    Iris::wait_for_interrupt (IRQ_MSC)
92    MSC_IMASK = ~0
8893    //kdebug ("cmd: ")
8994    //kdebug_num (cmd)
9095    unsigned stat = MSC_STAT
...... 
178183        else if r >> 8 != cmd:
179184            kdebug ("stat: ")
180185            kdebug_num (MSC_STAT)
186            kdebug ("; response: ")
187            kdebug_num (r)
188            kdebug ("; cmd: ")
189            kdebug_num (cmd)
181190            Iris::panic (r, "response doesn't match command")
182191        r <<= 24
183192        r |= MSC_RES << 8
...... 
199208    Iris::my_memory.map (buffer_page, buffer)
200209    // Reset all state, by faking a release event.
201210    release ()
202    // Enable slow clock to msc.
203    CPM_MSCCDR = ~0
211    // Enable 25 MHz clock to msc.
212    CPM_MSCCDR = 13
204213    cpm_start_msc ()
205214    // Enable msc pins.
206215    gpio_as_msc ()
...... 
223232        Iris::sleep (1)
224233
225234    // Initialize registers.
226    MSC_CLKRT = MSC_CLKRT_CLK_RATE_DIV_128
235    MSC_CLKRT = MSC_CLKRT_CLK_RATE_DIV_1
227236    MSC_RESTO = 64
228237    MSC_RDTO = ~0
229238    MSC_BLKLEN = 0x200
230239    MSC_NOB = 0
231240    MSC_IREG = ~0
232    MSC_IMASK = ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_RXFIFO_RD_REQ | MSC_IMASK_TXFIFO_WR_REQ)
241    MSC_IMASK = ~(MSC_IMASK_END_CMD_RES | MSC_IMASK_RXFIFO_RD_REQ)
233242    MSC_ARG = 0
234243
235244    // Start the clock.
...... 
237246    // Set cards, if any, to idle.
238247    send (0, 0, NONE)
239248
240    // Reset SDIO device, if any.
241    send (52, 0x88000c08, R5)
249    // Reset SDIO device, if any. Don't do this, because it breaks for some reason.
250    //send (52, 0x88000c08, R5)
242251
243252void Mmc::check_mmc ():
244253    //kdebug ("checking mmc\n")
...... 
378387        //kdebug ("/")
379388        //kdebug_num (size)
380389        //kdebug (" ==> ")
381        if !send (17, p + a, DATA):
390        if !send (17, p + a, RD_DATA):
382391            Iris::panic (0, "unable to request data")
392        MSC_IMASK = ~MSC_IMASK_RXFIFO_RD_REQ
383393        for unsigned aa = 0; aa < 1 << 9; aa += 4:
384394            while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
385395                Iris::register_interrupt (IRQ_MSC)
...... 
392402                //kdebug (" ")
393403                //kdebug_num (d >> (8 * i), 2)
394404        //kdebug ("\n")
405        MSC_IMASK = ~0
395406        MSC_IREG = MSC_IREG_DATA_TRAN_DONE
396407    //kdebug ("done filling page\n")
397408
409void Mmc::write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset):
410    if address.h:
411        Iris::panic (1, "page too high: not supported")
412        return
413    unsigned blockmask = ~((1 << 9) - 1)
414    unsigned p = address.l & blockmask
415    size &= blockmask
416    offset &= ~PAGE_MASK
417    if size + offset > PAGE_SIZE:
418        size = PAGE_SIZE - offset
419    page.share (buffer_page)
420    buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
421    MSC_NOB = 1
422    MSC_BLKLEN = 1 << 9
423    for unsigned a = 0; a < size; a += 1 << 9:
424        //kdebug_num (a)
425        //kdebug ("/")
426        //kdebug_num (size)
427        //kdebug ("\n")
428        if !send (24, p + a, WR_DATA):
429            Iris::panic (0, "unable to send data")
430        MSC_IMASK = ~MSC_IMASK_TXFIFO_WR_REQ
431        for unsigned aa = 0; aa < 1 << 9; aa += 4:
432            while MSC_STAT & MSC_STAT_DATA_FIFO_FULL:
433                Iris::register_interrupt (IRQ_MSC)
434                Iris::wait_for_interrupt (IRQ_MSC)
435            MSC_TXFIFO = *(unsigned *)(buffer + a + aa + offset)
436        MSC_IMASK = ~0
437        MSC_IREG = MSC_IREG_DATA_TRAN_DONE
438    //kdebug ("done writing page\n")
439
440void Mmc::wait_write ():
441    MSC_IMASK = ~MSC_IMASK_PRG_DONE
442    while !MSC_STAT & MSC_STAT_PRG_DONE:
443        Iris::register_interrupt (IRQ_MSC)
444        Iris::wait_for_interrupt (IRQ_MSC)
445    MSC_IREG = MSC_IREG_PRG_DONE
446
398447static Mmc mmc
399448
400449enum types:
...... 
464513                        Iris::free_cap (page)
465514                        Iris::free_cap (reply)
466515                        break
467                    case Iris::WString::SET_CHARS:
468516                    case Iris::WString::SET_BLOCK:
469                        // Fall through: don't support writing yet.
517                        Iris::Cap reply = Iris::get_reply ()
518                        Iris::Page page = Iris::get_arg ()
519                        mmc.write_page (page, Iris::recv.data[1], Iris::recv.data[0].h >> 16, Iris::recv.data[0].h & 0xffff)
520                        reply.invoke ()
521                        Iris::free_cap (page)
522                        Iris::free_cap (reply)
523                        mmc.wait_write ()
524                        break
525                    case Iris::WString::SET_CHARS:
526                        // Fall through: don't support writing single characters.
470527                    case Iris::WString::TRUNCATE:
528                        // Fall through: don't support resizing.
471529                    default:
472530                        Iris::panic (0, "unexpected event for sd+mmc")
473531                break

Archive Download the corresponding diff file

Branches:
master



interactive