Root/
| 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 | |
| 32 | struct kPage |
| 33 | struct kThread |
| 34 | struct kMessage |
| 35 | struct kReceiver |
| 36 | struct kCapability |
| 37 | struct kCaps |
| 38 | struct kMemory |
| 39 | struct kList |
| 40 | struct kListitem |
| 41 | |
| 42 | // Some functions which must be defined early. |
| 43 | #ifndef NDEBUG |
| 44 | void kdebug (unsigned ch) |
| 45 | void kdebug (char const *str) |
| 46 | void 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 | |
| 54 | typedef kPage *kPageP |
| 55 | typedef kThread *kThreadP |
| 56 | typedef kMessage *kMessageP |
| 57 | typedef kReceiver *kReceiverP |
| 58 | typedef kCapability *kCapabilityP |
| 59 | typedef kCaps *kCapsP |
| 60 | typedef kMemory *kMemoryP |
| 61 | typedef kList *kListP |
| 62 | typedef kListitem *kListitemP |
| 63 | typedef void *kPointer |
| 64 | |
| 65 | struct 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 | |
| 80 | struct 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 | |
| 87 | struct 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 | |
| 92 | bool kObject::is_free (): |
| 93 | return ((kFree *)this)->marker == ~0 |
| 94 | |
| 95 | // Include architecture-specific parts. |
| 96 | #include "arch.hh" |
| 97 | |
| 98 | struct 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 | |
| 112 | struct _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. |
| 118 | struct 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 | |
| 144 | struct 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 | |
| 167 | struct 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 | |
| 176 | struct 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 | |
| 188 | struct 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 | |
| 194 | struct kList : public kObject: |
| 195 | kListitemP first_listitem |
| 196 | // This is a real Caps of one element, not a link. |
| 197 | kCaps owner |
| 198 | |
| 199 | struct 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 | |
| 207 | struct 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. |
| 256 | extern "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 |
| 284 | void schedule () |
| 285 | void timer_interrupt () |
| 286 | |
| 287 | EXTERN kMemory top_memory |
| 288 | EXTERN kReceiverP first_alarm |
| 289 | EXTERN kThread idle |
| 290 | EXTERN kMemory idle_memory |
| 291 | EXTERN kPage idle_page |
| 292 | EXTERN kThreadP first_scheduled |
| 293 | EXTERN kThreadP current, old_current |
| 294 | EXTERN 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. |
| 299 | EXTERN kCaps reply_caps, replied_caps |
| 300 | EXTERN kReceiver *reply_target |
| 301 | EXTERN Iris::Num reply_protected |
| 302 | |
| 303 | // Defined in memory.ccp |
| 304 | unsigned init_memory (unsigned mem) |
| 305 | unsigned raw_zalloc () |
| 306 | void raw_pfree (unsigned page) |
| 307 | unsigned phys_alloc (unsigned num) |
| 308 | void phys_free (unsigned page, unsigned num) |
| 309 | |
| 310 | // Defind in invoke.ccp |
| 311 | void invoke (kReceiverP target, Iris::Num protected_data, kCapability::Context *c) |
| 312 | |
| 313 | // Defined by architecture-specific files. |
| 314 | void kThread_arch_init (kThread *thread) |
| 315 | void kThread_arch_receive (kThread *thread, Iris::Num protected_data, Iris::Num *data) |
| 316 | unsigned *kThread_arch_info (kThread *thread, unsigned num) |
| 317 | void kMemory_arch_init (kMemory *mem) |
| 318 | void kMemory_arch_free (kMemory *mem) |
| 319 | bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address) |
| 320 | void kMemory_arch_unmap (kMemory *mem, kPage *page) |
| 321 | kPage *kMemory_arch_get_mapping (kMemory *mem, unsigned address) |
| 322 | void kPage_arch_init (kPage *page) |
| 323 | void kPage_arch_update_mapping (kPage *page) |
| 324 | void arch_register_interrupt (unsigned num, kReceiverP r) |
| 325 | void arch_reboot () |
| 326 | void arch_poweroff () |
| 327 | void arch_suspend () |
| 328 | void arch_boot (unsigned address, unsigned arg) |
| 329 | void 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 | |
| 336 | bool kMemory::map (kPage *page, unsigned address): |
| 337 | return kMemory_arch_map (this, page, address) |
| 338 | void kMemory::unmap (kPage *page): |
| 339 | page->forget () |
| 340 | kMemory_arch_unmap (this, page) |
| 341 | kPage *kMemory::get_mapping (unsigned address): |
| 342 | return kMemory_arch_get_mapping (this, address) |
| 343 | kCapability *kCapRef::deref (): |
| 344 | return caps ? caps->cap (index) : NULL |
| 345 | void kCapRef::clone (kCapRef source, bool copy): |
| 346 | caps->clone (index, source, copy) |
| 347 | void 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) |
| 351 | void kCapability::invoke (kCapability::Context *c): |
| 352 | ::invoke (target, protected_data, c) |
| 353 | kCapability *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 |
Branches:
master
