Root/userspace/glue/buffer.ccp

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
22static unsigned align
23static Iris::Page page, rpage
24static unsigned mapping, rmapping
25static Iris::Num size, current
26static Iris::String dev
27
28static 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
41Iris::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

Archive Download this file

Branches:
master



interactive