#pypp 0 // Iris: micro-kernel for a capability-based operating system. // source/buffer.ccp: block device buffer. // Copyright 2010 Bas Wijnen // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #include "iris.hh" #include "devices.hh" static unsigned align static Iris::Page page, rpage static unsigned mapping, rmapping static Iris::Num size, current static Iris::String dev static void read_block (Iris::Num idx): idx = idx.value () & PAGE_MASK if idx.value () == current.value (): return //kdebug ("buffering block ") //kdebug_num (idx.h) //kdebug (":") //kdebug_num (idx.l) //kdebug ("\n") dev.get_block (idx, PAGE_SIZE, 0, page) //kdebug ("buffered\n") current = idx Iris::Num start (): dev = Iris::my_parent.get_capability () align = dev.get_align_bits () size = dev.get_size () if align > PAGE_BITS: Iris::panic (align, "invalid alignment value for block device") page = Iris::my_memory.create_page () rpage = Iris::my_memory.create_page () page.set_flags (Iris::Page::PAYING) rpage.set_flags (Iris::Page::PAYING) mapping = 0x15000 rmapping = 0x17000 Iris::my_memory.map (page, mapping) Iris::my_memory.map (rpage, rmapping) current.h = ~0 current.l = ~0 Iris::Cap cap = Iris::my_receiver.create_capability (0) Iris::my_parent.provide_capability (cap.copy ()) Iris::free_cap (cap) Iris::my_parent.init_done () while true: Iris::wait () switch Iris::recv.data[0].l: case Iris::String::GET_SIZE: Iris::recv.reply.invoke (size) break case Iris::String::GET_ALIGN_BITS: // Use 16 byte alignment to make implementing GET_CHARS easier. Iris::recv.reply.invoke (4) break case Iris::String::GET_CHARS: Iris::Cap reply = Iris::get_reply () unsigned offset = Iris::recv.data[1].l & ~PAGE_MASK & ~((1 << 4) - 1) read_block (Iris::recv.data[1]) unsigned *data = (unsigned *)((char *)mapping)[offset] reply.invoke (Iris::Num (data[0], data[1]), Iris::Num (data[2], data[3])) Iris::free_cap (reply) break case Iris::String::GET_BLOCK: Iris::Cap reply = Iris::get_reply () Iris::Page arg = Iris::get_arg () unsigned offset = Iris::recv.data[1].l & ~PAGE_MASK & ~((1 << 4) - 1) unsigned sz = Iris::recv.data[0].h >> 16 unsigned roffset = Iris::recv.data[0].h & 0xffff Iris::Num idx = Iris::recv.data[1] arg.set_flags (Iris::Page::FRAME | Iris::Page::PAYING) arg.share (rpage) rpage.set_flags (Iris::Page::FRAME) read_block (idx) for unsigned i = 0; i < sz; ++i: ((char *)rmapping)[roffset + i] = ((char *)mapping)[offset + i] rpage.set_flags (0, Iris::Page::FRAME) reply.invoke () Iris::free_cap (reply) Iris::free_cap (arg) break default: Iris::panic (Iris::recv.data[0].l, "invalid request for buffer")