1
0
mirror of git://projects.qi-hardware.com/iris.git synced 2024-07-07 19:08:54 +03:00
iris/init.ccp
Bas Wijnen 60ea570aaa more
2009-05-20 22:07:56 +02:00

142 lines
4.1 KiB
COBOL

#pypp 0
// Also declare things which only work during kernel init.
#define INIT
#include "kernel.hh"
#define reg_hack(x) #x
#define cp0_get(reg, sel, target) do { __asm__ volatile ("mfc0 %0, $" reg_hack(reg) ", " #sel : "=r" (target)); } while (0)
#define cp0_set(reg, value) do { __asm__ volatile ("mtc0 %0, $" reg_hack(reg) :: "r" (value)); } while (0)
#define cp0_set0(reg) do { __asm__ volatile ("mtc0 $zero, $" reg_hack(reg)); } while (0)
// cp0 registers.
#define CP0_INDEX 0
#define CP0_ENTRY_LO0 2
#define CP0_ENTRY_LO1 3
#define CP0_PAGE_MASK 5
#define CP0_WIRED 6
#define CP0_COUNT 9
#define CP0_ENTRY_HI 10
#define CP0_COMPARE 11
#define CP0_STATUS 12
#define CP0_CAUSE 13
#define CP0_EPC 14
#define CP0_CONFIG 16
static void init_idle ():
// initialize idle task as if it is currently running.
idle.prev_obj = NULL
idle.next_obj = NULL
idle.prev = NULL
idle.next = NULL
idle.schedule_prev = NULL
idle.schedule_next = NULL
idle.address_space = &idle_memory
// initialize idle_memory.
idle_memory.prev_obj = NULL
idle_memory.next_obj = NULL
idle_memory.prev = NULL
idle_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.arch.directory = (unsigned **)0x80000000
idle_memory.arch.asid = 0
// initialize idle_page
idle_page.prev_obj = NULL
idle_page.next_obj = NULL
idle_page.prev = NULL
idle_page.next = NULL
idle_page.physical = (void *)0
static void init_cp0 ():
// Set timer to a defined value
cp0_set (CP0_COMPARE, 1000000)
// Reset timer
cp0_set0 (CP0_COUNT)
// Use the interrupt vector for interrupts
cp0_set (CP0_CAUSE, 1 << 23)
// clear the tlb, hardwire page 0 to 0xffffffff
// and soft-wire it to (0x294 << 20) + (0x290 << 10)
// (for the idle task).
cp0_set (CP0_WIRED, 1)
cp0_set0 (CP0_PAGE_MASK)
cp0_set0 (CP0_ENTRY_LO0)
cp0_set0 (CP0_ENTRY_LO1)
// Get number of tlb entries (is 31).
unsigned num;
cp0_get (CP0_CONFIG, 1, 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.
cp0_set (CP0_ENTRY_HI, 0x70000000 + 0x1000 * i)
cp0_set (CP0_INDEX, i)
// write the data.
__asm__ volatile ("tlbwi")
#endif
// Fill the upper page in kseg3.
cp0_set (CP0_ENTRY_HI, 0xfffff000)
cp0_set (CP0_ENTRY_LO0, 0x1d)
cp0_set (CP0_ENTRY_LO1, 0x1f)
cp0_set0 (CP0_INDEX)
__asm__ volatile ("tlbwi")
// Fill the idle task's page in useg. Set it to non-cachable.
cp0_set (CP0_ENTRY_HI, 0x284a0000)
cp0_set (CP0_ENTRY_LO0, 0x16)
cp0_set (CP0_ENTRY_LO1, 0x14)
__asm__ volatile ("tlbwr")
// Allow eret to be used to jump to the idle task.
cp0_set (CP0_EPC, 0x284a0288)
// 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)
static void init_threads ():
for unsigned i = 0; i < NUM_THREADS; ++i:
Memory *mem = top_memory.alloc_memory ()
Thread *thread = mem->alloc_thread ()
// TODO
/// 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.prev_obj = NULL
top_memory.next_obj = NULL
top_memory.prev = NULL
top_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.arch.directory = NULL
top_memory.arch.asid = 0
init_threads ()
// Done; return to user space (the idle task).
__asm__ volatile ("eret")