//boot/trunk/arch/ppc32/loader/asm.S |
---|
46,7 → 46,7 |
# r3 = memmap (pa) |
# r4 = trans (pa) |
# r5 = number of kernel pages |
# r5 = kernel size |
# r6 = real_mode (pa) |
mtspr srr0, r6 |
69,9 → 69,9 |
# copy kernel to proper location |
# |
# r4 = trans (pa) |
# r5 = number of kernel pages |
# r5 = kernel size |
li r31, PAGE_SIZE >> 3 |
li r31, PAGE_SIZE >> 2 |
li r30, 0 |
page_copy: |
79,7 → 79,7 |
cmpwi r5, 0 |
beq copy_end |
# copy single page |
# copy page |
mtctr r31 |
lwz r29, 0(r4) |
91,33 → 91,85 |
addi r29, r29, 4 |
addi r30, r30, 4 |
subi r5, r5, 4 |
cmpwi r5, 0 |
beq copy_end |
bdnz copy_loop |
subi r5, r5, 1 |
addi r4, r4, 4 |
b page_copy |
copy_end: |
# fill segment registers |
# invalidate segment registers |
li r31, 16 |
mtctr r31 |
li r31, 0 |
li r30, 0x2000 |
# li r31, 16 |
# mtctr r31 |
# li r31, 0 |
# li r30, 0 |
seg_fill: |
mtsrin r30, r31 |
addis r31, r31, 0x1000 # add 256 MB |
addi r30, r30, 0x111 # move to next SR |
bdnz seg_fill |
# mtsrin r30, r31 |
# addis r31, r31, 0x1000 # move to next SR |
# |
# bdnz seg_fill |
# invalidate block address translation registers |
mtspr ibat0u, r30 |
mtspr ibat0l, r30 |
mtspr ibat1u, r30 |
mtspr ibat1l, r30 |
mtspr ibat2u, r30 |
mtspr ibat2l, r30 |
mtspr ibat3u, r30 |
mtspr ibat3l, r30 |
mtspr dbat0u, r30 |
mtspr dbat0l, r30 |
mtspr dbat1u, r30 |
mtspr dbat1l, r30 |
mtspr dbat2u, r30 |
mtspr dbat2l, r30 |
mtspr dbat3u, r30 |
mtspr dbat3l, r30 |
# create identity mapping |
# FIXME: map exactly the size of RAM |
lis r31, 0x8000 |
ori r31, r31, 0x0ffe |
lis r30, 0x0000 |
ori r30, r30, 0x0002 |
mtspr ibat0u, r31 |
mtspr ibat0l, r30 |
mtspr dbat0u, r31 |
mtspr dbat0l, r30 |
# FIXME: temporal framebuffer mapping |
lis r31, 0xf000 |
ori r31, r31, 0x0ffe |
lis r30, 0x8400 |
ori r30, r30, 0x0002 |
mtspr dbat1u, r31 |
mtspr dbat1l, r30 |
tlbia |
# start the kernel |
//boot/trunk/arch/ppc32/loader/regname.h |
---|
189,6 → 189,22 |
#define sprg2 274 |
#define sprg3 275 |
#define prv 287 |
#define ibat0u 528 |
#define ibat0l 529 |
#define ibat1u 530 |
#define ibat1l 531 |
#define ibat2u 532 |
#define ibat2l 533 |
#define ibat3u 534 |
#define ibat3l 535 |
#define dbat0u 536 |
#define dbat0l 537 |
#define dbat1u 538 |
#define dbat1l 539 |
#define dbat2u 540 |
#define dbat2l 541 |
#define dbat3u 542 |
#define dbat3l 543 |
#define hid0 1008 |
/* MSR bits */ |
//boot/trunk/arch/ppc32/loader/main.c |
---|
46,6 → 46,15 |
} |
static void check_overlap(const void *addr, const char *desc) |
{ |
if ((unsigned int) addr < KERNEL_SIZE) { |
printf("Error: %s overlaps kernel physical area\n", desc); |
halt(); |
} |
} |
void bootstrap(void) |
{ |
printf("\nHelenOS PPC Bootloader\n"); |
54,33 → 63,32 |
check_align(&real_mode, "Bootstrap trampoline"); |
check_align(&trans, "Translation table"); |
if (!ofw_memmap(&memmap)) { |
printf("Error: Unable to get memory map\n"); |
halt(); |
} |
void *real_mode_pa = ofw_translate(&real_mode); |
void *trans_pa = ofw_translate(&trans); |
void *memmap_pa = ofw_translate(&memmap); |
printf("Memory statistics\n"); |
check_overlap(real_mode_pa, "Bootstrap trampoline"); |
check_overlap(trans_pa, "Translation table"); |
check_overlap(memmap_pa, "Memory map"); |
printf("Memory statistics (total %d MB)\n", memmap.total >> 20); |
printf(" kernel image at %L (size %d bytes)\n", KERNEL_START, KERNEL_SIZE); |
printf(" memory map at %L (physical %L)\n", &memmap, memmap_pa); |
printf(" bootstrap trampoline at %L (physical %L)\n", &real_mode, real_mode_pa); |
printf(" translation table at %L (physical %L)\n", &trans, trans_pa); |
if (!ofw_memmap(&memmap)) { |
printf("Unable to get memory map\n"); |
halt(); |
} |
printf("Total memory %d MB\n", memmap.total >> 20); |
unsigned int addr; |
unsigned int pages; |
for (addr = 0, pages = 0; addr < KERNEL_SIZE; addr += PAGE_SIZE, pages++) { |
for (addr = 0; addr < KERNEL_SIZE; addr += PAGE_SIZE) { |
void *pa = ofw_translate(KERNEL_START + addr); |
if ((unsigned int) pa < KERNEL_SIZE) { |
printf("Error: Kernel image overlaps kernel physical area\n"); |
halt(); |
} |
check_overlap(pa, "Kernel image"); |
trans[addr >> PAGE_WIDTH] = pa; |
} |
printf("Booting the kernel...\n"); |
jump_to_kernel(memmap_pa, trans_pa, pages, real_mode_pa); |
jump_to_kernel(memmap_pa, trans_pa, KERNEL_SIZE, real_mode_pa); |
} |
//boot/trunk/arch/ppc32/loader/asm.h |
---|
35,7 → 35,7 |
#define TRANS_SIZE 1024 |
#define TRANS_ITEM_SIZE 4 |
#define KERNEL_START_ADDR 0x80002000 |
#define KERNEL_START_ADDR 0x80004000 |
#ifndef __ASM__ |
42,7 → 42,7 |
extern void *trans[TRANS_SIZE]; |
extern void halt(); |
extern void jump_to_kernel(void *memmap, void *trans, unsigned int cnt, void *real_mode) __attribute__((noreturn)); |
extern void jump_to_kernel(void *memmap, void *trans, unsigned int kernel_size, void *real_mode) __attribute__((noreturn)); |
extern void real_mode(); |
#endif |
//boot/trunk/arch/ppc32/loader/_link.ld |
---|
20,9 → 20,8 |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
} |
.image 0x10000000+SIZEOF(.boot): AT (SIZEOF(.boot)) SUBALIGN(4096) { |
. = ALIGN(4096); |
*(.image); |
} |
} |