diff options
-rw-r--r-- | sys/ia64/acpica/OsdEnvironment.c | 22 | ||||
-rw-r--r-- | sys/ia64/acpica/madt.c | 166 | ||||
-rw-r--r-- | sys/ia64/ia64/locore.S | 52 | ||||
-rw-r--r-- | sys/ia64/ia64/locore.s | 52 | ||||
-rw-r--r-- | sys/ia64/ia64/mp_machdep.c | 172 | ||||
-rw-r--r-- | sys/ia64/ia64/sal.c | 23 | ||||
-rw-r--r-- | sys/ia64/include/sal.h | 5 | ||||
-rw-r--r-- | sys/ia64/include/smp.h | 32 |
8 files changed, 359 insertions, 165 deletions
diff --git a/sys/ia64/acpica/OsdEnvironment.c b/sys/ia64/acpica/OsdEnvironment.c index 5da1d5c..897fc26 100644 --- a/sys/ia64/acpica/OsdEnvironment.c +++ b/sys/ia64/acpica/OsdEnvironment.c @@ -51,25 +51,15 @@ AcpiOsTerminate(void) } ACPI_STATUS -AcpiOsGetRootPointer( - UINT32 Flags, - ACPI_PHYSICAL_ADDRESS *RsdpPhysicalAddress) +AcpiOsGetRootPointer(UINT32 Flags, ACPI_PHYSICAL_ADDRESS *RsdpPhysicalAddress) { - RSDP_DESCRIPTOR *rsdp; - XSDT_DESCRIPTOR *xsdt; - if (ia64_efi_acpi20_table) { + if (ia64_efi_acpi20_table) *RsdpPhysicalAddress = ia64_efi_acpi20_table; - rsdp = (RSDP_DESCRIPTOR *) - IA64_PHYS_TO_RR7(ia64_efi_acpi20_table); - xsdt = (XSDT_DESCRIPTOR *) - IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); - ia64_parse_xsdt(xsdt); - return(AE_OK); - } else if (ia64_efi_acpi_table) { + else if (ia64_efi_acpi_table) *RsdpPhysicalAddress = ia64_efi_acpi_table; - return(AE_OK); - } + else + return(AE_NOT_FOUND); - return(AE_NOT_FOUND); + return(AE_OK); } diff --git a/sys/ia64/acpica/madt.c b/sys/ia64/acpica/madt.c index 325bf62..a3bc09d 100644 --- a/sys/ia64/acpica/madt.c +++ b/sys/ia64/acpica/madt.c @@ -28,96 +28,71 @@ #include "acpi.h" +void cpu_mp_add(uint, uint, uint); +struct sapic *sapic_create(int, int, u_int64_t); + #pragma pack(1) -#define APIC_INTERRUPT_SOURCE_OVERRIDE 2 -#define APIC_NMI 3 -#define APIC_LOCAL_APIC_NMI 4 -#define APIC_LOCAL_APIC_OVERRIDE 5 -#define APIC_IO_SAPIC 6 -#define APIC_LOCAL_SAPIC 7 -#define APIC_PLATFORM_INTERRUPT 8 - +#define APIC_INTERRUPT_SOURCE_OVERRIDE 2 +#define APIC_NMI 3 +#define APIC_LOCAL_APIC_NMI 4 +#define APIC_LOCAL_APIC_OVERRIDE 5 +#define APIC_IO_SAPIC 6 +#define APIC_LOCAL_SAPIC 7 +#define APIC_PLATFORM_INTERRUPT 8 -typedef struct /* Interrupt Source Override */ +typedef struct /* Interrupt Source Override */ { - APIC_HEADER header; - UINT8 Bus; - UINT8 Source; - UINT32 GlobalSystemInterrupt; - UINT16 Flags; + APIC_HEADER header; + UINT8 Bus; + UINT8 Source; + UINT32 GlobalSystemInterrupt; + UINT16 Flags; } INTERRUPT_SOURCE_OVERRIDE; -typedef struct /* IO SAPIC */ +typedef struct /* IO SAPIC */ { - APIC_HEADER header; - UINT8 IoSapicId; /* I/O SAPIC ID */ - UINT8 Reserved; /* reserved - must be zero */ - UINT32 Vector; /* interrupt vector index where INTI - * lines start */ - UINT64 IoSapicAddress; /* SAPIC's physical address */ - + APIC_HEADER header; + UINT8 IoSapicId; /* I/O SAPIC ID */ + UINT8 Reserved; /* reserved - must be zero */ + UINT32 Vector; /* interrupt base */ + UINT64 IoSapicAddress; /* SAPIC's physical address */ } IO_SAPIC; - typedef struct /* LOCAL SAPIC */ { - APIC_HEADER header; - UINT16 ProcessorId; /* ACPI processor id */ - UINT16 ProcessorEnabled: 1; /* Processor is usable if set */ - UINT16 Reserved1 : 15; - UINT8 LocalSapicId; /* processor's local SAPIC id */ - UINT8 LocalSapicEid; /* processor's local SAPIC eid */ - + APIC_HEADER header; + UINT8 ProcessorId; /* ACPI processor id */ + UINT8 LocalSapicId; /* Processor local SAPIC id */ + UINT8 LocalSapicEid; /* Processor local SAPIC eid */ + UINT8 Reserved; + UINT32 Reserved1: 16; + UINT32 ProcessorEnabled: 1; + UINT32 Reserved2: 15; } LOCAL_SAPIC; - typedef struct /* PLATFORM INTERRUPT SOURCE */ { - APIC_HEADER header; - UINT16 Polarity : 2; /* Polarity of input signal */ - UINT16 TriggerMode: 2; /* Trigger mode of input signal */ - UINT16 Reserved1 : 12; - UINT8 InterruptType; /* 1-PMI, 2-INIT, 3-Error */ - UINT8 ProcessorId; /* Processor ID of destination */ - UINT8 ProcessorEid; /* Processor EID of destination */ - UINT8 IoSapicVector; /* Value for redirection table */ - UINT32 GlobalSystemInterrupt; /* Global System Interrupt */ - UINT32 Reserved2; - + APIC_HEADER header; + UINT16 Polarity : 2; /* Polarity of input signal */ + UINT16 TriggerMode: 2; /* Trigger mode of input signal */ + UINT16 Reserved1 : 12; + UINT8 InterruptType; /* 1-PMI, 2-INIT, 3-Error */ + UINT8 ProcessorId; /* Processor ID of destination */ + UINT8 ProcessorEid; /* Processor EID of destination */ + UINT8 IoSapicVector; /* Value for redirection table */ + UINT32 GlobalSystemInterrupt; /* Global System Interrupt */ + UINT32 Reserved2; } PLATFORM_INTERRUPT_SOURCE; - #pragma pack() static void -parse_local_apic(PROCESSOR_APIC *apic) -{ - if (bootverbose) { - printf("\t\tProcessorId=0x%x, APIC Id=0x%x", - apic->ProcessorApicId, apic->LocalApicId); - if (!apic->ProcessorEnabled) - printf(" (disabled)"); - printf("\n"); - } -} - -static void -parse_io_apic(IO_APIC *apic) -{ - if (bootverbose) - printf("\t\tId=0x%x, Vector=0x%x, Address=0x%lx\n", - apic->IoApicId, apic->Vector, apic->IoApicAddress); -} - -static void parse_interrupt_override(INTERRUPT_SOURCE_OVERRIDE *override) { if (bootverbose) - printf("\t\tBus=%d, Source=%d, Irq=0x%x\n", - override->Bus, - override->Source, - override->GlobalSystemInterrupt); + printf("\t\tBus=%d, Source=%d, Irq=0x%x\n", override->Bus, + override->Source, override->GlobalSystemInterrupt); } static void @@ -125,9 +100,7 @@ parse_io_sapic(IO_SAPIC *sapic) { if (bootverbose) printf("\t\tId=0x%x, Vector=0x%x, Address=0x%lx\n", - sapic->IoSapicId, - sapic->Vector, - sapic->IoSapicAddress); + sapic->IoSapicId, sapic->Vector, sapic->IoSapicAddress); sapic_create(sapic->IoSapicId, sapic->Vector, sapic->IoSapicAddress); } @@ -142,6 +115,11 @@ parse_local_sapic(LOCAL_SAPIC *sapic) printf(" (disabled)"); printf("\n"); } +#ifdef SMP + if (sapic->ProcessorEnabled) + cpu_mp_add(sapic->ProcessorId, sapic->LocalSapicId, + sapic->LocalSapicEid); +#endif } static void @@ -149,13 +127,10 @@ parse_platform_interrupt(PLATFORM_INTERRUPT_SOURCE *source) { if (bootverbose) printf("\t\tPolarity=%d, TriggerMode=%d, Id=0x%x, " - "Eid=0x%x, Vector=0x%x, Irq=%d\n", - source->Polarity, - source->TriggerMode, - source->ProcessorId, - source->ProcessorEid, - source->IoSapicVector, - source->GlobalSystemInterrupt); + "Eid=0x%x, Vector=0x%x, Irq=%d\n", source->Polarity, + source->TriggerMode, source->ProcessorId, + source->ProcessorEid, source->IoSapicVector, + source->GlobalSystemInterrupt); } static void @@ -177,13 +152,11 @@ parse_madt(APIC_TABLE *madt) case APIC_PROC: if (bootverbose) printf("Local APIC entry\n"); - parse_local_apic((PROCESSOR_APIC *) head); break; case APIC_IO: if (bootverbose) printf("I/O APIC entry\n"); - parse_io_apic((IO_APIC *) head); break; case APIC_INTERRUPT_SOURCE_OVERRIDE: @@ -203,6 +176,7 @@ parse_madt(APIC_TABLE *madt) printf("Local APIC NMI entry\n"); break; + case APIC_LOCAL_APIC_OVERRIDE: if (bootverbose) printf("Local APIC override entry\n"); @@ -238,28 +212,32 @@ parse_madt(APIC_TABLE *madt) } void -ia64_parse_xsdt(XSDT_DESCRIPTOR *xsdt) +ia64_probe_sapics(void) { - int i, count; + ACPI_PHYSICAL_ADDRESS rsdp_phys; + RSDP_DESCRIPTOR *rsdp; + XSDT_DESCRIPTOR *xsdt; ACPI_TABLE_HEADER *table; + int i, count; - /* - * First find the MADT. - */ - count = (UINT64 *) ((char *) xsdt + xsdt->Header.Length) - - &xsdt->TableOffsetEntry[0]; + if (AcpiOsGetRootPointer(0, &rsdp_phys) != AE_OK) + return; + + rsdp = (RSDP_DESCRIPTOR *)IA64_PHYS_TO_RR7(rsdp_phys); + xsdt = (XSDT_DESCRIPTOR *)IA64_PHYS_TO_RR7(rsdp->XsdtPhysicalAddress); + + count = (UINT64 *)((char *)xsdt + xsdt->Header.Length) + - xsdt->TableOffsetEntry; for (i = 0; i < count; i++) { table = (ACPI_TABLE_HEADER *) IA64_PHYS_TO_RR7(xsdt->TableOffsetEntry[i]); + if (bootverbose) - printf("Table '%c%c%c%c' at %p\n", - table->Signature[0], - table->Signature[1], - table->Signature[2], - table->Signature[3], - table); - if (!strncmp(table->Signature, APIC_SIG, 4)) { + printf("Table '%c%c%c%c' at %p\n", table->Signature[0], + table->Signature[1], table->Signature[2], + table->Signature[3], table); + + if (!strncmp(table->Signature, APIC_SIG, 4)) parse_madt((APIC_TABLE *) table); - } } } diff --git a/sys/ia64/ia64/locore.S b/sys/ia64/ia64/locore.S index ae5946b..278c276 100644 --- a/sys/ia64/ia64/locore.S +++ b/sys/ia64/ia64/locore.S @@ -54,6 +54,7 @@ #include <sys/cdefs.h> #include <machine/asm.h> +#include <machine/ia64_cpu.h> #include <machine/fpu.h> #include <sys/syscall.h> #include <assym.s> @@ -74,7 +75,6 @@ kstack: .space KSTACK_PAGES * PAGE_SIZE * Not really a leaf but we can't return. */ ENTRY(__start, 1) - movl r8=ia64_vector_table // set up IVT early movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT ;; @@ -130,6 +130,56 @@ ENTRY(__start, 1) END(__start) +/* + * AP wake-up entry point. The handoff state is similar as for the BSP, + * as described on page 3-9 of the IPF SAL Specification. The difference + * lies in the contents of register b0. For APs this register holds the + * return address into the SAL rendezvous routine. + */ + .align 32 +ENTRY(os_boot_rendez,0) +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 r16 = 2f-1b, r16 + mov cr.ipsr = r17 + ;; + dep r16 = r18, r16, 61, 3 + ;; + mov cr.iip = r16 + ;; + rfi + + .align 32 +2: movl r16 = ia64_vector_table // set up IVT early + movl r17 = ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT + ;; + mov cr.iva = r16 + mov cr.pta = r17 + ;; + srlz.i + ;; + srlz.d + movl gp = __gp + ;; + br.call.sptk.many rp = ia64_ap_get_stack + ;; + mov r9 = KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16 + ;; + add sp = r9, r8 + mov ar.bspstore = r8 + ;; + loadrs + ;; + mov ar.rsc = 3 + ;; + alloc r16=ar.pfs,0,0,0,0 + ;; + br.call.sptk.many rp=ia64_ap_startup + /* NOT REACHED */ +END(os_boot_rendez) + /**************************************************************************/ /* diff --git a/sys/ia64/ia64/locore.s b/sys/ia64/ia64/locore.s index ae5946b..278c276 100644 --- a/sys/ia64/ia64/locore.s +++ b/sys/ia64/ia64/locore.s @@ -54,6 +54,7 @@ #include <sys/cdefs.h> #include <machine/asm.h> +#include <machine/ia64_cpu.h> #include <machine/fpu.h> #include <sys/syscall.h> #include <assym.s> @@ -74,7 +75,6 @@ kstack: .space KSTACK_PAGES * PAGE_SIZE * Not really a leaf but we can't return. */ ENTRY(__start, 1) - movl r8=ia64_vector_table // set up IVT early movl r9=ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT ;; @@ -130,6 +130,56 @@ ENTRY(__start, 1) END(__start) +/* + * AP wake-up entry point. The handoff state is similar as for the BSP, + * as described on page 3-9 of the IPF SAL Specification. The difference + * lies in the contents of register b0. For APs this register holds the + * return address into the SAL rendezvous routine. + */ + .align 32 +ENTRY(os_boot_rendez,0) +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 r16 = 2f-1b, r16 + mov cr.ipsr = r17 + ;; + dep r16 = r18, r16, 61, 3 + ;; + mov cr.iip = r16 + ;; + rfi + + .align 32 +2: movl r16 = ia64_vector_table // set up IVT early + movl r17 = ia64_vhpt+(1<<8)+(15<<2)+1 // and VHPT + ;; + mov cr.iva = r16 + mov cr.pta = r17 + ;; + srlz.i + ;; + srlz.d + movl gp = __gp + ;; + br.call.sptk.many rp = ia64_ap_get_stack + ;; + mov r9 = KSTACK_PAGES*PAGE_SIZE-SIZEOF_PCB-SIZEOF_TRAPFRAME-16 + ;; + add sp = r9, r8 + mov ar.bspstore = r8 + ;; + loadrs + ;; + mov ar.rsc = 3 + ;; + alloc r16=ar.pfs,0,0,0,0 + ;; + br.call.sptk.many rp=ia64_ap_startup + /* NOT REACHED */ +END(os_boot_rendez) + /**************************************************************************/ /* diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c index 251e52d..86898b7 100644 --- a/sys/ia64/ia64/mp_machdep.c +++ b/sys/ia64/ia64/mp_machdep.c @@ -46,77 +46,186 @@ #include <machine/pal.h> #include <machine/pmap.h> #include <machine/clock.h> +#include <machine/sal.h> -static void ipi_send(u_int64_t, u_int64_t); +#define LID_SAPIC_ID(x) ((int)((x) >> 24) & 0xff) +#define LID_SAPIC_EID(x) ((int)((x) >> 16) & 0xff) -u_int64_t cpu_to_lid[MAXCPU]; -int ncpus; +void ia64_probe_sapics(void); + +static MALLOC_DEFINE(M_SMP, "smp", "SMP structures"); + +static void ipi_send(u_int64_t, int); +static void cpu_mp_unleash(void *); + +struct mp_cpu { + TAILQ_ENTRY(mp_cpu) cpu_next; + u_int64_t cpu_lid; /* Local processor ID */ + int32_t cpu_no; /* Sequential CPU number */ + u_int32_t cpu_bsp:1; /* 1=BSP; 0=AP */ + u_int32_t cpu_awake:1; /* 1=Awake; 0=sleeping */ + void *cpu_stack; +}; + +int mp_hardware = 0; +int mp_ipi_vector[IPI_COUNT]; + +TAILQ_HEAD(, mp_cpu) ia64_cpus = TAILQ_HEAD_INITIALIZER(ia64_cpus); + +void * +ia64_ap_get_stack(void) +{ + struct mp_cpu *cpu; + u_int64_t lid = ia64_get_lid() & 0xffff0000; + + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + if (cpu->cpu_lid == lid) + return (cpu->cpu_stack); + } + + /* XXX - Should never reach here */ + return NULL; +} + +void +ia64_ap_startup(void) +{ + struct mp_cpu *cpu; + u_int64_t lid = ia64_get_lid() & 0xffff0000; + + 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); + } + } +} int cpu_mp_probe() { - all_cpus = 1; /* Needed for MB init code */ - return (0); + ia64_probe_sapics(); + return (mp_hardware); } void -cpu_mp_start() +cpu_mp_add(uint acpiid, uint apicid, uint apiceid) { + struct mp_cpu *cpu; + u_int64_t lid = ia64_get_lid() & 0xffff0000; + + cpu = malloc(sizeof(*cpu), M_SMP, M_WAITOK|M_ZERO); + if (cpu == NULL) + return; + + 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_bsp = 1; + cpu->cpu_awake = 1; + } else + cpu->cpu_lid = lid; + all_cpus |= (1 << acpiid); + mp_ncpus++; } void 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"); + } +} + +void +cpu_mp_start() +{ + struct mp_cpu *cpu; + + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + if (!cpu->cpu_bsp) { + cpu->cpu_stack = malloc(KSTACK_PAGES * PAGE_SIZE, + M_SMP, M_WAITOK); + if (bootverbose) + printf("SMP: waking up CPU%d\n", cpu->cpu_no); + ipi_send(cpu->cpu_lid, IPI_AP_WAKEUP); + } + } +} + +static void +cpu_mp_unleash(void *dummy) +{ + struct mp_cpu *cpu; + int awake = 0; + + if (!mp_hardware) + return; + + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + if (cpu->cpu_awake) + awake++; + } + + printf("SMP: %d CPUs, %d awake\n", mp_ncpus, awake); } /* * send an IPI to a set of cpus. */ void -ipi_selected(u_int cpus, u_int64_t ipi) +ipi_selected(u_int64_t cpus, int ipi) { - u_int mask; - int cpu; + struct mp_cpu *cpu; - for (mask = 1, cpu = 0; cpu < ncpus; mask <<= 1, cpu++) { - if (cpus & mask) - ipi_send(cpu_to_lid[cpu], ipi); + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + if (cpus & (1 << cpu->cpu_no)) + ipi_send(cpu->cpu_lid, ipi); } } /* - * send an IPI INTerrupt containing 'vector' to all CPUs, including myself + * send an IPI to all CPUs, including myself. */ void -ipi_all(u_int64_t ipi) +ipi_all(int ipi) { - int cpu; + struct mp_cpu *cpu; - for (cpu = 0; cpu < ncpus; cpu++) - ipi_send(cpu_to_lid[cpu], ipi); + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + ipi_send(cpu->cpu_lid, ipi); + } } /* - * send an IPI to all CPUs EXCEPT myself + * send an IPI to all CPUs EXCEPT myself. */ void -ipi_all_but_self(u_int64_t ipi) +ipi_all_but_self(int ipi) { - u_int64_t lid; - int cpu; + struct mp_cpu *cpu; + u_int64_t lid = ia64_get_lid(); - for (cpu = 0; cpu < ncpus; cpu++) { - lid = cpu_to_lid[cpu]; - if (lid != ia64_get_lid()) - ipi_send(lid, ipi); + TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) { + if (cpu->cpu_lid != lid) + ipi_send(cpu->cpu_lid, ipi); } } /* - * send an IPI to myself + * send an IPI to myself. */ void -ipi_self(u_int64_t ipi) +ipi_self(int ipi) { ipi_send(ia64_get_lid(), ipi); @@ -128,12 +237,15 @@ ipi_self(u_int64_t ipi) * fields are used here. */ static void -ipi_send(u_int64_t lid, u_int64_t ipi) +ipi_send(u_int64_t lid, int ipi) { volatile u_int64_t *pipi; + u_int64_t vector; - CTR2(KTR_SMP, __func__ ": lid=%lx, ipi=%lx", lid, ipi); pipi = ia64_memory_address(PAL_PIB_DEFAULT_ADDR | ((lid >> 12) & 0xFFFF0L)); - *pipi = ipi & 0xFF; + vector = (u_int64_t)(mp_ipi_vector[ipi] & 0xff); + *pipi = vector; } + +SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL); diff --git a/sys/ia64/ia64/sal.c b/sys/ia64/ia64/sal.c index a1bb1ce..6118771 100644 --- a/sys/ia64/ia64/sal.c +++ b/sys/ia64/ia64/sal.c @@ -29,6 +29,9 @@ #include <sys/param.h> #include <sys/systm.h> #include <machine/sal.h> +#include <machine/smp.h> + +void os_boot_rendez(void); struct ia64_fdesc { u_int64_t func; @@ -40,7 +43,6 @@ static sal_entry_t fake_sal; extern u_int64_t ia64_pal_entry; sal_entry_t *ia64_sal_entry = fake_sal; -u_int64_t ia64_sal_wakeup; static struct ia64_sal_result fake_sal(u_int64_t a1, u_int64_t a2, u_int64_t a3, u_int64_t a4, @@ -86,23 +88,28 @@ ia64_sal_init(struct sal_system_table *saltab) ia64_sal_entry = (sal_entry_t *) &sal_fdesc; break; } -#ifdef SMP case 5: { struct sal_ap_wakeup_descriptor *dp; + struct ia64_sal_result sal; + int ipi; dp = (struct sal_ap_wakeup_descriptor*)p; KASSERT(dp->sale_mechanism == 0, ("Unsupported AP wake-up mechanism")); - ia64_sal_wakeup = dp->sale_vector; if (bootverbose) printf("SMP: AP wake-up vector: 0x%lx\n", - ia64_sal_wakeup); - /* - * Register OS_BOOT_RENDEZ using SAL_SET_VECTORS - */ + dp->sale_vector); + for (ipi = 0; ipi < IPI_COUNT; ipi++) + mp_ipi_vector[ipi] = dp->sale_vector + ipi; + + sal = ia64_sal_entry(SAL_SET_VECTORS, + SAL_OS_BOOT_RENDEZ, + ia64_tpa((vm_offset_t)os_boot_rendez), 0, 0, + 0, 0, 0); + + mp_hardware = 1; break; } -#endif } p += sizes[*p]; } diff --git a/sys/ia64/include/sal.h b/sys/ia64/include/sal.h index b9dd889..c4ee7bf 100644 --- a/sys/ia64/include/sal.h +++ b/sys/ia64/include/sal.h @@ -113,6 +113,11 @@ struct sal_ap_wakeup_descriptor { #define SAL_FREQ_BASE 0x01000012 #define SAL_UPDATE_PAL 0x01000020 +/* SAL_SET_VECTORS event handler types */ +#define SAL_OS_MCA 0 +#define SAL_OS_INIT 1 +#define SAL_OS_BOOT_RENDEZ 2 + struct ia64_sal_result { int64_t sal_status; u_int64_t sal_result[3]; diff --git a/sys/ia64/include/smp.h b/sys/ia64/include/smp.h index ded849f..3f99e15 100644 --- a/sys/ia64/include/smp.h +++ b/sys/ia64/include/smp.h @@ -7,26 +7,28 @@ #ifdef _KERNEL /* - * Interprocessor interrupts for SMP. + * Interprocessor interrupts for SMP. The following values are indices + * into the IPI vector table. The SAL gives us the vector used for AP + * wake-up. Keep the IPI_AP_WAKEUP at index 0. */ -#define IPI_INVLTLB 0x0001 -#define IPI_RENDEZVOUS 0x0002 -#define IPI_AST 0x0004 -#define IPI_CHECKSTATE 0x0008 -#define IPI_STOP 0x0010 +#define IPI_AP_WAKEUP 0 +#define IPI_AST 1 +#define IPI_CHECKSTATE 2 +#define IPI_INVLTLB 3 +#define IPI_RENDEZVOUS 4 +#define IPI_STOP 5 + +#define IPI_COUNT 6 #ifndef LOCORE -/* global data in mp_machdep.c */ -extern volatile u_int checkstate_probed_cpus; -extern volatile u_int checkstate_need_ast; -extern volatile u_int resched_cpus; +extern int mp_hardware; +extern int mp_ipi_vector[]; -void ipi_all(u_int64_t ipi); -void ipi_all_but_self(u_int64_t ipi); -void ipi_selected(u_int cpus, u_int64_t ipi); -void ipi_self(u_int64_t ipi); -void smp_init_secondary(void); +void ipi_all(int ipi); +void ipi_all_but_self(int ipi); +void ipi_selected(u_int64_t cpus, int ipi); +void ipi_self(int ipi); #endif /* !LOCORE */ #endif /* _KERNEL */ |