1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2025-04-21 12:27:27 +03:00

new stuff almost working

This commit is contained in:
Bas Wijnen
2009-08-24 21:02:35 +02:00
parent ebdc68a9d8
commit 418f6c6594
18 changed files with 651 additions and 495 deletions

View File

@@ -21,96 +21,85 @@
void kThread_arch_init (kThread *thread):
thread->arch.at = 0
thread->arch.v0 = 0
thread->arch.v1 = 0
thread->arch.a0 = 0
thread->arch.a1 = 0
thread->arch.a2 = 0
thread->arch.a3 = 0
thread->arch.t0 = 0
thread->arch.t1 = 0
thread->arch.t2 = 0
thread->arch.t3 = 0
thread->arch.t4 = 0
thread->arch.t5 = 0
thread->arch.t6 = 0
thread->arch.t7 = 0
thread->arch.t8 = 0
thread->arch.t9 = 0
for unsigned i = 0; i < 2; ++i:
thread->arch.v[i] = 0
thread->arch.k[i] = 0
for unsigned i = 0; i < 4; ++i:
thread->arch.a[i] = 0
for unsigned i = 0; i < 10; ++i:
thread->arch.t[i] = 0
thread->arch.gp = 0
thread->arch.fp = 0
thread->arch.ra = 0
thread->arch.hi = 0
thread->arch.lo = 0
thread->arch.k0 = 0
thread->arch.k1 = 0
void kThread_arch_receive (kThread *thread, Num cap_protected, Num recv_protected, Num *data):
thread->arch.a0 = data[0].l
thread->arch.a1 = data[0].h
thread->arch.a2 = data[1].l
thread->arch.a3 = data[1].h
thread->arch.s0 = cap_protected.l
thread->arch.s1 = cap_protected.h
thread->arch.s2 = recv_protected.l
thread->arch.s3 = recv_protected.h
thread->arch.a[0] = data[0].l
thread->arch.a[1] = data[0].h
thread->arch.a[2] = data[1].l
thread->arch.a[3] = data[1].h
thread->arch.s[0] = cap_protected.l
thread->arch.s[1] = cap_protected.h
thread->arch.s[2] = recv_protected.l
thread->arch.s[3] = recv_protected.h
unsigned *kThread_arch_info (kThread *thread, unsigned num):
switch num:
case 1:
return &thread->arch.at
case 2:
return &thread->arch.v0
return &thread->arch.v[0]
case 3:
return &thread->arch.v1
return &thread->arch.v[1]
case 4:
return &thread->arch.a0
return &thread->arch.a[0]
case 5:
return &thread->arch.a1
return &thread->arch.a[1]
case 6:
return &thread->arch.a2
return &thread->arch.a[2]
case 7:
return &thread->arch.a3
return &thread->arch.a[3]
case 8:
return &thread->arch.t0
return &thread->arch.t[0]
case 9:
return &thread->arch.t1
return &thread->arch.t[1]
case 10:
return &thread->arch.t2
return &thread->arch.t[2]
case 11:
return &thread->arch.t3
return &thread->arch.t[3]
case 12:
return &thread->arch.t4
return &thread->arch.t[4]
case 13:
return &thread->arch.t5
return &thread->arch.t[5]
case 14:
return &thread->arch.t6
return &thread->arch.t[6]
case 15:
return &thread->arch.t7
return &thread->arch.t[7]
case 16:
return &thread->arch.s0
return &thread->arch.s[0]
case 17:
return &thread->arch.s1
return &thread->arch.s[1]
case 18:
return &thread->arch.s2
return &thread->arch.s[2]
case 19:
return &thread->arch.s3
return &thread->arch.s[3]
case 20:
return &thread->arch.s4
return &thread->arch.s[4]
case 21:
return &thread->arch.s5
return &thread->arch.s[5]
case 22:
return &thread->arch.s6
return &thread->arch.s[6]
case 23:
return &thread->arch.s7
return &thread->arch.s[7]
case 24:
return &thread->arch.t8
return &thread->arch.t[8]
case 25:
return &thread->arch.t9
return &thread->arch.t[9]
case 26:
return &thread->arch.k0
return &thread->arch.k[0]
case 27:
return &thread->arch.k1
return &thread->arch.k[1]
case 28:
return &thread->arch.gp
case 29:
@@ -205,6 +194,7 @@ static unsigned make_entry_lo (kPage *page, bool readonly):
bool kMemory_arch_map (kMemory *mem, kPage *page, unsigned address, bool readonly):
if address >= 0x80000000:
panic (0x32134293, "trying to map to kernel address")
return false
address &= PAGE_MASK
if !mem->arch.directory:

