mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
reorganize capabilities; doesn't work yet
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
|
||||
load = 0x80000000
|
||||
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=3
|
||||
ARCH_CXXFLAGS = -DNUM_THREADS=2
|
||||
ARCH_CPPFLAGS = -Imips -Wa,-mips32
|
||||
CROSS = mipsel-linux-gnu-
|
||||
OBJDUMP = $(CROSS)objdump
|
||||
@@ -34,7 +34,7 @@ uimage:
|
||||
mips/entry.o: $(boot_threads)
|
||||
mips/init.o: TARGET_FLAGS = -I/usr/include
|
||||
$(boot_threads): TARGET_FLAGS = -I.
|
||||
$(boot_threads): boot-programs/devices.hh
|
||||
$(addprefix boot-programs/,$(addsuffix .cc,$(boot_threads))): boot-programs/devices.hh
|
||||
lcd: boot-programs/charset.data
|
||||
|
||||
boot-programs/charset.data: boot-programs/charset
|
||||
|
||||
@@ -45,15 +45,11 @@ void Thread_arch_init (Thread *thread):
|
||||
thread->arch.k0 = 0
|
||||
thread->arch.k1 = 0
|
||||
|
||||
void Thread_arch_receive (Thread *thread, unsigned protected_data, Capability::Context *c):
|
||||
thread->arch.a0 = (unsigned)c->cap[0]
|
||||
thread->arch.a1 = (unsigned)c->cap[1]
|
||||
thread->arch.a2 = (unsigned)c->cap[2]
|
||||
thread->arch.a3 = (unsigned)c->cap[3]
|
||||
thread->arch.t0 = c->data[0]
|
||||
thread->arch.t1 = c->data[1]
|
||||
thread->arch.t2 = c->data[2]
|
||||
thread->arch.t3 = c->data[3]
|
||||
void Thread_arch_receive (Thread *thread, unsigned protected_data, unsigned *data):
|
||||
thread->arch.t0 = data[0]
|
||||
thread->arch.t1 = data[1]
|
||||
thread->arch.t2 = data[2]
|
||||
thread->arch.t3 = data[3]
|
||||
thread->arch.v0 = protected_data
|
||||
|
||||
unsigned *Thread_arch_info (Thread *thread, unsigned num):
|
||||
@@ -193,16 +189,16 @@ static void free_page (arch_page_table *t, arch_page *p):
|
||||
free_page_table (t, idx)
|
||||
|
||||
static unsigned make_entry_lo (Page *page, bool write):
|
||||
if !page->data.frame:
|
||||
if !page->frame:
|
||||
return 0
|
||||
unsigned flags
|
||||
if page->data.flags & PAGE_FLAG_UNCACHED:
|
||||
if page->flags & PAGE_FLAG_UNCACHED:
|
||||
flags = 0x10 | 0x2
|
||||
else:
|
||||
flags = 0x18 | 0x2
|
||||
if write:
|
||||
flags |= 0x4
|
||||
return ((page->data.frame & ~0x80000000) >> 6) | flags
|
||||
return ((page->frame & ~0x80000000) >> 6) | flags
|
||||
|
||||
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
|
||||
if address >= 0x80000000:
|
||||
@@ -282,7 +278,7 @@ void Page_arch_update_mapping (Page *page):
|
||||
if !page->arch.first_mapped:
|
||||
return
|
||||
Memory *as = page->address_space
|
||||
unsigned target = make_entry_lo (page, page->data.flags & PAGE_FLAG_WRITABLE)
|
||||
unsigned target = make_entry_lo (page, page->flags & PAGE_FLAG_WRITABLE)
|
||||
for arch_page *p = page->arch.first_mapped; p; p = p->next_mapped:
|
||||
unsigned de = p->mapping >> 21
|
||||
unsigned te = (p->mapping >> 12) & ((1 << 9) - 1)
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
#ifdef __KERNEL
|
||||
// register save positions in Thread
|
||||
#define SAVE_PC (5 * 4)
|
||||
#define SAVE_PC (6 * 4)
|
||||
#define SAVE_SP (SAVE_PC + 4)
|
||||
#define SAVE_AT (SAVE_SP + 4)
|
||||
#define SAVE_V0 (SAVE_AT + 4)
|
||||
@@ -122,12 +122,12 @@ struct Thread_arch:
|
||||
// bits 12-20 are an index in the page table, bits 21-30
|
||||
// are an index in the page directory and bit 31 is always 0.
|
||||
|
||||
struct arch_page : public Object <arch_page> :
|
||||
struct arch_page : public Object :
|
||||
Page *page
|
||||
unsigned mapping
|
||||
arch_page *prev_mapped, *next_mapped
|
||||
|
||||
struct arch_page_table : public Object <arch_page_table> :
|
||||
struct arch_page_table : public Object :
|
||||
arch_page *first_page
|
||||
|
||||
struct Page_arch:
|
||||
|
||||
@@ -29,13 +29,13 @@ static void init_idle ():
|
||||
idle.schedule_prev = NULL
|
||||
idle.schedule_next = NULL
|
||||
idle.address_space = &idle_memory
|
||||
idle.refs = NULL
|
||||
idle.refs.reset ()
|
||||
idle.flags = THREAD_FLAG_RUNNING | THREAD_FLAG_PRIV
|
||||
// initialize idle_memory.
|
||||
idle_memory.prev = NULL
|
||||
idle_memory.next = NULL
|
||||
idle_memory.address_space = NULL
|
||||
idle_memory.refs = NULL
|
||||
idle_memory.refs.reset ()
|
||||
idle_memory.pages = &idle_page
|
||||
idle_memory.threads = &idle
|
||||
idle_memory.memories = NULL
|
||||
@@ -48,9 +48,9 @@ static void init_idle ():
|
||||
// initialize idle_page
|
||||
idle_page.prev = NULL
|
||||
idle_page.next = NULL
|
||||
idle_page.data.frame = 0x80000000
|
||||
idle_page.data.flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
idle_page.refs = NULL
|
||||
idle_page.frame = 0x80000000
|
||||
idle_page.flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
idle_page.refs.reset ()
|
||||
idle_page.address_space = NULL
|
||||
current = &idle
|
||||
directory = idle_memory.arch.directory
|
||||
@@ -103,10 +103,6 @@ static void init_cp0 ():
|
||||
// Wait with initializing the status register until the last moment, so that
|
||||
// exceptions in the bootup code will fill EPC and friends.
|
||||
|
||||
// This returns unsigned, because the value is used to fill thread->arch.a*.
|
||||
static unsigned mkcap (Memory *mem, unsigned type, void *obj):
|
||||
return (unsigned)mem->alloc_capability ((Receiver *)type, NULL, &mem->capabilities, (unsigned)obj)
|
||||
|
||||
static void init_threads ():
|
||||
Thread *previous = NULL
|
||||
first_scheduled = NULL
|
||||
@@ -115,7 +111,7 @@ static void init_threads ():
|
||||
for unsigned i = 0; i < NUM_THREADS; ++i:
|
||||
Memory *mem = top_memory.alloc_memory ()
|
||||
assert (mem)
|
||||
Thread *thread = mem->alloc_thread ()
|
||||
Thread *thread = mem->alloc_thread (3)
|
||||
Page **pages = (Page **)mem->zalloc ()
|
||||
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
|
||||
for unsigned j = 0; j < SELFMAG; ++j:
|
||||
@@ -155,8 +151,8 @@ static void init_threads ():
|
||||
unsigned idx = file_offset + section_offset
|
||||
if !pages[idx]:
|
||||
pages[idx] = mem->alloc_page ()
|
||||
pages[idx]->data.frame = thread_start[i] + (idx << PAGE_BITS)
|
||||
pages[idx]->data.flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
pages[idx]->frame = thread_start[i] + (idx << PAGE_BITS)
|
||||
pages[idx]->flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
++top_memory.limit
|
||||
mem->use ()
|
||||
if !mem->map (pages[idx], p, writable):
|
||||
@@ -173,11 +169,11 @@ static void init_threads ():
|
||||
if !page:
|
||||
panic (0x00220022, "out of memory")
|
||||
return
|
||||
page->data.frame = mem->zalloc ()
|
||||
if !page->data.frame:
|
||||
page->frame = mem->zalloc ()
|
||||
if !page->frame:
|
||||
panic (0x02220022, "out of memory");
|
||||
return
|
||||
page->data.flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
page->flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
if !mem->map (page, p, true):
|
||||
panic (0x33557799, "unable to map initial bss page")
|
||||
return
|
||||
@@ -190,31 +186,34 @@ static void init_threads ():
|
||||
break
|
||||
if a < shdr->sh_addr:
|
||||
continue
|
||||
((unsigned *)page->data.frame)[(a & ~PAGE_MASK) >> 2] = 0
|
||||
((unsigned *)page->frame)[(a & ~PAGE_MASK) >> 2] = 0
|
||||
for unsigned p = 0; p <= ((thread_start[i + 1] - thread_start[i] - 1) >> PAGE_BITS); ++p:
|
||||
if pages[p]:
|
||||
continue
|
||||
++top_memory.limit
|
||||
top_memory.pfree (thread_start[i] + (p << PAGE_BITS))
|
||||
Page *stackpage = mem->alloc_page ()
|
||||
stackpage->data.frame = mem->zalloc ()
|
||||
stackpage->data.flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
stackpage->frame = mem->zalloc ()
|
||||
stackpage->flags = PAGE_FLAG_WRITABLE | PAGE_FLAG_PAYING | PAGE_FLAG_FRAME
|
||||
if !stackpage || !mem->map (stackpage, 0x7ffff000, true):
|
||||
panic (0x13151719, "unable to map initial stack page")
|
||||
return
|
||||
thread->caps[0] = mem->alloc_caps (16)
|
||||
for unsigned r = 0; r < 4; ++r:
|
||||
thread->rcaps[r] = CapRef ()
|
||||
Receiver *recv = mem->alloc_receiver ()
|
||||
recv->owner = thread
|
||||
thread->receivers = recv
|
||||
thread->arch.a0 = mkcap (mem, CAPTYPE_RECEIVER | CAP_RECEIVER_ALL_RIGHTS, recv)
|
||||
thread->arch.a1 = mkcap (mem, CAPTYPE_THREAD | CAP_THREAD_ALL_PRIV_RIGHTS, thread)
|
||||
thread->arch.a2 = mkcap (mem, CAPTYPE_MEMORY | CAP_MEMORY_ALL_RIGHTS, mem)
|
||||
thread->arch.a3 = mkcap (mem, CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_CALL), recv)
|
||||
thread->caps[0]->set (__my_receiver, (ReceiverP)(CAPTYPE_RECEIVER | CAP_RECEIVER_ALL_RIGHTS), (Protected)recv, CapRef ())
|
||||
thread->caps[0]->set (__my_thread, (ReceiverP)(CAPTYPE_THREAD | CAP_THREAD_ALL_PRIV_RIGHTS), (Protected)thread, CapRef ())
|
||||
thread->caps[0]->set (__my_memory, (ReceiverP)(CAPTYPE_MEMORY | CAP_MEMORY_ALL_RIGHTS), (Protected)mem, CapRef ())
|
||||
thread->caps[0]->set (__my_call, (ReceiverP)(CAPTYPE_RECEIVER | (1 << CAP_RECEIVER_CALL)), (Protected)recv, CapRef ())
|
||||
thread->flags = THREAD_FLAG_RUNNING | THREAD_FLAG_PRIV
|
||||
if !i:
|
||||
first_scheduled = thread
|
||||
init_receiver = recv
|
||||
else:
|
||||
thread->arch.t0 = mkcap (mem, (unsigned)init_receiver, (void *)i)
|
||||
thread->caps[0]->set (__my_parent, init_receiver, i, CapRef ())
|
||||
previous->schedule_next = thread
|
||||
thread->schedule_prev = previous
|
||||
thread->schedule_next = NULL
|
||||
@@ -236,7 +235,7 @@ void init (unsigned mem):
|
||||
top_memory.prev = NULL
|
||||
top_memory.next = NULL
|
||||
top_memory.address_space = NULL
|
||||
top_memory.refs = NULL
|
||||
top_memory.refs.reset ()
|
||||
top_memory.pages = NULL
|
||||
top_memory.threads = NULL
|
||||
top_memory.memories = NULL
|
||||
|
||||
@@ -101,7 +101,7 @@ Thread *interrupt ():
|
||||
Capability::Context c
|
||||
for unsigned j = 0; j < 4; ++j:
|
||||
c.data[j] = 0
|
||||
c.cap[j] = NULL
|
||||
c.cap[j].reset ()
|
||||
c.copy[j] = false
|
||||
arch_interrupt_receiver[i]->send_message (i, &c)
|
||||
arch_interrupt_receiver[i] = NULL
|
||||
@@ -124,20 +124,26 @@ void flush_tlb (unsigned asid):
|
||||
__asm__ volatile ("tlbwi")
|
||||
|
||||
static void arch_invoke ():
|
||||
Capability *target
|
||||
CapRef target
|
||||
bool wait
|
||||
target = old_current->address_space->find_capability (old_current->arch.v0, &wait)
|
||||
target = old_current->find_capability (old_current->arch.v0, &wait)
|
||||
do_schedule = false
|
||||
if wait:
|
||||
old_current->wait ()
|
||||
bool dummy
|
||||
CapRef c0, c1, c2, c3
|
||||
c0 = old_current->find_capability (old_current->arch.t4, &dummy)
|
||||
c1 = old_current->find_capability (old_current->arch.t5, &dummy)
|
||||
c2 = old_current->find_capability (old_current->arch.t6, &dummy)
|
||||
c3 = old_current->find_capability (old_current->arch.t7, &dummy)
|
||||
old_current->wait (c0, c1, c2, c3)
|
||||
if !target:
|
||||
// There must be no action here.
|
||||
else:
|
||||
Capability::Context c
|
||||
c.cap[0] = old_current->address_space->find_capability (old_current->arch.a0, &c.copy[0])
|
||||
c.cap[1] = old_current->address_space->find_capability (old_current->arch.a1, &c.copy[1])
|
||||
c.cap[2] = old_current->address_space->find_capability (old_current->arch.a2, &c.copy[2])
|
||||
c.cap[3] = old_current->address_space->find_capability (old_current->arch.a3, &c.copy[3])
|
||||
c.cap[0] = old_current->find_capability (old_current->arch.a0, &c.copy[0])
|
||||
c.cap[1] = old_current->find_capability (old_current->arch.a1, &c.copy[1])
|
||||
c.cap[2] = old_current->find_capability (old_current->arch.a2, &c.copy[2])
|
||||
c.cap[3] = old_current->find_capability (old_current->arch.a3, &c.copy[3])
|
||||
c.data[0] = old_current->arch.t0
|
||||
c.data[1] = old_current->arch.t1
|
||||
c.data[2] = old_current->arch.t2
|
||||
@@ -207,7 +213,7 @@ Thread *exception ():
|
||||
break
|
||||
case 9:
|
||||
// Breakpoint.
|
||||
#if 0
|
||||
#if 1
|
||||
current->raise (ERR_BREAKPOINT, 0)
|
||||
#else
|
||||
current->pc += 4
|
||||
@@ -216,7 +222,7 @@ Thread *exception ():
|
||||
panic (0, "Break instruction while log capability was already set")
|
||||
break
|
||||
bool dummy
|
||||
dbg_cap = current->address_space->find_capability (current->arch.a1, &dummy)
|
||||
dbg_cap = current->find_capability (current->arch.a1, &dummy)
|
||||
if !dbg_cap:
|
||||
panic (0, "no log capability provided")
|
||||
break
|
||||
|
||||
@@ -138,12 +138,11 @@
|
||||
// Map IO memory (requires a priviledged __my_thread capability).
|
||||
#include <iris.h>
|
||||
static void __map_io (unsigned physical, unsigned mapping):
|
||||
Capability page = memory_create_page (__my_memory)
|
||||
memory_create_page (6, __my_memory)
|
||||
// 0 means not cachable; 0 means don't free when done.
|
||||
alloc_physical (page, physical, 0, 0)
|
||||
alloc_physical (6, physical, 0, 0)
|
||||
// 1 means writable.
|
||||
memory_map (__my_memory, page, mapping, 1)
|
||||
drop (page)
|
||||
memory_map (__my_memory, 6, mapping, 1)
|
||||
|
||||
#define map_harb() do { __map_io (HARB_PHYSICAL, HARB_BASE); } while (0)
|
||||
#define map_emc() do { __map_io (EMC_PHYSICAL, EMC_BASE); } while (0)
|
||||
|
||||
Reference in New Issue
Block a user