1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-11-05 11:17:12 +02:00
iris/kernel.hhp

358 lines
11 KiB
Plaintext
Raw Normal View History

2009-05-11 01:28:12 +03:00
#pypp 0
2009-06-01 15:26:42 +03:00
// Iris: micro-kernel for a capability-based operating system.
// kernel.hhp: Header for all kernel sources.
// Copyright 2009 Bas Wijnen <wijnen@debian.org>
//
// 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 <http://www.gnu.org/licenses/>.
2009-05-11 01:28:12 +03:00
#ifndef _KERNEL_HH
#define _KERNEL_HH
2009-06-01 15:26:42 +03:00
// Include definitions which are shared with user space.
2009-10-31 10:32:23 +02:00
#define __KERNEL__
2009-05-22 23:48:49 +03:00
2009-06-01 15:26:42 +03:00
// Normally define all variables in this file as extern.
// Exactly once (in data.ccp), EXTERN is predefined empty.
// That results in space being allocated in its object file.
2009-05-18 10:30:27 +03:00
#ifndef EXTERN
#define EXTERN extern
#endif
struct kPage
struct kThread
struct kMessage
struct kReceiver
struct kCapability
struct kCaps
struct kMemory
2009-12-28 08:53:29 +02:00
struct kList
struct kListitem
2009-12-11 10:43:42 +02:00
// Some functions which must be defined early.
2010-01-24 22:34:24 +02:00
#ifndef NDEBUG
void kdebug (unsigned ch)
void kdebug (char const *str)
void kdebug_num (unsigned num, unsigned digits = 8)
#else
#define kdebug(x) do {} while (0)
#define kdebug_num(n) do {} while (0)
#endif
2009-12-11 10:43:42 +02:00
#include "iris.hh"
typedef kPage *kPageP
typedef kThread *kThreadP
typedef kMessage *kMessageP
typedef kReceiver *kReceiverP
typedef kCapability *kCapabilityP
typedef kCaps *kCapsP
typedef kMemory *kMemoryP
2009-12-28 08:53:29 +02:00
typedef kList *kListP
typedef kListitem *kListitemP
typedef void *kPointer
struct kCapRef:
kCapsP caps
unsigned index
inline kCapability *deref ()
2009-08-24 22:02:35 +03:00
bool valid ():
return deref () != NULL
kCapability *operator-> ():
return deref ()
void reset ():
caps = NULL
kCapRef (kCapsP c, unsigned i) : caps (c), index (i):
kCapRef () : caps (NULL), index (~0):
inline void clone (kCapRef source, bool copy)
inline void set (kReceiver *target, Iris::Num pdata, kCapRef parent, kCapRef *parent_ptr = NULL)
struct kObject:
kCapRef refs
kMemoryP address_space
2009-05-18 10:30:27 +03:00
// Next and previous object of the same type in any page.
kPointer prev, next
inline bool is_free ()
2009-05-18 10:30:27 +03:00
struct kFree : public kObject:
2009-05-18 10:30:27 +03:00
// This marker is ~0. No other kernel structure may allow this value
// at this point. It is used to recognize free chunks.
unsigned marker
bool kObject::is_free ():
return ((kFree *)this)->marker == ~0
2009-05-18 10:30:27 +03:00
2009-06-01 15:26:42 +03:00
// Include architecture-specific parts.
#include "arch.hh"
struct kCapability : public kObject:
2009-06-08 14:46:13 +03:00
struct Context:
Iris::Num data[2]
2009-09-06 12:04:09 +03:00
kCapRef reply
kCapRef arg
bool copy[2]
kReceiverP target
kCapRef parent
kCapRef children
kCapRef sibling_prev, sibling_next
Iris::Num protected_data
inline void invoke (kCapability::Context *c)
2009-06-08 14:46:13 +03:00
void invalidate ()
2009-09-08 22:20:30 +03:00
struct _slot_data:
kThreadP thread
unsigned index
2010-01-17 11:01:42 +02:00
// The order of the members is defined in arch.hh. It must be first an object which cannot be ~0, then
// pc, sp and arch. After that everything is allowed.
struct kThread : public kObject:
kReceiverP receivers
2009-07-25 01:54:12 +03:00
unsigned pc, sp
kThread_arch arch
2009-07-25 01:54:12 +03:00
unsigned flags
kThreadP schedule_prev, schedule_next
2009-09-06 12:04:09 +03:00
unsigned recv_reply, recv_arg
2010-06-07 00:03:25 +03:00
// slot[] is an array of slots pointers to kCapses.
unsigned slots
2009-12-26 15:17:06 +02:00
#ifndef NDEBUG
unsigned id
#endif
2009-09-08 22:20:30 +03:00
struct caps_store:
_slot_data prev, next
kCapsP caps
caps_store slot[1]
void unset_slot (unsigned s)
2009-07-25 01:54:12 +03:00
void raise (unsigned code, unsigned data)
void run ()
void unrun ()
void wait ()
2009-07-25 01:54:12 +03:00
void unwait ()
bool is_waiting ():
return flags & Iris::Thread::WAITING
kCapRef find_capability (unsigned code, bool *copy)
struct kReceiver : public kObject:
kThreadP owner
kReceiverP prev_owned, next_owned
kReceiverP prev_alarm, next_alarm
2009-07-20 01:23:45 +03:00
unsigned alarm_count
// random is used like the tlb random register to find invalid caps to store the message to.
unsigned random
kCapsP caps
// These are capabilities which call this receiver on invoke.
kCapRef capabilities
// The message queue. kMessages are added at the tail, and removed at the front.
kMessageP messages
kMessageP last_message
Iris::Num reply_protected_data
2009-06-01 02:12:54 +03:00
bool protected_only
// This limit is for messages stored in its address space. There is unlimited space if senders provide it.
2009-10-10 02:31:10 +03:00
unsigned queue_limit, queue_use
void own (kThreadP o)
2009-05-24 13:22:22 +03:00
void orphan ()
2009-06-01 02:12:54 +03:00
bool try_deliver ()
bool send_message (Iris::Num protected_data, kCapability::Context *c)
2009-10-10 02:31:10 +03:00
void check (unsigned line)
2009-05-11 01:28:12 +03:00
struct kPage : public kObject:
2009-05-29 00:35:27 +03:00
unsigned frame
unsigned flags
2010-01-17 11:01:42 +02:00
unsigned mapping
kPageP share_prev, share_next
kPage_arch arch
2009-06-01 02:12:54 +03:00
void forget ()
2009-05-29 00:35:27 +03:00
struct kCaps : public kObject:
2009-09-08 22:20:30 +03:00
_slot_data first_slot
unsigned size
kCapability caps[1]
2010-01-24 22:34:24 +02:00
inline kCapability *cap (unsigned idx)
void set (unsigned index, kReceiver *target, Iris::Num pdata, kCapRef parent, kCapRef *parent_ptr = NULL)
void clone (unsigned index, kCapRef source, bool copy)
2009-12-30 15:00:37 +02:00
void init (unsigned size)
2010-01-24 22:34:24 +02:00
// The 8 comes from the size of the admin data in a free page. When changing that, this must be changed as well.
#define MAX_NUM_CAPS ((PAGE_SIZE - 8 - sizeof (kCaps)) / sizeof (kCapability) + 1)
2009-09-06 12:04:09 +03:00
struct kMessage : public kObject:
Iris::Num protected_data
Iris::Num data[2]
2009-09-06 12:04:09 +03:00
// This is a real Caps of two elements, not a link.
kCaps caps
2009-12-30 15:00:37 +02:00
struct kList : public kObject:
kListitemP first_listitem
// This is a real Caps of one element, not a link.
kCaps owner
2009-12-28 08:53:29 +02:00
struct kListitem : public kObject:
2009-12-30 15:00:37 +02:00
kListP list
2009-12-28 08:53:29 +02:00
kListitemP prev_item, next_item
Iris::Num info
2009-12-30 15:00:37 +02:00
// This is a real Caps of one element, not a link.
kCaps target
void add (kList *l)
2009-12-28 08:53:29 +02:00
struct kMemory : public kObject:
kFree *frees
kPageP pages
kThreadP threads
kReceiverP receivers
kCapsP capses
2009-12-28 08:53:29 +02:00
kListP lists
kListitemP listitems
kMemoryP memories
2009-05-11 01:28:12 +03:00
unsigned limit, used
kMemory_arch arch
2009-05-11 01:28:12 +03:00
2010-01-17 11:01:42 +02:00
inline bool map (kPage *page, unsigned address)
inline void unmap (kPage *page)
inline kPage *get_mapping (unsigned address)
2009-05-19 00:18:23 +03:00
2009-05-18 10:30:27 +03:00
// Allocation of pages.
2009-07-20 01:23:45 +03:00
bool use (unsigned num = 1)
void unuse (unsigned num = 1)
2009-05-22 23:48:49 +03:00
unsigned palloc ()
unsigned zalloc ()
void pfree (unsigned page)
void zfree (unsigned page)
2009-05-11 01:28:12 +03:00
2009-05-18 10:30:27 +03:00
// Allocation routines for kernel structures
2009-05-19 00:18:23 +03:00
void *search_free (unsigned size, void **first)
kPage *alloc_page ()
kThread *alloc_thread (unsigned size)
kMessage *alloc_message (kReceiver *target)
kReceiver *alloc_receiver ()
kCaps *alloc_caps (unsigned size)
2009-12-30 15:00:37 +02:00
kList *alloc_list ()
kListitem *alloc_listitem ()
kMemory *alloc_memory ()
void free_page (kPage *page)
void free_thread (kThread *thread)
void free_message (kReceiver *owner, kMessage *message)
void free_receiver (kReceiver *receiver)
void free_caps (kCaps *page)
2009-12-30 15:00:37 +02:00
void free_list (kList *list)
void free_listitem (kListitem *listitem)
void free_memory (kMemory *mem)
void free_obj (kObject *obj, void **first)
2009-10-10 02:31:10 +03:00
void check (unsigned line)
void print (unsigned line, unsigned indent)
2009-05-19 00:18:23 +03:00
2009-05-18 10:30:27 +03:00
// Functions which can be called from assembly must not be mangled.
extern "C":
2009-08-24 22:02:35 +03:00
// Panic. n is sent over caps led. message is sent to dbg_caps (when in use).
2010-01-16 17:13:54 +02:00
#define panic(n, m) panic_impl ((n), __stringify (__LINE__), __PRETTY_FUNCTION__, (m))
void panic_impl (unsigned n, char const *line, char const *name, char const *message = "")
2009-08-24 22:02:35 +03:00
#ifndef NDEBUG
EXTERN Iris::Num dbg_code
2010-01-24 22:34:24 +02:00
EXTERN unsigned dbg_buffer[32]
EXTERN unsigned dbg_buffer_head
static void dbg_push (unsigned n):
dbg_buffer[dbg_buffer_head++] = n
if dbg_buffer_head == 32:
dbg_buffer_head = 0
EXTERN kCapRef dbg_cap
2009-08-24 22:02:35 +03:00
void dbg_send (unsigned num, unsigned bits)
void check (unsigned num, char const *msg)
2009-10-10 02:31:10 +03:00
#define dbg_check() ::check (__LINE__, __FILE__)
void print_free ()
void check_impl (kObject *o, unsigned num, char const *msg)
bool check_free (kObject *o, unsigned size)
2009-08-24 22:02:35 +03:00
#define dpanic(n, msg) panic (n, msg)
2009-10-10 02:31:10 +03:00
#define dbg_print() top_memory.print (__LINE__, 0)
2009-08-24 22:02:35 +03:00
#else
#define dbg_send(n, m) do {} while (0)
#define check (n, x) do {} while (0)
#define dpanic(n, x) do {} while (0)
#endif
2009-05-11 01:28:12 +03:00
2009-07-04 17:21:28 +03:00
/// Defined in schedule.ccp
2009-05-20 23:07:56 +03:00
void schedule ()
2009-07-04 17:21:28 +03:00
void timer_interrupt ()
2009-05-20 23:07:56 +03:00
EXTERN kMemory top_memory
EXTERN kReceiverP first_alarm
EXTERN kThread idle
EXTERN kMemory idle_memory
EXTERN kPage idle_page
EXTERN kThreadP first_scheduled
EXTERN kThreadP current, old_current
2009-08-24 22:02:35 +03:00
EXTERN bool do_schedule, must_wait
2010-01-24 22:34:24 +02:00
// reply_caps is the source of a receiver-generated reply capability.
// replied_caps is the source of kernel-generated capabilities which are used as arguments in a reply.
// reply_target is the target receiver for kernel replies.
// reply_protected is the protected data for the kernel reply.
2010-01-24 22:34:24 +02:00
EXTERN kCaps reply_caps, replied_caps
EXTERN kReceiver *reply_target
EXTERN Iris::Num reply_protected
2009-05-20 23:07:56 +03:00
// Defined in memory.ccp
unsigned init_memory (unsigned mem)
2009-06-01 02:12:54 +03:00
unsigned raw_zalloc ()
void raw_pfree (unsigned page)
2009-07-20 01:23:45 +03:00
unsigned phys_alloc (unsigned num)
void phys_free (unsigned page, unsigned num)
2009-06-01 02:12:54 +03:00
// Defind in invoke.ccp
void invoke (kReceiverP target, Iris::Num protected_data, kCapability::Context *c)
2009-06-01 15:26:42 +03:00
// Defined by architecture-specific files.
void kThread_arch_init (kThread *thread)
void kThread_arch_receive (kThread *thread, Iris::Num protected_data, Iris::Num *data)
unsigned *kThread_arch_info (kThread *thread, unsigned num)
void kMemory_arch_init (kMemory *mem)
void kMemory_arch_free (kMemory *mem)
2010-01-17 11:01:42 +02:00
bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address)
void kMemory_arch_unmap (kMemory *mem, kPage *page)
kPage *kMemory_arch_get_mapping (kMemory *mem, unsigned address)
2010-01-18 06:01:59 +02:00
void kPage_arch_init (kPage *page)
void kPage_arch_update_mapping (kPage *page)
void arch_register_interrupt (unsigned num, kReceiverP r)
2009-10-04 20:47:20 +03:00
void arch_reboot ()
2010-08-10 11:09:50 +03:00
void arch_poweroff ()
2010-08-24 00:55:51 +03:00
void arch_boot (unsigned address, unsigned arg)
2009-12-30 23:41:45 +02:00
void arch_uncache_page (unsigned page)
2010-01-24 22:34:24 +02:00
#define assert(x) do { if (!(x)) panic (__LINE__, "assertion failed"); } while (0)
#define __stringify2(x) #x
#define __stringify(x) __stringify2 (x)
#define kdebug_line() do { kdebug (__FILE__ ":"); kdebug (__PRETTY_FUNCTION__); kdebug (":"); kdebug (__stringify (__LINE__)); kdebug ('\n'); } while (0)
2010-01-17 11:01:42 +02:00
bool kMemory::map (kPage *page, unsigned address):
return kMemory_arch_map (this, page, address)
void kMemory::unmap (kPage *page):
2010-01-18 06:01:59 +02:00
page->forget ()
2010-01-17 11:01:42 +02:00
kMemory_arch_unmap (this, page)
kPage *kMemory::get_mapping (unsigned address):
return kMemory_arch_get_mapping (this, address)
kCapability *kCapRef::deref ():
return caps ? caps->cap (index) : NULL
void kCapRef::clone (kCapRef source, bool copy):
caps->clone (index, source, copy)
void kCapRef::set (kReceiver *target, Iris::Num pdata, kCapRef parent, kCapRef *parent_ptr):
2010-01-24 22:34:24 +02:00
if valid ():
deref ()->invalidate ()
caps->set (index, target, pdata, parent, parent_ptr)
void kCapability::invoke (kCapability::Context *c):
2009-09-06 12:04:09 +03:00
::invoke (target, protected_data, c)
2010-01-24 22:34:24 +02:00
kCapability *kCaps::cap (unsigned idx):
if idx >= size:
2010-01-30 10:21:56 +02:00
dpanic (idx, "invalid capability requested")
2010-01-24 22:34:24 +02:00
return NULL
return &caps[idx]
2009-07-20 01:23:45 +03:00
2009-05-11 01:28:12 +03:00
#endif