]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - sys/powerpc/aim/machdep.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / sys / powerpc / aim / machdep.c
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$");
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/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>
122
123 #include <ddb/ddb.h>
124
125 #include <dev/ofw/openfirm.h>
126
127 #ifdef DDB
128 extern vm_offset_t ksym_start, ksym_end;
129 #endif
130
131 int cold = 1;
132 int cacheline_size = 32;
133 int ppc64 = 0;
134 int hw_direct_map = 1;
135
136 struct pcpu __pcpu[MAXCPU];
137
138 static struct trapframe frame0;
139
140 char            machine[] = "powerpc";
141 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
142
143 static void     cpu_startup(void *);
144 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
145
146 SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
147            CTLFLAG_RD, &cacheline_size, 0, "");
148
149 u_int           powerpc_init(u_int, u_int, u_int, void *);
150
151 int             save_ofw_mapping(void);
152 int             restore_ofw_mapping(void);
153
154 void            install_extint(void (*)(void));
155
156 int             setfault(faultbuf);             /* defined in locore.S */
157
158 static int      grab_mcontext(struct thread *, mcontext_t *, int);
159
160 void            asm_panic(char *);
161
162 long            Maxmem = 0;
163 long            realmem = 0;
164
165 struct pmap     ofw_pmap;
166 extern int      ofmsr;
167
168 struct bat      battable[16];
169
170 struct kva_md_info kmi;
171
172 static void
173 powerpc_ofw_shutdown(void *junk, int howto)
174 {
175         if (howto & RB_HALT) {
176                 OF_halt();
177         }
178         OF_reboot();
179 }
180
181 static void
182 cpu_startup(void *dummy)
183 {
184
185         /*
186          * Initialise the decrementer-based clock.
187          */
188         decr_init();
189
190         /*
191          * Good {morning,afternoon,evening,night}.
192          */
193         cpu_setup(PCPU_GET(cpuid));
194
195 #ifdef PERFMON
196         perfmon_init();
197 #endif
198         printf("real memory  = %ld (%ld MB)\n", ptoa(physmem),
199             ptoa(physmem) / 1048576);
200         realmem = physmem;
201
202         /*
203          * Display any holes after the first chunk of extended memory.
204          */
205         if (bootverbose) {
206                 int indx;
207
208                 printf("Physical memory chunk(s):\n");
209                 for (indx = 0; phys_avail[indx + 1] != 0; indx += 2) {
210                         int size1 = phys_avail[indx + 1] - phys_avail[indx];
211
212                         printf("0x%08x - 0x%08x, %d bytes (%d pages)\n",
213                             phys_avail[indx], phys_avail[indx + 1] - 1, size1,
214                             size1 / PAGE_SIZE);
215                 }
216         }
217
218         vm_ksubmap_init(&kmi);
219
220         printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
221             ptoa(cnt.v_free_count) / 1048576);
222
223         /*
224          * Set up buffers, so they can be used to read disk labels.
225          */
226         bufinit();
227         vm_pager_bufferinit();
228
229         EVENTHANDLER_REGISTER(shutdown_final, powerpc_ofw_shutdown, 0,
230             SHUTDOWN_PRI_LAST);
231 }
232
233 extern char     kernel_text[], _end[];
234
235 extern void     *testppc64, *testppc64size;
236 extern void     *restorebridge, *restorebridgesize;
237 extern void     *rfid_patch, *rfi_patch1, *rfi_patch2;
238 #ifdef SMP
239 extern void     *rstcode, *rstsize;
240 #endif
241 extern void     *trapcode, *trapcode64, *trapsize;
242 extern void     *alitrap, *alisize;
243 extern void     *dsitrap, *dsisize;
244 extern void     *decrint, *decrsize;
245 extern void     *extint, *extsize;
246 extern void     *dblow, *dbsize;
247
248 u_int
249 powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
250 {
251         struct          pcpu *pc;
252         vm_offset_t     end;
253         void            *generictrap;
254         size_t          trap_offset;
255         void            *kmdp;
256         char            *env;
257         uint32_t        msr, scratch;
258         uint8_t         *cache_check;
259
260         end = 0;
261         kmdp = NULL;
262         trap_offset = 0;
263
264         /*
265          * Parse metadata if present and fetch parameters.  Must be done
266          * before console is inited so cninit gets the right value of
267          * boothowto.
268          */
269         if (mdp != NULL) {
270                 preload_metadata = mdp;
271                 kmdp = preload_search_by_type("elf kernel");
272                 if (kmdp != NULL) {
273                         boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
274                         kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
275                         end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
276 #ifdef DDB
277                         ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
278                         ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
279 #endif
280                 }
281         }
282
283         /*
284          * Init params/tunables that can be overridden by the loader
285          */
286         init_param1();
287
288         /*
289          * Start initializing proc0 and thread0.
290          */
291         proc_linkup0(&proc0, &thread0);
292         thread0.td_frame = &frame0;
293
294         /*
295          * Set up per-cpu data.
296          */
297         pc = __pcpu;
298         pcpu_init(pc, 0, sizeof(struct pcpu));
299         pc->pc_curthread = &thread0;
300         pc->pc_cpuid = 0;
301
302         __asm __volatile("mtsprg 0, %0" :: "r"(pc));
303
304         /*
305          * Init mutexes, which we use heavily in PMAP
306          */
307
308         mutex_init();
309
310         /*
311          * Install the OF client interface
312          */
313
314         OF_bootstrap();
315
316         /*
317          * Initialize the console before printing anything.
318          */
319         cninit();
320
321         /*
322          * Complain if there is no metadata.
323          */
324         if (mdp == NULL || kmdp == NULL) {
325                 printf("powerpc_init: no loader metadata.\n");
326         }
327
328         /*
329          * Init KDB
330          */
331
332         kdb_init();
333
334         /*
335          * PowerPC 970 CPUs have a misfeature requested by Apple that makes
336          * them pretend they have a 32-byte cacheline. Turn this off
337          * before we measure the cacheline size.
338          */
339
340         switch (mfpvr() >> 16) {
341                 case IBM970:
342                 case IBM970FX:
343                 case IBM970MP:
344                 case IBM970GX:
345                         scratch = mfspr64upper(SPR_HID5,msr);
346                         scratch &= ~HID5_970_DCBZ_SIZE_HI;
347                         mtspr64(SPR_HID5, scratch, mfspr(SPR_HID5), msr);
348                         break;
349         }
350
351         /*
352          * Initialize the interrupt tables and figure out our cache line
353          * size and whether or not we need the 64-bit bridge code.
354          */
355
356         /*
357          * Disable translation in case the vector area hasn't been
358          * mapped (G5).
359          */
360
361         msr = mfmsr();
362         mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI);
363         isync();
364
365         /*
366          * Measure the cacheline size using dcbz
367          *
368          * Use EXC_PGM as a playground. We are about to overwrite it
369          * anyway, we know it exists, and we know it is cache-aligned.
370          */
371
372         cache_check = (void *)EXC_PGM;
373
374         for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++)
375                 cache_check[cacheline_size] = 0xff;
376
377         __asm __volatile("dcbz %0,0":: "r" (cache_check) : "memory");
378
379         /* Find the first byte dcbz did not zero to get the cache line size */
380         for (cacheline_size = 0; cacheline_size < 0x100 &&
381             cache_check[cacheline_size] == 0; cacheline_size++);
382
383         /* Work around psim bug */
384         if (cacheline_size == 0) {
385                 printf("WARNING: cacheline size undetermined, setting to 32\n");
386                 cacheline_size = 32;
387         }
388
389         /*
390          * Figure out whether we need to use the 64 bit PMAP. This works by
391          * executing an instruction that is only legal on 64-bit PPC (mtmsrd),
392          * and setting ppc64 = 0 if that causes a trap.
393          */
394
395         ppc64 = 1;
396
397         bcopy(&testppc64, (void *)EXC_PGM,  (size_t)&testppc64size);
398         __syncicache((void *)EXC_PGM, (size_t)&testppc64size);
399
400         __asm __volatile("\
401                 mfmsr %0;       \
402                 mtsprg2 %1;     \
403                                 \
404                 mtmsrd %0;      \
405                 mfsprg2 %1;"
406             : "=r"(scratch), "=r"(ppc64));
407
408         /*
409          * Now copy restorebridge into all the handlers, if necessary,
410          * and set up the trap tables.
411          */
412
413         if (ppc64) {
414                 /* Patch the two instances of rfi -> rfid */
415                 bcopy(&rfid_patch,&rfi_patch1,4);
416         #ifdef KDB
417                 /* rfi_patch2 is at the end of dbleave */
418                 bcopy(&rfid_patch,&rfi_patch2,4);
419         #endif
420
421                 /*
422                  * Copy a code snippet to restore 32-bit bridge mode
423                  * to the top of every non-generic trap handler
424                  */
425
426                 trap_offset += (size_t)&restorebridgesize;
427                 bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 
428                 bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 
429                 bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 
430                 bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 
431                 bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 
432                 bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 
433                 bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 
434
435                 /*
436                  * Set the common trap entry point to the one that
437                  * knows to restore 32-bit operation on execution.
438                  */
439
440                 generictrap = &trapcode64;
441         } else {
442                 generictrap = &trapcode;
443         }
444
445 #ifdef SMP
446         bcopy(&rstcode, (void *)(EXC_RST + trap_offset),  (size_t)&rstsize);
447 #else
448         bcopy(generictrap, (void *)EXC_RST,  (size_t)&trapsize);
449 #endif
450
451 #ifdef KDB
452         bcopy(&dblow,   (void *)(EXC_MCHK + trap_offset), (size_t)&dbsize);
453         bcopy(&dblow,   (void *)(EXC_PGM + trap_offset),  (size_t)&dbsize);
454         bcopy(&dblow,   (void *)(EXC_TRC + trap_offset),  (size_t)&dbsize);
455         bcopy(&dblow,   (void *)(EXC_BPT + trap_offset),  (size_t)&dbsize);
456 #else
457         bcopy(generictrap, (void *)EXC_MCHK, (size_t)&trapsize);
458         bcopy(generictrap, (void *)EXC_PGM,  (size_t)&trapsize);
459         bcopy(generictrap, (void *)EXC_TRC,  (size_t)&trapsize);
460         bcopy(generictrap, (void *)EXC_BPT,  (size_t)&trapsize);
461 #endif
462         bcopy(&dsitrap,  (void *)(EXC_DSI + trap_offset),  (size_t)&dsisize);
463         bcopy(&alitrap,  (void *)(EXC_ALI + trap_offset),  (size_t)&alisize);
464         bcopy(generictrap, (void *)EXC_ISI,  (size_t)&trapsize);
465         bcopy(generictrap, (void *)EXC_EXI,  (size_t)&trapsize);
466         bcopy(generictrap, (void *)EXC_FPU,  (size_t)&trapsize);
467         bcopy(generictrap, (void *)EXC_DECR, (size_t)&trapsize);
468         bcopy(generictrap, (void *)EXC_SC,   (size_t)&trapsize);
469         bcopy(generictrap, (void *)EXC_FPA,  (size_t)&trapsize);
470         bcopy(generictrap, (void *)EXC_VEC,  (size_t)&trapsize);
471         bcopy(generictrap, (void *)EXC_VECAST, (size_t)&trapsize);
472         bcopy(generictrap, (void *)EXC_THRM, (size_t)&trapsize);
473         __syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD);
474
475         /*
476          * Restore MSR
477          */
478         mtmsr(msr);
479         isync();
480         
481         /*
482          * Choose a platform module so we can get the physical memory map.
483          */
484         
485         platform_probe_and_attach();
486
487         /*
488          * Initialise virtual memory. Use BUS_PROBE_GENERIC priority
489          * in case the platform module had a better idea of what we
490          * should do.
491          */
492         if (ppc64)
493                 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
494         else
495                 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);
496
497         pmap_bootstrap(startkernel, endkernel);
498         mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
499         isync();
500
501         /*
502          * Initialize params/tunables that are derived from memsize
503          */
504         init_param2(physmem);
505
506         /*
507          * Grab booted kernel's name
508          */
509         env = getenv("kernelname");
510         if (env != NULL) {
511                 strlcpy(kernelname, env, sizeof(kernelname));
512                 freeenv(env);
513         }
514
515         /*
516          * Finish setting up thread0.
517          */
518         thread0.td_pcb = (struct pcb *)
519             ((thread0.td_kstack + thread0.td_kstack_pages * PAGE_SIZE -
520             sizeof(struct pcb)) & ~15);
521         bzero((void *)thread0.td_pcb, sizeof(struct pcb));
522         pc->pc_curpcb = thread0.td_pcb;
523
524         /* Initialise the message buffer. */
525         msgbufinit(msgbufp, MSGBUF_SIZE);
526
527 #ifdef KDB
528         if (boothowto & RB_KDB)
529                 kdb_enter(KDB_WHY_BOOTFLAGS,
530                     "Boot flags requested debugger");
531 #endif
532
533         return (((uintptr_t)thread0.td_pcb - 16) & ~15);
534 }
535
536 void
537 bzero(void *buf, size_t len)
538 {
539         caddr_t p;
540
541         p = buf;
542
543         while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
544                 *p++ = 0;
545                 len--;
546         }
547
548         while (len >= sizeof(u_long) * 8) {
549                 *(u_long*) p = 0;
550                 *((u_long*) p + 1) = 0;
551                 *((u_long*) p + 2) = 0;
552                 *((u_long*) p + 3) = 0;
553                 len -= sizeof(u_long) * 8;
554                 *((u_long*) p + 4) = 0;
555                 *((u_long*) p + 5) = 0;
556                 *((u_long*) p + 6) = 0;
557                 *((u_long*) p + 7) = 0;
558                 p += sizeof(u_long) * 8;
559         }
560
561         while (len >= sizeof(u_long)) {
562                 *(u_long*) p = 0;
563                 len -= sizeof(u_long);
564                 p += sizeof(u_long);
565         }
566
567         while (len) {
568                 *p++ = 0;
569                 len--;
570         }
571 }
572
573 void
574 sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
575 {
576         struct trapframe *tf;
577         struct sigframe *sfp;
578         struct sigacts *psp;
579         struct sigframe sf;
580         struct thread *td;
581         struct proc *p;
582         int oonstack, rndfsize;
583         int sig;
584         int code;
585
586         td = curthread;
587         p = td->td_proc;
588         PROC_LOCK_ASSERT(p, MA_OWNED);
589         sig = ksi->ksi_signo;
590         code = ksi->ksi_code;
591         psp = p->p_sigacts;
592         mtx_assert(&psp->ps_mtx, MA_OWNED);
593         tf = td->td_frame;
594         oonstack = sigonstack(tf->fixreg[1]);
595
596         rndfsize = ((sizeof(sf) + 15) / 16) * 16;
597
598         CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
599              catcher, sig);
600
601         /*
602          * Save user context
603          */
604         memset(&sf, 0, sizeof(sf));
605         grab_mcontext(td, &sf.sf_uc.uc_mcontext, 0);
606         sf.sf_uc.uc_sigmask = *mask;
607         sf.sf_uc.uc_stack = td->td_sigstk;
608         sf.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
609             ? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
610
611         sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
612
613         /*
614          * Allocate and validate space for the signal handler context.
615          */
616         if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack &&
617             SIGISMEMBER(psp->ps_sigonstack, sig)) {
618                 sfp = (struct sigframe *)(td->td_sigstk.ss_sp +
619                    td->td_sigstk.ss_size - rndfsize);
620         } else {
621                 sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
622         }
623
624         /*
625          * Translate the signal if appropriate (Linux emu ?)
626          */
627         if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
628                 sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
629
630         /*
631          * Save the floating-point state, if necessary, then copy it.
632          */
633         /* XXX */
634
635         /*
636          * Set up the registers to return to sigcode.
637          *
638          *   r1/sp - sigframe ptr
639          *   lr    - sig function, dispatched to by blrl in trampoline
640          *   r3    - sig number
641          *   r4    - SIGINFO ? &siginfo : exception code
642          *   r5    - user context
643          *   srr0  - trampoline function addr
644          */
645         tf->lr = (register_t)catcher;
646         tf->fixreg[1] = (register_t)sfp;
647         tf->fixreg[FIRSTARG] = sig;
648         tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
649         if (SIGISMEMBER(psp->ps_siginfo, sig)) {
650                 /*
651                  * Signal handler installed with SA_SIGINFO.
652                  */
653                 tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
654
655                 /*
656                  * Fill siginfo structure.
657                  */
658                 sf.sf_si = ksi->ksi_info;
659                 sf.sf_si.si_signo = sig;
660                 sf.sf_si.si_addr = (void *)((tf->exc == EXC_DSI) ? 
661                     tf->cpu.aim.dar : tf->srr0);
662         } else {
663                 /* Old FreeBSD-style arguments. */
664                 tf->fixreg[FIRSTARG+1] = code;
665                 tf->fixreg[FIRSTARG+3] = (tf->exc == EXC_DSI) ? 
666                     tf->cpu.aim.dar : tf->srr0;
667         }
668         mtx_unlock(&psp->ps_mtx);
669         PROC_UNLOCK(p);
670
671         tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
672
673         /*
674          * copy the frame out to userland.
675          */
676         if (copyout(&sf, sfp, sizeof(*sfp)) != 0) {
677                 /*
678                  * Process has trashed its stack. Kill it.
679                  */
680                 CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
681                 PROC_LOCK(p);
682                 sigexit(td, SIGILL);
683         }
684
685         CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
686              tf->srr0, tf->fixreg[1]);
687
688         PROC_LOCK(p);
689         mtx_lock(&psp->ps_mtx);
690 }
691
692 int
693 sigreturn(struct thread *td, struct sigreturn_args *uap)
694 {
695         struct proc *p;
696         ucontext_t uc;
697         int error;
698
699         CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
700
701         if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
702                 CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
703                 return (EFAULT);
704         }
705
706         error = set_mcontext(td, &uc.uc_mcontext);
707         if (error != 0)
708                 return (error);
709
710         p = td->td_proc;
711         PROC_LOCK(p);
712         td->td_sigmask = uc.uc_sigmask;
713         SIG_CANTMASK(td->td_sigmask);
714         signotify(td);
715         PROC_UNLOCK(p);
716
717         CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
718              td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]);
719
720         return (EJUSTRETURN);
721 }
722
723 #ifdef COMPAT_FREEBSD4
724 int
725 freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
726 {
727
728         return sigreturn(td, (struct sigreturn_args *)uap);
729 }
730 #endif
731
732 /*
733  * Construct a PCB from a trapframe. This is called from kdb_trap() where
734  * we want to start a backtrace from the function that caused us to enter
735  * the debugger. We have the context in the trapframe, but base the trace
736  * on the PCB. The PCB doesn't have to be perfect, as long as it contains
737  * enough for a backtrace.
738  */
739 void
740 makectx(struct trapframe *tf, struct pcb *pcb)
741 {
742
743         pcb->pcb_lr = tf->srr0;
744         pcb->pcb_sp = tf->fixreg[1];
745 }
746
747 /*
748  * get_mcontext/sendsig helper routine that doesn't touch the
749  * proc lock
750  */
751 static int
752 grab_mcontext(struct thread *td, mcontext_t *mcp, int flags)
753 {
754         struct pcb *pcb;
755
756         pcb = td->td_pcb;
757
758         memset(mcp, 0, sizeof(mcontext_t));
759
760         mcp->mc_vers = _MC_VERSION;
761         mcp->mc_flags = 0;
762         memcpy(&mcp->mc_frame, td->td_frame, sizeof(struct trapframe));
763         if (flags & GET_MC_CLEAR_RET) {
764                 mcp->mc_gpr[3] = 0;
765                 mcp->mc_gpr[4] = 0;
766         }
767
768         /*
769          * This assumes that floating-point context is *not* lazy,
770          * so if the thread has used FP there would have been a
771          * FP-unavailable exception that would have set things up
772          * correctly.
773          */
774         if (pcb->pcb_flags & PCB_FPU) {
775                 KASSERT(td == curthread,
776                         ("get_mcontext: fp save not curthread"));
777                 critical_enter();
778                 save_fpu(td);
779                 critical_exit();
780                 mcp->mc_flags |= _MC_FP_VALID;
781                 memcpy(&mcp->mc_fpscr, &pcb->pcb_fpu.fpscr, sizeof(double));
782                 memcpy(mcp->mc_fpreg, pcb->pcb_fpu.fpr, 32*sizeof(double));
783         }
784
785         /*
786          * Repeat for Altivec context
787          */
788
789         if (pcb->pcb_flags & PCB_VEC) {
790                 KASSERT(td == curthread,
791                         ("get_mcontext: fp save not curthread"));
792                 critical_enter();
793                 save_vec(td);
794                 critical_exit();
795                 mcp->mc_flags |= _MC_AV_VALID;
796                 mcp->mc_vscr  = pcb->pcb_vec.vscr;
797                 mcp->mc_vrsave =  pcb->pcb_vec.vrsave;
798                 memcpy(mcp->mc_avec, pcb->pcb_vec.vr, sizeof(mcp->mc_avec));
799         }
800
801         mcp->mc_len = sizeof(*mcp);
802
803         return (0);
804 }
805
806 int
807 get_mcontext(struct thread *td, mcontext_t *mcp, int flags)
808 {
809         int error;
810
811         error = grab_mcontext(td, mcp, flags);
812         if (error == 0) {
813                 PROC_LOCK(curthread->td_proc);
814                 mcp->mc_onstack = sigonstack(td->td_frame->fixreg[1]);
815                 PROC_UNLOCK(curthread->td_proc);
816         }
817
818         return (error);
819 }
820
821 int
822 set_mcontext(struct thread *td, const mcontext_t *mcp)
823 {
824         struct pcb *pcb;
825         struct trapframe *tf;
826
827         pcb = td->td_pcb;
828         tf = td->td_frame;
829
830         if (mcp->mc_vers != _MC_VERSION ||
831             mcp->mc_len != sizeof(*mcp))
832                 return (EINVAL);
833
834         /*
835          * Don't let the user set privileged MSR bits
836          */
837         if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) {
838                 return (EINVAL);
839         }
840
841         memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
842
843         if (mcp->mc_flags & _MC_FP_VALID) {
844                 if ((pcb->pcb_flags & PCB_FPU) != PCB_FPU) {
845                         critical_enter();
846                         enable_fpu(td);
847                         critical_exit();
848                 }
849                 memcpy(&pcb->pcb_fpu.fpscr, &mcp->mc_fpscr, sizeof(double));
850                 memcpy(pcb->pcb_fpu.fpr, mcp->mc_fpreg, 32*sizeof(double));
851         }
852
853         if (mcp->mc_flags & _MC_AV_VALID) {
854                 if ((pcb->pcb_flags & PCB_VEC) != PCB_VEC) {
855                         critical_enter();
856                         enable_vec(td);
857                         critical_exit();
858                 }
859                 pcb->pcb_vec.vscr = mcp->mc_vscr;
860                 pcb->pcb_vec.vrsave = mcp->mc_vrsave;
861                 memcpy(pcb->pcb_vec.vr, mcp->mc_avec, sizeof(mcp->mc_avec));
862         }
863
864
865         return (0);
866 }
867
868 void
869 cpu_boot(int howto)
870 {
871 }
872
873 /*
874  * Flush the D-cache for non-DMA I/O so that the I-cache can
875  * be made coherent later.
876  */
877 void
878 cpu_flush_dcache(void *ptr, size_t len)
879 {
880         /* TBD */
881 }
882
883 void
884 cpu_initclocks(void)
885 {
886
887         decr_tc_init();
888 }
889
890 /*
891  * Shutdown the CPU as much as possible.
892  */
893 void
894 cpu_halt(void)
895 {
896
897         OF_exit();
898 }
899
900 void
901 cpu_idle(int busy)
902 {
903         uint32_t msr;
904
905         msr = mfmsr();
906
907 #ifdef INVARIANTS
908         if ((msr & PSL_EE) != PSL_EE) {
909                 struct thread *td = curthread;
910                 printf("td msr %x\n", td->td_md.md_saved_msr);
911                 panic("ints disabled in idleproc!");
912         }
913 #endif
914         if (powerpc_pow_enabled) {
915                 powerpc_sync();
916                 mtmsr(msr | PSL_POW);
917                 isync();
918         }
919 }
920
921 int
922 cpu_idle_wakeup(int cpu)
923 {
924
925         return (0);
926 }
927
928 /*
929  * Set set up registers on exec.
930  */
931 void
932 exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
933 {
934         struct trapframe        *tf;
935         struct ps_strings       arginfo;
936
937         tf = trapframe(td);
938         bzero(tf, sizeof *tf);
939         tf->fixreg[1] = -roundup(-stack + 8, 16);
940
941         /*
942          * XXX Machine-independent code has already copied arguments and
943          * XXX environment to userland.  Get them back here.
944          */
945         (void)copyin((char *)PS_STRINGS, &arginfo, sizeof(arginfo));
946
947         /*
948          * Set up arguments for _start():
949          *      _start(argc, argv, envp, obj, cleanup, ps_strings);
950          *
951          * Notes:
952          *      - obj and cleanup are the auxilliary and termination
953          *        vectors.  They are fixed up by ld.elf_so.
954          *      - ps_strings is a NetBSD extention, and will be
955          *        ignored by executables which are strictly
956          *        compliant with the SVR4 ABI.
957          *
958          * XXX We have to set both regs and retval here due to different
959          * XXX calling convention in trap.c and init_main.c.
960          */
961         /*
962          * XXX PG: these get overwritten in the syscall return code.
963          * execve() should return EJUSTRETURN, like it does on NetBSD.
964          * Emulate by setting the syscall return value cells. The
965          * registers still have to be set for init's fork trampoline.
966          */
967         td->td_retval[0] = arginfo.ps_nargvstr;
968         td->td_retval[1] = (register_t)arginfo.ps_argvstr;
969         tf->fixreg[3] = arginfo.ps_nargvstr;
970         tf->fixreg[4] = (register_t)arginfo.ps_argvstr;
971         tf->fixreg[5] = (register_t)arginfo.ps_envstr;
972         tf->fixreg[6] = 0;                      /* auxillary vector */
973         tf->fixreg[7] = 0;                      /* termination vector */
974         tf->fixreg[8] = (register_t)PS_STRINGS; /* NetBSD extension */
975
976         tf->srr0 = entry;
977         tf->srr1 = PSL_MBO | PSL_USERSET | PSL_FE_DFLT;
978         td->td_pcb->pcb_flags = 0;
979 }
980
981 int
982 fill_regs(struct thread *td, struct reg *regs)
983 {
984         struct trapframe *tf;
985
986         tf = td->td_frame;
987         memcpy(regs, tf, sizeof(struct reg));
988
989         return (0);
990 }
991
992 int
993 fill_dbregs(struct thread *td, struct dbreg *dbregs)
994 {
995         /* No debug registers on PowerPC */
996         return (ENOSYS);
997 }
998
999 int
1000 fill_fpregs(struct thread *td, struct fpreg *fpregs)
1001 {
1002         struct pcb *pcb;
1003
1004         pcb = td->td_pcb;
1005
1006         if ((pcb->pcb_flags & PCB_FPU) == 0)
1007                 memset(fpregs, 0, sizeof(struct fpreg));
1008         else
1009                 memcpy(fpregs, &pcb->pcb_fpu, sizeof(struct fpreg));
1010
1011         return (0);
1012 }
1013
1014 int
1015 set_regs(struct thread *td, struct reg *regs)
1016 {
1017         struct trapframe *tf;
1018
1019         tf = td->td_frame;
1020         memcpy(tf, regs, sizeof(struct reg));
1021         
1022         return (0);
1023 }
1024
1025 int
1026 set_dbregs(struct thread *td, struct dbreg *dbregs)
1027 {
1028         /* No debug registers on PowerPC */
1029         return (ENOSYS);
1030 }
1031
1032 int
1033 set_fpregs(struct thread *td, struct fpreg *fpregs)
1034 {
1035         struct pcb *pcb;
1036
1037         pcb = td->td_pcb;
1038         if ((pcb->pcb_flags & PCB_FPU) == 0)
1039                 enable_fpu(td);
1040         memcpy(&pcb->pcb_fpu, fpregs, sizeof(struct fpreg));
1041
1042         return (0);
1043 }
1044
1045 int
1046 ptrace_set_pc(struct thread *td, unsigned long addr)
1047 {
1048         struct trapframe *tf;
1049
1050         tf = td->td_frame;
1051         tf->srr0 = (register_t)addr;
1052
1053         return (0);
1054 }
1055
1056 int
1057 ptrace_single_step(struct thread *td)
1058 {
1059         struct trapframe *tf;
1060         
1061         tf = td->td_frame;
1062         tf->srr1 |= PSL_SE;
1063
1064         return (0);
1065 }
1066
1067 int
1068 ptrace_clear_single_step(struct thread *td)
1069 {
1070         struct trapframe *tf;
1071
1072         tf = td->td_frame;
1073         tf->srr1 &= ~PSL_SE;
1074
1075         return (0);
1076 }
1077
1078 void
1079 kdb_cpu_clear_singlestep(void)
1080 {
1081
1082         kdb_frame->srr1 &= ~PSL_SE;
1083 }
1084
1085 void
1086 kdb_cpu_set_singlestep(void)
1087 {
1088
1089         kdb_frame->srr1 |= PSL_SE;
1090 }
1091
1092 /*
1093  * Initialise a struct pcpu.
1094  */
1095 void
1096 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
1097 {
1098
1099 }
1100
1101 void
1102 spinlock_enter(void)
1103 {
1104         struct thread *td;
1105
1106         td = curthread;
1107         if (td->td_md.md_spinlock_count == 0)
1108                 td->td_md.md_saved_msr = intr_disable();
1109         td->td_md.md_spinlock_count++;
1110         critical_enter();
1111 }
1112
1113 void
1114 spinlock_exit(void)
1115 {
1116         struct thread *td;
1117
1118         td = curthread;
1119         critical_exit();
1120         td->td_md.md_spinlock_count--;
1121         if (td->td_md.md_spinlock_count == 0)
1122                 intr_restore(td->td_md.md_saved_msr);
1123 }
1124
1125 /*
1126  * kcopy(const void *src, void *dst, size_t len);
1127  *
1128  * Copy len bytes from src to dst, aborting if we encounter a fatal
1129  * page fault.
1130  *
1131  * kcopy() _must_ save and restore the old fault handler since it is
1132  * called by uiomove(), which may be in the path of servicing a non-fatal
1133  * page fault.
1134  */
1135 int
1136 kcopy(const void *src, void *dst, size_t len)
1137 {
1138         struct thread   *td;
1139         faultbuf        env, *oldfault;
1140         int             rv;
1141
1142         td = PCPU_GET(curthread);
1143         oldfault = td->td_pcb->pcb_onfault;
1144         if ((rv = setfault(env)) != 0) {
1145                 td->td_pcb->pcb_onfault = oldfault;
1146                 return rv;
1147         }
1148
1149         memcpy(dst, src, len);
1150
1151         td->td_pcb->pcb_onfault = oldfault;
1152         return (0);
1153 }
1154
1155 void
1156 asm_panic(char *pstr)
1157 {
1158         panic(pstr);
1159 }
1160
1161 int db_trap_glue(struct trapframe *);           /* Called from trap_subr.S */
1162
1163 int
1164 db_trap_glue(struct trapframe *frame)
1165 {
1166         if (!(frame->srr1 & PSL_PR)
1167             && (frame->exc == EXC_TRC || frame->exc == EXC_RUNMODETRC
1168                 || (frame->exc == EXC_PGM
1169                     && (frame->srr1 & 0x20000))
1170                 || frame->exc == EXC_BPT
1171                 || frame->exc == EXC_DSI)) {
1172                 int type = frame->exc;
1173                 if (type == EXC_PGM && (frame->srr1 & 0x20000)) {
1174                         type = T_BREAKPOINT;
1175                 }
1176                 return (kdb_trap(type, 0, frame));
1177         }
1178
1179         return (0);
1180 }