diff options
-rw-r--r-- | sys/powerpc/aim/aim_machdep.c (renamed from sys/powerpc/aim/machdep.c) | 345 | ||||
-rw-r--r-- | sys/powerpc/aim/mmu_oea64.c | 5 | ||||
-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 | ||||
-rw-r--r-- | sys/powerpc/conf/GENERIC | 1 | ||||
-rw-r--r-- | sys/powerpc/powerpc/machdep.c | 502 | ||||
-rw-r--r-- | sys/powerpc/powerpc/uma_machdep.c (renamed from sys/powerpc/aim/uma_machdep.c) | 0 |
7 files changed, 531 insertions, 698 deletions
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/aim_machdep.c index 1c22220..ab09ab6 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/aim_machdep.c @@ -129,106 +129,14 @@ __FBSDID("$FreeBSD$"); #include <dev/ofw/openfirm.h> -int cold = 1; #ifdef __powerpc64__ extern int n_slbs; -int cacheline_size = 128; -#else -int cacheline_size = 32; #endif -int hw_direct_map = 1; - -extern void *ap_pcpu; - -struct pcpu __pcpu[MAXCPU]; - -static struct trapframe frame0; - -char machine[] = "powerpc"; -SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); - -static void cpu_startup(void *); -SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); - -SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, - CTLFLAG_RD, &cacheline_size, 0, ""); - -uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *); - -long Maxmem = 0; -long realmem = 0; #ifndef __powerpc64__ struct bat battable[16]; #endif -struct kva_md_info kmi; - -static void -cpu_startup(void *dummy) -{ - - /* - * Initialise the decrementer-based clock. - */ - decr_init(); - - /* - * Good {morning,afternoon,evening,night}. - */ - cpu_setup(PCPU_GET(cpuid)); - -#ifdef PERFMON - perfmon_init(); -#endif - printf("real memory = %ld (%ld MB)\n", ptoa(physmem), - ptoa(physmem) / 1048576); - realmem = physmem; - - if (bootverbose) - printf("available KVA = %zd (%zd MB)\n", - virtual_end - virtual_avail, - (virtual_end - virtual_avail) / 1048576); - - /* - * Display any holes after the first chunk of extended memory. - */ - if (bootverbose) { - int indx; - - printf("Physical memory chunk(s):\n"); - for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { - vm_offset_t size1 = - phys_avail[indx + 1] - phys_avail[indx]; - - #ifdef __powerpc64__ - printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n", - #else - printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", - #endif - phys_avail[indx], phys_avail[indx + 1] - 1, size1, - size1 / PAGE_SIZE); - } - } - - vm_ksubmap_init(&kmi); - - printf("avail memory = %ld (%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(); -} - -extern vm_offset_t __startkernel, __endkernel; -extern unsigned char __bss_start[]; -extern unsigned char __sbss_start[]; -extern unsigned char __sbss_end[]; -extern unsigned char _end[]; - #ifndef __powerpc64__ /* Bits for running on 64-bit systems in 32-bit mode. */ extern void *testppc64, *testppc64size; @@ -252,121 +160,25 @@ extern void *imisstrap, *imisssize; extern void *dlmisstrap, *dlmisssize; extern void *dsmisstrap, *dsmisssize; -uintptr_t -powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) +extern void *ap_pcpu; + +void aim_cpu_init(vm_offset_t toc); + +void +aim_cpu_init(vm_offset_t toc) { - struct pcpu *pc; - vm_offset_t startkernel, endkernel; size_t trap_offset, trapsize; vm_offset_t trap; - void *kmdp; - char *env; register_t msr, scratch; uint8_t *cache_check; int cacheline_warn; #ifndef __powerpc64__ int ppc64; #endif -#ifdef DDB - vm_offset_t ksym_start; - vm_offset_t ksym_end; -#endif - kmdp = NULL; trap_offset = 0; cacheline_warn = 0; - /* First guess at start/end kernel positions */ - startkernel = __startkernel; - endkernel = __endkernel; - - /* Check for ePAPR loader, which puts a magic value into r6 */ - if (mdp == (void *)0x65504150) - mdp = NULL; - - /* - * Parse metadata if present and fetch parameters. Must be done - * before console is inited so cninit gets the right value of - * boothowto. - */ - 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 *); - endkernel = ulmax(endkernel, MD_FETCH(kmdp, - MODINFOMD_KERNEND, vm_offset_t)); -#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); - } - - /* Store boot environment state */ - OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry); - - /* - * 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. - */ - pc = __pcpu; - 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 - pc->pc_cpuid = 0; - - __asm __volatile("mtsprg 0, %0" :: "r"(pc)); - - /* - * Init mutexes, which we use heavily in PMAP - */ - - mutex_init(); - - /* - * Install the OF client interface - */ - - OF_bootstrap(); - - /* - * Initialize the console before printing anything. - */ - cninit(); - - /* - * Complain if there is no metadata. - */ - if (mdp == NULL || kmdp == NULL) { - printf("powerpc_init: no loader metadata.\n"); - } - - /* - * Init KDB - */ - - kdb_init(); - /* Various very early CPU fix ups */ switch (mfpvr() >> 16) { /* @@ -431,9 +243,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) cacheline_size = 32; } - /* Make sure the kernel icache is valid before we go too much further */ - __syncicache((caddr_t)startkernel, endkernel - startkernel); - #ifndef __powerpc64__ /* * Figure out whether we need to use the 64 bit PMAP. This works by @@ -552,12 +361,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) } /* - * Choose a platform module so we can get the physical memory map. - */ - - platform_probe_and_attach(); - - /* * Initialise virtual memory. Use BUS_PROBE_GENERIC priority * in case the platform module had a better idea of what we * should do. @@ -566,96 +369,6 @@ powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); else pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); - - pmap_bootstrap(startkernel, endkernel); - mtmsr(PSL_KERNSET & ~PSL_EE); - - /* - * Initialize params/tunables that are derived from memsize - */ - init_param2(physmem); - - /* - * Grab booted kernel's name - */ - env = kern_getenv("kernelname"); - if (env != NULL) { - strlcpy(kernelname, env, sizeof(kernelname)); - freeenv(env); - } - - /* - * Finish setting up thread0. - */ - thread0.td_pcb = (struct pcb *) - ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - - sizeof(struct pcb)) & ~15UL); - bzero((void *)thread0.td_pcb, sizeof(struct pcb)); - pc->pc_curpcb = thread0.td_pcb; - - /* Initialise the message buffer. */ - msgbufinit(msgbufp, msgbufsize); - -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, - "Boot flags requested debugger"); -#endif - - return (((uintptr_t)thread0.td_pcb - - (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); -} - -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--; - } -} - -void -cpu_boot(int howto) -{ -} - -/* - * 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) -{ - /* TBD */ } /* @@ -669,17 +382,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; @@ -727,41 +429,7 @@ memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb)); #endif } -void -spinlock_enter(void) -{ - struct thread *td; - register_t msr; - - td = curthread; - if (td->td_md.md_spinlock_count == 0) { - __asm __volatile("or 2,2,2"); /* Set high thread priority */ - 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); - __asm __volatile("or 6,6,6"); /* Set normal thread priority */ - } -} - #ifndef __powerpc64__ - uint64_t va_to_vsid(pmap_t pm, vm_offset_t va) { @@ -945,3 +613,4 @@ cpu_sleep() enable_vec(curthread); powerpc_sync(); } + diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 23bd449..c45f941 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -137,8 +137,6 @@ struct ofw_map { extern unsigned char _etext[]; extern unsigned char _end[]; -extern int ofw_real_mode; - /* * Map of physical memory regions. */ @@ -852,8 +850,7 @@ moea64_late_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend */ chosen = OF_finddevice("/chosen"); - if (!ofw_real_mode && chosen != -1 && - OF_getprop(chosen, "mmu", &mmui, 4) != -1) { + if (chosen != -1 && OF_getprop(chosen, "mmu", &mmui, 4) != -1) { mmu = OF_instance_to_package(mmui); if (mmu == -1 || (sz = OF_getproplen(mmu, "translations")) == -1) 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; diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index e3939be..b5bf850 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -32,6 +32,7 @@ options PSIM #GDB PSIM ppc simulator options MAMBO #IBM Mambo Full System Simulator options PSERIES #PAPR-compliant systems +options FDT options SCHED_ULE #ULE scheduler options PREEMPTION #Enable kernel thread preemption options INET #InterNETworking diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c new file mode 100644 index 0000000..2bc9496 --- /dev/null +++ b/sys/powerpc/powerpc/machdep.c @@ -0,0 +1,502 @@ +/*- + * Copyright (C) 1995, 1996 Wolfgang Solfrank. + * Copyright (C) 1995, 1996 TooLs GmbH. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + */ +/*- + * Copyright (C) 2001 Benno Rice + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``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 TOOLS GMBH 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. + * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include "opt_compat.h" +#include "opt_ddb.h" +#include "opt_kstack_pages.h" +#include "opt_platform.h" + +#include <sys/param.h> +#include <sys/proc.h> +#include <sys/systm.h> +#include <sys/bio.h> +#include <sys/buf.h> +#include <sys/bus.h> +#include <sys/cons.h> +#include <sys/cpu.h> +#include <sys/eventhandler.h> +#include <sys/exec.h> +#include <sys/imgact.h> +#include <sys/kdb.h> +#include <sys/kernel.h> +#include <sys/ktr.h> +#include <sys/linker.h> +#include <sys/lock.h> +#include <sys/malloc.h> +#include <sys/mbuf.h> +#include <sys/msgbuf.h> +#include <sys/mutex.h> +#include <sys/ptrace.h> +#include <sys/reboot.h> +#include <sys/rwlock.h> +#include <sys/signalvar.h> +#include <sys/syscallsubr.h> +#include <sys/sysctl.h> +#include <sys/sysent.h> +#include <sys/sysproto.h> +#include <sys/ucontext.h> +#include <sys/uio.h> +#include <sys/vmmeter.h> +#include <sys/vnode.h> + +#include <net/netisr.h> + +#include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> +#include <vm/vm_page.h> +#include <vm/vm_map.h> +#include <vm/vm_object.h> +#include <vm/vm_pager.h> + +#include <machine/altivec.h> +#ifndef __powerpc64__ +#include <machine/bat.h> +#endif +#include <machine/cpu.h> +#include <machine/elf.h> +#include <machine/fpu.h> +#include <machine/hid.h> +#include <machine/kdb.h> +#include <machine/md_var.h> +#include <machine/metadata.h> +#include <machine/mmuvar.h> +#include <machine/pcb.h> +#include <machine/reg.h> +#include <machine/sigframe.h> +#include <machine/spr.h> +#include <machine/trap.h> +#include <machine/vmparam.h> +#include <machine/ofw_machdep.h> + +#include <ddb/ddb.h> + +#include <dev/ofw/openfirm.h> + +int cold = 1; +#ifdef __powerpc64__ +int cacheline_size = 128; +#else +int cacheline_size = 32; +#endif +int hw_direct_map = 1; + +extern void *ap_pcpu; + +struct pcpu __pcpu[MAXCPU]; + +static struct trapframe frame0; + +char machine[] = "powerpc"; +SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); + +static void cpu_startup(void *); +SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); + +SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, + CTLFLAG_RD, &cacheline_size, 0, ""); + +uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *); + +long Maxmem = 0; +long realmem = 0; + +struct kva_md_info kmi; + +static void +cpu_startup(void *dummy) +{ + + /* + * Initialise the decrementer-based clock. + */ + decr_init(); + + /* + * Good {morning,afternoon,evening,night}. + */ + cpu_setup(PCPU_GET(cpuid)); + +#ifdef PERFMON + perfmon_init(); +#endif + printf("real memory = %ld (%ld MB)\n", ptoa(physmem), + ptoa(physmem) / 1048576); + realmem = physmem; + + if (bootverbose) + printf("available KVA = %zd (%zd MB)\n", + virtual_end - virtual_avail, + (virtual_end - virtual_avail) / 1048576); + + /* + * Display any holes after the first chunk of extended memory. + */ + if (bootverbose) { + int indx; + + printf("Physical memory chunk(s):\n"); + for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { + vm_offset_t size1 = + phys_avail[indx + 1] - phys_avail[indx]; + + #ifdef __powerpc64__ + printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n", + #else + printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", + #endif + phys_avail[indx], phys_avail[indx + 1] - 1, size1, + size1 / PAGE_SIZE); + } + } + + vm_ksubmap_init(&kmi); + + printf("avail memory = %ld (%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(); +} + +extern vm_offset_t __startkernel, __endkernel; +extern unsigned char __bss_start[]; +extern unsigned char __sbss_start[]; +extern unsigned char __sbss_end[]; +extern unsigned char _end[]; + +void aim_cpu_init(vm_offset_t toc); +void booke_cpu_init(void); + +uintptr_t +powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) +{ + struct pcpu *pc; + vm_offset_t startkernel, endkernel; + void *kmdp; + char *env; +#ifdef DDB + vm_offset_t ksym_start; + vm_offset_t ksym_end; +#endif + + kmdp = NULL; + + /* First guess at start/end kernel positions */ + startkernel = __startkernel; + endkernel = __endkernel; + + /* Check for ePAPR loader, which puts a magic value into r6 */ + if (mdp == (void *)0x65504150) + mdp = NULL; + + /* + * Parse metadata if present and fetch parameters. Must be done + * before console is inited so cninit gets the right value of + * boothowto. + */ + 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 *); + endkernel = ulmax(endkernel, MD_FETCH(kmdp, + MODINFOMD_KERNEND, vm_offset_t)); +#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); + } +#ifdef BOOKE + tlb1_init(); +#endif + + /* Store boot environment state */ + OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry); + + /* + * 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. + */ + pc = __pcpu; + 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 + pc->pc_cpuid = 0; + + __asm __volatile("mtsprg 0, %0" :: "r"(pc)); + + /* + * Init mutexes, which we use heavily in PMAP + */ + + mutex_init(); + + /* + * Install the OF client interface + */ + + OF_bootstrap(); + + /* + * Initialize the console before printing anything. + */ + cninit(); + + /* + * Complain if there is no metadata. + */ + if (mdp == NULL || kmdp == NULL) { + printf("powerpc_init: no loader metadata.\n"); + } + + /* + * Init KDB + */ + + kdb_init(); + +#ifdef AIM + aim_cpu_init(toc); +#else /* BOOKE */ + booke_cpu_init(); + + /* Make sure the kernel icache is valid before we go too much further */ + __syncicache((caddr_t)startkernel, endkernel - startkernel); +#endif + + /* + * Choose a platform module so we can get the physical memory map. + */ + + platform_probe_and_attach(); + + /* + * Bring up MMU + */ + pmap_bootstrap(startkernel, endkernel); + mtmsr(PSL_KERNSET & ~PSL_EE); + + /* + * Initialize params/tunables that are derived from memsize + */ + init_param2(physmem); + + /* + * Grab booted kernel's name + */ + env = kern_getenv("kernelname"); + if (env != NULL) { + strlcpy(kernelname, env, sizeof(kernelname)); + freeenv(env); + } + + /* + * Finish setting up thread0. + */ + thread0.td_pcb = (struct pcb *) + ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - + sizeof(struct pcb)) & ~15UL); + bzero((void *)thread0.td_pcb, sizeof(struct pcb)); + pc->pc_curpcb = thread0.td_pcb; + + /* Initialise the message buffer. */ + msgbufinit(msgbufp, msgbufsize); + +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter(KDB_WHY_BOOTFLAGS, + "Boot flags requested debugger"); +#endif + + return (((uintptr_t)thread0.td_pcb - + (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); +} + +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--; + } +} + +/* + * 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; + } +} + +int +ptrace_set_pc(struct thread *td, unsigned long addr) +{ + struct trapframe *tf; + + tf = td->td_frame; + tf->srr0 = (register_t)addr; + + return (0); +} + +void +spinlock_enter(void) +{ + struct thread *td; + register_t msr; + + td = curthread; + if (td->td_md.md_spinlock_count == 0) { + __asm __volatile("or 2,2,2"); /* Set high thread priority */ + 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); + __asm __volatile("or 6,6,6"); /* Set normal thread priority */ + } +} + diff --git a/sys/powerpc/aim/uma_machdep.c b/sys/powerpc/powerpc/uma_machdep.c index 1c27e3e..1c27e3e 100644 --- a/sys/powerpc/aim/uma_machdep.c +++ b/sys/powerpc/powerpc/uma_machdep.c |