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 176222 2008-02-12 20:55:51Z marcel $");
| 58__FBSDID("$FreeBSD: head/sys/powerpc/aim/machdep.c 176742 2008-03-02 17:05:57Z raj $");
|
59 60#include "opt_compat.h" 61#include "opt_ddb.h" 62#include "opt_kstack_pages.h" 63#include "opt_msgbuf.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/signalvar.h> 88#include <sys/sysctl.h> 89#include <sys/sysent.h> 90#include <sys/sysproto.h> 91#include <sys/ucontext.h> 92#include <sys/uio.h> 93#include <sys/vmmeter.h> 94#include <sys/vnode.h> 95 96#include <net/netisr.h> 97 98#include <vm/vm.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> 105 106#include <machine/bat.h> 107#include <machine/cpu.h> 108#include <machine/elf.h> 109#include <machine/fpu.h>
| 59 60#include "opt_compat.h" 61#include "opt_ddb.h" 62#include "opt_kstack_pages.h" 63#include "opt_msgbuf.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/signalvar.h> 88#include <sys/sysctl.h> 89#include <sys/sysent.h> 90#include <sys/sysproto.h> 91#include <sys/ucontext.h> 92#include <sys/uio.h> 93#include <sys/vmmeter.h> 94#include <sys/vnode.h> 95 96#include <net/netisr.h> 97 98#include <vm/vm.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> 105 106#include <machine/bat.h> 107#include <machine/cpu.h> 108#include <machine/elf.h> 109#include <machine/fpu.h>
|
| 110#include <machine/kdb.h>
|
110#include <machine/md_var.h> 111#include <machine/metadata.h> 112#include <machine/mmuvar.h> 113#include <machine/pcb.h> 114#include <machine/powerpc.h> 115#include <machine/reg.h> 116#include <machine/sigframe.h> 117#include <machine/trap.h> 118#include <machine/vmparam.h> 119 120#include <ddb/ddb.h> 121 122#include <dev/ofw/openfirm.h> 123 124#ifdef DDB 125extern vm_offset_t ksym_start, ksym_end; 126#endif 127 128int cold = 1; 129 130static struct pcpu pcpu0; 131static struct trapframe frame0; 132 133vm_offset_t kstack0; 134vm_offset_t kstack0_phys; 135 136char machine[] = "powerpc"; 137SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 138 139static int cacheline_size = CACHELINESIZE; 140SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 141 CTLFLAG_RD, &cacheline_size, 0, ""); 142 143static void cpu_startup(void *); 144SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 145 146void powerpc_init(u_int, u_int, u_int, void *); 147 148int save_ofw_mapping(void); 149int restore_ofw_mapping(void); 150 151void install_extint(void (*)(void)); 152 153int setfault(faultbuf); /* defined in locore.S */ 154 155static int grab_mcontext(struct thread *, mcontext_t *, int); 156 157void asm_panic(char *); 158 159long Maxmem = 0; 160long realmem = 0; 161 162struct pmap ofw_pmap; 163extern int ofmsr; 164 165struct bat battable[16]; 166 167struct kva_md_info kmi; 168 169void setPQL2(int *const size, int *const ways); 170 171void 172setPQL2(int *const size, int *const ways) 173{ 174 return; 175} 176 177static void 178powerpc_ofw_shutdown(void *junk, int howto) 179{ 180 if (howto & RB_HALT) { 181 OF_halt(); 182 } 183 OF_reboot(); 184} 185 186static void 187cpu_startup(void *dummy) 188{ 189 190 /* 191 * Initialise the decrementer-based clock. 192 */ 193 decr_init(); 194 195 /* 196 * Good {morning,afternoon,evening,night}. 197 */ 198 cpu_setup(PCPU_GET(cpuid)); 199 200 /* startrtclock(); */ 201#ifdef PERFMON 202 perfmon_init(); 203#endif 204 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 205 ptoa(physmem) / 1048576); 206 realmem = physmem; 207 208 /* 209 * Display any holes after the first chunk of extended memory. 210 */ 211 if (bootverbose) { 212 int indx; 213 214 printf("Physical memory chunk(s):\n"); 215 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 216 int size1 = phys_avail[indx + 1] - phys_avail[indx]; 217 218 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", 219 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 220 size1 / PAGE_SIZE); 221 } 222 } 223 224 vm_ksubmap_init(&kmi); 225 226 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 227 ptoa(cnt.v_free_count) / 1048576); 228 229 /* 230 * Set up buffers, so they can be used to read disk labels. 231 */ 232 bufinit(); 233 vm_pager_bufferinit(); 234 235 EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, 236 SHUTDOWN_PRI_LAST); 237} 238 239extern char kernel_text[], _end[]; 240 241extern void *trapcode, *trapsize; 242extern void *alitrap, *alisize; 243extern void *dsitrap, *dsisize; 244extern void *decrint, *decrsize; 245extern void *extint, *extsize; 246extern void *dblow, *dbsize; 247extern void *vectrap, *vectrapsize; 248 249void 250powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) 251{ 252 struct pcpu *pc; 253 vm_offset_t end, off; 254 void *kmdp; 255 char *env; 256 257 end = 0; 258 kmdp = NULL; 259 260 /* 261 * Parse metadata if present and fetch parameters. Must be done 262 * before console is inited so cninit gets the right value of 263 * boothowto. 264 */ 265 if (mdp != NULL) { 266 preload_metadata = mdp; 267 kmdp = preload_search_by_type("elf kernel"); 268 if (kmdp != NULL) { 269 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 270 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 271 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 272#ifdef DDB 273 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 274 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 275#endif 276 } 277 } 278 279 /* 280 * Init params/tunables that can be overridden by the loader 281 */ 282 init_param1(); 283 284 /* 285 * Start initializing proc0 and thread0. 286 */ 287 proc_linkup0(&proc0, &thread0); 288 thread0.td_frame = &frame0; 289 290 /* 291 * Set up per-cpu data. 292 */ 293 pc = &pcpu0; 294 pcpu_init(pc, 0, sizeof(struct pcpu)); 295 pc->pc_curthread = &thread0; 296 pc->pc_curpcb = thread0.td_pcb; 297 pc->pc_cpuid = 0; 298 299 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 300 301 mutex_init(); 302 303 /* 304 * Initialize the console before printing anything. 305 */ 306 cninit(); 307 308 /* 309 * Complain if there is no metadata. 310 */ 311 if (mdp == NULL || kmdp == NULL) { 312 printf("powerpc_init: no loader metadata.\n"); 313 } 314 315 kdb_init(); 316 317 kobj_machdep_init(); 318 319 /* 320 * XXX: Initialize the interrupt tables. 321 * Disable translation in case the vector area 322 * hasn't been mapped (G5) 323 */ 324 mtmsr(mfmsr() & ~(PSL_IR | PSL_DR)); 325 isync(); 326 bcopy(&trapcode, (void *)EXC_RST, (size_t)&trapsize); 327 bcopy(&trapcode, (void *)EXC_MCHK, (size_t)&trapsize); 328 bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize); 329 bcopy(&trapcode, (void *)EXC_ISI, (size_t)&trapsize); 330 bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize); 331 bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize); 332 bcopy(&trapcode, (void *)EXC_PGM, (size_t)&trapsize); 333 bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize); 334 bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize); 335 bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize); 336 bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize); 337 bcopy(&trapcode, (void *)EXC_FPA, (size_t)&trapsize); 338 bcopy(&vectrap, (void *)EXC_VEC, (size_t)&vectrapsize); 339 bcopy(&trapcode, (void *)EXC_VECAST, (size_t)&trapsize); 340 bcopy(&trapcode, (void *)EXC_THRM, (size_t)&trapsize); 341 bcopy(&trapcode, (void *)EXC_BPT, (size_t)&trapsize); 342#ifdef KDB 343 bcopy(&dblow, (void *)EXC_RST, (size_t)&dbsize); 344 bcopy(&dblow, (void *)EXC_MCHK, (size_t)&dbsize); 345 bcopy(&dblow, (void *)EXC_PGM, (size_t)&dbsize); 346 bcopy(&dblow, (void *)EXC_TRC, (size_t)&dbsize); 347 bcopy(&dblow, (void *)EXC_BPT, (size_t)&dbsize); 348#endif 349 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 350 351 /* 352 * Make sure translation has been enabled 353 */ 354 mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI); 355 isync(); 356 357 /* 358 * Initialise virtual memory. 359 */ 360 pmap_mmu_install(MMU_TYPE_OEA, 0); /* XXX temporary */ 361 pmap_bootstrap(startkernel, endkernel); 362 363 /* 364 * Initialize params/tunables that are derived from memsize 365 */ 366 init_param2(physmem); 367 368 /* 369 * Grab booted kernel's name 370 */ 371 env = getenv("kernelname"); 372 if (env != NULL) { 373 strlcpy(kernelname, env, sizeof(kernelname)); 374 freeenv(env); 375 } 376 377 /* 378 * Finish setting up thread0. 379 */ 380 thread0.td_kstack = kstack0; 381 thread0.td_pcb = (struct pcb *) 382 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 383 384 /* 385 * Map and initialise the message buffer. 386 */ 387 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 388 pmap_kenter((vm_offset_t)msgbufp + off, msgbuf_phys + off); 389 msgbufinit(msgbufp, MSGBUF_SIZE); 390 391#ifdef KDB 392 if (boothowto & RB_KDB) 393 kdb_enter(KDB_WHY_BOOTFLAGS, 394 "Boot flags requested debugger"); 395#endif 396} 397 398void 399bzero(void *buf, size_t len) 400{ 401 caddr_t p; 402 403 p = buf; 404 405 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 406 *p++ = 0; 407 len--; 408 } 409 410 while (len >= sizeof(u_long) * 8) { 411 *(u_long*) p = 0; 412 *((u_long*) p + 1) = 0; 413 *((u_long*) p + 2) = 0; 414 *((u_long*) p + 3) = 0; 415 len -= sizeof(u_long) * 8; 416 *((u_long*) p + 4) = 0; 417 *((u_long*) p + 5) = 0; 418 *((u_long*) p + 6) = 0; 419 *((u_long*) p + 7) = 0; 420 p += sizeof(u_long) * 8; 421 } 422 423 while (len >= sizeof(u_long)) { 424 *(u_long*) p = 0; 425 len -= sizeof(u_long); 426 p += sizeof(u_long); 427 } 428 429 while (len) { 430 *p++ = 0; 431 len--; 432 } 433} 434 435void 436sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 437{ 438 struct trapframe *tf; 439 struct sigframe *sfp; 440 struct sigacts *psp; 441 struct sigframe sf; 442 struct thread *td; 443 struct proc *p; 444 int oonstack, rndfsize; 445 int sig; 446 int code; 447 448 td = curthread; 449 p = td->td_proc; 450 PROC_LOCK_ASSERT(p, MA_OWNED); 451 sig = ksi->ksi_signo; 452 code = ksi->ksi_code; 453 psp = p->p_sigacts; 454 mtx_assert(&psp->ps_mtx, MA_OWNED); 455 tf = td->td_frame; 456 oonstack = sigonstack(tf->fixreg[1]); 457 458 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 459 460 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 461 catcher, sig); 462 463 /* 464 * Save user context 465 */ 466 memset(&sf, 0, sizeof(sf)); 467 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 468 sf.sf_uc.uc_sigmask = *mask; 469 sf.sf_uc.uc_stack = td->td_sigstk; 470 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 471 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 472 473 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 474 475 /* 476 * Allocate and validate space for the signal handler context. 477 */ 478 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 479 SIGISMEMBER(psp->ps_sigonstack, sig)) { 480 sfp = (struct sigframe *)(td->td_sigstk.ss_sp + 481 td->td_sigstk.ss_size - rndfsize); 482 } else { 483 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); 484 } 485 486 /* 487 * Translate the signal if appropriate (Linux emu ?) 488 */ 489 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 490 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 491 492 /* 493 * Save the floating-point state, if necessary, then copy it. 494 */ 495 /* XXX */ 496 497 /* 498 * Set up the registers to return to sigcode. 499 * 500 * r1/sp - sigframe ptr 501 * lr - sig function, dispatched to by blrl in trampoline 502 * r3 - sig number 503 * r4 - SIGINFO ? &siginfo : exception code 504 * r5 - user context 505 * srr0 - trampoline function addr 506 */ 507 tf->lr = (register_t)catcher; 508 tf->fixreg[1] = (register_t)sfp; 509 tf->fixreg[FIRSTARG] = sig; 510 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; 511 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 512 /* 513 * Signal handler installed with SA_SIGINFO. 514 */ 515 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si; 516 517 /* 518 * Fill siginfo structure. 519 */ 520 sf.sf_si = ksi->ksi_info; 521 sf.sf_si.si_signo = sig;
| 111#include <machine/md_var.h> 112#include <machine/metadata.h> 113#include <machine/mmuvar.h> 114#include <machine/pcb.h> 115#include <machine/powerpc.h> 116#include <machine/reg.h> 117#include <machine/sigframe.h> 118#include <machine/trap.h> 119#include <machine/vmparam.h> 120 121#include <ddb/ddb.h> 122 123#include <dev/ofw/openfirm.h> 124 125#ifdef DDB 126extern vm_offset_t ksym_start, ksym_end; 127#endif 128 129int cold = 1; 130 131static struct pcpu pcpu0; 132static struct trapframe frame0; 133 134vm_offset_t kstack0; 135vm_offset_t kstack0_phys; 136 137char machine[] = "powerpc"; 138SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 139 140static int cacheline_size = CACHELINESIZE; 141SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size, 142 CTLFLAG_RD, &cacheline_size, 0, ""); 143 144static void cpu_startup(void *); 145SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) 146 147void powerpc_init(u_int, u_int, u_int, void *); 148 149int save_ofw_mapping(void); 150int restore_ofw_mapping(void); 151 152void install_extint(void (*)(void)); 153 154int setfault(faultbuf); /* defined in locore.S */ 155 156static int grab_mcontext(struct thread *, mcontext_t *, int); 157 158void asm_panic(char *); 159 160long Maxmem = 0; 161long realmem = 0; 162 163struct pmap ofw_pmap; 164extern int ofmsr; 165 166struct bat battable[16]; 167 168struct kva_md_info kmi; 169 170void setPQL2(int *const size, int *const ways); 171 172void 173setPQL2(int *const size, int *const ways) 174{ 175 return; 176} 177 178static void 179powerpc_ofw_shutdown(void *junk, int howto) 180{ 181 if (howto & RB_HALT) { 182 OF_halt(); 183 } 184 OF_reboot(); 185} 186 187static void 188cpu_startup(void *dummy) 189{ 190 191 /* 192 * Initialise the decrementer-based clock. 193 */ 194 decr_init(); 195 196 /* 197 * Good {morning,afternoon,evening,night}. 198 */ 199 cpu_setup(PCPU_GET(cpuid)); 200 201 /* startrtclock(); */ 202#ifdef PERFMON 203 perfmon_init(); 204#endif 205 printf("real memory = %ld (%ld MB)\n", ptoa(physmem), 206 ptoa(physmem) / 1048576); 207 realmem = physmem; 208 209 /* 210 * Display any holes after the first chunk of extended memory. 211 */ 212 if (bootverbose) { 213 int indx; 214 215 printf("Physical memory chunk(s):\n"); 216 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) { 217 int size1 = phys_avail[indx + 1] - phys_avail[indx]; 218 219 printf("0x%08x - 0x%08x, %d bytes (%d pages)\n", 220 phys_avail[indx], phys_avail[indx + 1] - 1, size1, 221 size1 / PAGE_SIZE); 222 } 223 } 224 225 vm_ksubmap_init(&kmi); 226 227 printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count), 228 ptoa(cnt.v_free_count) / 1048576); 229 230 /* 231 * Set up buffers, so they can be used to read disk labels. 232 */ 233 bufinit(); 234 vm_pager_bufferinit(); 235 236 EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0, 237 SHUTDOWN_PRI_LAST); 238} 239 240extern char kernel_text[], _end[]; 241 242extern void *trapcode, *trapsize; 243extern void *alitrap, *alisize; 244extern void *dsitrap, *dsisize; 245extern void *decrint, *decrsize; 246extern void *extint, *extsize; 247extern void *dblow, *dbsize; 248extern void *vectrap, *vectrapsize; 249 250void 251powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) 252{ 253 struct pcpu *pc; 254 vm_offset_t end, off; 255 void *kmdp; 256 char *env; 257 258 end = 0; 259 kmdp = NULL; 260 261 /* 262 * Parse metadata if present and fetch parameters. Must be done 263 * before console is inited so cninit gets the right value of 264 * boothowto. 265 */ 266 if (mdp != NULL) { 267 preload_metadata = mdp; 268 kmdp = preload_search_by_type("elf kernel"); 269 if (kmdp != NULL) { 270 boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); 271 kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); 272 end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); 273#ifdef DDB 274 ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); 275 ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); 276#endif 277 } 278 } 279 280 /* 281 * Init params/tunables that can be overridden by the loader 282 */ 283 init_param1(); 284 285 /* 286 * Start initializing proc0 and thread0. 287 */ 288 proc_linkup0(&proc0, &thread0); 289 thread0.td_frame = &frame0; 290 291 /* 292 * Set up per-cpu data. 293 */ 294 pc = &pcpu0; 295 pcpu_init(pc, 0, sizeof(struct pcpu)); 296 pc->pc_curthread = &thread0; 297 pc->pc_curpcb = thread0.td_pcb; 298 pc->pc_cpuid = 0; 299 300 __asm __volatile("mtsprg 0, %0" :: "r"(pc)); 301 302 mutex_init(); 303 304 /* 305 * Initialize the console before printing anything. 306 */ 307 cninit(); 308 309 /* 310 * Complain if there is no metadata. 311 */ 312 if (mdp == NULL || kmdp == NULL) { 313 printf("powerpc_init: no loader metadata.\n"); 314 } 315 316 kdb_init(); 317 318 kobj_machdep_init(); 319 320 /* 321 * XXX: Initialize the interrupt tables. 322 * Disable translation in case the vector area 323 * hasn't been mapped (G5) 324 */ 325 mtmsr(mfmsr() & ~(PSL_IR | PSL_DR)); 326 isync(); 327 bcopy(&trapcode, (void *)EXC_RST, (size_t)&trapsize); 328 bcopy(&trapcode, (void *)EXC_MCHK, (size_t)&trapsize); 329 bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize); 330 bcopy(&trapcode, (void *)EXC_ISI, (size_t)&trapsize); 331 bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize); 332 bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize); 333 bcopy(&trapcode, (void *)EXC_PGM, (size_t)&trapsize); 334 bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize); 335 bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize); 336 bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize); 337 bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize); 338 bcopy(&trapcode, (void *)EXC_FPA, (size_t)&trapsize); 339 bcopy(&vectrap, (void *)EXC_VEC, (size_t)&vectrapsize); 340 bcopy(&trapcode, (void *)EXC_VECAST, (size_t)&trapsize); 341 bcopy(&trapcode, (void *)EXC_THRM, (size_t)&trapsize); 342 bcopy(&trapcode, (void *)EXC_BPT, (size_t)&trapsize); 343#ifdef KDB 344 bcopy(&dblow, (void *)EXC_RST, (size_t)&dbsize); 345 bcopy(&dblow, (void *)EXC_MCHK, (size_t)&dbsize); 346 bcopy(&dblow, (void *)EXC_PGM, (size_t)&dbsize); 347 bcopy(&dblow, (void *)EXC_TRC, (size_t)&dbsize); 348 bcopy(&dblow, (void *)EXC_BPT, (size_t)&dbsize); 349#endif 350 __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD); 351 352 /* 353 * Make sure translation has been enabled 354 */ 355 mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI); 356 isync(); 357 358 /* 359 * Initialise virtual memory. 360 */ 361 pmap_mmu_install(MMU_TYPE_OEA, 0); /* XXX temporary */ 362 pmap_bootstrap(startkernel, endkernel); 363 364 /* 365 * Initialize params/tunables that are derived from memsize 366 */ 367 init_param2(physmem); 368 369 /* 370 * Grab booted kernel's name 371 */ 372 env = getenv("kernelname"); 373 if (env != NULL) { 374 strlcpy(kernelname, env, sizeof(kernelname)); 375 freeenv(env); 376 } 377 378 /* 379 * Finish setting up thread0. 380 */ 381 thread0.td_kstack = kstack0; 382 thread0.td_pcb = (struct pcb *) 383 (thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1; 384 385 /* 386 * Map and initialise the message buffer. 387 */ 388 for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE) 389 pmap_kenter((vm_offset_t)msgbufp + off, msgbuf_phys + off); 390 msgbufinit(msgbufp, MSGBUF_SIZE); 391 392#ifdef KDB 393 if (boothowto & RB_KDB) 394 kdb_enter(KDB_WHY_BOOTFLAGS, 395 "Boot flags requested debugger"); 396#endif 397} 398 399void 400bzero(void *buf, size_t len) 401{ 402 caddr_t p; 403 404 p = buf; 405 406 while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) { 407 *p++ = 0; 408 len--; 409 } 410 411 while (len >= sizeof(u_long) * 8) { 412 *(u_long*) p = 0; 413 *((u_long*) p + 1) = 0; 414 *((u_long*) p + 2) = 0; 415 *((u_long*) p + 3) = 0; 416 len -= sizeof(u_long) * 8; 417 *((u_long*) p + 4) = 0; 418 *((u_long*) p + 5) = 0; 419 *((u_long*) p + 6) = 0; 420 *((u_long*) p + 7) = 0; 421 p += sizeof(u_long) * 8; 422 } 423 424 while (len >= sizeof(u_long)) { 425 *(u_long*) p = 0; 426 len -= sizeof(u_long); 427 p += sizeof(u_long); 428 } 429 430 while (len) { 431 *p++ = 0; 432 len--; 433 } 434} 435 436void 437sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 438{ 439 struct trapframe *tf; 440 struct sigframe *sfp; 441 struct sigacts *psp; 442 struct sigframe sf; 443 struct thread *td; 444 struct proc *p; 445 int oonstack, rndfsize; 446 int sig; 447 int code; 448 449 td = curthread; 450 p = td->td_proc; 451 PROC_LOCK_ASSERT(p, MA_OWNED); 452 sig = ksi->ksi_signo; 453 code = ksi->ksi_code; 454 psp = p->p_sigacts; 455 mtx_assert(&psp->ps_mtx, MA_OWNED); 456 tf = td->td_frame; 457 oonstack = sigonstack(tf->fixreg[1]); 458 459 rndfsize = ((sizeof(sf) + 15) / 16) * 16; 460 461 CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, 462 catcher, sig); 463 464 /* 465 * Save user context 466 */ 467 memset(&sf, 0, sizeof(sf)); 468 grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0); 469 sf.sf_uc.uc_sigmask = *mask; 470 sf.sf_uc.uc_stack = td->td_sigstk; 471 sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) 472 ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE; 473 474 sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 475 476 /* 477 * Allocate and validate space for the signal handler context. 478 */ 479 if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 480 SIGISMEMBER(psp->ps_sigonstack, sig)) { 481 sfp = (struct sigframe *)(td->td_sigstk.ss_sp + 482 td->td_sigstk.ss_size - rndfsize); 483 } else { 484 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize); 485 } 486 487 /* 488 * Translate the signal if appropriate (Linux emu ?) 489 */ 490 if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize) 491 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; 492 493 /* 494 * Save the floating-point state, if necessary, then copy it. 495 */ 496 /* XXX */ 497 498 /* 499 * Set up the registers to return to sigcode. 500 * 501 * r1/sp - sigframe ptr 502 * lr - sig function, dispatched to by blrl in trampoline 503 * r3 - sig number 504 * r4 - SIGINFO ? &siginfo : exception code 505 * r5 - user context 506 * srr0 - trampoline function addr 507 */ 508 tf->lr = (register_t)catcher; 509 tf->fixreg[1] = (register_t)sfp; 510 tf->fixreg[FIRSTARG] = sig; 511 tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc; 512 if (SIGISMEMBER(psp->ps_siginfo, sig)) { 513 /* 514 * Signal handler installed with SA_SIGINFO. 515 */ 516 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si; 517 518 /* 519 * Fill siginfo structure. 520 */ 521 sf.sf_si = ksi->ksi_info; 522 sf.sf_si.si_signo = sig;
|
522 sf.sf_si.si_addr = (void *) ((tf->exc == EXC_DSI) ? 523 tf->dar : tf->srr0);
| 523 sf.sf_si.si_addr = (void *)((tf->exc == EXC_DSI) ? 524 tf->cpu.aim.dar : tf->srr0);
|
524 } else { 525 /* Old FreeBSD-style arguments. */ 526 tf->fixreg[FIRSTARG+1] = code; 527 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ?
| 525 } else { 526 /* Old FreeBSD-style arguments. */ 527 tf->fixreg[FIRSTARG+1] = code; 528 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ?
|
528 tf->dar : tf->srr0;
| 529 tf->cpu.aim.dar : tf->srr0;
|
529 } 530 mtx_unlock(&psp->ps_mtx); 531 PROC_UNLOCK(p); 532 533 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); 534 535 /* 536 * copy the frame out to userland. 537 */ 538 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 539 /* 540 * Process has trashed its stack. Kill it. 541 */ 542 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 543 PROC_LOCK(p); 544 sigexit(td, SIGILL); 545 } 546 547 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, 548 tf->srr0, tf->fixreg[1]); 549 550 PROC_LOCK(p); 551 mtx_lock(&psp->ps_mtx); 552} 553 554int 555sigreturn(struct thread *td, struct sigreturn_args *uap) 556{ 557 struct proc *p; 558 ucontext_t uc; 559 int error; 560 561 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 562 563 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 564 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 565 return (EFAULT); 566 } 567 568 error = set_mcontext(td, &uc.uc_mcontext); 569 if (error != 0) 570 return (error); 571 572 p = td->td_proc; 573 PROC_LOCK(p); 574 td->td_sigmask = uc.uc_sigmask; 575 SIG_CANTMASK(td->td_sigmask); 576 signotify(td); 577 PROC_UNLOCK(p); 578 579 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 580 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 581 582 return (EJUSTRETURN); 583} 584 585#ifdef COMPAT_FREEBSD4 586int 587freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 588{ 589 590 return sigreturn(td, (struct sigreturn_args *)uap); 591} 592#endif 593 594/* 595 * Construct a PCB from a trapframe. This is called from kdb_trap() where 596 * we want to start a backtrace from the function that caused us to enter 597 * the debugger. We have the context in the trapframe, but base the trace 598 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 599 * enough for a backtrace. 600 */ 601void 602makectx(struct trapframe *tf, struct pcb *pcb) 603{ 604 605 pcb->pcb_lr = tf->srr0; 606 pcb->pcb_sp = tf->fixreg[1]; 607} 608 609/* 610 * get_mcontext/sendsig helper routine that doesn't touch the 611 * proc lock 612 */ 613static int 614grab_mcontext(struct thread *td, mcontext_t *mcp, int flags) 615{ 616 struct pcb *pcb; 617 618 pcb = td->td_pcb; 619 620 memset(mcp, 0, sizeof(mcontext_t)); 621 622 mcp->mc_vers = _MC_VERSION; 623 mcp->mc_flags = 0; 624 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe)); 625 if (flags & GET_MC_CLEAR_RET) { 626 mcp->mc_gpr[3] = 0; 627 mcp->mc_gpr[4] = 0; 628 } 629 630 /* 631 * This assumes that floating-point context is *not* lazy, 632 * so if the thread has used FP there would have been a 633 * FP-unavailable exception that would have set things up 634 * correctly. 635 */ 636 if (pcb->pcb_flags & PCB_FPU) { 637 KASSERT(td == curthread, 638 ("get_mcontext: fp save not curthread")); 639 critical_enter(); 640 save_fpu(td); 641 critical_exit(); 642 mcp->mc_flags |= _MC_FP_VALID; 643 memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double)); 644 memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double)); 645 } 646 647 /* XXX Altivec context ? */ 648 649 mcp->mc_len = sizeof(*mcp); 650 651 return (0); 652} 653 654int 655get_mcontext(struct thread *td, mcontext_t *mcp, int flags) 656{ 657 int error; 658 659 error = grab_mcontext(td, mcp, flags); 660 if (error == 0) { 661 PROC_LOCK(curthread->td_proc); 662 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); 663 PROC_UNLOCK(curthread->td_proc); 664 } 665 666 return (error); 667} 668 669int 670set_mcontext(struct thread *td, const mcontext_t *mcp) 671{ 672 struct pcb *pcb; 673 struct trapframe *tf; 674 675 pcb = td->td_pcb; 676 tf = td->td_frame; 677 678 if (mcp->mc_vers != _MC_VERSION || 679 mcp->mc_len != sizeof(*mcp)) 680 return (EINVAL); 681 682 /* 683 * Don't let the user set privileged MSR bits 684 */ 685 if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) { 686 return (EINVAL); 687 } 688 689 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame)); 690 691 if (mcp->mc_flags & _MC_FP_VALID) { 692 if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) { 693 critical_enter(); 694 enable_fpu(td); 695 critical_exit(); 696 } 697 memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double)); 698 memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double)); 699 } 700 701 /* XXX Altivec context? */ 702 703 return (0); 704} 705 706void 707cpu_boot(int howto) 708{ 709} 710 711void 712cpu_initclocks(void) 713{ 714 715 decr_tc_init(); 716} 717 718/* Get current clock frequency for the given cpu id. */ 719int 720cpu_est_clockrate(int cpu_id, uint64_t *rate) 721{ 722 723 return (ENXIO); 724} 725 726/* 727 * Shutdown the CPU as much as possible. 728 */ 729void 730cpu_halt(void) 731{ 732 733 OF_exit(); 734} 735 736void 737cpu_idle(void) 738{ 739 /* TODO: Insert code to halt (until next interrupt) */ 740 741#ifdef INVARIANTS 742 if ((mfmsr() & PSL_EE) != PSL_EE) { 743 struct thread *td = curthread; 744 printf("td msr %x\n", td->td_md.md_saved_msr); 745 panic("ints disabled in idleproc!"); 746 } 747#endif 748} 749 750/* 751 * Set set up registers on exec. 752 */ 753void 754exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 755{ 756 struct trapframe *tf; 757 struct ps_strings arginfo; 758 759 tf = trapframe(td); 760 bzero(tf, sizeof *tf); 761 tf->fixreg[1] = -roundup(-stack + 8, 16); 762 763 /* 764 * XXX Machine-independent code has already copied arguments and 765 * XXX environment to userland. Get them back here. 766 */ 767 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); 768 769 /* 770 * Set up arguments for _start(): 771 * _start(argc, argv, envp, obj, cleanup, ps_strings); 772 * 773 * Notes: 774 * - obj and cleanup are the auxilliary and termination 775 * vectors. They are fixed up by ld.elf_so. 776 * - ps_strings is a NetBSD extention, and will be 777 * ignored by executables which are strictly 778 * compliant with the SVR4 ABI. 779 * 780 * XXX We have to set both regs and retval here due to different 781 * XXX calling convention in trap.c and init_main.c. 782 */ 783 /* 784 * XXX PG: these get overwritten in the syscall return code. 785 * execve() should return EJUSTRETURN, like it does on NetBSD. 786 * Emulate by setting the syscall return value cells. The 787 * registers still have to be set for init's fork trampoline. 788 */ 789 td->td_retval[0] = arginfo.ps_nargvstr; 790 td->td_retval[1] = (register_t)arginfo.ps_argvstr; 791 tf->fixreg[3] = arginfo.ps_nargvstr; 792 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 793 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 794 tf->fixreg[6] = 0; /* auxillary vector */ 795 tf->fixreg[7] = 0; /* termination vector */ 796 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ 797 798 tf->srr0 = entry; 799 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 800 td->td_pcb->pcb_flags = 0; 801} 802 803int 804fill_regs(struct thread *td, struct reg *regs) 805{ 806 struct trapframe *tf; 807 808 tf = td->td_frame; 809 memcpy(regs, tf, sizeof(struct reg)); 810 811 return (0); 812} 813 814int 815fill_dbregs(struct thread *td, struct dbreg *dbregs) 816{ 817 /* No debug registers on PowerPC */ 818 return (ENOSYS); 819} 820 821int 822fill_fpregs(struct thread *td, struct fpreg *fpregs) 823{ 824 struct pcb *pcb; 825 826 pcb = td->td_pcb; 827 828 if ((pcb->pcb_flags & PCB_FPU) == 0) 829 memset(fpregs, 0, sizeof(struct fpreg)); 830 else 831 memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg)); 832 833 return (0); 834} 835 836int 837set_regs(struct thread *td, struct reg *regs) 838{ 839 struct trapframe *tf; 840 841 tf = td->td_frame; 842 memcpy(tf, regs, sizeof(struct reg)); 843 844 return (0); 845} 846 847int 848set_dbregs(struct thread *td, struct dbreg *dbregs) 849{ 850 /* No debug registers on PowerPC */ 851 return (ENOSYS); 852} 853 854int 855set_fpregs(struct thread *td, struct fpreg *fpregs) 856{ 857 struct pcb *pcb; 858 859 pcb = td->td_pcb; 860 if ((pcb->pcb_flags & PCB_FPU) == 0) 861 enable_fpu(td); 862 memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg)); 863 864 return (0); 865} 866 867int 868ptrace_set_pc(struct thread *td, unsigned long addr) 869{ 870 struct trapframe *tf; 871 872 tf = td->td_frame; 873 tf->srr0 = (register_t)addr; 874 875 return (0); 876} 877 878int 879ptrace_single_step(struct thread *td) 880{ 881 struct trapframe *tf; 882 883 tf = td->td_frame; 884 tf->srr1 |= PSL_SE; 885 886 return (0); 887} 888 889int 890ptrace_clear_single_step(struct thread *td) 891{ 892 struct trapframe *tf; 893 894 tf = td->td_frame; 895 tf->srr1 &= ~PSL_SE; 896 897 return (0); 898} 899
| 530 } 531 mtx_unlock(&psp->ps_mtx); 532 PROC_UNLOCK(p); 533 534 tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode)); 535 536 /* 537 * copy the frame out to userland. 538 */ 539 if (copyout(&sf, sfp, sizeof(*sfp)) != 0) { 540 /* 541 * Process has trashed its stack. Kill it. 542 */ 543 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp); 544 PROC_LOCK(p); 545 sigexit(td, SIGILL); 546 } 547 548 CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, 549 tf->srr0, tf->fixreg[1]); 550 551 PROC_LOCK(p); 552 mtx_lock(&psp->ps_mtx); 553} 554 555int 556sigreturn(struct thread *td, struct sigreturn_args *uap) 557{ 558 struct proc *p; 559 ucontext_t uc; 560 int error; 561 562 CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 563 564 if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 565 CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 566 return (EFAULT); 567 } 568 569 error = set_mcontext(td, &uc.uc_mcontext); 570 if (error != 0) 571 return (error); 572 573 p = td->td_proc; 574 PROC_LOCK(p); 575 td->td_sigmask = uc.uc_sigmask; 576 SIG_CANTMASK(td->td_sigmask); 577 signotify(td); 578 PROC_UNLOCK(p); 579 580 CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 581 td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 582 583 return (EJUSTRETURN); 584} 585 586#ifdef COMPAT_FREEBSD4 587int 588freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap) 589{ 590 591 return sigreturn(td, (struct sigreturn_args *)uap); 592} 593#endif 594 595/* 596 * Construct a PCB from a trapframe. This is called from kdb_trap() where 597 * we want to start a backtrace from the function that caused us to enter 598 * the debugger. We have the context in the trapframe, but base the trace 599 * on the PCB. The PCB doesn't have to be perfect, as long as it contains 600 * enough for a backtrace. 601 */ 602void 603makectx(struct trapframe *tf, struct pcb *pcb) 604{ 605 606 pcb->pcb_lr = tf->srr0; 607 pcb->pcb_sp = tf->fixreg[1]; 608} 609 610/* 611 * get_mcontext/sendsig helper routine that doesn't touch the 612 * proc lock 613 */ 614static int 615grab_mcontext(struct thread *td, mcontext_t *mcp, int flags) 616{ 617 struct pcb *pcb; 618 619 pcb = td->td_pcb; 620 621 memset(mcp, 0, sizeof(mcontext_t)); 622 623 mcp->mc_vers = _MC_VERSION; 624 mcp->mc_flags = 0; 625 memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe)); 626 if (flags & GET_MC_CLEAR_RET) { 627 mcp->mc_gpr[3] = 0; 628 mcp->mc_gpr[4] = 0; 629 } 630 631 /* 632 * This assumes that floating-point context is *not* lazy, 633 * so if the thread has used FP there would have been a 634 * FP-unavailable exception that would have set things up 635 * correctly. 636 */ 637 if (pcb->pcb_flags & PCB_FPU) { 638 KASSERT(td == curthread, 639 ("get_mcontext: fp save not curthread")); 640 critical_enter(); 641 save_fpu(td); 642 critical_exit(); 643 mcp->mc_flags |= _MC_FP_VALID; 644 memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double)); 645 memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double)); 646 } 647 648 /* XXX Altivec context ? */ 649 650 mcp->mc_len = sizeof(*mcp); 651 652 return (0); 653} 654 655int 656get_mcontext(struct thread *td, mcontext_t *mcp, int flags) 657{ 658 int error; 659 660 error = grab_mcontext(td, mcp, flags); 661 if (error == 0) { 662 PROC_LOCK(curthread->td_proc); 663 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]); 664 PROC_UNLOCK(curthread->td_proc); 665 } 666 667 return (error); 668} 669 670int 671set_mcontext(struct thread *td, const mcontext_t *mcp) 672{ 673 struct pcb *pcb; 674 struct trapframe *tf; 675 676 pcb = td->td_pcb; 677 tf = td->td_frame; 678 679 if (mcp->mc_vers != _MC_VERSION || 680 mcp->mc_len != sizeof(*mcp)) 681 return (EINVAL); 682 683 /* 684 * Don't let the user set privileged MSR bits 685 */ 686 if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) { 687 return (EINVAL); 688 } 689 690 memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame)); 691 692 if (mcp->mc_flags & _MC_FP_VALID) { 693 if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) { 694 critical_enter(); 695 enable_fpu(td); 696 critical_exit(); 697 } 698 memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double)); 699 memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double)); 700 } 701 702 /* XXX Altivec context? */ 703 704 return (0); 705} 706 707void 708cpu_boot(int howto) 709{ 710} 711 712void 713cpu_initclocks(void) 714{ 715 716 decr_tc_init(); 717} 718 719/* Get current clock frequency for the given cpu id. */ 720int 721cpu_est_clockrate(int cpu_id, uint64_t *rate) 722{ 723 724 return (ENXIO); 725} 726 727/* 728 * Shutdown the CPU as much as possible. 729 */ 730void 731cpu_halt(void) 732{ 733 734 OF_exit(); 735} 736 737void 738cpu_idle(void) 739{ 740 /* TODO: Insert code to halt (until next interrupt) */ 741 742#ifdef INVARIANTS 743 if ((mfmsr() & PSL_EE) != PSL_EE) { 744 struct thread *td = curthread; 745 printf("td msr %x\n", td->td_md.md_saved_msr); 746 panic("ints disabled in idleproc!"); 747 } 748#endif 749} 750 751/* 752 * Set set up registers on exec. 753 */ 754void 755exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings) 756{ 757 struct trapframe *tf; 758 struct ps_strings arginfo; 759 760 tf = trapframe(td); 761 bzero(tf, sizeof *tf); 762 tf->fixreg[1] = -roundup(-stack + 8, 16); 763 764 /* 765 * XXX Machine-independent code has already copied arguments and 766 * XXX environment to userland. Get them back here. 767 */ 768 (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo)); 769 770 /* 771 * Set up arguments for _start(): 772 * _start(argc, argv, envp, obj, cleanup, ps_strings); 773 * 774 * Notes: 775 * - obj and cleanup are the auxilliary and termination 776 * vectors. They are fixed up by ld.elf_so. 777 * - ps_strings is a NetBSD extention, and will be 778 * ignored by executables which are strictly 779 * compliant with the SVR4 ABI. 780 * 781 * XXX We have to set both regs and retval here due to different 782 * XXX calling convention in trap.c and init_main.c. 783 */ 784 /* 785 * XXX PG: these get overwritten in the syscall return code. 786 * execve() should return EJUSTRETURN, like it does on NetBSD. 787 * Emulate by setting the syscall return value cells. The 788 * registers still have to be set for init's fork trampoline. 789 */ 790 td->td_retval[0] = arginfo.ps_nargvstr; 791 td->td_retval[1] = (register_t)arginfo.ps_argvstr; 792 tf->fixreg[3] = arginfo.ps_nargvstr; 793 tf->fixreg[4] = (register_t)arginfo.ps_argvstr; 794 tf->fixreg[5] = (register_t)arginfo.ps_envstr; 795 tf->fixreg[6] = 0; /* auxillary vector */ 796 tf->fixreg[7] = 0; /* termination vector */ 797 tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */ 798 799 tf->srr0 = entry; 800 tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT; 801 td->td_pcb->pcb_flags = 0; 802} 803 804int 805fill_regs(struct thread *td, struct reg *regs) 806{ 807 struct trapframe *tf; 808 809 tf = td->td_frame; 810 memcpy(regs, tf, sizeof(struct reg)); 811 812 return (0); 813} 814 815int 816fill_dbregs(struct thread *td, struct dbreg *dbregs) 817{ 818 /* No debug registers on PowerPC */ 819 return (ENOSYS); 820} 821 822int 823fill_fpregs(struct thread *td, struct fpreg *fpregs) 824{ 825 struct pcb *pcb; 826 827 pcb = td->td_pcb; 828 829 if ((pcb->pcb_flags & PCB_FPU) == 0) 830 memset(fpregs, 0, sizeof(struct fpreg)); 831 else 832 memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg)); 833 834 return (0); 835} 836 837int 838set_regs(struct thread *td, struct reg *regs) 839{ 840 struct trapframe *tf; 841 842 tf = td->td_frame; 843 memcpy(tf, regs, sizeof(struct reg)); 844 845 return (0); 846} 847 848int 849set_dbregs(struct thread *td, struct dbreg *dbregs) 850{ 851 /* No debug registers on PowerPC */ 852 return (ENOSYS); 853} 854 855int 856set_fpregs(struct thread *td, struct fpreg *fpregs) 857{ 858 struct pcb *pcb; 859 860 pcb = td->td_pcb; 861 if ((pcb->pcb_flags & PCB_FPU) == 0) 862 enable_fpu(td); 863 memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg)); 864 865 return (0); 866} 867 868int 869ptrace_set_pc(struct thread *td, unsigned long addr) 870{ 871 struct trapframe *tf; 872 873 tf = td->td_frame; 874 tf->srr0 = (register_t)addr; 875 876 return (0); 877} 878 879int 880ptrace_single_step(struct thread *td) 881{ 882 struct trapframe *tf; 883 884 tf = td->td_frame; 885 tf->srr1 |= PSL_SE; 886 887 return (0); 888} 889 890int 891ptrace_clear_single_step(struct thread *td) 892{ 893 struct trapframe *tf; 894 895 tf = td->td_frame; 896 tf->srr1 &= ~PSL_SE; 897 898 return (0); 899} 900
|
| 901void 902kdb_cpu_clear_singlestep(void) 903{ 904 905 kdb_frame->srr1 &= ~PSL_SE; 906} 907 908void 909kdb_cpu_set_singlestep(void) 910{ 911 912 kdb_frame->srr1 |= PSL_SE; 913} 914
|
900/* 901 * Initialise a struct pcpu. 902 */ 903void 904cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 905{ 906 907} 908 909void 910spinlock_enter(void) 911{ 912 struct thread *td; 913 914 td = curthread; 915 if (td->td_md.md_spinlock_count == 0) 916 td->td_md.md_saved_msr = intr_disable(); 917 td->td_md.md_spinlock_count++; 918 critical_enter(); 919} 920 921void 922spinlock_exit(void) 923{ 924 struct thread *td; 925 926 td = curthread; 927 critical_exit(); 928 td->td_md.md_spinlock_count--; 929 if (td->td_md.md_spinlock_count == 0) 930 intr_restore(td->td_md.md_saved_msr); 931} 932 933/* 934 * kcopy(const void *src, void *dst, size_t len); 935 * 936 * Copy len bytes from src to dst, aborting if we encounter a fatal 937 * page fault. 938 * 939 * kcopy() _must_ save and restore the old fault handler since it is 940 * called by uiomove(), which may be in the path of servicing a non-fatal 941 * page fault. 942 */ 943int 944kcopy(const void *src, void *dst, size_t len) 945{ 946 struct thread *td; 947 faultbuf env, *oldfault; 948 int rv; 949 950 td = PCPU_GET(curthread); 951 oldfault = td->td_pcb->pcb_onfault; 952 if ((rv = setfault(env)) != 0) { 953 td->td_pcb->pcb_onfault = oldfault; 954 return rv; 955 } 956 957 memcpy(dst, src, len); 958 959 td->td_pcb->pcb_onfault = oldfault; 960 return (0); 961} 962 963void 964asm_panic(char *pstr) 965{ 966 panic(pstr); 967} 968 969int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ 970 971int 972db_trap_glue(struct trapframe *frame) 973{ 974 if (!(frame->srr1 & PSL_PR) 975 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC 976 || (frame->exc == EXC_PGM 977 && (frame->srr1 & 0x20000)) 978 || frame->exc == EXC_BPT 979 || frame->exc == EXC_DSI)) { 980 int type = frame->exc; 981 if (type == EXC_PGM && (frame->srr1 & 0x20000)) { 982 type = T_BREAKPOINT; 983 } 984 return (kdb_trap(type, 0, frame)); 985 } 986 987 return (0); 988}
| 915/* 916 * Initialise a struct pcpu. 917 */ 918void 919cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) 920{ 921 922} 923 924void 925spinlock_enter(void) 926{ 927 struct thread *td; 928 929 td = curthread; 930 if (td->td_md.md_spinlock_count == 0) 931 td->td_md.md_saved_msr = intr_disable(); 932 td->td_md.md_spinlock_count++; 933 critical_enter(); 934} 935 936void 937spinlock_exit(void) 938{ 939 struct thread *td; 940 941 td = curthread; 942 critical_exit(); 943 td->td_md.md_spinlock_count--; 944 if (td->td_md.md_spinlock_count == 0) 945 intr_restore(td->td_md.md_saved_msr); 946} 947 948/* 949 * kcopy(const void *src, void *dst, size_t len); 950 * 951 * Copy len bytes from src to dst, aborting if we encounter a fatal 952 * page fault. 953 * 954 * kcopy() _must_ save and restore the old fault handler since it is 955 * called by uiomove(), which may be in the path of servicing a non-fatal 956 * page fault. 957 */ 958int 959kcopy(const void *src, void *dst, size_t len) 960{ 961 struct thread *td; 962 faultbuf env, *oldfault; 963 int rv; 964 965 td = PCPU_GET(curthread); 966 oldfault = td->td_pcb->pcb_onfault; 967 if ((rv = setfault(env)) != 0) { 968 td->td_pcb->pcb_onfault = oldfault; 969 return rv; 970 } 971 972 memcpy(dst, src, len); 973 974 td->td_pcb->pcb_onfault = oldfault; 975 return (0); 976} 977 978void 979asm_panic(char *pstr) 980{ 981 panic(pstr); 982} 983 984int db_trap_glue(struct trapframe *); /* Called from trap_subr.S */ 985 986int 987db_trap_glue(struct trapframe *frame) 988{ 989 if (!(frame->srr1 & PSL_PR) 990 && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC 991 || (frame->exc == EXC_PGM 992 && (frame->srr1 & 0x20000)) 993 || frame->exc == EXC_BPT 994 || frame->exc == EXC_DSI)) { 995 int type = frame->exc; 996 if (type == EXC_PGM && (frame->srr1 & 0x20000)) { 997 type = T_BREAKPOINT; 998 } 999 return (kdb_trap(type, 0, frame)); 1000 } 1001 1002 return (0); 1003}
|