mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-04-21 12:27:27 +03:00
working with new invoke system
This commit is contained in:
@@ -34,15 +34,13 @@ void kThread_arch_init (kThread *thread):
|
||||
thread->arch.hi = 0
|
||||
thread->arch.lo = 0
|
||||
|
||||
void kThread_arch_receive (kThread *thread, Num cap_protected, Num recv_protected, Num *data):
|
||||
void kThread_arch_receive (kThread *thread, Kernel::Num protected_data, Kernel::Num *data):
|
||||
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
|
||||
thread->arch.t[0] = protected_data.l
|
||||
thread->arch.t[1] = protected_data.h
|
||||
|
||||
unsigned *kThread_arch_info (kThread *thread, unsigned num):
|
||||
switch num:
|
||||
@@ -184,7 +182,7 @@ static unsigned make_entry_lo (kPage *page, bool readonly):
|
||||
if !page->frame:
|
||||
return 0
|
||||
unsigned flags
|
||||
if page->flags & Page::UNCACHED:
|
||||
if page->flags & Kernel::Page::UNCACHED:
|
||||
flags = 0x10 | 0x2
|
||||
else:
|
||||
flags = 0x18 | 0x2
|
||||
@@ -271,7 +269,7 @@ void kPage_arch_update_mapping (kPage *page):
|
||||
if !page->arch.first_mapped:
|
||||
return
|
||||
kMemory *as = page->address_space
|
||||
unsigned target = make_entry_lo (page, page->flags & Page::READONLY)
|
||||
unsigned target = make_entry_lo (page, page->flags & Kernel::Page::READONLY)
|
||||
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)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
|
||||
#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.
|
||||
@@ -34,7 +33,7 @@ static void init_idle ():
|
||||
idle.schedule_next = NULL
|
||||
idle.address_space = &idle_memory
|
||||
idle.refs.reset ()
|
||||
idle.flags = Thread::RUNNING | Thread::PRIV
|
||||
idle.flags = Kernel::Thread::RUNNING | Kernel::Thread::PRIV
|
||||
// initialize idle_memory.
|
||||
idle_memory.prev = NULL
|
||||
idle_memory.next = NULL
|
||||
@@ -53,7 +52,7 @@ static void init_idle ():
|
||||
idle_page.prev = NULL
|
||||
idle_page.next = NULL
|
||||
idle_page.frame = 0x80000000
|
||||
idle_page.flags = Page::PAYING | Page::FRAME
|
||||
idle_page.flags = Kernel::Page::PAYING | Kernel::Page::FRAME
|
||||
idle_page.refs.reset ()
|
||||
idle_page.address_space = NULL
|
||||
current = &idle
|
||||
@@ -156,7 +155,7 @@ static void init_threads ():
|
||||
if !pages[idx]:
|
||||
pages[idx] = mem->alloc_page ()
|
||||
pages[idx]->frame = thread_start[i] + (idx << PAGE_BITS)
|
||||
pages[idx]->flags = Page::PAYING | Page::FRAME
|
||||
pages[idx]->flags = Kernel::Page::PAYING | Kernel::Page::FRAME
|
||||
++top_memory.limit
|
||||
mem->use ()
|
||||
if !mem->map (pages[idx], p, readonly):
|
||||
@@ -177,7 +176,7 @@ static void init_threads ():
|
||||
if !page->frame:
|
||||
panic (0x02220022, "out of memory");
|
||||
return
|
||||
page->flags = Page::PAYING | Page::FRAME
|
||||
page->flags = Kernel::Page::PAYING | Kernel::Page::FRAME
|
||||
if !mem->map (page, p):
|
||||
panic (0x33557799, "unable to map initial bss page")
|
||||
return
|
||||
@@ -198,22 +197,21 @@ static void init_threads ():
|
||||
top_memory.pfree (thread_start[i] + (p << PAGE_BITS))
|
||||
kPage *stackpage = mem->alloc_page ()
|
||||
stackpage->frame = mem->zalloc ()
|
||||
stackpage->flags = Page::PAYING | Page::FRAME
|
||||
stackpage->flags = Kernel::Page::PAYING | Kernel::Page::FRAME
|
||||
if !stackpage || !mem->map (stackpage, 0x7ffff000):
|
||||
panic (0x13151719, "unable to map initial stack page")
|
||||
return
|
||||
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
|
||||
thread->caps[0]->set (__receiver_num, (kReceiverP)(CAPTYPE_RECEIVER | CAP_MASTER), Num ((unsigned)recv), kCapRef (), &recv->refs)
|
||||
thread->caps[0]->set (__thread_num, (kReceiverP)(CAPTYPE_THREAD | CAP_MASTER), Num ((unsigned)thread), kCapRef (), &thread->refs)
|
||||
thread->caps[0]->set (__memory_num, (kReceiverP)(CAPTYPE_MEMORY | CAP_MASTER), Num ((unsigned)mem), kCapRef (), &mem->refs)
|
||||
thread->caps[0]->set (__call_num, (kReceiverP)(CAPTYPE_RECEIVER | Receiver::CALL), Num ((unsigned)recv), kCapRef (), &recv->refs)
|
||||
thread->flags = Thread::RUNNING | Thread::PRIV
|
||||
thread->caps[0]->set (__receiver_num, (kReceiverP)(CAPTYPE_RECEIVER | CAP_MASTER), Kernel::Num ((unsigned)recv), kCapRef (), &recv->refs)
|
||||
thread->caps[0]->set (__thread_num, (kReceiverP)(CAPTYPE_THREAD | CAP_MASTER), Kernel::Num ((unsigned)thread), kCapRef (), &thread->refs)
|
||||
thread->caps[0]->set (__memory_num, (kReceiverP)(CAPTYPE_MEMORY | CAP_MASTER), Kernel::Num ((unsigned)mem), kCapRef (), &mem->refs)
|
||||
thread->caps[0]->set (__call_num, (kReceiverP)(CAPTYPE_RECEIVER | Kernel::Receiver::CALL), Kernel::Num ((unsigned)recv), kCapRef (), &recv->refs)
|
||||
thread->flags = Kernel::Thread::RUNNING | Kernel::Thread::PRIV
|
||||
if !i:
|
||||
first_scheduled = thread
|
||||
init_receiver = recv
|
||||
|
||||
@@ -31,7 +31,7 @@ static void handle_exit ():
|
||||
schedule ()
|
||||
if !current:
|
||||
current = &idle
|
||||
if (current->flags & (Thread::RUNNING | Thread::WAITING)) != Thread::RUNNING:
|
||||
if (current->flags & (Kernel::Thread::RUNNING | Kernel::Thread::WAITING)) != Kernel::Thread::RUNNING:
|
||||
panic (current->flags, "non-scheduled thread running")
|
||||
if !current:
|
||||
current = &idle
|
||||
@@ -55,7 +55,7 @@ static void handle_exit ():
|
||||
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
|
||||
if current->flags & Thread::PRIV:
|
||||
if current->flags & Kernel::Thread::PRIV:
|
||||
cp0_set (CP0_STATUS, 0x1000ff13)
|
||||
else:
|
||||
cp0_set (CP0_STATUS, 0x0000ff13)
|
||||
@@ -68,7 +68,7 @@ kThread *tlb_refill ():
|
||||
if !directory:
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_NO_PAGE_DIRECTORY, addr)
|
||||
current->raise (Kernel::ERR_NO_PAGE_DIRECTORY, addr)
|
||||
handle_exit ()
|
||||
return current
|
||||
unsigned EntryHi
|
||||
@@ -77,7 +77,7 @@ kThread *tlb_refill ():
|
||||
if !t:
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_NO_PAGE_TABLE, addr)
|
||||
current->raise (Kernel::ERR_NO_PAGE_TABLE, addr)
|
||||
else:
|
||||
// - 2 instead of - 1 means reset bit 0
|
||||
unsigned idx = (EntryHi >> 12) & ((1 << 9) - 2)
|
||||
@@ -104,7 +104,6 @@ kThread *interrupt ():
|
||||
kCapability::Context c
|
||||
for unsigned j = 0; j < 2; ++j:
|
||||
c.data[j] = 0
|
||||
c.caps = NULL
|
||||
arch_interrupt_receiver[i]->send_message (i, &c)
|
||||
arch_interrupt_receiver[i] = NULL
|
||||
if ipr & (1 << IRQ_OST0):
|
||||
@@ -130,40 +129,23 @@ static void arch_invoke ():
|
||||
target = old_current->find_capability (old_current->arch.v[0], &must_wait)
|
||||
do_schedule = false
|
||||
kCapability::Context msg
|
||||
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, ©)
|
||||
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
|
||||
msg.reply = old_current->find_capability (old_current->arch.t[0], &msg.copy[0])
|
||||
msg.arg = old_current->find_capability (old_current->arch.t[1], &msg.copy[1])
|
||||
if must_wait:
|
||||
old_current->recv_slot = old_current->arch.s[0]
|
||||
bool dummy
|
||||
old_current->recv_reply = old_current->arch.t[2]
|
||||
old_current->recv_arg = old_current->arch.t[3]
|
||||
if !target.valid ():
|
||||
if must_wait:
|
||||
old_current->wait ()
|
||||
return
|
||||
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])
|
||||
msg.data[0] = Kernel::Num (old_current->arch.a[0], old_current->arch.a[1])
|
||||
msg.data[1] = Kernel::Num (old_current->arch.a[2], old_current->arch.a[3])
|
||||
target->invoke (&msg)
|
||||
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:
|
||||
else if old_current != current && (old_current->flags & (Kernel::Thread::RUNNING | Kernel::Thread::WAITING)) == Kernel::Thread::RUNNING:
|
||||
// If the caller received an immediate reply from the kernel, it is no longer set as current. Don't let it lose its timeslice.
|
||||
current = old_current
|
||||
|
||||
@@ -181,31 +163,31 @@ kThread *exception ():
|
||||
// TLB modification.
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_WRITE_DENIED, addr)
|
||||
current->raise (Kernel::ERR_WRITE_DENIED, addr)
|
||||
break
|
||||
case 2:
|
||||
// TLB load or instruction fetch.
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_UNMAPPED_READ, addr)
|
||||
current->raise (Kernel::ERR_UNMAPPED_READ, addr)
|
||||
break
|
||||
case 3:
|
||||
// TLB store.
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_UNMAPPED_WRITE, addr)
|
||||
current->raise (Kernel::ERR_UNMAPPED_WRITE, addr)
|
||||
break
|
||||
case 4:
|
||||
// Address error load or instruction fetch.
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_INVALID_ADDRESS_READ, addr)
|
||||
current->raise (Kernel::ERR_INVALID_ADDRESS_READ, addr)
|
||||
break
|
||||
case 5:
|
||||
// Address error store.
|
||||
unsigned addr
|
||||
cp0_get (CP0_BAD_V_ADDR, addr)
|
||||
current->raise (ERR_INVALID_ADDRESS_WRITE, addr)
|
||||
current->raise (Kernel::ERR_INVALID_ADDRESS_WRITE, addr)
|
||||
break
|
||||
case 6:
|
||||
// Bus error instruction fetch.
|
||||
@@ -224,7 +206,7 @@ kThread *exception ():
|
||||
case 9:
|
||||
// Breakpoint.
|
||||
#if 0 || defined (NDEBUG)
|
||||
//current->raise (ERR_BREAKPOINT, 0)
|
||||
//current->raise (Kernel::ERR_BREAKPOINT, 0)
|
||||
#ifndef NDEBUG
|
||||
current->pc += 4
|
||||
#endif
|
||||
@@ -250,19 +232,19 @@ kThread *exception ():
|
||||
break
|
||||
case 10:
|
||||
// Reserved instruction.
|
||||
current->raise (ERR_RESERVED_INSTRUCTION, 0)
|
||||
current->raise (Kernel::ERR_RESERVED_INSTRUCTION, 0)
|
||||
break
|
||||
case 11:
|
||||
// Coprocessor unusable.
|
||||
current->raise (ERR_COPROCESSOR_UNUSABLE, 0)
|
||||
current->raise (Kernel::ERR_COPROCESSOR_UNUSABLE, 0)
|
||||
break
|
||||
case 12:
|
||||
// Arithmetic overflow.
|
||||
current->raise (ERR_OVERFLOW, 0)
|
||||
current->raise (Kernel::ERR_OVERFLOW, 0)
|
||||
break
|
||||
case 13:
|
||||
// Trap.
|
||||
current->raise (ERR_TRAP, 0)
|
||||
current->raise (Kernel::ERR_TRAP, 0)
|
||||
break
|
||||
case 15:
|
||||
// Floating point exception.
|
||||
@@ -270,7 +252,7 @@ kThread *exception ():
|
||||
break
|
||||
case 23:
|
||||
// Reference to WatchHi/WatchLo address.
|
||||
current->raise (ERR_WATCHPOINT, 0)
|
||||
current->raise (Kernel::ERR_WATCHPOINT, 0)
|
||||
break
|
||||
case 24:
|
||||
// Machine check.
|
||||
|
||||
@@ -135,14 +135,14 @@
|
||||
// Default lcd framebuffer mapping space.
|
||||
#define LCD_FRAMEBUFFER_BASE ((unsigned short *)0x00021000)
|
||||
|
||||
// Map IO memory (requires a priviledged __my_thread capability).
|
||||
// Map IO memory (requires a priviledged Kernel::my_thread capability).
|
||||
#include <iris.hh>
|
||||
static void __map_io (unsigned physical, unsigned mapping):
|
||||
Page p = __my_memory.create_page ()
|
||||
Kernel::Page p = Kernel::my_memory.create_page ()
|
||||
// false means not cachable; false means don't free when done.
|
||||
p.alloc_physical (physical, false, false)
|
||||
__my_memory.map (p, mapping)
|
||||
free_cap (p)
|
||||
Kernel::my_memory.map (p, mapping)
|
||||
Kernel::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)
|
||||
@@ -2324,8 +2324,8 @@ static __inline__ void udelay (unsigned us):
|
||||
|
||||
#ifndef __KERNEL
|
||||
static __inline__ void cdelay (unsigned ds):
|
||||
__my_receiver.set_alarm (ds * (HZ / 100))
|
||||
Cap ().call (~0)
|
||||
Kernel::my_receiver.set_alarm (ds * (HZ / 100))
|
||||
Kernel::Cap ().call (~0)
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Reference in New Issue
Block a user