2 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
3 * Copyright (C) 1995, 1996 TooLs GmbH.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
32 * Copyright (C) 2001 Benno Rice
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
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.
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 $
57 #include <sys/cdefs.h>
58 __FBSDID("$FreeBSD$");
60 #include "opt_compat.h"
62 #include "opt_kstack_pages.h"
63 #include "opt_msgbuf.h"
65 #include <sys/param.h>
67 #include <sys/systm.h>
73 #include <sys/eventhandler.h>
75 #include <sys/imgact.h>
77 #include <sys/kernel.h>
79 #include <sys/linker.h>
81 #include <sys/malloc.h>
83 #include <sys/msgbuf.h>
84 #include <sys/mutex.h>
85 #include <sys/ptrace.h>
86 #include <sys/reboot.h>
87 #include <sys/signalvar.h>
88 #include <sys/sysctl.h>
89 #include <sys/sysent.h>
90 #include <sys/sysproto.h>
91 #include <sys/ucontext.h>
93 #include <sys/vmmeter.h>
94 #include <sys/vnode.h>
96 #include <net/netisr.h>
99 #include <vm/vm_extern.h>
100 #include <vm/vm_kern.h>
101 #include <vm/vm_page.h>
102 #include <vm/vm_map.h>
103 #include <vm/vm_object.h>
104 #include <vm/vm_pager.h>
106 #include <machine/altivec.h>
107 #include <machine/bat.h>
108 #include <machine/cpu.h>
109 #include <machine/elf.h>
110 #include <machine/fpu.h>
111 #include <machine/hid.h>
112 #include <machine/kdb.h>
113 #include <machine/md_var.h>
114 #include <machine/metadata.h>
115 #include <machine/mmuvar.h>
116 #include <machine/pcb.h>
117 #include <machine/reg.h>
118 #include <machine/sigframe.h>
119 #include <machine/spr.h>
120 #include <machine/trap.h>
121 #include <machine/vmparam.h>
125 #include <dev/ofw/openfirm.h>
128 extern vm_offset_t ksym_start, ksym_end;
132 int cacheline_size = 32;
133 int hw_direct_map = 1;
135 struct pcpu __pcpu[MAXCPU];
137 static struct trapframe frame0;
139 char machine[] = "powerpc";
140 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
142 static void cpu_startup(void *);
143 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
145 SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
146 CTLFLAG_RD, &cacheline_size, 0, "");
148 u_int powerpc_init(u_int, u_int, u_int, void *);
150 int save_ofw_mapping(void);
151 int restore_ofw_mapping(void);
153 void install_extint(void (*)(void));
155 int setfault(faultbuf); /* defined in locore.S */
157 void asm_panic(char *);
162 struct pmap ofw_pmap;
165 struct bat battable[16];
167 struct kva_md_info kmi;
170 cpu_startup(void *dummy)
174 * Initialise the decrementer-based clock.
179 * Good {morning,afternoon,evening,night}.
181 cpu_setup(PCPU_GET(cpuid));
186 printf("real memory = %ld (%ld MB)\n", ptoa(physmem),
187 ptoa(physmem) / 1048576);
191 printf("available KVA = %zd (%zd MB)\n",
192 virtual_end - virtual_avail,
193 (virtual_end - virtual_avail) / 1048576);
196 * Display any holes after the first chunk of extended memory.
201 printf("Physical memory chunk(s):\n");
202 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
203 int size1 = phys_avail[indx + 1] - phys_avail[indx];
205 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n",
206 phys_avail[indx], phys_avail[indx + 1] - 1, size1,
211 vm_ksubmap_init(&kmi);
213 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
214 ptoa(cnt.v_free_count) / 1048576);
217 * Set up buffers, so they can be used to read disk labels.
220 vm_pager_bufferinit();
223 extern char kernel_text[], _end[];
225 extern void *testppc64, *testppc64size;
226 extern void *restorebridge, *restorebridgesize;
227 extern void *rfid_patch, *rfi_patch1, *rfi_patch2;
229 extern void *rstcode, *rstsize;
231 extern void *trapcode, *trapcode64, *trapsize;
232 extern void *alitrap, *alisize;
233 extern void *dsitrap, *dsisize;
234 extern void *decrint, *decrsize;
235 extern void *extint, *extsize;
236 extern void *dblow, *dbsize;
239 powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
247 uint32_t msr, scratch;
248 uint8_t *cache_check;
256 * Parse metadata if present and fetch parameters. Must be done
257 * before console is inited so cninit gets the right value of
261 preload_metadata = mdp;
262 kmdp = preload_search_by_type("elf kernel");
264 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
265 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
266 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
268 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
269 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
275 * Init params/tunables that can be overridden by the loader
280 * Start initializing proc0 and thread0.
282 proc_linkup0(&proc0, &thread0);
283 thread0.td_frame = &frame0;
286 * Set up per-cpu data.
289 pcpu_init(pc, 0, sizeof(struct pcpu));
290 pc->pc_curthread = &thread0;
293 __asm __volatile("mtsprg 0, %0" :: "r"(pc));
296 * Init mutexes, which we use heavily in PMAP
302 * Install the OF client interface
308 * Initialize the console before printing anything.
313 * Complain if there is no metadata.
315 if (mdp == NULL || kmdp == NULL) {
316 printf("powerpc_init: no loader metadata.\n");
326 * PowerPC 970 CPUs have a misfeature requested by Apple that makes
327 * them pretend they have a 32-byte cacheline. Turn this off
328 * before we measure the cacheline size.
331 switch (mfpvr() >> 16) {
336 scratch = mfspr64upper(SPR_HID5,msr);
337 scratch &= ~HID5_970_DCBZ_SIZE_HI;
338 mtspr64(SPR_HID5, scratch, mfspr(SPR_HID5), msr);
343 * Initialize the interrupt tables and figure out our cache line
344 * size and whether or not we need the 64-bit bridge code.
348 * Disable translation in case the vector area hasn't been
353 mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI);
357 * Measure the cacheline size using dcbz
359 * Use EXC_PGM as a playground. We are about to overwrite it
360 * anyway, we know it exists, and we know it is cache-aligned.
363 cache_check = (void *)EXC_PGM;
365 for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++)
366 cache_check[cacheline_size] = 0xff;
368 __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory");
370 /* Find the first byte dcbz did not zero to get the cache line size */
371 for (cacheline_size = 0; cacheline_size < 0x100 &&
372 cache_check[cacheline_size] == 0; cacheline_size++);
374 /* Work around psim bug */
375 if (cacheline_size == 0) {
376 printf("WARNING: cacheline size undetermined, setting to 32\n");
381 * Figure out whether we need to use the 64 bit PMAP. This works by
382 * executing an instruction that is only legal on 64-bit PPC (mtmsrd),
383 * and setting ppc64 = 0 if that causes a trap.
388 bcopy(&testppc64, (void *)EXC_PGM, (size_t)&testppc64size);
389 __syncicache((void *)EXC_PGM, (size_t)&testppc64size);
397 : "=r"(scratch), "=r"(ppc64));
400 cpu_features |= PPC_FEATURE_64;
403 * Now copy restorebridge into all the handlers, if necessary,
404 * and set up the trap tables.
407 if (cpu_features & PPC_FEATURE_64) {
408 /* Patch the two instances of rfi -> rfid */
409 bcopy(&rfid_patch,&rfi_patch1,4);
411 /* rfi_patch2 is at the end of dbleave */
412 bcopy(&rfid_patch,&rfi_patch2,4);
416 * Copy a code snippet to restore 32-bit bridge mode
417 * to the top of every non-generic trap handler
420 trap_offset += (size_t)&restorebridgesize;
421 bcopy(&restorebridge, (void *)EXC_RST, trap_offset);
422 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset);
423 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset);
424 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset);
425 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset);
426 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset);
427 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset);
430 * Set the common trap entry point to the one that
431 * knows to restore 32-bit operation on execution.
434 generictrap = &trapcode64;
436 generictrap = &trapcode;
440 bcopy(&rstcode, (void *)(EXC_RST + trap_offset), (size_t)&rstsize);
442 bcopy(generictrap, (void *)EXC_RST, (size_t)&trapsize);
446 bcopy(&dblow, (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize);
447 bcopy(&dblow, (void *)(EXC_PGM + trap_offset), (size_t)&dbsize);
448 bcopy(&dblow, (void *)(EXC_TRC + trap_offset), (size_t)&dbsize);
449 bcopy(&dblow, (void *)(EXC_BPT + trap_offset), (size_t)&dbsize);
451 bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize);
452 bcopy(generictrap, (void *)EXC_PGM, (size_t)&trapsize);
453 bcopy(generictrap, (void *)EXC_TRC, (size_t)&trapsize);
454 bcopy(generictrap, (void *)EXC_BPT, (size_t)&trapsize);
456 bcopy(&dsitrap, (void *)(EXC_DSI + trap_offset), (size_t)&dsisize);
457 bcopy(&alitrap, (void *)(EXC_ALI + trap_offset), (size_t)&alisize);
458 bcopy(generictrap, (void *)EXC_ISI, (size_t)&trapsize);
459 bcopy(generictrap, (void *)EXC_EXI, (size_t)&trapsize);
460 bcopy(generictrap, (void *)EXC_FPU, (size_t)&trapsize);
461 bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize);
462 bcopy(generictrap, (void *)EXC_SC, (size_t)&trapsize);
463 bcopy(generictrap, (void *)EXC_FPA, (size_t)&trapsize);
464 bcopy(generictrap, (void *)EXC_VEC, (size_t)&trapsize);
465 bcopy(generictrap, (void *)EXC_VECAST_G4, (size_t)&trapsize);
466 bcopy(generictrap, (void *)EXC_VECAST_G5, (size_t)&trapsize);
467 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD);
476 * Choose a platform module so we can get the physical memory map.
479 platform_probe_and_attach();
482 * Initialise virtual memory. Use BUS_PROBE_GENERIC priority
483 * in case the platform module had a better idea of what we
486 if (cpu_features & PPC_FEATURE_64)
487 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
489 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);
491 pmap_bootstrap(startkernel, endkernel);
492 mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
496 * Initialize params/tunables that are derived from memsize
498 init_param2(physmem);
501 * Grab booted kernel's name
503 env = getenv("kernelname");
505 strlcpy(kernelname, env, sizeof(kernelname));
510 * Finish setting up thread0.
512 thread0.td_pcb = (struct pcb *)
513 ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
514 sizeof(struct pcb)) & ~15);
515 bzero((void *)thread0.td_pcb, sizeof(struct pcb));
516 pc->pc_curpcb = thread0.td_pcb;
518 /* Initialise the message buffer. */
519 msgbufinit(msgbufp, MSGBUF_SIZE);
522 if (boothowto & RB_KDB)
523 kdb_enter(KDB_WHY_BOOTFLAGS,
524 "Boot flags requested debugger");
527 return (((uintptr_t)thread0.td_pcb - 16) & ~15);
531 bzero(void *buf, size_t len)
537 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
542 while (len >= sizeof(u_long) * 8) {
544 *((u_long*) p + 1) = 0;
545 *((u_long*) p + 2) = 0;
546 *((u_long*) p + 3) = 0;
547 len -= sizeof(u_long) * 8;
548 *((u_long*) p + 4) = 0;
549 *((u_long*) p + 5) = 0;
550 *((u_long*) p + 6) = 0;
551 *((u_long*) p + 7) = 0;
552 p += sizeof(u_long) * 8;
555 while (len >= sizeof(u_long)) {
557 len -= sizeof(u_long);
573 * Flush the D-cache for non-DMA I/O so that the I-cache can
574 * be made coherent later.
577 cpu_flush_dcache(void *ptr, size_t len)
592 * Shutdown the CPU as much as possible.
608 vers = mfpvr() >> 16;
611 if ((msr & PSL_EE) != PSL_EE) {
612 struct thread *td = curthread;
613 printf("td msr %x\n", td->td_md.md_saved_msr);
614 panic("ints disabled in idleproc!");
617 if (powerpc_pow_enabled) {
628 dssall; sync; mtmsr %0; isync"
629 :: "r"(msr | PSL_POW));
633 mtmsr(msr | PSL_POW);
641 cpu_idle_wakeup(int cpu)
648 ptrace_set_pc(struct thread *td, unsigned long addr)
650 struct trapframe *tf;
653 tf->srr0 = (register_t)addr;
659 ptrace_single_step(struct thread *td)
661 struct trapframe *tf;
670 ptrace_clear_single_step(struct thread *td)
672 struct trapframe *tf;
681 kdb_cpu_clear_singlestep(void)
684 kdb_frame->srr1 &= ~PSL_SE;
688 kdb_cpu_set_singlestep(void)
691 kdb_frame->srr1 |= PSL_SE;
695 * Initialise a struct pcpu.
698 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
709 if (td->td_md.md_spinlock_count == 0)
710 td->td_md.md_saved_msr = intr_disable();
711 td->td_md.md_spinlock_count++;
722 td->td_md.md_spinlock_count--;
723 if (td->td_md.md_spinlock_count == 0)
724 intr_restore(td->td_md.md_saved_msr);
728 * kcopy(const void *src, void *dst, size_t len);
730 * Copy len bytes from src to dst, aborting if we encounter a fatal
733 * kcopy() _must_ save and restore the old fault handler since it is
734 * called by uiomove(), which may be in the path of servicing a non-fatal
738 kcopy(const void *src, void *dst, size_t len)
741 faultbuf env, *oldfault;
744 td = PCPU_GET(curthread);
745 oldfault = td->td_pcb->pcb_onfault;
746 if ((rv = setfault(env)) != 0) {
747 td->td_pcb->pcb_onfault = oldfault;
751 memcpy(dst, src, len);
753 td->td_pcb->pcb_onfault = oldfault;
758 asm_panic(char *pstr)
763 int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */
766 db_trap_glue(struct trapframe *frame)
768 if (!(frame->srr1 & PSL_PR)
769 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC
770 || (frame->exc == EXC_PGM
771 && (frame->srr1 & 0x20000))
772 || frame->exc == EXC_BPT
773 || frame->exc == EXC_DSI)) {
774 int type = frame->exc;
775 if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
778 return (kdb_trap(type, 0, frame));