#pypp 0 #include #include #define NUM_PARTITIONS 4 #define SECTOR_BITS 9 #define BLOCK_MASK (~((1 << SECTOR_BITS) - 1)) unsigned bits struct Partition: static Iris::Num device_size unsigned lba_start, lba_size unsigned type bool active Iris::Num start, size static unsigned read_num (char *data): return data[0] & 0xff | (data[1] & 0xff) << 8 | (data[2] & 0xff) << 16 | (data[3] & 0xff) << 24 void read (char *data): if data[0] == 0: active = false else: active = true if (data[0] & 0xff) != 0x80: kdebug ("Warning: invalid active code ") kdebug_num (data[0], 2) kdebug ("\n") type = data[4] & 0xff lba_start = read_num (data + 8) lba_size = read_num (data + 12) start = Iris::Num (lba_start).value () << SECTOR_BITS size = Iris::Num (lba_size).value () << SECTOR_BITS kdebug ("Partition read: ") kdebug_num (lba_start) kdebug ("+") kdebug_num (lba_size) kdebug ("\n") Iris::Num Partition::device_size static Iris::WBlock dev static void read_sector (Iris::Num idx, Iris::Page page, unsigned size = 1 << SECTOR_BITS, unsigned offset = 0): offset &= ~PAGE_MASK if size + offset > PAGE_SIZE: size = PAGE_SIZE - offset size >>= SECTOR_BITS idx = idx.value () >> SECTOR_BITS for unsigned i = 0; i < size; ++i: dev.get_block ((idx.value () + i) << SECTOR_BITS, 1 << SECTOR_BITS, (i << SECTOR_BITS) + offset, page) Iris::Num start (): Partition::device_size = 0 dev = Iris::my_parent.get_capability () bits = dev.get_align_bits () if bits > SECTOR_BITS: Iris::panic (bits, "partitioned device doesn't support 512 byte access\n") Partition::device_size = dev.get_size () Iris::Page page = Iris::my_memory.create_page () page.set_flags (Iris::Page::PAYING) char *buffer = (char *)0x15000 unsigned *ubuffer = (unsigned *)buffer Iris::my_memory.map (page, (unsigned)buffer) read_sector (0, page) if buffer[0x1fe] != 0x55 || (buffer[0x1ff] & 0xff) != 0xaa: kdebug ("invalid mbr signature\n") Partition partition[NUM_PARTITIONS] Iris::Cap cap for unsigned i = 0; i < NUM_PARTITIONS; ++i: partition[i].read (buffer + 0x1be + 0x10 * i) cap = Iris::my_receiver.create_capability (i) Iris::my_parent.provide_capability (cap.copy (), i) Iris::free_cap (cap) page.set_flags (0, Iris::Page::PAYING | Iris::Page::FRAME) Iris::my_parent.init_done () while true: Iris::wait () //kdebug ("partition received: ") //kdebug_num (Iris::recv.data[0].l) //kdebug ("\n") switch Iris::recv.data[0].l: case Iris::Block::GET_SIZE: Iris::recv.reply.invoke (partition[Iris::recv.protected_data.l].size) break case Iris::Block::GET_ALIGN_BITS: Iris::recv.reply.invoke (SECTOR_BITS) break case Iris::Block::GET_BLOCK: Iris::Cap reply = Iris::get_reply () Iris::Cap arg = Iris::get_arg () Iris::Num p = Iris::recv.data[1].value () & BLOCK_MASK Iris::Num offset = partition[Iris::recv.protected_data.l].start.value () unsigned size = Iris::recv.data[0].h >> 16 unsigned out_offset = Iris::recv.data[0].h & 0xffff //kdebug ("partition sending sector ") //kdebug_num (offset.h) //kdebug (":") //kdebug_num (offset.l) //kdebug (" + ") //kdebug_num (p.h) //kdebug (":") //kdebug_num (p.l) //kdebug (" = ") //kdebug_num (Iris::Num (offset.value () + p.value ()).h) //kdebug (":") //kdebug_num (Iris::Num (offset.value () + p.value ()).l) //kdebug ("\n") read_sector (offset.value () + p.value (), arg, size, out_offset) reply.invoke () Iris::free_cap (reply) Iris::free_cap (arg) break case Iris::WBlock::SET_BLOCK: Iris::panic (Iris::recv.data[0].l, "writing to partitions not supported yet") case Iris::WBlock::TRUNCATE: default: Iris::panic (Iris::recv.data[0].l, "invalid request for partition handler")