]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/powerpc/aim/machdep.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.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 hw_direct_map = 1;
134
135 struct pcpu __pcpu[MAXCPU];
136
137 static struct trapframe frame0;
138
139 char            machine[] = "powerpc";
140 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
141
142 static void     cpu_startup(void *);
143 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL);
144
145 SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
146            CTLFLAG_RD, &cacheline_size, 0, "");
147
148 u_int           powerpc_init(u_int, u_int, u_int, void *);
149
150 int             save_ofw_mapping(void);
151 int             restore_ofw_mapping(void);
152
153 void            install_extint(void (*)(void));
154
155 int             setfault(faultbuf);             /* defined in locore.S */
156
157 void            asm_panic(char *);
158
159 long            Maxmem = 0;
160 long            realmem = 0;
161
162 struct pmap     ofw_pmap;
163 extern int      ofmsr;
164
165 struct bat      battable[16];
166
167 struct kva_md_info kmi;
168
169 static void
170 cpu_startup(void *dummy)
171 {
172
173         /*
174          * Initialise the decrementer-based clock.
175          */
176         decr_init();
177
178         /*
179          * Good {morning,afternoon,evening,night}.
180          */
181         cpu_setup(PCPU_GET(cpuid));
182
183 #ifdef PERFMON
184         perfmon_init();
185 #endif
186         printf("real memory  = %ld (%ld MB)\n", ptoa(physmem),
187             ptoa(physmem) / 1048576);
188         realmem = physmem;
189
190         if (bootverbose)
191                 printf("available KVA = %zd (%zd MB)\n",
192                     virtual_end - virtual_avail,
193                     (virtual_end - virtual_avail) / 1048576);
194
195         /*
196          * Display any holes after the first chunk of extended memory.
197          */
198         if (bootverbose) {
199                 int indx;
200
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];
204
205                         printf("0x%08x - 0x%08x, %d bytes (%d pages)\n",
206                             phys_avail[indx], phys_avail[indx + 1] - 1, size1,
207                             size1 / PAGE_SIZE);
208                 }
209         }
210
211         vm_ksubmap_init(&kmi);
212
213         printf("avail memory = %ld (%ld MB)\n", ptoa(cnt.v_free_count),
214             ptoa(cnt.v_free_count) / 1048576);
215
216         /*
217          * Set up buffers, so they can be used to read disk labels.
218          */
219         bufinit();
220         vm_pager_bufferinit();
221 }
222
223 extern char     kernel_text[], _end[];
224
225 extern void     *testppc64, *testppc64size;
226 extern void     *restorebridge, *restorebridgesize;
227 extern void     *rfid_patch, *rfi_patch1, *rfi_patch2;
228 #ifdef SMP
229 extern void     *rstcode, *rstsize;
230 #endif
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;
237
238 u_int
239 powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
240 {
241         struct          pcpu *pc;
242         vm_offset_t     end;
243         void            *generictrap;
244         size_t          trap_offset;
245         void            *kmdp;
246         char            *env;
247         uint32_t        msr, scratch;
248         uint8_t         *cache_check;
249         int             ppc64;
250
251         end = 0;
252         kmdp = NULL;
253         trap_offset = 0;
254
255         /*
256          * Parse metadata if present and fetch parameters.  Must be done
257          * before console is inited so cninit gets the right value of
258          * boothowto.
259          */
260         if (mdp != NULL) {
261                 preload_metadata = mdp;
262                 kmdp = preload_search_by_type("elf kernel");
263                 if (kmdp != NULL) {
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);
267 #ifdef DDB
268                         ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
269                         ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
270 #endif
271                 }
272         }
273
274         /*
275          * Init params/tunables that can be overridden by the loader
276          */
277         init_param1();
278
279         /*
280          * Start initializing proc0 and thread0.
281          */
282         proc_linkup0(&proc0, &thread0);
283         thread0.td_frame = &frame0;
284
285         /*
286          * Set up per-cpu data.
287          */
288         pc = __pcpu;
289         pcpu_init(pc, 0, sizeof(struct pcpu));
290         pc->pc_curthread = &thread0;
291         pc->pc_cpuid = 0;
292
293         __asm __volatile("mtsprg 0, %0" :: "r"(pc));
294
295         /*
296          * Init mutexes, which we use heavily in PMAP
297          */
298
299         mutex_init();
300
301         /*
302          * Install the OF client interface
303          */
304
305         OF_bootstrap();
306
307         /*
308          * Initialize the console before printing anything.
309          */
310         cninit();
311
312         /*
313          * Complain if there is no metadata.
314          */
315         if (mdp == NULL || kmdp == NULL) {
316                 printf("powerpc_init: no loader metadata.\n");
317         }
318
319         /*
320          * Init KDB
321          */
322
323         kdb_init();
324
325         /*
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.
329          */
330
331         switch (mfpvr() >> 16) {
332                 case IBM970:
333                 case IBM970FX:
334                 case IBM970MP:
335                 case IBM970GX:
336                         scratch = mfspr64upper(SPR_HID5,msr);
337                         scratch &= ~HID5_970_DCBZ_SIZE_HI;
338                         mtspr64(SPR_HID5, scratch, mfspr(SPR_HID5), msr);
339                         break;
340         }
341
342         /*
343          * Initialize the interrupt tables and figure out our cache line
344          * size and whether or not we need the 64-bit bridge code.
345          */
346
347         /*
348          * Disable translation in case the vector area hasn't been
349          * mapped (G5).
350          */
351
352         msr = mfmsr();
353         mtmsr((msr & ~(PSL_IR | PSL_DR)) | PSL_RI);
354         isync();
355
356         /*
357          * Measure the cacheline size using dcbz
358          *
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.
361          */
362
363         cache_check = (void *)EXC_PGM;
364
365         for (cacheline_size = 0; cacheline_size < 0x100; cacheline_size++)
366                 cache_check[cacheline_size] = 0xff;
367
368         __asm __volatile("dcbz 0,%0":: "r" (cache_check) : "memory");
369
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++);
373
374         /* Work around psim bug */
375         if (cacheline_size == 0) {
376                 printf("WARNING: cacheline size undetermined, setting to 32\n");
377                 cacheline_size = 32;
378         }
379
380         /*
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.
384          */
385
386         ppc64 = 1;
387
388         bcopy(&testppc64, (void *)EXC_PGM,  (size_t)&testppc64size);
389         __syncicache((void *)EXC_PGM, (size_t)&testppc64size);
390
391         __asm __volatile("\
392                 mfmsr %0;       \
393                 mtsprg2 %1;     \
394                                 \
395                 mtmsrd %0;      \
396                 mfsprg2 %1;"
397             : "=r"(scratch), "=r"(ppc64));
398
399         if (ppc64)
400                 cpu_features |= PPC_FEATURE_64;
401
402         /*
403          * Now copy restorebridge into all the handlers, if necessary,
404          * and set up the trap tables.
405          */
406
407         if (cpu_features & PPC_FEATURE_64) {
408                 /* Patch the two instances of rfi -> rfid */
409                 bcopy(&rfid_patch,&rfi_patch1,4);
410         #ifdef KDB
411                 /* rfi_patch2 is at the end of dbleave */
412                 bcopy(&rfid_patch,&rfi_patch2,4);
413         #endif
414
415                 /*
416                  * Copy a code snippet to restore 32-bit bridge mode
417                  * to the top of every non-generic trap handler
418                  */
419
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); 
428
429                 /*
430                  * Set the common trap entry point to the one that
431                  * knows to restore 32-bit operation on execution.
432                  */
433
434                 generictrap = &trapcode64;
435         } else {
436                 generictrap = &trapcode;
437         }
438
439 #ifdef SMP
440         bcopy(&rstcode, (void *)(EXC_RST + trap_offset),  (size_t)&rstsize);
441 #else
442         bcopy(generictrap, (void *)EXC_RST,  (size_t)&trapsize);
443 #endif
444
445 #ifdef KDB
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);
450 #else
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);
455 #endif
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);
468
469         /*
470          * Restore MSR
471          */
472         mtmsr(msr);
473         isync();
474         
475         /*
476          * Choose a platform module so we can get the physical memory map.
477          */
478         
479         platform_probe_and_attach();
480
481         /*
482          * Initialise virtual memory. Use BUS_PROBE_GENERIC priority
483          * in case the platform module had a better idea of what we
484          * should do.
485          */
486         if (cpu_features & PPC_FEATURE_64)
487                 pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
488         else
489                 pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);
490
491         pmap_bootstrap(startkernel, endkernel);
492         mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
493         isync();
494
495         /*
496          * Initialize params/tunables that are derived from memsize
497          */
498         init_param2(physmem);
499
500         /*
501          * Grab booted kernel's name
502          */
503         env = getenv("kernelname");
504         if (env != NULL) {
505                 strlcpy(kernelname, env, sizeof(kernelname));
506                 freeenv(env);
507         }
508
509         /*
510          * Finish setting up thread0.
511          */
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;
517
518         /* Initialise the message buffer. */
519         msgbufinit(msgbufp, MSGBUF_SIZE);
520
521 #ifdef KDB
522         if (boothowto & RB_KDB)
523                 kdb_enter(KDB_WHY_BOOTFLAGS,
524                     "Boot flags requested debugger");
525 #endif
526
527         return (((uintptr_t)thread0.td_pcb - 16) & ~15);
528 }
529
530 void
531 bzero(void *buf, size_t len)
532 {
533         caddr_t p;
534
535         p = buf;
536
537         while (((vm_offset_t) p & (sizeof(u_long) - 1)) && len) {
538                 *p++ = 0;
539                 len--;
540         }
541
542         while (len >= sizeof(u_long) * 8) {
543                 *(u_long*) p = 0;
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;
553         }
554
555         while (len >= sizeof(u_long)) {
556                 *(u_long*) p = 0;
557                 len -= sizeof(u_long);
558                 p += sizeof(u_long);
559         }
560
561         while (len) {
562                 *p++ = 0;
563                 len--;
564         }
565 }
566
567 void
568 cpu_boot(int howto)
569 {
570 }
571
572 /*
573  * Flush the D-cache for non-DMA I/O so that the I-cache can
574  * be made coherent later.
575  */
576 void
577 cpu_flush_dcache(void *ptr, size_t len)
578 {
579         /* TBD */
580 }
581
582 void
583 cpu_initclocks(void)
584 {
585
586         decr_tc_init();
587         stathz = hz;
588         profhz = hz;
589 }
590
591 /*
592  * Shutdown the CPU as much as possible.
593  */
594 void
595 cpu_halt(void)
596 {
597
598         OF_exit();
599 }
600
601 void
602 cpu_idle(int busy)
603 {
604         uint32_t msr;
605         uint16_t vers;
606
607         msr = mfmsr();
608         vers = mfpvr() >> 16;
609
610 #ifdef INVARIANTS
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!");
615         }
616 #endif
617         if (powerpc_pow_enabled) {
618                 switch (vers) {
619                 case IBM970:
620                 case IBM970FX:
621                 case IBM970MP:
622                 case MPC7447A:
623                 case MPC7448:
624                 case MPC7450:
625                 case MPC7455:
626                 case MPC7457:
627                         __asm __volatile("\
628                             dssall; sync; mtmsr %0; isync"
629                             :: "r"(msr | PSL_POW));
630                         break;
631                 default:
632                         powerpc_sync();
633                         mtmsr(msr | PSL_POW);
634                         isync();
635                         break;
636                 }
637         }
638 }
639
640 int
641 cpu_idle_wakeup(int cpu)
642 {
643
644         return (0);
645 }
646
647 int
648 ptrace_set_pc(struct thread *td, unsigned long addr)
649 {
650         struct trapframe *tf;
651
652         tf = td->td_frame;
653         tf->srr0 = (register_t)addr;
654
655         return (0);
656 }
657
658 int
659 ptrace_single_step(struct thread *td)
660 {
661         struct trapframe *tf;
662         
663         tf = td->td_frame;
664         tf->srr1 |= PSL_SE;
665
666         return (0);
667 }
668
669 int
670 ptrace_clear_single_step(struct thread *td)
671 {
672         struct trapframe *tf;
673
674         tf = td->td_frame;
675         tf->srr1 &= ~PSL_SE;
676
677         return (0);
678 }
679
680 void
681 kdb_cpu_clear_singlestep(void)
682 {
683
684         kdb_frame->srr1 &= ~PSL_SE;
685 }
686
687 void
688 kdb_cpu_set_singlestep(void)
689 {
690
691         kdb_frame->srr1 |= PSL_SE;
692 }
693
694 /*
695  * Initialise a struct pcpu.
696  */
697 void
698 cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
699 {
700
701 }
702
703 void
704 spinlock_enter(void)
705 {
706         struct thread *td;
707
708         td = curthread;
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++;
712         critical_enter();
713 }
714
715 void
716 spinlock_exit(void)
717 {
718         struct thread *td;
719
720         td = curthread;
721         critical_exit();
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);
725 }
726
727 /*
728  * kcopy(const void *src, void *dst, size_t len);
729  *
730  * Copy len bytes from src to dst, aborting if we encounter a fatal
731  * page fault.
732  *
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
735  * page fault.
736  */
737 int
738 kcopy(const void *src, void *dst, size_t len)
739 {
740         struct thread   *td;
741         faultbuf        env, *oldfault;
742         int             rv;
743
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;
748                 return rv;
749         }
750
751         memcpy(dst, src, len);
752
753         td->td_pcb->pcb_onfault = oldfault;
754         return (0);
755 }
756
757 void
758 asm_panic(char *pstr)
759 {
760         panic(pstr);
761 }
762
763 int db_trap_glue(struct trapframe *);           /* Called from trap_subr.S */
764
765 int
766 db_trap_glue(struct trapframe *frame)
767 {
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)) {
776                         type = T_BREAKPOINT;
777                 }
778                 return (kdb_trap(type, 0, frame));
779         }
780
781         return (0);
782 }