mirror of
git://projects.qi-hardware.com/iris.git
synced 2025-01-01 17:42:05 +02:00
more
This commit is contained in:
parent
12637f5695
commit
f800bc51be
4
Makefile
4
Makefile
@ -1,12 +1,13 @@
|
|||||||
load = 0x80000000
|
load = 0x80000000
|
||||||
|
|
||||||
CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -nostdinc -DNUM_THREADS=0 -I/usr/include
|
CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -nostdinc -DNUM_THREADS=2 -I/usr/include
|
||||||
CPPFLAGS = -O5 -Wa,-mips32
|
CPPFLAGS = -O5 -Wa,-mips32
|
||||||
CROSS = mipsel-linux-gnu-
|
CROSS = mipsel-linux-gnu-
|
||||||
CC = $(CROSS)gcc
|
CC = $(CROSS)gcc
|
||||||
LD = $(CROSS)ld
|
LD = $(CROSS)ld
|
||||||
OBJCOPY = $(CROSS)objcopy
|
OBJCOPY = $(CROSS)objcopy
|
||||||
OBJDUMP = $(CROSS)objdump
|
OBJDUMP = $(CROSS)objdump
|
||||||
|
STRIP = $(CROSS)strip
|
||||||
|
|
||||||
kernel_sources = interrupts.cc panic.cc data.cc test.cc alloc.cc memory.cc arch.cc invoke.cc schedule.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
|
boot_sources = init.cc
|
||||||
@ -37,6 +38,7 @@ entry.o: thread0 thread1
|
|||||||
|
|
||||||
%: boot-helper.o boot-programs/%.o
|
%: boot-helper.o boot-programs/%.o
|
||||||
$(LD) $^ -o $@
|
$(LD) $^ -o $@
|
||||||
|
$(STRIP) $@
|
||||||
|
|
||||||
# entry.o must be the first file. boot.o must be the first of the init objects (which can be dumped after loading).
|
# entry.o must be the first file. boot.o must be the first of the init objects (which can be dumped after loading).
|
||||||
all: entry.o $(subst .cc,.o,$(kernel_sources)) boot.o $(subst .cc,.o,$(boot_sources))
|
all: entry.o $(subst .cc,.o,$(kernel_sources)) boot.o $(subst .cc,.o,$(boot_sources))
|
||||||
|
@ -31,7 +31,7 @@ unsigned Memory::zalloc ():
|
|||||||
FreePage *ret = zero_pages
|
FreePage *ret = zero_pages
|
||||||
if !ret:
|
if !ret:
|
||||||
ret = junk_pages
|
ret = junk_pages
|
||||||
for unsigned i = 1; i < PAGE_SIZE; ++i:
|
for unsigned i = 1; i < (PAGE_SIZE >> 2); ++i:
|
||||||
((unsigned *)ret)[i] = 0
|
((unsigned *)ret)[i] = 0
|
||||||
junk_pages = ret->next
|
junk_pages = ret->next
|
||||||
else:
|
else:
|
||||||
|
@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
int main ():
|
int main ():
|
||||||
while true:
|
while true:
|
||||||
__asm__ volatile ("move $v0, $zero; li $a0, 1 ; move $a1, $a0 ; move $a2, $a0 ; syscall")
|
__asm__ volatile ("move $v0, $zero; li $a0, 1 ; move $a1, $zero ; move $a2, $a0 ; syscall")
|
||||||
|
2
boot.S
2
boot.S
@ -45,7 +45,7 @@ start_hack_for_disassembler:
|
|||||||
jr $t9
|
jr $t9
|
||||||
nop
|
nop
|
||||||
|
|
||||||
tread_start:
|
thread_start:
|
||||||
.word thread0
|
.word thread0
|
||||||
.word thread1
|
.word thread1
|
||||||
.word thread2
|
.word thread2
|
||||||
|
32
entry.S
32
entry.S
@ -8,6 +8,7 @@
|
|||||||
#define Random 1
|
#define Random 1
|
||||||
#define EntryLo0 2
|
#define EntryLo0 2
|
||||||
#define EntryLo1 3
|
#define EntryLo1 3
|
||||||
|
#define BadVAddr 8
|
||||||
#define EntryHi 10
|
#define EntryHi 10
|
||||||
#define Status 12
|
#define Status 12
|
||||||
#define EPC 14
|
#define EPC 14
|
||||||
@ -51,13 +52,6 @@
|
|||||||
addr_000:
|
addr_000:
|
||||||
// TLB refill
|
// TLB refill
|
||||||
// TODO: this should probably be assembly-only for speed reasons
|
// TODO: this should probably be assembly-only for speed reasons
|
||||||
|
|
||||||
//mfc0 $a0, $EPC
|
|
||||||
li $a0, 0x11992288
|
|
||||||
la $t9, panic
|
|
||||||
jr $t9
|
|
||||||
nop
|
|
||||||
|
|
||||||
sw $ra, -0xd88($zero)
|
sw $ra, -0xd88($zero)
|
||||||
bal save_regs
|
bal save_regs
|
||||||
la $t9, tlb_refill
|
la $t9, tlb_refill
|
||||||
@ -66,13 +60,6 @@ addr_000:
|
|||||||
.fill 0x100 - (. - addr_000)
|
.fill 0x100 - (. - addr_000)
|
||||||
addr_100:
|
addr_100:
|
||||||
// Cache error
|
// Cache error
|
||||||
// TODO
|
|
||||||
|
|
||||||
li $a0, 0xaaaa0000
|
|
||||||
la $t9, panic
|
|
||||||
jr $t9
|
|
||||||
nop
|
|
||||||
|
|
||||||
sw $ra, -0xd88($zero)
|
sw $ra, -0xd88($zero)
|
||||||
bal save_regs
|
bal save_regs
|
||||||
la $t9, cache_error
|
la $t9, cache_error
|
||||||
@ -89,13 +76,6 @@ addr_180:
|
|||||||
.fill 0x200 - (. - addr_000)
|
.fill 0x200 - (. - addr_000)
|
||||||
addr_200:
|
addr_200:
|
||||||
// Interrupt
|
// Interrupt
|
||||||
// TODO
|
|
||||||
|
|
||||||
li $a0, 0x0a0f0000
|
|
||||||
la $t9, panic
|
|
||||||
jr $t9
|
|
||||||
nop
|
|
||||||
|
|
||||||
sw $ra, -0xd88($zero)
|
sw $ra, -0xd88($zero)
|
||||||
bal save_regs
|
bal save_regs
|
||||||
la $t9, interrupt
|
la $t9, interrupt
|
||||||
@ -117,6 +97,7 @@ start_idle: // 288
|
|||||||
// idle task would need to own capabilities.
|
// idle task would need to own capabilities.
|
||||||
move $v0, $zero
|
move $v0, $zero
|
||||||
syscall
|
syscall
|
||||||
|
nop
|
||||||
1: wait
|
1: wait
|
||||||
b 1b
|
b 1b
|
||||||
nop
|
nop
|
||||||
@ -152,7 +133,6 @@ kernel_exit:
|
|||||||
lw $s5, SAVE_S5($v0)
|
lw $s5, SAVE_S5($v0)
|
||||||
lw $s6, SAVE_S6($v0)
|
lw $s6, SAVE_S6($v0)
|
||||||
lw $s7, SAVE_S7($v0)
|
lw $s7, SAVE_S7($v0)
|
||||||
lw $sp, SAVE_SP($v0)
|
|
||||||
lw $fp, SAVE_FP($v0)
|
lw $fp, SAVE_FP($v0)
|
||||||
lw $ra, SAVE_RA($v0)
|
lw $ra, SAVE_RA($v0)
|
||||||
lw $at, SAVE_AT($v0)
|
lw $at, SAVE_AT($v0)
|
||||||
@ -161,6 +141,8 @@ kernel_exit:
|
|||||||
sw $k1, -0xd90($zero)
|
sw $k1, -0xd90($zero)
|
||||||
lw $k1, SAVE_K1($v0)
|
lw $k1, SAVE_K1($v0)
|
||||||
sw $v0, -0xd8c($zero)
|
sw $v0, -0xd8c($zero)
|
||||||
|
|
||||||
|
lw $sp, SAVE_SP($v0)
|
||||||
lw $gp, SAVE_GP($v0)
|
lw $gp, SAVE_GP($v0)
|
||||||
lw $v0, -0xd90($zero)
|
lw $v0, -0xd90($zero)
|
||||||
eret
|
eret
|
||||||
@ -216,15 +198,15 @@ save_regs:
|
|||||||
move $t9, $ra
|
move $t9, $ra
|
||||||
la $ra, kernel_exit
|
la $ra, kernel_exit
|
||||||
jr $t9
|
jr $t9
|
||||||
move $a0, $k0
|
nop
|
||||||
|
|
||||||
.globl thread0
|
.globl thread0
|
||||||
.globl thread1
|
.globl thread1
|
||||||
.globl thread2
|
.globl thread2
|
||||||
|
.balign 0x1000
|
||||||
thread0:
|
thread0:
|
||||||
.balign 0x1000
|
|
||||||
.incbin "thread0"
|
.incbin "thread0"
|
||||||
thread1:
|
|
||||||
.balign 0x1000
|
.balign 0x1000
|
||||||
|
thread1:
|
||||||
.incbin "thread1"
|
.incbin "thread1"
|
||||||
thread2:
|
thread2:
|
||||||
|
32
init.ccp
32
init.ccp
@ -31,7 +31,8 @@ static void init_idle ():
|
|||||||
idle_page.next_obj = NULL
|
idle_page.next_obj = NULL
|
||||||
idle_page.prev = NULL
|
idle_page.prev = NULL
|
||||||
idle_page.next = NULL
|
idle_page.next = NULL
|
||||||
idle_page.physical = 0
|
idle_page.physical = 0x80000000
|
||||||
|
current = &idle
|
||||||
|
|
||||||
static void init_cp0 ():
|
static void init_cp0 ():
|
||||||
// Set timer to a defined value
|
// Set timer to a defined value
|
||||||
@ -74,15 +75,16 @@ static void init_cp0 ():
|
|||||||
__asm__ volatile ("tlbwr")
|
__asm__ volatile ("tlbwr")
|
||||||
// Allow eret to be used to jump to the idle task.
|
// Allow eret to be used to jump to the idle task.
|
||||||
cp0_set (CP0_EPC, 0x284a0288)
|
cp0_set (CP0_EPC, 0x284a0288)
|
||||||
// Enable all interrupts and say we're handling an exception.
|
// Wait with initializing the status register until the last moment, so that
|
||||||
// Since we're going to enter the idle task, allow access to cp0.
|
// exceptions in the bootup code will fill EPC and friends.
|
||||||
cp0_set (CP0_STATUS, 0x1000ff13)
|
|
||||||
|
|
||||||
static void init_threads ():
|
static void init_threads ():
|
||||||
|
Thread *previous = NULL
|
||||||
|
first_scheduled = NULL
|
||||||
for unsigned i = 0; i < NUM_THREADS; ++i:
|
for unsigned i = 0; i < NUM_THREADS; ++i:
|
||||||
Memory *mem = top_memory.alloc_memory ()
|
Memory *mem = top_memory.alloc_memory ()
|
||||||
Thread *thread = mem->alloc_thread ()
|
Thread *thread = mem->alloc_thread ()
|
||||||
Page **pages = (Page **)mem->palloc ()
|
Page **pages = (Page **)mem->zalloc ()
|
||||||
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
|
Elf32_Ehdr *header = (Elf32_Ehdr *)thread_start[i]
|
||||||
for unsigned j = 0; j < SELFMAG; ++j:
|
for unsigned j = 0; j < SELFMAG; ++j:
|
||||||
if header->e_ident[j] != ELFMAG[j]:
|
if header->e_ident[j] != ELFMAG[j]:
|
||||||
@ -95,8 +97,8 @@ static void init_threads ():
|
|||||||
panic (i * 0x1000 + EI_VERSION, "invalid ELF version")
|
panic (i * 0x1000 + EI_VERSION, "invalid ELF version")
|
||||||
if header->e_type != ET_EXEC:
|
if header->e_type != ET_EXEC:
|
||||||
panic (i * 0x1000 + 0x10, "invalid ELF type")
|
panic (i * 0x1000 + 0x10, "invalid ELF type")
|
||||||
if header->e_machine != EM_MIPS_RS3_LE:
|
if header->e_machine != EM_MIPS_RS3_LE && header->e_machine != EM_MIPS:
|
||||||
panic (i * 0x1000 + 0x10, "invalid ELF machine")
|
panic (i * 0x1000 + 0x12, "invalid ELF machine")
|
||||||
thread->pc = header->e_entry
|
thread->pc = header->e_entry
|
||||||
thread->sp = 0x80000000
|
thread->sp = 0x80000000
|
||||||
for unsigned section = 0; section < header->e_shnum; ++section:
|
for unsigned section = 0; section < header->e_shnum; ++section:
|
||||||
@ -130,8 +132,9 @@ static void init_threads ():
|
|||||||
break
|
break
|
||||||
if a < shdr->sh_addr:
|
if a < shdr->sh_addr:
|
||||||
continue
|
continue
|
||||||
*(unsigned *)a = 0
|
((unsigned *)page->physical)[(a & ~PAGE_MASK) >> 2] = 0
|
||||||
for unsigned p = 0; p <= ((thread_start[i + 1] - thread_start[i] - 1) >> PAGE_BITS); ++p:
|
for unsigned p = 0; p <= ((thread_start[i + 1] - thread_start[i] - 1) >> PAGE_BITS); ++p:
|
||||||
|
// TODO: this also skips pages where new space is allocated.
|
||||||
if pages[p]:
|
if pages[p]:
|
||||||
continue
|
continue
|
||||||
++top_memory.limit
|
++top_memory.limit
|
||||||
@ -146,10 +149,19 @@ static void init_threads ():
|
|||||||
Capability *admin = mem->alloc_capability ((Receiver *)(CAPTYPE_ADMIN | ~PAGE_MASK), &mem->capabilities, ~0)
|
Capability *admin = mem->alloc_capability ((Receiver *)(CAPTYPE_ADMIN | ~PAGE_MASK), &mem->capabilities, ~0)
|
||||||
thread->arch.a3 = (unsigned)admin
|
thread->arch.a3 = (unsigned)admin
|
||||||
mem->pfree ((unsigned)pages)
|
mem->pfree ((unsigned)pages)
|
||||||
|
thread->schedule_next = NULL
|
||||||
|
thread->schedule_prev = previous
|
||||||
|
if previous:
|
||||||
|
previous->schedule_next = thread
|
||||||
|
else:
|
||||||
|
first_scheduled = thread
|
||||||
|
previous = thread
|
||||||
|
|
||||||
// Initialize the kernel, finish by falling into the idle task.
|
// Initialize the kernel, finish by falling into the idle task.
|
||||||
extern unsigned _end
|
extern unsigned _end
|
||||||
void init ():
|
void init ():
|
||||||
|
// Disable interrupts and set interrupt vectors to normal.
|
||||||
|
cp0_set0 (CP0_STATUS)
|
||||||
// Initialize kernel variables to empty.
|
// Initialize kernel variables to empty.
|
||||||
sleepers = NULL
|
sleepers = NULL
|
||||||
runners = NULL
|
runners = NULL
|
||||||
@ -182,5 +194,9 @@ void init ():
|
|||||||
|
|
||||||
init_threads ()
|
init_threads ()
|
||||||
|
|
||||||
|
// Enable all interrupts and say we're handling an exception.
|
||||||
|
// Since we're going to enter the idle task, allow access to cp0.
|
||||||
|
cp0_set (CP0_STATUS, 0x1000ff13)
|
||||||
|
|
||||||
// Done; return to user space (the idle task).
|
// Done; return to user space (the idle task).
|
||||||
__asm__ volatile ("eret")
|
__asm__ volatile ("eret")
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
#include "kernel.hh"
|
#include "kernel.hh"
|
||||||
|
|
||||||
/// A TLB miss has occurred. This should eventually move to entry.S.
|
/// A TLB miss has occurred. This should eventually move to entry.S.
|
||||||
Thread *tlb_refill (Thread *current, unsigned EntryHi):
|
Thread *tlb_refill ():
|
||||||
panic (0x88776655, "TLB refill")
|
//panic (0x88776655, "TLB refill")
|
||||||
|
unsigned EntryHi
|
||||||
|
cp0_get (CP0_ENTRY_HI, EntryHi)
|
||||||
Page *page0 = current->address_space->get_mapping (EntryHi & ~(1 << 12))
|
Page *page0 = current->address_space->get_mapping (EntryHi & ~(1 << 12))
|
||||||
Page *page1 = 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):
|
if (!(EntryHi & (1 << 12)) && !page0) || ((EntryHi & (1 << 12)) && !page1):
|
||||||
@ -24,7 +26,8 @@ Thread *tlb_refill (Thread *current, unsigned EntryHi):
|
|||||||
return current
|
return current
|
||||||
|
|
||||||
/// An interrupt which is not an exception has occurred.
|
/// An interrupt which is not an exception has occurred.
|
||||||
Thread *interrupt (Thread *current):
|
Thread *interrupt ():
|
||||||
|
panic (0x88877722)
|
||||||
unsigned cause
|
unsigned cause
|
||||||
cp0_get (CP0_CAUSE, cause)
|
cp0_get (CP0_CAUSE, cause)
|
||||||
for unsigned i = 0; i < 8; ++i:
|
for unsigned i = 0; i < 8; ++i:
|
||||||
@ -32,17 +35,16 @@ Thread *interrupt (Thread *current):
|
|||||||
// TODO: Handle interrupt.
|
// TODO: Handle interrupt.
|
||||||
// Disable all interrupts which are not handled.
|
// Disable all interrupts which are not handled.
|
||||||
unsigned status
|
unsigned status
|
||||||
__asm__ volatile ("mfc0 %0, $12" : "=r"(status))
|
cp0_get (CP0_STATUS, status)
|
||||||
__asm__ volatile ("mfc0 %0, $13" : "=r"(cause))
|
cp0_get (CP0_CAUSE, cause)
|
||||||
status &= ~(cause & 0x0000ff00)
|
status &= ~(cause & 0x0000ff00)
|
||||||
__asm__ volatile ("mtc0 %0, $12" :: "r"(status))
|
cp0_set (CP0_STATUS, status)
|
||||||
return current
|
return current
|
||||||
|
|
||||||
/// A general exception has occurred.
|
/// A general exception has occurred.
|
||||||
Thread *exception (Thread *current):
|
Thread *exception ():
|
||||||
unsigned cause
|
unsigned cause
|
||||||
led (true, true, true)
|
cp0_get (CP0_CAUSE, cause)
|
||||||
__asm__ volatile ("mfc0 %0, $13" : "=r"(cause))
|
|
||||||
switch (cause >> 2) & 0x1f:
|
switch (cause >> 2) & 0x1f:
|
||||||
case 0:
|
case 0:
|
||||||
// Interrupt.
|
// Interrupt.
|
||||||
@ -51,12 +53,15 @@ Thread *exception (Thread *current):
|
|||||||
// TLB modification.
|
// TLB modification.
|
||||||
panic (0x21223344, "TLB modification.")
|
panic (0x21223344, "TLB modification.")
|
||||||
case 2:
|
case 2:
|
||||||
unsigned a
|
//unsigned a
|
||||||
cp0_get (CP0_EPC, a)
|
//cp0_get (CP0_EPC, a)
|
||||||
panic (a)
|
//panic (a)
|
||||||
// TLB load or instruction fetch.
|
// TLB load or instruction fetch.
|
||||||
panic (0x31223344, "TLB load or instruction fetch.")
|
panic (0x31223344, "TLB load or instruction fetch.")
|
||||||
case 3:
|
case 3:
|
||||||
|
unsigned a
|
||||||
|
cp0_get (CP0_EPC, a)
|
||||||
|
panic (a)
|
||||||
// TLB store.
|
// TLB store.
|
||||||
panic (0x41223344, "TLB store.")
|
panic (0x41223344, "TLB store.")
|
||||||
case 4:
|
case 4:
|
||||||
@ -74,14 +79,15 @@ Thread *exception (Thread *current):
|
|||||||
case 8:
|
case 8:
|
||||||
// Syscall.
|
// Syscall.
|
||||||
// DEBUG: allow new exceptions.
|
// DEBUG: allow new exceptions.
|
||||||
//cp0_set (CP0_STATUS, 0x1000ff00)
|
//cp0_set0 (CP0_STATUS)
|
||||||
Thread_arch_invoke ()
|
arch_invoke ()
|
||||||
return current
|
return current
|
||||||
case 9:
|
case 9:
|
||||||
// Breakpoint.
|
// Breakpoint.
|
||||||
panic (0x91223344, "Breakpoint.")
|
panic (0x91223344, "Breakpoint.")
|
||||||
case 10:
|
case 10:
|
||||||
// Reserved instruction.
|
// Reserved instruction.
|
||||||
|
panic (*(unsigned *)0x004000b0)
|
||||||
panic (0xa1223344, "Reserved instruction.")
|
panic (0xa1223344, "Reserved instruction.")
|
||||||
case 11:
|
case 11:
|
||||||
// Coprocessor unusable.
|
// Coprocessor unusable.
|
||||||
@ -119,10 +125,12 @@ Thread *exception (Thread *current):
|
|||||||
case 29:
|
case 29:
|
||||||
case 31:
|
case 31:
|
||||||
// Reserved.
|
// Reserved.
|
||||||
panic (0xf5223344, "Reserved.")
|
panic (0xf5223344, "Reserved exception code")
|
||||||
|
default:
|
||||||
|
panic (0xf6223344, "Impossible exception code")
|
||||||
return current
|
return current
|
||||||
|
|
||||||
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
/// There's a cache error. Big trouble. Probably not worth trying to recover.
|
||||||
Thread *cache_error (Thread *current):
|
Thread *cache_error ():
|
||||||
panic (0x33333333, "cache error")
|
panic (0x33333333, "cache error")
|
||||||
return current
|
return current
|
||||||
|
@ -133,12 +133,12 @@ EXTERN Thread *current
|
|||||||
|
|
||||||
// Defined in arch.cc
|
// Defined in arch.cc
|
||||||
void Thread_arch_init (Thread *thread)
|
void Thread_arch_init (Thread *thread)
|
||||||
void Thread_arch_invoke ()
|
|
||||||
void Memory_arch_init (Memory *mem)
|
void Memory_arch_init (Memory *mem)
|
||||||
void Memory_arch_free (Memory *mem)
|
void Memory_arch_free (Memory *mem)
|
||||||
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write)
|
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write)
|
||||||
void Memory_arch_unmap (Memory *mem, Page *page, unsigned address)
|
void Memory_arch_unmap (Memory *mem, Page *page, unsigned address)
|
||||||
Page *Memory_arch_get_mapping (Memory *mem, unsigned address)
|
Page *Memory_arch_get_mapping (Memory *mem, unsigned address)
|
||||||
|
void arch_invoke ()
|
||||||
void arch_schedule (Thread *previous, Thread *target)
|
void arch_schedule (Thread *previous, Thread *target)
|
||||||
|
|
||||||
bool Memory::map (Page *page, unsigned address, bool write):
|
bool Memory::map (Page *page, unsigned address, bool write):
|
||||||
|
24
mips.ccp
24
mips.ccp
@ -54,6 +54,10 @@ void Memory_arch_free (Memory *mem):
|
|||||||
mem->zfree ((unsigned)mem->arch.directory)
|
mem->zfree ((unsigned)mem->arch.directory)
|
||||||
|
|
||||||
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
|
bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
|
||||||
|
if !mem->arch.directory:
|
||||||
|
mem->arch.directory = (unsigned **)mem->zalloc ()
|
||||||
|
if !mem->arch.directory:
|
||||||
|
return false
|
||||||
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
||||||
if !table:
|
if !table:
|
||||||
table = (unsigned *)mem->zalloc ()
|
table = (unsigned *)mem->zalloc ()
|
||||||
@ -64,6 +68,7 @@ bool Memory_arch_map (Memory *mem, Page *page, unsigned address, bool write):
|
|||||||
if table[idx]:
|
if table[idx]:
|
||||||
mem->unmap ((Page *)(table[idx] & ~3), address)
|
mem->unmap ((Page *)(table[idx] & ~3), address)
|
||||||
table[idx] = write ? (unsigned)page : (unsigned)page + 1
|
table[idx] = write ? (unsigned)page : (unsigned)page + 1
|
||||||
|
return true
|
||||||
|
|
||||||
void Memory_arch_unmap (Memory *mem, Page *page, unsigned address):
|
void Memory_arch_unmap (Memory *mem, Page *page, unsigned address):
|
||||||
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
||||||
@ -72,18 +77,15 @@ void Memory_arch_unmap (Memory *mem, Page *page, unsigned address):
|
|||||||
Page *Memory_arch_get_mapping (Memory *mem, unsigned address):
|
Page *Memory_arch_get_mapping (Memory *mem, unsigned address):
|
||||||
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
unsigned *table = mem->arch.directory[(unsigned)address >> 22]
|
||||||
unsigned v = table[((unsigned)address >> 12) & ((1 << 10) - 1)]
|
unsigned v = table[((unsigned)address >> 12) & ((1 << 10) - 1)]
|
||||||
|
return (Page *)(v & ~1)
|
||||||
|
|
||||||
void Thread_arch_invoke ():
|
void arch_invoke ():
|
||||||
Capability *target, *c0, *c1, *c2, *c3
|
Capability *target, *c0, *c1, *c2, *c3
|
||||||
if current:
|
target = current->address_space->find_capability (current->arch.v0)
|
||||||
target = current->address_space->find_capability (current->arch.v0)
|
|
||||||
else:
|
|
||||||
target = NULL
|
|
||||||
if !target:
|
if !target:
|
||||||
// TODO: there must be no action here. This is just because the rest doesn't work yet.
|
// TODO: there must be no action here. This is just because the rest doesn't work yet.
|
||||||
if current:
|
led (current->arch.a0, current->arch.a1, current->arch.a2)
|
||||||
led (current->arch.a0, current->arch.a1, current->arch.a2)
|
dbg_sleep (1000)
|
||||||
dbg_sleep (1000)
|
|
||||||
schedule ()
|
schedule ()
|
||||||
return
|
return
|
||||||
c0 = current->address_space->find_capability (current->arch.a0)
|
c0 = current->address_space->find_capability (current->arch.a0)
|
||||||
@ -93,9 +95,5 @@ void Thread_arch_invoke ():
|
|||||||
target->invoke (current->arch.t0, current->arch.t1, current->arch.t2, current->arch.t3, c0, c1, c2, c3)
|
target->invoke (current->arch.t0, current->arch.t1, current->arch.t2, current->arch.t3, c0, c1, c2, c3)
|
||||||
|
|
||||||
void arch_schedule (Thread *previous, Thread *target):
|
void arch_schedule (Thread *previous, Thread *target):
|
||||||
if target:
|
cp0_set (CP0_ENTRY_HI, target->address_space->arch.asid)
|
||||||
cp0_set (CP0_ENTRY_HI, target->address_space->arch.asid)
|
|
||||||
else:
|
|
||||||
// The idle tasks asid is 0.
|
|
||||||
cp0_set (CP0_ENTRY_HI, 0)
|
|
||||||
// TODO: flush TLB if the asid is already taken.
|
// TODO: flush TLB if the asid is already taken.
|
||||||
|
8
mips.hhp
8
mips.hhp
@ -63,10 +63,10 @@ EXTERN unsigned g_asid
|
|||||||
// Functions which can be called from assembly must not be mangled.
|
// Functions which can be called from assembly must not be mangled.
|
||||||
extern "C":
|
extern "C":
|
||||||
// Kernel entry points, called from entry.S.
|
// Kernel entry points, called from entry.S.
|
||||||
Thread *interrupt (Thread *current)
|
Thread *interrupt ()
|
||||||
Thread *cache_error (Thread *current)
|
Thread *cache_error ()
|
||||||
Thread *exception (Thread *current)
|
Thread *exception ()
|
||||||
Thread *tlb_refill (Thread *current, unsigned EntryHi)
|
Thread *tlb_refill ()
|
||||||
|
|
||||||
#ifdef INIT
|
#ifdef INIT
|
||||||
// Initialize most things (the rest is done in boot.S)
|
// Initialize most things (the rest is done in boot.S)
|
||||||
|
@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
void schedule ():
|
void schedule ():
|
||||||
Thread *old = current
|
Thread *old = current
|
||||||
if current:
|
current = current->schedule_next
|
||||||
current = current->schedule_next
|
|
||||||
if !current:
|
if !current:
|
||||||
current = first_scheduled
|
current = first_scheduled
|
||||||
if !current:
|
if !current:
|
||||||
current = &idle
|
current = &idle
|
||||||
if old != current:
|
if old != current:
|
||||||
arch_schedule (old, current)
|
arch_schedule (old, current)
|
||||||
|
2
test.ccp
2
test.ccp
@ -76,5 +76,5 @@ void led (bool one, bool two, bool three):
|
|||||||
__gpio_set_pin (NETWORK_IO)
|
__gpio_set_pin (NETWORK_IO)
|
||||||
|
|
||||||
void dbg_sleep (unsigned ms):
|
void dbg_sleep (unsigned ms):
|
||||||
for unsigned i = 0; i < 1000 * ms; ++i:
|
for unsigned i = 0; i < 10000 * ms; ++i:
|
||||||
__gpio_as_output (CAPSLOCKLED_IO)
|
__gpio_as_output (CAPSLOCKLED_IO)
|
||||||
|
Loading…
Reference in New Issue
Block a user