mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-11-16 21:36:14 +02:00
more
This commit is contained in:
parent
616e81d7a8
commit
60ea570aaa
4
Makefile
4
Makefile
@ -8,7 +8,7 @@ LD = $(CROSS)ld
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
OBJDUMP = $(CROSS)objdump
|
||||
|
||||
kernel_sources = interrupts.cc panic.cc data.cc test.cc alloc.cc memory.cc
|
||||
kernel_sources = interrupts.cc panic.cc data.cc test.cc alloc.cc memory.cc arch.cc invoke.cc schedule.cc
|
||||
boot_sources = init.cc
|
||||
BUILT_SOURCES = $(kernel_sources) $(boot_sources)
|
||||
|
||||
@ -22,7 +22,7 @@ PYPP = /usr/bin/pypp
|
||||
uimage: all.raw Makefile
|
||||
mkimage -A MIPS -O Linux -C none -a $(load) -e 0x$(shell /bin/sh -c '$(OBJDUMP) -t all | grep __start$$ | cut -b-8') -n "Shevek's kernel" -d $< $@ | sed -e 's/:/;/g'
|
||||
|
||||
arch.hh: mips.hh
|
||||
arch.%: mips.%
|
||||
ln -s $< $@ || true
|
||||
|
||||
%.o:%.cc Makefile kernel.hh arch.hh
|
||||
|
111
alloc.ccp
111
alloc.ccp
@ -1,6 +1,7 @@
|
||||
#pypp 0
|
||||
#include "kernel.hh"
|
||||
|
||||
// TODO: avoid recursion.
|
||||
bool Memory::use ():
|
||||
if used >= limit:
|
||||
return false
|
||||
@ -143,6 +144,34 @@ Thread *Memory::alloc_thread ():
|
||||
ret->schedule_next = NULL
|
||||
return ret
|
||||
|
||||
Message *Memory::alloc_message (Capability *source):
|
||||
Message *ret = (Message *)search_free (sizeof (Message), (void **)&source->target->messages)
|
||||
for unsigned i = 0; i < 4; ++i:
|
||||
ret->capabilities[i] = NULL
|
||||
ret->data[i] = 0
|
||||
ret->protected_data = source->protected_data
|
||||
return ret
|
||||
|
||||
Receiver *Memory::alloc_receiver ():
|
||||
Receiver *ret = (Receiver *)search_free (sizeof (Receiver), (void **)&receivers)
|
||||
ret->owner = NULL
|
||||
ret->prev_owned = NULL
|
||||
ret->next_owned = NULL
|
||||
ret->capabilities = NULL
|
||||
ret->messages = NULL
|
||||
return ret
|
||||
|
||||
Capability *Memory::alloc_capability (Receiver *target, Capability **parent, unsigned protected_data):
|
||||
Capability *ret = (Capability *)search_free (sizeof (Capability), (void **)&capabilities)
|
||||
ret->target = target
|
||||
ret->children = NULL
|
||||
ret->sibling_prev = NULL
|
||||
ret->sibling_next = parent ? *parent : NULL
|
||||
if ret->sibling_next:
|
||||
ret->sibling_next->sibling_prev = ret
|
||||
ret->protected_data = protected_data
|
||||
return ret
|
||||
|
||||
Memory *Memory::alloc_memory ():
|
||||
Memory *ret = (Memory *)search_free (sizeof (Memory), (void **)&memories)
|
||||
ret->parent = this
|
||||
@ -164,7 +193,7 @@ void Memory::free_page (Page *page):
|
||||
page->next->prev = page->prev
|
||||
unuse ()
|
||||
pfree (page->physical)
|
||||
free_obj (this)
|
||||
page->free_obj (this)
|
||||
|
||||
void Memory::free_thread (Thread *thread):
|
||||
if thread->prev:
|
||||
@ -173,8 +202,82 @@ void Memory::free_thread (Thread *thread):
|
||||
threads = thread->next
|
||||
if thread->next:
|
||||
thread->next->prev = thread->prev
|
||||
// TODO: unschedule
|
||||
free_obj (this)
|
||||
// Unschedule.
|
||||
if thread->schedule_prev:
|
||||
thread->schedule_prev->schedule_next = thread->schedule_next
|
||||
else if first_scheduled == thread:
|
||||
first_scheduled = thread->schedule_next
|
||||
if thread->schedule_next:
|
||||
thread->schedule_next->schedule_prev = thread->schedule_prev
|
||||
thread->free_obj (this)
|
||||
|
||||
void Memory::free_message (Message *message):
|
||||
for unsigned i = 0; i < 4; ++i:
|
||||
free_capability (message->capabilities[i])
|
||||
message->free_obj (this)
|
||||
|
||||
void Memory::free_receiver (Receiver *receiver):
|
||||
if receiver->prev_owned:
|
||||
receiver->prev_owned->next_owned = receiver->next_owned
|
||||
else:
|
||||
receiver->owner->receivers = receiver->next_owned
|
||||
if receiver->next_owned:
|
||||
receiver->next_owned->prev_owned = receiver->prev_owned
|
||||
while receiver->capabilities:
|
||||
receiver->capabilities->invalidate ()
|
||||
while receiver->messages:
|
||||
free_message (receiver->messages)
|
||||
receiver->free_obj (this)
|
||||
|
||||
void Memory::free_capability (Capability *capability):
|
||||
if capability->sibling_prev:
|
||||
capability->sibling_prev->sibling_next = capability->sibling_next
|
||||
else:
|
||||
capability->target->capabilities = capability->sibling_next
|
||||
if capability->sibling_next:
|
||||
capability->sibling_next->sibling_prev = capability->sibling_prev
|
||||
// The sibling_prev link is used here to point to the parent.
|
||||
// This method is used to avoid recursion.
|
||||
capability->sibling_prev = NULL
|
||||
Capability *c = capability
|
||||
while c->children:
|
||||
c->children->sibling_prev = c
|
||||
c = c->children
|
||||
while c:
|
||||
Capability *next = c->sibling_next
|
||||
if !next:
|
||||
next = c->sibling_prev
|
||||
if next:
|
||||
next->sibling_prev = c->sibling_prev
|
||||
c->free_obj (this)
|
||||
c = next
|
||||
|
||||
void Capability::invalidate ():
|
||||
if sibling_prev:
|
||||
sibling_prev->sibling_next = sibling_next
|
||||
else:
|
||||
target->capabilities = sibling_next
|
||||
if sibling_next:
|
||||
sibling_next->sibling_prev = sibling_prev
|
||||
// The sibling_prev link is used here to point to the parent.
|
||||
// This method is used to avoid recursion.
|
||||
sibling_prev = NULL
|
||||
Capability *c = this
|
||||
while c->children:
|
||||
c->children->sibling_prev = c
|
||||
c = c->children
|
||||
while c:
|
||||
Capability *next = c->sibling_next
|
||||
if !next:
|
||||
next = c->sibling_prev
|
||||
if next:
|
||||
next->sibling_prev = c->sibling_prev
|
||||
c->target = NULL
|
||||
c->children = NULL
|
||||
c->sibling_prev = NULL
|
||||
c->sibling_next = NULL
|
||||
c->protected_data = 0
|
||||
c = next
|
||||
|
||||
void Memory::free_memory (Memory *mem):
|
||||
if mem->prev:
|
||||
@ -190,4 +293,4 @@ void Memory::free_memory (Memory *mem):
|
||||
while mem->memories:
|
||||
free_memory (mem->memories)
|
||||
Memory_arch_free (mem)
|
||||
free_obj (this)
|
||||
mem->free_obj (this)
|
||||
|
7
entry.S
7
entry.S
@ -72,13 +72,6 @@ addr_100:
|
||||
.fill 0x180 - (. - addr_000)
|
||||
addr_180:
|
||||
// General exception
|
||||
// TODO
|
||||
|
||||
li $a0, 0xaaff0000
|
||||
la $t9, panic
|
||||
jr $t9
|
||||
nop
|
||||
|
||||
sw $ra, -0x188($zero)
|
||||
bal save_regs
|
||||
la $t9, exception
|
||||
|
2
init.ccp
2
init.ccp
@ -41,7 +41,7 @@ static void init_idle ():
|
||||
idle_memory.memories = NULL
|
||||
idle_memory.limit = 0
|
||||
idle_memory.used = 0
|
||||
idle_memory.arch.directory = (Page ***)0x80000000
|
||||
idle_memory.arch.directory = (unsigned **)0x80000000
|
||||
idle_memory.arch.asid = 0
|
||||
// initialize idle_page
|
||||
idle_page.prev_obj = NULL
|
||||
|
107
interrupts.ccp
107
interrupts.ccp
@ -1,23 +1,11 @@
|
||||
#pypp 0
|
||||
#include "kernel.hh"
|
||||
|
||||
// hi and lo cannot be saved in assemply due to space restrictions.
|
||||
#define save_hilo(x) do { __asm__ volatile ("mfhi %0 ; mflo %1" : "=r"((x)->arch.hi), "=r"((x)->arch.lo)); } while (0)
|
||||
|
||||
/// A TLB miss has occurred. This should eventually move to entry.S.
|
||||
Thread *tlb_refill (Thread *current, unsigned EntryHi):
|
||||
save_hilo (current)
|
||||
Page ***dir = current->address_space->arch.directory
|
||||
if !dir:
|
||||
panic (0x00000000, "no page directory for thread")
|
||||
EntryHi >>= 12
|
||||
Page **table = dir[EntryHi >> 10]
|
||||
if !table:
|
||||
panic (0x11111111, "no page table at requested address")
|
||||
EntryHi &= (1 << 10) - 1
|
||||
Page *page0 = table[EntryHi & ~1]
|
||||
Page *page1 = table[EntryHi | 1]
|
||||
if (!(EntryHi & 1) && !page0) || ((EntryHi & 1) && !page1):
|
||||
Page *page0 = current->address_space->get_mapping (EntryHi & ~(1 << 12))
|
||||
Page *page1 = current->address_space->get_mapping (EntryHi | (1 << 12))
|
||||
if (!(EntryHi & (1 << 12)) && !page0) || ((EntryHi & (1 << 12)) && !page1):
|
||||
panic (0x22222222, "no page mapped at requested address")
|
||||
unsigned low0, low1
|
||||
if page0:
|
||||
@ -33,17 +21,98 @@ Thread *tlb_refill (Thread *current, unsigned EntryHi):
|
||||
|
||||
/// An interrupt which is not an exception has occurred.
|
||||
Thread *interrupt (Thread *current):
|
||||
save_hilo (current)
|
||||
unsigned cause
|
||||
__asm__ volatile ("mfc0 %0, $13" : "=r"(cause))
|
||||
for unsigned i = 0; i < 8; ++i:
|
||||
if cause & (1 << (i + 8)):
|
||||
// TODO: Handle interrupt.
|
||||
// Disable all interrupts which are not handled.
|
||||
unsigned status
|
||||
__asm__ volatile ("mfc0 %0, $12" : "=r"(status))
|
||||
__asm__ volatile ("mfc0 %0, $13" : "=r"(cause))
|
||||
status &= ~(cause & 0x0000ff00)
|
||||
__asm__ volatile ("mtc0 %0, $12" :: "r"(status))
|
||||
return current
|
||||
|
||||
/// A general exception has occurred.
|
||||
Thread *exception (Thread *current):
|
||||
save_hilo (current)
|
||||
panic (0xdeadbeaf, "exception")
|
||||
unsigned cause
|
||||
__asm__ volatile ("mfc0 %0, $13" : "=r"(cause))
|
||||
switch (cause >> 2) & 0x1f:
|
||||
case 0:
|
||||
// Interrupt.
|
||||
panic (0x11223344, "Interrupt.")
|
||||
case 1:
|
||||
// TLB modification.
|
||||
panic (0x11223344, "TLB modification.")
|
||||
case 2:
|
||||
// TLB load or instruction fetch.
|
||||
panic (0x11223344, "TLB load or instruction fetch.")
|
||||
case 3:
|
||||
// TLB store.
|
||||
panic (0x11223344, "TLB store.")
|
||||
case 4:
|
||||
// Address error load or instruction fetch.
|
||||
panic (0x11223344, "Address error load or instruction fetch.")
|
||||
case 5:
|
||||
// Address error store.
|
||||
panic (0x11223344, "Address error store.")
|
||||
case 6:
|
||||
// Bus error instruction fetch.
|
||||
panic (0x11223344, "Bus error instruction fetch.")
|
||||
case 7:
|
||||
// Bus error load or store.
|
||||
panic (0x11223344, "Bus error load or store.")
|
||||
case 8:
|
||||
// Syscall.
|
||||
Thread_arch_invoke ()
|
||||
return current
|
||||
case 9:
|
||||
// Breakpoint.
|
||||
panic (0x11223344, "Breakpoint.")
|
||||
case 10:
|
||||
// Reserved instruction.
|
||||
panic (0x11223344, "Reserved instruction.")
|
||||
case 11:
|
||||
// Coprocessor unusable.
|
||||
panic (0x11223344, "Coprocessor unusable.")
|
||||
case 12:
|
||||
// Arithmetic overflow.
|
||||
panic (0x11223344, "Arithmetic overflow.")
|
||||
case 13:
|
||||
// Trap.
|
||||
panic (0x11223344, "Trap.")
|
||||
case 15:
|
||||
// Floating point exception.
|
||||
panic (0x11223344, "Floating point exception.")
|
||||
case 23:
|
||||
// Reference to WatchHi/WatchLo address.
|
||||
panic (0x11223344, "Reference to WatchHi/WatchLo address.")
|
||||
case 24:
|
||||
// Machine check.
|
||||
panic (0x11223344, "Machine check.")
|
||||
case 30:
|
||||
// Cache error (EJTAG only).
|
||||
panic (0x11223344, "Cache error (EJTAG only).")
|
||||
case 14:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 29:
|
||||
case 31:
|
||||
// Reserved.
|
||||
panic (0x11223344, "Reserved.")
|
||||
return current
|
||||
|
||||
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
||||
Thread *cache_error (Thread *current):
|
||||
save_hilo (current)
|
||||
panic (0x33333333, "cache error")
|
||||
return current
|
||||
|
14
invoke.ccp
Normal file
14
invoke.ccp
Normal file
@ -0,0 +1,14 @@
|
||||
#pypp 0
|
||||
#include "kernel.hh"
|
||||
|
||||
Capability *Memory::find_capability (unsigned code):
|
||||
for Capability *c = capabilities; c; c = c->next:
|
||||
if c == (Capability *)code:
|
||||
return c
|
||||
return NULL
|
||||
|
||||
void Capability::invoke (unsigned d0, unsigned d1, unsigned d2, unsigned d3, Capability *c0, Capability *c1, Capability *c2, Capability *c3):
|
||||
if (unsigned)target & PAGE_MASK:
|
||||
// TODO: Create message in receiver.
|
||||
return
|
||||
// TODO: Handle kernel request.
|
59
kernel.hhp
59
kernel.hhp
@ -11,6 +11,9 @@
|
||||
struct Object_base
|
||||
struct Page
|
||||
struct Thread
|
||||
struct Message
|
||||
struct Receiver
|
||||
struct Capability
|
||||
struct Memory
|
||||
|
||||
#include "arch.hh"
|
||||
@ -42,18 +45,41 @@ struct Thread : public Object <Thread>:
|
||||
unsigned pc, sp
|
||||
Thread_arch arch
|
||||
Thread *schedule_prev, *schedule_next
|
||||
Receiver *receivers
|
||||
|
||||
struct Message : public Object <Message>:
|
||||
Capability *capabilities[4]
|
||||
unsigned data[4]
|
||||
unsigned protected_data
|
||||
|
||||
struct Receiver : public Object <Receiver>:
|
||||
Thread *owner
|
||||
Receiver *prev_owned, *next_owned
|
||||
Capability *capabilities
|
||||
Message *messages
|
||||
|
||||
struct Capability : public Object <Capability>:
|
||||
Receiver *target
|
||||
Capability *children
|
||||
Capability *sibling_prev, *sibling_next
|
||||
unsigned protected_data
|
||||
void invoke (unsigned d0, unsigned d1, unsigned d2, unsigned d3, Capability *c0, Capability *c1, Capability *c2, Capability *c3)
|
||||
void invalidate ()
|
||||
|
||||
struct Memory : public Object <Memory>:
|
||||
Memory *parent
|
||||
Free *frees
|
||||
Page *pages
|
||||
Thread *threads
|
||||
Receiver *receivers
|
||||
Capability *capabilities
|
||||
Memory *memories
|
||||
unsigned limit, used
|
||||
Memory_arch arch
|
||||
|
||||
void unmap (Page *page, void *address):
|
||||
Memory_arch_unmap (this, page, address)
|
||||
inline bool map (Page *page, unsigned address, bool write)
|
||||
inline void unmap (Page *page, unsigned address)
|
||||
inline Page *get_mapping (unsigned address)
|
||||
|
||||
// Allocation of pages.
|
||||
bool use ()
|
||||
@ -67,14 +93,19 @@ struct Memory : public Object <Memory>:
|
||||
void *search_free (unsigned size, void **first)
|
||||
Page *alloc_page ()
|
||||
Thread *alloc_thread ()
|
||||
Message *alloc_message (Capability *source)
|
||||
Receiver *alloc_receiver ()
|
||||
Capability *alloc_capability (Receiver *target, Capability **parent, unsigned protected_data)
|
||||
Memory *alloc_memory ()
|
||||
|
||||
void free_page (Page *page)
|
||||
void free_thread (Thread *thread)
|
||||
void free_message (Message *message)
|
||||
void free_receiver (Receiver *receiver)
|
||||
void free_capability (Capability *capability)
|
||||
void free_memory (Memory *mem)
|
||||
|
||||
#define ARCH_PART2
|
||||
#include "arch.hh"
|
||||
Capability *find_capability (unsigned code)
|
||||
|
||||
// Functions which can be called from assembly must not be mangled.
|
||||
extern "C":
|
||||
@ -83,6 +114,8 @@ extern "C":
|
||||
// Debug: switch caps led
|
||||
void led (bool one, bool two, bool three)
|
||||
|
||||
void schedule ()
|
||||
|
||||
struct FreePage:
|
||||
FreePage *next
|
||||
|
||||
@ -92,5 +125,23 @@ EXTERN Thread *sleepers, *runners
|
||||
EXTERN Thread idle
|
||||
EXTERN Memory idle_memory
|
||||
EXTERN Page idle_page
|
||||
EXTERN Thread *first_scheduled
|
||||
EXTERN Thread *current
|
||||
|
||||
// Defined in arch.cc
|
||||
void Thread_arch_init (Thread *thread)
|
||||
void Thread_arch_invoke ()
|
||||
void Memory_arch_init (Memory *mem)
|
||||
void Memory_arch_free (Memory *mem)
|
||||
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write)
|
||||
void Memory_arch_unmap (Memory *mem, Page *page, unsigned address)
|
||||
Page *Memory_arch_get_mapping (Memory *mem, unsigned address)
|
||||
|
||||
bool Memory::map (Page *page, unsigned address, bool write):
|
||||
return Memory_arch_map (this, page, address, write)
|
||||
void Memory::unmap (Page *page, unsigned address):
|
||||
Memory_arch_unmap (this, page, address)
|
||||
Page *Memory::get_mapping (unsigned address):
|
||||
return Memory_arch_get_mapping (this, address)
|
||||
|
||||
#endif
|
||||
|
88
mips.ccp
Normal file
88
mips.ccp
Normal file
@ -0,0 +1,88 @@
|
||||
#pypp 0
|
||||
#include "kernel.hh"
|
||||
|
||||
void Thread_arch_init (Thread *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
|
||||
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 Memory_arch_init (Memory *mem):
|
||||
++g_asid
|
||||
g_asid &= 0x3f
|
||||
if !g_asid:
|
||||
++g_asid
|
||||
mem->arch.asid = g_asid
|
||||
mem->arch.directory = NULL
|
||||
|
||||
void Memory_arch_free (Memory *mem):
|
||||
if !mem->arch.directory:
|
||||
return
|
||||
for unsigned i = 0; i < PAGE_SIZE; ++i:
|
||||
unsigned *table = mem->arch.directory[i]
|
||||
if !table:
|
||||
continue
|
||||
for unsigned j = 0; j < PAGE_SIZE; ++j:
|
||||
Page *page = (Page *)(table[j] & ~3)
|
||||
if !page:
|
||||
continue
|
||||
mem->unmap (page, i * 0x1000 * 0x400 + j * 0x1000)
|
||||
mem->unuse ()
|
||||
mem->zfree (table)
|
||||
mem->arch.directory[i] = NULL
|
||||
mem->unuse ()
|
||||
mem->zfree (mem->arch.directory)
|
||||
|
||||
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
|
||||
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
||||
if !table:
|
||||
table = (unsigned *)mem->zalloc ()
|
||||
if !table:
|
||||
return false
|
||||
mem->arch.directory[(unsigned)address >> 22] = table
|
||||
unsigned idx = ((unsigned)address >> 12) & ((1 << 10) - 1)
|
||||
if table[idx]:
|
||||
mem->unmap ((Page *)(table[idx] & ~3), address)
|
||||
table[idx] = write ? (unsigned)page : (unsigned)page + 1
|
||||
|
||||
void Memory_arch_unmap (Memory *mem, Page *page, unsigned address):
|
||||
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
||||
table[((unsigned)address >> 12) & ((1 << 10) - 1)] = 0
|
||||
|
||||
Page *Memory_arch_get_mapping (Memory *mem, unsigned address):
|
||||
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
||||
unsigned v = table[((unsigned)address >> 12) & ((1 << 10) - 1)]
|
||||
|
||||
void Thread_arch_invoke ():
|
||||
Capability *target, *c0, *c1, *c2, *c3
|
||||
target = current->address_space->find_capability (current->arch.v0)
|
||||
if !target:
|
||||
// TODO: there must be no action here. This is just because the rest doesn't work yet.
|
||||
led (current->arch.a0, current->arch.a1, current->arch.a2)
|
||||
schedule ()
|
||||
return
|
||||
c0 = current->address_space->find_capability (current->arch.a0)
|
||||
c1 = current->address_space->find_capability (current->arch.a1)
|
||||
c2 = current->address_space->find_capability (current->arch.a2)
|
||||
c3 = current->address_space->find_capability (current->arch.a3)
|
||||
target->invoke (current->arch.t0, current->arch.t1, current->arch.t2, current->arch.t3, c0, c1, c2, c3)
|
63
mips.hhp
63
mips.hhp
@ -13,69 +13,10 @@ struct Thread_arch:
|
||||
|
||||
struct Memory_arch:
|
||||
unsigned asid
|
||||
Page ***directory
|
||||
|
||||
static void Memory_arch_unmap (Memory *mem, Page *page, void *address)
|
||||
|
||||
#endif // _ARCH_HH
|
||||
|
||||
#ifdef ARCH_PART2
|
||||
static void Thread_arch_init (Thread *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
|
||||
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
|
||||
unsigned **directory
|
||||
|
||||
EXTERN unsigned g_asid
|
||||
|
||||
static void Memory_arch_init (Memory *mem):
|
||||
++g_asid
|
||||
g_asid &= 0x3f
|
||||
if !g_asid:
|
||||
++g_asid
|
||||
mem->arch.asid = g_asid
|
||||
mem->arch.directory = NULL
|
||||
|
||||
static void Memory_arch_free (Memory *mem):
|
||||
if !mem->arch.directory:
|
||||
return
|
||||
for unsigned i = 0; i < PAGE_SIZE; ++i:
|
||||
Page **table = mem->arch.directory[i]
|
||||
if !table:
|
||||
continue
|
||||
for unsigned j = 0; j < PAGE_SIZE; ++j:
|
||||
Page *page = table[j]
|
||||
if !page:
|
||||
continue
|
||||
mem->unmap (page, (void *)(i * 0x1000 * 0x400 + j * 0x1000))
|
||||
mem->unuse ()
|
||||
mem->zfree (table)
|
||||
mem->arch.directory[i] = NULL
|
||||
mem->unuse ()
|
||||
mem->zfree (mem->arch.directory)
|
||||
|
||||
static void Memory_arch_unmap (Memory *mem, Page *page, void *address):
|
||||
|
||||
// Functions which can be called from assembly must not be mangled.
|
||||
extern "C":
|
||||
// Kernel entry points, called from entry.S.
|
||||
@ -91,4 +32,4 @@ extern "C":
|
||||
void run_idle (Thread *self)
|
||||
#endif
|
||||
|
||||
#endif // ARCH_PART2
|
||||
#endif
|
||||
|
10
schedule.ccp
Normal file
10
schedule.ccp
Normal file
@ -0,0 +1,10 @@
|
||||
#pypp 0
|
||||
#include "kernel.hh"
|
||||
|
||||
void schedule ():
|
||||
if current:
|
||||
current = current->schedule_next
|
||||
if !current:
|
||||
current = first_scheduled
|
||||
if !current:
|
||||
current = &idle
|
Loading…
Reference in New Issue
Block a user