View File

@@ -72,47 +72,23 @@
#define SAVE_PC (6 * 4)
#define SAVE_SP (SAVE_PC + 4)
#define SAVE_AT (SAVE_SP + 4)
#define SAVE_V0 (SAVE_AT + 4)
#define SAVE_V1 (SAVE_V0 + 4)
#define SAVE_A0 (SAVE_V1 + 4)
#define SAVE_A1 (SAVE_A0 + 4)
#define SAVE_A2 (SAVE_A1 + 4)
#define SAVE_A3 (SAVE_A2 + 4)
#define SAVE_T0 (SAVE_A3 + 4)
#define SAVE_T1 (SAVE_T0 + 4)
#define SAVE_T2 (SAVE_T1 + 4)
#define SAVE_T3 (SAVE_T2 + 4)
#define SAVE_T4 (SAVE_T3 + 4)
#define SAVE_T5 (SAVE_T4 + 4)
#define SAVE_T6 (SAVE_T5 + 4)
#define SAVE_T7 (SAVE_T6 + 4)
#define SAVE_T8 (SAVE_T7 + 4)
#define SAVE_T9 (SAVE_T8 + 4)
#define SAVE_S0 (SAVE_T9 + 4)
#define SAVE_S1 (SAVE_S0 + 4)
#define SAVE_S2 (SAVE_S1 + 4)
#define SAVE_S3 (SAVE_S2 + 4)
#define SAVE_S4 (SAVE_S3 + 4)
#define SAVE_S5 (SAVE_S4 + 4)
#define SAVE_S6 (SAVE_S5 + 4)
#define SAVE_S7 (SAVE_S6 + 4)
#define SAVE_GP (SAVE_S7 + 4)
#define SAVE_V (SAVE_AT + 4)
#define SAVE_A (SAVE_V + 2 * 4)
#define SAVE_T (SAVE_A + 4 * 4)
#define SAVE_S (SAVE_T + 10 * 4)
#define SAVE_GP (SAVE_S + 8 * 4)
#define SAVE_FP (SAVE_GP + 4)
#define SAVE_RA (SAVE_FP + 4)
#define SAVE_HI (SAVE_RA + 4)
#define SAVE_LO (SAVE_HI + 4)
#define SAVE_K0 (SAVE_LO + 4)
#define SAVE_K1 (SAVE_K0 + 4)
#define SAVE_K (SAVE_LO + 4)
#ifndef ASM
void flush_tlb (unsigned asid)
struct kThread_arch:
unsigned at, v0, v1, a0, a1, a2, a3
unsigned t0, t1, t2, t3, t4, t5, t6, t7, t8, t9
unsigned s0, s1, s2, s3, s4, s5, s6, s7
unsigned gp, fp, ra, hi, lo, k0, k1
unsigned at, v[2], a[4], t[10], s[8], gp, fp, ra, hi, lo, k[2]
// The following is used for page mapping.
// Each Memory has a two directories with 0x400 entries,

View File

