o Do not parse the MADT as a side-effect in AcpiOsGetRootPointer,

do it as a side-effect of probing for MP hardware. This allows
   us to scan for local SAPICs early (especially before MBUF
   initialization).
o  Fix the Local SAPIC structure so that matches the Local SAPIC
   table entry. Now that the Local SAPIC info is the same as the
   Local APIC info, stop dumping the Local APIC entries.
o  For every Local SAPIC entry in the MADT that's not disabled,
   let the SMP code know about it. They represent actual CPUs.
o  Register the OS_BOOT_RENDEZ entry point and provide a (bogus)
   implementation for the entry point.
o  Provide a mapping for internal IPI numbers to ExtINT vectors.
o  In a MP system, announce the CPUs and start them by sending
   IPI_AP_WAKEUP to each of them. Not that it makes a difference
   at this time :-)
o  Miscellaneous style fixes and other adjustments.
This commit is contained in:
Marcel Moolenaar 2001-10-29 02:16:02 +00:00
parent 434d21ccbf
commit 229778f87e
8 changed files with 366 additions and 172 deletions

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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)
/**************************************************************************/
/*

View File

@ -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)
/**************************************************************************/
/*

View File

@ -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);
}
/*
* send an IPI to all CPUs EXCEPT myself
*/
void
ipi_all_but_self(u_int64_t ipi)
{
u_int64_t lid;
int cpu;
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) {
ipi_send(cpu->cpu_lid, ipi);
}
}
/*
* send an IPI to myself
* send an IPI to all CPUs EXCEPT myself.
*/
void
ipi_self(u_int64_t ipi)
ipi_all_but_self(int ipi)
{
struct mp_cpu *cpu;
u_int64_t lid = ia64_get_lid();
TAILQ_FOREACH(cpu, &ia64_cpus, cpu_next) {
if (cpu->cpu_lid != lid)
ipi_send(cpu->cpu_lid, ipi);
}
}
/*
* send an IPI to myself.
*/
void
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);

View File

@ -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];
}

View File

@ -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];

View File

@ -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 */