From f4cac9b3a5de0406fe850396e017b9aecf865722 Mon Sep 17 00:00:00 2001 From: Bas Wijnen Date: Sat, 15 Jan 2011 02:10:46 +0100 Subject: [PATCH] lists and bugfixes --- devices.hhp | 11 +- invoke.ccp | 18 ++- iris.hhp | 9 ++ mips/nanonote/Makefile.arch | 9 +- mips/nanonote/board.ccp | 21 +--- mips/nanonote/jz4740.hhp | 20 ++++ mips/nanonote/sdram-setup.ccp | 17 ++- mips/nanonote/sdram-setup.ld | 2 +- mips/nanonote/server/usb-server.ccp | 3 +- mips/nanonote/threadlist.S | 2 +- source/sd+mmc.ccp | 180 ++++++++++++++++++---------- 11 files changed, 199 insertions(+), 93 deletions(-) diff --git a/devices.hhp b/devices.hhp index 1081536..1ae40bf 100644 --- a/devices.hhp +++ b/devices.hhp @@ -37,6 +37,7 @@ namespace Iris: enum request: LOCK_RO = 0x2001 UNLOCK_RO + SET_CHANGE_CB NUM template // struct Locker : public _Locker_base, public _T: @@ -46,6 +47,12 @@ namespace Iris: // Release a read-only lock. void unlock_ro (): _T::call (CAP_MASTER_DIRECT | UNLOCK_RO) + // Register a callback when the backing store is changed. + // The cb is invoked with data[0] set to the position of the first change and data[1] set to the length of the changed part. + // The accuracy of this is not guaranteed. Servers which only want to provide an event should set data[0] == 0, data[1] == ~0. + // The change invoke must happen before this function's reply is sent. + void set_change_cb (Listitem cb): + _T::ocall (cb, CAP_MASTER_DIRECT | SET_CHANGE_CB) Locker (): Locker (Cap c) : _T (c): @@ -130,8 +137,8 @@ namespace Iris: struct _WBlock : public Block: _WBlock (Cap c = Cap ()) : Block (c): enum request: - TRUNCATE = _Block::ID - SET_BLOCK + TRUNCATE = _WString::TRUNCATE + SET_BLOCK = _WString::ID ID /// Set the size of the block. This setting may have a limited range, or not be supported at all. void truncate (Num size): diff --git a/invoke.ccp b/invoke.ccp index d387300..b2419d4 100644 --- a/invoke.ccp +++ b/invoke.ccp @@ -320,6 +320,22 @@ static void memory_invoke (unsigned cmd, unsigned target, Iris::Num protected_da dpanic (0x43311992, "out of memory creating caps") reply_num (Iris::ERR_OUT_OF_MEMORY) return + case CAPTYPE_LIST: + kList *ret = mem->alloc_list () + if ret: + reply_cap (CAPTYPE_LIST | CAP_MASTER, (unsigned)ret, &ret->refs) + else: + dpanic (0x13311995, "out of memory creating list") + reply_num (Iris::ERR_OUT_OF_MEMORY) + return + case CAPTYPE_LISTITEM: + kListitem *ret = mem->alloc_listitem () + if ret: + reply_cap (CAPTYPE_LISTITEM | CAP_MASTER, (unsigned)ret, &ret->refs) + else: + dpanic (0x13311997, "out of memory creating list") + reply_num (Iris::ERR_OUT_OF_MEMORY) + return default: dpanic (0, "invalid create type") reply_num (Iris::ERR_INVALID_ARGUMENT) @@ -873,7 +889,7 @@ static void list_invoke (unsigned cmd, unsigned target, Iris::Num protected_data return item = item->next_item if !item: - reply_num (0) + reply_num (~0) return reply_cap (CAPTYPE_LISTITEM | Iris::Listitem::LIST, (unsigned)item, &item->refs) return diff --git a/iris.hhp b/iris.hhp index 1c9244e..3380541 100644 --- a/iris.hhp +++ b/iris.hhp @@ -496,17 +496,26 @@ namespace Iris: GET_INFO SET_INFO GET_CAP + // Get the next listitem from the given one. Use this to loop over all listitems. Listitem get_next (Listitem current = Listitem ()): iocall (current, CAP_MASTER_DIRECT | GET_NEXT) + if recv.data[0].l: + return Cap () return get_arg () + // Set the callback. This is called when an item is removed from the list. + // When called, data[0] is 0 when the list is now empty; 1 otherwise. data[1] is the removed item's info. void set_cb (Cap cb): ocall (cb, CAP_MASTER_DIRECT | SET_CB) + // Add an item to the front of the list. void add_item (Listitem item): ocall (item, CAP_MASTER_DIRECT | ADD_ITEM) + // Return item info. Num get_info (Listitem item): return ocall (item, CAP_MASTER_DIRECT | GET_INFO) + // Set item info. void set_info (Listitem item, Num info): ocall (item, CAP_MASTER_DIRECT | SET_INFO, info) + // Get item capability. Cap get_cap (Listitem item): iocall (item, CAP_MASTER_DIRECT | GET_CAP) return get_arg () diff --git a/mips/nanonote/Makefile.arch b/mips/nanonote/Makefile.arch index 2762842..a0c2204 100644 --- a/mips/nanonote/Makefile.arch +++ b/mips/nanonote/Makefile.arch @@ -15,7 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -start_load = 0x80600000 +start_load = 0x80400000 load = 0x80000000 # Uncomment one of these to select the boot method for the image. #UDC_BOOT = yes @@ -27,10 +27,11 @@ boot_sources = mips/init.cc mips/nanonote/board.cc arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh mips/nand.hh udc_boot_programs = udc sd_boot_programs = sd+mmc partition fat -unbrick_boot_programs = nand usb-mass-storage +unbrick_boot_programs = nand sd+mmc usb-mass-storage standard_boot_programs = bootinit -programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui test boot booter $(udc_boot_programs) $(sd_boot_programs) $(unbrick_boot_programs) $(standard_boot_programs) +# use sort to remove duplicates. +programs = $(sort init gpio lcd bsquare ball buzzer metronome elfrun alarm rtc gui test boot booter $(udc_boot_programs) $(sd_boot_programs) $(unbrick_boot_programs) $(standard_boot_programs)) ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL CROSS = mipsel-linux-gnu- @@ -56,7 +57,7 @@ iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) mips/start.raw.gz fs cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference else ifneq ($(UNBRICK),) -boot_threads = $(standard_boot_programs) $(unbrick_boot_programs) +boot_threads = $(standard_boot_programs) $(unbrick_boot_programs) sd+mmc ARCH_CXXFLAGS = -DNUM_THREADS=3 BOOT_CPPFLAGS = -DUNBRICK all: mips/start.raw diff --git a/mips/nanonote/board.ccp b/mips/nanonote/board.ccp index a74550f..1f907af 100644 --- a/mips/nanonote/board.ccp +++ b/mips/nanonote/board.ccp @@ -23,10 +23,6 @@ void board_init (): pll_init () cpm_stop_all () - #ifndef NDEBUG - cpm_start_uart0 () - gpio_as_uart0 () - #endif // Timer interrupts and buzzer. cpm_start_tcu () // sdram memory. @@ -42,7 +38,7 @@ void board_init (): // buzzer. gpio_as_pwm4 () // Set up memory. - setup_sdram () + //setup_sdram () // Use some gpio pins for lcd. gpio_as_gpio (2, (1 << 21) | (1 << 22) | (1 << 23)) gpio_as_output (2, (1 << 21) | (1 << 22) | (1 << 23)) @@ -66,20 +62,7 @@ void board_init (): tcu_unmask_full_match_irq (0) tcu_start_counter (0) #ifndef NDEBUG - // Set up uart. - UART0_IER = 0 - UART0_FCR = 0 - UART0_MCR = 0 - UART0_SIRCR = 0 - UART0_UACR = 0 - UART0_UMR = 16 - UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1 | UARTLCR_DLAB - unsigned const baud = 57600 - unsigned uart_div = 12000000 / 16 / baud - UART0_DLHR = (uart_div >> 8) & 0xff - UART0_DLLR = uart_div & 0xff - UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1 - UART0_FCR = UARTFCR_UUE | UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS + setup_uart () kdebug ("\n\nSerial port initialized\n") #endif diff --git a/mips/nanonote/jz4740.hhp b/mips/nanonote/jz4740.hhp index 740e372..510d63b 100644 --- a/mips/nanonote/jz4740.hhp +++ b/mips/nanonote/jz4740.hhp @@ -3701,6 +3701,26 @@ static void setup_sdram (): dbg_log_num (EMC_RTCOR, 8) dbg_log ("\n") #endif + +static void setup_uart (): + #ifndef NDEBUG + // Set up uart. + cpm_start_uart0 () + gpio_as_uart0 () + UART0_IER = 0 + UART0_FCR = 0 + UART0_MCR = 0 + UART0_SIRCR = 0 + UART0_UACR = 0 + UART0_UMR = 16 + UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1 | UARTLCR_DLAB + unsigned const baud = 57600 + unsigned uart_div = 12000000 / 16 / baud + UART0_DLHR = (uart_div >> 8) & 0xff + UART0_DLLR = uart_div & 0xff + UART0_LCR = UARTLCR_WLEN_8 | UARTLCR_STOP1 + UART0_FCR = UARTFCR_UUE | UARTFCR_FE | UARTFCR_RFLS | UARTFCR_TFLS + #endif #endif #endif diff --git a/mips/nanonote/sdram-setup.ccp b/mips/nanonote/sdram-setup.ccp index 3b6ee7f..8e2eee5 100644 --- a/mips/nanonote/sdram-setup.ccp +++ b/mips/nanonote/sdram-setup.ccp @@ -18,16 +18,22 @@ // This runs like the kernel. In particular, it doesn't want userspace declarations. #define __KERNEL__ -#define dbg_log(x) do {} while (0) #define dbg_log_char(x) do {} while (0) +#define dbg_log(x) do {} while (0) #define dbg_log_num(...) do {} while (0) + #include "jz4740.hh" +void kdebug (unsigned ch): + while !(UART0_LSR & UARTLSR_TDRQ): + UART0_TDR = ch + while !(UART0_LSR & UARTLSR_TEMT): + asm volatile (".set noreorder\n" "\t.globl __start\n" "\t.text\n" "__start:\n" - "\tla $sp, 0x80004000\n" + "\tnop\n" "__hack_label:\n" "\tmove $a0, $ra\n" "\tbal 1f\n" @@ -35,6 +41,7 @@ asm volatile (".set noreorder\n" "\t.word _gp\n" "1:\n" "\tlw $gp, 0($ra)\n" + "\tla $sp, stack + 0x100\n" "\tla $t9, start_cpp\n" "\tmove $ra, $a0\n" "\tjr $t9\n" @@ -43,7 +50,11 @@ asm volatile (".set noreorder\n" extern "C": void start_cpp () + char stack[0x100] void start_cpp (): - setup_sdram () + //setup_uart () + //kdebug ('.') + //setup_sdram () + //kdebug ('!') // everything is ok now: return to boot loader to load stage 2. diff --git a/mips/nanonote/sdram-setup.ld b/mips/nanonote/sdram-setup.ld index 2cfa90f..b28c2cb 100644 --- a/mips/nanonote/sdram-setup.ld +++ b/mips/nanonote/sdram-setup.ld @@ -2,7 +2,7 @@ OUTPUT_ARCH(mips) ENTRY(__start) MEMORY { - ram : ORIGIN = 0x80002000 , LENGTH = 0x100000 + ram : ORIGIN = 0x80002000 , LENGTH = 0x2000 } SECTIONS diff --git a/mips/nanonote/server/usb-server.ccp b/mips/nanonote/server/usb-server.ccp index c04a793..1cdb596 100644 --- a/mips/nanonote/server/usb-server.ccp +++ b/mips/nanonote/server/usb-server.ccp @@ -225,6 +225,7 @@ struct client : public shevek::server ::connection: disconnect () void data::request (requests r, unsigned data): + std::cerr << shevek::ostring ("requesting %08x with data %08x\n", r, data) if usb_control_msg (handle, USB_ENDPOINT_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, r, (data >> 16) & 0xffff, data & 0xffff, NULL, 0, timeout) < 0: std::cerr << "unable to send control message to NanoNote: " << usb_strerror () << ".\n" usb_release_interface (handle, 0) @@ -232,6 +233,7 @@ void data::request (requests r, unsigned data): handle = NULL void data::send_file (unsigned address, unsigned size, char const *data): + std::cerr << shevek::ostring ("setting data address to 0x%08x\n", address) request (VR_SET_DATA_ADDRESS, address) char const *ptr = data while ptr - data < size: @@ -292,7 +294,6 @@ void data::boot (std::string const &filename, unsigned load, unsigned entry): request (VR_PROGRAM_START1, STAGE1_ENTRY) usleep (100) std::ostringstream stage2 - usb_release_interface (handle, 0) file.close () file.open (filename.c_str ()) stage2 << file.rdbuf () diff --git a/mips/nanonote/threadlist.S b/mips/nanonote/threadlist.S index 3414824..4307b62 100644 --- a/mips/nanonote/threadlist.S +++ b/mips/nanonote/threadlist.S @@ -74,7 +74,7 @@ thread0: .balign 0x1000 thread1: - .incbin "fs/nand.elf" + .incbin "fs/sd+mmc.elf" .balign 0x1000 thread2: diff --git a/source/sd+mmc.ccp b/source/sd+mmc.ccp index 993eabc..1139be3 100644 --- a/source/sd+mmc.ccp +++ b/source/sd+mmc.ccp @@ -68,10 +68,16 @@ class Mmc: return read_block_size unsigned get_block_bits (): return hc ? 9 : csd.read_bl_len > csd.write_bl_len ? csd.read_bl_len : csd.write_bl_len - void fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset) void write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset) + void read_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset) void wait_write () + void add_cb (Iris::Listitem item): + cb_list.add_item (item) private: + void set_block (unsigned block) + unsigned current_block_num + bool dirty + unsigned *current_block unsigned rca bool have_sdmem, have_io bool hc @@ -79,6 +85,7 @@ class Mmc: CSD csd unsigned num_blocks, read_block_size Iris::Page buffer_page + Iris::List cb_list static unsigned const buffer = 0x15000 bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigned *response): @@ -129,6 +136,9 @@ bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigne d = MSC_RES cid.year = 2000 + (d >> 4 & 0xff) cid.month = d & 0xf + #if 1 + Iris::debug ("CID: mid=%x, oid=%x %x, pnm=%x %x %x %x %x, prv=%x, psn=%x, year=%x, month=%x\n", cid.mid, cid.oid[0], cid.oid[1], cid.pnm[0], cid.pnm[1], cid.pnm[2], cid.pnm[3], cid.pnm[4], cid.prv, cid.psn, cid.year, cid.month) + #endif else: // Header (8) 1.0 1.0 // Read out csd. @@ -175,6 +185,15 @@ bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigne num_blocks >>= 9 - csd.read_bl_len else: num_blocks <<= csd.read_bl_len - 9 + #if 1 + Iris::debug ("CSD: size=%x<<%x, r/w len=%x/%x, %s, %s, %s\n", csd.c_size, csd.c_size_mult, csd.read_bl_len, csd.write_bl_len, csd.copy ? "copy" : "no copy", csd.perm_write_protect ? "fixed write protect" : "no fixed write protect", csd.tmp_write_protect ? "write protect" : "no write protect") + #endif + unsigned c_size + unsigned c_size_mult + unsigned read_bl_len, write_bl_len + bool copy + bool perm_write_protect + bool tmp_write_protect else if response_type != NONE: unsigned r = MSC_RES if response_type == R3: @@ -203,6 +222,10 @@ bool Mmc::send (unsigned cmd, unsigned arg, Response_type response_type, unsigne return true void Mmc::reset (): + current_block_num = ~0 + dirty = false + cb_list = Iris::my_memory.create_list () + current_block = (unsigned *)(buffer + PAGE_SIZE) // Create a buffer to use for data transfer. buffer_page = Iris::my_memory.create_page () Iris::my_memory.map (buffer_page, buffer) @@ -348,6 +371,20 @@ void Mmc::detect (): kdebug (" = ") kdebug_num (num_blocks * read_block_size) kdebug ("\n") + // Set up buffer memory. + for unsigned i = 0; i < 1 << csd.write_bl_len; i += PAGE_SIZE: + Iris::Page p = Iris::my_memory.create_page () + p.set_flags (Iris::Page::PAYING | Iris::Page::FRAME) + Iris::my_memory.map (p, (unsigned)current_block + i) + Iris::free_cap (p) + Iris::Listitem item = cb_list.get_next () + while item.code != Iris::Cap ().code: + Iris::Cap c = cb_list.get_cap (item) + c.invoke (0, ~0) + Iris::free_cap (c) + Iris::Listitem nextitem = cb_list.get_next (item); + Iris::free_cap (item) + item = nextitem void Mmc::release (): kdebug ("mmc release\n") @@ -355,87 +392,94 @@ void Mmc::release (): have_sdmem = false have_io = false read_block_size = 0 + if num_blocks != 0: + for unsigned i = 0; i < 1 << csd.write_bl_len; i += PAGE_SIZE: + Iris::Page p = Iris::my_memory.mapping ((void *)((unsigned)current_block + i)) + Iris::my_memory.destroy (p) + Iris::free_cap (p) + if dirty: + Iris::debug ("Warning: sd/mmc card removed before data was written to it") + current_block_num = ~0 + dirty = false num_blocks = 0 + Iris::Listitem item = cb_list.get_next () + while item.code != Iris::Cap ().code: + Iris::Cap c = cb_list.get_cap (item) + c.invoke (0, ~0) + Iris::free_cap (c) + Iris::Listitem nextitem = cb_list.get_next (item); + Iris::free_cap (item) + item = nextitem void Mmc::interrupt (): kdebug ("mmc interrupt\n") -void Mmc::fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset): - if address.h: - Iris::panic (0, "page too high: not supported") +void Mmc::set_block (unsigned block): + if current_block_num == block: return - //kdebug ("smc get page ") - //kdebug_num (address.l) - //kdebug ("+") - //kdebug_num (size) - //kdebug ("@") - //kdebug_num (offset) - //kdebug ("\n") - unsigned blockmask = ~((1 << 9) - 1) - unsigned p = address.l & blockmask - size &= blockmask - offset &= ~PAGE_MASK - if size + offset > PAGE_SIZE: - size = PAGE_SIZE - offset - page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME) - page.share (buffer_page) - buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME) + if dirty && current_block_num != ~0: + MSC_NOB = 1 + MSC_BLKLEN = 1 << csd.write_bl_len + if !send (24, (current_block_num << csd.write_bl_len), WR_DATA): + Iris::panic (0, "unable to send data") + MSC_IMASK = ~MSC_IMASK_TXFIFO_WR_REQ + for unsigned a = 0; a < 1 << csd.write_bl_len; a += 4: + while MSC_STAT & MSC_STAT_DATA_FIFO_FULL: + Iris::register_interrupt (IRQ_MSC) + Iris::wait_for_interrupt (IRQ_MSC) + MSC_TXFIFO = current_block[a >> 2] + MSC_IMASK = ~0 + MSC_IREG = MSC_IREG_DATA_TRAN_DONE + //kdebug ("done writing page\n") + current_block_num = block + dirty = false MSC_NOB = 1 MSC_BLKLEN = 1 << 9 - for unsigned a = 0; a < size; a += 1 << 9: - //kdebug_num (a) - //kdebug ("/") - //kdebug_num (size) - //kdebug (" ==> ") - if !send (17, p + a, RD_DATA): + for unsigned a = 0; a < 1 << csd.write_bl_len; a += 1 << 9: + if !send (17, (block << csd.write_bl_len) + a, RD_DATA): Iris::panic (0, "unable to request data") MSC_IMASK = ~MSC_IMASK_RXFIFO_RD_REQ for unsigned aa = 0; aa < 1 << 9; aa += 4: while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY: Iris::register_interrupt (IRQ_MSC) Iris::wait_for_interrupt (IRQ_MSC) - *(unsigned *)(buffer + a + aa + offset) = MSC_RXFIFO - //unsigned d = *(unsigned *)(buffer + a + aa + offset) - //if (aa & 0x3f) == 0: - //kdebug ("\n") - //for unsigned i = 0; i < 4; ++i: - //kdebug (" ") - //kdebug_num (d >> (8 * i), 2) - //kdebug ("\n") + current_block[(a + aa) >> 2] = MSC_RXFIFO MSC_IMASK = ~0 MSC_IREG = MSC_IREG_DATA_TRAN_DONE //kdebug ("done filling page\n") -void Mmc::write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset): - if address.h: - Iris::panic (1, "page too high: not supported") - return +void Mmc::read_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset): + if address.value () >> (csd.write_bl_len + 32): + Iris::panic (address.h, "page too high: not supported") + unsigned block = address.value () >> csd.write_bl_len + unsigned start_pos = address.l & (1 << csd.write_bl_len) - 1 + set_block (block) unsigned blockmask = ~((1 << 9) - 1) - unsigned p = address.l & blockmask size &= blockmask - offset &= ~PAGE_MASK + offset &= ~PAGE_MASK & ~3 if size + offset > PAGE_SIZE: size = PAGE_SIZE - offset page.share (buffer_page) buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME) - MSC_NOB = 1 - MSC_BLKLEN = 1 << 9 - for unsigned a = 0; a < size; a += 1 << 9: - //kdebug_num (a) - //kdebug ("/") - //kdebug_num (size) - //kdebug ("\n") - if !send (24, p + a, WR_DATA): - Iris::panic (0, "unable to send data") - MSC_IMASK = ~MSC_IMASK_TXFIFO_WR_REQ - for unsigned aa = 0; aa < 1 << 9; aa += 4: - while MSC_STAT & MSC_STAT_DATA_FIFO_FULL: - Iris::register_interrupt (IRQ_MSC) - Iris::wait_for_interrupt (IRQ_MSC) - MSC_TXFIFO = *(unsigned *)(buffer + a + aa + offset) - MSC_IMASK = ~0 - MSC_IREG = MSC_IREG_DATA_TRAN_DONE - //kdebug ("done writing page\n") + for unsigned i = 0; i < size; i += 4: + ((unsigned *)buffer)[(offset + i) >> 2] = current_block[(start_pos + i) >> 2] + +void Mmc::write_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset): + if address.value () >> (csd.write_bl_len + 32): + Iris::panic (address.h, "page too high: not supported") + unsigned block = address.value () >> csd.write_bl_len + unsigned start_pos = address.l & (1 << csd.write_bl_len) - 1 + set_block (block) + unsigned blockmask = ~((1 << 9) - 1) + size &= blockmask + offset &= ~PAGE_MASK & ~3 + if size + offset > PAGE_SIZE: + size = PAGE_SIZE - offset + page.share (buffer_page) + buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME) + for unsigned i = 0; i < size; i += 4: + current_block[(start_pos + i) >> 2] = ((unsigned *)buffer)[(offset + i) >> 2] + dirty = true void Mmc::wait_write (): MSC_IMASK = ~MSC_IMASK_PRG_DONE @@ -473,7 +517,7 @@ Iris::Num start (): mmc.detect () cap = Iris::my_receiver.create_capability (REQUEST) - Iris::my_parent.provide_capability (cap.copy ()) + Iris::my_parent.provide_capability (cap.copy ()) Iris::free_cap (cap) Iris::my_parent.init_done () @@ -496,21 +540,25 @@ Iris::Num start (): //kdebug ("\n") switch Iris::recv.data[0].l: case Iris::Block::GET_SIZE: + Iris::debug ("get size\n") unsigned long long size = mmc.get_num_blocks () * mmc.get_read_block_size () Iris::recv.reply.invoke (size) break case Iris::Block::GET_ALIGN_BITS: + Iris::debug ("get align bits\n") Iris::recv.reply.invoke (9) break case Iris::Block::GET_BLOCK: + //Iris::debug ("get block\n") Iris::Cap reply = Iris::get_reply () Iris::Page page = Iris::get_arg () - mmc.fill_page (page, Iris::recv.data[1], Iris::recv.data[0].h >> 16, Iris::recv.data[0].h & 0xffff) + mmc.read_page (page, Iris::recv.data[1], Iris::recv.data[0].h >> 16, Iris::recv.data[0].h & 0xffff) reply.invoke () Iris::free_cap (page) Iris::free_cap (reply) break case Iris::WBlock::SET_BLOCK: + Iris::debug ("set block\n") Iris::Cap reply = Iris::get_reply () Iris::Page page = Iris::get_arg () mmc.write_page (page, Iris::recv.data[1], Iris::recv.data[0].h >> 16, Iris::recv.data[0].h & 0xffff) @@ -519,7 +567,17 @@ Iris::Num start (): Iris::free_cap (reply) mmc.wait_write () break - case Iris::WString::TRUNCATE: + case Iris::Block::SET_CHANGE_CB: + Iris::debug ("set change cb\n") + Iris::Listitem item = Iris::get_arg () + Iris::Cap reply = Iris::get_reply () + mmc.add_cb (item) + reply.invoke () + Iris::free_cap (item) + Iris::free_cap (reply) + break + case Iris::WBlock::TRUNCATE: + Iris::debug ("truncate\n") // Fall through: don't support resizing. default: Iris::panic (0, "unexpected event for sd+mmc")