Root/include/kernel.hhp

1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// kernel.hhp: Header for all kernel sources.
4// Copyright 2009 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#ifndef _KERNEL_HH
20#define _KERNEL_HH
21
22// Include definitions which are shared with user space.
23#define __KERNEL__
24
25// Normally define all variables in this file as extern.
26// Exactly once (in data.ccp), EXTERN is predefined empty.
27// That results in space being allocated in its object file.
28#ifndef EXTERN
29#define EXTERN extern
30#endif
31
32struct kPage
33struct kThread
34struct kMessage
35struct kReceiver
36struct kCapability
37struct kCaps
38struct kMemory
39struct kList
40struct kListitem
41
42// Some functions which must be defined early.
43#ifndef NDEBUG
44void kdebug (unsigned ch)
45void kdebug (char const *str)
46void kdebug_num (unsigned num, unsigned digits = 8)
47#else
48#define kdebug(x) do {} while (0)
49#define kdebug_num(n) do {} while (0)
50#endif
51
52#include "iris.hh"
53
54typedef kPage *kPageP
55typedef kThread *kThreadP
56typedef kMessage *kMessageP
57typedef kReceiver *kReceiverP
58typedef kCapability *kCapabilityP
59typedef kCaps *kCapsP
60typedef kMemory *kMemoryP
61typedef kList *kListP
62typedef kListitem *kListitemP
63typedef void *kPointer
64
65struct kCapRef:
66    kCapsP caps
67    unsigned index
68    inline kCapability *deref ()
69    bool valid ():
70        return deref () != NULL
71    kCapability *operator-> ():
72        return deref ()
73    void reset ():
74        caps = NULL
75    kCapRef (kCapsP c, unsigned i) : caps (c), index (i):
76    kCapRef () : caps (NULL), index (~0):
77    inline void clone (kCapRef source, bool copy)
78    inline void set (kReceiver *target, Iris::Num pdata, kCapRef parent, kCapRef *parent_ptr = NULL)
79
80struct kObject:
81    kCapRef refs
82    kMemoryP address_space
83    // Next and previous object of the same type in any page.
84    kPointer prev, next
85    inline bool is_free ()
86
87struct kFree : public kObject:
88    // This marker is ~0. No other kernel structure may allow this value
89    // at this point. It is used to recognize free chunks.
90    unsigned marker
91
92bool kObject::is_free ():
93    return ((kFree *)this)->marker == ~0
94
95// Include architecture-specific parts.
96#include "arch.hh"
97
98struct kCapability : public kObject:
99    struct Context:
100        Iris::Num data[2]
101        kCapRef reply
102        kCapRef arg
103        bool copy[2]
104    kReceiverP target
105    kCapRef parent
106    kCapRef children
107    kCapRef sibling_prev, sibling_next
108    Iris::Num protected_data
109    inline void invoke (kCapability::Context *c)
110    void invalidate ()
111
112struct _slot_data:
113    kThreadP thread
114    unsigned index
115
116// The order of the members is defined in arch.hh. It must be first an object which cannot be ~0, then
117// pc, sp and arch. After that everything is allowed.
118struct kThread : public kObject:
119    kReceiverP receivers
120    unsigned pc, sp
121    kThread_arch arch
122    unsigned flags
123    kThreadP schedule_prev, schedule_next
124    unsigned recv_reply, recv_arg
125    // slot[] is an array of slots pointers to kCapses.
126    unsigned slots
127    #ifndef NDEBUG
128    unsigned id
129    #endif
130    struct caps_store:
131        _slot_data prev, next
132        kCapsP caps
133    caps_store slot[1]
134    void unset_slot (unsigned s)
135    void raise (unsigned code, unsigned data)
136    void run ()
137    void unrun ()
138    void wait ()
139    void unwait ()
140    bool is_waiting ():
141        return flags & Iris::Thread::WAITING
142    kCapRef find_capability (unsigned code, bool *copy)
143
144struct kReceiver : public kObject:
145    kThreadP owner
146    kReceiverP prev_owned, next_owned
147    kReceiverP prev_alarm, next_alarm
148    unsigned alarm_count
149    // random is used like the tlb random register to find invalid caps to store the message to.
150    unsigned random
151    kCapsP caps
152    // These are capabilities which call this receiver on invoke.
153    kCapRef capabilities
154    // The message queue. kMessages are added at the tail, and removed at the front.
155    kMessageP messages
156    kMessageP last_message
157    Iris::Num reply_protected_data
158    bool protected_only
159    // This limit is for messages stored in its address space. There is unlimited space if senders provide it.
160    unsigned queue_limit, queue_use
161    void own (kThreadP o)
162    void orphan ()
163    bool try_deliver ()
164    bool send_message (Iris::Num protected_data, kCapability::Context *c)
165    void check (unsigned line)
166
167struct kPage : public kObject:
168    unsigned frame
169    unsigned flags
170    unsigned mapping
171    kPageP share_prev, share_next
172    kPage_arch arch
173    void forget ()
174    void check_payment ()
175
176struct kCaps : public kObject:
177    _slot_data first_slot
178    unsigned size
179    kCapability caps[1]
180    inline kCapability *cap (unsigned idx)
181    void set (unsigned index, kReceiver *target, Iris::Num pdata, kCapRef parent, kCapRef *parent_ptr = NULL)
182    void clone (unsigned index, kCapRef source, bool copy)
183    void init (unsigned size)
184
185// The 8 comes from the size of the admin data in a free page. When changing that, this must be changed as well.
186#define MAX_NUM_CAPS ((PAGE_SIZE - 8 - sizeof (kCaps)) / sizeof (kCapability) + 1)
187
188struct kMessage : public kObject:
189    Iris::Num protected_data
190    Iris::Num data[2]
191    // This is a real Caps of two elements, not a link.
192    kCaps caps
193
194struct kList : public kObject:
195    kListitemP first_listitem
196    // This is a real Caps of one element, not a link.
197    kCaps owner
198
199struct kListitem : public kObject:
200    kListP list
201    kListitemP prev_item, next_item
202    Iris::Num info
203    // This is a real Caps of one element, not a link.
204    kCaps target
205    void add (kList *l)
206
207struct kMemory : public kObject:
208    kFree *frees
209    kPageP pages
210    kThreadP threads
211    kReceiverP receivers
212    kCapsP capses
213    kListP lists
214    kListitemP listitems
215    kMemoryP memories
216    unsigned limit, used
217    kMemory_arch arch
218
219    inline bool map (kPage *page, unsigned address)
220    inline void unmap (kPage *page)
221    inline kPage *get_mapping (unsigned address)
222
223    // Allocation of pages.
224    bool use (unsigned num = 1)
225    void unuse (unsigned num = 1)
226    unsigned palloc ()
227    unsigned zalloc ()
228    void pfree (unsigned page)
229    void zfree (unsigned page)
230
231    // Allocation routines for kernel structures
232    void *search_free (unsigned size, void **first)
233    kPage *alloc_page ()
234    kThread *alloc_thread (unsigned size)
235    kMessage *alloc_message (kReceiver *target)
236    kReceiver *alloc_receiver ()
237    kCaps *alloc_caps (unsigned size)
238    kList *alloc_list ()
239    kListitem *alloc_listitem ()
240    kMemory *alloc_memory ()
241
242    void free_page (kPage *page)
243    void free_thread (kThread *thread)
244    void free_message (kReceiver *owner, kMessage *message)
245    void free_receiver (kReceiver *receiver)
246    void free_caps (kCaps *page)
247    void free_list (kList *list)
248    void free_listitem (kListitem *listitem)
249    void free_memory (kMemory *mem)
250
251    void free_obj (kObject *obj, void **first)
252    void check (unsigned line)
253    void print (unsigned line, unsigned indent)
254
255// Functions which can be called from assembly must not be mangled.
256extern "C":
257    // Panic. n is sent over caps led. message is sent to dbg_caps (when in use).
258    #define panic(n, m) panic_impl ((n), __stringify (__LINE__), __PRETTY_FUNCTION__, (m))
259    void panic_impl (unsigned n, char const *line, char const *name, char const *message = "")
260    #ifndef NDEBUG
261    EXTERN Iris::Num dbg_code
262    EXTERN unsigned dbg_buffer[32]
263    EXTERN unsigned dbg_buffer_head
264    static void dbg_push (unsigned n):
265        dbg_buffer[dbg_buffer_head++] = n
266        if dbg_buffer_head == 32:
267            dbg_buffer_head = 0
268    EXTERN kCapRef dbg_cap
269    void dbg_send (unsigned num, unsigned bits)
270    void check (unsigned num, char const *msg)
271    #define dbg_check() ::check (__LINE__, __FILE__)
272    void print_free ()
273    void check_impl (kObject *o, unsigned num, char const *msg)
274    bool check_free (kObject *o, unsigned size)
275    #define dpanic(n, msg) panic (n, msg)
276    #define dbg_print() top_memory.print (__LINE__, 0)
277    #else
278    #define dbg_send(n, m) do {} while (0)
279    #define check (n, x) do {} while (0)
280    #define dpanic(n, x) do {} while (0)
281    #endif
282
283/// Defined in schedule.ccp
284void schedule ()
285void timer_interrupt ()
286
287EXTERN kMemory top_memory
288EXTERN kReceiverP first_alarm
289EXTERN kThread idle
290EXTERN kMemory idle_memory
291EXTERN kPage idle_page
292EXTERN kThreadP first_scheduled
293EXTERN kThreadP current, old_current
294EXTERN bool do_schedule, must_wait
295// reply_caps is the source of a receiver-generated reply capability.
296// replied_caps is the source of kernel-generated capabilities which are used as arguments in a reply.
297// reply_target is the target receiver for kernel replies.
298// reply_protected is the protected data for the kernel reply.
299EXTERN kCaps reply_caps, replied_caps
300EXTERN kReceiver *reply_target
301EXTERN Iris::Num reply_protected
302
303// Defined in memory.ccp
304unsigned init_memory (unsigned mem)
305unsigned raw_zalloc ()
306void raw_pfree (unsigned page)
307unsigned phys_alloc (unsigned num)
308void phys_free (unsigned page, unsigned num)
309
310// Defind in invoke.ccp
311void invoke (kReceiverP target, Iris::Num protected_data, kCapability::Context *c)
312
313// Defined by architecture-specific files.
314void kThread_arch_init (kThread *thread)
315void kThread_arch_receive (kThread *thread, Iris::Num protected_data, Iris::Num *data)
316unsigned *kThread_arch_info (kThread *thread, unsigned num)
317void kMemory_arch_init (kMemory *mem)
318void kMemory_arch_free (kMemory *mem)
319bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address)
320void kMemory_arch_unmap (kMemory *mem, kPage *page)
321kPage *kMemory_arch_get_mapping (kMemory *mem, unsigned address)
322void kPage_arch_init (kPage *page)
323void kPage_arch_update_mapping (kPage *page)
324void arch_register_interrupt (unsigned num, kReceiverP r)
325void arch_reboot ()
326void arch_poweroff ()
327void arch_suspend ()
328void arch_boot (unsigned address, unsigned arg)
329void arch_uncache_page (unsigned page)
330
331#define assert(x) do { if (!(x)) panic (__LINE__, "assertion failed"); } while (0)
332#define __stringify2(x) #x
333#define __stringify(x) __stringify2 (x)
334#define kdebug_line() do { kdebug (__FILE__ ":"); kdebug (__PRETTY_FUNCTION__); kdebug (":"); kdebug (__stringify (__LINE__)); kdebug ('\n'); } while (0)
335
336bool kMemory::map (kPage *page, unsigned address):
337    return kMemory_arch_map (this, page, address)
338void kMemory::unmap (kPage *page):
339    page->forget ()
340    kMemory_arch_unmap (this, page)
341kPage *kMemory::get_mapping (unsigned address):
342    return kMemory_arch_get_mapping (this, address)
343kCapability *kCapRef::deref ():
344    return caps ? caps->cap (index) : NULL
345void kCapRef::clone (kCapRef source, bool copy):
346    caps->clone (index, source, copy)
347void kCapRef::set (kReceiver *target, Iris::Num pdata, kCapRef parent, kCapRef *parent_ptr):
348    if valid ():
349        deref ()->invalidate ()
350    caps->set (index, target, pdata, parent, parent_ptr)
351void kCapability::invoke (kCapability::Context *c):
352    ::invoke (target, protected_data, c)
353kCapability *kCaps::cap (unsigned idx):
354    if idx >= size:
355        dpanic (idx, "invalid capability requested")
356        return NULL
357    return &caps[idx]
358
359#endif
360

Archive Download this file

Branches:
master



interactive