@@ -118,49 +118,48 @@ start_idle: // 280
// TODO: save only fragile registers now, the rest on task switch.
kernel_exit:
#ifndef NDEBUG
// Allow interrupts to set EPC and friends.
// Interrupts were enabled in the kernel; set them to usermode setting again.
mfc0 $k0, $CP0_STATUS
ori $k0, $k0, 0xff13
mtc0 $k0, $CP0_STATUS
#endif
sw $v0, -0xd8c($zero)
lw $k0, SAVE_PC($v0)
mtc0 $k0, $CP0_EPC
lw $k0, SAVE_LO($v0)
lw $k1, SAVE_HI($v0)
mtlo $k0
mthi $k1
lw $v1, SAVE_V1($v0)
lw $a0, SAVE_A0($v0)
lw $a1, SAVE_A1($v0)
lw $a2, SAVE_A2($v0)
lw $a3, SAVE_A3($v0)
lw $t0, SAVE_T0($v0)
lw $t1, SAVE_T1($v0)
lw $t2, SAVE_T2($v0)
lw $t3, SAVE_T3($v0)
lw $t4, SAVE_T4($v0)
lw $t5, SAVE_T5($v0)
lw $t6, SAVE_T6($v0)
lw $t7, SAVE_T7($v0)
lw $t8, SAVE_T8($v0)
lw $t9, SAVE_T9($v0)
lw $s0, SAVE_S0($v0)
lw $s1, SAVE_S1($v0)
lw $s2, SAVE_S2($v0)
lw $s3, SAVE_S3($v0)
lw $s4, SAVE_S4($v0)
lw $s5, SAVE_S5($v0)
lw $s6, SAVE_S6($v0)
lw $s7, SAVE_S7($v0)
lw $v1, SAVE_V + 1 * 4($v0)
lw $a0, SAVE_A + 0 * 4($v0)
lw $a1, SAVE_A + 1 * 4($v0)
lw $a2, SAVE_A + 2 * 4($v0)
lw $a3, SAVE_A + 3 * 4($v0)
lw $t0, SAVE_T + 0 * 4($v0)
lw $t1, SAVE_T + 1 * 4($v0)
lw $t2, SAVE_T + 2 * 4($v0)
lw $t3, SAVE_T + 3 * 4($v0)
lw $t4, SAVE_T + 4 * 4($v0)
lw $t5, SAVE_T + 5 * 4($v0)
lw $t6, SAVE_T + 6 * 4($v0)
lw $t7, SAVE_T + 7 * 4($v0)
lw $t8, SAVE_T + 8 * 4($v0)
lw $t9, SAVE_T + 9 * 4($v0)
lw $s0, SAVE_S + 0 * 4($v0)
lw $s1, SAVE_S + 1 * 4($v0)
lw $s2, SAVE_S + 2 * 4($v0)
lw $s3, SAVE_S + 3 * 4($v0)
lw $s4, SAVE_S + 4 * 4($v0)
lw $s5, SAVE_S + 5 * 4($v0)
lw $s6, SAVE_S + 6 * 4($v0)
lw $s7, SAVE_S + 7 * 4($v0)
lw $fp, SAVE_FP($v0)
lw $ra, SAVE_RA($v0)
lw $at, SAVE_AT($v0)
lw $k0, SAVE_K0($v0)
lw $k1, SAVE_V0($v0)
lw $k0, SAVE_K + 0 * 4($v0)
lw $k1, SAVE_V + 0 * 4($v0)
sw $k1, -0xd90($zero)
lw $k1, SAVE_K1($v0)
sw $v0, -0xd8c($zero)
lw $k1, SAVE_K + 1 * 4($v0)
lw $sp, SAVE_SP($v0)
lw $gp, SAVE_GP($v0)
lw $v0, -0xd90($zero)
@@ -175,36 +174,36 @@ save_regs:
sw $sp, SAVE_SP($k0)
sw $fp, SAVE_FP($k0)
sw $k1, SAVE_K1($k0)
sw $k1, SAVE_K + 4($k0)
lw $k1, -0xd90($zero)
sw $k1, SAVE_K0($k0)
sw $k1, SAVE_K + 0($k0)
lw $k1, -0xd88($zero)
sw $k1, SAVE_RA($k0)
sw $v0, SAVE_V0($k0)
sw $v1, SAVE_V1($k0)
sw $a0, SAVE_A0($k0)
sw $a1, SAVE_A1($k0)
sw $a2, SAVE_A2($k0)
sw $a3, SAVE_A3($k0)
sw $t0, SAVE_T0($k0)
sw $t1, SAVE_T1($k0)
sw $t2, SAVE_T2($k0)
sw $t3, SAVE_T3($k0)
sw $t4, SAVE_T4($k0)
sw $t5, SAVE_T5($k0)
sw $t6, SAVE_T6($k0)
sw $t7, SAVE_T7($k0)
sw $t8, SAVE_T8($k0)
sw $t9, SAVE_T9($k0)
sw $s0, SAVE_S0($k0)
sw $s1, SAVE_S1($k0)
sw $s2, SAVE_S2($k0)
sw $s3, SAVE_S3($k0)
sw $s4, SAVE_S4($k0)
sw $s5, SAVE_S5($k0)
sw $s6, SAVE_S6($k0)
sw $s7, SAVE_S7($k0)
sw $v0, SAVE_V + 0 * 4($k0)
sw $v1, SAVE_V + 1 * 4($k0)
sw $a0, SAVE_A + 0 * 4($k0)
sw $a1, SAVE_A + 1 * 4($k0)
sw $a2, SAVE_A + 2 * 4($k0)
sw $a3, SAVE_A + 3 * 4($k0)
sw $t0, SAVE_T + 0 * 4($k0)
sw $t1, SAVE_T + 1 * 4($k0)
sw $t2, SAVE_T + 2 * 4($k0)
sw $t3, SAVE_T + 3 * 4($k0)
sw $t4, SAVE_T + 4 * 4($k0)
sw $t5, SAVE_T + 5 * 4($k0)
sw $t6, SAVE_T + 6 * 4($k0)
sw $t7, SAVE_T + 7 * 4($k0)
sw $t8, SAVE_T + 8 * 4($k0)
sw $t9, SAVE_T + 9 * 4($k0)
sw $s0, SAVE_S + 0 * 4($k0)
sw $s1, SAVE_S + 1 * 4($k0)
sw $s2, SAVE_S + 2 * 4($k0)
sw $s3, SAVE_S + 3 * 4($k0)
sw $s4, SAVE_S + 4 * 4($k0)
sw $s5, SAVE_S + 5 * 4($k0)
sw $s6, SAVE_S + 6 * 4($k0)
sw $s7, SAVE_S + 7 * 4($k0)
mfhi $v0
mflo $v1
sw $v0, SAVE_HI($k0)

