mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-16 20:44:05 +02:00
123 lines
3.8 KiB
COBOL
123 lines
3.8 KiB
COBOL
#pypp 0
|
|
#include <iris.hh>
|
|
#include <devices.hh>
|
|
|
|
#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 <Iris::WBlock> ()
|
|
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 <Iris::WBlock> (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")
|