Root/
| 1 | #pypp 0 |
| 2 | // Iris: micro-kernel for a capability-based operating system. |
| 3 | // source/buffer.ccp: block device buffer. |
| 4 | // Copyright 2010 Bas Wijnen <wijnen@debian.org> |
| 5 | // |
| 6 | // This program is free software: you can redistribute it and/or modify |
| 7 | // it under the terms of the GNU General Public License as published by |
| 8 | // the Free Software Foundation, either version 3 of the License, or |
| 9 | // (at your option) any later version. |
| 10 | // |
| 11 | // This program is distributed in the hope that it will be useful, |
| 12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | // GNU General Public License for more details. |
| 15 | // |
| 16 | // You should have received a copy of the GNU General Public License |
| 17 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | |
| 19 | #include "iris.hh" |
| 20 | #include "devices.hh" |
| 21 | |
| 22 | static unsigned align |
| 23 | static Iris::Page page, rpage |
| 24 | static unsigned mapping, rmapping |
| 25 | static Iris::Num size, current |
| 26 | static Iris::String dev |
| 27 | |
| 28 | static void read_block (Iris::Num idx): |
| 29 | idx = idx.value () & PAGE_MASK |
| 30 | if idx.value () == current.value (): |
| 31 | return |
| 32 | //kdebug ("buffering block ") |
| 33 | //kdebug_num (idx.h) |
| 34 | //kdebug (":") |
| 35 | //kdebug_num (idx.l) |
| 36 | //kdebug ("\n") |
| 37 | dev.get_block (idx, PAGE_SIZE, 0, page) |
| 38 | //kdebug ("buffered\n") |
| 39 | current = idx |
| 40 | |
| 41 | Iris::Num start (): |
| 42 | dev = Iris::my_parent.get_capability <Iris::WString> () |
| 43 | align = dev.get_align_bits () |
| 44 | size = dev.get_size () |
| 45 | if align > PAGE_BITS: |
| 46 | Iris::panic (align, "invalid alignment value for block device") |
| 47 | page = Iris::my_memory.create_page () |
| 48 | rpage = Iris::my_memory.create_page () |
| 49 | page.set_flags (Iris::Page::PAYING) |
| 50 | rpage.set_flags (Iris::Page::PAYING) |
| 51 | mapping = 0x15000 |
| 52 | rmapping = 0x17000 |
| 53 | Iris::my_memory.map (page, mapping) |
| 54 | Iris::my_memory.map (rpage, rmapping) |
| 55 | current.h = ~0 |
| 56 | current.l = ~0 |
| 57 | Iris::Cap cap = Iris::my_receiver.create_capability (0) |
| 58 | Iris::my_parent.provide_capability <Iris::WString> (cap.copy ()) |
| 59 | Iris::free_cap (cap) |
| 60 | Iris::my_parent.init_done () |
| 61 | while true: |
| 62 | Iris::wait () |
| 63 | switch Iris::recv.data[0].l: |
| 64 | case Iris::String::GET_SIZE: |
| 65 | Iris::recv.reply.invoke (size) |
| 66 | break |
| 67 | case Iris::String::GET_ALIGN_BITS: |
| 68 | // Use 16 byte alignment to make implementing GET_CHARS easier. |
| 69 | Iris::recv.reply.invoke (4) |
| 70 | break |
| 71 | case Iris::String::GET_CHARS: |
| 72 | Iris::Cap reply = Iris::get_reply () |
| 73 | unsigned offset = Iris::recv.data[1].l & ~PAGE_MASK & ~((1 << 4) - 1) |
| 74 | read_block (Iris::recv.data[1]) |
| 75 | unsigned *data = (unsigned *)((char *)mapping)[offset] |
| 76 | reply.invoke (Iris::Num (data[0], data[1]), Iris::Num (data[2], data[3])) |
| 77 | Iris::free_cap (reply) |
| 78 | break |
| 79 | case Iris::String::GET_BLOCK: |
| 80 | Iris::Cap reply = Iris::get_reply () |
| 81 | Iris::Page arg = Iris::get_arg () |
| 82 | unsigned offset = Iris::recv.data[1].l & ~PAGE_MASK & ~((1 << 4) - 1) |
| 83 | unsigned sz = Iris::recv.data[0].h >> 16 |
| 84 | unsigned roffset = Iris::recv.data[0].h & 0xffff |
| 85 | Iris::Num idx = Iris::recv.data[1] |
| 86 | arg.set_flags (Iris::Page::FRAME | Iris::Page::PAYING) |
| 87 | arg.share (rpage) |
| 88 | rpage.set_flags (Iris::Page::FRAME) |
| 89 | read_block (idx) |
| 90 | for unsigned i = 0; i < sz; ++i: |
| 91 | ((char *)rmapping)[roffset + i] = ((char *)mapping)[offset + i] |
| 92 | rpage.set_flags (0, Iris::Page::FRAME) |
| 93 | reply.invoke () |
| 94 | Iris::free_cap (reply) |
| 95 | Iris::free_cap (arg) |
| 96 | break |
| 97 | default: |
| 98 | Iris::panic (Iris::recv.data[0].l, "invalid request for buffer") |
| 99 |
Branches:
master
