Root/
| 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 | |
| 9 | unsigned bits |
| 10 | |
| 11 | struct 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 | |
| 39 | Iris::Num Partition::device_size |
| 40 | |
| 41 | static Iris::WBlock dev |
| 42 | static 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 | |
| 51 | Iris::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 |
Branches:
master
