Date: Sat, 15 Mar 2008 19:18:24 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 137794 for review Message-ID: <200803151918.m2FJIOvw063922@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=137794 Change 137794 by marcel@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@ha addi 1,1,tmpstk@l - addi 1,1,8192 + addi 1,1,8192-16 mfmsr 0 lis 9,ofmsr@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@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();
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803151918.m2FJIOvw063922>