1/*- 2 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3 * Copyright (C) 1995, 1996 TooLs GmbH. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by TooLs GmbH. 17 * 4. The name of TooLs GmbH may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31/*- 32 * Copyright (C) 2001 Benno Rice 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 55 */ 56 57#include <sys/cdefs.h>
| 1/*- 2 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 3 * Copyright (C) 1995, 1996 TooLs GmbH. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by TooLs GmbH. 17 * 4. The name of TooLs GmbH may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31/*- 32 * Copyright (C) 2001 Benno Rice 33 * All rights reserved. 34 * 35 * Redistribution and use in source and binary forms, with or without 36 * modification, are permitted provided that the following conditions 37 * are met: 38 * 1. Redistributions of source code must retain the above copyright 39 * notice, this list of conditions and the following disclaimer. 40 * 2. Redistributions in binary form must reproduce the above copyright 41 * notice, this list of conditions and the following disclaimer in the 42 * documentation and/or other materials provided with the distribution. 43 * 44 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR 45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 47 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 49 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 50 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 52 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 53 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 * $NetBSD: machdep.c,v 1.74.2.1 2000/11/01 16:13:48 tv Exp $ 55 */ 56 57#include <sys/cdefs.h>
|
58__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 277411 2015-01-20 05:28:03Z nwhitehorn $");
| 58__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 277498 2015-01-21 19:07:45Z nwhitehorn $");
|
59 60#include "opt_compat.h" 61#include "opt_ddb.h" 62#include "opt_kstack_pages.h" 63#include "opt_platform.h" 64 65#include <sys/param.h> 66#include <sys/proc.h> 67#include <sys/systm.h> 68#include <sys/bio.h> 69#include <sys/buf.h> 70#include <sys/bus.h> 71#include <sys/cons.h> 72#include <sys/cpu.h> 73#include <sys/eventhandler.h> 74#include <sys/exec.h> 75#include <sys/imgact.h> 76#include <sys/kdb.h> 77#include <sys/kernel.h> 78#include <sys/ktr.h> 79#include <sys/linker.h> 80#include <sys/lock.h> 81#include <sys/malloc.h> 82#include <sys/mbuf.h> 83#include <sys/msgbuf.h> 84#include <sys/mutex.h> 85#include <sys/ptrace.h> 86#include <sys/reboot.h> 87#include <sys/rwlock.h> 88#include <sys/signalvar.h> 89#include <sys/syscallsubr.h> 90#include <sys/sysctl.h> 91#include <sys/sysent.h> 92#include <sys/sysproto.h> 93#include <sys/ucontext.h> 94#include <sys/uio.h> 95#include <sys/vmmeter.h> 96#include <sys/vnode.h> 97 98#include <net/netisr.h> 99 100#include <vm/vm.h> 101#include <vm/vm_extern.h> 102#include <vm/vm_kern.h> 103#include <vm/vm_page.h> 104#include <vm/vm_map.h> 105#include <vm/vm_object.h> 106#include <vm/vm_pager.h> 107 108#include <machine/altivec.h> 109#ifndef __powerpc64__ 110#include <machine/bat.h> 111#endif 112#include <machine/cpu.h> 113#include <machine/elf.h> 114#include <machine/fpu.h> 115#include <machine/hid.h> 116#include <machine/kdb.h> 117#include <machine/md_var.h> 118#include <machine/metadata.h> 119#include <machine/mmuvar.h> 120#include <machine/pcb.h> 121#include <machine/reg.h> 122#include <machine/sigframe.h> 123#include <machine/spr.h> 124#include <machine/trap.h> 125#include <machine/vmparam.h> 126#include <machine/ofw_machdep.h> 127 128#include <ddb/ddb.h> 129 130#include <dev/ofw/openfirm.h> 131 132int cold = 1; 133#ifdef __powerpc64__ 134extern int n_slbs; 135int cacheline_size = 128; 136#else 137int cacheline_size = 32; 138#endif 139int hw_direct_map = 1; 140 141extern void *ap_pcpu; 142 143struct pcpu __pcpu[MAXCPU]; 144 145static struct trapframe frame0; 146 147char machine[] = "powerpc"; 148SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 149 150static void cpu_startup(void *); 151SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 152 153SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 154 CTLFLAG_RD, &cacheline_size, 0, ""); 155 156uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *); 157 158long Maxmem = 0; 159long realmem = 0; 160 161#ifndef __powerpc64__ 162struct bat battable[16]; 163#endif 164 165struct kva_md_info kmi; 166 167static void 168cpu_startup(void *dummy) 169{ 170 171 /* 172 * Initialise the decrementer-based clock. 173 */ 174 decr_init(); 175 176 /* 177 * Good {morning,afternoon,evening,night}. 178 */ 179 cpu_setup(PCPU_GET(cpuid)); 180 181#ifdef PERFMON 182 perfmon_init(); 183#endif 184 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 185 ptoa(physmem) / 1048576); 186 realmem = physmem; 187 188 if (bootverbose) 189 printf("available KVA = %zd (%zd MB)\n", 190 virtual_end - virtual_avail, 191 (virtual_end - virtual_avail) / 1048576); 192 193 /* 194 * Display any holes after the first chunk of extended memory. 195 */ 196 if (bootverbose) { 197 int indx; 198 199 printf("Physical memory chunk(s):\n"); 200 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 201 vm_offset_t size1 = 202 phys_avail[indx + 1] - phys_avail[indx]; 203 204 #ifdef __powerpc64__ 205 printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n", 206 #else 207 printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", 208 #endif 209 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 210 size1 / PAGE_SIZE); 211 } 212 } 213 214 vm_ksubmap_init(&kmi); 215 216 printf("avail memory = %ld (%ld MB)\n", ptoa(vm_cnt.v_free_count), 217 ptoa(vm_cnt.v_free_count) / 1048576); 218 219 /* 220 * Set up buffers, so they can be used to read disk labels. 221 */ 222 bufinit(); 223 vm_pager_bufferinit(); 224} 225 226extern vm_offset_t __startkernel, __endkernel; 227extern unsigned char __bss_start[]; 228extern unsigned char __sbss_start[]; 229extern unsigned char __sbss_end[]; 230extern unsigned char _end[]; 231 232#ifndef __powerpc64__ 233/* Bits for running on 64-bit systems in 32-bit mode. */ 234extern void *testppc64, *testppc64size; 235extern void *restorebridge, *restorebridgesize; 236extern void *rfid_patch, *rfi_patch1, *rfi_patch2; 237extern void *trapcode64; 238#endif 239 240extern void *rstcode, *rstsize;
| 59 60#include "opt_compat.h" 61#include "opt_ddb.h" 62#include "opt_kstack_pages.h" 63#include "opt_platform.h" 64 65#include <sys/param.h> 66#include <sys/proc.h> 67#include <sys/systm.h> 68#include <sys/bio.h> 69#include <sys/buf.h> 70#include <sys/bus.h> 71#include <sys/cons.h> 72#include <sys/cpu.h> 73#include <sys/eventhandler.h> 74#include <sys/exec.h> 75#include <sys/imgact.h> 76#include <sys/kdb.h> 77#include <sys/kernel.h> 78#include <sys/ktr.h> 79#include <sys/linker.h> 80#include <sys/lock.h> 81#include <sys/malloc.h> 82#include <sys/mbuf.h> 83#include <sys/msgbuf.h> 84#include <sys/mutex.h> 85#include <sys/ptrace.h> 86#include <sys/reboot.h> 87#include <sys/rwlock.h> 88#include <sys/signalvar.h> 89#include <sys/syscallsubr.h> 90#include <sys/sysctl.h> 91#include <sys/sysent.h> 92#include <sys/sysproto.h> 93#include <sys/ucontext.h> 94#include <sys/uio.h> 95#include <sys/vmmeter.h> 96#include <sys/vnode.h> 97 98#include <net/netisr.h> 99 100#include <vm/vm.h> 101#include <vm/vm_extern.h> 102#include <vm/vm_kern.h> 103#include <vm/vm_page.h> 104#include <vm/vm_map.h> 105#include <vm/vm_object.h> 106#include <vm/vm_pager.h> 107 108#include <machine/altivec.h> 109#ifndef __powerpc64__ 110#include <machine/bat.h> 111#endif 112#include <machine/cpu.h> 113#include <machine/elf.h> 114#include <machine/fpu.h> 115#include <machine/hid.h> 116#include <machine/kdb.h> 117#include <machine/md_var.h> 118#include <machine/metadata.h> 119#include <machine/mmuvar.h> 120#include <machine/pcb.h> 121#include <machine/reg.h> 122#include <machine/sigframe.h> 123#include <machine/spr.h> 124#include <machine/trap.h> 125#include <machine/vmparam.h> 126#include <machine/ofw_machdep.h> 127 128#include <ddb/ddb.h> 129 130#include <dev/ofw/openfirm.h> 131 132int cold = 1; 133#ifdef __powerpc64__ 134extern int n_slbs; 135int cacheline_size = 128; 136#else 137int cacheline_size = 32; 138#endif 139int hw_direct_map = 1; 140 141extern void *ap_pcpu; 142 143struct pcpu __pcpu[MAXCPU]; 144 145static struct trapframe frame0; 146 147char machine[] = "powerpc"; 148SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 149 150static void cpu_startup(void *); 151SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); 152 153SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 154 CTLFLAG_RD, &cacheline_size, 0, ""); 155 156uintptr_t powerpc_init(vm_offset_t, vm_offset_t, vm_offset_t, void *); 157 158long Maxmem = 0; 159long realmem = 0; 160 161#ifndef __powerpc64__ 162struct bat battable[16]; 163#endif 164 165struct kva_md_info kmi; 166 167static void 168cpu_startup(void *dummy) 169{ 170 171 /* 172 * Initialise the decrementer-based clock. 173 */ 174 decr_init(); 175 176 /* 177 * Good {morning,afternoon,evening,night}. 178 */ 179 cpu_setup(PCPU_GET(cpuid)); 180 181#ifdef PERFMON 182 perfmon_init(); 183#endif 184 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 185 ptoa(physmem) / 1048576); 186 realmem = physmem; 187 188 if (bootverbose) 189 printf("available KVA = %zd (%zd MB)\n", 190 virtual_end - virtual_avail, 191 (virtual_end - virtual_avail) / 1048576); 192 193 /* 194 * Display any holes after the first chunk of extended memory. 195 */ 196 if (bootverbose) { 197 int indx; 198 199 printf("Physical memory chunk(s):\n"); 200 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 201 vm_offset_t size1 = 202 phys_avail[indx + 1] - phys_avail[indx]; 203 204 #ifdef __powerpc64__ 205 printf("0x%016lx - 0x%016lx, %ld bytes (%ld pages)\n", 206 #else 207 printf("0x%08x - 0x%08x, %d bytes (%ld pages)\n", 208 #endif 209 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 210 size1 / PAGE_SIZE); 211 } 212 } 213 214 vm_ksubmap_init(&kmi); 215 216 printf("avail memory = %ld (%ld MB)\n", ptoa(vm_cnt.v_free_count), 217 ptoa(vm_cnt.v_free_count) / 1048576); 218 219 /* 220 * Set up buffers, so they can be used to read disk labels. 221 */ 222 bufinit(); 223 vm_pager_bufferinit(); 224} 225 226extern vm_offset_t __startkernel, __endkernel; 227extern unsigned char __bss_start[]; 228extern unsigned char __sbss_start[]; 229extern unsigned char __sbss_end[]; 230extern unsigned char _end[]; 231 232#ifndef __powerpc64__ 233/* Bits for running on 64-bit systems in 32-bit mode. */ 234extern void *testppc64, *testppc64size; 235extern void *restorebridge, *restorebridgesize; 236extern void *rfid_patch, *rfi_patch1, *rfi_patch2; 237extern void *trapcode64; 238#endif 239 240extern void *rstcode, *rstsize;
|
241extern void *trapcode, *trapsize;
| 241extern void *trapcode, *trapsize, *trapcode2;
|
242extern void *slbtrap, *slbtrapsize; 243extern void *alitrap, *alisize; 244extern void *dsitrap, *dsisize; 245extern void *decrint, *decrsize; 246extern void *extint, *extsize; 247extern void *dblow, *dbsize; 248extern void *imisstrap, *imisssize; 249extern void *dlmisstrap, *dlmisssize; 250extern void *dsmisstrap, *dsmisssize; 251 252uintptr_t 253powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) 254{ 255 struct pcpu *pc; 256 vm_offset_t startkernel, endkernel; 257 void *generictrap; 258 size_t trap_offset; 259 void *kmdp; 260 char *env; 261 register_t msr, scratch; 262#ifdef WII 263 register_t vers; 264#endif 265 uint8_t *cache_check; 266 int cacheline_warn; 267 #ifndef __powerpc64__ 268 int ppc64; 269 #endif 270#ifdef DDB 271 vm_offset_t ksym_start; 272 vm_offset_t ksym_end; 273#endif 274 275 kmdp = NULL; 276 trap_offset = 0; 277 cacheline_warn = 0; 278 279 /* First guess at start/end kernel positions */ 280 startkernel = __startkernel; 281 endkernel = __endkernel; 282 283#ifdef WII 284 /* 285 * The Wii loader doesn't pass us any environment so, mdp 286 * points to garbage at this point. The Wii CPU is a 750CL. 287 */ 288 vers = mfpvr(); 289 if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL)) 290 mdp = NULL; 291#endif 292 293 /* Check for ePAPR loader, which puts a magic value into r6 */ 294 if (mdp == (void *)0x65504150) 295 mdp = NULL; 296 297 /* 298 * Parse metadata if present and fetch parameters. Must be done 299 * before console is inited so cninit gets the right value of 300 * boothowto. 301 */ 302 if (mdp != NULL) { 303 preload_metadata = mdp; 304 kmdp = preload_search_by_type("elf kernel"); 305 if (kmdp != NULL) { 306 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 307 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 308 endkernel = ulmax(endkernel, MD_FETCH(kmdp, 309 MODINFOMD_KERNEND, vm_offset_t)); 310#ifdef DDB 311 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 312 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 313 db_fetch_ksymtab(ksym_start, ksym_end); 314#endif 315 } 316 } else { 317 bzero(__sbss_start, __sbss_end - __sbss_start); 318 bzero(__bss_start, _end - __bss_start); 319 } 320 321 /* Store boot environment state */ 322 OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry); 323 324 /* 325 * Init params/tunables that can be overridden by the loader 326 */ 327 init_param1(); 328 329 /* 330 * Start initializing proc0 and thread0. 331 */ 332 proc_linkup0(&proc0, &thread0); 333 thread0.td_frame = &frame0; 334 335 /* 336 * Set up per-cpu data. 337 */ 338 pc = __pcpu; 339 pcpu_init(pc, 0, sizeof(struct pcpu)); 340 pc->pc_curthread = &thread0; 341#ifdef __powerpc64__ 342 __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread)); 343#else 344 __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread)); 345#endif 346 pc->pc_cpuid = 0; 347 348 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 349 350 /* 351 * Init mutexes, which we use heavily in PMAP 352 */ 353 354 mutex_init(); 355 356 /* 357 * Install the OF client interface 358 */ 359 360 OF_bootstrap(); 361 362 /* 363 * Initialize the console before printing anything. 364 */ 365 cninit(); 366 367 /* 368 * Complain if there is no metadata. 369 */ 370 if (mdp == NULL || kmdp == NULL) { 371 printf("powerpc_init: no loader metadata.\n"); 372 } 373 374 /* 375 * Init KDB 376 */ 377 378 kdb_init(); 379 380 /* Various very early CPU fix ups */ 381 switch (mfpvr() >> 16) { 382 /* 383 * PowerPC 970 CPUs have a misfeature requested by Apple that 384 * makes them pretend they have a 32-byte cacheline. Turn this 385 * off before we measure the cacheline size. 386 */ 387 case IBM970: 388 case IBM970FX: 389 case IBM970MP: 390 case IBM970GX: 391 scratch = mfspr(SPR_HID5); 392 scratch &= ~HID5_970_DCBZ_SIZE_HI; 393 mtspr(SPR_HID5, scratch); 394 break; 395 #ifdef __powerpc64__ 396 case IBMPOWER7: 397 /* XXX: get from ibm,slb-size in device tree */ 398 n_slbs = 32; 399 break; 400 #endif 401 } 402 403 /* 404 * Initialize the interrupt tables and figure out our cache line 405 * size and whether or not we need the 64-bit bridge code. 406 */ 407 408 /* 409 * Disable translation in case the vector area hasn't been 410 * mapped (G5). Note that no OFW calls can be made until 411 * translation is re-enabled. 412 */ 413 414 msr = mfmsr(); 415 mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); 416 417 /* 418 * Measure the cacheline size using dcbz 419 * 420 * Use EXC_PGM as a playground. We are about to overwrite it 421 * anyway, we know it exists, and we know it is cache-aligned. 422 */ 423 424 cache_check = (void *)EXC_PGM; 425 426 for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) 427 cache_check[cacheline_size] = 0xff; 428 429 __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); 430 431 /* Find the first byte dcbz did not zero to get the cache line size */ 432 for (cacheline_size = 0; cacheline_size < 0x100 && 433 cache_check[cacheline_size] == 0; cacheline_size++); 434 435 /* Work around psim bug */ 436 if (cacheline_size == 0) { 437 cacheline_warn = 1; 438 cacheline_size = 32; 439 } 440 441 /* Make sure the kernel icache is valid before we go too much further */ 442 __syncicache((caddr_t)startkernel, endkernel - startkernel); 443 444 #ifndef __powerpc64__ 445 /* 446 * Figure out whether we need to use the 64 bit PMAP. This works by 447 * executing an instruction that is only legal on 64-bit PPC (mtmsrd), 448 * and setting ppc64 = 0 if that causes a trap. 449 */ 450 451 ppc64 = 1; 452 453 bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); 454 __syncicache((void *)EXC_PGM, (size_t)&testppc64size); 455 456 __asm __volatile("\ 457 mfmsr %0; \ 458 mtsprg2 %1; \ 459 \ 460 mtmsrd %0; \ 461 mfsprg2 %1;" 462 : "=r"(scratch), "=r"(ppc64)); 463 464 if (ppc64) 465 cpu_features |= PPC_FEATURE_64; 466 467 /* 468 * Now copy restorebridge into all the handlers, if necessary, 469 * and set up the trap tables. 470 */ 471 472 if (cpu_features & PPC_FEATURE_64) { 473 /* Patch the two instances of rfi -> rfid */ 474 bcopy(&rfid_patch,&rfi_patch1,4); 475 #ifdef KDB 476 /* rfi_patch2 is at the end of dbleave */ 477 bcopy(&rfid_patch,&rfi_patch2,4); 478 #endif 479 480 /* 481 * Copy a code snippet to restore 32-bit bridge mode 482 * to the top of every non-generic trap handler 483 */ 484 485 trap_offset += (size_t)&restorebridgesize; 486 bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 487 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 488 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 489 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 490 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 491 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 492 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 493 494 /* 495 * Set the common trap entry point to the one that 496 * knows to restore 32-bit operation on execution. 497 */ 498 499 generictrap = &trapcode64; 500 } else { 501 generictrap = &trapcode; 502 } 503 504 #else /* powerpc64 */ 505 cpu_features |= PPC_FEATURE_64; 506 generictrap = &trapcode; 507 508 /* Set TOC base so that the interrupt code can get at it */
| 242extern void *slbtrap, *slbtrapsize; 243extern void *alitrap, *alisize; 244extern void *dsitrap, *dsisize; 245extern void *decrint, *decrsize; 246extern void *extint, *extsize; 247extern void *dblow, *dbsize; 248extern void *imisstrap, *imisssize; 249extern void *dlmisstrap, *dlmisssize; 250extern void *dsmisstrap, *dsmisssize; 251 252uintptr_t 253powerpc_init(vm_offset_t fdt, vm_offset_t toc, vm_offset_t ofentry, void *mdp) 254{ 255 struct pcpu *pc; 256 vm_offset_t startkernel, endkernel; 257 void *generictrap; 258 size_t trap_offset; 259 void *kmdp; 260 char *env; 261 register_t msr, scratch; 262#ifdef WII 263 register_t vers; 264#endif 265 uint8_t *cache_check; 266 int cacheline_warn; 267 #ifndef __powerpc64__ 268 int ppc64; 269 #endif 270#ifdef DDB 271 vm_offset_t ksym_start; 272 vm_offset_t ksym_end; 273#endif 274 275 kmdp = NULL; 276 trap_offset = 0; 277 cacheline_warn = 0; 278 279 /* First guess at start/end kernel positions */ 280 startkernel = __startkernel; 281 endkernel = __endkernel; 282 283#ifdef WII 284 /* 285 * The Wii loader doesn't pass us any environment so, mdp 286 * points to garbage at this point. The Wii CPU is a 750CL. 287 */ 288 vers = mfpvr(); 289 if ((vers & 0xfffff0e0) == (MPC750 << 16 | MPC750CL)) 290 mdp = NULL; 291#endif 292 293 /* Check for ePAPR loader, which puts a magic value into r6 */ 294 if (mdp == (void *)0x65504150) 295 mdp = NULL; 296 297 /* 298 * Parse metadata if present and fetch parameters. Must be done 299 * before console is inited so cninit gets the right value of 300 * boothowto. 301 */ 302 if (mdp != NULL) { 303 preload_metadata = mdp; 304 kmdp = preload_search_by_type("elf kernel"); 305 if (kmdp != NULL) { 306 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 307 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 308 endkernel = ulmax(endkernel, MD_FETCH(kmdp, 309 MODINFOMD_KERNEND, vm_offset_t)); 310#ifdef DDB 311 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 312 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 313 db_fetch_ksymtab(ksym_start, ksym_end); 314#endif 315 } 316 } else { 317 bzero(__sbss_start, __sbss_end - __sbss_start); 318 bzero(__bss_start, _end - __bss_start); 319 } 320 321 /* Store boot environment state */ 322 OF_initial_setup((void *)fdt, NULL, (int (*)(void *))ofentry); 323 324 /* 325 * Init params/tunables that can be overridden by the loader 326 */ 327 init_param1(); 328 329 /* 330 * Start initializing proc0 and thread0. 331 */ 332 proc_linkup0(&proc0, &thread0); 333 thread0.td_frame = &frame0; 334 335 /* 336 * Set up per-cpu data. 337 */ 338 pc = __pcpu; 339 pcpu_init(pc, 0, sizeof(struct pcpu)); 340 pc->pc_curthread = &thread0; 341#ifdef __powerpc64__ 342 __asm __volatile("mr 13,%0" :: "r"(pc->pc_curthread)); 343#else 344 __asm __volatile("mr 2,%0" :: "r"(pc->pc_curthread)); 345#endif 346 pc->pc_cpuid = 0; 347 348 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 349 350 /* 351 * Init mutexes, which we use heavily in PMAP 352 */ 353 354 mutex_init(); 355 356 /* 357 * Install the OF client interface 358 */ 359 360 OF_bootstrap(); 361 362 /* 363 * Initialize the console before printing anything. 364 */ 365 cninit(); 366 367 /* 368 * Complain if there is no metadata. 369 */ 370 if (mdp == NULL || kmdp == NULL) { 371 printf("powerpc_init: no loader metadata.\n"); 372 } 373 374 /* 375 * Init KDB 376 */ 377 378 kdb_init(); 379 380 /* Various very early CPU fix ups */ 381 switch (mfpvr() >> 16) { 382 /* 383 * PowerPC 970 CPUs have a misfeature requested by Apple that 384 * makes them pretend they have a 32-byte cacheline. Turn this 385 * off before we measure the cacheline size. 386 */ 387 case IBM970: 388 case IBM970FX: 389 case IBM970MP: 390 case IBM970GX: 391 scratch = mfspr(SPR_HID5); 392 scratch &= ~HID5_970_DCBZ_SIZE_HI; 393 mtspr(SPR_HID5, scratch); 394 break; 395 #ifdef __powerpc64__ 396 case IBMPOWER7: 397 /* XXX: get from ibm,slb-size in device tree */ 398 n_slbs = 32; 399 break; 400 #endif 401 } 402 403 /* 404 * Initialize the interrupt tables and figure out our cache line 405 * size and whether or not we need the 64-bit bridge code. 406 */ 407 408 /* 409 * Disable translation in case the vector area hasn't been 410 * mapped (G5). Note that no OFW calls can be made until 411 * translation is re-enabled. 412 */ 413 414 msr = mfmsr(); 415 mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI); 416 417 /* 418 * Measure the cacheline size using dcbz 419 * 420 * Use EXC_PGM as a playground. We are about to overwrite it 421 * anyway, we know it exists, and we know it is cache-aligned. 422 */ 423 424 cache_check = (void *)EXC_PGM; 425 426 for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++) 427 cache_check[cacheline_size] = 0xff; 428 429 __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory"); 430 431 /* Find the first byte dcbz did not zero to get the cache line size */ 432 for (cacheline_size = 0; cacheline_size < 0x100 && 433 cache_check[cacheline_size] == 0; cacheline_size++); 434 435 /* Work around psim bug */ 436 if (cacheline_size == 0) { 437 cacheline_warn = 1; 438 cacheline_size = 32; 439 } 440 441 /* Make sure the kernel icache is valid before we go too much further */ 442 __syncicache((caddr_t)startkernel, endkernel - startkernel); 443 444 #ifndef __powerpc64__ 445 /* 446 * Figure out whether we need to use the 64 bit PMAP. This works by 447 * executing an instruction that is only legal on 64-bit PPC (mtmsrd), 448 * and setting ppc64 = 0 if that causes a trap. 449 */ 450 451 ppc64 = 1; 452 453 bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size); 454 __syncicache((void *)EXC_PGM, (size_t)&testppc64size); 455 456 __asm __volatile("\ 457 mfmsr %0; \ 458 mtsprg2 %1; \ 459 \ 460 mtmsrd %0; \ 461 mfsprg2 %1;" 462 : "=r"(scratch), "=r"(ppc64)); 463 464 if (ppc64) 465 cpu_features |= PPC_FEATURE_64; 466 467 /* 468 * Now copy restorebridge into all the handlers, if necessary, 469 * and set up the trap tables. 470 */ 471 472 if (cpu_features & PPC_FEATURE_64) { 473 /* Patch the two instances of rfi -> rfid */ 474 bcopy(&rfid_patch,&rfi_patch1,4); 475 #ifdef KDB 476 /* rfi_patch2 is at the end of dbleave */ 477 bcopy(&rfid_patch,&rfi_patch2,4); 478 #endif 479 480 /* 481 * Copy a code snippet to restore 32-bit bridge mode 482 * to the top of every non-generic trap handler 483 */ 484 485 trap_offset += (size_t)&restorebridgesize; 486 bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 487 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 488 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 489 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 490 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 491 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 492 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 493 494 /* 495 * Set the common trap entry point to the one that 496 * knows to restore 32-bit operation on execution. 497 */ 498 499 generictrap = &trapcode64; 500 } else { 501 generictrap = &trapcode; 502 } 503 504 #else /* powerpc64 */ 505 cpu_features |= PPC_FEATURE_64; 506 generictrap = &trapcode; 507 508 /* Set TOC base so that the interrupt code can get at it */
|
| 509 *((void **)TRAP_GENTRAP) = &trapcode2;
|
509 *((register_t *)TRAP_TOCBASE) = toc; 510 #endif 511 512 bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize); 513 514#ifdef KDB 515 bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize); 516 bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbsize); 517 bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbsize); 518 bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbsize); 519#else 520 bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize); 521 bcopy(generictrap, (void *)EXC_PGM, (size_t)&trapsize); 522 bcopy(generictrap, (void *)EXC_TRC, (size_t)&trapsize); 523 bcopy(generictrap, (void *)EXC_BPT, (size_t)&trapsize); 524#endif 525 bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&alisize); 526 bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsisize); 527 bcopy(generictrap, (void *)EXC_ISI, (size_t)&trapsize); 528 #ifdef __powerpc64__ 529 bcopy(&slbtrap, (void *)EXC_DSE, (size_t)&slbtrapsize); 530 bcopy(&slbtrap, (void *)EXC_ISE, (size_t)&slbtrapsize); 531 #endif 532 bcopy(generictrap, (void *)EXC_EXI, (size_t)&trapsize); 533 bcopy(generictrap, (void *)EXC_FPU, (size_t)&trapsize); 534 bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize); 535 bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize); 536 bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize); 537 bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize); 538 bcopy(generictrap, (void *)EXC_PERF, (size_t)&trapsize); 539 bcopy(generictrap, (void *)EXC_VECAST_G4, (size_t)&trapsize); 540 bcopy(generictrap, (void *)EXC_VECAST_G5, (size_t)&trapsize); 541 #ifndef __powerpc64__ 542 /* G2-specific TLB miss helper handlers */ 543 bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize); 544 bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize); 545 bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize); 546 #endif 547 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 548 549 /* 550 * Restore MSR 551 */ 552 mtmsr(msr); 553 554 /* Warn if cachline size was not determined */ 555 if (cacheline_warn == 1) { 556 printf("WARNING: cacheline size undetermined, setting to 32\n"); 557 } 558 559 /* 560 * Choose a platform module so we can get the physical memory map. 561 */ 562 563 platform_probe_and_attach(); 564 565 /* 566 * Initialise virtual memory. Use BUS_PROBE_GENERIC priority 567 * in case the platform module had a better idea of what we 568 * should do. 569 */ 570 if (cpu_features & PPC_FEATURE_64) 571 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); 572 else 573 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); 574 575 pmap_bootstrap(startkernel, endkernel); 576 mtmsr(PSL_KERNSET & ~PSL_EE); 577 578 /* 579 * Initialize params/tunables that are derived from memsize 580 */ 581 init_param2(physmem); 582 583 /* 584 * Grab booted kernel's name 585 */ 586 env = kern_getenv("kernelname"); 587 if (env != NULL) { 588 strlcpy(kernelname, env, sizeof(kernelname)); 589 freeenv(env); 590 } 591 592 /* 593 * Finish setting up thread0. 594 */ 595 thread0.td_pcb = (struct pcb *) 596 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - 597 sizeof(struct pcb)) & ~15UL); 598 bzero((void *)thread0.td_pcb, sizeof(struct pcb)); 599 pc->pc_curpcb = thread0.td_pcb; 600 601 /* Initialise the message buffer. */ 602 msgbufinit(msgbufp, msgbufsize); 603 604#ifdef KDB 605 if (boothowto & RB_KDB) 606 kdb_enter(KDB_WHY_BOOTFLAGS, 607 "Boot flags requested debugger"); 608#endif 609 610 return (((uintptr_t)thread0.td_pcb - 611 (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); 612} 613 614void 615bzero(void *buf, size_t len) 616{ 617 caddr_t p; 618 619 p = buf; 620 621 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 622 *p++ = 0; 623 len--; 624 } 625 626 while (len >= sizeof(u_long) * 8) { 627 *(u_long*) p = 0; 628 *((u_long*) p + 1) = 0; 629 *((u_long*) p + 2) = 0; 630 *((u_long*) p + 3) = 0; 631 len -= sizeof(u_long) * 8; 632 *((u_long*) p + 4) = 0; 633 *((u_long*) p + 5) = 0; 634 *((u_long*) p + 6) = 0; 635 *((u_long*) p + 7) = 0; 636 p += sizeof(u_long) * 8; 637 } 638 639 while (len >= sizeof(u_long)) { 640 *(u_long*) p = 0; 641 len -= sizeof(u_long); 642 p += sizeof(u_long); 643 } 644 645 while (len) { 646 *p++ = 0; 647 len--; 648 } 649} 650 651void 652cpu_boot(int howto) 653{ 654} 655 656/* 657 * Flush the D-cache for non-DMA I/O so that the I-cache can 658 * be made coherent later. 659 */ 660void 661cpu_flush_dcache(void *ptr, size_t len) 662{ 663 /* TBD */ 664} 665 666/* 667 * Shutdown the CPU as much as possible. 668 */ 669void 670cpu_halt(void) 671{ 672 673 OF_exit(); 674} 675 676int 677ptrace_set_pc(struct thread *td, unsigned long addr) 678{ 679 struct trapframe *tf; 680 681 tf = td->td_frame; 682 tf->srr0 = (register_t)addr; 683 684 return (0); 685} 686 687int 688ptrace_single_step(struct thread *td) 689{ 690 struct trapframe *tf; 691 692 tf = td->td_frame; 693 tf->srr1 |= PSL_SE; 694 695 return (0); 696} 697 698int 699ptrace_clear_single_step(struct thread *td) 700{ 701 struct trapframe *tf; 702 703 tf = td->td_frame; 704 tf->srr1 &= ~PSL_SE; 705 706 return (0); 707} 708 709void 710kdb_cpu_clear_singlestep(void) 711{ 712 713 kdb_frame->srr1 &= ~PSL_SE; 714} 715 716void 717kdb_cpu_set_singlestep(void) 718{ 719 720 kdb_frame->srr1 |= PSL_SE; 721} 722 723/* 724 * Initialise a struct pcpu. 725 */ 726void 727cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 728{ 729#ifdef __powerpc64__ 730/* Copy the SLB contents from the current CPU */ 731memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb)); 732#endif 733} 734 735void 736spinlock_enter(void) 737{ 738 struct thread *td; 739 register_t msr; 740 741 td = curthread; 742 if (td->td_md.md_spinlock_count == 0) { 743 msr = intr_disable(); 744 td->td_md.md_spinlock_count = 1; 745 td->td_md.md_saved_msr = msr; 746 } else 747 td->td_md.md_spinlock_count++; 748 critical_enter(); 749} 750 751void 752spinlock_exit(void) 753{ 754 struct thread *td; 755 register_t msr; 756 757 td = curthread; 758 critical_exit(); 759 msr = td->td_md.md_saved_msr; 760 td->td_md.md_spinlock_count--; 761 if (td->td_md.md_spinlock_count == 0) 762 intr_restore(msr); 763} 764 765int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ 766 767int 768db_trap_glue(struct trapframe *frame) 769{ 770 if (!(frame->srr1 & PSL_PR) 771 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC 772 || (frame->exc == EXC_PGM 773 && (frame->srr1 & 0x20000)) 774 || frame->exc == EXC_BPT 775 || frame->exc == EXC_DSI)) { 776 int type = frame->exc; 777 778 /* Ignore DTrace traps. */ 779 if (*(uint32_t *)frame->srr0 == EXC_DTRACE) 780 return (0); 781 if (type == EXC_PGM && (frame->srr1 & 0x20000)) { 782 type = T_BREAKPOINT; 783 } 784 return (kdb_trap(type, 0, frame)); 785 } 786 787 return (0); 788} 789 790#ifndef __powerpc64__ 791 792uint64_t 793va_to_vsid(pmap_t pm, vm_offset_t va) 794{ 795 return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); 796} 797 798#endif 799 800vm_offset_t 801pmap_early_io_map(vm_paddr_t pa, vm_size_t size) 802{ 803 804 return (pa); 805} 806 807/* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */ 808void 809flush_disable_caches(void) 810{ 811 register_t msr; 812 register_t msscr0; 813 register_t cache_reg; 814 volatile uint32_t *memp; 815 uint32_t temp; 816 int i; 817 int x; 818 819 msr = mfmsr(); 820 powerpc_sync(); 821 mtmsr(msr & ~(PSL_EE | PSL_DR)); 822 msscr0 = mfspr(SPR_MSSCR0); 823 msscr0 &= ~MSSCR0_L2PFE; 824 mtspr(SPR_MSSCR0, msscr0); 825 powerpc_sync(); 826 isync(); 827 __asm__ __volatile__("dssall; sync"); 828 powerpc_sync(); 829 isync(); 830 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 831 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 832 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 833 834 /* Lock the L1 Data cache. */ 835 mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF); 836 powerpc_sync(); 837 isync(); 838 839 mtspr(SPR_LDSTCR, 0); 840 841 /* 842 * Perform this in two stages: Flush the cache starting in RAM, then do it 843 * from ROM. 844 */ 845 memp = (volatile uint32_t *)0x00000000; 846 for (i = 0; i < 128 * 1024; i++) { 847 temp = *memp; 848 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 849 memp += 32/sizeof(*memp); 850 } 851 852 memp = (volatile uint32_t *)0xfff00000; 853 x = 0xfe; 854 855 for (; x != 0xff;) { 856 mtspr(SPR_LDSTCR, x); 857 for (i = 0; i < 128; i++) { 858 temp = *memp; 859 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 860 memp += 32/sizeof(*memp); 861 } 862 x = ((x << 1) | 1) & 0xff; 863 } 864 mtspr(SPR_LDSTCR, 0); 865 866 cache_reg = mfspr(SPR_L2CR); 867 if (cache_reg & L2CR_L2E) { 868 cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450); 869 mtspr(SPR_L2CR, cache_reg); 870 powerpc_sync(); 871 mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF); 872 while (mfspr(SPR_L2CR) & L2CR_L2HWF) 873 ; /* Busy wait for cache to flush */ 874 powerpc_sync(); 875 cache_reg &= ~L2CR_L2E; 876 mtspr(SPR_L2CR, cache_reg); 877 powerpc_sync(); 878 mtspr(SPR_L2CR, cache_reg | L2CR_L2I); 879 powerpc_sync(); 880 while (mfspr(SPR_L2CR) & L2CR_L2I) 881 ; /* Busy wait for L2 cache invalidate */ 882 powerpc_sync(); 883 } 884 885 cache_reg = mfspr(SPR_L3CR); 886 if (cache_reg & L3CR_L3E) { 887 cache_reg &= ~(L3CR_L3IO | L3CR_L3DO); 888 mtspr(SPR_L3CR, cache_reg); 889 powerpc_sync(); 890 mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF); 891 while (mfspr(SPR_L3CR) & L3CR_L3HWF) 892 ; /* Busy wait for cache to flush */ 893 powerpc_sync(); 894 cache_reg &= ~L3CR_L3E; 895 mtspr(SPR_L3CR, cache_reg); 896 powerpc_sync(); 897 mtspr(SPR_L3CR, cache_reg | L3CR_L3I); 898 powerpc_sync(); 899 while (mfspr(SPR_L3CR) & L3CR_L3I) 900 ; /* Busy wait for L3 cache invalidate */ 901 powerpc_sync(); 902 } 903 904 mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE); 905 powerpc_sync(); 906 isync(); 907 908 mtmsr(msr); 909} 910 911void 912cpu_sleep() 913{ 914 static u_quad_t timebase = 0; 915 static register_t sprgs[4]; 916 static register_t srrs[2]; 917 918 jmp_buf resetjb; 919 struct thread *fputd; 920 struct thread *vectd; 921 register_t hid0; 922 register_t msr; 923 register_t saved_msr; 924 925 ap_pcpu = pcpup; 926 927 PCPU_SET(restore, &resetjb); 928 929 saved_msr = mfmsr(); 930 fputd = PCPU_GET(fputhread); 931 vectd = PCPU_GET(vecthread); 932 if (fputd != NULL) 933 save_fpu(fputd); 934 if (vectd != NULL) 935 save_vec(vectd); 936 if (setjmp(resetjb) == 0) { 937 sprgs[0] = mfspr(SPR_SPRG0); 938 sprgs[1] = mfspr(SPR_SPRG1); 939 sprgs[2] = mfspr(SPR_SPRG2); 940 sprgs[3] = mfspr(SPR_SPRG3); 941 srrs[0] = mfspr(SPR_SRR0); 942 srrs[1] = mfspr(SPR_SRR1); 943 timebase = mftb(); 944 powerpc_sync(); 945 flush_disable_caches(); 946 hid0 = mfspr(SPR_HID0); 947 hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP; 948 powerpc_sync(); 949 isync(); 950 msr = mfmsr() | PSL_POW; 951 mtspr(SPR_HID0, hid0); 952 powerpc_sync(); 953 954 while (1) 955 mtmsr(msr); 956 } 957 mttb(timebase); 958 PCPU_SET(curthread, curthread); 959 PCPU_SET(curpcb, curthread->td_pcb); 960 pmap_activate(curthread); 961 powerpc_sync(); 962 mtspr(SPR_SPRG0, sprgs[0]); 963 mtspr(SPR_SPRG1, sprgs[1]); 964 mtspr(SPR_SPRG2, sprgs[2]); 965 mtspr(SPR_SPRG3, sprgs[3]); 966 mtspr(SPR_SRR0, srrs[0]); 967 mtspr(SPR_SRR1, srrs[1]); 968 mtmsr(saved_msr); 969 if (fputd == curthread) 970 enable_fpu(curthread); 971 if (vectd == curthread) 972 enable_vec(curthread); 973 powerpc_sync(); 974}
| 510 *((register_t *)TRAP_TOCBASE) = toc; 511 #endif 512 513 bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize); 514 515#ifdef KDB 516 bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize); 517 bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbsize); 518 bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbsize); 519 bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbsize); 520#else 521 bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize); 522 bcopy(generictrap, (void *)EXC_PGM, (size_t)&trapsize); 523 bcopy(generictrap, (void *)EXC_TRC, (size_t)&trapsize); 524 bcopy(generictrap, (void *)EXC_BPT, (size_t)&trapsize); 525#endif 526 bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&alisize); 527 bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsisize); 528 bcopy(generictrap, (void *)EXC_ISI, (size_t)&trapsize); 529 #ifdef __powerpc64__ 530 bcopy(&slbtrap, (void *)EXC_DSE, (size_t)&slbtrapsize); 531 bcopy(&slbtrap, (void *)EXC_ISE, (size_t)&slbtrapsize); 532 #endif 533 bcopy(generictrap, (void *)EXC_EXI, (size_t)&trapsize); 534 bcopy(generictrap, (void *)EXC_FPU, (size_t)&trapsize); 535 bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize); 536 bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize); 537 bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize); 538 bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize); 539 bcopy(generictrap, (void *)EXC_PERF, (size_t)&trapsize); 540 bcopy(generictrap, (void *)EXC_VECAST_G4, (size_t)&trapsize); 541 bcopy(generictrap, (void *)EXC_VECAST_G5, (size_t)&trapsize); 542 #ifndef __powerpc64__ 543 /* G2-specific TLB miss helper handlers */ 544 bcopy(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize); 545 bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize); 546 bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize); 547 #endif 548 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 549 550 /* 551 * Restore MSR 552 */ 553 mtmsr(msr); 554 555 /* Warn if cachline size was not determined */ 556 if (cacheline_warn == 1) { 557 printf("WARNING: cacheline size undetermined, setting to 32\n"); 558 } 559 560 /* 561 * Choose a platform module so we can get the physical memory map. 562 */ 563 564 platform_probe_and_attach(); 565 566 /* 567 * Initialise virtual memory. Use BUS_PROBE_GENERIC priority 568 * in case the platform module had a better idea of what we 569 * should do. 570 */ 571 if (cpu_features & PPC_FEATURE_64) 572 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); 573 else 574 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); 575 576 pmap_bootstrap(startkernel, endkernel); 577 mtmsr(PSL_KERNSET & ~PSL_EE); 578 579 /* 580 * Initialize params/tunables that are derived from memsize 581 */ 582 init_param2(physmem); 583 584 /* 585 * Grab booted kernel's name 586 */ 587 env = kern_getenv("kernelname"); 588 if (env != NULL) { 589 strlcpy(kernelname, env, sizeof(kernelname)); 590 freeenv(env); 591 } 592 593 /* 594 * Finish setting up thread0. 595 */ 596 thread0.td_pcb = (struct pcb *) 597 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE - 598 sizeof(struct pcb)) & ~15UL); 599 bzero((void *)thread0.td_pcb, sizeof(struct pcb)); 600 pc->pc_curpcb = thread0.td_pcb; 601 602 /* Initialise the message buffer. */ 603 msgbufinit(msgbufp, msgbufsize); 604 605#ifdef KDB 606 if (boothowto & RB_KDB) 607 kdb_enter(KDB_WHY_BOOTFLAGS, 608 "Boot flags requested debugger"); 609#endif 610 611 return (((uintptr_t)thread0.td_pcb - 612 (sizeof(struct callframe) - 3*sizeof(register_t))) & ~15UL); 613} 614 615void 616bzero(void *buf, size_t len) 617{ 618 caddr_t p; 619 620 p = buf; 621 622 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 623 *p++ = 0; 624 len--; 625 } 626 627 while (len >= sizeof(u_long) * 8) { 628 *(u_long*) p = 0; 629 *((u_long*) p + 1) = 0; 630 *((u_long*) p + 2) = 0; 631 *((u_long*) p + 3) = 0; 632 len -= sizeof(u_long) * 8; 633 *((u_long*) p + 4) = 0; 634 *((u_long*) p + 5) = 0; 635 *((u_long*) p + 6) = 0; 636 *((u_long*) p + 7) = 0; 637 p += sizeof(u_long) * 8; 638 } 639 640 while (len >= sizeof(u_long)) { 641 *(u_long*) p = 0; 642 len -= sizeof(u_long); 643 p += sizeof(u_long); 644 } 645 646 while (len) { 647 *p++ = 0; 648 len--; 649 } 650} 651 652void 653cpu_boot(int howto) 654{ 655} 656 657/* 658 * Flush the D-cache for non-DMA I/O so that the I-cache can 659 * be made coherent later. 660 */ 661void 662cpu_flush_dcache(void *ptr, size_t len) 663{ 664 /* TBD */ 665} 666 667/* 668 * Shutdown the CPU as much as possible. 669 */ 670void 671cpu_halt(void) 672{ 673 674 OF_exit(); 675} 676 677int 678ptrace_set_pc(struct thread *td, unsigned long addr) 679{ 680 struct trapframe *tf; 681 682 tf = td->td_frame; 683 tf->srr0 = (register_t)addr; 684 685 return (0); 686} 687 688int 689ptrace_single_step(struct thread *td) 690{ 691 struct trapframe *tf; 692 693 tf = td->td_frame; 694 tf->srr1 |= PSL_SE; 695 696 return (0); 697} 698 699int 700ptrace_clear_single_step(struct thread *td) 701{ 702 struct trapframe *tf; 703 704 tf = td->td_frame; 705 tf->srr1 &= ~PSL_SE; 706 707 return (0); 708} 709 710void 711kdb_cpu_clear_singlestep(void) 712{ 713 714 kdb_frame->srr1 &= ~PSL_SE; 715} 716 717void 718kdb_cpu_set_singlestep(void) 719{ 720 721 kdb_frame->srr1 |= PSL_SE; 722} 723 724/* 725 * Initialise a struct pcpu. 726 */ 727void 728cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 729{ 730#ifdef __powerpc64__ 731/* Copy the SLB contents from the current CPU */ 732memcpy(pcpu->pc_slb, PCPU_GET(slb), sizeof(pcpu->pc_slb)); 733#endif 734} 735 736void 737spinlock_enter(void) 738{ 739 struct thread *td; 740 register_t msr; 741 742 td = curthread; 743 if (td->td_md.md_spinlock_count == 0) { 744 msr = intr_disable(); 745 td->td_md.md_spinlock_count = 1; 746 td->td_md.md_saved_msr = msr; 747 } else 748 td->td_md.md_spinlock_count++; 749 critical_enter(); 750} 751 752void 753spinlock_exit(void) 754{ 755 struct thread *td; 756 register_t msr; 757 758 td = curthread; 759 critical_exit(); 760 msr = td->td_md.md_saved_msr; 761 td->td_md.md_spinlock_count--; 762 if (td->td_md.md_spinlock_count == 0) 763 intr_restore(msr); 764} 765 766int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ 767 768int 769db_trap_glue(struct trapframe *frame) 770{ 771 if (!(frame->srr1 & PSL_PR) 772 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC 773 || (frame->exc == EXC_PGM 774 && (frame->srr1 & 0x20000)) 775 || frame->exc == EXC_BPT 776 || frame->exc == EXC_DSI)) { 777 int type = frame->exc; 778 779 /* Ignore DTrace traps. */ 780 if (*(uint32_t *)frame->srr0 == EXC_DTRACE) 781 return (0); 782 if (type == EXC_PGM && (frame->srr1 & 0x20000)) { 783 type = T_BREAKPOINT; 784 } 785 return (kdb_trap(type, 0, frame)); 786 } 787 788 return (0); 789} 790 791#ifndef __powerpc64__ 792 793uint64_t 794va_to_vsid(pmap_t pm, vm_offset_t va) 795{ 796 return ((pm->pm_sr[(uintptr_t)va >> ADDR_SR_SHFT]) & SR_VSID_MASK); 797} 798 799#endif 800 801vm_offset_t 802pmap_early_io_map(vm_paddr_t pa, vm_size_t size) 803{ 804 805 return (pa); 806} 807 808/* From p3-53 of the MPC7450 RISC Microprocessor Family Reference Manual */ 809void 810flush_disable_caches(void) 811{ 812 register_t msr; 813 register_t msscr0; 814 register_t cache_reg; 815 volatile uint32_t *memp; 816 uint32_t temp; 817 int i; 818 int x; 819 820 msr = mfmsr(); 821 powerpc_sync(); 822 mtmsr(msr & ~(PSL_EE | PSL_DR)); 823 msscr0 = mfspr(SPR_MSSCR0); 824 msscr0 &= ~MSSCR0_L2PFE; 825 mtspr(SPR_MSSCR0, msscr0); 826 powerpc_sync(); 827 isync(); 828 __asm__ __volatile__("dssall; sync"); 829 powerpc_sync(); 830 isync(); 831 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 832 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 833 __asm__ __volatile__("dcbf 0,%0" :: "r"(0)); 834 835 /* Lock the L1 Data cache. */ 836 mtspr(SPR_LDSTCR, mfspr(SPR_LDSTCR) | 0xFF); 837 powerpc_sync(); 838 isync(); 839 840 mtspr(SPR_LDSTCR, 0); 841 842 /* 843 * Perform this in two stages: Flush the cache starting in RAM, then do it 844 * from ROM. 845 */ 846 memp = (volatile uint32_t *)0x00000000; 847 for (i = 0; i < 128 * 1024; i++) { 848 temp = *memp; 849 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 850 memp += 32/sizeof(*memp); 851 } 852 853 memp = (volatile uint32_t *)0xfff00000; 854 x = 0xfe; 855 856 for (; x != 0xff;) { 857 mtspr(SPR_LDSTCR, x); 858 for (i = 0; i < 128; i++) { 859 temp = *memp; 860 __asm__ __volatile__("dcbf 0,%0" :: "r"(memp)); 861 memp += 32/sizeof(*memp); 862 } 863 x = ((x << 1) | 1) & 0xff; 864 } 865 mtspr(SPR_LDSTCR, 0); 866 867 cache_reg = mfspr(SPR_L2CR); 868 if (cache_reg & L2CR_L2E) { 869 cache_reg &= ~(L2CR_L2IO_7450 | L2CR_L2DO_7450); 870 mtspr(SPR_L2CR, cache_reg); 871 powerpc_sync(); 872 mtspr(SPR_L2CR, cache_reg | L2CR_L2HWF); 873 while (mfspr(SPR_L2CR) & L2CR_L2HWF) 874 ; /* Busy wait for cache to flush */ 875 powerpc_sync(); 876 cache_reg &= ~L2CR_L2E; 877 mtspr(SPR_L2CR, cache_reg); 878 powerpc_sync(); 879 mtspr(SPR_L2CR, cache_reg | L2CR_L2I); 880 powerpc_sync(); 881 while (mfspr(SPR_L2CR) & L2CR_L2I) 882 ; /* Busy wait for L2 cache invalidate */ 883 powerpc_sync(); 884 } 885 886 cache_reg = mfspr(SPR_L3CR); 887 if (cache_reg & L3CR_L3E) { 888 cache_reg &= ~(L3CR_L3IO | L3CR_L3DO); 889 mtspr(SPR_L3CR, cache_reg); 890 powerpc_sync(); 891 mtspr(SPR_L3CR, cache_reg | L3CR_L3HWF); 892 while (mfspr(SPR_L3CR) & L3CR_L3HWF) 893 ; /* Busy wait for cache to flush */ 894 powerpc_sync(); 895 cache_reg &= ~L3CR_L3E; 896 mtspr(SPR_L3CR, cache_reg); 897 powerpc_sync(); 898 mtspr(SPR_L3CR, cache_reg | L3CR_L3I); 899 powerpc_sync(); 900 while (mfspr(SPR_L3CR) & L3CR_L3I) 901 ; /* Busy wait for L3 cache invalidate */ 902 powerpc_sync(); 903 } 904 905 mtspr(SPR_HID0, mfspr(SPR_HID0) & ~HID0_DCE); 906 powerpc_sync(); 907 isync(); 908 909 mtmsr(msr); 910} 911 912void 913cpu_sleep() 914{ 915 static u_quad_t timebase = 0; 916 static register_t sprgs[4]; 917 static register_t srrs[2]; 918 919 jmp_buf resetjb; 920 struct thread *fputd; 921 struct thread *vectd; 922 register_t hid0; 923 register_t msr; 924 register_t saved_msr; 925 926 ap_pcpu = pcpup; 927 928 PCPU_SET(restore, &resetjb); 929 930 saved_msr = mfmsr(); 931 fputd = PCPU_GET(fputhread); 932 vectd = PCPU_GET(vecthread); 933 if (fputd != NULL) 934 save_fpu(fputd); 935 if (vectd != NULL) 936 save_vec(vectd); 937 if (setjmp(resetjb) == 0) { 938 sprgs[0] = mfspr(SPR_SPRG0); 939 sprgs[1] = mfspr(SPR_SPRG1); 940 sprgs[2] = mfspr(SPR_SPRG2); 941 sprgs[3] = mfspr(SPR_SPRG3); 942 srrs[0] = mfspr(SPR_SRR0); 943 srrs[1] = mfspr(SPR_SRR1); 944 timebase = mftb(); 945 powerpc_sync(); 946 flush_disable_caches(); 947 hid0 = mfspr(SPR_HID0); 948 hid0 = (hid0 & ~(HID0_DOZE | HID0_NAP)) | HID0_SLEEP; 949 powerpc_sync(); 950 isync(); 951 msr = mfmsr() | PSL_POW; 952 mtspr(SPR_HID0, hid0); 953 powerpc_sync(); 954 955 while (1) 956 mtmsr(msr); 957 } 958 mttb(timebase); 959 PCPU_SET(curthread, curthread); 960 PCPU_SET(curpcb, curthread->td_pcb); 961 pmap_activate(curthread); 962 powerpc_sync(); 963 mtspr(SPR_SPRG0, sprgs[0]); 964 mtspr(SPR_SPRG1, sprgs[1]); 965 mtspr(SPR_SPRG2, sprgs[2]); 966 mtspr(SPR_SPRG3, sprgs[3]); 967 mtspr(SPR_SRR0, srrs[0]); 968 mtspr(SPR_SRR1, srrs[1]); 969 mtmsr(saved_msr); 970 if (fputd == curthread) 971 enable_fpu(curthread); 972 if (vectd == curthread) 973 enable_vec(curthread); 974 powerpc_sync(); 975}
|