From cdee16a0c2dc2a4aafba5851701a13b733fc9e47 Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Sat, 3 May 2003 16:28:01 +0000 Subject: [PATCH] work in progress on ppc port git-svn-id: svn+ssh://newos.org/var/svn/newos/newos@922 c25cc9d1-44fa-0310-b259-ad778cb1d433 --- boot/ppc/makefile | 3 +- boot/ppc/stage1.S | 13 ++- boot/ppc/stage2.c | 13 ++- boot/ppc/stage2.ld | 2 +- boot/ppc/stage2_asm.S | 255 +++++++++++++++++++++-------------------- boot/ppc/stage2_faults.c | 117 ++++++++++++++++++- boot/ppc/stage2_mmu.c | 167 ++++++++++++++++----------- boot/ppc/stage2_priv.h | 5 +- include/boot/arch/ppc/stage2.h | 3 +- make.syscfg | 2 +- 10 files changed, 369 insertions(+), 211 deletions(-) diff --git a/boot/ppc/makefile b/boot/ppc/makefile index b5d82d9..0517500 100644 --- a/boot/ppc/makefile +++ b/boot/ppc/makefile @@ -9,6 +9,7 @@ MY_TARGETDIR := $(BOOT_TARGETDIR) MY_SRCDIR := $(BOOT_SRCDIR) MY_TARGET := $(STAGE2) MY_OBJS := \ + stage2.o \ stage2_asm.o \ stage2_mmu.o \ stage2_of.o \ @@ -31,7 +32,7 @@ CONFIG_FILE := $(BOOT_SRCDIR)/config.ini SEMIFINAL := $(BOOT_TARGETDIR)/final.bootdir $(SEMIFINAL): $(STAGE2) $(ALL) $(TOOLS) $(MAKEFLOP) $(CONFIG_FILE) - $(BOOTMAKER) --bigendian --strip-debug --strip-binary $(STRIP) $(CONFIG_FILE) -o $(SEMIFINAL) + $(BOOTMAKER) --bigendian $(CONFIG_FILE) -o $(SEMIFINAL) FINAL_ASMINCLUDE := $(BOOT_TARGETDIR)/final.asminclude diff --git a/boot/ppc/stage1.S b/boot/ppc/stage1.S index d6de105..a66ca1c 100644 --- a/boot/ppc/stage1.S +++ b/boot/ppc/stage1.S @@ -5,8 +5,9 @@ #define BASE 0x100000 #define BOOTDIR_BASE (BASE + 0x1000) -#define STAGE2_BOOTDIR_PAGE (BOOTDIR_BASE + 0x60) -#define STAGE2_OFFSET (BOOTDIR_BASE + 0x74) +#define STAGE2_BOOTDIR_ENTRY (BOOTDIR_BASE + 0x80) +#define STAGE2_BOOTDIR_PAGE (STAGE2_BOOTDIR_ENTRY + 0x60) +#define STAGE2_OFFSET (STAGE2_BOOTDIR_ENTRY + 0x74) .text .globl _start @@ -16,14 +17,14 @@ _start: /* load the base of the bootdir */ lis 8,BOOTDIR_BASE@ha - ori 8,8,BOOTDIR_BASE@l + ori 8,8,BOOTDIR_BASE@l /* load the offset the stage2 will start into the bootdir */ lis 9,STAGE2_BOOTDIR_PAGE@ha ori 9,9,STAGE2_BOOTDIR_PAGE@l lwz 9,0(9) mulli 9,9,4096 - + /* load the offset into that page the stage2 entry point will be */ lis 10,STAGE2_OFFSET@ha ori 10,10,STAGE2_OFFSET@l @@ -39,9 +40,9 @@ _start: .align 4 tempstack: - .skip 0x800 + .skip 0x800 tempstack_end: - + .data #include "build/ppc/boot/final.asminclude" diff --git a/boot/ppc/stage2.c b/boot/ppc/stage2.c index b208c2d..95ceddc 100644 --- a/boot/ppc/stage2.c +++ b/boot/ppc/stage2.c @@ -3,9 +3,9 @@ ** Distributed under the terms of the NewOS License. */ #include -#include -#include -#include +#include +#include + #include "stage2_priv.h" void _start(int arg1, int arg2, void *openfirmware); @@ -23,12 +23,17 @@ void _start(int arg1, int arg2, void *openfirmware) printf("Welcome to the stage2 bootloader!\n"); - printf("arg1 0x%x, arg2 0x%x, openfirmware 0x%x\n", arg1, arg2, openfirmware); + printf("arg1 0x%x, arg2 0x%x, openfirmware %p\n", arg1, arg2, openfirmware); printf("msr = 0x%x\n", getmsr()); + // bring up the mmu s2_mmu_init(&ka); + // initialize fault handlers + s2_faults_init(&ka); + + printf("_start: spinning forever...\n"); for(;;); } diff --git a/boot/ppc/stage2.ld b/boot/ppc/stage2.ld index dcdbe62..be800a3 100644 --- a/boot/ppc/stage2.ld +++ b/boot/ppc/stage2.ld @@ -4,7 +4,7 @@ OUTPUT_ARCH(powerpc) ENTRY(_start) SECTIONS { - . = 0x102000 + SIZEOF_HEADERS; + . = 0x100000 + 0x1000 + 0x4000 + SIZEOF_HEADERS; /* text/read-only data */ .text : { *(.text .gnu.linkonce.t.*) } diff --git a/boot/ppc/stage2_asm.S b/boot/ppc/stage2_asm.S index 89cf2da..ce4c00c 100644 --- a/boot/ppc/stage2_asm.S +++ b/boot/ppc/stage2_asm.S @@ -1,242 +1,245 @@ /* -** Copyright 2001, Travis Geiselbrecht. All rights reserved. +** Copyright 2001-2003, Travis Geiselbrecht. All rights reserved. ** Distributed under the terms of the NewOS License. */ .text -// void getibats(int bats[8]); + +/* void getibats(int bats[8]); */ .globl getibats getibats: - mfibatu 0,0 - stw 0,0(3) - mfibatl 0,0 - stwu 0,4(3) - mfibatu 0,1 - stwu 0,4(3) - mfibatl 0,1 - stwu 0,4(3) - mfibatu 0,2 - stwu 0,4(3) - mfibatl 0,2 - stwu 0,4(3) - mfibatu 0,3 - stwu 0,4(3) - mfibatl 0,3 - stwu 0,4(3) + mfibatu r0,0 + stw r0,0(r3) + mfibatl r0,0 + stwu r0,4(r3) + mfibatu r0,1 + stwu r0,8(r3) + mfibatl r0,1 + stwu r0,12(r3) + mfibatu r0,2 + stwu r0,16(r3) + mfibatl r0,2 + stwu r0,20(r3) + mfibatu r0,3 + stwu r0,24(r3) + mfibatl r0,3 + stwu r0,28(r3) blr // void setibats(int bats[8]); .globl setibats setibats: - mfmsr 8 - li 0,0 - mtmsr 0 + mfmsr r8 + li r0,0 + mtmsr r0 - lwz 0,0(3) - mtibatu 0,0 + lwz r0,0(r3) + mtibatu 0,r0 isync - lwzu 0,4(3) - mtibatl 0,0 + lwzu r0,4(r3) + mtibatl 0,r0 isync - lwzu 0,4(3) - mtibatu 1,0 + lwzu r0,8(r3) + mtibatu 1,r0 isync - lwzu 0,4(3) - mtibatl 1,0 + lwzu r0,12(r3) + mtibatl 1,r0 isync - lwzu 0,4(3) - mtibatu 2,0 + lwzu r0,16(r3) + mtibatu 2,r0 isync - lwzu 0,4(3) - mtibatl 2,0 + lwzu r0,20(r3) + mtibatl 2,r0 isync - lwzu 0,4(3) - mtibatu 3,0 + lwzu r0,24(r3) + mtibatu 3,r0 isync - lwzu 0,4(3) - mtibatl 3,0 + lwzu r0,28(r3) + mtibatl 3,r0 isync - mtmsr 8 + mtmsr r8 isync blr // void getdbats(int bats[8]); .globl getdbats getdbats: - mfdbatu 0,0 - stw 0,0(3) - mfdbatl 0,0 - stwu 0,4(3) - mfdbatu 0,1 - stwu 0,4(3) - mfdbatl 0,1 - stwu 0,4(3) - mfdbatu 0,2 - stwu 0,4(3) - mfdbatl 0,2 - stwu 0,4(3) - mfdbatu 0,3 - stwu 0,4(3) - mfdbatl 0,3 - stwu 0,4(3) + mfdbatu r0,0 + stw r0,0(r3) + mfdbatl r0,0 + stwu r0,4(r3) + mfdbatu r0,1 + stwu r0,4(r3) + mfdbatl r0,1 + stwu r0,4(r3) + mfdbatu r0,2 + stwu r0,4(r3) + mfdbatl r0,2 + stwu r0,4(r3) + mfdbatu r0,3 + stwu r0,4(r3) + mfdbatl r0,3 + stwu r0,4(r3) blr // void setdbats(int bats[8]); .globl setdbats setdbats: - mfmsr 8 - li 0,0 - mtmsr 0 - - lwz 0,0(3) - mtdbatu 0,0 - lwzu 0,4(3) - mtdbatl 0,0 - lwzu 0,4(3) - mtdbatu 1,0 - lwzu 0,4(3) - mtdbatl 1,0 - lwzu 0,4(3) - mtdbatu 2,0 - lwzu 0,4(3) - mtdbatl 2,0 - lwzu 0,4(3) - mtdbatu 3,0 - lwzu 0,4(3) - mtdbatl 3,0 - - mtmsr 8 + mfmsr r8 + li r0,0 + mtmsr r0 + + lwz r0,0(r3) + mtdbatu 0,r0 + lwzu r0,4(r3) + mtdbatl 0,r0 + lwzu r0,4(r3) + mtdbatu 1,r0 + lwzu r0,4(r3) + mtdbatl 1,r0 + lwzu r0,4(r3) + mtdbatu 2,r0 + lwzu r0,4(r3) + mtdbatl 2,r0 + lwzu r0,4(r3) + mtdbatu 3,r0 + lwzu r0,4(r3) + mtdbatl 3,r0 + + mtmsr r8 sync blr // unsigned int getsdr1(); .globl getsdr1 getsdr1: - mfsdr1 3 + mfsdr1 r3 blr // void setsdr1(unsigned int sdr); .globl setsdr1 setsdr1: sync - mtsdr1 3 + mtsdr1 r3 sync blr -// unsigned int getsr(int sr); +// unsigned int getsr(unsigned int va); .globl getsr getsr: - mfsrin 3,3 + mfsrin r3,r3 + sync + blr + +// void setsr(unsigned int va, unsigned int val); +.globl setsr +setsr: + mtsrin r4,r3 + sync blr + + // unsigned int getmsr(); .globl getmsr getmsr: - mfmsr 3 + mfmsr r3 blr // void setmsr(unsigned int msr); .globl setmsr setmsr: - mtmsr 3 + mtmsr r3 blr .globl system_reset_exception_entry system_reset_exception_entry: - lis 3,system_reset_exception@ha - ori 3,3,system_reset_exception@l - mtlr 3 - blr + bla system_reset_exception + rfi .globl system_reset_exception_entry_end system_reset_exception_entry_end: .globl machine_check_exception_entry machine_check_exception_entry: - lis 3,machine_check_exception@ha - ori 3,3,machine_check_exception@l - mtlr 3 - blr + bla machine_check_exception + rfi .globl machine_check_exception_entry_end machine_check_exception_entry_end: .globl dsi_exception_entry dsi_exception_entry: - lis 3,dsi_exception@ha - ori 3,3,dsi_exception@l - mtlr 3 - blr + bla dsi_exception + rfi .globl dsi_exception_entry_end dsi_exception_entry_end: .globl isi_exception_entry isi_exception_entry: - lis 3,isi_exception@ha - ori 3,3,isi_exception@l - mtlr 3 - blr + bla isi_exception + rfi .globl isi_exception_entry_end isi_exception_entry_end: .globl external_interrupt_entry external_interrupt_entry: - lis 3,external_interrupt@ha - ori 3,3,external_interrupt@l - mtlr 3 - blr + bla external_interrupt + rfi .globl external_interrupt_entry_end external_interrupt_entry_end: .globl alignment_exception_entry alignment_exception_entry: - lis 3,alignment_exception@ha - ori 3,3,alignment_exception@l - mtlr 3 - blr + bla alignment_exception + rfi .globl alignment_exception_entry_end alignment_exception_entry_end: .globl program_exception_entry program_exception_entry: - lis 3,program_exception@ha - ori 3,3,program_exception@l - mtlr 3 - blr + bla program_exception + rfi .globl program_exception_entry_end program_exception_entry_end: .globl decrementer_exception_entry decrementer_exception_entry: - lis 3,decrementer_exception@ha - ori 3,3,decrementer_exception@l - mtlr 3 - blr + bla decrementer_exception + rfi .globl decrementer_exception_entry_end decrementer_exception_entry_end: .globl system_call_exception_entry system_call_exception_entry: - lis 3,system_call_exception@ha - ori 3,3,system_call_exception@l - mtlr 3 - blr + mfmsr r0 + ori r0,r0,0x3030 + sync + mtmsr r0 + isync + + bla system_call_exception + rfi .globl system_call_exception_entry_end system_call_exception_entry_end: .globl trace_exception_entry trace_exception_entry: - lis 3,trace_exception@ha - ori 3,3,trace_exception@l - mtlr 3 - blr + bla trace_exception + rfi .globl trace_exception_entry_end trace_exception_entry_end: .globl floating_point_assist_exception_entry floating_point_assist_exception_entry: - lis 3,floating_point_assist_exception@ha - ori 3,3,floating_point_assist_exception@l - mtlr 3 - blr + bla floating_point_assist_exception + rfi .globl floating_point_assist_exception_entry_end floating_point_assist_exception_entry_end: + +.globl g3_exception_entry +g3_exception_entry: + bla g3_exception_entry_exception + rfi +.globl g3_exception_entry_end +g3_exception_entry_end: + diff --git a/boot/ppc/stage2_faults.c b/boot/ppc/stage2_faults.c index d77ac17..2749041 100644 --- a/boot/ppc/stage2_faults.c +++ b/boot/ppc/stage2_faults.c @@ -3,6 +3,7 @@ ** Distributed under the terms of the NewOS License. */ #include +#include #include "stage2_priv.h" void system_reset_exception_entry(); @@ -27,11 +28,20 @@ void trace_exception_entry(); extern int trace_exception_entry_end; void floating_point_assist_exception_entry(); extern int floating_point_assist_exception_entry_end; +void g3_exception_entry(); +extern int g3_exception_entry_end; void s2_faults_init(kernel_args *ka) { printf("s2_faults_init: entry\n"); + printf("msr = 0x%x\n", getmsr()); setmsr(getmsr() & ~0x00000040); // make it look for exceptions in the zero page + printf("msr = 0x%x\n", getmsr()); +/* + printf("msr = 0x%x\n", getmsr()); + setmsr(getmsr() & ~0x00000030); // no more mmu + printf("msr = 0x%x\n", getmsr()); +*/ printf("s2_faults_init: foo\n"); printf("0x%x\n", *(unsigned int *)0x00000100); printf("0x%x\n", *(unsigned int *)0x00000104); @@ -67,25 +77,64 @@ void s2_faults_init(kernel_args *ka) (int)&trace_exception_entry_end - (int)&trace_exception_entry); memcpy((void *)0x00000e00, &floating_point_assist_exception_entry, (int)&floating_point_assist_exception_entry_end - (int)&floating_point_assist_exception_entry); + + memcpy((void *)0x00000f00, &g3_exception_entry, + (int)&g3_exception_entry_end - (int)&g3_exception_entry); + memcpy((void *)0x00001300, &g3_exception_entry, + (int)&g3_exception_entry_end - (int)&g3_exception_entry); + memcpy((void *)0x00001400, &g3_exception_entry, + (int)&g3_exception_entry_end - (int)&g3_exception_entry); + memcpy((void *)0x00001700, &g3_exception_entry, + (int)&g3_exception_entry_end - (int)&g3_exception_entry); + printf("s2_faults_init: exit\n"); - syncicache(0, 0x1000); + syncicache(0, 0x10000); + +#if 1 + // test it +// printf("test = %d\n", *(int *)0x3); + + // syscall + asm("sc"); + + // turn single-step mode +// setmsr(getmsr() | 0x00000400); +#endif } void system_reset_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("system_reset_exception\n"); for(;;); } void machine_check_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("machine_check_exception\n"); for(;;); } void dsi_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } *(int *)0x16008190 = 0xffffff; printf("dsi_exception\n"); for(;;); @@ -93,49 +142,111 @@ void dsi_exception() void isi_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("isi_exception\n"); for(;;); } void external_interrupt() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("external_interrupt\n"); for(;;); } void alignment_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("alignment_exception\n"); for(;;); } void program_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("program_exception\n"); for(;;); } void decrementer_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("decrementer_exception\n"); for(;;); } void system_call_exception() { - printf("system_call_exception\n"); - for(;;); +/* + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } +// printf("system_call_exception\n"); +// for(;;); +*/ } void trace_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("trace_exception\n"); for(;;); } void floating_point_assist_exception() { + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } printf("floating_point_assist_exception\n"); for(;;); } +void g3_exception_entry_exception() +{ + { + int i; + for(i = 0; i < 128*1024; i++) { + ((char *)0x96008000)[i] = i; + } + } + printf("g3_exception_entry_exception\n"); + for(;;); +} + diff --git a/boot/ppc/stage2_mmu.c b/boot/ppc/stage2_mmu.c index 806bd92..7ed048d 100644 --- a/boot/ppc/stage2_mmu.c +++ b/boot/ppc/stage2_mmu.c @@ -28,12 +28,12 @@ static unsigned int secondary_hash(unsigned int primary_hash); #define BATL_PP_RW 0x2 struct pte { - // pte lower word - unsigned int v : 1; + // pte upper word + unsigned int v : 1; unsigned int vsid : 24; unsigned int hash : 1; unsigned int api : 6; - // pte upper word + // pte lower word unsigned int ppn : 20; unsigned int unused : 3; unsigned int r : 1; @@ -52,6 +52,9 @@ static unsigned int ptable_hash_mask = 0; static unsigned long total_ram_size = 0; +static void print_pte(struct pte *e); + + static void find_phys_memory_map(kernel_args *ka) { int handle; @@ -104,7 +107,7 @@ static void find_used_phys_memory_map(kernel_args *ka) unsigned long pa; int mode; } memmap[64]; - int translation_map_len = 0; + int translation_map_len = 0; // get the current translation map of the system, // to find how much memory was mapped to load the stage1 and bootdir @@ -115,9 +118,9 @@ static void find_used_phys_memory_map(kernel_args *ka) translation_map_len = of_getprop(handle, "translations", memmap, sizeof(memmap)); translation_map_len /= sizeof(struct translation_map); for(i=0; iphys_alloc_range[0].start = memmap[i].pa; ka->phys_alloc_range[0].size = memmap[i].len; ka->num_phys_alloc_ranges = 1; @@ -128,10 +131,12 @@ static void find_used_phys_memory_map(kernel_args *ka) static void tlbia() { unsigned long i; - + asm volatile("sync"); for(i=0; i< 0x40000; i += 0x1000) { asm volatile("tlbie %0" :: "r" (i)); + asm volatile("eieio"); + asm volatile("sync"); } asm volatile("tlbsync"); asm volatile("sync"); @@ -176,36 +181,31 @@ int s2_mmu_init(kernel_args *ka) ibats[0] = 0; dbats[0] = 0; } - // identity map the first 256Mb of RAM + // identity map the first 512Mb of RAM ibats[0] = BATU_LEN_256M | BATU_VS; dbats[0] = BATU_LEN_256M | BATU_VS; ibats[1] = BATL_MC | BATL_PP_RW; dbats[1] = BATL_MC | BATL_PP_RW; - - // XXX remove ibats[2] = 0x10000000 | BATU_LEN_256M | BATU_VS; dbats[2] = 0x10000000 | BATU_LEN_256M | BATU_VS; - ibats[3] = 0x90000000 | BATL_CI | BATL_PP_RW; - dbats[3] = 0x90000000 | BATL_CI | BATL_PP_RW; + ibats[3] = 0x10000000 | BATL_MC | BATL_PP_RW; + dbats[3] = 0x10000000 | BATL_MC | BATL_PP_RW; + + /* map 0x90000000 down to a usable spot in memory */ + ibats[4] = 0x20000000 | BATU_LEN_256M | BATU_VS; + dbats[4] = 0x20000000 | BATU_LEN_256M | BATU_VS; + ibats[5] = 0x90000000 | BATL_CI | BATL_PP_RW; + dbats[5] = 0x90000000 | BATL_CI | BATL_PP_RW; setibats(ibats); setdbats(dbats); tlbia(); - s2_faults_init(ka); - // XXX remove - s2_change_framebuffer_addr(0x16008000); + s2_change_framebuffer_addr(0x26008000); printf("msr = 0x%x\n", getmsr()); -// setmsr(getmsr() | 0x400); - printf("foo\n"); - - *(int *)0x30000000 = 5; - printf("here\n"); - - for(;;); // figure out where physical memory is and what is being used find_phys_memory_map(ka); @@ -215,114 +215,147 @@ int s2_mmu_init(kernel_args *ka) { unsigned long top_ram = 0; - // find the largest address of physical memory, but with a max of 256 MB, - // so it'll be within our 256 MB BAT window + // find the largest address of physical memory, but with a max of 512 MB, + // so it'll be within our 512 MB BAT window for(i=0; inum_phys_mem_ranges; i++) { if(ka->phys_mem_range[i].start + ka->phys_mem_range[i].size > top_ram) { - if(ka->phys_mem_range[i].start + ka->phys_mem_range[i].size > 256*1024*1024) { - if(ka->phys_mem_range[i].start < 256*1024*1024) { - top_ram = 256*1024*1024; + if(ka->phys_mem_range[i].start + ka->phys_mem_range[i].size > 512*1024*1024) { + if(ka->phys_mem_range[i].start < 512*1024*1024) { + top_ram = 512*1024*1024; break; } } top_ram = ka->phys_mem_range[i].start + ka->phys_mem_range[i].size; } } - printf("top of ram (but under 256Mb) is 0x%x\n", top_ram); + printf("top of ram (but under 512MB) is 0x%x\n", top_ram); // figure the size of the new pagetable, as recommended by Motorola if(total_ram_size <= 8*1024*1024) { ptable_size = 64*1024; - ptable_hash_mask = 0x0; } else if(total_ram_size <= 16*1024*1024) { ptable_size = 128*1024; - ptable_hash_mask = 0x1; } else if(total_ram_size <= 32*1024*1024) { ptable_size = 256*1024; - ptable_hash_mask = 0x3; } else if(total_ram_size <= 64*1024*1024) { ptable_size = 512*1024; - ptable_hash_mask = 0x7; } else if(total_ram_size <= 128*1024*1024) { ptable_size = 1024*1024; - ptable_hash_mask = 0xf; } else if(total_ram_size <= 256*1024*1024) { ptable_size = 2*1024*1024; - ptable_hash_mask = 0x1f; } else if(total_ram_size <= 512*1024*1024) { ptable_size = 4*1024*1024; - ptable_hash_mask = 0x3f; } else if(total_ram_size <= 1024*1024*1024) { ptable_size = 8*1024*1024; - ptable_hash_mask = 0x7f; } else if(total_ram_size <= 2*1024*1024*1024) { ptable_size = 16*1024*1024; - ptable_hash_mask = 0xff; } else { ptable_size = 32*1024*1024; - ptable_hash_mask = 0x1ff; } - ptable = (struct pteg *)(top_ram - ptable_size - 0x100000); + // figure out where to put the page table + ptable_hash_mask = (ptable_size >> 6) - 1; + ptable = (struct pteg *)(top_ram - ptable_size); printf("ptable at pa 0x%x, size 0x%x\n", ptable, ptable_size); printf("mask = 0x%x\n", ptable_hash_mask); - printf("sdr1 = 0x%x\n", getsdr1()); - printf("msr = 0x%x\n", getmsr()); - - for(i=0; i<16; i++) { - printf("sr[%i] = 0x%x\n", i, getsr(i)); + // save it's new location in the kernel args + ka->arch_args.page_table.start = (unsigned long)ptable; + ka->arch_args.page_table.size = ptable_size; + ka->arch_args.page_table_mask = ptable_hash_mask; + +#if 0 + { + struct pteg *old_ptable; + int j; + + printf("sdr1 = 0x%x\n", getsdr1()); + + old_ptable = (struct pteg *)((unsigned int)getsdr1() & 0xffff0000); + printf("old_ptable %p\n", old_ptable); + for(i=0; i< (64*1024) >> 6 ; i++) { + for(j=0; j< 8; j++) + if(old_ptable[i].pte[j].v && old_ptable[i].pte[j].vsid == 0) + print_pte(&old_ptable[i].pte[j]); + } } +#endif + printf("memsetting pagetable and performing switch\n"); memset(ptable, 0, ptable_size); - mmu_map_page(0, 0x96008000, 0x96008000); - mmu_map_page(0, 0x96009000, 0x96009000); - mmu_map_page(0, 0x9600a000, 0x9600a000); - mmu_map_page(0, 0x0, 0x30000000); - + // set up the segment registers + for(i=0; i<16; i++) { + setsr(i * 0x10000000, i); + } + printf("done, setting sdr1\n"); - setsdr1(((unsigned int)ptable & 0xffff0000) | ptable_hash_mask); + setsdr1(((unsigned int)ptable & 0xffff0000) | (ptable_hash_mask >> 10)); tlbia(); - printf("hello\n"); printf("sdr1 = 0x%x\n", getsdr1()); - printf("%d\n", *(int *)0x30000000); + +#if 0 + mmu_map_page(0x96008000, 0x96008000); + mmu_map_page(0x96009000, 0x96009000); + mmu_map_page(0x9600a000, 0x9600a000); + mmu_map_page(0x0, 0x30000000); + + printf("testing...\n"); + printf("hello\n"); + printf("%d\n", *(int *)0x30000000); printf("%d\n", *(int *)0x96008000); printf("hello2\n"); - - for(i=0; i<64; i++) { - *(char *)(0x96008000 + i) = i; - } - printf("foo\n"); - +#endif } return 0; } -void mmu_map_page(unsigned int vsid, unsigned long pa, unsigned long va) +static void print_pte(struct pte *e) +{ + printf("entry %p: ", e); + printf("v %d ", e->v); + if(e->v) { + printf("vsid 0x%x ", e->vsid); + printf("hash %d ", e->hash); + printf("api 0x%x ", e->api); + + printf("ppn 0x%x ", e->ppn); + printf("r %d ", e->r); + printf("c %d ", e->c); + printf("wimg 0x%x ", e->wimg); + printf("pp 0x%x ", e->pp); + } + printf("\n"); +} + +void mmu_map_page(unsigned long pa, unsigned long va) { unsigned int hash; struct pteg *pteg; int i; + unsigned int vsid; + + // lookup the vsid based off the va + vsid = getsr(va) & 0xffffff; + +// printf("mmu_map_page: vsid %d, pa 0x%x, va 0x%x\n", vsid, pa, va); - printf("mmu_map_page: vsid %d, pa 0x%x, va 0x%x\n", vsid, pa, va); + hash = primary_hash(vsid, va); +// printf("hash = 0x%x\n", hash); - hash = primary_hash(0, va); - printf("hash = 0x%x\n", hash); - pteg = &ptable[hash]; - printf("pteg @ 0x%x\n", pteg); +// printf("pteg @ 0x%x\n", pteg); // search for the first free slot for this pte for(i=0; i<8; i++) { - printf("trying pteg[%i]\n", i); +// printf("trying pteg[%i]\n", i); if(pteg->pte[i].v == 0) { // upper word pteg->pte[i].ppn = pa / PAGE_SIZE; pteg->pte[i].unused = 0; pteg->pte[i].r = 0; pteg->pte[i].c = 0; - pteg->pte[i].wimg = 0x4; + pteg->pte[i].wimg = 0x0; pteg->pte[i].unused1 = 0; pteg->pte[i].pp = 0x2; // RW asm volatile("eieio"); @@ -332,7 +365,9 @@ void mmu_map_page(unsigned int vsid, unsigned long pa, unsigned long va) pteg->pte[i].api = (va >> 22) & 0x3f; pteg->pte[i].v = 1; tlbia(); - printf("set pteg to 0x%x 0x%x\n", *((int *)&pteg->pte[i]), *(((int *)&pteg->pte[i])+1)); +// printf("set pteg to "); +// print_pte(&pteg->pte[i]); +// printf("set pteg to 0x%x 0x%x\n", *((int *)&pteg->pte[i]), *(((int *)&pteg->pte[i])+1)); return; } } diff --git a/boot/ppc/stage2_priv.h b/boot/ppc/stage2_priv.h index 605ad5a..7d8c0fd 100644 --- a/boot/ppc/stage2_priv.h +++ b/boot/ppc/stage2_priv.h @@ -25,7 +25,7 @@ int of_write(int handle, void *buf, int buf_len); int of_seek(int handle, long long pos); int s2_mmu_init(); -void mmu_map_page(unsigned int vsid, unsigned long pa, unsigned long va);; +void mmu_map_page(unsigned long pa, unsigned long va);; void syncicache(void *address, int len); void s2_faults_init(kernel_args *ka); @@ -36,7 +36,8 @@ void getdbats(int bats[8]); void setdbats(int bats[8]); unsigned int *getsdr1(); void setsdr1(unsigned int sdr); -unsigned int getsr(int sr); +unsigned int getsr(unsigned int va); +void setsr(unsigned int va, unsigned int val); unsigned int getmsr(); void setmsr(unsigned int msr); diff --git a/include/boot/arch/ppc/stage2.h b/include/boot/arch/ppc/stage2.h index c8827d6..9f8892a 100644 --- a/include/boot/arch/ppc/stage2.h +++ b/include/boot/arch/ppc/stage2.h @@ -1,4 +1,4 @@ -/* +/* ** Copyright 2001, Travis Geiselbrecht. All rights reserved. ** Distributed under the terms of the NewOS License. */ @@ -11,6 +11,7 @@ typedef struct { // architecture specific addr_range page_table; // maps where the page table is located, in physical memory + unsigned int page_table_mask; addr_range framebuffer; // maps where the framebuffer is located, in physical memory int screen_x, screen_y, screen_depth; } arch_kernel_args; diff --git a/make.syscfg b/make.syscfg index 4e9967e..75b03ea 100644 --- a/make.syscfg +++ b/make.syscfg @@ -175,7 +175,7 @@ ifeq ($(ARCH),ppc) OBJCOPY = ppc-elf-objcopy STRIP = ppc-elf-strip endif - GLOBAL_CFLAGS = -fno-pic -O -D__PPC__ + GLOBAL_CFLAGS = -fno-pic -O -D__PPC__ -mregnames GLOBAL_LDFLAGS = TOOLCHAIN_ARCH = ppc endif -- 2.11.4.GIT