mirror of
git://projects.qi-hardware.com/iris.git
synced 2024-12-29 01:51:08 +02:00
idle
This commit is contained in:
parent
aee799648f
commit
5d9d12b860
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
all
|
||||
all.raw
|
||||
all.raw.gz
|
||||
report
|
||||
uimage
|
||||
|
14
Makefile
14
Makefile
@ -1,4 +1,4 @@
|
||||
load = 0xa0000000
|
||||
load = 0x80000000
|
||||
|
||||
CXXFLAGS = -Wno-unused-parameter -fno-strict-aliasing -fno-builtin -nostdinc
|
||||
CPPFLAGS = -O5 -Wa,-mips32
|
||||
@ -8,7 +8,9 @@ LD = $(CROSS)ld
|
||||
OBJCOPY = $(CROSS)objcopy
|
||||
OBJDUMP = $(CROSS)objdump
|
||||
|
||||
BUILT_SOURCES = interrupts.cc panic.cc data.cc test.cc
|
||||
kernel_sources = interrupts.cc panic.cc data.cc test.cc
|
||||
boot_sources = init.cc
|
||||
BUILT_SOURCES = $(kernel_sources) $(boot_sources)
|
||||
|
||||
PYPP = /usr/bin/pypp
|
||||
%.cc: %.ccp kernel.hh
|
||||
@ -17,8 +19,8 @@ PYPP = /usr/bin/pypp
|
||||
$(PYPP) --name $< < $< > $@
|
||||
|
||||
# Transform ':' into ';' so vim doesn't think there are errors.
|
||||
uimage: all.raw.gz Makefile
|
||||
mkimage -A MIPS -O Linux -C gzip -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'
|
||||
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'
|
||||
|
||||
%.o:%.cc Makefile kernel.hh
|
||||
$(CC) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
@ -26,8 +28,8 @@ uimage: all.raw.gz Makefile
|
||||
%.o:%.S Makefile
|
||||
$(CC) $(CPPFLAGS) -DKERNEL_STACK_SIZE=0x2000 -c $< -o $@
|
||||
|
||||
# entry.o must be the first file. For the rest, the order doesn't matter.
|
||||
all: entry.o $(subst .cc,.o,$(BUILT_SOURCES))
|
||||
# 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))
|
||||
$(LD) --omagic -Ttext $(load) $^ -o $@
|
||||
|
||||
junk = mdebug.abi32 reginfo comment pdr
|
||||
|
45
boot.S
Normal file
45
boot.S
Normal file
@ -0,0 +1,45 @@
|
||||
// The kernel stack.
|
||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||
|
||||
.globl __start
|
||||
.set noreorder
|
||||
|
||||
#define Status 12
|
||||
#define Config 16
|
||||
|
||||
__start:
|
||||
bal 1f
|
||||
nop
|
||||
.word _gp
|
||||
// For some reason the disassembler considers everything
|
||||
// after __start non-code until the next label. So I add a label.
|
||||
start_hack_for_disassembler:
|
||||
1: lw $gp, 0($ra)
|
||||
|
||||
la $sp, kernel_stack + KERNEL_STACK_SIZE
|
||||
|
||||
// Disable interrupts during bootstrap.
|
||||
mtc0 $zero, $Status
|
||||
|
||||
// TODO: flush cache and optionally refill it.
|
||||
|
||||
// Set kseg0 cachable.
|
||||
li $k0, 0x3
|
||||
mtc0 $k0, $Config, 0
|
||||
|
||||
// Jump into cached code.
|
||||
la $t9, 1f
|
||||
jr $t9
|
||||
nop
|
||||
1:
|
||||
|
||||
// Clear .bss
|
||||
la $a0, _edata
|
||||
la $a1, _end
|
||||
1: sw $zero, 0($a0)
|
||||
bne $a1, $a0, 1b
|
||||
addu $a0, 4
|
||||
|
||||
la $t9, init
|
||||
jr $t9
|
||||
nop
|
234
entry.S
234
entry.S
@ -1,73 +1,15 @@
|
||||
// The kernel stack.
|
||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
||||
|
||||
.globl __start
|
||||
.globl run_idle
|
||||
.set noat
|
||||
.set noreorder
|
||||
|
||||
#define EntryLo0 2
|
||||
#define EntryLo1 3
|
||||
#define EntryHi 10
|
||||
#define Random 1
|
||||
#define Index 0
|
||||
#define PageMask 5
|
||||
#define Wired 6
|
||||
#define Config 16
|
||||
#define Status 12
|
||||
#define Cause 13
|
||||
#define Compare 11
|
||||
|
||||
#define save_regs \
|
||||
sw $k0, -0x180($zero) ;\
|
||||
lw $k0, -0x184($zero) ;\
|
||||
sw $at, 12($k0) ;\
|
||||
sw $k1, 108($k0) ;\
|
||||
lw $k1, -0x180($zero) ;\
|
||||
sw $k1, 104($k0) ;\
|
||||
sw $v0, 16($k0) ;\
|
||||
sw $v1, 20($k0) ;\
|
||||
sw $t0, 40($k0) ;\
|
||||
sw $sp, 84($k0) ;\
|
||||
sw $fp, 88($k0) ;\
|
||||
sw $ra, 92($k0) ;\
|
||||
lw $gp, -12($zero) ;\
|
||||
la $sp, kernel_stack + KERNEL_STACK_SIZE ;\
|
||||
move $a0, $k0 ;\
|
||||
la $ra, kernel_exit ;\
|
||||
bal save_args
|
||||
|
||||
#define restore_regs \
|
||||
lw $v0, 96($k0) ;\
|
||||
lw $v1, 100($k0) ;\
|
||||
mthi $v0 ;\
|
||||
mtlo $v1 ;\
|
||||
lw $v0, 16($k0) ;\
|
||||
lw $v1, 20($k0) ;\
|
||||
lw $a0, 24($k0) ;\
|
||||
lw $a1, 28($k0) ;\
|
||||
lw $a2, 32($k0) ;\
|
||||
lw $a3, 36($k0) ;\
|
||||
lw $t0, 40($k0) ;\
|
||||
lw $t1, 44($k0) ;\
|
||||
lw $t2, 48($k0) ;\
|
||||
lw $t3, 52($k0) ;\
|
||||
lw $t4, 56($k0) ;\
|
||||
lw $t5, 60($k0) ;\
|
||||
lw $t6, 64($k0) ;\
|
||||
lw $t7, 68($k0) ;\
|
||||
lw $t8, 72($k0) ;\
|
||||
lw $t9, 76($k0) ;\
|
||||
lw $gp, 80($k0) ;\
|
||||
lw $sp, 84($k0) ;\
|
||||
lw $fp, 88($k0) ;\
|
||||
lw $ra, 92($k0) ;\
|
||||
lw $at, 12($k0) ;\
|
||||
lw $k1, 104($k0) ;\
|
||||
sw $k1, -0x180($zero) ;\
|
||||
lw $k1, 108($k0) ;\
|
||||
sw $k0, -0x184($zero) ;\
|
||||
lw $k0, -0x180($zero)
|
||||
|
||||
addr_000:
|
||||
// TLB refill
|
||||
@ -76,9 +18,10 @@ addr_000:
|
||||
li $a0, 0xffff0000
|
||||
la $t9, panic
|
||||
jr $t9
|
||||
nop
|
||||
|
||||
save_regs
|
||||
mfc0 $a1, $EntryHi
|
||||
sw $ra, -0x188($zero)
|
||||
bal save_regs
|
||||
la $t9, tlb_refill
|
||||
jr $t9
|
||||
nop
|
||||
@ -90,8 +33,10 @@ addr_100:
|
||||
li $a0, 0xaaaa0000
|
||||
la $t9, panic
|
||||
jr $t9
|
||||
nop
|
||||
|
||||
save_regs
|
||||
sw $ra, -0x188($zero)
|
||||
bal save_regs
|
||||
la $t9, cache_error
|
||||
jr $t9
|
||||
nop
|
||||
@ -100,11 +45,13 @@ addr_180:
|
||||
// General exception
|
||||
// TODO
|
||||
|
||||
li $a0, 0xaaff0000
|
||||
//li $a0, 0xaaff0000
|
||||
la $t9, panic
|
||||
jr $t9
|
||||
nop
|
||||
|
||||
save_regs
|
||||
sw $ra, -0x188($zero)
|
||||
bal save_regs
|
||||
la $t9, exception
|
||||
jr $t9
|
||||
nop
|
||||
@ -116,85 +63,83 @@ addr_200:
|
||||
li $a0, 0x0a0f0000
|
||||
la $t9, panic
|
||||
jr $t9
|
||||
nop
|
||||
|
||||
save_regs
|
||||
sw $ra, -0x188($zero)
|
||||
bal save_regs
|
||||
la $t9, interrupt
|
||||
jr $t9
|
||||
nop
|
||||
.fill 0x280 - (. - addr_000)
|
||||
.fill 0x280 - (. - addr_000) - 16
|
||||
|
||||
// space for save_regs.
|
||||
// space for save_regs: k0; current Thread; ra; gp
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
|
||||
start_idle:
|
||||
b .
|
||||
nop
|
||||
.word idle_page
|
||||
.word 0x80000000 // A pointer to the current page.
|
||||
|
||||
__start:
|
||||
bal 1f
|
||||
nop
|
||||
.word _gp
|
||||
// For some reason the disassembler considers everything
|
||||
// after __start non-code until the next label. So I add a label.
|
||||
start_hack:
|
||||
1: lw $gp, 0($ra)
|
||||
|
||||
la $sp, kernel_stack + KERNEL_STACK_SIZE
|
||||
|
||||
// Disable interrupts during bootstrap.
|
||||
mtc0 $zero, $Status
|
||||
|
||||
// TODO: flush cache
|
||||
|
||||
// Set kseg0 cachable.
|
||||
li $k0, 0x3
|
||||
mtc0 $k0, $Config, 0
|
||||
|
||||
// Clear .bss
|
||||
la $a0, _edata
|
||||
la $a1, _end
|
||||
1: sw $zero, 0($a0)
|
||||
bne $a1, $a0, 1b
|
||||
addu $a0, 4
|
||||
|
||||
// Set timer to a defined value
|
||||
mtc0 $zero, $Compare, 0
|
||||
|
||||
// Use the interrupt vector for interrupts
|
||||
li $k0, 1 << 23
|
||||
mtc0 $k0, $Cause
|
||||
|
||||
li $a0, 0xff0a0000
|
||||
la $t9, panic
|
||||
jr $t9
|
||||
|
||||
// clear the tlb, hardwire page 0 to 0xffffffff
|
||||
// and soft-wire it to (0x294 << 20) + (0x290 << 10)
|
||||
// (for the idle task).
|
||||
|
||||
// this address doesn't reach the tlb, so it can't trigger exceptions.
|
||||
mtc0 $zero, $PageMask
|
||||
mtc0 $zero, $EntryLo0
|
||||
mtc0 $zero, $EntryLo1
|
||||
li $t0, 0x80000000
|
||||
// There are 32 tlb entries.
|
||||
addi $a0, $zero, 31
|
||||
1: mtc0 $t0, $EntryHi
|
||||
mtc0 $a0, $Index
|
||||
tlbwi
|
||||
addiu $t0, $t0, 1 << 13
|
||||
bgtz $a0, 1b
|
||||
addiu $a0, $a0, -1
|
||||
|
||||
la $t9, init
|
||||
jalr $t9
|
||||
.word idle_page // 280
|
||||
.word 0x80000000 // 284 A pointer to the current page.
|
||||
start_idle: // 288
|
||||
// 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.
|
||||
mfc0 $a0, $9
|
||||
syscall
|
||||
1: wait
|
||||
b 1b
|
||||
nop
|
||||
sw $gp, -12($zero)
|
||||
|
||||
save_args:
|
||||
kernel_exit:
|
||||
move $k0, $v0
|
||||
lw $v0, 96($k0)
|
||||
lw $v1, 100($k0)
|
||||
mthi $v0
|
||||
mtlo $v1
|
||||
lw $v0, 16($k0)
|
||||
lw $v1, 20($k0)
|
||||
lw $a0, 24($k0)
|
||||
lw $a1, 28($k0)
|
||||
lw $a2, 32($k0)
|
||||
lw $a3, 36($k0)
|
||||
lw $t0, 40($k0)
|
||||
lw $t1, 44($k0)
|
||||
lw $t2, 48($k0)
|
||||
lw $t3, 52($k0)
|
||||
lw $t4, 56($k0)
|
||||
lw $t5, 60($k0)
|
||||
lw $t6, 64($k0)
|
||||
lw $t7, 68($k0)
|
||||
lw $t8, 72($k0)
|
||||
lw $t9, 76($k0)
|
||||
lw $gp, 80($k0)
|
||||
lw $sp, 84($k0)
|
||||
lw $fp, 88($k0)
|
||||
lw $ra, 92($k0)
|
||||
lw $at, 12($k0)
|
||||
lw $k1, 104($k0) // Real $k0
|
||||
sw $k1, -0x190($zero)
|
||||
lw $k1, 108($k0)
|
||||
sw $k0, -0x18c($zero)
|
||||
lw $k0, -0x190($zero)
|
||||
eret
|
||||
|
||||
save_regs:
|
||||
sw $k0, -0x190($zero)
|
||||
lw $k0, -0x18c($zero)
|
||||
sw $at, 12($k0)
|
||||
sw $gp, 80($k0)
|
||||
sw $sp, 84($k0)
|
||||
sw $fp, 88($k0)
|
||||
|
||||
sw $k1, 108($k0)
|
||||
lw $k1, -0x190($zero)
|
||||
sw $k1, 104($k0) // Real $k0
|
||||
|
||||
lw $k1, -0x188($zero)
|
||||
sw $k1, 92($k0) // Real $ra
|
||||
sw $v0, 16($k0)
|
||||
sw $v1, 20($k0)
|
||||
sw $a0, 24($k0)
|
||||
sw $a1, 28($k0)
|
||||
sw $a2, 32($k0)
|
||||
@ -208,23 +153,14 @@ save_args:
|
||||
sw $t7, 68($k0)
|
||||
sw $t8, 72($k0)
|
||||
sw $t9, 76($k0)
|
||||
sw $gp, 80($k0)
|
||||
j $ra
|
||||
mfhi $v0
|
||||
mflo $v1
|
||||
sw $v0, 96($k0)
|
||||
sw $v1, 100($k0)
|
||||
|
||||
run_idle:
|
||||
move $k0, $a0
|
||||
move $k1, $gp
|
||||
// Prepare enabling interrupts and switching to user mode.
|
||||
// The command is executed in the delay slot of the jump.
|
||||
li $t0, 0xff11
|
||||
// Now it's acceptable to receive an exception. Jump to kuseg,
|
||||
// thereby generating a tlb_refill exception (which is handled).
|
||||
// The address is the virtual address where the idle task is.
|
||||
la $t9, ((0x294 << 20) + (0x290 << 10) + 0x288)
|
||||
lw $gp, -0x184($zero)
|
||||
la $sp, kernel_stack + KERNEL_STACK_SIZE
|
||||
move $t9, $ra
|
||||
la $ra, kernel_exit
|
||||
jr $t9
|
||||
mtc0 $t0, $Status
|
||||
|
||||
kernel_exit:
|
||||
move $k0, $v0
|
||||
restore_regs
|
||||
eret
|
||||
move $a0, $k0
|
||||
|
125
init.ccp
Normal file
125
init.ccp
Normal file
@ -0,0 +1,125 @@
|
||||
#pypp 0
|
||||
#include "kernel.hh"
|
||||
|
||||
static void init_idle ():
|
||||
// initialize idle task as if it is currently running.
|
||||
idle.size = sizeof (Thread)
|
||||
idle.prev = NULL
|
||||
idle.next = NULL
|
||||
idle.thread_prev = NULL
|
||||
idle.thread_next = NULL
|
||||
idle.schedule_prev = NULL
|
||||
idle.schedule_next = NULL
|
||||
idle.address_space = &idle_memory
|
||||
// initialize idle_memory.
|
||||
idle_memory.size = sizeof (Memory)
|
||||
idle_memory.prev = NULL
|
||||
idle_memory.next = NULL
|
||||
idle_memory.memory_prev = NULL
|
||||
idle_memory.memory_next = NULL
|
||||
idle_memory.pages = &idle_page
|
||||
idle_memory.threads = &idle
|
||||
idle_memory.memories = NULL
|
||||
idle_memory.limit = 0
|
||||
idle_memory.used = 0
|
||||
idle_memory.cpu.directory = (Page ***)0x80000000
|
||||
idle_memory.cpu.asid = 0
|
||||
// initialize idle_page
|
||||
idle_page.size = sizeof (Page)
|
||||
idle_page.prev = NULL
|
||||
idle_page.next = NULL
|
||||
idle_page.page_prev = NULL
|
||||
idle_page.page_next = NULL
|
||||
// Not an error, this is really physical page 0.
|
||||
idle_page.physical = 0
|
||||
|
||||
static void init_cp0 ():
|
||||
// Set timer to a defined value (11 is Compare)
|
||||
__asm__ volatile ("mtc0 %0, $11, 0" :: "r"(1000000))
|
||||
// Reset timer (9 is Count)
|
||||
__asm__ volatile ("mtc0 $zero, $9, 0")
|
||||
// Use the interrupt vector for interrupts (13 is Cause)
|
||||
__asm__ volatile ("mtc0 %0, $13" :: "r"(1 << 23))
|
||||
|
||||
// clear the tlb, hardwire page 0 to 0xffffffff
|
||||
// and soft-wire it to (0x294 << 20) + (0x290 << 10)
|
||||
// (for the idle task).
|
||||
|
||||
// 6 is Wired.
|
||||
__asm__ volatile ("mtc0 %0, $6" :: "r"(1))
|
||||
// 5 is PageMask.
|
||||
__asm__ volatile ("mtc0 $zero, $5")
|
||||
// 2 is EntryLo0.
|
||||
__asm__ volatile ("mtc0 $zero, $2")
|
||||
// 3 is EntryLo1.
|
||||
__asm__ volatile ("mtc0 $zero, $3")
|
||||
// Get number of tlb entries (is 31).
|
||||
unsigned num;
|
||||
__asm__ volatile ("mfc0 %0, $16, 1" : "=r"(num))
|
||||
num >>= 25
|
||||
num &= 0x3f
|
||||
// Clear the tlb.
|
||||
#if 0
|
||||
for unsigned i = 1; i < num; ++i:
|
||||
// this address doesn't reach the tlb, so it can't trigger exceptions.
|
||||
// 10 is EntryHi
|
||||
__asm__ volatile ("mtc0 %0, $10" :: "r"(0x70000000 + 0x1000 * i))
|
||||
// 0 is Index.
|
||||
__asm__ volatile ("mtc0 %0, $0" :: "r"(i))
|
||||
// write the data.
|
||||
__asm__ volatile ("tlbwi")
|
||||
#endif
|
||||
// Fill the upper page in kseg3.
|
||||
__asm__ volatile ("mtc0 %0, $10" :: "r"(0xfffff000))
|
||||
__asm__ volatile ("mtc0 %0, $2" :: "r"(0x0000001d))
|
||||
__asm__ volatile ("mtc0 %0, $3" :: "r"(0x0000001f))
|
||||
__asm__ volatile ("mtc0 %0, $0" :: "r"(0))
|
||||
__asm__ volatile ("tlbwi")
|
||||
// Fill the idle task's page in useg. Set it to non-cachable.
|
||||
__asm__ volatile ("mtc0 %0, $10" :: "r"(0x284a0000))
|
||||
__asm__ volatile ("mtc0 %0, $2" :: "r"(0x00000016))
|
||||
__asm__ volatile ("mtc0 %0, $3" :: "r"(0x00000014))
|
||||
__asm__ volatile ("tlbwr")
|
||||
// Allow eret to be used to jump to the idle task.
|
||||
// 14 is EPC.
|
||||
__asm__ volatile ("mtc0 %0, $14" :: "r"(0x284a0288))
|
||||
// Enable all interrupts and say we're handling an exception.
|
||||
// 12 is Status.
|
||||
__asm__ volatile ("mtc0 %0, $12" :: "r"(0x1000ff13))
|
||||
|
||||
/// Initialize the kernel, finish by falling into the idle task.
|
||||
extern unsigned _end
|
||||
void init ():
|
||||
// Initialize kernel variables to empty.
|
||||
sleepers = NULL
|
||||
runners = NULL
|
||||
zero_pages = NULL
|
||||
// Fill junk pages with all memory not currently used.
|
||||
junk_pages = (FreePage *)(((unsigned)&_end + (1 << 12) - 1) & ~((1 << 12) - 1))
|
||||
FreePage *p, *next
|
||||
unsigned count = 1
|
||||
for p = junk_pages, next = p; (unsigned)next - 0x80000000 < (1 << 27); p = next, next = (FreePage *)((unsigned)p + (1 << 12)):
|
||||
p->next = next
|
||||
++count
|
||||
p->next = NULL
|
||||
// initialize system control coprocessor.
|
||||
init_cp0 ()
|
||||
// initialize everything about the idle task.
|
||||
init_idle ()
|
||||
// initialize top_memory.
|
||||
top_memory.size = sizeof (Memory)
|
||||
top_memory.prev = NULL
|
||||
top_memory.next = NULL
|
||||
top_memory.memory_prev = NULL
|
||||
top_memory.memory_next = NULL
|
||||
top_memory.pages = NULL
|
||||
top_memory.threads = NULL
|
||||
top_memory.memories = NULL
|
||||
top_memory.limit = count
|
||||
top_memory.used = 0
|
||||
top_memory.cpu.directory = NULL
|
||||
top_memory.cpu.asid = 0
|
||||
// TOOO: set up initial threads.
|
||||
|
||||
// Done; return to user space (the idle task).
|
||||
__asm__ volatile ("eret")
|
@ -2,7 +2,7 @@
|
||||
#include "kernel.hh"
|
||||
|
||||
// hi and lo cannot be saved in assemply due to space restrictions.
|
||||
#define save_hilo(x) do { __asm__ ("mfhi %0 ; mflo %1" : "=r"((x)->cpu.hi), "=r"((x)->cpu.lo)); } while (0)
|
||||
#define save_hilo(x) do { __asm__ volatile ("mfhi %0 ; mflo %1" : "=r"((x)->cpu.hi), "=r"((x)->cpu.lo)); } while (0)
|
||||
|
||||
/// A TLB miss has occurred. This should eventually move to entry.S.
|
||||
Thread *tlb_refill (Thread *current, unsigned EntryHi):
|
||||
@ -29,7 +29,7 @@ Thread *tlb_refill (Thread *current, unsigned EntryHi):
|
||||
low1 = page1->physical | 0x18 | 0x4 | 0x2
|
||||
else
|
||||
low1 = 0
|
||||
__asm__ ("mtc0 %0, $2; mtc0 %1, $3; tlbwr" :: "r"(low0), "r"(low1))
|
||||
__asm__ volatile ("mtc0 %0, $2; mtc0 %1, $3; tlbwr" :: "r"(low0), "r"(low1))
|
||||
return current
|
||||
|
||||
/// An interrupt which is not an exception has occurred.
|
||||
@ -49,67 +49,3 @@ Thread *cache_error (Thread *current):
|
||||
save_hilo (current)
|
||||
panic (0x33333333, "cache error")
|
||||
return current
|
||||
|
||||
static void init_idle ():
|
||||
// initialize idle task as if it is currently running.
|
||||
idle.size = sizeof (Thread)
|
||||
idle.prev = NULL
|
||||
idle.next = NULL
|
||||
idle.thread_prev = NULL
|
||||
idle.thread_next = NULL
|
||||
idle.schedule_prev = NULL
|
||||
idle.schedule_next = NULL
|
||||
idle.address_space = &idle_memory
|
||||
// initialize idle_memory.
|
||||
idle_memory.size = sizeof (Memory)
|
||||
idle_memory.prev = NULL
|
||||
idle_memory.next = NULL
|
||||
idle_memory.memory_prev = NULL
|
||||
idle_memory.memory_next = NULL
|
||||
idle_memory.pages = &idle_page
|
||||
idle_memory.threads = &idle
|
||||
idle_memory.memories = NULL
|
||||
idle_memory.limit = 0
|
||||
idle_memory.used = 0
|
||||
idle_memory.cpu.directory = (Page ***)0x80000000
|
||||
idle_memory.cpu.asid = 0
|
||||
// initialize idle_page
|
||||
idle_page.size = sizeof (Page)
|
||||
idle_page.prev = NULL
|
||||
idle_page.next = NULL
|
||||
idle_page.page_prev = NULL
|
||||
idle_page.page_next = NULL
|
||||
// Not an error, this is really physical page 0.
|
||||
idle_page.physical = 0
|
||||
|
||||
/// Initialize the kernel, finish by falling into the idle task.
|
||||
extern unsigned _end
|
||||
void init ():
|
||||
// Initialize kernel variables to empty.
|
||||
sleepers = NULL
|
||||
runners = NULL
|
||||
zero_pages = NULL
|
||||
// Fill junk pages with all memory not currently used.
|
||||
junk_pages = (FreePage *)(((unsigned)&_end + (1 << 12) - 1) & ~((1 << 12) - 1))
|
||||
FreePage *p, *next
|
||||
unsigned count = 1
|
||||
for p = junk_pages; (unsigned)next - 0x80000000 < (1 << 27); p = next, next = (FreePage *)((unsigned)p + 1 << 12):
|
||||
p->next = next
|
||||
++count
|
||||
p->next = NULL
|
||||
// initialize everything about the idle task.
|
||||
init_idle ()
|
||||
// initialize top_memory.
|
||||
top_memory.size = sizeof (Memory)
|
||||
top_memory.prev = NULL
|
||||
top_memory.next = NULL
|
||||
top_memory.memory_prev = NULL
|
||||
top_memory.memory_next = NULL
|
||||
top_memory.pages = NULL
|
||||
top_memory.threads = NULL
|
||||
top_memory.memories = NULL
|
||||
top_memory.limit = count
|
||||
top_memory.used = 0
|
||||
top_memory.cpu.directory = NULL
|
||||
top_memory.cpu.asid = 0
|
||||
// TOOO: set up initial threads.
|
||||
|
@ -4,7 +4,7 @@
|
||||
void panic (unsigned n, char const *message):
|
||||
while (1):
|
||||
for unsigned bit = 0x80000000; bit; bit >>= 1:
|
||||
for int i = 0; i < 60000; ++i:
|
||||
led (n & bit, i > 20000 && i < 40000)
|
||||
for int i = 0; i < 100000; ++i:
|
||||
for int i = 0; i < 600000; ++i:
|
||||
led (n & bit, i > 200000 && i < 400000)
|
||||
for int i = 0; i < 1000000; ++i:
|
||||
led (false, false)
|
||||
|
24
start.S
24
start.S
@ -1,24 +0,0 @@
|
||||
.set noreorder
|
||||
.globl __start
|
||||
.globl kernel_stack
|
||||
__start:
|
||||
bal 1f
|
||||
nop
|
||||
.word _gp
|
||||
1: lw $gp, 0($ra)
|
||||
nop
|
||||
|
||||
la $a0, _edata
|
||||
la $a1, _end
|
||||
1: sw $zero, 0($a0)
|
||||
bne $a1, $a0, 1b
|
||||
addu $a0, 4
|
||||
|
||||
la $sp, kernel_stack + KERNEL_STACK_SIZE
|
||||
|
||||
bal kernel_entry
|
||||
nop
|
||||
b .
|
||||
nop
|
||||
|
||||
.lcomm kernel_stack, KERNEL_STACK_SIZE
|
Loading…
Reference in New Issue
Block a user