1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-07-01 00:44:31 +03:00

working again with new paging layout

This commit is contained in:
Bas Wijnen 2009-05-27 14:38:52 +02:00
parent e13dc897fd
commit 35fb72c239
7 changed files with 108 additions and 33 deletions

View File

@ -28,7 +28,9 @@ extern "C" {
#define CAP_RECEIVER_CREATE_CAPABILITY 2
#define CAP_RECEIVER_CREATE_CALL_CAPABILITY 3
/* Not an operation; a capability with this bit set is a call capability. */
#define CAP_RECEIVER_CALL 4
#define CAP_RECEIVER_CALL 8
/* Same thing for reply capability. */
#define CAP_RECEIVER_REPLY 9
#define CAP_MEMORY_CREATE 1
#define CAP_MEMORY_DESTROY 2
@ -44,6 +46,8 @@ extern "C" {
/* Flag values for processor state */
#define THREAD_FLAG_WAITING 0x80000000
#define THREAD_FLAG_RUNNING 0x40000000
#define THREAD_FLAG_PRIV 0x20000000
#define THREAD_FLAG_USER 0x1fffffff
#define CAP_PAGE_MAP 1
#define CAP_PAGE_SHARE 2

18
entry.S
View File

@ -11,6 +11,7 @@
#include "arch.hh"
addr_000:
#if 0
// TLB refill
bne $zero, $k0, slow_refill
nop
@ -40,8 +41,10 @@ addr_000:
slow_refill0:
move $k1, $zero
slow_refill:
#endif
sw $ra, -0xd88($zero)
bal save_regs
nop
la $t9, tlb_refill
jr $t9
nop
@ -50,26 +53,33 @@ addr_100:
// Cache error
sw $ra, -0xd88($zero)
bal save_regs
nop
la $t9, cache_error
jr $t9
nop
.fill 0x180 - (. - addr_000)
addr_180:
// General exception
// Allow new exceptions to update EPC and friends.
mtc0 $zero, $CP0_STATUS
sw $ra, -0xd88($zero)
bal save_regs
nop
la $t9, exception
jr $t9
nop
.fill 0x200 - (. - addr_000)
.fill 0x200 - (. - addr_000) - 8
.word 0x0000001e // 1f8 EntryLo data for idle page.
.word 0x80000000 // 1fc A pointer to the current page.
addr_200:
// Interrupt
sw $ra, -0xd88($zero)
bal save_regs
nop
la $t9, interrupt
jr $t9
nop
.fill 0x280 - (. - addr_000) - 16
.fill 0x280 - (. - addr_000) - 20
directory:
.word 0 // -d94 == directory
@ -79,9 +89,7 @@ directory:
.word 0 // -d88 == ra
.word _gp // -d84 == gp
.word idle_page // 280
.word 0x80000000 // 284 A pointer to the current page.
start_idle: // 288
start_idle: // 280
// Wait for the next interrupt, then the first thread will be scheduled.
// It is impractical to try to call schedule, because for that the
// idle task would need to own capabilities.

View File

@ -24,6 +24,8 @@ static void init_idle ():
idle_memory.limit = 0
idle_memory.used = 0
idle_memory.arch.directory = (unsigned **)0x80000000
// Shadow is never used for the idle task.
idle_memory.arch.shadow = NULL
idle_memory.arch.asid = 0
// initialize idle_page
idle_page.prev = NULL
@ -69,12 +71,16 @@ static void init_cp0 ():
cp0_set0 (CP0_INDEX)
__asm__ volatile ("tlbwi")
// Fill the idle task's page in useg. Set it to non-cachable.
cp0_set (CP0_ENTRY_HI, 0x284a0000)
// its directory entry is at 1fc, so it's number 7f (0fe00000).
// its table entry is at 1f8, so it's number 7e (0007e000).
// its address is 280 (00000280), used below for EPC.
unsigned const idle_entry_hi = 0x0fe7e000
cp0_set (CP0_ENTRY_HI, idle_entry_hi)
cp0_set (CP0_ENTRY_LO0, 0x16)
cp0_set (CP0_ENTRY_LO1, 0x14)
__asm__ volatile ("tlbwr")
// Allow eret to be used to jump to the idle task.
cp0_set (CP0_EPC, 0x284a0288)
cp0_set (CP0_EPC, (idle_entry_hi & PAGE_MASK) | 0x280)
// Wait with initializing the status register until the last moment, so that
// exceptions in the bootup code will fill EPC and friends.

View File

@ -41,6 +41,7 @@ Thread *interrupt ():
Thread *exception ():
unsigned cause
cp0_get (CP0_CAUSE, cause)
//dbg_send (cause >> 2, 5)
switch (cause >> 2) & 0x1f:
case 0:
// Interrupt. This shouldn't happen, since CAUSE[IV] == 1.
@ -68,10 +69,8 @@ Thread *exception ():
panic (0x81223344, "Bus error load or store.")
case 8:
// Syscall.
// DEBUG: allow new exceptions.
//cp0_set0 (CP0_STATUS)
arch_invoke ()
return current
break
case 9:
// Breakpoint.
panic (0x91223344, "Breakpoint.")

View File

@ -20,6 +20,7 @@ Capability *Memory::find_capability (unsigned code, bool *copy):
return NULL
static Capability *reply
static Receiver *reply_receiver
static void reply_cap (unsigned target, unsigned protected_data):
Capability r
@ -33,19 +34,28 @@ static void reply_cap (unsigned target, unsigned protected_data):
unsigned d[4] = { 0, 0, 0, 0 }
Capability *caps[4] = { &r, NULL, NULL, NULL }
bool cops[4] = { true, false, false, false }
reply->invoke (d, caps, cops)
if reply:
reply->invoke (d, caps, cops)
else:
// TODO: send message to reply_receiver
static void reply_cap (Capability *cap, bool copy):
unsigned d[4] = { 0, 0, 0, 0 }
Capability *caps[4] = { cap, NULL, NULL, NULL }
bool cops[4] = { copy, false, false, false }
reply->invoke (d, caps, cops)
if reply:
reply->invoke (d, caps, cops)
else:
// TODO: send message to reply_receiver
static void reply_num (unsigned num):
unsigned d[4] = { num, 0, 0, 0 }
Capability *caps[4] = { NULL, NULL, NULL, NULL }
bool cops[4] = { false, false, false, false }
reply->invoke (d, caps, cops)
if reply:
reply->invoke (d, caps, cops)
else:
// TODO: send message to reply_receiver
static void admin_invoke (unsigned target, Capability *cap, unsigned request, unsigned data):
switch request:
@ -117,7 +127,32 @@ static void memory_invoke (unsigned target, unsigned protected_data, Capability
return
break
case CAP_MEMORY_DESTROY:
// TODO
if !cap || cap->address_space != mem || (unsigned)cap->target & ~KERNEL_MASK:
return
switch (unsigned)cap->target & CAPTYPE_MASK:
case CAPTYPE_ADMIN:
// Admin capabilities don't take space, so they cannot be destroyed.
return
case CAPTYPE_RECEIVER:
mem->free_receiver ((Receiver *)cap->protected_data)
return
case CAPTYPE_MEMORY:
mem->free_memory ((Memory *)cap->protected_data)
return
case CAPTYPE_THREAD:
mem->free_thread ((Thread *)cap->protected_data)
return
case CAPTYPE_PAGE:
mem->free_page ((Page *)cap->protected_data)
return
case CAPTYPE_CAPABILITY:
mem->free_capability ((Capability *)cap->protected_data)
return
case CAPTYPE_CAPPAGE:
mem->free_cappage ((Cappage *)cap->protected_data)
return
default:
panic (0x55228930, "invalid case")
break
case CAP_MEMORY_LIST:
// TODO
@ -205,7 +240,7 @@ static bool kernel_invoke (unsigned target, unsigned protected_data, unsigned d[
// other parameters' meanings depend on the operation.
if !((1 << d[0]) & target & ~REQUEST_MASK):
// You are not allowed to perform this operation.
return false
return true
reply = c[0]
if d[0] == CAP_DEGRADE:
reply_cap (target & d[1], protected_data)
@ -215,10 +250,21 @@ static bool kernel_invoke (unsigned target, unsigned protected_data, unsigned d[
admin_invoke (target, c[1], d[0], d[1])
break
case CAPTYPE_RECEIVER:
if target & CAP_RECEIVER_CALL:
if target & (1 << CAP_RECEIVER_CALL):
// This is a call capability.
protected_data = c[0]->protected_data
target = (unsigned)c[0]->target
if ~(unsigned)c[0]->target & ~KERNEL_MASK:
// TODO: create reply capability.
else:
// Kernel call: don't create actual capablities.
reply = NULL
reply_receiver = (Receiver *)protected_data
return kernel_invoke (target, protected_data, d, c, copy)
if target & (1 << CAP_RECEIVER_REPLY):
// This is a reply capability.
// TODO
return false
return true
receiver_invoke (target, protected_data, c[1], d[0], d[1])
break
case CAPTYPE_MEMORY:

View File

@ -139,6 +139,8 @@ bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
if !mem->arch.first_page_table:
mem->zfree ((unsigned)mem->arch.directory)
mem->zfree ((unsigned)mem->arch.shadow)
mem->arch.directory = NULL
mem->arch.shadow = NULL
return false
t = alloc_page_table (mem)
if !t:
@ -146,8 +148,11 @@ bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
if !mem->arch.first_page_table:
mem->zfree ((unsigned)mem->arch.directory)
mem->zfree ((unsigned)mem->arch.shadow)
mem->arch.directory = NULL
mem->arch.shadow = NULL
return false
mem->arch.directory[address >> 21] = table
mem->arch.shadow[address >> 21] = t
arch_page *p = alloc_page (mem, t)
if !p:
if !t->first_page:
@ -157,7 +162,7 @@ bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
unsigned idx = (address >> 12) & ((1 << 9) - 1)
if table[idx]:
mem->unmap ((Page *)table[idx + 0x200], address)
table[idx] = page->physical ? (page->physical >> 6) | 0x18 | (write ? 0x4 : 0) | 0x2 : 0
table[idx] = page->physical ? ((page->physical & ~0x80000000) >> 6) | 0x18 | (write ? 0x4 : 0) | 0x2 : 0
table[idx + 0x200] = (unsigned)p
p->mapping = address
p->page = page
@ -199,17 +204,17 @@ void arch_invoke ():
schedule ()
// Calling an invalid capability always fails.
caller->arch.v0 = 0
return
c[0] = caller->address_space->find_capability (caller->arch.a0, &copy[0])
c[1] = caller->address_space->find_capability (caller->arch.a1, &copy[1])
c[2] = caller->address_space->find_capability (caller->arch.a2, &copy[2])
c[3] = caller->address_space->find_capability (caller->arch.a3, &copy[3])
unsigned d[4]
d[0] = caller->arch.t0
d[1] = caller->arch.t1
d[2] = caller->arch.t2
d[3] = caller->arch.t3
caller->arch.v0 = target->invoke (d, c, copy) ? 1 : 0
else:
c[0] = caller->address_space->find_capability (caller->arch.a0, &copy[0])
c[1] = caller->address_space->find_capability (caller->arch.a1, &copy[1])
c[2] = caller->address_space->find_capability (caller->arch.a2, &copy[2])
c[3] = caller->address_space->find_capability (caller->arch.a3, &copy[3])
unsigned d[4]
d[0] = caller->arch.t0
d[1] = caller->arch.t1
d[2] = caller->arch.t2
d[3] = caller->arch.t3
caller->arch.v0 = target->invoke (d, c, copy) ? 1 : 0
if caller != current:
if (Memory *)asids[current->address_space->arch.asid] != current->address_space:
if asids[0]:
@ -223,6 +228,12 @@ void arch_invoke ():
++random
if random >= 64:
random = 1
asids[current->address_space->arch.asid] = (unsigned)current
asids[current->address_space->arch.asid] = (unsigned)current->address_space
cp0_set (CP0_ENTRY_HI, current->address_space->arch.asid)
directory = current->address_space->arch.directory
unsigned status
cp0_get (CP0_STATUS, status)
status &= 0x0fffffff
if current->flags & THREAD_FLAG_PRIV:
status |= 0x10000000
cp0_set (CP0_STATUS, status | 0x13)

View File

@ -80,7 +80,7 @@ void dbg_sleep (unsigned ms):
__gpio_as_output (CAPSLOCKLED_IO)
void dbg_send (unsigned code, unsigned bits):
for int i = bits; i >= 0; --i:
for int i = bits - 1; i >= 0; --i:
bool on = code & (1 << i)
dbg_led (false, false, false)
dbg_sleep (200)
@ -92,5 +92,6 @@ void dbg_send (unsigned code, unsigned bits):
dbg_led (false, false, false)
dbg_sleep (200)
dbg_led (true, true, false)
dbg_sleep (200)
dbg_sleep (500)
dbg_led (false, false, false)
dbg_sleep (500)