//boot/trunk/arch/ppc32/loader/asm.S |
---|
38,6 → 38,7 |
.global memsetb |
.global memcpy |
.global flush_instruction_cache |
.global jump_to_kernel |
memsetb: |
180,11 → 181,6 |
blr |
jump_to_kernel: |
mtspr SPRN_SRR0, r3 |
mfmsr r3 |
lis r4, ~0@h |
ori r4, r4, ~(MSR_IR | MSR_DR)@l |
and r3, r3, r4 |
mtspr SPRN_SRR1, r3 |
bl flush_instruction_cache |
rfi |
mtlr r3 |
blr |
//boot/trunk/arch/ppc32/loader/ofw.h |
---|
60,12 → 60,11 |
extern phandle ofw_find_device(const char *name); |
extern int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen); |
extern int ofw_call(const char *service, const int nargs, const int nret, ...); |
#define ofw_call_method(instance, method, nargs, nret, ...) ofw_call("call-method", (nargs + 2), nret, method, instance, ##__VA_ARGS__) |
extern ihandle ofw_open(const char *name); |
extern void ofw_write(const char *str, const int len); |
extern void *ofw_claim(const void *addr, const int size, const int align); |
extern void *ofw_translate(const void *virt); |
extern int ofw_map(const void *phys, const void *virt, const int size, const int mode); |
#endif |
//boot/trunk/arch/ppc32/loader/main.c |
---|
31,7 → 31,8 |
#include "ofw.h" |
#include "asm.h" |
#define KERNEL_LOAD_ADDRESS 0x400000 |
#define KERNEL_PHYSICAL_ADDRESS 0x1000 |
#define KERNEL_VIRTUAL_ADDRESS 0x80001000 |
#define KERNEL_START &_binary_____________kernel_kernel_bin_start |
#define KERNEL_END &_binary_____________kernel_kernel_bin_end |
#define KERNEL_SIZE ((unsigned int) KERNEL_END - (unsigned int) KERNEL_START) |
40,18 → 41,23 |
{ |
printf("\nHelenOS PPC Bootloader\n"); |
void *loader = ofw_translate(&start); |
printf("loaded at %L (physical %L)\n", &start, loader); |
printf("kernel load address %L (size %d)\n", KERNEL_LOAD_ADDRESS, KERNEL_SIZE); |
void *phys = ofw_translate(&start); |
printf("loaded at %L (physical %L)\n", &start, phys); |
void *addr = ofw_claim((void *) KERNEL_LOAD_ADDRESS, KERNEL_SIZE, 1); |
if (addr == NULL) { |
printf("Error: Unable to claim memory"); |
// FIXME: map just the kernel |
if (ofw_map((void *) KERNEL_PHYSICAL_ADDRESS, (void *) KERNEL_VIRTUAL_ADDRESS, 1024 * 1024, 0) != 0) { |
printf("Unable to map kernel memory at %L (physical %L)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS); |
halt(); |
} |
printf("Claimed memory at %L\n", addr); |
memcpy(addr, KERNEL_START, KERNEL_SIZE); |
printf("kernel memory mapped at %L (physical %L, size %d bytes)\n", KERNEL_VIRTUAL_ADDRESS, KERNEL_PHYSICAL_ADDRESS, KERNEL_SIZE); |
// FIXME: relocate the kernel in real mode |
memcpy((void *) KERNEL_VIRTUAL_ADDRESS, KERNEL_START, KERNEL_SIZE); |
// FIXME: proper framebuffer mapping |
ofw_map((void *) 0x84000000, (void *) 0x84000000, 2 * 1024 * 1024, 0); |
printf("Booting the kernel...\n"); |
jump_to_kernel(addr); |
flush_instruction_cache(); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS); |
} |
//boot/trunk/arch/ppc32/loader/asm.h |
---|
29,6 → 29,7 |
#ifndef __ASM_H__ |
#define __ASM_H__ |
void flush_instruction_cache(void); |
void jump_to_kernel(void *addr) __attribute__((noreturn)); |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
//boot/trunk/arch/ppc32/loader/_link.ld |
---|
7,7 → 7,7 |
ENTRY(start) |
SECTIONS { |
.image 0x80000000: AT (0x80000000) { |
.image 0x10000000: AT (0) { |
*(BOOTSTRAP) |
*(.text); |
//boot/trunk/arch/ppc32/loader/ofw.c |
---|
78,10 → 78,7 |
ofw(&args); |
if (nret > 0) |
return args.args[nargs + nret - 1]; |
else |
return 0; |
return args.args[nargs]; |
} |
112,13 → 109,13 |
} |
void *ofw_claim(const void *addr, const int size, const int align) |
void *ofw_translate(const void *virt) |
{ |
return (void *) ofw_call("claim", 3, 1, addr, size, align); |
return (void *) ofw_call("call-method", 7, 1, "translate", ofw_mmu, virt, 0, 0, 0, 0); |
} |
void *ofw_translate(const void *virt) |
int ofw_map(const void *phys, const void *virt, const int size, const int mode) |
{ |
return (void *) ofw_call_method(ofw_mmu, "translate", 1, 5, virt); |
return ofw_call("call-method", 6, 1, "map", ofw_mmu, mode, size, virt, phys); |
} |