Root/userspace/glue/partition.ccp

1#pypp 0
2#include <iris.hh>
3#include <devices.hh>
4
5#define NUM_PARTITIONS 4
6#define SECTOR_BITS 9
7#define BLOCK_MASK (~((1 << SECTOR_BITS) - 1))
8
9unsigned bits
10
11struct Partition:
12    static Iris::Num device_size
13    unsigned lba_start, lba_size
14    unsigned type
15    bool active
16    Iris::Num start, size
17    static unsigned read_num (char *data):
18        return data[0] & 0xff | (data[1] & 0xff) << 8 | (data[2] & 0xff) << 16 | (data[3] & 0xff) << 24
19    void read (char *data):
20        if data[0] == 0:
21            active = false
22        else:
23            active = true
24            if (data[0] & 0xff) != 0x80:
25                kdebug ("Warning: invalid active code ")
26                kdebug_num (data[0], 2)
27                kdebug ("\n")
28        type = data[4] & 0xff
29        lba_start = read_num (data + 8)
30        lba_size = read_num (data + 12)
31        start = Iris::Num (lba_start).value () << SECTOR_BITS
32        size = Iris::Num (lba_size).value () << SECTOR_BITS
33        kdebug ("Partition read: ")
34        kdebug_num (lba_start)
35        kdebug ("+")
36        kdebug_num (lba_size)
37        kdebug ("\n")
38
39Iris::Num Partition::device_size
40
41static Iris::WBlock dev
42static void read_sector (Iris::Num idx, Iris::Page page, unsigned size = 1 << SECTOR_BITS, unsigned offset = 0):
43    offset &= ~PAGE_MASK
44    if size + offset > PAGE_SIZE:
45        size = PAGE_SIZE - offset
46    size >>= SECTOR_BITS
47    idx = idx.value () >> SECTOR_BITS
48    for unsigned i = 0; i < size; ++i:
49        dev.get_block ((idx.value () + i) << SECTOR_BITS, 1 << SECTOR_BITS, (i << SECTOR_BITS) + offset, page)
50
51Iris::Num start ():
52    Partition::device_size = 0
53    dev = Iris::my_parent.get_capability <Iris::WBlock> ()
54    bits = dev.get_align_bits ()
55    if bits > SECTOR_BITS:
56        Iris::panic (bits, "partitioned device doesn't support 512 byte access\n")
57    Partition::device_size = dev.get_size ()
58    Iris::Page page = Iris::my_memory.create_page ()
59    page.set_flags (Iris::Page::PAYING)
60    char *buffer = (char *)0x15000
61    unsigned *ubuffer = (unsigned *)buffer
62    Iris::my_memory.map (page, (unsigned)buffer)
63    read_sector (0, page)
64
65    if buffer[0x1fe] != 0x55 || (buffer[0x1ff] & 0xff) != 0xaa:
66        kdebug ("invalid mbr signature\n")
67
68    Partition partition[NUM_PARTITIONS]
69
70    Iris::Cap cap
71    for unsigned i = 0; i < NUM_PARTITIONS; ++i:
72        partition[i].read (buffer + 0x1be + 0x10 * i)
73        cap = Iris::my_receiver.create_capability (i)
74        Iris::my_parent.provide_capability <Iris::WBlock> (cap.copy (), i)
75        Iris::free_cap (cap)
76
77    page.set_flags (0, Iris::Page::PAYING | Iris::Page::FRAME)
78
79    Iris::my_parent.init_done ()
80
81    while true:
82        Iris::wait ()
83        //kdebug ("partition received: ")
84        //kdebug_num (Iris::recv.data[0].l)
85        //kdebug ("\n")
86        switch Iris::recv.data[0].l:
87            case Iris::Block::GET_SIZE:
88                Iris::recv.reply.invoke (partition[Iris::recv.protected_data.l].size)
89                break
90            case Iris::Block::GET_ALIGN_BITS:
91                Iris::recv.reply.invoke (SECTOR_BITS)
92                break
93            case Iris::Block::GET_BLOCK:
94                Iris::Cap reply = Iris::get_reply ()
95                Iris::Cap arg = Iris::get_arg ()
96                Iris::Num p = Iris::recv.data[1].value () & BLOCK_MASK
97                Iris::Num offset = partition[Iris::recv.protected_data.l].start.value ()
98                unsigned size = Iris::recv.data[0].h >> 16
99                unsigned out_offset = Iris::recv.data[0].h & 0xffff
100                //kdebug ("partition sending sector ")
101                //kdebug_num (offset.h)
102                //kdebug (":")
103                //kdebug_num (offset.l)
104                //kdebug (" + ")
105                //kdebug_num (p.h)
106                //kdebug (":")
107                //kdebug_num (p.l)
108                //kdebug (" = ")
109                //kdebug_num (Iris::Num (offset.value () + p.value ()).h)
110                //kdebug (":")
111                //kdebug_num (Iris::Num (offset.value () + p.value ()).l)
112                //kdebug ("\n")
113                read_sector (offset.value () + p.value (), arg, size, out_offset)
114                reply.invoke ()
115                Iris::free_cap (reply)
116                Iris::free_cap (arg)
117                break
118            case Iris::WBlock::SET_BLOCK:
119                Iris::panic (Iris::recv.data[0].l, "writing to partitions not supported yet")
120            case Iris::WBlock::TRUNCATE:
121            default:
122                Iris::panic (Iris::recv.data[0].l, "invalid request for partition handler")
123

Archive Download this file

Branches:
master



interactive