//boot/trunk/arch/ppc32/loader/asm.S |
---|
181,6 → 181,7 |
blr |
jump_to_kernel: |
mr r10, r4 |
mtlr r3 |
blr |
//boot/trunk/arch/ppc32/loader/ofw.h |
---|
30,7 → 30,9 |
#define __OFW_H__ |
#define NULL 0 |
#define MAX_OFW_ARGS 10 |
#define MEMMAP_MAX_RECORDS 32 |
#define false 0 |
#define true 1 |
typedef __builtin_va_list va_list; |
38,33 → 40,25 |
#define va_arg(ap, type) __builtin_va_arg(ap, type) |
#define va_end(ap) __builtin_va_end(ap) |
typedef unsigned int ofw_arg_t; |
typedef unsigned int ihandle; |
typedef unsigned int phandle; |
typedef struct { |
void *start; |
unsigned int size; |
} memzone_t; |
/** OpenFirmware command structure |
* |
*/ |
typedef struct { |
const char *service; /**< Command name */ |
unsigned int nargs; /**< Number of in arguments */ |
unsigned int nret; /**< Number of out arguments */ |
ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments */ |
} ofw_args_t; |
unsigned int total; |
unsigned int count; |
memzone_t zones[MEMMAP_MAX_RECORDS]; |
} memmap_t; |
typedef void (*ofw_entry)(ofw_args_t *); |
extern void init(void); |
void halt(void); |
extern void halt(void); |
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, ...); |
extern ihandle ofw_open(const char *name); |
extern void ofw_write(const char *str, const int len); |
extern void *ofw_translate(const void *virt); |
extern int ofw_map(const void *phys, const void *virt, const int size, const int mode); |
extern int ofw_memmap(memmap_t *map); |
#endif |
//boot/trunk/arch/ppc32/loader/main.c |
---|
28,7 → 28,6 |
#include "main.h" |
#include "printf.h" |
#include "ofw.h" |
#include "asm.h" |
#define KERNEL_PHYSICAL_ADDRESS 0x1000 |
37,6 → 36,8 |
#define KERNEL_END &_binary_____________kernel_kernel_bin_end |
#define KERNEL_SIZE ((unsigned int) KERNEL_END - (unsigned int) KERNEL_START) |
memmap_t memmap; |
void bootstrap(void) |
{ |
printf("\nHelenOS PPC Bootloader\n"); |
44,6 → 45,12 |
void *phys = ofw_translate(&start); |
printf("loaded at %L (physical %L)\n", &start, phys); |
if (!ofw_memmap(&memmap)) { |
printf("Unable to get memory map\n"); |
halt(); |
} |
printf("total memory %d MB\n", memmap.total >> 20); |
// 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); |
59,5 → 66,5 |
printf("Booting the kernel...\n"); |
flush_instruction_cache(); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, ofw_translate(&memmap)); |
} |
//boot/trunk/arch/ppc32/loader/asm.h |
---|
30,7 → 30,7 |
#define __ASM_H__ |
void flush_instruction_cache(void); |
void jump_to_kernel(void *addr) __attribute__((noreturn)); |
void jump_to_kernel(void *code, void *memmap) __attribute__((noreturn)); |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
//boot/trunk/arch/ppc32/loader/_link.ld |
---|
18,5 → 18,6 |
*(.sdata2); |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
} |
} |
//boot/trunk/arch/ppc32/loader/main.h |
---|
29,9 → 29,13 |
#ifndef __MAIN_H__ |
#define __MAIN_H__ |
#include "ofw.h" |
extern int _binary_____________kernel_kernel_bin_start; |
extern int _binary_____________kernel_kernel_bin_end; |
extern void start(void); |
extern void bootstrap(void); |
extern memmap_t memmap; |
#endif |
//boot/trunk/arch/ppc32/loader/ofw.c |
---|
29,36 → 29,33 |
#include "ofw.h" |
#include "printf.h" |
ofw_entry ofw; |
#define MAX_OFW_ARGS 10 |
phandle ofw_chosen; |
ihandle ofw_mmu; |
ihandle ofw_stdout; |
typedef unsigned int ofw_arg_t; |
typedef unsigned int ihandle; |
typedef unsigned int phandle; |
/** OpenFirmware command structure |
* |
*/ |
typedef struct { |
const char *service; /**< Command name */ |
unsigned int nargs; /**< Number of in arguments */ |
unsigned int nret; /**< Number of out arguments */ |
ofw_arg_t args[MAX_OFW_ARGS]; /**< List of arguments */ |
} ofw_args_t; |
void init(void) |
{ |
ofw_chosen = ofw_find_device("/chosen"); |
if (ofw_chosen == -1) |
halt(); |
typedef void (*ofw_entry)(ofw_args_t *); |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
ofw_stdout = 0; |
ofw_mmu = ofw_open("/mmu"); |
if (ofw_mmu == -1) { |
puts("Unable to open /mmu node\n"); |
halt(); |
} |
} |
ofw_entry ofw; |
void halt(void) |
{ |
ofw_call("exit", 0, 0); |
} |
phandle ofw_chosen; |
ihandle ofw_mmu; |
ihandle ofw_stdout; |
int ofw_call(const char *service, const int nargs, const int nret, ...) |
static int ofw_call(const char *service, const int nargs, const int nret, ...) |
{ |
va_list list; |
ofw_args_t args; |
82,30 → 79,52 |
} |
ihandle ofw_open(const char *name) |
static phandle ofw_find_device(const char *name) |
{ |
return ofw_call("finddevice", 1, 1, name); |
} |
static int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen) |
{ |
return ofw_call("getprop", 4, 1, device, name, buf, buflen); |
} |
static ihandle ofw_open(const char *name) |
{ |
return ofw_call("open", 1, 1, name); |
} |
void ofw_write(const char *str, const int len) |
void init(void) |
{ |
if (ofw_stdout == 0) |
return; |
ofw_chosen = ofw_find_device("/chosen"); |
if (ofw_chosen == -1) |
halt(); |
ofw_call("write", 3, 1, ofw_stdout, str, len); |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
ofw_stdout = 0; |
ofw_mmu = ofw_open("/mmu"); |
if (ofw_mmu == -1) { |
puts("Unable to open /mmu node\n"); |
halt(); |
} |
} |
phandle ofw_find_device(const char *name) |
void halt(void) |
{ |
return ofw_call("finddevice", 1, 1, name); |
ofw_call("exit", 0, 0); |
} |
int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen) |
void ofw_write(const char *str, const int len) |
{ |
return ofw_call("getprop", 4, 1, device, name, buf, buflen); |
if (ofw_stdout == 0) |
return; |
ofw_call("write", 3, 1, ofw_stdout, str, len); |
} |
119,3 → 138,27 |
{ |
return ofw_call("call-method", 6, 1, "map", ofw_mmu, mode, size, virt, phys); |
} |
int ofw_memmap(memmap_t *map) |
{ |
int i; |
int ret; |
phandle handle = ofw_find_device("/memory"); |
if (handle == -1) |
return false; |
ret = ofw_get_property(handle, "reg", &map->zones, sizeof(map->zones)); |
if (ret == -1) |
return false; |
map->total = 0; |
map->count = 0; |
for (i = 0; i < MEMMAP_MAX_RECORDS; i++) { |
if (map->zones[i].size == 0) |
break; |
map->count++; |
map->total += map->zones[i].size; |
} |
} |