PERFORCE change 137794 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sat Mar 15 19:18:25 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=137794
Change 137794 by marcel at marcel_xcllnt on 2008/03/15 19:17:43
Save WIP.
The AP boots up to tracepoint 0x2001.
Enabling IR and DR probably requires that we flush any TLBs
first. I'm sure I should be invalidating the caches too...
Affected files ...
.. //depot/projects/powerpc/sys/powerpc/aim/locore.S#7 edit
.. //depot/projects/powerpc/sys/powerpc/aim/mmu_oea.c#2 edit
.. //depot/projects/powerpc/sys/powerpc/aim/mp_cpudep.c#3 edit
.. //depot/projects/powerpc/sys/powerpc/aim/trap_subr.S#4 edit
.. //depot/projects/powerpc/sys/powerpc/booke/trap_subr.S#2 edit
.. //depot/projects/powerpc/sys/powerpc/include/cpufunc.h#4 edit
.. //depot/projects/powerpc/sys/powerpc/include/smp.h#6 edit
.. //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#18 edit
Differences ...
==== //depot/projects/powerpc/sys/powerpc/aim/locore.S#7 (text+ko) ====
@@ -81,8 +81,9 @@
* Globals
*/
.data
+ .align 4
GLOBAL(tmpstk)
- .space 8208
+ .space 8192
GLOBAL(esym)
.long 0 /* end of symbol table */
@@ -153,7 +154,7 @@
lis 1,tmpstk at ha
addi 1,1,tmpstk at l
- addi 1,1,8192
+ addi 1,1,8192-16
mfmsr 0
lis 9,ofmsr at ha
==== //depot/projects/powerpc/sys/powerpc/aim/mmu_oea.c#2 (text+ko) ====
@@ -147,6 +147,7 @@
#include <machine/md_var.h>
#include <machine/psl.h>
#include <machine/pte.h>
+#include <machine/smp.h>
#include <machine/sr.h>
#include <machine/mmuvar.h>
@@ -203,8 +204,6 @@
extern struct pmap ofw_pmap;
-
-
/*
* Lock for the pteg and pvo tables.
*/
@@ -615,6 +614,59 @@
}
void
+pmap_cpu_bootstrap(volatile uint32_t *trcp, int ap)
+{
+ u_int sdr;
+ int i;
+
+ trcp[0] = 0x1000;
+ trcp[1] = (uint32_t)&pmap_cpu_bootstrap;
+
+ if (ap) {
+ __asm __volatile("mtdbatu 0,%0" :: "r"(battable[0].batu));
+ __asm __volatile("mtdbatl 0,%0" :: "r"(battable[0].batl));
+ isync();
+ __asm __volatile("mtibatu 0,%0" :: "r"(battable[0].batu));
+ __asm __volatile("mtibatl 0,%0" :: "r"(battable[0].batl));
+ isync();
+ }
+
+ trcp[0] = 0x1001;
+
+ for (i = 1; i < 4; i++) {
+ __asm __volatile("mtdbatu %0,%1" :: "n"(i), "r"(0));
+ __asm __volatile("mtibatu %0,%1" :: "n"(i), "r"(0));
+ isync();
+ }
+
+ trcp[0] = 0x1002;
+
+ __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
+ __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
+ isync();
+
+ trcp[0] = 0x1003;
+
+ for (i = 0; i < 16; i++)
+ mtsrin(i << ADDR_SR_SHFT, EMPTY_SEGMENT);
+
+ trcp[0] = 0x1004;
+
+ __asm __volatile("mtsr %0,%1" :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
+ __asm __volatile("mtsr %0,%1" :: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT));
+ __asm __volatile("sync");
+
+ trcp[0] = 0x1005;
+
+ sdr = (u_int)moea_pteg_table | (moea_pteg_mask >> 10);
+ __asm __volatile("mtsdr1 %0" :: "r"(sdr));
+ isync();
+
+ trcp[0] = 0x1006;
+ trcp[1] = sdr;
+}
+
+void
moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
{
ihandle_t mmui;
@@ -622,9 +674,9 @@
int sz;
int i, j;
int ofw_mappings;
+ uint32_t trace;
vm_size_t size, physsz, hwphyssz;
vm_offset_t pa, va, off;
- u_int batl, batu;
/*
* Set up BAT0 to map the lowest 256 MB area
@@ -657,28 +709,15 @@
* Use an IBAT and a DBAT to map the bottom segment of memory
* where we are.
*/
- batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
- batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
__asm (".balign 32; \n"
"mtibatu 0,%0; mtibatl 0,%1; isync; \n"
"mtdbatu 0,%0; mtdbatl 0,%1; isync"
- :: "r"(batu), "r"(batl));
-
-#if 0
- /* map frame buffer */
- batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
- batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
- __asm ("mtdbatu 1,%0; mtdbatl 1,%1; isync"
- :: "r"(batu), "r"(batl));
-#endif
+ :: "r"(battable[0].batu), "r"(battable[0].batl));
-#if 1
/* map pci space */
- batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
- batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
- __asm ("mtdbatu 1,%0; mtdbatl 1,%1; isync"
- :: "r"(batu), "r"(batl));
-#endif
+ __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
+ __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
+ isync();
/*
* Set the start and end of kva.
@@ -901,20 +940,8 @@
msgbufp = (struct msgbuf *)virtual_avail;
virtual_avail += round_page(MSGBUF_SIZE);
- /*
- * Initialize hardware.
- */
- for (i = 0; i < 16; i++) {
- mtsrin(i << ADDR_SR_SHFT, EMPTY_SEGMENT);
- }
- __asm __volatile ("mtsr %0,%1"
- :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
- __asm __volatile ("mtsr %0,%1"
- :: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT));
- __asm __volatile ("sync; mtsdr1 %0; isync"
- :: "r"((u_int)moea_pteg_table | (moea_pteg_mask >> 10)));
+ pmap_cpu_bootstrap(&trace, 0);
tlbia();
-
pmap_bootstrapped++;
}
==== //depot/projects/powerpc/sys/powerpc/aim/mp_cpudep.c#3 (text+ko) ====
@@ -32,11 +32,14 @@
#include <sys/kernel.h>
#include <sys/bus.h>
#include <sys/pcpu.h>
+#include <sys/proc.h>
#include <sys/smp.h>
+#include <machine/bat.h>
#include <machine/bus.h>
#include <machine/cpu.h>
#include <machine/intr_machdep.h>
+#include <machine/pcb.h>
#include <machine/smp.h>
#include <machine/trap_aim.h>
@@ -45,6 +48,8 @@
extern void *rstcode;
+void *ap_pcpu;
+
static int
powerpc_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu)
{
@@ -130,33 +135,68 @@
return (powerpc_smp_fill_cpuref(cpuref, bsp));
}
+#if 0
static void
dump_rstvec(void)
{
uint32_t buf[6];
- mtmsr(mfmsr() & ~(PSL_IR | PSL_DR));
- isync();
bcopy((void *)EXC_RST, buf, sizeof(buf));
- mtmsr(mfmsr() | PSL_IR | PSL_DR);
-
printf("XXX: %08x %08x %08x %08x %08x %08x\n", buf[0], buf[1], buf[2],
buf[3], buf[4], buf[5]);
}
+#endif
+
+uint32_t
+cpudep_ap_bootstrap(volatile uint32_t *trcp)
+{
+ uint32_t sp;
+
+ trcp[0] = 0x2000;
+ trcp[1] = (uint32_t)&cpudep_ap_bootstrap;
+ __asm __volatile("mtsprg 0, %0" :: "r"(ap_pcpu));
+ __asm __volatile("sync");
+
+ trcp[0] = 0x2001;
+ trcp[1] = (uint32_t)pcpup;
+
+ mtmsr(PSL_IR | PSL_DR | PSL_ME);
+ isync();
+
+ trcp[0] = 0x2002;
+ trcp[1] = 0;
+
+ pcpup->pc_curthread = pcpup->pc_idlethread;
+ pcpup->pc_curtcb = pcpup->pc_curthread->td_pcb;
+ sp = pcpup->pc_curpcb->pcb_sp;
+
+ trcp[0] = 0x2003;
+ trcp[1] = sp;
+
+ breakpoint();
+
+ return (sp);
+}
+
int
powerpc_smp_start_cpu(struct pcpu *pc)
{
phandle_t cpu;
+ volatile uint32_t *trcp;
volatile uint8_t *rstvec;
- int res, reset;
+ uint32_t trace;
+ int res, reset, timeout;
cpu = pc->pc_hwref;
res = OF_getprop(cpu, "soft-reset", &reset, sizeof(reset));
if (res < 0)
return (ENXIO);
- dump_rstvec();
+ trcp = (uint32_t *)(EXC_RST + 4);
+ trace = *trcp;
+
+ ap_pcpu = pc;
rstvec = (uint8_t *)(0x80000000 + reset);
@@ -166,9 +206,12 @@
*rstvec = 0;
__asm __volatile("sync");
- DELAY(1000);
+ timeout = 1000;
+ while (!pc->pc_awake && timeout--)
+ DELAY(100);
- dump_rstvec();
+ if (!pc->pc_awake)
+ printf("XXX: timeout (trace=%x; data=%x)\n", trcp[0], trcp[1]);
return (0);
}
==== //depot/projects/powerpc/sys/powerpc/aim/trap_subr.S#4 (text+ko) ====
@@ -233,35 +233,72 @@
* Define the kdb debugger stack
*/
.data
+ .align 4
GLOBAL(dbstk)
- .space INTSTK+8 /* kdb stack */
+ .space INTSTK+8 /* kdb stack */
#endif
+ .text
+
/*
- * This code gets copied to all the trap vectors
- * (except ISI/DSI, ALI, and the interrupts)
+ * Processor reset exception handler. These are typically
+ * the first instructions the processor executes after a
+ * software reset.
*/
- .text
-
.globl CNAME(rstcode), CNAME(rstsize)
CNAME(rstcode):
bl 1f
- .long 0
+ /* We use this space for tracing purposes. */
.long 0
.long 0
- .long 0
1:
- mflr %r3
- stw %r3, 0(%r3)
- stw %r1, 4(%r3)
- stw %r2, 8(%r3)
- mfmsr %r4
- stw %r4, 12(%r3)
-9: b 9b
+ mflr %r2
+ mfmsr %r3
+ stw %r2,0(%r2) /* trace: 0x104 - we're here. */
+ stw %r3,4(%r2) /* trace data: MSR */
+ sync
+
+ lis %r1,(dbstk+INTSTK)@ha
+ addi %r1,%r1,(dbstk+INTSTK)@l
+
+ addi %r3,%r2,4
+ stw %r3,0(%r1)
+ sync
+ stw %r3,0(%r2) /* trace: 0x108 - stack is writable */
+ stw %r1,4(%r2) /* trace data: SP */
+ sync
+
+ mr %r3,%r2
+ lis %r4,1 at l
+ bla CNAME(pmap_cpu_bootstrap)
+
+ addi %r3,%r2,8
+ stw %r3,0(%r2) /* trace 0x10c - back from 1st call */
+ sync
+
+ mr %r3,%r2
+ bla CNAME(cpudep_ap_bootstrap)
+ mr %r1,%r3
+
+ addi %r3,%r2,12
+ stw %r3,0(%r2) /* trace 0x110 - back from 2nd call */
+ stw %r1,4(%r2) /* trace data: SP */
+
+ mr %r3,%r2
+ bla CNAME(machdep_ap_bootstrap)
+
+ /* Should not be reached */
+9:
+ b 9b
CNAME(rstsize) = . - CNAME(rstcode)
+/*
+ * This code gets copied to all the trap vectors
+ * (except ISI/DSI, ALI, and the interrupts)
+ */
+
.globl CNAME(trapcode),CNAME(trapsize)
CNAME(trapcode):
mtsprg1 %r1 /* save SP */
@@ -477,8 +514,8 @@
/*
* Deliberate entry to dbtrap
*/
- .globl CNAME(ppc_db_trap)
-CNAME(ppc_db_trap):
+ .globl CNAME(breakpoint)
+CNAME(breakpoint):
mtsprg1 %r1
mfmsr %r3
mtsrr1 %r3
==== //depot/projects/powerpc/sys/powerpc/booke/trap_subr.S#2 (text+ko) ====
@@ -795,8 +795,8 @@
/*
* Deliberate entry to dbtrap
*/
- .globl CNAME(ppc_db_trap)
-CNAME(ppc_db_trap):
+ .globl CNAME(breakpoint)
+CNAME(breakpoint):
mtsprg1 %r1
mfmsr %r3
mtsrr1 %r3
==== //depot/projects/powerpc/sys/powerpc/include/cpufunc.h#4 (text+ko) ====
@@ -48,16 +48,8 @@
struct thread;
#ifdef KDB
-void ppc_db_trap(void);
-#endif
-
-static __inline void
-breakpoint(void)
-{
-#ifdef KDB
- ppc_db_trap();
+void breakpoint(void);
#endif
-}
/* CPU register mangling inlines */
==== //depot/projects/powerpc/sys/powerpc/include/smp.h#6 (text+ko) ====
@@ -55,6 +55,10 @@
int powerpc_smp_next_cpu(struct cpuref *);
int powerpc_smp_start_cpu(struct pcpu *);
+void pmap_cpu_bootstrap(volatile uint32_t *, int);
+uint32_t cpudep_ap_bootstrap(volatile uint32_t *);
+void machdep_ap_bootstrap(volatile uint32_t *);
+
#endif /* !LOCORE */
#endif /* _KERNEL */
#endif /* !_MACHINE_SMP_H */
==== //depot/projects/powerpc/sys/powerpc/powerpc/mp_machdep.c#18 (text+ko) ====
@@ -49,6 +49,23 @@
int mp_ipi_test = 0;
+void
+machdep_ap_bootstrap(volatile uint32_t *trcp)
+{
+
+ trcp[0] = 0x3000;
+ trcp[1] = (uint32_t)&machdep_ap_bootstrap;
+
+ pcpup->pc_awake = 1;
+
+ while (ap_spin)
+ DELAY(0);
+
+ ap_awake++;
+
+ while (1);
+}
+
struct cpu_group *
cpu_topo(void)
{
@@ -159,6 +176,8 @@
return;
}
+ ap_spin = 1;
+
cpus = 0;
smp_cpus = 0;
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
@@ -217,9 +236,7 @@
break;
case IPI_STOP:
self = PCPU_GET(cpumask);
-#if 0
savectx(PCPU_PTR(pcb));
-#endif
atomic_set_int(&stopped_cpus, self);
while ((started_cpus & self) == 0)
cpu_spinwait();
More information about the p4-projects
mailing list