Date:2010-05-15 18:42:17 (13 years 7 months ago)
Author:Bas Wijnen
Commit:6bf41032d80d1c11ca1414f4b8a4d26547c7ee10
Message:add partial nand and sd/mmc drivers

Files: Makefile (2 diffs)
devices.hhp (11 diffs)
init.config (3 diffs)
mips/nanonote/Makefile.arch (1 diff)
mips/nanonote/board.ccp (1 diff)
mips/nanonote/jz4740.hhp (2 diffs)
source/alarm.ccp (2 diffs)
source/crt0.ccp (1 diff)
source/gui.ccp (4 diffs)
source/init.ccp (1 diff)
source/nand.ccp (1 diff)
source/nanonote-gpio.ccp (6 diffs)
source/sd+mmc.ccp (1 diff)

Change Details

Makefile
2323LD = $(CROSS)ld
2424OBJCOPY = $(CROSS)objcopy
2525
26headers = kernel.hh iris.hh ui.hh $(arch_headers)
26headers = kernel.hh iris.hh devices.hh ui.hh $(arch_headers)
2727iris_sources = panic.cc data.cc alloc.cc memory.cc invoke.cc schedule.cc $(arch_iris_sources)
2828BUILT_SOURCES = $(iris_sources) $(boot_sources)
2929
...... 
5959
6060debug:
6161    stty -F $(SERIAL) raw 9600
62    cat $(SERIAL)
62    while : ; do cat $(SERIAL) ; done
6363
6464.PHONY: clean
65.PRECIOUS: iris.hh kernel.hh ui.hh boot-programs/crt0.o
65.PRECIOUS: $(headers) boot-programs/crt0.o source/crt0.o
devices.hhp
2424namespace Iris:
2525    // Caplist interface.
2626    template <typename _T> //
27    struct Caplist : public Iris::Caps:
28        Caplist (Iris::Caps c = Iris::Cap ()) : Iris::Caps (c):
29        Caplist <_T> create (unsigned size, Iris::Memory mem = Iris::my_memory):
27    struct Caplist : public Caps:
28        Caplist (Caps c = Cap ()) : Caps (c):
29        Caplist <_T> create (unsigned size, Memory mem = my_memory):
3030            return Caplist <_T> (mem.create_caps (size))
3131        void set (unsigned idx, _T value):
32            return Iris::Caps::set (idx, value)
32            return Caps::set (idx, value)
3333        _T get (unsigned idx):
34            return _T (Iris::Caps::get (idx))
34            return _T (Caps::get (idx))
3535
3636    /// A block of data with a size and content. Any character can be stored in it (including '\0').
37    struct String : public Iris::Cap:
38        String (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
37    struct String : public Cap:
38        String (Cap c = Cap ()) : Cap (c):
3939        enum request:
4040            GET_SIZE = 0x2001
4141            GET_CHARS
4242            GET_PAGE
4343            ID
4444        /// Get the size of the string.
45        Iris::Num get_size ():
45        Num get_size ():
4646            return call (CAP_MASTER_DIRECT | GET_SIZE)
4747        /// Get exactly 16 characters. The index must be word-aligned.
48        char *get_chars (Iris::Num idx, char buffer[16]):
48        char *get_chars (Num idx, char buffer[16]):
4949            call (CAP_MASTER_DIRECT | GET_CHARS, idx)
5050            unsigned *b = (unsigned *)buffer
51            b[0] = Iris::recv.data[0].l
52            b[1] = Iris::recv.data[0].h
53            b[2] = Iris::recv.data[1].l
54            b[3] = Iris::recv.data[1].h
51            b[0] = recv.data[0].l
52            b[1] = recv.data[0].h
53            b[2] = recv.data[1].l
54            b[3] = recv.data[1].h
5555            return buffer
5656        /// Helper function for get_page.
57        static Iris::Page _create_paying_page ():
58            Iris::Page ret = Iris::my_memory.create_page ()
59            ret.set_flags (Iris::Page::PAYING, Iris::Page::PAYING)
57        static Page _create_paying_page ():
58            Page ret = my_memory.create_page ()
59            ret.set_flags (Page::PAYING, Page::PAYING)
6060            return ret
6161        /// Get a page from the string. This need not be implemented for strings smaller than PAGE_SIZE. The index must be page-aligned.
62        Cap get_page (Iris::Num idx, Iris::Page ret = _create_paying_page ()):
62        Cap get_page (Num idx, Page ret = _create_paying_page ()):
6363            ocall (ret, CAP_MASTER_DIRECT | GET_PAGE, idx)
6464            return ret
6565
6666    /// A writable String.
6767    struct WString : public String:
68        WString (Iris::Cap c = Iris::Cap ()) : String (c):
68        WString (Cap c = Cap ()) : String (c):
6969        enum request:
7070            TRUNCATE = String::ID
7171            SET_CHARS
7272            SET_PAGE
7373            ID
7474        /// Set the size of the string. Strings may have a limit to this setting.
75        void truncate (Iris::Num size):
75        void truncate (Num size):
7676            call (CAP_MASTER_DIRECT | TRUNCATE, size)
7777        /// Set exactly 4 characters. The index must be word-aligned.
78        void set_chars (Iris::Num idx, char buffer[4]):
79            call (Iris::Num (CAP_MASTER_DIRECT | SET_CHARS, *(unsigned *)buffer), idx)
78        void set_chars (Num idx, char buffer[4]):
79            call (Num (CAP_MASTER_DIRECT | SET_CHARS, *(unsigned *)buffer), idx)
8080        /// Overwrite a page from the string. This need not be implemented for strings smaller than PAGE_SIZE. The index must be page-aligned. The caller may lose the frame in the transaction.
81        void set_page (Iris::Num idx, Iris::Page page):
81        void set_page (Num idx, Page page):
8282            ocall (page, CAP_MASTER_DIRECT | SET_PAGE, idx)
8383
8484    // Every process which wants to be switchable through a terminal must implement this interface.
85    struct Device : public Iris::Cap:
86        Device (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
85    struct Device : public Cap:
86        Device (Cap c = Cap ()) : Cap (c):
8787        enum request:
8888            RESET = WString::ID
8989            ID
...... 
9191        void reset ():
9292            call (CAP_MASTER_DIRECT | RESET)
9393
94    struct Elfrun : public Iris::Cap:
95        Elfrun (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
94    struct Event : public Device:
95        Event (Cap c = Cap ()) : Device (c):
9696        enum request:
97            RUN_STRING = Device::ID
97            SET_CB = Device::ID
98            ID
99        // Set the event callback. Pending event emit to the new callback immediately.
100        void set_cb (Cap cb):
101            ocall (cb, CAP_MASTER_DIRECT | SET_CB)
102
103    struct Elfrun : public Cap:
104        Elfrun (Cap c = Cap ()) : Cap (c):
105        enum request:
106            RUN_STRING = Event::ID
98107            RUN_CAPS
99108            ID
100109        enum arg_pos:
101110            PARENT_MEMORY
102111            DATA
103112            PARENT
104        Iris::Caps run_string (Memory parent_memory, String data, Cap parent, unsigned num_slots = 8, unsigned num_caps = 32):
105            Iris::Caps caps = Iris::my_memory.create_caps (3)
113        Caps run_string (Memory parent_memory, String data, Cap parent, unsigned num_slots = 8, unsigned num_caps = 32):
114            Caps caps = my_memory.create_caps (3)
106115            caps.set (PARENT_MEMORY, parent_memory)
107116            caps.set (DATA, data)
108117            caps.set (PARENT, parent)
109            iocall (caps.copy (), CAP_MASTER_DIRECT | RUN_STRING, Iris::Num (num_slots, num_caps))
110            Iris::Caps ret = Iris::get_arg ()
111            Iris::my_memory.destroy (caps)
112            Iris::free_cap (caps)
118            iocall (caps.copy (), CAP_MASTER_DIRECT | RUN_STRING, Num (num_slots, num_caps))
119            Caps ret = get_arg ()
120            my_memory.destroy (caps)
121            free_cap (caps)
113122            return ret
114        Iris::Caps run_caps (Memory parent_memory, Caps data, Cap parent, unsigned pages, unsigned num_slots = 8, unsigned num_caps = 32):
115            Iris::Caps caps = Iris::my_memory.create_caps (3)
123        Caps run_caps (Memory parent_memory, Caps data, Cap parent, unsigned pages, unsigned num_slots = 8, unsigned num_caps = 32):
124            Caps caps = my_memory.create_caps (3)
116125            caps.set (PARENT_MEMORY, parent_memory)
117126            caps.set (DATA, data)
118127            caps.set (PARENT, parent)
119            iocall (caps.copy (), Iris::Num (CAP_MASTER_DIRECT | RUN_CAPS, pages), Iris::Num (num_slots, num_caps))
120            Iris::Caps ret = Iris::get_arg ()
121            Iris::my_memory.destroy (caps)
122            Iris::free_cap (caps)
128            iocall (caps.copy (), Num (CAP_MASTER_DIRECT | RUN_CAPS, pages), Num (num_slots, num_caps))
129            Caps ret = get_arg ()
130            my_memory.destroy (caps)
131            free_cap (caps)
123132            return ret
124133
125134    // Interface for talking to the parent process.
126    struct Parent : public Iris::Cap:
127        Parent (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
135    struct Parent : public Cap:
136        Parent (Cap c = Cap ()) : Cap (c):
128137        enum request:
129138            GET_CAPABILITY = Elfrun::ID
130139            PROVIDE_CAPABILITY
...... 
136145            ID
137146        // Get a handle.
138147        template <typename _T> _T get_capability (unsigned num = 0):
139            icall (Iris::Num (CAP_MASTER_DIRECT | GET_CAPABILITY, num), _T::ID)
140            return Iris::get_arg ()
148            icall (Num (CAP_MASTER_DIRECT | GET_CAPABILITY, num), _T::ID)
149            return get_arg ()
141150        // Provide a device handle.
142151        template <typename _T> void provide_capability (Cap cap, unsigned num = 0):
143            ocall (cap, Iris::Num (CAP_MASTER_DIRECT | PROVIDE_CAPABILITY, num), _T::ID)
152            ocall (cap, Num (CAP_MASTER_DIRECT | PROVIDE_CAPABILITY, num), _T::ID)
144153        // Wait until a device is used by the caller again.
145154        template <typename _T> void wait (unsigned num = 0):
146            call (Iris::Num (CAP_MASTER_DIRECT | WAIT, num), _T::ID)
155            call (Num (CAP_MASTER_DIRECT | WAIT, num), _T::ID)
147156        // Get memory paid for by another thread, which cannot be inspected or changed by that thread. The memory can be inspected and changed by the user (owning both threads). The call will fail when the threads are not owned by the same user.
148        Iris::Memory get_memory (Iris::Cap target):
157        Memory get_memory (Cap target):
149158            iocall (target, CAP_MASTER_DIRECT | GET_MEMORY)
150            return Iris::get_arg ()
159            return get_arg ()
151160        // Get a handle that another thread can use to call get_memory on. The actual limit on the created memory is floor(limit, thread address space limit).
152        Iris::Cap provide_memory (unsigned limit):
161        Cap provide_memory (unsigned limit):
153162            icall (CAP_MASTER_DIRECT | PROVIDE_MEMORY, limit)
154            return Iris::get_arg ()
163            return get_arg ()
155164        // Signal the parent that the initialisation phase is over.
156        void init_done (Iris::Num stage = 0):
165        void init_done (Num stage = 0):
157166            call (CAP_MASTER_DIRECT | INIT_DONE, stage)
158167        // Exit the program. The parent does not reply, but kills the process.
159        void exit (Iris::Num code):
168        void exit (Num code):
160169            call (CAP_MASTER_DIRECT | EXIT, code)
161170
162171    // Keyboard interface.
163    struct Keyboard : public Device:
164        Keyboard (Iris::Cap c = Iris::Cap ()) : Iris::Device (c):
172    struct Keyboard : public Event:
173        Keyboard (Cap c = Cap ()) : Event (c):
165174        enum request:
166            SET_CB = Parent::ID
167            GET_NUM_KEYS
175            GET_NUM_KEYS = Parent::ID
168176            GET_KEYS
169177            ID
170178        // At event: the callback is called with a keycode. One bit defines if it's a press or release event.
171179        enum constant:
172180            RELEASE = 1 << 31
173        // Set the event callback. Currently pressed keys emit a key press event to the new callback immediately.
174        void set_cb (Iris::Cap cb):
175            ocall (cb, CAP_MASTER_DIRECT | SET_CB)
176181        // Get the number of keys on the keyboard.
177182        unsigned get_num_keys ():
178183            return call (CAP_MASTER_DIRECT | GET_NUM_KEYS).l
...... 
182187
183188    // Buzzer interface.
184189    struct Buzzer : public Device:
185        Buzzer (Iris::Cap c = Iris::Cap ()) : Iris::Device (c):
190        Buzzer (Cap c = Cap ()) : Device (c):
186191        enum request:
187192            BEEP = Keyboard::ID
188193            STOP
189194            ID
190195        // Emit a beep of specified frequency, time and volume. Volume may not be supported. If an other beep is in progress, it is aborted.
191        void beep (unsigned freq, unsigned ms, unsigned volume, Iris::Cap cb = Iris::Cap ()):
192            ocall (cb, Iris::Num (CAP_MASTER_DIRECT | BEEP, volume), Iris::Num (freq, ms))
196        void beep (unsigned freq, unsigned ms, unsigned volume, Cap cb = Cap ()):
197            ocall (cb, Num (CAP_MASTER_DIRECT | BEEP, volume), Num (freq, ms))
193198        // Abort current beep, if any.
194199        void stop ():
195200            call (CAP_MASTER_DIRECT | STOP)
196201
197202    // Display interface.
198203    struct Display : public Device:
199        Display (Iris::Cap c = Iris::Cap ()) : Iris::Device (c):
204        Display (Cap c = Cap ()) : Device (c):
200205        enum request:
201206            SET_EOF_CB = Buzzer::ID
202207            MAP_FB
...... 
205210            ID
206211        // Register an end-of-frame callback.
207212        // At end of frame, the callback is invoked and forgotten. It must be reregistered to keep a stream of events.
208        void set_eof_cb (Iris::Cap cb):
213        void set_eof_cb (Cap cb):
209214            ocall (cb, CAP_MASTER_DIRECT | SET_EOF_CB)
210215        // Map the framebuffer into memory.
211        Iris::Caps map_fb (unsigned address, Iris::Memory mem = Iris::my_memory, bool use = true):
212            iocall (mem, Iris::Num (CAP_MASTER_DIRECT | MAP_FB, use ? 1 : 0), address)
213            return Iris::get_arg ()
214        void unmap_fb (Iris::Caps caps):
216        Caps map_fb (unsigned address, Memory mem = my_memory, bool use = true):
217            iocall (mem, Num (CAP_MASTER_DIRECT | MAP_FB, use ? 1 : 0), address)
218            return get_arg ()
219        void unmap_fb (Caps caps):
215220            ocall (caps, CAP_MASTER_DIRECT | UNMAP_FB)
216221        // Get information about the display.
217222        void get_info ():
218223            // TODO: Interface is to be designed.
219            Iris::panic (0, "using undefined interface Display::get_info ()")
224            panic (0, "using undefined interface Display::get_info ()")
220225
221226    // Numerical setting, such as a display backlight.
222    struct Setting : public Iris::Device:
223        Setting (Iris::Cap c = Iris::Cap ()) : Iris::Device (c):
227    struct Setting : public Device:
228        Setting (Cap c = Cap ()) : Device (c):
224229        enum request:
225230            SET = Display::ID
226231            GET_RANGE
...... 
238243    // Seekable is not a class, it is identical to [W]String.
239244
240245    // Directory interface.
241    struct Directory : public Iris::Cap:
242        Directory (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
246    struct Directory : public Cap:
247        Directory (Cap c = Cap ()) : Cap (c):
243248        enum request:
244249            GET_SIZE = Setting::ID
245250            GET_NAME
...... 
249254            UNLOCK_RO
250255            ID
251256        // Get the number of entries in this directory.
252        Iris::Num get_size ():
257        Num get_size ():
253258            return call (CAP_MASTER_DIRECT | GET_SIZE)
254259        // Get the filename.
255        String get_name (Iris::Num idx):
260        String get_name (Num idx):
256261            icall (CAP_MASTER_DIRECT | GET_NAME, idx)
257            return Iris::get_arg ()
262            return get_arg ()
258263        // Get the file.
259        Iris::Cap get_file_ro (Iris::Num idx):
264        Cap get_file_ro (Num idx):
260265            icall (CAP_MASTER_DIRECT | GET_FILE_RO, idx)
261            return Iris::get_arg ()
266            return get_arg ()
262267        // Get file info. TODO: define possible types.
263        Iris::Num get_file_info (Iris::Num idx, unsigned type):
264            return icall (Iris::Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx)
268        Num get_file_info (Num idx, unsigned type):
269            return icall (Num (CAP_MASTER_DIRECT | GET_FILE_INFO, type), idx)
265270        // Lock the directory for reading. Multiple read locks can exist simultaneously, but no write lock can be present.
266271        void lock_ro ():
267272            call (CAP_MASTER_DIRECT | LOCK_RO)
...... 
269274        void unlock_ro ():
270275            call (CAP_MASTER_DIRECT | UNLOCK_RO)
271276    struct WDirectory : public Directory:
272        WDirectory (Iris::Cap c = Iris::Cap ()) : Directory (c):
277        WDirectory (Cap c = Cap ()) : Directory (c):
273278        enum request:
274279            GET_FILE = Directory::ID
275280            CREATE_FILE
...... 
278283            UNLOCK
279284            ID
280285        // Get the file.
281        Iris::Cap get_file (Iris::Num idx):
286        Cap get_file (Num idx):
282287            icall (CAP_MASTER_DIRECT | GET_FILE, idx)
283            return Iris::get_arg ()
288            return get_arg ()
284289        // Create a new file. After this, any index may map to a different file.
285        Iris::Cap create_file (String name):
290        Cap create_file (String name):
286291            icall (CAP_MASTER_DIRECT | CREATE_FILE)
287            return Iris::get_arg ()
292            return get_arg ()
288293        // Delete a file. After this, any index may map to a different file.
289        void delete_file (Iris::Num idx):
294        void delete_file (Num idx):
290295            call (CAP_MASTER_DIRECT | DELETE_FILE, idx)
291296        // Lock the directory. Write operations can only be done when the directory is locked.
292297        void lock ():
...... 
297302
298303    // A filesystem turns a String into a Directory.
299304    struct Filesystem : public Device:
300        Filesystem (Iris::Cap c = Iris::Cap ()) : Device (c):
305        Filesystem (Cap c = Cap ()) : Device (c):
301306        enum request:
302307            USE_DEVICE = WDirectory::ID
303308            USE_DEVICE_RO
304309            ID
305310        WDirectory use_device (WString dev):
306311            ocall (dev, CAP_MASTER_DIRECT | USE_DEVICE)
307            return Iris::get_arg ()
312            return get_arg ()
308313        Directory use_device_ro (String dev):
309314            ocall (dev, CAP_MASTER_DIRECT | USE_DEVICE_RO)
310            return Iris::get_arg ()
315            return get_arg ()
311316
312317    // Stream interface.
313    struct Stream : public Iris::Cap:
314        Stream (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
318    struct Stream : public Cap:
319        Stream (Cap c = Cap ()) : Cap (c):
315320        enum request:
316321            READ = Filesystem::ID
317322            WRITE
318323            ID
319324        // Try to read size bytes. Returns the number of bytes successfully read.
320        Iris::Num read (Iris::Num size, bool block):
321            return icall (Iris::Num (CAP_MASTER_DIRECT | READ, block), size)
325        Num read (Num size, bool block):
326            return icall (Num (CAP_MASTER_DIRECT | READ, block), size)
322327        // Try to write size bytes. Returns the number of bytes successfully written.
323        Iris::Num write (String s, Iris::Num size):
328        Num write (String s, Num size):
324329            return ocall (s, CAP_MASTER_DIRECT | WRITE, size)
325330
326    struct UI : public Iris::Cap:
327        UI (Iris::Cap c = Iris::Cap ()) : Iris::Cap (c):
331    struct UI : public Cap:
332        UI (Cap c = Cap ()) : Cap (c):
328333        enum request:
329334            GET_STATE = Stream::ID
330335            EVENT
...... 
332337            ID
333338        enum constant:
334339            INPUT = 1 << 31
335        void get_state (Iris::Cap cap):
340        void get_state (Cap cap):
336341            ocall (cap, CAP_MASTER_DIRECT | GET_STATE)
337342        void event (unsigned code, unsigned value = 0):
338            call (Iris::Num (CAP_MASTER_DIRECT | EVENT, code), value)
343            call (Num (CAP_MASTER_DIRECT | EVENT, code), value)
339344        void exit ():
340345            call (CAP_MASTER_DIRECT | EXIT)
341346
342347    // Block device interface.
343348    struct Block_device : public WString:
344        Block_device (Iris::Cap c = Iris::Cap ()) : WString (c):
349        Block_device (Cap c = Cap ()) : WString (c):
345350        // TODO: to be designed.
346351
347352
init.config
55    driver driver_gpio = "gpio.elf"
66    program alarm = "alarm.elf"
77    program gui = "gui.elf"
8    #driver nand = "nand.elf"
9    driver sdmmc = "sd+mmc.elf"
810
911    # receive <name> / <type> [, <index>] = <cap> prepare to accept a capability from a named program.
1012    receive driver_lcd / Display = display
...... 
1214    receive driver_buzzer / Buzzer = buzzer
1315    receive driver_gpio / Keyboard , 0 = keyboard
1416    receive driver_gpio / Keyboard , 1 = sysreq
17    receive driver_gpio / Event = sdmmc_gpio
1518    receive alarm / UI = ui
19    receive sdmmc / WString = sdmmc
1620
1721    # sysreq <cap> use a capability as the system request keyboard.
1822    sysreq sysreq
...... 
2327    give gui / Setting = display_bright
2428    give gui / Buzzer = buzzer
2529    give gui / Keyboard = keyboard
30    give sdmmc / Event = sdmmc_gpio
2631
2732    # include <file> include a file as another config file.
2833
mips/nanonote/Makefile.arch
2727
2828arch_iris_sources = mips/interrupts.cc mips/arch.cc
2929boot_sources = mips/init.cc mips/nanonote/board.cc
30arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh devices.hh
30arch_headers = mips/arch.hh mips/nanonote/jz4740.hh mips/nanonote/board.hh
3131boot_threads = bootinit udc
32programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui
32programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui nand sd+mmc
3333
3434all: test
3535
mips/nanonote/board.ccp
4646    // Use some gpio pins for lcd.
4747    gpio_as_gpio (2, (1 << 21) | (1 << 22) | (1 << 23))
4848    gpio_as_output (2, (1 << 21) | (1 << 22) | (1 << 23))
49    // And some for sd/mmc.
50    gpio_as_gpio (3, (1 << 0) | (1 << 2))
51    gpio_as_output (3, 1 << 2)
52    gpio_as_input (3, 1 << 0)
53    gpio_disable_pull (3, (1 << 0) | (1 << 2))
54    // Disable power to sd/mmc by default.
55    gpio_set (3, 1 << 2)
4956    // Set up keyboard: this breaks uart receive.
5057    gpio_as_gpio (3, 0x05fc0000)
5158    // Set up timed interrupts.
mips/nanonote/jz4740.hhp
120120#define map_rtc() do { __map_io (RTC_PHYSICAL, RTC_BASE); } while (1)
121121#define map_gpio() do { __map_io (GPIO_PHYSICAL, GPIO_BASE); } while (0)
122122#define map_aic() do { __map_io (AIC_PHYSICAL, AIC_BASE); } while (0)
123#define map_msc() do { __map_io (MSC_PHYSICAL, MSC_BASE); } while (0)
123124#define map_uart0() do { __map_io (UART0_PHYSICAL, UART0_BASE); } while (0)
124125#define map_i2c() do { __map_io (I2C_PHYSICAL, I2C_BASE); } while (0)
125126#define map_ssi() do { __map_io (SSI_PHYSICAL, SSI_BASE); } while (0)
...... 
31403141#define msc_rd_rxfifo() ( MSC_RXFIFO )
31413142#define msc_wr_txfifo(v) ( MSC_TXFIFO = v )
31423143
3143static void msc_reset():
3144    MSC_STRPCL = MSC_STRPCL_RESET
3145    while MSC_STAT & MSC_STAT_IS_RESETTING:
3146
31473144#define msc_start_clk() (MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START)
31483145
3149#define msc_stop_clk() (MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP)
3150
31513146#define MMC_CLK 19169200
31523147#define SD_CLK 24576000
31533148
source/alarm.ccp
1212    ALARM
1313    NUM_OUTS
1414
15static UI <NUM_INS, NUM_OUTS> ui
16static UI <NUM_INS, NUM_OUTS>::in <unsigned> total_time
17static UI <NUM_INS, NUM_OUTS>::in_event do_start
18static UI <NUM_INS, NUM_OUTS>::out <unsigned> current_time
19static UI <NUM_INS, NUM_OUTS>::out_event do_alarm
15typedef UI <NUM_INS, NUM_OUTS> ui_t
16static ui_t ui
17static ui_t::in <unsigned> total_time
18static ui_t::in_event do_start
19static ui_t::out <unsigned> current_time
20static ui_t::out_event do_alarm
2021
2122static bool ticking
2223
...... 
5657        switch Iris::recv.protected_data.l:
5758            case ~0:
5859                // alarm.
59                current_time = current_time - 1
60                if current_time:
61                    current_time = current_time - 1
6062                if !current_time:
6163                    do_alarm ()
6264                    ticking = false
source/crt0.ccp
137137        Iris::recv.reply = Iris::alloc_cap ()
138138        Iris::recv.arg = Iris::alloc_cap ()
139139        Iris::Num ret = start ()
140        Iris::my_parent.invoke (~0, ret)
140        Iris::my_parent.exit (ret)
141141        Iris::my_memory.destroy (Iris::my_thread)
142142        // The program no longer exists. If it somehow does, generate an address fault.
143143        while true:
source/gui.ccp
2525static Iris::Display display
2626static Iris::Buzzer buzzer
2727static unsigned *framebuffer
28static unsigned alarming
2829
2930enum PD:
3031    UI
...... 
151152    draw_num (upper, 3, time / 10)
152153    draw_num (upper, 4, time % 10)
153154
154static void beep ():
155    buzzer.beep (4 * 440, 1000, ~0)
155static void do_alarm ():
156    static unsigned tune[] = { 4, 6, 6, 5, 7, 7 }
157    if ++alarming > sizeof (tune) / sizeof (*tune):
158        alarming = 1
159    buzzer.beep (tune[alarming - 1] * 220, 300, ~0)
160    Iris::my_receiver.set_alarm (HZ / 3)
156161
157162Iris::Num start ():
158163    Iris::my_parent.init_done ()
164
159165    display = Iris::my_parent.get_capability <Iris::Display> ()
160166    Iris::Setting bright = Iris::my_parent.get_capability <Iris::Setting> ()
161167    Iris::Keyboard keyboard = Iris::my_parent.get_capability <Iris::Keyboard> ()
162168    buzzer = Iris::my_parent.get_capability <Iris::Buzzer> ()
163169    Iris::UI app = Iris::my_parent.get_capability <Iris::UI> ()
164    Iris::Cap cb = Iris::my_receiver.create_capability (UI)
170
165171    framebuffer = (unsigned *)0x15000
166172    Iris::Caps fb = display.map_fb ((unsigned)framebuffer)
167    bright.set (bright.get_range ())
173
174    unsigned screen_max = bright.get_range ()
175    bright.set (0)
176    bool screen_on = false
177
178    Iris::Cap cb = Iris::my_receiver.create_capability (UI)
168179    app.get_state (cb.copy ())
169180    Iris::free_cap (cb)
181
170182    cb = Iris::my_receiver.create_capability (KBD)
171183    keyboard.set_cb (cb.copy ())
172184    Iris::free_cap (cb)
185
173186    draw_num (false, 2, 10)
174187    draw_num (true, 2, 10)
188
175189    unsigned total_time = 0
190    alarming = 0
176191    while true:
177192        Iris::wait ()
178193        switch Iris::recv.protected_data.l:
194            case ~0:
195                // Alarm.
196                if alarming:
197                    do_alarm ()
198                break
179199            case UI:
180200                switch Iris::recv.data[0].l:
181201                    case CURRENT_TIME:
182202                        draw_time (false, Iris::recv.data[1].l)
183203                        break
184204                    case ALARM:
185                        beep ()
205                        do_alarm ()
186206                        break
187207                    case TOTAL_TIME | Iris::UI::INPUT:
188208                        total_time = Iris::recv.data[1].l
...... 
194214            case KBD:
195215                if Iris::recv.data[0].l & Iris::Keyboard::RELEASE:
196216                    break
217                alarming = 0
197218                switch Iris::recv.data[0].l:
198219                    case Key::VOLUME_UP:
199220                        total_time += 60
...... 
236257                        break
237258                    case Key::ENTER:
238259                        app.event (START)
260                        break
261                    case Key::BACKSPACE:
262                        screen_on = !screen_on
263                        if screen_on:
264                            bright.set (screen_max)
265                        else:
266                            bright.set (0)
267                        break
source/init.ccp
269269    { "String", 6, Iris::String::ID },
270270    { "WString", 7, Iris::WString::ID },
271271    { "Device", 6, Iris::Device::ID },
272    { "Event", 5, Iris::Event::ID },
272273    { "Parent", 6, Iris::Parent::ID },
273274    { "Keyboard", 8, Iris::Keyboard::ID },
274275    { "Buzzer", 6, Iris::Buzzer::ID },
source/nand.ccp
1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// boot-programs/nand.ccp: NAND driver.
4// Copyright 2009 Bas Wijnen <wijnen@debian.org>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#include "devices.hh"
20#define ARCH
21#include "arch.hh"
22
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_READ1 1
28#define CMD_RNDOUT 5
29#define CMD_PAGEPROG 0x10
30#define CMD_READOOB 0x50
31#define CMD_ERASE1 0x60
32#define CMD_STATUS 0x70
33#define CMD_STATUS_MULTI 0x71
34#define CMD_SEQIN 0x80
35#define CMD_RNDIN 0x85
36#define CMD_READID 0x90
37#define CMD_ERASE2 0xd0
38#define CMD_RESET 0xff
39
40// Extended commands for large page devices
41#define CMD_READSTART 0x30
42#define CMD_RNDOUTSTART 0xE0
43#define CMD_CACHEDPROG 0x15
44
45// Extended commands for AG-AND device
46// Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but
47// there is no way to distinguish that from NAND_CMD_READ0
48// until the remaining sequence of commands has been completed
49// so add a high order bit and mask it off in the command.
50#define CMD_DEPLETE1 0x100
51#define CMD_DEPLETE2 0x38
52#define CMD_STATUS_MULTI 0x71
53#define CMD_STATUS_ERROR 0x72
54// multi-bank error status (banks 0-3)
55#define CMD_STATUS_ERROR0 0x73
56#define CMD_STATUS_ERROR1 0x74
57#define CMD_STATUS_ERROR2 0x75
58#define CMD_STATUS_ERROR3 0x76
59#define CMD_STATUS_RESET 0x7f
60#define CMD_STATUS_CLEAR 0xff
61
62#define CMD_NONE -1
63
64// Status bits
65#define STATUS_FAIL 0x01
66#define STATUS_FAIL_N1 0x02
67#define STATUS_TRUE_READY 0x20
68#define STATUS_READY 0x40
69#define STATUS_WP 0x80
70
71static volatile char *command
72static volatile char *address
73static volatile char *data
74
75static unsigned page_bits
76static unsigned redundant_bits
77static unsigned block_bits
78static unsigned word_size
79
80static void unbusy ():
81    while !(gpio_get_port (2) & (1 << 30)):
82        Iris::schedule ()
83
84static void reset ():
85    Iris::Page data_page = Iris::my_memory.create_page ()
86    Iris::Page command_page = Iris::my_memory.create_page ()
87    Iris::Page address_page = Iris::my_memory.create_page ()
88
89    unsigned base = 0x18000000
90    data_page.alloc_physical (base, false, false)
91    command_page.alloc_physical (base + 0x8000, false, false)
92    address_page.alloc_physical (base + 0x10000, false, false)
93
94    Iris::my_memory.map (data_page, (unsigned)data)
95    Iris::my_memory.map (command_page, (unsigned)command)
96    Iris::my_memory.map (address_page, (unsigned)address)
97
98    Iris::free_cap (data_page)
99    Iris::free_cap (command_page)
100    Iris::free_cap (address_page)
101
102    // Set up.
103    gpio_as_nand ()
104    EMC_NFCSR = EMC_NFCSR_NFE1 | EMC_NFCSR_NFCE1
105
106    // Reset nand.
107    *command = CMD_RESET
108    unbusy ()
109
110    *command = CMD_READID
111    *address = 0
112    unsigned d = *data
113    //unsigned maker = d
114    d = *data
115    //unsigned device = d
116    d = *data
117    //unsigned internal_chip_number = 1 << (d & 0x3)
118    //unsigned cell_type = 2 << ((d >> 2) & 0x3)
119    //unsigned simultaneously_programmed_pages = 1 << ((d >> 4) & 0x3)
120    //bool can_interleave_program_between_chips = d & 0x40
121    //bool can_cache_program = d & 0x80
122    d = *data
123    page_bits = 10 + (d & 3)
124    kdebug ("page bits: ")
125    kdebug_num (page_bits)
126    kdebug ("\n")
127    redundant_bits = (d & 4 ? 4 : 3)
128    block_bits = 64 + ((d >> 4) & 3)
129    word_size = (d & 0x40 ? 16 : 8)
130    //unsigned serial_access_minimum = (d & 0x80 ? 25 : 50)
131    d = *data
132    //unsigned num_planes = 1 << ((d >> 2) & 3)
133    //unsigned plane_bits = 26 + ((d >> 4) & 7)
134
135static void read (unsigned a, char *buffer):
136    unsigned column = a & ((1 << page_bits) - 1)
137    unsigned row = a >> page_bits
138    kdebug ("reading: ")
139    kdebug_num (a)
140    kdebug ("/")
141    kdebug_num (row)
142    kdebug ("/")
143    kdebug_num (column)
144    kdebug (": ")
145    *command = CMD_READ0
146    *address = column
147    *address = column >> 8
148    *address = row
149    *address = row >> 8
150    *address = row >> 16
151    *command = CMD_READSTART
152    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_ERST
153    // Wait for nand to be ready.
154    unbusy ()
155    for unsigned t = 0; t < 0x200; ++t:
156        buffer[t] = *data
157    char error[9]
158    unsigned errcol = (1 << page_bits) + (column >> 5)
159    *command = CMD_RNDOUT
160    *address = errcol
161    *address = errcol >> 8
162    *command = CMD_RNDOUTSTART
163    for unsigned t = 0; t < 9; ++t:
164        error[t] = *data
165    EMC_NFPAR (0) = ((unsigned *)error)[0]
166    EMC_NFPAR (1) = ((unsigned *)error)[1]
167    EMC_NFPAR (2) = error[9]
168    EMC_NFECR = EMC_NFECR_ECCE | EMC_NFECR_RS | EMC_NFECR_RS_DECODING | EMC_NFECR_PRDY
169    while !(EMC_NFINTS & EMC_NFINTS_DECF):
170        Iris::schedule ()
171    // delay...
172    //Iris::schedule ()
173    unsigned errs = (EMC_NFINTS & EMC_NFINTS_ERRCNT_MASK) >> EMC_NFINTS_ERRCNT_BIT
174
175Iris::Num start ():
176    for unsigned i = 0; i < 30; ++i:
177        Iris::schedule ()
178    map_emc ()
179    map_gpio ()
180
181    command = (volatile char *)0x15000
182    address = (volatile char *)0x16000
183    data = (volatile char *)0x17000
184
185    reset ()
186
187    char buffer[0x200]
188
189    // Send nand contents to serial port.
190    for unsigned a = 0; a < 0x4000; a += 0x200:
191        read (a, buffer)
192        //for unsigned s = 0; s < 0x10; ++s:
193            for unsigned t = 0; t < 0x10; ++t:
194                kdebug (" ")
195                kdebug_num (buffer[0 * 0x20 + t], 2)
196            kdebug ("\n")
197        //kdebug ("\n")
198    // Exit.
199    return 0
source/nanonote-gpio.ccp
165165    #endif
166166    }
167167
168class PowerButton:
168class Event:
169169    bool state, started
170    unsigned pin
170171    Iris::Cap cb
171172    public:
172173    void scan ():
173174        if !started:
174175            return
175        gpio_mask_irq (3, 1 << 29)
176        bool s = gpio_get_port (3) & (1 << 29)
176        gpio_mask_irq (3, 1 << pin)
177        bool s = gpio_get_port (3) & (1 << pin)
177178        if s != state:
178179            state = s
179180            cb.invoke (state ? Iris::Keyboard::RELEASE : 0)
180        gpio_as_interrupt (3, 1 << 29, !state, true)
181        gpio_unmask_irq (3, 1 << 29)
182    PowerButton ():
183        gpio_as_gpio (3, 29)
181        gpio_as_interrupt (3, 1 << pin, !state, true)
182        gpio_unmask_irq (3, 1 << pin)
183    Event (unsigned p):
184        pin = p
185        gpio_as_gpio (3, pin)
184186        state = true
185187        started = false
186188    void set_cb (Iris::Cap c):
...... 
195197enum codes:
196198    KBD_DEV = 32
197199    PWR
200    SDMMC
198201
199202Iris::Num start ():
200203    map_gpio ()
201204
202205    DevKbd kbd
203    PowerButton pwr
206    Event pwr (29)
207    Event sdmmc (0)
204208
205    Iris::Device dev = Iris::my_receiver.create_capability (KBD_DEV)
209    Iris::Keyboard dev = Iris::my_receiver.create_capability (KBD_DEV)
206210    Iris::Keyboard pw = Iris::my_receiver.create_capability (PWR)
211    Iris::Event sm = Iris::my_receiver.create_capability (SDMMC)
207212    Iris::my_parent.provide_capability <Iris::Keyboard> (dev.copy (), 0)
208213    Iris::my_parent.provide_capability <Iris::Keyboard> (pw.copy (), 1)
214    Iris::my_parent.provide_capability <Iris::Event> (sm.copy ())
209215    Iris::free_cap (dev)
210216    Iris::free_cap (pw)
217    Iris::free_cap (sm)
211218    Iris::my_parent.init_done ()
212219    if kbd.scanning ():
213220        Iris::my_receiver.set_alarm (SCAN_INTERVAL)
...... 
225232                // Interrupt.
226233                pwr.scan ()
227234                kbd.scan ()
235                sdmmc.scan ()
228236                if kbd.scanning ():
229237                    Iris::my_receiver.set_alarm (SCAN_INTERVAL)
230238                Iris::register_interrupt (IRQ_GPIO3)
...... 
235243                    case Iris::Device::RESET:
236244                        Iris::recv.reply.invoke ()
237245                        break
238                    case Iris::Keyboard::SET_CB:
246                    case Iris::Event::SET_CB:
239247                        Iris::Cap reply = Iris::get_reply ()
240248                        kbd.active (Iris::get_arg ())
241249                        reply.invoke ()
...... 
256264                    case Iris::Device::RESET:
257265                        Iris::recv.reply.invoke ()
258266                        break
259                    case Iris::Keyboard::SET_CB:
267                    case Iris::Event::SET_CB:
260268                        Iris::Cap reply = Iris::get_reply ()
261269                        pwr.set_cb (Iris::get_arg ())
262270                        reply.invoke ()
...... 
268276                        kdebug ("\n")
269277                        break
270278                break
279            case SDMMC:
280                switch Iris::recv.data[0].l:
281                    case Iris::Device::RESET:
282                        Iris::recv.reply.invoke ()
283                        break
284                    case Iris::Event::SET_CB:
285                        Iris::Cap reply = Iris::get_reply ()
286                        sdmmc.set_cb (Iris::get_arg ())
287                        reply.invoke ()
288                        Iris::free_cap (reply)
289                        break
290                    default:
291                        kdebug ("SdMmc gpio invalid request\n")
292                        kdebug_num (Iris::recv.data[0].l)
293                        kdebug ("\n")
294                        break
295                break
271296            default:
272297                kdebug ("keyboard unknown num: ")
273298                kdebug_num (Iris::recv.protected_data.h)
source/sd+mmc.ccp
1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// source/sd+mmc.ccp: sd+mmc driver.
4// Copyright 2009 Bas Wijnen <wijnen@debian.org>
5//
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19#include "devices.hh"
20#define ARCH
21#include "arch.hh"
22
23class Mmc:
24    static unsigned const PORT = 3
25    static unsigned const PIN = 2
26    bool check_sdio ()
27    void check_sdmem ()
28    void check_mmc ()
29    public:
30    void reset ()
31    void detect ()
32    void release ()
33    void interrupt ()
34
35void Mmc::reset ():
36    // Enable slow clock to msc.
37    CPM_MSCCDR = ~0
38    cpm_start_msc ()
39    // Enable msc pins.
40    gpio_as_msc ()
41    // Disable power to card.
42    gpio_as_gpio (PORT, 1 << PIN)
43    gpio_as_output (PORT, 1 << PIN)
44    gpio_disable_pull (PORT, 1 << PIN)
45    gpio_set (PORT, 1 << PIN)
46
47    // Stop the clock.
48    MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_STOP
49    while MSC_STAT & MSC_STAT_CLK_EN:
50        Iris::schedule ()
51
52    // Initialize registers.
53    MSC_CLKRT = MSC_CLKRT_CLK_RATE_DIV_128
54    MSC_RESTO = 64
55    MSC_RDTO = ~0
56    MSC_BLKLEN = 0x200
57    MSC_NOB = 0
58    MSC_IMASK = ~0
59    MSC_ARG = 0
60
61    // Reset controller and inserted devices.
62    MSC_STRPCL = MSC_STRPCL_RESET
63    while MSC_STAT & MSC_STAT_IS_RESETTING:
64        Iris::schedule ()
65
66    // Start the clock.
67    MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START
68    // Set cards, if any, to idle.
69    MSC_CMD = 0
70    MSC_CMDAT = MSC_CMDAT_RESPONSE_NONE
71    msc_start_op ()
72    while !msc_ireg_end_cmd_res ():
73        Iris::schedule ()
74    msc_ireg_clear_end_cmd_res ()
75
76    // Reset SDIO device, if any.
77    MSC_CMD = 52
78    MSC_ARG = 0x88000C08
79    MSC_CMDAT = MSC_CMDAT_RESPONSE_R5
80    msc_start_op ()
81    while !msc_ireg_end_cmd_res ():
82        Iris::schedule ()
83    msc_ireg_clear_end_cmd_res ()
84
85bool Mmc::check_sdio ():
86    // 2. Send CMD5 (IO_SEND_OP_CMD) to validate voltage.
87    // 3. If the response is correct and the number of IO functions > 0, then continue, else go to check SDMEM.
88    // 4. If C-bit in the response is ready (the initialization has finished), go to 6.
89    // 5. Send CMD5 (IO_SEND_OP_CMD) to validate voltage, then go to 4.
90    // 6. If memory-present-bit in the response is true, then it is a combo card (SDIO + Memory), else
91    // it is only a SDIO card.
92    // 7. If it is a combo card, go to check SDMEM to initialize the memory part.
93    // 8. Send CMD3 (SET_RELATIVE_ADDR) to let the card publish a RCA. The RCA is returned
94    // from the response.
95    // 9. If do not accept the new RCA, go to 8, else record the new RCA.
96    // 10. Go to check MMC, because we can assure that there is no SDMEM card.
97    return false
98
99void Mmc::check_sdmem ():
100    // 2. Send CMD55. Here the default RCA 0x0000 is used for CMD55.
101    // 3. If the response is correct (CMD55 has response), then continue, else go to check MMC.
102    // 4. Send ACMD41 (SD_SEND_OP_CMD) to validate voltage (the general OCR value is 0x00FF8000).
103    // 5. If the initialization has finished, go to 7. (The response is the OCR register and it includes a status information bit (bit [31]). This status bit is set if the card power up procedure has been finished. As long as the card is busy, the corresponding bit[31] is set to LOW.)
104    // 6. Send CMD55 and ACMD41 to validate voltage, and then go to 5.
105    // 7. Send CMD2 (ALL_SEND_CID) to get the card CID.
106    // 8. Send CMD3 (SET_RELATIVE_ADDR) to let card publish a RCA. The RCA is returned from the response.
107    // 9. If do not accept the new RCA, go to 8, else record the new RCA.
108    // 10. Go to check MMC.
109
110void Mmc::check_mmc ():
111    // 1. SEND CMD1 (SEND_OP_CMD) TO VALIDATE VOLTAGE (THE GENERAL OCR VALUE IS 0X00FF88000).
112    // 2. IF THE RESPONSE IS CORRECT, THEN CONTINUE, ELSE GOTO 9.
113    // 3. IF THE INITIALIZATION HAS FINISHED, GO TO 5. (THE RESPONSE IS THE OCR REGISTER AND IT INCLUDES A STATUS INFORMATION BIT (BIT [31]). THIS STATUS BIT IS SET IF THE CARD POWER UP PROCEDURE HAS BEEN FINISHED. AS LONG AS THE CARD IS BUSY, THE CORRESPONDING BIT[31] IS SET TO LOW.)
114    // 4. Send CMD1 (SEND_OP_CMD) to validate voltage, and then go to 3.
115    // 5. Send CMD2 (ALL_SEND_CID) to get the card CID.
116    // 6. If the response timeout occurs, goto 9.
117    // 7. Send CMD3 (SET_RELATIVE_ADDR) to assign the card a RCA.
118    // 8. If there are other MMC cards, then go to 5.
119
120void Mmc::detect ():
121    kdebug ("mmc detect\n")
122    gpio_clear (PORT, 1 << PIN)
123    if check_sdio ():
124        check_sdmem ()
125    check_mmc ()
126
127void Mmc::release ():
128    kdebug ("mmc release\n")
129    gpio_set (PORT, 1 << PIN)
130
131void Mmc::interrupt ():
132    kdebug ("mmc interrupt\n")
133
134
135enum types:
136    DETECT
137    REQUEST
138
139Iris::Num start ():
140    map_msc ()
141    map_gpio ()
142    map_cpm ()
143
144    Mmc mmc
145    mmc.reset ()
146
147    Iris::Event detect = Iris::my_parent.get_capability <Iris::Event> ()
148    Iris::Cap cap = Iris::my_receiver.create_capability (DETECT)
149    detect.set_cb (cap.copy ())
150    cap.invoke (~0)
151    Iris::free_cap (cap)
152
153    // Get a message from the queue. This is either the "there is no card" message, or the message we just sent.
154    Iris::wait ()
155    if Iris::recv.data[0].l != ~0:
156        // If it was "there is no card", the message we sent is still in the queue.
157        Iris::wait ()
158    else:
159        // Otherwise, there is a card.
160        mmc.detect ()
161
162    cap = Iris::my_receiver.create_capability (REQUEST)
163    Iris::my_parent.provide_capability <Iris::WString> (cap.copy ())
164    Iris::free_cap (cap)
165
166    Iris::my_parent.init_done ()
167
168    while true:
169        Iris::wait ()
170        switch Iris::recv.protected_data.l:
171            case DETECT:
172                if Iris::recv.data[0].l:
173                    mmc.detect ()
174                else:
175                    mmc.release ()
176                break
177            case IRQ_MSC:
178                mmc.interrupt ()
179                break
180            case REQUEST:
181                kdebug ("sd+mmc request\n")
182                break
183            default:
184                Iris::panic (0, "unexpected request source for sd+mmc")

Archive Download the corresponding diff file

Branches:
master



interactive