Date:2010-06-22 20:55:02 (13 years 6 months ago)
Author:Bas Wijnen
Commit:a277156a2ec891fa817af1a4ce49cd5a2535149d
Message:working fat reader

Files: .gitignore (1 diff)
devices.hhp (2 diffs)
iris.hhp (3 diffs)
mbr+fat.txt (1 diff)
mips/nanonote/Makefile.arch (3 diffs)
mips/nanonote/server/usb-server.ccp (1 diff)
mips/nanonote/threadlist-udc.S (1 diff)
source/bootinit.ccp (8 diffs)
source/buffer.ccp (1 diff)
source/elfrun.ccp (4 diffs)
source/fat.ccp (16 diffs)
source/init.ccp (5 diffs)
source/partition.ccp (5 diffs)
source/sd+mmc.ccp (7 diffs)
source/test.ccp (1 diff)
source/udc.ccp (5 diffs)

Change Details

.gitignore
2222mips/nanonote/server/missing
2323mips/nanonote/server/usb-server
2424fs/
25iris-sd.tar
devices.hhp
6060        /// Helper function for get_block.
6161        static Page _create_paying_page ():
6262            Page ret = my_memory.create_page ()
63            ret.set_flags (Page::PAYING, Page::PAYING)
63            ret.set_flags (Page::PAYING)
6464            return ret
6565        /// Get a block from the string; place it at offset on page. This need not be implemented for strings smaller than PAGE_SIZE. All arguments must be aligned.
6666        Cap get_block (Num idx, unsigned size = PAGE_SIZE, unsigned offset = 0, Page ret = _create_paying_page ()):
...... 
304304        void unlock ():
305305            call (CAP_MASTER_DIRECT | UNLOCK)
306306
307    // A filesystem turns a String into a Directory.
308    struct Filesystem : public Device:
309        Filesystem (Cap c = Cap ()) : Device (c):
310        enum request:
311            USE_DEVICE = WDirectory::ID
312            USE_DEVICE_RO
313            ID
314        WDirectory use_device (WString dev):
315            ocall (dev, CAP_MASTER_DIRECT | USE_DEVICE)
316            return get_arg ()
317        Directory use_device_ro (String dev):
318            ocall (dev, CAP_MASTER_DIRECT | USE_DEVICE_RO)
319            return get_arg ()
320
321307    // Stream interface.
322308    struct Stream : public Cap:
323309        Stream (Cap c = Cap ()) : Cap (c):
324310        enum request:
325            READ = Filesystem::ID
311            READ = Directory::ID
326312            WRITE
327313            ID
328314        // Try to read size bytes. Returns the number of bytes successfully read.
iris.hhp
375375            set_info (PC, pc)
376376        void set_sp (unsigned sp):
377377            set_info (SP, sp)
378        void set_flags (unsigned value, unsigned mask):
379            set_info (FLAGS, value, mask)
378        void set_flags (unsigned set, unsigned reset = 0):
379            set_info (FLAGS, set, set | reset)
380380        unsigned get_pc ():
381381            return get_info (PC)
382382        unsigned get_sp ():
...... 
384384        unsigned get_flags ():
385385            return get_info (FLAGS)
386386        void run (bool run = true):
387            set_flags (run ? RUNNING : 0, RUNNING)
387            set_flags (run ? RUNNING : 0, run ? 0 : RUNNING)
388388        void wait (bool wait):
389            set_flags (wait ? WAITING : 0, WAITING)
389            set_flags (wait ? WAITING : 0, wait ? 0 : WAITING)
390390        inline unsigned use (Caps caps, unsigned slot = alloc_slot ())
391391        inline Caps get_caps (unsigned slot)
392392        unsigned get_num_caps ():
...... 
461461            ocall (target, Num (CAP_MASTER_DIRECT | SHARE, flags))
462462        unsigned get_flags ():
463463            return call (CAP_MASTER_DIRECT | GET_FLAGS).l
464        bool set_flags (unsigned new_flags, unsigned mask):
465            call (CAP_MASTER_DIRECT | SET_FLAGS, Num (new_flags, mask))
464        bool set_flags (unsigned set, unsigned reset = 0):
465            call (CAP_MASTER_DIRECT | SET_FLAGS, Num (set, set | reset))
466466            return recv.data[0].l == NO_ERROR
467467        unsigned physical_address ():
468468            return my_thread.ocall (*this, CAP_MASTER_DIRECT | Thread::PRIV_PHYSICAL_ADDRESS).l
mbr+fat.txt
818101 a 5 unicode characters.
82820b 1 attribute: 000rsh0v.
83830c 1 0
840d 1 checksum
840d 1 checksum of short filename.
85850e c 6 unicode characters.
86861a 2 0
87871c 4 2 unicode characters.
8888
89checksum is name[0] rotated 11 times, name[1] 10 times, etc and all added up.
mips/nanonote/Makefile.arch
1818load = 0x80000000
1919UDC_BOOT=1
2020
21ARCH_CXXFLAGS = -DNUM_THREADS=2
2221ARCH_CPPFLAGS = -I. -Imips -Imips/nanonote -Wa,-mips32 -DNANONOTE -DUSE_SERIAL
2322CROSS = mipsel-linux-gnu-
2423OBJDUMP = $(CROSS)objdump
...... 
3231udc_boot_programs = udc
3332sd_boot_programs = sd+mmc partition fat
3433standard_boot_programs = bootinit
35ifdef UDC_BOOT
36    boot_threads = $(standard_boot_programs) $(udc_boot_programs)
37    threadlist = mips/nanonote/threadlist-udc
38    INIT_FLAGS = -DUDC_BOOT
39else
40    boot_threads = $(standard_boot_programs) $(sd_boot_programs)
41    threadlist = mips/nanonote/threadlist-sd
42    INIT_FLAGS = -DSD_BOOT
43endif
34
4435programs = init gpio lcd bsquare ball buzzer metronome elfrun alarm gui nand test $(udc_boot_programs) $(sd_boot_programs) $(standard_boot_programs)
4536
37ifdef UDC_BOOT
38boot_threads = $(standard_boot_programs) $(udc_boot_programs)
39threadlist = mips/nanonote/threadlist-udc
40ARCH_CXXFLAGS = -DNUM_THREADS=2
4641all: test
42else
43boot_threads = $(standard_boot_programs) $(sd_boot_programs)
44threadlist = mips/nanonote/threadlist-sd
45ARCH_CXXFLAGS = -DNUM_THREADS=4
46all: iris-sd.tar
47iris-sd.tar: $(addprefix fs/,$(addsuffix .elf,$(programs))) iris.raw init.config
48    mkimage -a $(load) -e a$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8') -n Iris -d iris.raw fs/uimage | sed -e 's/:/;/g'
49    cd fs && tar cvf ../$@ uimage init.config $(addsuffix .elf,$(programs)) --dereference
50endif
4751
4852test: iris.raw mips/nanonote/server/usb-server mips/nanonote/sdram-setup.raw $(addsuffix .elf,$(addprefix fs/,$(programs))) fs/init.config
4953    echo "reboot 0xa$(shell /bin/sh -c '$(OBJDUMP) -t iris.elf | grep __start$$ | cut -b2-8')" | nc localhost 5050
...... 
6670mips/nanonote/sdram-setup.elf: LDFLAGS = --omagic -T mips/nanonote/sdram-setup.ld
6771$(threadlist).o: $(addprefix fs/,$(addsuffix .elf,$(boot_threads)))
6872mips/boot.o: TARGET_FLAGS = -DMEMORY_SIZE="32 << 20"
69mips/init.o: TARGET_FLAGS = -I/usr/include $(INIT_FLAGS)
73mips/init.o: TARGET_FLAGS = -I/usr/include
7074source/bootinit.o: TARGET_FLAGS = -I/usr/include
7175source/elfrun.o: TARGET_FLAGS = -I/usr/include
7276source/gpio.ccp: source/nanonote-gpio.ccp
mips/nanonote/server/usb-server.ccp
322322    std::cerr << "\nSetting: " << Iris::Setting::ID
323323    std::cerr << "\nDirectory: " << Iris::Directory::ID
324324    std::cerr << "\nWDirectory: " << Iris::WDirectory::ID
325    std::cerr << "\nFilesystem: " << Iris::Filesystem::ID
326325    std::cerr << "\nStream: " << Iris::Stream::ID
327326    std::cerr << "\n"
328327
mips/nanonote/threadlist-udc.S
2121
2222    .balign 0x1000
2323thread0:
24    .incbin "bootinit.elf"
24    .incbin "fs/bootinit.elf"
2525
2626    .balign 0x1000
2727thread1:
28    .incbin "udc.elf"
28    .incbin "fs/udc.elf"
2929
3030    .balign 0x1000
3131thread2:
source/bootinit.ccp
11#pypp 0
22// Iris: micro-kernel for a capability-based operating system.
3// boot-programs/bootinit.ccp: Bootstrapping code.
4// Copyright 2009 Bas Wijnen <wijnen@debian.org>
3// source/bootinit.ccp: Bootstrapping code.
4// Copyright 2009-2010 Bas Wijnen <wijnen@debian.org>
55//
66// This program is free software: you can redistribute it and/or modify
77// it under the terms of the GNU General Public License as published by
...... 
2222
2323#define ELFRUN_NAME "elfrun.elf"
2424#define INIT_NAME "init.elf"
25
2526#define NUM_SLOTS 8
2627#define NUM_CAPS 32
2728
...... 
4546        unsigned pages = ((size - rest) + PAGE_SIZE - 1) >> PAGE_BITS
4647        for unsigned p = 0; p < pages; ++p:
4748            Iris::Page page = Iris::my_memory.create_page ()
48            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
49            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
4950            Iris::my_memory.map (page, _free + rest + (p << PAGE_BITS))
5051            Iris::free_cap (page)
5152    _free += size
...... 
6364
6465// Get the initial block device and filesystem.
6566static Iris::Directory receive_devices ():
66    Iris::String data
67    Iris::Filesystem fs
68    bool have_data = false, have_fs = false
69    for unsigned i = 0; i < 2; ++i:
67    Iris::String device
68    bool have_device = false
69    Iris::Cap reply[2]
70    bool have_reply[2]
71    have_reply[0] = false
72    have_reply[1] = false
73    unsigned next = 2
74    while true:
7075        Iris::wait ()
71        if Iris::recv.data[0].l != Iris::Parent::PROVIDE_CAPABILITY:
72            Iris::panic (Iris::recv.data[0].l, "Invalid bootstrap request.")
73        switch Iris::recv.data[1].l:
74            case Iris::String::ID:
75                if have_data:
76                    Iris::panic (0, "duplicate device.")
77                data = Iris::get_arg ()
78                Iris::recv.reply.invoke ()
79                have_data = true
76        kdebug_num (Iris::recv.protected_data.l, 1)
77        kdebug (": ")
78        if Iris::recv.protected_data.l == 0:
79            kdebug ("sd detect event device request\n")
80            // SD detection event device request.
81            // Ignore all; that will result in the driver thinking there is a card.
82            Iris::recv.reply.invoke ()
83            continue
84        switch Iris::recv.data[0].l:
85            case Iris::Parent::PROVIDE_CAPABILITY:
86                switch Iris::recv.data[1].l:
87                    case Iris::String::ID:
88                    case Iris::WString::ID:
89                        // Ignore other partitions.
90                        Iris::Cap r = Iris::get_reply ()
91                        if Iris::recv.data[0].h != 0:
92                            kdebug ("ignoring non-0 partition\n")
93                        else:
94                            if have_device:
95                                Iris::panic (0, "double device provided")
96                            device = Iris::get_arg ()
97                            if have_reply[next - 2]:
98                                kdebug ("string provided (used)\n")
99                                reply[next++ - 2].invoke (0, 0, device.copy ())
100                                Iris::free_cap (device)
101                            else:
102                                kdebug ("string provided (stored)\n")
103                                have_device = true
104                        r.invoke ()
105                        Iris::free_cap (r)
106                        break
107                    case Iris::Directory::ID:
108                        kdebug ("directory provided\n")
109                        Iris::Directory ret = Iris::get_arg ()
110                        Iris::recv.reply.invoke ()
111                        return ret
112                    default:
113                        Iris::panic (Iris::recv.data[1].l, "invalid capability type provided by boot thread")
80114                break
81            case Iris::Filesystem::ID:
82                if have_fs:
83                    Iris::panic (0, "duplicate filesystem.")
84                fs = Iris::get_arg ()
115            case Iris::Parent::GET_CAPABILITY:
116                if Iris::recv.data[1].l == Iris::Event::ID:
117                    kdebug ("event requested\n")
118                    // Detection of sd card.
119                    Iris::Cap reply = Iris::get_reply ()
120                    Iris::Cap event = Iris::my_receiver.create_capability (0)
121                    reply.invoke (0, 0, event.copy ())
122                    Iris::free_cap (event)
123                    Iris::free_cap (reply)
124                    break
125                if Iris::recv.data[1].l != Iris::String::ID && Iris::recv.data[1].l != Iris::WString::ID:
126                    Iris::panic (Iris::recv.data[1].l, "invalid capability type requested by boot thread")
127                if next == Iris::recv.protected_data.l && have_device:
128                    kdebug ("string requested (sent)\n")
129                    Iris::recv.reply.invoke (0, 0, device.copy ())
130                    Iris::free_cap (device)
131                    have_device = false
132                    ++next
133                else:
134                    kdebug ("string requested (not sent)\n")
135                    reply[Iris::recv.protected_data.l - 2] = Iris::get_reply ()
136                    have_reply[Iris::recv.protected_data.l - 2] = true
137                break
138            case Iris::Parent::INIT_DONE:
139                kdebug ("init done\n")
140                // Ignore.
85141                Iris::recv.reply.invoke ()
86                have_fs = true
87142                break
143            case Iris::Parent::EXIT:
144                Iris::panic (Iris::recv.protected_data.l, "boot thread exits")
88145            default:
89                Iris::panic (Iris::recv.data[1].l, "unexpected device")
90    // Initialize the root file system.
91    Iris::Directory root = fs.use_device_ro (data.copy ())
92    Iris::free_cap (data)
93    Iris::free_cap (fs)
94    return root
146                Iris::panic (Iris::recv.protected_data.l, "invalid boot request")
95147
96148static bool stringcmp (char const *s1, char const *s2, unsigned size):
97149    for unsigned t = 0; t < size; ++t:
...... 
137189        //kdebug ("\n")
138190        Iris::set_recv_arg (Iris::Cap (slot, p))
139191        Iris::my_memory.create_page ()
140        Iris::Page (slot, p).set_flags (Iris::Page::PAYING, Iris::Page::PAYING)
192        Iris::Page (slot, p).set_flags (Iris::Page::PAYING)
141193        data.get_block (p << PAGE_BITS, PAGE_SIZE, 0, Iris::Cap (slot, p))
142194        Iris::my_memory.map (Iris::Cap (slot, p), (unsigned)&mapping[p << PAGE_BITS])
143195    Iris::Thread thread = mem.create_thread (NUM_SLOTS)
...... 
190242                    f = Iris::Page::PAYING | Iris::Page::MAPPED_READONLY
191243                else:
192244                    f = Iris::Page::PAYING
193                page.set_flags (f, f)
245                page.set_flags (f)
194246                Iris::Page (slot, idx).share (page, 0)
195247                //kdebug ("mapping at ")
196248                //kdebug_num (p)
...... 
222274                    page = mem.create_page ()
223275                    if Iris::recv.data[0].l != Iris::NO_ERROR:
224276                        Iris::panic (Iris::recv.data[0].l, "out of memory")
225                    if !page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME):
277                    if !page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME):
226278                        Iris::panic (0, "out of memory")
227279                    if !mem.map (page, p):
228280                        Iris::panic (0, "unable to map bss page")
...... 
232284    Iris::my_memory.destroy (pages_caps)
233285    Iris::free_slot (slot)
234286    Iris::Page stackpage = mem.create_page ()
235    stackpage.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
287    stackpage.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
236288    if Iris::recv.data[0].l != Iris::NO_ERROR || !mem.map (stackpage, 0x7ffff000):
237289        Iris::panic (Iris::recv.data[0].l, "unable to map initial stack page")
238290    Iris::free_cap (stackpage)
source/buffer.ccp
1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// source/buffer.ccp: block device buffer.
4// Copyright 2010 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 "iris.hh"
20#include "devices.hh"
21
22static unsigned align
23static Iris::Page page, rpage
24static unsigned mapping, rmapping
25static Iris::Num size, current
26static Iris::String dev
27
28static void read_block (Iris::Num idx):
29    idx = idx.value () & PAGE_MASK
30    if idx.value () == current.value ():
31        return
32    //kdebug ("buffering block ")
33    //kdebug_num (idx.h)
34    //kdebug (":")
35    //kdebug_num (idx.l)
36    //kdebug ("\n")
37    dev.get_block (idx, PAGE_SIZE, 0, page)
38    //kdebug ("buffered\n")
39    current = idx
40
41Iris::Num start ():
42    dev = Iris::my_parent.get_capability <Iris::WString> ()
43    align = dev.get_align_bits ()
44    size = dev.get_size ()
45    if align > PAGE_BITS:
46        Iris::panic (align, "invalid alignment value for block device")
47    page = Iris::my_memory.create_page ()
48    rpage = Iris::my_memory.create_page ()
49    page.set_flags (Iris::Page::PAYING)
50    rpage.set_flags (Iris::Page::PAYING)
51    mapping = 0x15000
52    rmapping = 0x17000
53    Iris::my_memory.map (page, mapping)
54    Iris::my_memory.map (rpage, rmapping)
55    current.h = ~0
56    current.l = ~0
57    Iris::Cap cap = Iris::my_receiver.create_capability (0)
58    Iris::my_parent.provide_capability <Iris::WString> (cap.copy ())
59    Iris::free_cap (cap)
60    Iris::my_parent.init_done ()
61    while true:
62        Iris::wait ()
63        switch Iris::recv.data[0].l:
64            case Iris::String::GET_SIZE:
65                Iris::recv.reply.invoke (size)
66                break
67            case Iris::String::GET_ALIGN_BITS:
68                // Use 16 byte alignment to make implementing GET_CHARS easier.
69                Iris::recv.reply.invoke (4)
70                break
71            case Iris::String::GET_CHARS:
72                Iris::Cap reply = Iris::get_reply ()
73                unsigned offset = Iris::recv.data[1].l & ~PAGE_MASK & ~((1 << 4) - 1)
74                read_block (Iris::recv.data[1])
75                unsigned *data = (unsigned *)((char *)mapping)[offset]
76                reply.invoke (Iris::Num (data[0], data[1]), Iris::Num (data[2], data[3]))
77                Iris::free_cap (reply)
78                break
79            case Iris::String::GET_BLOCK:
80                Iris::Cap reply = Iris::get_reply ()
81                Iris::Page arg = Iris::get_arg ()
82                unsigned offset = Iris::recv.data[1].l & ~PAGE_MASK & ~((1 << 4) - 1)
83                unsigned sz = Iris::recv.data[0].h >> 16
84                unsigned roffset = Iris::recv.data[0].h & 0xffff
85                Iris::Num idx = Iris::recv.data[1]
86                arg.set_flags (Iris::Page::FRAME | Iris::Page::PAYING)
87                arg.share (rpage)
88                rpage.set_flags (Iris::Page::FRAME)
89                read_block (idx)
90                for unsigned i = 0; i < sz; ++i:
91                    ((char *)rmapping)[roffset + i] = ((char *)mapping)[offset + i]
92                rpage.set_flags (0, Iris::Page::FRAME)
93                reply.invoke ()
94                Iris::free_cap (reply)
95                Iris::free_cap (arg)
96                break
97            default:
98                Iris::panic (Iris::recv.data[0].l, "invalid request for buffer")
source/elfrun.ccp
4040        unsigned pages = ((size - rest) + PAGE_SIZE - 1) >> PAGE_BITS
4141        for unsigned p = 0; p < pages; ++p:
4242            Iris::Page page = Iris::my_memory.create_page ()
43            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
43            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
4444            Iris::my_memory.map (page, _free + rest + (p << PAGE_BITS))
4545            Iris::free_cap (page)
4646    _free += size
...... 
173173                    f = Iris::Page::PAYING | Iris::Page::MAPPED_READONLY
174174                else:
175175                    f = Iris::Page::PAYING
176                page.set_flags (f, f)
176                page.set_flags (f)
177177                Iris::Page (slot, idx).share (page, 0)
178178                //kdebug ("mapping at ")
179179                //kdebug_num (p)
...... 
210210                    page = mem.create_page ()
211211                    if Iris::recv.data[0].l != Iris::NO_ERROR:
212212                        Iris::panic (Iris::recv.data[0].l, "out of memory")
213                    if !page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME):
213                    if !page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME):
214214                        Iris::panic (0, "out of memory")
215215                    if !mem.map (page, p):
216216                        Iris::panic (0, "unable to map bss page")
...... 
229229    Iris::free_slot (slot)
230230    Iris::free_cap (pages_caps)
231231    Iris::Page stackpage = mem.create_page ()
232    stackpage.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
232    stackpage.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
233233    if Iris::recv.data[0].l != Iris::NO_ERROR || !mem.map (stackpage, 0x7ffff000):
234234        Iris::panic (Iris::recv.data[0].l, "unable to map initial stack page")
235235    Iris::free_cap (stackpage)
source/fat.ccp
2626        unsigned pages = ((size - rest) + PAGE_SIZE - 1) >> PAGE_BITS
2727        for unsigned p = 0; p < pages; ++p:
2828            Iris::Page page = Iris::my_memory.create_page ()
29            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
29            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
3030            Iris::my_memory.map (page, _free + rest + (p << PAGE_BITS))
3131            Iris::free_cap (page)
3232    _free += size
...... 
147147        return ret
148148
149149    void map_fat_cluster (unsigned c, unsigned offset = 0):
150        read_block ((hidden_sectors + reserved_sectors + ((c * bits + 8 * offset) >> (sector_size_bits + 3))) << sector_size_bits)
150        //unsigned b = current_block.l
151        read_block ((reserved_sectors + ((c * bits + 8 * offset) >> (sector_size_bits + 3))) << sector_size_bits)
152        //if b != current_block.l:
153            //for unsigned i = 0; i < 0x20; ++i:
154                //kdebug (" ")
155                //kdebug_num (data[i], 2)
156            //kdebug ("\n")
151157
152158    unsigned make_bits (unsigned orig):
153159        unsigned ret
154160        for ret = 0; ret < 32; ++ret:
155161            if orig == 1 << ret:
156162                return ret
157        Iris::panic (ret, "non-power of 2")
158        return ret
163        //Iris::panic (orig, "non-power of 2")
164        kdebug ("not a power of two, using 16\n")
165        return 16
159166
160167    void reset ():
161168        read_block (0)
...... 
182189            kdebug ("warning: limiting sectors because of limited device size\n")
183190
184191        root_sectors = (root_entries * 32 + (1 << sector_size_bits) - 1) >> sector_size_bits
185        header_sectors = hidden_sectors + reserved_sectors + sectors_per_fat * num_fats + root_sectors
192        header_sectors = reserved_sectors + sectors_per_fat * num_fats + root_sectors
186193        clusters = (sectors - header_sectors) >> sectors_per_cluster_bits
187194        unsigned skip
188195        if clusters >= 65525:
...... 
254261        bad_clusters = 0
255262        fat = new unsigned[clusters]
256263        unsigned counted_free_clusters = 0
264        first_free_cluster = ~0
257265        for unsigned c = 0; c < clusters; ++c:
258266            // reduced cluster.
259267            unsigned rc = c & (1 << sector_size_bits) - 1
...... 
288296            else if bits == 12 && fat[c] == 0xfff || bits == 16 && fat[c] == 0xffff || bits == 32 && fat[c] == 0xfffffff:
289297                // Last cluster in chain.
290298                fat[c] = ~0
299                kdebug ("last cluster: ")
300                kdebug_num (c)
301                kdebug ("\n")
291302            else if bits == 12 && fat[c] == 0xff7 || bits == 16 && fat[c] == 0xfff7 || bits == 32 && fat[c] == 0xffffff7:
292303                // Bad cluster.
293304                fat[c] = first_bad_cluster
...... 
296307            else:
297308                // Non-last cluster in chain.
298309                fat[c] -= 2
310                kdebug_num (c)
311                kdebug (" -> ")
312                kdebug_num (fat[c])
313                kdebug ("\n")
299314    unsigned fat_lookup (unsigned first_cluster, unsigned cluster):
315        //kdebug ("looking up ")
316        //kdebug_num (first_cluster)
317        //kdebug ("+")
318        //kdebug_num (cluster)
319        //kdebug (":")
300320        while cluster--:
301321            first_cluster = fat[first_cluster]
322            //kdebug ("->")
323            //kdebug_num (first_cluster)
302324            if first_cluster == ~0:
303                kdebug ("sector beyond end of file requested\n")
325                //kdebug ("sector beyond end of file requested\n")
304326                return ~0
327        //kdebug ("\n")
305328        return first_cluster
306329    struct File:
307330        Fat *fat
...... 
310333        char name[11]
311334        bool archive, readonly, system, hidden, directory, volume
312335        unsigned create_second, create_minute_hour, create_date, access_date, time, date
336        unsigned checksum
313337        void load_cluster (unsigned idx, Iris::Page p = page, unsigned offset = 0):
314338            unsigned cluster = fat->fat_lookup (first_cluster, idx >> fat->cluster_size_bits)
315            kdebug ("loading cluster ")
316            kdebug_num (idx)
317            kdebug ("@")
318            kdebug_num (cluster)
319            kdebug (" from file\n")
339            //kdebug ("loading cluster ")
340            //kdebug_num (idx)
341            //kdebug ("@")
342            //kdebug_num (cluster)
343            //kdebug (" from file\n")
320344            if cluster == ~0:
321345                kdebug ("invalid cluster requested from file\n")
322346                return
323347            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)
324            kdebug ("sector ")
325            kdebug_num (fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits))
326            kdebug ("\n")
327    void get_dir_entry (unsigned dir, unsigned idx, File *f):
328        f->fat = this
348            //kdebug ("sector ")
349            //kdebug_num (fat->header_sectors + (Iris::Num (cluster).value () << fat->sectors_per_cluster_bits))
350            //kdebug ("\n")
351    char *load_dir_entry (unsigned dir, unsigned idx):
329352        unsigned sector = idx >> (sector_size_bits - 5)
330353        unsigned num = (idx << 5) & ~BLOCK_MASK
331354        Iris::Num hwsector
...... 
333356            if sector < root_sectors:
334357                hwsector = header_sectors - root_sectors + sector
335358            else:
336                hwsector = ~0
359                return NULL
337360        else:
338361            unsigned entry = fat_lookup (dir, sector)
339362            if entry == ~0:
340                hwsector = ~0
341            else:
342                hwsector = header_sectors + (Iris::Num (entry).value () << sectors_per_cluster_bits)
343        if hwsector.value () == ~0:
344            kdebug ("invalid sector requested from directory\n")
345            f->first_cluster = ~0
346            return
363                return NULL
364            hwsector = header_sectors + (Iris::Num (entry).value () << sectors_per_cluster_bits)
347365        read_block (hwsector.value () << sector_size_bits)
348        char *e = &data[num]
366        return &data[num]
367    char *find_idx (unsigned dir, unsigned *idx, unsigned *count = NULL):
368        unsigned todo = *idx + 1
369        char *e
370        if count:
371            *count = 0
372        for *idx = 0; todo; ++*idx:
373            e = load_dir_entry (dir, *idx)
374            if !e:
375                return NULL
376            if (e[0xb] & 0xff) == 0xf:
377                // This is part of a long filename.
378                continue
379            if (e[0] & 0xff) == 0xe5:
380                // This is a deleted file.
381                continue
382            if !e[0]:
383                // This is a free entry.
384                continue
385            if count:
386                ++*count
387            --todo
388        --*idx
389        return e
390    unsigned get_dir_size (unsigned dir):
391        unsigned num = 0 - 2
392        unsigned ret
393        find_idx (dir, &num, &ret)
394        return ret
395    bool get_dir_entry (unsigned dir, unsigned idx, File *f):
396        char *e = load_dir_entry (dir, idx)
397        if !e:
398            kdebug ("unable to load dir entry\n")
399            return false
400        f->fat = this
349401        for unsigned i = 0; i < 11; ++i:
350402            f->name[i] = e[i]
351        f->archive = e[0xb] & 0x20
352        f->readonly = e[0xb] & 0x10
353        f->system = e[0xb] & 0x8
403        f->readonly = e[0xb] & 0x1
404        f->system = e[0xb] & 0x2
354405        f->hidden = e[0xb] & 0x4
355        f->directory = e[0xb] & 0x2
356        f->volume = e[0xb] & 0x1
406        f->volume = e[0xb] & 0x8
407        f->directory = e[0xb] & 0x10
408        f->archive = e[0xb] & 0x20
357409        f->create_second = read_num (e + 0xd, 1)
358410        f->create_minute_hour = read_num (e + 0xe, 2)
359411        f->create_date = read_num (e + 0x10, 2)
...... 
362414        f->date = read_num (e + 0x18, 1)
363415        f->size = read_num (e + 0x1c, 4)
364416        f->first_cluster = (read_num (e + 0x14, 2) << 16 | read_num (e + 0x1a, 2)) - 2
417        f->checksum = 0
418        for unsigned i = 0; i < 11; ++i:
419            f->checksum = ((((f->checksum & 1) << 7) | ((f->checksum & 0xfe) >> 1)) + f->name[i]) & 0xff
420        //kdebug ("loaded dir entry, first cluster = ")
421        //kdebug_num (f->first_cluster)
422        //kdebug ("\n")
423        return true
424    struct LFN:
425        unsigned ordinal
426        unsigned name[13]
427        unsigned checksum
428    bool load_lfn (unsigned dir, unsigned idx, unsigned t, unsigned checksum, LFN *lfn):
429        if t >= idx:
430            return false
431        char *e = load_dir_entry (dir, idx - t - 1)
432        if (e[0xb] & 0xff) != 0xf:
433            return false
434        lfn->ordinal = read_num (e + 0x00, 1)
435        for unsigned i = 0; i < 5; ++i:
436            lfn->name[i] = read_num (e + 0x01 + 2 * i, 2)
437        lfn->checksum = read_num (e + 0xd, 1)
438        for unsigned i = 0; i < 6; ++i:
439            lfn->name[i + 5] = read_num (e + 0xe + 2 * i, 2)
440        for unsigned i = 0; i < 2; ++i:
441            lfn->name[i + 11] = read_num (e + 0x1c + 2 * i, 2)
442        return true
443    unsigned parse_shortname (File const &f, char *name):
444        if f.name[0] == ' ':
445            Iris::panic (0, "fat name starts with space")
446        unsigned len = 8
447        while f.name[len - 1] == ' ':
448            --len
449        char *ptr = name
450        for unsigned i = 0; i < len; ++i:
451            *ptr++ = f.name[i]
452        if f.name[8] == ' ':
453            return len
454        *ptr++ = '.'
455        len = 3
456        while f.name[8 + len - 1] == ' ':
457            --len
458        for unsigned i = 0; i < len; ++i:
459            *ptr++ = f.name[8 + i]
460        return ptr - name
461    unsigned get_name_size (unsigned dir, unsigned idx, File const &f):
462        LFN lfn
463        unsigned num = 0
464        if !load_lfn (dir, idx, 0, f.checksum, &lfn):
465            // Not a long filename.
466            char n[12]
467            return parse_shortname (f, n)
468        unsigned ordinal = 0
469        while true:
470            if !load_lfn (dir, idx, num, f.checksum, &lfn):
471                Iris::panic (0, "error parsing long filename")
472            if (lfn.ordinal & 0x3f) != ++ordinal:
473                Iris::panic (lfn.ordinal, "error in sequence for long filename")
474            if lfn.ordinal & 0x40:
475                break
476            ++num
477        unsigned i
478        for i = 0; i < 13; ++i:
479            if !lfn.name[i]:
480                break
481        return num * 13 + i
365482
366483// Capability encoding.
367484// 0:ROOT_CLUSTER = non fat-32 root directory.
...... 
379496    device_size = dev.get_size ()
380497    data = (char *)0x15000; //alloc_space (1)
381498    page = Iris::my_memory.create_page ()
382    page.set_flags (Iris::Page::PAYING, Iris::Page::PAYING)
499    page.set_flags (Iris::Page::PAYING)
383500    Iris::my_memory.map (page, (unsigned)data)
384501
385502    Fat fat
...... 
400517        Iris::wait ()
401518        unsigned dir = Iris::recv.protected_data.h
402519        if dir & 0x80000000:
520            dir &= ~0x80000000
403521            // File name.
404522            unsigned idx = Iris::recv.protected_data.l
405523            Iris::Cap reply = Iris::get_reply ()
...... 
407525            unsigned size = Iris::recv.data[0].h >> 16
408526            unsigned cmd = Iris::recv.data[0].l
409527            Fat::File f
410            fat.get_dir_entry (dir & ~0x80000000, idx, &f)
528            if !fat.find_idx (dir, &idx):
529                Iris::panic (Iris::recv.protected_data.l, "invalid index")
530            if !fat.get_dir_entry (dir, idx, &f):
531                Iris::panic (Iris::recv.protected_data.l, "invalid dir entry requested for filename")
411532            switch cmd:
412533                case Iris::String::GET_SIZE:
413                    kdebug ("filename size requested\n")
414                    reply.invoke (11)
534                    //kdebug ("filename size requested\n")
535                    reply.invoke (fat.get_name_size (dir, idx, f))
415536                    break
416537                case Iris::String::GET_CHARS:
417538                    //kdebug ("filename chars requested\n")
539                    //kdebug ("flags: ")
540                    //kdebug_char (f.readonly ? 'R' : 'r')
541                    //kdebug_char (f.system ? 'S' : 's')
542                    //kdebug_char (f.hidden ? 'H' : 'h')
543                    //kdebug_char (f.volume ? 'V' : 'v')
544                    //kdebug_char (f.directory ? 'D' : 'd')
545                    //kdebug_char (f.archive ? 'A' : 'a')
546                    //kdebug_char ('\n')
547
418548                    /**/union { unsigned u[4]; char c[16]; } u
419549                    for unsigned k = 0; k < 4; ++k:
420550                        u.u[k] = 0
421                    for unsigned k = 0; k + num < 11; ++k:
422                        u.c[k] = f.name[k + num]
551                    Fat::LFN lfn
552                    if !fat.load_lfn (dir, idx, 0, f.checksum, &lfn):
553                        // Not a long filename.
554                        char n[12]
555                        unsigned len = fat.parse_shortname (f, n)
556                        //kdebug ("short filename: ")
557                        for unsigned k = 0; k + num < len; ++k:
558                            u.c[k] = n[k + num]
559                            //kdebug_char (u.c[k])
560                        //kdebug ("\n")
561                    else:
562                        // Very inefficient, but it works: reload everything for every character.
563                        //kdebug ("filename: ")
564                        for unsigned c = 0; c < 16; ++c:
565                            if !fat.load_lfn (dir, idx, (num + c) / 13, f.checksum, &lfn):
566                                // Filename isn't this long: keep the rest at 0.
567                                break
568                            u.c[c] = lfn.name[(num + c) % 13]
569                            if u.c[c] == 0:
570                                break
571                            //kdebug_char (u.c[c])
572                        //kdebug ("\n")
423573                    reply.invoke (Iris::Num (u.u[0], u.u[1]), Iris::Num (u.u[2], u.u[3]))
424574                    break
425575                case Iris::String::GET_ALIGN_BITS:
426                    kdebug ("filename align requested\n")
576                    //kdebug ("filename align requested\n")
427577                    reply.invoke (0)
428578                    break
429579                case Iris::String::GET_BLOCK:
...... 
431581                    Iris::panic (Iris::recv.data[0].l, "invalid request for fat filename")
432582            Iris::free_cap (reply)
433583        else if dir:
434            // File.
584            // If it *has* a directory, it *is* a file.
435585            unsigned idx = Iris::recv.protected_data.l
436586            Iris::Cap reply = Iris::get_reply ()
437587            Iris::Cap arg = Iris::get_arg ()
...... 
439589            unsigned size = Iris::recv.data[0].h >> 16
440590            unsigned offset = Iris::recv.data[0].h & 0xffff
441591            unsigned cmd = Iris::recv.data[0].l
592            if !fat.find_idx (dir, &idx):
593                Iris::panic (0, "file not found")
442594            Fat::File f
443595            fat.get_dir_entry (dir, idx, &f)
444596            switch cmd:
445597                case Iris::String::GET_SIZE:
446                    kdebug ("file size requested\n")
598                    //kdebug ("file size requested\n")
447599                    reply.invoke (f.size)
448600                    break
449601                case Iris::String::GET_CHARS:
450                    kdebug ("file chars requested\n")
602                    //kdebug ("file chars requested\n")
451603                    unsigned mask = 1 << (fat.cluster_size_bits) - 1
452604                    f.load_cluster (num.l & ~mask)
453605                    unsigned n = num.l & mask & ~0xf
...... 
455607                    reply.invoke (Iris::Num (dat[0], dat[1]), Iris::Num (dat[2], dat[3]))
456608                    break
457609                case Iris::String::GET_ALIGN_BITS:
458                    kdebug ("file align requested\n")
610                    //kdebug ("file align requested\n")
459611                    reply.invoke (fat.cluster_size_bits)
460612                    break
461613                case Iris::String::GET_BLOCK:
462                    kdebug ("file block requested\n")
614                    //kdebug ("file block requested\n")
463615                    unsigned mask = 1 << (fat.cluster_size_bits) - 1
464616                    if offset > PAGE_SIZE:
465                        kdebug ("invalid offset requested\n")
617                        //kdebug ("invalid offset requested\n")
466618                        break
467619                    if size + offset > PAGE_SIZE:
468620                        size = PAGE_SIZE - offset
...... 
480632            Iris::free_cap (arg)
481633        else:
482634            // Directory.
483            if Iris::recv.protected_data.l != ROOT_CLUSTER:
484                // Normal directory.
485                switch Iris::recv.data[0].l:
486                    case Iris::Directory::GET_SIZE:
487                        kdebug ("dir size requested\n")
488                        Iris::recv.reply.invoke ()
489                        break
490                    case Iris::Directory::GET_NAME:
491                        kdebug ("dir name requested\n")
492                        Iris::recv.reply.invoke ()
493                        break
494                    case Iris::Directory::GET_FILE_RO:
495                        kdebug ("dir file requested\n")
496                        Iris::Cap reply = Iris::get_reply ()
497                        Iris::Cap ret = Iris::my_receiver.create_capability (Iris::Num (Iris::recv.data[1].l, Iris::recv.protected_data.l))
498                        reply.invoke (0, 0, ret.copy ())
499                        Iris::free_cap (reply)
500                        Iris::free_cap (ret)
501                        break
502                    case Iris::Directory::GET_FILE_INFO:
503                        kdebug ("dir file info requested\n")
504                        Iris::recv.reply.invoke ()
505                        break
506                    case Iris::Directory::LOCK_RO:
507                    case Iris::Directory::UNLOCK_RO:
508                        kdebug ("dir lock or unlock requested\n")
509                        Iris::recv.reply.invoke ()
510                        break
511                    default:
512                        kdebug ("invalid dir operation requested\n")
513                        Iris::recv.reply.invoke ()
514                        break
515            else:
516                // Non-fat32 root directory.
517                switch Iris::recv.data[0].l:
518                    case Iris::Directory::GET_SIZE:
519                        kdebug ("root size requested\n")
520                        Iris::recv.reply.invoke (fat.root_entries)
521                        break
522                    case Iris::Directory::GET_NAME:
523                        //kdebug ("root name requested\n")
524                        Iris::Cap reply = Iris::get_reply ()
525                        Iris::Cap ret = Iris::my_receiver.create_capability (Iris::Num (Iris::recv.data[1].l, Iris::recv.protected_data.l | 0x80000000))
526                        reply.invoke (0, 0, ret.copy ())
527                        Iris::free_cap (reply)
528                        Iris::free_cap (ret)
529                        break
530                    case Iris::Directory::GET_FILE_RO:
531                        kdebug ("root file requested\n")
532                        Iris::Cap reply = Iris::get_reply ()
533                        Iris::Cap ret = Iris::my_receiver.create_capability (Iris::Num (Iris::recv.data[1].l, Iris::recv.protected_data.l))
534                        reply.invoke (0, 0, ret.copy ())
535                        Iris::free_cap (reply)
536                        Iris::free_cap (ret)
537                        break
538                    case Iris::Directory::GET_FILE_INFO:
539                        kdebug ("root file info requested\n")
540                        Iris::recv.reply.invoke ()
541                        break
542                    case Iris::Directory::LOCK_RO:
543                    case Iris::Directory::UNLOCK_RO:
544                        kdebug ("root lock or unlock requested\n")
545                        Iris::recv.reply.invoke ()
546                        break
547                    default:
548                        kdebug ("invalid root operation requested\n")
549                        Iris::recv.reply.invoke ()
550                        break
635            switch Iris::recv.data[0].l:
636                case Iris::Directory::GET_SIZE:
637                    //kdebug ("dir size requested\n")
638                    Iris::Cap reply = Iris::get_reply ()
639                    reply.invoke (fat.get_dir_size (Iris::recv.protected_data.l))
640                    Iris::free_cap (reply)
641                    break
642                case Iris::Directory::GET_NAME:
643                    //kdebug ("dir name requested\n")
644                    Iris::Cap reply = Iris::get_reply ()
645                    Iris::Cap ret = Iris::my_receiver.create_capability (Iris::Num (Iris::recv.data[1].l, Iris::recv.protected_data.l | 0x80000000))
646                    reply.invoke (0, 0, ret.copy ())
647                    Iris::free_cap (reply)
648                    Iris::free_cap (ret)
649                    break
650                case Iris::Directory::GET_FILE_RO:
651                    //kdebug ("dir file requested\n")
652                    Iris::Cap reply = Iris::get_reply ()
653                    dir = Iris::recv.protected_data.l
654                    unsigned idx = Iris::recv.data[1].l
655                    if !fat.find_idx (dir, &idx):
656                        Iris::panic (0, "file not found")
657                    Fat::File f
658                    fat.get_dir_entry (dir, idx, &f)
659                    Iris::Cap ret
660                    if f.directory:
661                        ret = Iris::my_receiver.create_capability (Iris::Num (f.first_cluster, 0))
662                    else:
663                        ret = Iris::my_receiver.create_capability (Iris::Num (idx, dir))
664                    reply.invoke (0, 0, ret.copy ())
665                    Iris::free_cap (reply)
666                    Iris::free_cap (ret)
667                    break
668                case Iris::Directory::GET_FILE_INFO:
669                    //kdebug ("dir file info requested\n")
670                    Iris::Cap reply = Iris::get_reply ()
671                    dir = Iris::recv.protected_data.l
672                    unsigned idx = Iris::recv.data[1].l
673                    if !fat.find_idx (dir, &idx):
674                        Iris::panic (0, "file not found")
675                    unsigned type = Iris::recv.data[0].h
676                    Fat::File f
677                    fat.get_dir_entry (dir, idx, &f)
678                    reply.invoke (f.directory ? 1 : 0)
679                    Iris::free_cap (reply)
680                    break
681                case Iris::Directory::LOCK_RO:
682                case Iris::Directory::UNLOCK_RO:
683                    //kdebug ("dir lock or unlock requested\n")
684                    Iris::recv.reply.invoke ()
685                    break
686                default:
687                    //kdebug ("invalid dir operation requested\n")
688                    Iris::recv.reply.invoke ()
689                    break
source/init.ccp
2020#include "iris.hh"
2121#include "keys.hh"
2222
23#define INIT_CONFIG "init.config"
24#define INIT_CONFIG_SIZE 12
25
2326#define NUM_SLOTS 8
2427#define NUM_CAPS 32
2528
...... 
4548        unsigned pages = ((size - rest) + PAGE_SIZE - 1) >> PAGE_BITS
4649        for unsigned p = 0; p < pages; ++p:
4750            Iris::Page page = Iris::my_memory.create_page ()
48            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
51            page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
4952            Iris::my_memory.map (page, _free + rest + (p << PAGE_BITS))
5053            Iris::free_cap (page)
5154    _free += size
...... 
277280    { "Setting", 7, Iris::Setting::ID },
278281    { "Directory", 9, Iris::Directory::ID },
279282    { "WDirectory", 10, Iris::WDirectory::ID },
280    { "Filesystem", 10, Iris::Filesystem::ID },
281283    { "Stream", 6, Iris::Stream::ID },
282284    { "UI", 2, Iris::UI::ID },
283285    { NULL, 0, 0 }
...... 
434436        char *name = get_filename (line, maxlen, name_len)
435437        include (name, name_len)
436438    else:
439        for unsigned i = 0; i < maxlen; ++i:
440            kdebug_char (start[i])
441        kdebug_char ('\n')
437442        Iris::panic (0, "invalid line in init.config")
438443    delspace (start, maxlen)
439444    if maxlen:
...... 
450455    elfrun = Iris::my_parent.get_capability <Iris::Elfrun> ()
451456    sysreq = NULL
452457    top_memory = Iris::get_top_memory ()
453    include ("init.config", 12)
458    include (INIT_CONFIG, INIT_CONFIG_SIZE)
454459    kdebug ("killing boot threads\n")
455460    Iris::my_parent.init_done ()
456461    for List <Program>::Item *p = programs.begin (); p; p = p->next:
source/partition.ccp
66#define SECTOR_BITS 9
77#define BLOCK_MASK (~((1 << SECTOR_BITS) - 1))
88
9unsigned bits
10
911struct Partition:
1012    static Iris::Num device_size
1113    unsigned lba_start, lba_size
...... 
2830        lba_size = read_num (data + 12)
2931        start = Iris::Num (lba_start).value () << SECTOR_BITS
3032        size = Iris::Num (lba_size).value () << SECTOR_BITS
31        //kdebug ("Partition read: ")
32        //kdebug_num (lba_start)
33        //kdebug ("+")
34        //kdebug_num (lba_size)
35        //kdebug ("\n")
33        kdebug ("Partition read: ")
34        kdebug_num (lba_start)
35        kdebug ("+")
36        kdebug_num (lba_size)
37        kdebug ("\n")
3638
3739Iris::Num Partition::device_size
3840
3941static Iris::WString dev
40static void read_block (Iris::Num idx, Iris::Page page, unsigned size = 1 << SECTOR_BITS, unsigned offset = 0):
41    idx = idx.value () >> SECTOR_BITS
42static void read_sector (Iris::Num idx, Iris::Page page, unsigned size = 1 << SECTOR_BITS, unsigned offset = 0):
4243    offset &= ~PAGE_MASK
4344    if size + offset > PAGE_SIZE:
4445        size = PAGE_SIZE - offset
4546    size >>= SECTOR_BITS
47    idx = idx.value () >> SECTOR_BITS
4648    for unsigned i = 0; i < size; ++i:
4749        dev.get_block ((idx.value () + i) << SECTOR_BITS, 1 << SECTOR_BITS, (i << SECTOR_BITS) + offset, page)
4850
4951Iris::Num start ():
5052    Partition::device_size = 0
5153    dev = Iris::my_parent.get_capability <Iris::WString> ()
52    if dev.get_align_bits () > SECTOR_BITS:
53        kdebug ("partitioned device doesn't support 512 byte access")
54        return 1
54    bits = dev.get_align_bits ()
55    if bits > SECTOR_BITS:
56        Iris::panic (bits, "partitioned device doesn't support 512 byte access\n")
5557    Partition::device_size = dev.get_size ()
5658    Iris::Page page = Iris::my_memory.create_page ()
57    page.set_flags (Iris::Page::PAYING, Iris::Page::PAYING)
59    page.set_flags (Iris::Page::PAYING)
5860    char *buffer = (char *)0x15000
5961    unsigned *ubuffer = (unsigned *)buffer
6062    Iris::my_memory.map (page, (unsigned)buffer)
61    read_block (0, page)
63    read_sector (0, page)
6264
6365    if buffer[0x1fe] != 0x55 || (buffer[0x1ff] & 0xff) != 0xaa:
6466        kdebug ("invalid mbr signature\n")
...... 
7880
7981    while true:
8082        Iris::wait ()
83        //kdebug ("partition received: ")
84        //kdebug_num (Iris::recv.data[0].l)
85        //kdebug ("\n")
8186        switch Iris::recv.data[0].l:
8287            case Iris::String::GET_SIZE:
8388                Iris::recv.reply.invoke (partition[Iris::recv.protected_data.l].size)
...... 
8792                Iris::Num request = Iris::recv.data[1]
8893                Iris::Num offset = (partition[Iris::recv.protected_data.l].start.value () + (request.value () & BLOCK_MASK)) & 0xf
8994                unsigned page_offset = request.l & ~BLOCK_MASK
90                page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
91                read_block (offset, page)
95                page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
96                read_sector (offset, page)
9297                reply.invoke (Iris::Num (ubuffer[page_offset >> 2 + 0], ubuffer[page_offset >> 2 + 1]), Iris::Num (ubuffer[page_offset >> 2 + 2], ubuffer[page_offset >> 2 + 3]))
9398                page.set_flags (0, Iris::Page::PAYING | Iris::Page::FRAME)
9499                Iris::free_cap (reply)
...... 
116121                //kdebug (":")
117122                //kdebug_num (Iris::Num (offset.value () + p.value ()).l)
118123                //kdebug ("\n")
119                read_block (offset.value () + p.value (), arg, size, out_offset)
124                read_sector (offset.value () + p.value (), arg, size, out_offset)
120125                reply.invoke ()
121126                Iris::free_cap (reply)
122127                Iris::free_cap (arg)
source/sd+mmc.ccp
6666    unsigned get_read_block_size ():
6767        return read_block_size
6868    unsigned get_block_bits ():
69        return csd.read_bl_len > csd.write_bl_len ? csd.read_bl_len : csd.write_bl_len
69        return hc ? 9 : csd.read_bl_len > csd.write_bl_len ? csd.read_bl_len : csd.write_bl_len
7070    void fill_page (Iris::Page page, Iris::Num address, unsigned size, unsigned offset)
7171    private:
7272    unsigned rca
7373    bool have_sdmem, have_io
74    bool hc
7475    CID cid
7576    CSD csd
7677    unsigned num_blocks, read_block_size
...... 
9495        Iris::panic (0, "crc error in mmc response")
9596        return false
9697    if stat & MSC_STAT_TIME_OUT_RES:
97        //kdebug ("time out waiting for mmc response\n")
98        kdebug ("time out waiting for mmc response\n")
99        MSC_IREG = MSC_IREG_END_CMD_RES
98100        return false
99101    if response_type == R2:
100102        unsigned d = MSC_RES
...... 
161163            // 1 0.1 15.4
162164            csd.tmp_write_protect = d & 0x10
163165            // Ignore file_format. 2 (+ 2) 0.4 16.0 ***
164            read_block_size = 1 << csd.read_bl_len
166            read_block_size = hc ? 512 : 1 << csd.read_bl_len
165167            num_blocks = (csd.c_size + 1) << (csd.c_size_mult + 2)
168            if hc:
169                if csd.read_bl_len < 9:
170                    num_blocks >>= 9 - csd.read_bl_len
171                else:
172                    num_blocks <<= csd.read_bl_len - 9
166173    else if response_type != NONE:
167174        unsigned r = MSC_RES
168175        if response_type == R3:
169176            if r >> 8 != 0x3f:
170177                Iris::panic (r, "r3 response was not 3f")
171178        else if r >> 8 != cmd:
179            kdebug ("stat: ")
180            kdebug_num (MSC_STAT)
172181            Iris::panic (r, "response doesn't match command")
173182        r <<= 24
174183        r |= MSC_RES << 8
175184        r |= MSC_RES & 0xff
176185        if response:
177186            *response = r
187    else:
178188    //kdebug ("extra response fifo read: ")
179189    //for unsigned i = 0; i < 9; ++i:
180190        //kdebug (" ")
...... 
225235    // Start the clock.
226236    MSC_STRPCL = MSC_STRPCL_CLOCK_CONTROL_START
227237    // Set cards, if any, to idle.
228    MSC_CMD = 0
229    MSC_CMDAT = MSC_CMDAT_RESPONSE_NONE
230    Iris::register_interrupt (IRQ_MSC)
231    msc_start_op ()
232    Iris::wait_for_interrupt (IRQ_MSC)
233    msc_ireg_clear_end_cmd_res ()
238    send (0, 0, NONE)
234239
235240    // Reset SDIO device, if any.
236    MSC_CMD = 52
237    MSC_ARG = 0x88000C08
238    MSC_CMDAT = MSC_CMDAT_RESPONSE_R5
239    Iris::register_interrupt (IRQ_MSC)
240    msc_start_op ()
241    Iris::wait_for_interrupt (IRQ_MSC)
242    msc_ireg_clear_end_cmd_res ()
241    send (52, 0x88000c08, R5)
243242
244243void Mmc::check_mmc ():
245244    //kdebug ("checking mmc\n")
...... 
253252
254253void Mmc::check_sdmem ():
255254    kdebug ("checking sdmem\n")
256    send (0, 0, NONE)
257255    // 2. Send CMD55. Here the default RCA 0x0000 is used for CMD55.
258256    // 3. If the response is correct (CMD55 has response), then continue, else go to check MMC.
259257    unsigned code
260    bool hc = false
258    hc = false
261259    if send (8, 0x1aa, R7, &code) && (code & 0xff) == 0xaa:
262260        kdebug ("hc\n")
263261        hc = true
...... 
357355    if address.h:
358356        Iris::panic (0, "page too high: not supported")
359357        return
360    unsigned blockmask = ~((1 << get_block_bits ()) - 1)
358    //kdebug ("smc get page ")
359    //kdebug_num (address.l)
360    //kdebug ("+")
361    //kdebug_num (size)
362    //kdebug ("@")
363    //kdebug_num (offset)
364    //kdebug ("\n")
365    unsigned blockmask = ~((1 << 9) - 1)
361366    unsigned p = address.l & blockmask
362367    size &= blockmask
363368    offset &= ~PAGE_MASK
364369    if size + offset > PAGE_SIZE:
365370        size = PAGE_SIZE - offset
366    page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
371    page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
367372    page.share (buffer_page)
368    buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME, Iris::Page::PAYING | Iris::Page::FRAME)
373    buffer_page.set_flags (Iris::Page::PAYING | Iris::Page::FRAME)
369374    MSC_NOB = 1
370    MSC_BLKLEN = read_block_size
371    for unsigned a = 0; a < size; a += 1 << get_block_bits ():
375    MSC_BLKLEN = 1 << 9
376    for unsigned a = 0; a < size; a += 1 << 9:
377        //kdebug_num (a)
378        //kdebug ("/")
379        //kdebug_num (size)
380        //kdebug (" ==> ")
372381        if !send (17, p + a, DATA):
373382            Iris::panic (0, "unable to request data")
374        for unsigned aa = 0; aa < read_block_size; aa += 4:
375            Iris::register_interrupt (IRQ_MSC)
376            Iris::wait_for_interrupt (IRQ_MSC)
383        for unsigned aa = 0; aa < 1 << 9; aa += 4:
384            while MSC_STAT & MSC_STAT_DATA_FIFO_EMPTY:
385                Iris::register_interrupt (IRQ_MSC)
386                Iris::wait_for_interrupt (IRQ_MSC)
377387            *(unsigned *)(buffer + a + aa + offset) = MSC_RXFIFO
388            //unsigned d = *(unsigned *)(buffer + a + aa + offset)
389            //if (aa & 0x3f) == 0:
390                //kdebug ("\n")
391            //for unsigned i = 0; i < 4; ++i:
392                //kdebug (" ")
393                //kdebug_num (d >> (8 * i), 2)
394        //kdebug ("\n")
378395        MSC_IREG = MSC_IREG_DATA_TRAN_DONE
396    //kdebug ("done filling page\n")
379397
380398static Mmc mmc
381399
...... 
436454                        Iris::panic (0, "get chars from mmc not supported yet")
437455                        break
438456                    case Iris::String::GET_ALIGN_BITS:
439                        Iris::recv.reply.invoke (mmc.get_block_bits ())
457                        Iris::recv.reply.invoke (9)
440458                        break
441459                    case Iris::String::GET_BLOCK:
442460                        Iris::Cap reply = Iris::get_reply ()
source/test.ccp
1919#include <iris.hh>
2020#include <devices.hh>
2121
22bool match (char const *a, char const *b):
23    for unsigned i = 0; i < 11; ++i:
22bool match (char const *a, char const *b, unsigned l1, unsigned l2):
23    if l1 != l2:
24        return false
25    for unsigned i = 0; i < l1; ++i:
2426        if a[i] != b[i]:
2527            return false
2628    return true
2729
28Iris::Num start ():
29    Iris::Directory dir = Iris::my_parent.get_capability <Iris::Directory> ()
30static bool print_name (Iris::String name, unsigned indent):
31    unsigned l = name.get_size ().l
32    for unsigned i = 0; i < indent; ++i:
33        kdebug_char (' ')
34    char part[16]
35    for unsigned i = 0; i < l; i += 16:
36        name.get_chars (i, part)
37        for unsigned k = 0; k < 16 && i * 16 + k < l; ++k:
38            kdebug_char (part[k])
39    kdebug_char ('\n')
40    return match (part, ".", l, 1) || match (part, "..", l, 2)
41
42static void print_dir (Iris::Directory dir, unsigned indent):
3043    dir.lock_ro ()
3144    Iris::Num files = dir.get_size ()
3245    for Iris::Num i = 0; i.value () < files.value (); i = i.value () + 1:
3346        Iris::String f = dir.get_name (i)
34        char start[16]
35        f.get_chars (0, start)
36        if match (start, "TEST TXT"):
37            Iris::free_cap (f)
38            f = dir.get_file_ro (i)
39            dir.unlock_ro ()
40            Iris::Page p = f.get_block (0)
41            char *mapping = (char *)0x15000
42            Iris::my_memory.map (p, (unsigned)mapping)
43            for unsigned j = 0; j < PAGE_SIZE; ++j:
44                kdebug_char (mapping[j])
45            kdebug_char ('\n')
46            return 0
47        unsigned i
48        for i = 0; i < 16; ++i:
49            if start[i] != 0:
50                break
51        if i < 16:
52            for i = 0; i < 16; ++i:
53                kdebug_num (start[i], 2)
54                kdebug (" ")
55            for i = 0; i < 16; ++i:
56                kdebug_char (start[i])
57            kdebug ("\n")
47        bool ignore = print_name (f, indent)
48        if !ignore && dir.get_file_info (i, 0).l & 1:
49            Iris::Directory d = dir.get_file_ro (i)
50            print_dir (d, indent + 4)
51            Iris::free_cap (d)
5852        Iris::free_cap (f)
59    kdebug ("file test.txt not found\n")
60    return 1
53    dir.unlock_ro ()
54
55Iris::Num start ():
56    Iris::Directory dir = Iris::my_parent.get_capability <Iris::Directory> ()
57    print_dir (dir, 0)
58    return 0
source/udc.ccp
218218    page = (unsigned *)LCD_FRAMEBUFFER_BASE
219219    p = page
220220    buffer_page = Iris::my_memory.create_page ()
221    buffer_page.set_flags (Iris::Page::FRAME | Iris::Page::PAYING, Iris::Page::FRAME | Iris::Page::PAYING)
221    buffer_page.set_flags (Iris::Page::FRAME | Iris::Page::PAYING)
222222    Iris::my_memory.map (buffer_page, (unsigned)page)
223223
224224    // Disconnect from the bus and don't try to get high-speed.
...... 
517517        *p++ = UDC_FIFO (1)
518518    if p - page == PAGE_SIZE >> 2:
519519        buffer_page.share (caller_arg, Iris::Page::FORGET)
520        buffer_page.set_flags (Iris::Page::FRAME, Iris::Page::FRAME)
520        buffer_page.set_flags (Iris::Page::FRAME)
521521        caller.invoke ()
522522        Iris::free_cap (caller)
523523        Iris::free_cap (caller_arg)
...... 
555555
556556enum pdata:
557557    LOG = 32
558    FS
559    DATA
560558    DIRECTORY
561559    FILE
562560    NAME
...... 
571569    __asm__ volatile ("li $a0, 1\nlw $a1, %0\nbreak" :: "m"(logcap.code): "a0", "a1", "memory")
572570    udc.init ()
573571    Iris::register_interrupt (IRQ_UDC)
574    Iris::Filesystem fs = Iris::my_receiver.create_capability (FS)
575    Iris::String data = Iris::my_receiver.create_capability (DATA)
576    Iris::my_parent.provide_capability <Iris::Filesystem> (fs.copy ())
577    Iris::my_parent.provide_capability <Iris::String> (data.copy ())
578    Iris::free_cap (fs)
579    Iris::free_cap (data)
572    Iris::Directory dir = Iris::my_receiver.create_capability (DIRECTORY)
573    Iris::my_parent.provide_capability <Iris::Directory> (dir.copy ())
574    Iris::free_cap (dir)
580575    unsigned state = 0
581576    while true:
582577        Iris::wait ()
...... 
590585            case LOG:
591586                udc.log (Iris::recv.data[0].l)
592587                break
593            case DATA:
594                //kdebug ("data request\n")
595                switch Iris::recv.data[0].l:
596                    case Iris::Device::RESET:
597                    case Iris::String::GET_SIZE:
598                    case Iris::String::GET_CHARS:
599                        reply.invoke (0)
600                        Iris::free_cap (reply)
601                        Iris::free_cap (arg)
602                        continue
603                    case Iris::String::GET_BLOCK:
604                    default:
605                        reply.invoke (Iris::ERR_INVALID_OPERATION)
606                        Iris::free_cap (reply)
607                        Iris::free_cap (arg)
608                        continue
609                break
610            case FS:
611                //kdebug ("fs request\n")
612                switch Iris::recv.data[0].l:
613                    case Iris::Device::RESET:
614                        reply.invoke (0)
615                        Iris::free_cap (reply)
616                        Iris::free_cap (arg)
617                        continue
618                    case Iris::Filesystem::USE_DEVICE:
619                    case Iris::Filesystem::USE_DEVICE_RO:
620                        Iris::Directory dir = Iris::my_receiver.create_capability (DIRECTORY)
621                        reply.invoke (0, 0, dir.copy ())
622                        Iris::free_cap (dir)
623                        Iris::free_cap (reply)
624                        Iris::free_cap (arg)
625                        continue
626                    default:
627                        reply.invoke (Iris::ERR_INVALID_OPERATION)
628                        Iris::free_cap (reply)
629                        Iris::free_cap (arg)
630                        continue
631                break
632588            case DIRECTORY:
633589                //kdebug ("dir request\n")
634590                switch Iris::recv.data[0].l:

Archive Download the corresponding diff file

Branches:
master



interactive