View File

@@ -22,6 +22,10 @@
#include "../kernel.hh"
#include <elf.h>
#define NUM_SLOTS 4
#define NUM_CAPS 16
#define NUM_TMP_CAPS 2
static void init_idle ():
// initialize idle task as if it is currently running.
idle.prev = NULL
@@ -111,7 +115,7 @@ static void init_threads ():
for unsigned i = 0; i < NUM_THREADS; ++i:
kMemory *mem = top_memory.alloc_memory ()
assert (mem)
kThread *thread = mem->alloc_thread (3)
kThread *thread = mem->alloc_thread (NUM_SLOTS)
kPage **pages = (kPage **)mem->zalloc ()
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
for unsigned j = 0; j < SELFMAG; ++j:
@@ -174,7 +178,7 @@ static void init_threads ():
panic (0x02220022, "out of memory");
return
page->flags = Page::PAYING | Page::FRAME
if !mem->map (page, p, true):
if !mem->map (page, p):
panic (0x33557799, "unable to map initial bss page")
return
else:
@@ -195,10 +199,13 @@ static void init_threads ():
kPage *stackpage = mem->alloc_page ()
stackpage->frame = mem->zalloc ()
stackpage->flags = Page::PAYING | Page::FRAME
if !stackpage || !mem->map (stackpage, 0x7ffff000, true):
if !stackpage || !mem->map (stackpage, 0x7ffff000):
panic (0x13151719, "unable to map initial stack page")
return
thread->caps[0] = mem->alloc_caps (16)
thread->caps[0] = mem->alloc_caps (NUM_CAPS)
thread->caps[__tmp_slot] = mem->alloc_caps (NUM_TMP_CAPS)
thread->arch.a[0] = NUM_SLOTS
thread->arch.a[1] = NUM_CAPS
kReceiver *recv = mem->alloc_receiver ()
recv->owner = thread
thread->receivers = recv
@@ -220,7 +227,10 @@ static void init_threads ():
// Initialize the kernel, finish by falling into the idle task.
void init (unsigned mem):
#ifndef NDEBUG
dbg_code = 0
#endif
must_wait = false
// Disable interrupts and set interrupt vectors to normal.
cp0_set0 (CP0_STATUS)
// Initialize kernel variables to empty.

View File

