diff options
Diffstat (limited to 'sys/powerpc/booke')
-rw-r--r-- | sys/powerpc/booke/booke_machdep.c (renamed from sys/powerpc/booke/machdep.c) | 369 | ||||
-rw-r--r-- | sys/powerpc/booke/pmap.c | 7 |
2 files changed, 20 insertions, 356 deletions
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/booke_machdep.c index 943063c..2a27775 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/booke_machdep.c @@ -163,6 +163,7 @@ extern unsigned char __bss_start[]; extern unsigned char __sbss_start[]; extern unsigned char __sbss_end[]; extern unsigned char _end[]; +extern vm_offset_t __endkernel; /* * Bootinfo is passed to us by legacy loaders. Save the address of the @@ -170,25 +171,6 @@ extern unsigned char _end[]; */ uint32_t *bootinfo; -struct kva_md_info kmi; -struct pcpu __pcpu[MAXCPU]; -struct trapframe frame0; -int cold = 1; -long realmem = 0; -long Maxmem = 0; -char machine[] = "powerpc"; -SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); - -int cacheline_size = 32; - -SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, - CTLFLAG_RD, &cacheline_size, 0, ""); - -int hw_direct_map = 0; - -static void cpu_booke_startup(void *); -SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_booke_startup, NULL); - void print_kernel_section_addr(void); void print_kenv(void); u_int booke_init(uint32_t, uint32_t); @@ -219,6 +201,16 @@ extern void *int_performance_counter; ("Handler " #handler " too far from interrupt vector base")); \ mtspr(ivor, (uintptr_t)(&handler) & 0xffffUL); +uintptr_t powerpc_init(vm_offset_t fdt, vm_offset_t, vm_offset_t, void *mdp); +void booke_cpu_init(void); + +void +booke_cpu_init(void) +{ + + pmap_mmu_install(MMU_TYPE_BOOKE, BUS_PROBE_GENERIC); +} + void ivor_setup(void) { @@ -244,90 +236,6 @@ ivor_setup(void) #endif } -static void -cpu_booke_startup(void *dummy) -{ - int indx; - unsigned long size; - - /* Initialise the decrementer-based clock. */ - decr_init(); - - /* Good {morning,afternoon,evening,night}. */ - cpu_setup(PCPU_GET(cpuid)); - - printf("real memory = %lu (%ld MB)\n", ptoa(physmem), - ptoa(physmem) / 1048576); - realmem = physmem; - - /* Display any holes after the first chunk of extended memory. */ - if (bootverbose) { - printf("Physical memory chunk(s):\n"); - for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { - size = phys_avail[indx + 1] - phys_avail[indx]; - - printf("0x%08x - 0x%08x, %lu bytes (%lu pages)\n", - phys_avail[indx], phys_avail[indx + 1] - 1, - size, size / PAGE_SIZE); - } - } - - vm_ksubmap_init(&kmi); - - printf("avail memory = %lu (%ld MB)\n", ptoa(vm_cnt.v_free_count), - ptoa(vm_cnt.v_free_count) / 1048576); - - /* Set up buffers, so they can be used to read disk labels. */ - bufinit(); - vm_pager_bufferinit(); -} - -static char * -kenv_next(char *cp) -{ - - if (cp != NULL) { - while (*cp != 0) - cp++; - cp++; - if (*cp == 0) - cp = NULL; - } - return (cp); -} - -void -print_kenv(void) -{ - int len; - char *cp; - - debugf("loader passed (static) kenv:\n"); - if (kern_envp == NULL) { - debugf(" no env, null ptr\n"); - return; - } - debugf(" kern_envp = 0x%08x\n", (u_int32_t)kern_envp); - - len = 0; - for (cp = kern_envp; cp != NULL; cp = kenv_next(cp)) - debugf(" %x %s\n", (u_int32_t)cp, cp); -} - -void -print_kernel_section_addr(void) -{ - - debugf("kernel image addresses:\n"); - debugf(" kernel_text = 0x%08x\n", (uint32_t)kernel_text); - debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext); - debugf(" _edata = 0x%08x\n", (uint32_t)_edata); - debugf(" __sbss_start = 0x%08x\n", (uint32_t)__sbss_start); - debugf(" __sbss_end = 0x%08x\n", (uint32_t)__sbss_end); - debugf(" __sbss_start = 0x%08x\n", (uint32_t)__bss_start); - debugf(" _end = 0x%08x\n", (uint32_t)_end); -} - static int booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp) { @@ -345,24 +253,20 @@ booke_check_for_fdt(uint32_t arg1, vm_offset_t *dtbp) return (0); } -u_int +uintptr_t booke_init(uint32_t arg1, uint32_t arg2) { - struct pcpu *pc; - void *kmdp, *mdp; + uintptr_t ret; + void *mdp; vm_offset_t dtbp, end; -#ifdef DDB - vm_offset_t ksym_start; - vm_offset_t ksym_end; -#endif - - kmdp = NULL; end = (uintptr_t)_end; dtbp = (vm_offset_t)NULL; /* Set up TLB initially */ bootinfo = NULL; + bzero(__sbss_start, __sbss_end - __sbss_start); + bzero(__bss_start, _end - __bss_start); tlb1_init(); /* @@ -391,152 +295,22 @@ booke_init(uint32_t arg1, uint32_t arg2) memmove((void *)end, (void *)dtbp, fdt_totalsize((void *)dtbp)); dtbp = end; end += fdt_totalsize((void *)dtbp); + __endkernel = end; mdp = NULL; } else if (arg1 > (uintptr_t)kernel_text) /* FreeBSD loader */ mdp = (void *)arg1; else /* U-Boot */ mdp = NULL; - /* - * Parse metadata and fetch parameters. - */ - if (mdp != NULL) { - preload_metadata = mdp; - kmdp = preload_search_by_type("elf kernel"); - if (kmdp != NULL) { - boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); - kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); - dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); - end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); - - bootinfo = (uint32_t *)preload_search_info(kmdp, - MODINFO_METADATA | MODINFOMD_BOOTINFO); - -#ifdef DDB - ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); - ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); - db_fetch_ksymtab(ksym_start, ksym_end); -#endif - } - } else { - bzero(__sbss_start, __sbss_end - __sbss_start); - bzero(__bss_start, _end - __bss_start); - } - -#if defined(FDT_DTB_STATIC) - /* - * In case the device tree blob was not retrieved (from metadata) try - * to use the statically embedded one. - */ - if (dtbp == (vm_offset_t)NULL) - dtbp = (vm_offset_t)&fdt_static_dtb; -#endif - - if (OF_install(OFW_FDT, 0) == FALSE) - while (1); - - if (OF_init((void *)dtbp) != 0) - while (1); - - OF_interpret("perform-fixup", 0); - /* Reset TLB1 to get rid of temporary mappings */ tlb1_init(); - /* Reset Time Base */ - mttb(0); - - /* Init params/tunables that can be overridden by the loader. */ - init_param1(); - - /* Start initializing proc0 and thread0. */ - proc_linkup0(&proc0, &thread0); - thread0.td_frame = &frame0; - - /* Set up per-cpu data and store the pointer in SPR general 0. */ - pc = &__pcpu[0]; - pcpu_init(pc, 0, sizeof(struct pcpu)); - pc->pc_curthread = &thread0; -#ifdef __powerpc64__ - __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread)); -#else - __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread)); -#endif - __asm __volatile("mtsprg 0, %0" :: "r"(pc)); - - /* Initialize system mutexes. */ - mutex_init(); - - /* Initialize the console before printing anything. */ - cninit(); - - /* Print out some debug info... */ - debugf("%s: console initialized\n", __func__); - debugf(" arg3 mdp = 0x%08x\n", (u_int32_t)mdp); - debugf(" end = 0x%08x\n", (u_int32_t)end); - debugf(" boothowto = 0x%08x\n", boothowto); -#ifdef MPC85XX - debugf(" kernel ccsrbar = 0x%08x\n", CCSRBAR_VA); -#endif - debugf(" MSR = 0x%08x\n", mfmsr()); -#if defined(BOOKE_E500) - debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0)); - debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1)); - debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR)); -#endif - - debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp); - - print_kernel_section_addr(); - print_kenv(); -#if defined(BOOKE_E500) - //tlb1_print_entries(); - //tlb1_print_tlbentries(); -#endif - - kdb_init(); - -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); -#endif - - /* Initialise platform module */ - platform_probe_and_attach(); - - /* Initialise virtual memory. */ - pmap_mmu_install(MMU_TYPE_BOOKE, 0); - pmap_bootstrap((uintptr_t)kernel_text, end); - debugf("MSR = 0x%08x\n", mfmsr()); -#if defined(BOOKE_E500) - //tlb1_print_entries(); - //tlb1_print_tlbentries(); -#endif - - /* Initialize params/tunables that are derived from memsize. */ - init_param2(physmem); - - /* Finish setting up thread0. */ - thread0.td_pcb = (struct pcb *) - ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - - sizeof(struct pcb)) & ~15); - bzero((void *)thread0.td_pcb, sizeof(struct pcb)); - pc->pc_curpcb = thread0.td_pcb; - - /* Initialise the message buffer. */ - msgbufinit(msgbufp, msgbufsize); - - /* Enable Machine Check interrupt. */ - mtmsr(mfmsr() | PSL_ME); - isync(); + ret = powerpc_init(dtbp, 0, 0, mdp); /* Enable L1 caches */ booke_enable_l1_cache(); - debugf("%s: SP = 0x%08x\n", __func__, - ((uintptr_t)thread0.td_pcb - 16) & ~15); - - return (((uintptr_t)thread0.td_pcb - 16) & ~15); + return (ret); } #define RES_GRANULE 32 @@ -560,63 +334,6 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) #endif } -/* - * Flush the D-cache for non-DMA I/O so that the I-cache can - * be made coherent later. - */ -void -cpu_flush_dcache(void *ptr, size_t len) -{ - register_t addr, off; - - /* - * Align the address to a cacheline and adjust the length - * accordingly. Then round the length to a multiple of the - * cacheline for easy looping. - */ - addr = (uintptr_t)ptr; - off = addr & (cacheline_size - 1); - addr -= off; - len = (len + off + cacheline_size - 1) & ~(cacheline_size - 1); - - while (len > 0) { - __asm __volatile ("dcbf 0,%0" :: "r"(addr)); - __asm __volatile ("sync"); - addr += cacheline_size; - len -= cacheline_size; - } -} - -void -spinlock_enter(void) -{ - struct thread *td; - register_t msr; - - td = curthread; - if (td->td_md.md_spinlock_count == 0) { - msr = intr_disable(); - td->td_md.md_spinlock_count = 1; - td->td_md.md_saved_msr = msr; - } else - td->td_md.md_spinlock_count++; - critical_enter(); -} - -void -spinlock_exit(void) -{ - struct thread *td; - register_t msr; - - td = curthread; - critical_exit(); - msr = td->td_md.md_saved_msr; - td->td_md.md_spinlock_count--; - if (td->td_md.md_spinlock_count == 0) - intr_restore(msr); -} - /* Shutdown the CPU as much as possible. */ void cpu_halt(void) @@ -628,17 +345,6 @@ cpu_halt(void) } int -ptrace_set_pc(struct thread *td, unsigned long addr) -{ - struct trapframe *tf; - - tf = td->td_frame; - tf->srr0 = (register_t)addr; - - return (0); -} - -int ptrace_single_step(struct thread *td) { struct trapframe *tf; @@ -680,40 +386,3 @@ kdb_cpu_set_singlestep(void) kdb_frame->srr1 |= PSL_DE; } -void -bzero(void *buf, size_t len) -{ - caddr_t p; - - p = buf; - - while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { - *p++ = 0; - len--; - } - - while (len >= sizeof(u_long) * 8) { - *(u_long*) p = 0; - *((u_long*) p + 1) = 0; - *((u_long*) p + 2) = 0; - *((u_long*) p + 3) = 0; - len -= sizeof(u_long) * 8; - *((u_long*) p + 4) = 0; - *((u_long*) p + 5) = 0; - *((u_long*) p + 6) = 0; - *((u_long*) p + 7) = 0; - p += sizeof(u_long) * 8; - } - - while (len >= sizeof(u_long)) { - *(u_long*) p = 0; - len -= sizeof(u_long); - p += sizeof(u_long); - } - - while (len) { - *p++ = 0; - len--; - } -} - diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 2c6df63..c5e3bf3 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -1031,13 +1031,8 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend) * Align kernel start and end address (kernel image). * Note that kernel end does not necessarily relate to kernsize. * kernsize is the size of the kernel that is actually mapped. - * Also note that "start - 1" is deliberate. With SMP, the - * entry point is exactly a page from the actual load address. - * As such, trunc_page() has no effect and we're off by a page. - * Since we always have the ELF header between the load address - * and the entry point, we can safely subtract 1 to compensate. */ - kernstart = trunc_page(start - 1); + kernstart = trunc_page(start); data_start = round_page(kernelend); data_end = data_start; |