diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S index 727f8219fa58..24ac142692f9 100644 --- a/sys/ia64/ia64/locore.S +++ b/sys/ia64/ia64/locore.S @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -153,32 +154,73 @@ END(mi_startup_trampoline) */ .align 32 ENTRY(os_boot_rendez,0) + rsm IA64_PSR_IC|IA64_PSR_I + ;; + srlz.d + mov r16 = (5<<8)|(PAGE_SHIFT<<2)|1 + movl r17 = 5<<61 + ;; + mov rr[r17] = r16 + ;; + srlz.d + mov r16 = (6<<8)|(28<<2) + movl r17 = 6<<61 + ;; + mov rr[r17] = r16 + ;; + srlz.d + mov r16 = (7<<8)|(28<<2) + movl r17 = 7<<61 + ;; + mov rr[r17] = r16 + ;; + srlz.d + mov r16 = (PTE_P|PTE_MA_WB|PTE_A|PTE_D|PTE_PL_KERN|PTE_AR_RWX) + mov r18 = 28<<2 + ;; + + mov cr.ifa = r17 + mov cr.itir = r18 + ptr.d r17, r18 + ptr.i r17, r18 + ;; + srlz.d + srlz.i + ;; + itr.d dtr[r0] = r16 + ;; + itr.i itr[r0] = r16 + srlz.d + ;; + srlz.i + ;; 1: mov r16 = ip - movl r17 = (IA64_PSR_AC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN) - mov r18 = 7 + add r17 = 2f-1b, r17 + movl r18 = (IA64_PSR_AC|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN) ;; - add r16 = 2f-1b, r16 - mov cr.ipsr = r17 + add r17 = r17, r16 + mov cr.ipsr = r18 + mov cr.ifs = r0 ;; - dep r16 = r18, r16, 61, 3 - ;; - mov cr.iip = r16 + mov cr.iip = r17 ;; rfi .align 32 2: movl r16 = ia64_vector_table // set up IVT early - movl r17 = ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT + movl r17 = ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT ;; mov cr.iva = r16 mov cr.pta = r17 ;; srlz.i + ssm psr.i ;; srlz.d + mov ar.rsc = 0 movl gp = __gp ;; - br.call.sptk.many rp = ia64_ap_get_stack + br.call.sptk.few rp = ia64_ap_get_stack ;; mov r9 = KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16 ;; @@ -189,10 +231,11 @@ ENTRY(os_boot_rendez,0) ;; mov ar.rsc = 3 ;; - alloc r16=ar.pfs,0,0,0,0 + alloc r16 = ar.pfs, 0, 0, 0, 0 ;; - br.call.sptk.many rp=ia64_ap_startup + br.call.sptk.few rp = ia64_ap_startup /* NOT REACHED */ +9: br 9b END(os_boot_rendez) #endif /* !SMP */ diff --git a/sys/ia64/ia64/locore.s b/sys/ia64/ia64/locore.s index 727f8219fa58..24ac142692f9 100644 --- a/sys/ia64/ia64/locore.s +++ b/sys/ia64/ia64/locore.s @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -153,32 +154,73 @@ END(mi_startup_trampoline) */ .align 32 ENTRY(os_boot_rendez,0) + rsm IA64_PSR_IC|IA64_PSR_I + ;; + srlz.d + mov r16 = (5<<8)|(PAGE_SHIFT<<2)|1 + movl r17 = 5<<61 + ;; + mov rr[r17] = r16 + ;; + srlz.d + mov r16 = (6<<8)|(28<<2) + movl r17 = 6<<61 + ;; + mov rr[r17] = r16 + ;; + srlz.d + mov r16 = (7<<8)|(28<<2) + movl r17 = 7<<61 + ;; + mov rr[r17] = r16 + ;; + srlz.d + mov r16 = (PTE_P|PTE_MA_WB|PTE_A|PTE_D|PTE_PL_KERN|PTE_AR_RWX) + mov r18 = 28<<2 + ;; + + mov cr.ifa = r17 + mov cr.itir = r18 + ptr.d r17, r18 + ptr.i r17, r18 + ;; + srlz.d + srlz.i + ;; + itr.d dtr[r0] = r16 + ;; + itr.i itr[r0] = r16 + srlz.d + ;; + srlz.i + ;; 1: mov r16 = ip - movl r17 = (IA64_PSR_AC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN) - mov r18 = 7 + add r17 = 2f-1b, r17 + movl r18 = (IA64_PSR_AC|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN) ;; - add r16 = 2f-1b, r16 - mov cr.ipsr = r17 + add r17 = r17, r16 + mov cr.ipsr = r18 + mov cr.ifs = r0 ;; - dep r16 = r18, r16, 61, 3 - ;; - mov cr.iip = r16 + mov cr.iip = r17 ;; rfi .align 32 2: movl r16 = ia64_vector_table // set up IVT early - movl r17 = ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT + movl r17 = ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT ;; mov cr.iva = r16 mov cr.pta = r17 ;; srlz.i + ssm psr.i ;; srlz.d + mov ar.rsc = 0 movl gp = __gp ;; - br.call.sptk.many rp = ia64_ap_get_stack + br.call.sptk.few rp = ia64_ap_get_stack ;; mov r9 = KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16 ;; @@ -189,10 +231,11 @@ ENTRY(os_boot_rendez,0) ;; mov ar.rsc = 3 ;; - alloc r16=ar.pfs,0,0,0,0 + alloc r16 = ar.pfs, 0, 0, 0, 0 ;; - br.call.sptk.many rp=ia64_ap_startup + br.call.sptk.few rp = ia64_ap_startup /* NOT REACHED */ +9: br 9b END(os_boot_rendez) #endif /* !SMP */ diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 4163b6196efa..eb8c0f05400e 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -69,7 +69,7 @@ struct mp_cpu { int mp_hardware = 0; int mp_ipi_vector[IPI_COUNT]; -int mp_ipi_test; +int mp_ipi_test = 0; TAILQ_HEAD(, mp_cpu) ia64_cpus = TAILQ_HEAD_INITIALIZER(ia64_cpus); @@ -77,32 +77,34 @@ void * ia64_ap_get_stack(void) { struct mp_cpu *cpu; - u_int64_t lid = ia64_get_lid() & 0xffff0000; + u_int64_t lid = ia64_get_lid() & 0xffff0000L; TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { if (cpu->cpu_lid == lid) return (cpu->cpu_stack); } - /* XXX - Should never reach here */ - return NULL; + panic(__func__": bad LID or RR5 misconfigured"); } void ia64_ap_startup(void) { struct mp_cpu *cpu; - u_int64_t lid = ia64_get_lid() & 0xffff0000; + u_int64_t lid = ia64_get_lid() & 0xffff0000L; TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { - if (cpu->cpu_lid == lid) { - cpu->cpu_lid = ia64_get_lid(); - cpu->cpu_awake = 1; - printf("SMP: CPU%d is awake!\n", cpu->cpu_no); - while (1) - ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0); - } + if (cpu->cpu_lid == lid) + break; } + + KASSERT(cpu != NULL, ("foo!")); + + cpu->cpu_lid = ia64_get_lid(); + cpu->cpu_awake = 1; + + while(1) + ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0); } int @@ -116,7 +118,7 @@ void cpu_mp_add(uint acpiid, uint apicid, uint apiceid) { struct mp_cpu *cpu; - u_int64_t lid = ia64_get_lid() & 0xffff0000; + u_int64_t bsp = ia64_get_lid() & 0xffff0000L; cpu = malloc(sizeof(*cpu), M_SMP, M_WAITOK|M_ZERO); if (cpu == NULL) @@ -124,13 +126,9 @@ cpu_mp_add(uint acpiid, uint apicid, uint apiceid) TAILQ_INSERT_TAIL(&ia64_cpus, cpu, cpu_next); cpu->cpu_no = acpiid; - lid = ((apicid & 0xff) << 8 | (apiceid & 0xff)) << 16; - if (lid == (ia64_get_lid() & 0xffff0000L)) { - cpu->cpu_lid = ia64_get_lid(); + cpu->cpu_lid = ((apicid & 0xff) << 8 | (apiceid & 0xff)) << 16; + if (cpu->cpu_lid == bsp) cpu->cpu_bsp = 1; - cpu->cpu_awake = 1; - } else - cpu->cpu_lid = lid; all_cpus |= (1 << acpiid); mp_ncpus++; } @@ -141,9 +139,12 @@ cpu_mp_announce() struct mp_cpu *cpu; TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { - printf("cpu%d: SAPIC Id=%x, SAPIC Eid=%x (%s)\n", cpu->cpu_no, - LID_SAPIC_ID(cpu->cpu_lid), LID_SAPIC_EID(cpu->cpu_lid), - (cpu->cpu_bsp) ? "BSP" : "AP"); + printf("cpu%d: SAPIC Id=%x, SAPIC Eid=%x", cpu->cpu_no, + LID_SAPIC_ID(cpu->cpu_lid), LID_SAPIC_EID(cpu->cpu_lid)); + if (cpu->cpu_bsp) + printf(" (BSP)\n"); + else + printf("\n"); } } @@ -157,10 +158,11 @@ cpu_mp_start() cpu->cpu_stack = malloc(KSTACK_PAGES * PAGE_SIZE, M_SMP, M_WAITOK); if (bootverbose) - printf("SMP: waking up CPU%d\n", cpu->cpu_no); + printf("SMP: waking up cpu%d\n", cpu->cpu_no); ipi_send(cpu->cpu_lid, IPI_AP_WAKEUP); } else { - mp_ipi_test = 0; + cpu->cpu_lid = ia64_get_lid(); + cpu->cpu_awake = 1; ipi_self(IPI_TEST); } } @@ -169,12 +171,21 @@ cpu_mp_start() static void cpu_mp_unleash(void *dummy) { + struct mp_cpu *cpu; + int awake = 0; if (!mp_hardware) return; if (mp_ipi_test != 1) printf("SMP: sending of a test IPI to BSP failed\n"); + + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + awake += cpu->cpu_awake; + } + + if (awake != mp_ncpus) + printf("SMP: %d CPU(s) didn't get woken\n", mp_ncpus - awake); } /*