@@ -25,6 +25,8 @@ void arch_flush_cache ():
__asm__ volatile ("lw $k0, %0; cache 0, 0($k0); cache 1, 0($k0)" :: "m"(line))
static void handle_exit ():
// Set must_wait to false, so random threads are not set to waiting when the kernel invokes something (such as a dbg_cap).
must_wait = false
if !current || (current == &idle):
schedule ()
if !current:
@@ -35,6 +37,7 @@ static void handle_exit ():
current = &idle
if old_current == current:
return
//dbg_send ((unsigned)current >> 12, 3)
arch_flush_cache ()
if current != &idle:
if (kMemory *)asids[current->address_space->arch.asid] != current->address_space:
@@ -124,40 +127,40 @@ void flush_tlb (unsigned asid):
static void arch_invoke ():
kCapRef target
bool wait
target = old_current->find_capability (old_current->arch.v0, &wait)
target = old_current->find_capability (old_current->arch.v[0], &must_wait)
do_schedule = false
kCapability::Context msg
unsigned num = old_current->arch.s2
unsigned first = old_current->arch.s3
if num:
if num > 10:
num = 10
bool copy
if old_current->arch.s1 < old_current->slots:
msg.caps = old_current->caps[old_current->arch.s1]
if msg.caps && first < msg.caps->size:
for unsigned i = first; i < num && i < msg.caps->size; ++i:
msg.caps->cap (i)->invalidate ()
kCapRef t = old_current->find_capability ((&old_current->arch.t0)[i], &copy)
if t:
msg.caps->clone (i, t, copy)
else:
msg.caps = NULL
unsigned num = old_current->arch.s[2]
unsigned first = old_current->arch.s[3]
if num > 2:
dpanic (0x23451234, "too many capabilities")
num = 2
if old_current->arch.s[1] < old_current->slots:
msg.caps = old_current->caps[old_current->arch.s[1]]
if msg.caps:
for unsigned i = 0; i < num && first + i < msg.caps->size; ++i:
unsigned code = old_current->arch.t[i]
msg.caps->cap (first + i)->invalidate ()
bool copy
kCapRef t = old_current->find_capability (code, &copy)
if t.valid ():
msg.caps->clone (first + i, t, copy)
else:
if num:
dpanic (0x34566244, "num without caps")
if old_current->arch.s[1] != ~0:
dpanic (0x28849932, "non-~0 slot too high")
msg.caps = NULL
if wait:
old_current->recv_slot = old_current->arch.s0
old_current->wait ()
if !target:
if (old_current->arch.v0 & ~CAP_COPY) != ~CAP_COPY:
panic (old_current->arch.v0, "debug")
// There must be no action here.
if must_wait:
old_current->recv_slot = old_current->arch.s[0]
if !target.valid ():
if must_wait:
old_current->wait ()
return
msg.data[0] = Num (old_current->arch.a0, old_current->arch.a1)
msg.data[1] = Num (old_current->arch.a2, old_current->arch.a3)
msg.data[0] = Num (old_current->arch.a[0], old_current->arch.a[1])
msg.data[1] = Num (old_current->arch.a[2], old_current->arch.a[3])
target->invoke (&msg)
if do_schedule && !wait:
if do_schedule && !must_wait:
// If the call was to schedule without wait, it isn't done yet.
schedule ()
else if old_current != current && (old_current->flags & (Thread::RUNNING | Thread::WAITING)) == Thread::RUNNING:
@@ -216,28 +219,35 @@ kThread *exception ():
// Syscall.
current->pc += 4
arch_invoke ()
//check (0x88392883, "check error")
break
case 9:
// Breakpoint.
#if 0
current->raise (ERR_BREAKPOINT, 0)
#if 0 || defined (NDEBUG)
//current->raise (ERR_BREAKPOINT, 0)
#ifndef NDEBUG
current->pc += 4
#endif
#else
current->pc += 4
if current->arch.a0:
if dbg_cap:
panic (0, "Break instruction while log capability was already set")
if current->arch.a[0]:
if dbg_cap.valid ():
dpanic (0, "Break instruction while log capability was already set")
break
bool dummy
dbg_cap = current->find_capability (current->arch.a1, &dummy)
if !dbg_cap:
panic (0, "no log capability provided")
dbg_cap = current->find_capability (current->arch.a[1], &dummy)
if !dbg_cap.valid ():
dpanic (0, "no log capability provided")
break
dbg_log ("debug capability registered. thread = ")
dbg_log_num ((unsigned)current)
dbg_log_char ('\n')
break
if dbg_cap:
dbg_log_char (current->arch.a1)
if dbg_cap.valid ():
dbg_log_char (current->arch.a[1])
break
break
#endif
break
case 10:
// Reserved instruction.
current->raise (ERR_RESERVED_INSTRUCTION, 0)

View File

@@ -140,9 +140,9 @@
static void __map_io (unsigned physical, unsigned mapping):
Page p = __my_memory.create_page ()
// false means not cachable; false means don't free when done.
p.alloc_physical (physical, 0, 0)
// true means writable.
__my_memory.map (p, mapping, true)
p.alloc_physical (physical, false, false)
__my_memory.map (p, mapping)
free_cap (p)
#define map_harb() do { __map_io (HARB_PHYSICAL, HARB_BASE); } while (0)
#define map_emc() do { __map_io (EMC_PHYSICAL, EMC_BASE); } while (0)