/boot/trunk/arch/ppc64/Makefile.inc |
---|
28,12 → 28,12 |
build: image.boot |
image.boot: kernel |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNEL=../../../$(KERNELDIR)/kernel.bin |
image.boot: kernel uspace |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
cp arch/$(ARCH)/loader/image.boot image.boot |
clean: clean_kernel |
make -C arch/$(ARCH)/loader clean |
clean: clean_kernel clean_uspace |
make -C arch/$(ARCH)/loader clean KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
-rm -f image.boot |
arch_distclean: distclean_kernel |
arch_distclean: distclean_kernel distclean_uspace |
/boot/trunk/arch/ppc64/loader/_link.ld |
---|
File deleted |
/boot/trunk/arch/ppc64/loader/asm.S |
---|
106,12 → 106,19 |
# r3 = bootinfo (pa) |
# r4 = bootinfo_size |
# r5 = trans (pa) |
# r6 = kernel size |
# r7 = framebuffer (pa) |
# r8 = real_mode (pa) |
# r6 = bytes to copy |
# r7 = real_mode (pa) |
mtspr srr0, r8 |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
# set real_mode meeting point address |
mtspr srr0, r7 |
# jumps to real_mode |
mfmsr r31 |
124,7 → 131,7 |
isync |
rfid |
.section REALMODE |
.section REALMODE, "ax" |
.align PAGE_WIDTH |
.global real_mode |
133,8 → 140,7 |
# copy kernel to proper location |
# |
# r5 = trans (pa) |
# r6 = kernel size |
# r7 = framebuffer (pa) |
# r6 = bytes to copy |
li r31, PAGE_SIZE >> 2 |
li r30, 0 |
168,74 → 174,23 |
copy_end: |
# invalidate segment registers |
# initially fill segment registers |
li r31, 16 |
mtctr r31 |
li r31, 0 |
li r30, 0 |
li r30, 0x2000 |
seg_fill: |
mtsrin r30, r31 |
addi r30, r30, 0x111 |
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 |
mr r30, r7 |
ori r30, r30, 0x0002 |
mtspr dbat1u, r31 |
mtspr dbat1l, r30 |
tlbia |
tlbsync |
# start the kernel |
# |
/boot/trunk/arch/ppc64/loader/ofw.h |
---|
47,16 → 47,16 |
typedef struct { |
unsigned long total; |
unsigned long count; |
unsigned int count; |
memzone_t zones[MEMMAP_MAX_RECORDS]; |
} memmap_t; |
typedef struct { |
void *addr; |
unsigned long width; |
unsigned long height; |
unsigned long bpp; |
unsigned long scanline; |
unsigned int width; |
unsigned int height; |
unsigned int bpp; |
unsigned int scanline; |
} screen_t; |
64,8 → 64,8 |
extern void ofw_write(const char *str, const long len); |
extern void *ofw_translate(const void *virt); |
extern long ofw_map(const void *phys, const void *virt, const long size, const long mode); |
extern long ofw_memmap(memmap_t *map); |
extern long ofw_screen(screen_t *screen); |
extern int ofw_map(const void *phys, const void *virt, const long size, const int mode); |
extern int ofw_memmap(memmap_t *map); |
extern int ofw_screen(screen_t *screen); |
#endif |
/boot/trunk/arch/ppc64/loader/boot.S |
---|
28,7 → 28,7 |
#include "regname.h" |
.section BOOTSTRAP |
.section BOOTSTRAP, "ax" |
.global start |
/boot/trunk/arch/ppc64/loader/regname.h |
---|
26,8 → 26,8 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __ppc64_REGNAME_H__ |
#define __ppc64_REGNAME_H__ |
#ifndef __ppc32_REGNAME_H__ |
#define __ppc32_REGNAME_H__ |
/* Condition Register Bit Fields */ |
#define cr0 0 |
189,22 → 189,6 |
#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/ppc64/loader/main.c |
---|
29,11 → 29,8 |
#include "main.h" |
#include "printf.h" |
#include "asm.h" |
#include "_components.h" |
#define KERNEL_START ((void *) &_binary_____________kernel_kernel_bin_start) |
#define KERNEL_END ((void *) &_binary_____________kernel_kernel_bin_end) |
#define KERNEL_SIZE ((unsigned long) KERNEL_END - (unsigned long) KERNEL_START) |
#define HEAP_GAP 1024000 |
bootinfo_t bootinfo; |
76,24 → 73,30 |
void bootstrap(void) |
{ |
printf("\nHelenOS PPC64 Bootloader\n"); |
printf("\nHelenOS PPC Bootloader\n"); |
check_align(KERNEL_START, "Kernel image"); |
check_align(&real_mode, "Bootstrap trampoline"); |
check_align(&trans, "Translation table"); |
init_components(); |
unsigned int i; |
for (i = 0; i < COMPONENTS; i++) |
check_align(components[i].start, components[i].name); |
check_align(&real_mode, "bootstrap trampoline"); |
check_align(&trans, "translation table"); |
if (!ofw_memmap(&bootinfo.memmap)) { |
printf("Error: Unable to get memory map, halting.\n"); |
printf("Error: unable to get memory map, halting.\n"); |
halt(); |
} |
if (bootinfo.memmap.total == 0) { |
printf("Error: No memory detected, halting.\n"); |
printf("Error: no memory detected, halting.\n"); |
halt(); |
} |
if (!ofw_screen(&bootinfo.screen)) { |
printf("Error: Unable to get screen properties, halting.\n"); |
printf("Error: unable to get screen properties, halting.\n"); |
halt(); |
} |
103,26 → 106,49 |
void *real_mode_pa = ofw_translate(&real_mode); |
void *trans_pa = ofw_translate(&trans); |
void *bootinfo_pa = ofw_translate(&bootinfo); |
void *fb = (void *) (((unsigned long) bootinfo.screen.addr) & ((unsigned long) ~0 << 17)); |
printf("\nMemory statistics (total %d MB)\n", bootinfo.memmap.total >> 20); |
printf(" kernel image at %L (size %d bytes)\n", KERNEL_START, KERNEL_SIZE); |
printf(" boot info at %L (physical %L)\n", &bootinfo, bootinfo_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); |
printf(" %L: boot info structure (physical %L)\n", &bootinfo, bootinfo_pa); |
printf(" %L: bootstrap trampoline (physical %L)\n", &real_mode, real_mode_pa); |
printf(" %L: translation table (physical %L)\n", &trans, trans_pa); |
for (i = 0; i < COMPONENTS; i++) |
printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size); |
unsigned long top = ALIGN_UP(KERNEL_SIZE, PAGE_SIZE); |
unsigned long addr; |
for (addr = 0; addr < KERNEL_SIZE; addr += PAGE_SIZE) { |
void *pa = ofw_translate(KERNEL_START + addr); |
fix_overlap(KERNEL_START + addr, &pa, "Kernel image", &top); |
trans[addr >> PAGE_WIDTH] = pa; |
unsigned long top = 0; |
for (i = 0; i < COMPONENTS; i++) |
top += ALIGN_UP(components[i].size, PAGE_SIZE); |
unsigned long pages = ALIGN_UP(KERNEL_SIZE, PAGE_SIZE) >> PAGE_WIDTH; |
for (i = 0; i < pages; i++) { |
void *pa = ofw_translate(KERNEL_START + (i << PAGE_WIDTH)); |
fix_overlap(KERNEL_START + (i << PAGE_WIDTH), &pa, "kernel", &top); |
trans[i] = pa; |
} |
fix_overlap(&real_mode, &real_mode_pa, "Bootstrap trampoline", &top); |
fix_overlap(&trans, &trans_pa, "Translation table", &top); |
fix_overlap(&bootinfo, &bootinfo_pa, "Boot info", &top); |
bootinfo.taskmap.count = 0; |
for (i = 1; i < COMPONENTS; i++) { |
unsigned long component_pages = ALIGN_UP(components[i].size, PAGE_SIZE) >> PAGE_WIDTH; |
unsigned long j; |
for (j = 0; j < component_pages; j++) { |
void *pa = ofw_translate(components[i].start + (j << PAGE_WIDTH)); |
fix_overlap(components[i].start + (j << PAGE_WIDTH), &pa, components[i].name, &top); |
trans[pages + j] = pa; |
if (j == 0) { |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) (pages << PAGE_WIDTH); |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size; |
bootinfo.taskmap.count++; |
} |
} |
pages += component_pages; |
} |
fix_overlap(&real_mode, &real_mode_pa, "bootstrap trampoline", &top); |
fix_overlap(&trans, &trans_pa, "translation table", &top); |
fix_overlap(&bootinfo, &bootinfo_pa, "boot info", &top); |
printf("\nBooting the kernel...\n"); |
jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, KERNEL_SIZE, fb, real_mode_pa); |
jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa); |
} |
/boot/trunk/arch/ppc64/loader/asm.h |
---|
33,7 → 33,7 |
#define PAGE_WIDTH 12 |
#define TRANS_SIZE 1024 |
#define TRANS_ITEM_SIZE 4 |
#define TRANS_ITEM_SIZE 8 |
#define KERNEL_START_ADDR 0x80004000 |
44,7 → 44,7 |
extern void *trans[TRANS_SIZE]; |
extern void halt(); |
extern void jump_to_kernel(void *bootinfo, unsigned long bootinfo_size, void *trans, unsigned long kernel_size, void *framebuffer, void *real_mode) __attribute__((noreturn)); |
extern void jump_to_kernel(void *bootinfo, unsigned long bootinfo_size, void *trans, unsigned long kernel_size, void *real_mode) __attribute__((noreturn)); |
extern void real_mode(); |
#endif |
/boot/trunk/arch/ppc64/loader/main.h |
---|
38,13 → 38,24 |
*/ |
#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1)) |
#define TASKMAP_MAX_RECORDS 32 |
typedef struct { |
void *addr; |
unsigned long size; |
} task_t; |
typedef struct { |
unsigned int count; |
task_t tasks[TASKMAP_MAX_RECORDS]; |
} taskmap_t; |
typedef struct { |
taskmap_t taskmap; |
memmap_t memmap; |
screen_t screen; |
} bootinfo_t; |
extern long _binary_____________kernel_kernel_bin_start; |
extern long _binary_____________kernel_kernel_bin_end; |
extern void start(void); |
extern void bootstrap(void); |
/boot/trunk/arch/ppc64/loader/ofw.c |
---|
33,9 → 33,9 |
#define MAX_OFW_ARGS 10 |
#define BUF_SIZE 1024 |
typedef unsigned long ofw_arg_t; |
typedef unsigned long ihandle; |
typedef unsigned long phandle; |
typedef unsigned int ofw_arg_t; |
typedef unsigned int ihandle; |
typedef unsigned int phandle; |
/** OpenFirmware command structure |
* |
42,8 → 42,8 |
*/ |
typedef struct { |
const char *service; /**< Command name */ |
unsigned long nargs; /**< Number of in arguments */ |
unsigned long nret; /**< Number of out arguments */ |
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; |
60,11 → 60,11 |
phandle ofw_aliases; |
static long ofw_call(const char *service, const long nargs, const long nret, ofw_arg_t *rets, ...) |
static int ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...) |
{ |
va_list list; |
ofw_args_t args; |
long i; |
int i; |
args.service = service; |
args.nargs = nargs; |
93,15 → 93,15 |
} |
static long ofw_get_property(const phandle device, const char *name, const void *buf, const long buflen) |
static int ofw_get_property(const phandle device, const char *name, const void *buf, const int buflen) |
{ |
return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen); |
} |
static unsigned long ofw_get_address_cells(const phandle device) |
static unsigned int ofw_get_address_cells(const phandle device) |
{ |
unsigned long ret; |
unsigned int ret; |
if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0) |
111,9 → 111,9 |
} |
static unsigned long ofw_get_size_cells(const phandle device) |
static unsigned int ofw_get_size_cells(const phandle device) |
{ |
unsigned long ret; |
unsigned int ret; |
if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0) |
184,28 → 184,28 |
} |
long ofw_map(const void *phys, const void *virt, const long size, const long mode) |
int ofw_map(const void *phys, const void *virt, const int size, const int mode) |
{ |
return ofw_call("call-method", 6, 1, NULL, "map", ofw_mmu, mode, size, virt, phys); |
} |
long ofw_memmap(memmap_t *map) |
int ofw_memmap(memmap_t *map) |
{ |
unsigned long buf[BUF_SIZE]; |
long ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(unsigned long) * BUF_SIZE); |
unsigned int buf[BUF_SIZE]; |
int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(unsigned int) * BUF_SIZE); |
if (ret <= 0) |
return false; |
unsigned long ac = ofw_get_address_cells(ofw_memory); |
unsigned long sc = ofw_get_size_cells(ofw_memory); |
unsigned int ac = ofw_get_address_cells(ofw_memory); |
unsigned int sc = ofw_get_size_cells(ofw_memory); |
long pos; |
int pos; |
map->total = 0; |
map->count = 0; |
for (pos = 0; (pos < ret / sizeof(unsigned long)) && (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) { |
for (pos = 0; (pos < ret / sizeof(unsigned int)) && (map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) { |
void * start = (void *) buf[pos + ac - 1]; |
unsigned long size = buf[pos + ac + sc - 1]; |
unsigned int size = buf[pos + ac + sc - 1]; |
if (size > 0) { |
map->zones[map->count].start = start; |
217,7 → 217,7 |
} |
long ofw_screen(screen_t *screen) |
int ofw_screen(screen_t *screen) |
{ |
char device_name[BUF_SIZE]; |
/boot/trunk/arch/ppc64/loader/Makefile |
---|
30,7 → 30,7 |
# |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
ifeq ($(COMPILER),native) |
CC = gcc |
46,7 → 46,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc64 -m64 |
CFLAGS = -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc64 -msoft-float -m64 |
DEFS = |
SOURCES = \ |
56,7 → 56,14 |
asm.S \ |
boot.S |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/ns/ns \ |
$(USPACEDIR)/init/init \ |
$(USPACEDIR)/fb/fb |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
.PHONY: all clean depend |
64,17 → 71,17 |
-include Makefile.depend |
image.boot: depend $(OBJECTS) kernel.o |
$(LD) -no-check-sections -N -T _link.ld $(OBJECTS) kernel.o -o $@ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) kernel.o |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-rm -f $(OBJECTS) image.boot kernel.o Makefile.depend |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend |
kernel.o: $(KERNEL) |
$(OBJCOPY) -I binary -O elf64-powerpc -B powerpc --rename-section .data=.image $(KERNEL) $@ |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(OBJCOPY) $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/boot/trunk/arch/ppc64/loader/pack |
---|
0,0 → 1,118 |
#! /bin/sh |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
[ "$#" -lt 1 ] && exit 1 |
OBJCOPY="$1" |
LINK="_link.ld" |
HEADER="_components.h" |
shift |
echo 'OUTPUT_FORMAT("elf64-powerpc") |
OUTPUT_ARCH(powerpc:common64) |
ENTRY(start) |
SECTIONS { |
.boot 0x0000000010000000: AT (0) { |
*(BOOTSTRAP); |
*(REALMODE); |
*(.text); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
. = ALIGN(4096); |
*(.kernel_image);' > "$LINK" |
echo '#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
typedef struct { |
char *name; |
void *start; |
void *end; |
unsigned long size; |
} component_t;' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
. = ALIGN(4096); |
*(.${BASENAME}_image);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned long) ${MACRO}_END - (unsigned long) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf32-powerpc -B powerpc:common --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo ' } |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
component_t components[COMPONENTS]; |
static void init_components(void) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |