1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-11-04 23:19:41 +02:00
iris/source/crt0.ccp

167 lines
4.8 KiB
Plaintext
Raw Normal View History

2010-01-14 19:14:37 +02:00
#pypp 0
// Iris: micro-kernel for a capability-based operating system.
// boot-programs/init.S: Startup code for initial Threads.
// 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/>.
#include "iris.hh"
#include "devices.hh"
// For some unknown reason, gcc needs this to be defined.
unsigned __gxx_personality_v0
struct list:
list *prev, *next
static unsigned __slots, __caps
static list *__slot_admin, *__cap_admin
static list *__first_free_slot, *__first_free_cap
namespace Iris:
bool enable_debug
Caps my_caps
2010-01-14 19:14:37 +02:00
Receiver my_receiver
Thread my_thread
Memory my_memory
Cap my_call
Parent my_parent
__recv_data_t recv
void print_caps ():
2010-07-08 13:38:36 +03:00
// __caps cannot be larger than 63.
bool used[63]
for unsigned i = 0; i < __caps; ++i:
2010-01-14 19:14:37 +02:00
used[i] = true
unsigned num = 0
for list *i = __first_free_cap; i; i = i->next:
if used[i - __cap_admin] == false:
panic (0, "inconsistent userspace cap db")
2010-01-14 19:14:37 +02:00
used[i - __cap_admin] = false
++num
2010-01-24 22:34:24 +02:00
kdebug_num (num, 2)
2010-01-14 19:14:37 +02:00
kdebug (":")
2010-07-08 13:38:36 +03:00
for unsigned i = 0; i < __caps; ++i:
2010-01-14 19:14:37 +02:00
kdebug_char (used[i] ? '#' : '.')
kdebug_char ('\n')
void free_slot (unsigned slot):
//kdebug ("free slot\n")
for list *i = __first_free_slot; i; i = i->next:
if slot == i - __slot_admin:
panic (0, "double free of userspace slot")
2010-01-14 19:14:37 +02:00
__slot_admin[slot].prev = NULL
__slot_admin[slot].next = __first_free_slot
if __slot_admin[slot].next:
__slot_admin[slot].next->prev = &__slot_admin[slot]
__first_free_slot = &__slot_admin[slot]
void free_cap (Cap cap):
if enable_debug:
kdebug ("free cap ")
kdebug_num (cap.idx (), 2)
kdebug ("\n")
for list *i = __first_free_cap; i; i = i->next:
if cap.idx () == i - __cap_admin:
panic (0, "double free of userspace cap")
2010-01-14 19:14:37 +02:00
if cap.slot () != 0:
kdebug ("trying to free capability from non-0 slot\n")
Iris::panic (0)
2010-01-14 19:14:37 +02:00
return
list *l = &__cap_admin[cap.idx ()]
l->prev = NULL
l->next = __first_free_cap
if l->next:
l->next->prev = l
__first_free_cap = l
unsigned alloc_slot ():
//kdebug ("alloc slot\n")
if !__first_free_slot:
// Out of slots... Probably best to raise an exception. For now, just return NO_SLOT.
kdebug ("out of slots!\n")
Iris::panic (0)
2010-01-14 19:14:37 +02:00
return ~0
list *ret = __first_free_slot
__first_free_slot = ret->next
if ret->next:
ret->next->prev = NULL
return ret - __slot_admin
Cap alloc_cap ():
if !__first_free_cap:
// Out of caps... Probably best to raise an exception. For now, just return CAP_NONE
kdebug ("out of capabilities!\n")
Iris::panic (0)
2010-01-14 19:14:37 +02:00
return Cap (0, CAP_NONE)
list *ret = __first_free_cap
__first_free_cap = ret->next
if ret->next:
ret->next->prev = NULL
if enable_debug:
kdebug ("alloc cap ")
kdebug_num (ret - __cap_admin, 2)
kdebug ("\n")
2010-01-14 19:14:37 +02:00
return Cap (0, ret - __cap_admin)
extern "C":
void run__main (unsigned slots, unsigned caps, list *slot_admin, list *cap_admin):
Iris::enable_debug = false
2010-01-14 19:14:37 +02:00
__slots = slots
__caps = caps
__slot_admin = slot_admin
__cap_admin = cap_admin
__first_free_slot = NULL
2010-01-24 22:34:24 +02:00
for unsigned i = 1; i < __slots; ++i:
Iris::free_slot (i)
2010-01-14 19:14:37 +02:00
__first_free_cap = NULL
for unsigned i = 6; i < __caps; ++i:
Iris::free_cap (Iris::Cap (0, i))
Iris::my_caps = Iris::Cap (0, __caps_num)
Iris::my_receiver = Iris::Cap (0, __receiver_num)
Iris::my_thread = Iris::Cap (0, __thread_num)
Iris::my_memory = Iris::Cap (0, __memory_num)
Iris::my_call = Iris::Cap (0, __call_num)
Iris::my_parent = Iris::Cap (0, __parent_num)
Iris::recv.reply = Iris::alloc_cap ()
Iris::recv.arg = Iris::alloc_cap ()
Iris::Num ret = start ()
2010-05-15 19:42:17 +03:00
Iris::my_parent.exit (ret)
Iris::my_memory.destroy (Iris::my_thread)
2010-06-07 00:03:25 +03:00
// The program no longer exists. If it somehow does, die again.
2010-01-14 19:14:37 +02:00
while true:
2010-06-07 00:03:25 +03:00
Iris::panic (0, "this program should no longer exist.")
2010-01-14 19:14:37 +02:00
*(volatile unsigned *)~0
2010-01-18 06:01:59 +02:00
__asm__ volatile ("\t.text\n"
"\t.globl __start\n"
2010-01-14 19:14:37 +02:00
"\t.set noreorder\n"
"__start:\n"
"\tbal 1f\n"
"__hack_label:\n"
"\tnop\n"
"\t.word _gp\n"
"1:\n"
"\tlw $gp, 0($ra)\n"
"\tsll $v0, $a0, 3\n"
"\tsll $v1, $a1, 3\n"
"\tsubu $sp, $sp, $v0\n"
"\tmove $a2, $sp\n"
"\tsubu $sp, $sp, $v1\n"
"\tmove $a3, $sp\n"
"\tla $t9, run__main\n"
"\tjr $t9\n"
"\tnop\n"
"\t.set reorder")