Root/userspace/boot/crt0.ccp

1#pypp 0
2// Iris: micro-kernel for a capability-based operating system.
3// boot-programs/init.S: Startup code for initial Threads.
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#include "iris.hh"
20#include "devices.hh"
21
22struct list:
23    list *prev, *next
24
25static unsigned __slots, __caps
26static list *__slot_admin, *__cap_admin
27static list *__first_free_slot, *__first_free_cap
28
29namespace Iris:
30    bool enable_debug
31    Caps my_caps
32    Receiver my_receiver
33    Thread my_thread
34    Memory my_memory
35    Cap my_call
36    Parent my_parent
37    __recv_data_t recv
38
39    void print_caps ():
40        // __caps cannot be larger than 63.
41        bool used[63]
42        for unsigned i = 0; i < __caps; ++i:
43            used[i] = true
44        unsigned num = 0
45        for list *i = __first_free_cap; i; i = i->next:
46            if used[i - __cap_admin] == false:
47                panic (0, "inconsistent userspace cap db")
48            used[i - __cap_admin] = false
49            ++num
50        kdebug_num (num, 2)
51        kdebug (":")
52        for unsigned i = 0; i < __caps; ++i:
53            kdebug_char (used[i] ? '#' : '.')
54        kdebug_char ('\n')
55
56    void free_slot (unsigned slot):
57        //kdebug ("free slot\n")
58        for list *i = __first_free_slot; i; i = i->next:
59            if slot == i - __slot_admin:
60                panic (0, "double free of userspace slot")
61        __slot_admin[slot].prev = NULL
62        __slot_admin[slot].next = __first_free_slot
63        if __slot_admin[slot].next:
64            __slot_admin[slot].next->prev = &__slot_admin[slot]
65        __first_free_slot = &__slot_admin[slot]
66
67    void free_cap (Cap cap):
68        if enable_debug:
69            kdebug ("free cap ")
70            kdebug_num (cap.idx (), 2)
71            kdebug ("\n")
72        for list *i = __first_free_cap; i; i = i->next:
73            if cap.idx () == i - __cap_admin:
74                panic (0, "double free of userspace cap")
75        if cap.slot () != 0:
76            kdebug ("trying to free capability from non-0 slot\n")
77            Iris::panic (0)
78            return
79        list *l = &__cap_admin[cap.idx ()]
80        l->prev = NULL
81        l->next = __first_free_cap
82        if l->next:
83            l->next->prev = l
84        __first_free_cap = l
85
86    unsigned alloc_slot ():
87        //kdebug ("alloc slot\n")
88        if !__first_free_slot:
89            // Out of slots... Probably best to raise an exception. For now, just return NO_SLOT.
90            kdebug ("out of slots!\n")
91            Iris::panic (0)
92            return ~0
93        list *ret = __first_free_slot
94        __first_free_slot = ret->next
95        if ret->next:
96            ret->next->prev = NULL
97        return ret - __slot_admin
98
99    Cap alloc_cap ():
100        if !__first_free_cap:
101            // Out of caps... Probably best to raise an exception. For now, just return CAP_NONE
102            kdebug ("out of capabilities!\n")
103            Iris::panic (0)
104            return Cap (0, CAP_NONE)
105        list *ret = __first_free_cap
106        __first_free_cap = ret->next
107        if ret->next:
108            ret->next->prev = NULL
109        if enable_debug:
110            kdebug ("alloc cap ")
111            kdebug_num (ret - __cap_admin, 2)
112            kdebug ("\n")
113        return Cap (0, ret - __cap_admin)
114
115extern "C":
116    void run__main (unsigned slots, unsigned caps, list *slot_admin, list *cap_admin):
117        Iris::enable_debug = false
118        __slots = slots
119        __caps = caps
120        __slot_admin = slot_admin
121        __cap_admin = cap_admin
122        __first_free_slot = NULL
123        for unsigned i = 1; i < __slots; ++i:
124            Iris::free_slot (i)
125        __first_free_cap = NULL
126        for unsigned i = 6; i < __caps; ++i:
127            Iris::free_cap (Iris::Cap (0, i))
128        Iris::my_caps = Iris::Cap (0, __caps_num)
129        Iris::my_receiver = Iris::Cap (0, __receiver_num)
130        Iris::my_thread = Iris::Cap (0, __thread_num)
131        Iris::my_memory = Iris::Cap (0, __memory_num)
132        Iris::my_call = Iris::Cap (0, __call_num)
133        Iris::my_parent = Iris::Cap (0, __parent_num)
134        Iris::recv.reply = Iris::alloc_cap ()
135        Iris::recv.arg = Iris::alloc_cap ()
136        Iris::Num ret = start ()
137        Iris::my_parent.exit (ret)
138        Iris::my_memory.destroy (Iris::my_thread)
139        // The program no longer exists. If it somehow does, die again.
140        while true:
141            Iris::panic (0, "this program should no longer exist.")
142            *(volatile unsigned *)~0
143
144__asm__ volatile ("\t.text\n"
145    "\t.globl __start\n"
146    "\t.set noreorder\n"
147    "__start:\n"
148    "\tbal 1f\n"
149    "__hack_label:\n"
150    "\tnop\n"
151    "\t.word _gp\n"
152    "1:\n"
153    "\tlw $gp, 0($ra)\n"
154    "\tsll $v0, $a0, 3\n"
155    "\tsll $v1, $a1, 3\n"
156    "\tsubu $sp, $sp, $v0\n"
157    "\tmove $a2, $sp\n"
158    "\tsubu $sp, $sp, $v1\n"
159    "\tmove $a3, $sp\n"
160    "\tla $t9, run__main\n"
161    "\tjr $t9\n"
162    "\tnop\n"
163    "\t.set reorder")
164

Archive Download this file

Branches:
master



interactive