PERFORCE change 39483 for review
Peter Wemm
peter at FreeBSD.org
Fri Oct 10 17:06:36 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=39483
Change 39483 by peter at peter_daintree on 2003/10/10 17:06:04
p4 integ -I smp_hammer branch (ie: suck in jhb's current changes)
(wow! conflict city!)
Affected files ...
.. //depot/projects/hammer/sys/amd64/acpica/madt.c#3 integrate
.. //depot/projects/hammer/sys/amd64/amd64/apic_vector.s#7 integrate
.. //depot/projects/hammer/sys/amd64/amd64/intr_machdep.c#3 integrate
.. //depot/projects/hammer/sys/amd64/amd64/io_apic.c#8 integrate
.. //depot/projects/hammer/sys/amd64/amd64/local_apic.c#11 integrate
.. //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#15 integrate
.. //depot/projects/hammer/sys/amd64/amd64/mpboot.s#8 integrate
.. //depot/projects/hammer/sys/amd64/include/apicvar.h#6 integrate
.. //depot/projects/hammer/sys/amd64/include/intr_machdep.h#4 integrate
.. //depot/projects/hammer/sys/amd64/isa/atpic.c#6 integrate
.. //depot/projects/hammer/sys/amd64/isa/atpic_vector.s#5 integrate
.. //depot/projects/hammer/sys/jhb_notes#5 integrate
Differences ...
==== //depot/projects/hammer/sys/amd64/acpica/madt.c#3 (text+ko) ====
@@ -62,8 +62,8 @@
struct lapic_info {
int la_present:1;
int la_enabled:1;
- int la_acpi_id:8;
-} lapics[NLAPICS];
+ int la_apic_id:8;
+} lapics[NLAPICS + 1];
static APIC_TABLE *madt;
static vm_paddr_t madt_physaddr;
@@ -338,9 +338,6 @@
madt_setup_io(void)
{
int i;
-#if 0
- u_char byte;
-#endif
/* First, we run through adding I/O APIC's. */
madt_walk_table(madt_parse_apics, NULL);
@@ -355,15 +352,6 @@
/* Finally, we throw the switch to enable the I/O APIC's. */
acpi_SetDefaultIntrModel(ACPI_INTR_APIC);
-#if 0
- /* XXX: how are we supposed to do this now? does _PIC do this for us? */
- if (mpfps->mpfb2 & MPFB2_IMCR_PRESENT) {
- outb(0x22, 0x70); /* select IMCR */
- byte = inb(0x23); /* current contents */
- byte |= 0x01; /* mask external INTR */
- outb(0x23, byte); /* disconnect 8259s/NMI */
- }
-#endif
return (0);
}
@@ -408,19 +396,24 @@
* its own.
*/
proc = (PROCESSOR_APIC *)entry;
- la = &lapics[proc->LocalApicId];
+#if 0
+ if (bootverbose)
+#endif
+ printf("MADT: Found CPU APIC ID %d ACPI ID %d: %s\n",
+ proc->LocalApicId, proc->ProcessorApicId,
+ proc->ProcessorEnabled ? "enabled" : "disabled");
+ if (proc->ProcessorApicId > NLAPICS)
+ panic("%s: CPU ID %d too high", __func__,
+ proc->ProcessorApicId);
+ la = &lapics[proc->ProcessorApicId];
KASSERT(la->la_present == 0,
- ("Duplicate local APIC ID %d", proc->LocalApicId));
+ ("Duplicate local ACPI ID %d", proc->ProcessorApicId));
la->la_present = 1;
- la->la_acpi_id = proc->ProcessorApicId;
+ la->la_apic_id = proc->LocalApicId;
if (proc->ProcessorEnabled) {
la->la_enabled = 1;
lapic_create(proc->LocalApicId, 0);
}
- /* XXXTEST */
- printf("MADT: Found CPU APIC ID %d ACPI ID %d: %s\n",
- proc->LocalApicId, proc->ProcessorApicId,
- proc->ProcessorEnabled ? "enabled" : "disabled");
break;
}
}
@@ -438,6 +431,12 @@
switch (entry->Type) {
case APIC_IO:
apic = (IO_APIC *)entry;
+#if 0
+ if (bootverbose)
+#endif
+ printf("MADT: Found IO APIC ID %d, Vector %d at %p\n",
+ apic->IoApicId, apic->Vector,
+ (void *)apic->IoApicAddress);
if (apic->IoApicId >= NIOAPICS)
panic("%s: I/O APIC ID %d too high", __func__,
apic->IoApicId);
@@ -448,9 +447,6 @@
(uintptr_t)apic->IoApicAddress, apic->IoApicId,
apic->Vector);
ioapics[apic->IoApicId].io_vector = apic->Vector;
- /* XXXTEST */
- printf("MADT: Found IO APIC ID %d, Vector %d at %p\n",
- apic->IoApicId, apic->Vector, (void *)(uintptr_t)apic->IoApicAddress);
break;
default:
break;
@@ -498,18 +494,14 @@
static int
madt_find_cpu(u_int acpi_id, u_int *apic_id)
{
- int i;
- for (i = 0; i < NLAPICS; i++)
- if (lapics[i].la_present && lapics[i].la_acpi_id == acpi_id) {
- if (apic_id != NULL)
- *apic_id = i;
- if (lapics[i].la_enabled)
- return (0);
- else
- return (ENXIO);
- }
- return (ENOENT);
+ if (!lapics[acpi_id].la_present)
+ return (ENOENT);
+ *apic_id = lapics[acpi_id].la_apic_id;
+ if (lapics[acpi_id].la_enabled)
+ return (0);
+ else
+ return (ENXIO);
}
/*
@@ -602,9 +594,12 @@
if (nmi->ProcessorApicId == 0xff)
apic_id = APIC_ID_ALL;
- else if (madt_find_cpu(nmi->ProcessorApicId, &apic_id) == ENOENT) {
- printf("MADT: Ignoring local NMI routed to ACPI CPU %u\n",
- nmi->ProcessorApicId);
+ else if (madt_find_cpu(nmi->ProcessorApicId, &apic_id) != 0) {
+#if 0
+ if (bootverbose)
+#endif
+ printf("MADT: Ignoring local NMI routed to ACPI CPU %u\n",
+ nmi->ProcessorApicId);
return;
}
if (nmi->LINTPin == 0)
==== //depot/projects/hammer/sys/amd64/amd64/apic_vector.s#7 (text+ko) ====
@@ -127,7 +127,7 @@
incl TD_INTR_NESTING_LEVEL(%rbx) ; \
bsrl %eax, %eax ; /* index of highset set bit in ISR */ \
jz 2f ; \
- addl $(32 * (index - 1)),%eax ; \
+ addl $(32 * index),%eax ; \
1: ; \
FAKE_MCOUNT(13*4(%esp)) ; /* XXX avoid double count */ \
movq %rax, %rdi ; /* pass the IRQ */ \
@@ -153,13 +153,13 @@
iretq
-MCOUNT_LABEL(bintr)
+MCOUNT_LABEL(bintr2)
ISR_VEC(1,apic_isr1)
ISR_VEC(2,apic_isr2)
ISR_VEC(3,apic_isr3)
ISR_VEC(4,apic_isr4)
ISR_VEC(5,apic_isr5)
-MCOUNT_LABEL(eintr)
+MCOUNT_LABEL(eintr2)
#ifdef SMP
/*
==== //depot/projects/hammer/sys/amd64/amd64/intr_machdep.c#3 (text+ko) ====
@@ -294,91 +294,3 @@
db_dump_ithread((*isrc)->is_ithread, verbose);
}
#endif
-
-/* XXX: this does not belong here */
-
-#include "opt_mca.h"
-
-#include <sys/syslog.h>
-#include <i386/bios/mca_machdep.h>
-
-#ifdef PC98
-#define NMI_PARITY 0x04
-#define NMI_EPARITY 0x02
-#else
-#define NMI_PARITY (1 << 7)
-#define NMI_IOCHAN (1 << 6)
-#define ENMI_WATCHDOG (1 << 7)
-#define ENMI_BUSTIMER (1 << 6)
-#define ENMI_IOSTATUS (1 << 5)
-#endif
-
-/*
- * Handle a NMI, possibly a machine check.
- * return true to panic system, false to ignore.
- */
-int
-isa_nmi(cd)
- int cd;
-{
- int retval = 0;
-#ifdef PC98
- int port = inb(0x33);
-
- log(LOG_CRIT, "NMI PC98 port = %x\n", port);
- if (epson_machine_id == 0x20)
- epson_outb(0xc16, epson_inb(0xc16) | 0x1);
- if (port & NMI_PARITY) {
- log(LOG_CRIT, "BASE RAM parity error, likely hardware failure.");
- retval = 1;
- } else if (port & NMI_EPARITY) {
- log(LOG_CRIT, "EXTENDED RAM parity error, likely hardware failure.");
- retval = 1;
- } else {
- log(LOG_CRIT, "\nNMI Resume ??\n");
- }
-#else /* IBM-PC */
- int isa_port = inb(0x61);
- int eisa_port = inb(0x461);
-
- log(LOG_CRIT, "NMI ISA %x, EISA %x\n", isa_port, eisa_port);
-#ifdef DEV_MCA
- if (MCA_system && mca_bus_nmi())
- return(0);
-#endif
-
- if (isa_port & NMI_PARITY) {
- log(LOG_CRIT, "RAM parity error, likely hardware failure.");
- retval = 1;
- }
-
- if (isa_port & NMI_IOCHAN) {
- log(LOG_CRIT, "I/O channel check, likely hardware failure.");
- retval = 1;
- }
-
- /*
- * On a real EISA machine, this will never happen. However it can
- * happen on ISA machines which implement XT style floating point
- * error handling (very rare). Save them from a meaningless panic.
- */
- if (eisa_port == 0xff)
- return(retval);
-
- if (eisa_port & ENMI_WATCHDOG) {
- log(LOG_CRIT, "EISA watchdog timer expired, likely hardware failure.");
- retval = 1;
- }
-
- if (eisa_port & ENMI_BUSTIMER) {
- log(LOG_CRIT, "EISA bus timeout, likely hardware failure.");
- retval = 1;
- }
-
- if (eisa_port & ENMI_IOSTATUS) {
- log(LOG_CRIT, "EISA I/O port status error.");
- retval = 1;
- }
-#endif
- return(retval);
-}
==== //depot/projects/hammer/sys/amd64/amd64/io_apic.c#8 (text+ko) ====
@@ -30,6 +30,7 @@
*/
#include "opt_isa.h"
+#include "opt_no_mixed_mode.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -48,7 +49,7 @@
#include <machine/apicvar.h>
#include <machine/segments.h>
-#ifdef DEV_ISA
+#if defined(DEV_ISA) && !defined(NO_MIXED_MODE)
#define MIXED_MODE
#endif
@@ -175,7 +176,7 @@
uint32_t flags;
mtx_lock_spin(&icu_lock);
- if (!intpin->io_masked) {
+ if (!intpin->io_masked && !intpin->io_edgetrigger) {
flags = ioapic_read(io->io_addr,
IOAPIC_REDTBL_LO(intpin->io_intpin));
flags |= IOART_INTMSET;
@@ -251,11 +252,6 @@
{
struct ioapic_intsrc *intpin = (struct ioapic_intsrc *)isrc;
- if (intpin->io_vector == IDT_TO_IRQ(IDT_SYSCALL)) {
- printf("WARNING: IRQ %d is not routed!\n",
- IDT_TO_IRQ(IDT_SYSCALL));
- return;
- }
KASSERT(intpin->io_dest != DEST_EXTINT,
("ExtINT pin trying to use ioapic enable_intr method"));
if (intpin->io_dest == DEST_NONE) {
@@ -392,7 +388,7 @@
* logical cluster destination until it is enabled.
*/
intpin->io_masked = 1;
- intpin->io_dest = -1;
+ intpin->io_dest = DEST_NONE;
if (bootverbose) {
printf("ioapic%u: intpin %d -> ", io->io_id, i);
if (intpin->io_vector == VECTOR_EXTINT)
@@ -611,7 +607,7 @@
break;
default:
flags |= IOART_DELLOPRI |
- IRQ_TO_IDT(pin->io_vector);
+ apic_irq_to_idt(pin->io_vector);
}
mtx_lock_spin(&icu_lock);
ioapic_write(apic, IOAPIC_REDTBL_LO(i), flags);
@@ -654,7 +650,8 @@
STAILQ_FOREACH(io, &ioapic_list, io_next)
for (i = 0; i < io->io_numintr; i++)
if (io->io_pins[i].io_dest != DEST_NONE &&
- io->io_pins[i].io_dest != DEST_EXTINT)
+ io->io_pins[i].io_dest != DEST_EXTINT &&
+ io->io_pins[i].io_vector != VECTOR_EXTINT /* XXXTEST */)
ioapic_program_destination(&io->io_pins[i]);
}
SYSINIT(ioapic_destinations, SI_SUB_SMP, SI_ORDER_SECOND,
@@ -684,10 +681,12 @@
if (extint->io_vector != VECTOR_EXTINT)
panic("Can't find ExtINT pin to route through!");
if (extint->io_dest == DEST_NONE) {
+#if 0
+ /* XXXTEST? */
ioapic_assign_cluster(extint);
+#endif
ioapic_enable_source(&extint->io_intsrc);
}
-
}
#endif /* MIXED_MODE */
==== //depot/projects/hammer/sys/amd64/amd64/local_apic.c#11 (text+ko) ====
@@ -75,6 +75,7 @@
struct lapic {
struct lvt la_lvts[LVT_MAX + 1];
+ int la_id:8;
int la_cluster:4;
int la_cluster_id:2;
int la_present:1;
@@ -85,7 +86,7 @@
/* Global defaults for local APIC LVT entries. */
static struct lvt lvts[LVT_MAX + 1] = {
{ 1, 1, 1, 1, APIC_LVT_DM_EXTINT, 0 }, /* LINT0: masked ExtINT */
- { 1, 1, 1, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */
+ { 1, 1, 0, 1, APIC_LVT_DM_NMI, 0 }, /* LINT1: NMI */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* Timer: needs a vector */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* Error: needs a vector */
{ 1, 1, 1, 1, APIC_LVT_DM_FIXED, 0 }, /* PMC */
@@ -130,10 +131,11 @@
case APIC_LVT_DM_SMI:
case APIC_LVT_DM_INIT:
case APIC_LVT_DM_EXTINT:
- KASSERT(lvt->lvt_edgetrigger == 1,
- ("LVT with mode %#x must be edge triggered",
- lvt->lvt_mode));
- /* FALLTHROUGH */
+ if (!lvt->lvt_edgetrigger) {
+ printf("lapic%u: Forcing LINT%u to edge trigger\n",
+ la->la_id, pin);
+ value |= APIC_LVT_TM;
+ }
/* Use a vector of 0. */
break;
case APIC_LVT_DM_FIXED:
@@ -197,6 +199,7 @@
* intra-cluster ID of 0.
*/
lapics[apic_id].la_present = 1;
+ lapics[apic_id].la_id = apic_id;
for (i = 0; i < LVT_MAX; i++) {
lapics[apic_id].la_lvts[i] = lvts[i];
lapics[apic_id].la_lvts[i].lvt_active = 0;
@@ -222,14 +225,14 @@
}
void
-lapic_enable_intr(u_int vector)
+lapic_enable_intr(u_int irq)
{
+ u_int vector;
- /* Convert to IDT vector. */
- vector = IRQ_TO_IDT(vector);
+ vector = apic_irq_to_idt(irq);
KASSERT(vector != IDT_SYSCALL, ("Attempt to overwrite syscall entry"));
KASSERT(ioint_handlers[vector / 32] != NULL,
- ("No ISR handler for IRQ %d", IDT_TO_IRQ(vector)));
+ ("No ISR handler for IRQ %u", irq));
setidt(vector, ioint_handlers[vector / 32], SDT_SYSIGT, SEL_KPL, 0);
}
@@ -283,19 +286,12 @@
void
lapic_disable(void)
{
- struct lapic *la;
- u_int32_t value;
- register_t eflags;
+ uint32_t value;
- la = &lapics[lapic_id()];
- KASSERT(la->la_present, ("missing APIC structure"));
- eflags = intr_disable();
-
- /* Disable local APIC to be safe during boot */
+ /* Software disable the local APIC. */
value = lapic->svr;
value &= ~APIC_SVR_SWEN;
lapic->svr = value;
- intr_restore(eflags);
}
int
@@ -341,88 +337,114 @@
}
int
-lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked)
+lapic_set_lvt_mask(u_int apic_id, u_int pin, u_char masked)
{
- if (lvt > LVT_MAX)
+ if (pin > LVT_MAX)
return (EINVAL);
if (apic_id == APIC_ID_ALL)
- lvts[lvt].lvt_masked = masked;
+ lvts[pin].lvt_masked = masked;
else {
KASSERT(lapics[apic_id].la_present,
("%s: missing APIC %u", __func__, apic_id));
- lapics[apic_id].la_lvts[lvt].lvt_masked = masked;
- lapics[apic_id].la_lvts[lvt].lvt_active = 1;
+ lapics[apic_id].la_lvts[pin].lvt_masked = masked;
+ lapics[apic_id].la_lvts[pin].lvt_active = 1;
}
+ /* XXXTEST */
+ printf("lapic%u: LINT%u %s\n", apic_id, pin,
+ masked ? "masked" : "unmasked");
return (0);
}
int
-lapic_set_lvt_mode(u_int apic_id, u_int lvt, u_int32_t mode)
+lapic_set_lvt_mode(u_int apic_id, u_int pin, u_int32_t mode)
{
- struct lvt *lv;
+ struct lvt *lvt;
- if (lvt > LVT_MAX)
+ if (pin > LVT_MAX)
return (EINVAL);
if (apic_id == APIC_ID_ALL)
- lv = &lvts[lvt];
+ lvt = &lvts[pin];
else {
KASSERT(lapics[apic_id].la_present,
("%s: missing APIC %u", __func__, apic_id));
- lv = &lapics[apic_id].la_lvts[lvt];
- lv->lvt_active = 1;
+ lvt = &lapics[apic_id].la_lvts[pin];
+ lvt->lvt_active = 1;
}
- lv->lvt_mode = mode;
+ lvt->lvt_mode = mode;
switch (mode) {
case APIC_LVT_DM_NMI:
case APIC_LVT_DM_SMI:
case APIC_LVT_DM_INIT:
case APIC_LVT_DM_EXTINT:
- lv->lvt_edgetrigger = 1;
- lv->lvt_activehi = 1;
+ lvt->lvt_edgetrigger = 1;
+ lvt->lvt_activehi = 1;
if (mode == APIC_LVT_DM_EXTINT)
- lv->lvt_masked = 1;
+ lvt->lvt_masked = 1;
else
- lv->lvt_masked = 0;
+ lvt->lvt_masked = 0;
break;
default:
panic("Unsupported delivery mode: 0x%x\n", mode);
- }
+ }
+ /* XXXTEST */
+ printf("lapic%u: Routing ", apic_id);
+ switch (mode) {
+ case APIC_LVT_DM_NMI:
+ printf("NMI");
+ break;
+ case APIC_LVT_DM_SMI:
+ printf("SMI");
+ break;
+ case APIC_LVT_DM_INIT:
+ printf("INIT");
+ break;
+ case APIC_LVT_DM_EXTINT:
+ printf("ExtINT");
+ break;
+ }
+ printf(" -> LINT%u\n", pin);
return (0);
}
int
-lapic_set_lvt_polarity(u_int apic_id, u_int lvt, u_char activehi)
+lapic_set_lvt_polarity(u_int apic_id, u_int pin, u_char activehi)
{
- if (lvt > LVT_MAX)
+ if (pin > LVT_MAX)
return (EINVAL);
if (apic_id == APIC_ID_ALL)
- lvts[lvt].lvt_activehi = activehi;
+ lvts[pin].lvt_activehi = activehi;
else {
KASSERT(lapics[apic_id].la_present,
("%s: missing APIC %u", __func__, apic_id));
- lapics[apic_id].la_lvts[lvt].lvt_active = 1;
- lapics[apic_id].la_lvts[lvt].lvt_activehi = activehi;
+ lapics[apic_id].la_lvts[pin].lvt_active = 1;
+ lapics[apic_id].la_lvts[pin].lvt_activehi = activehi;
}
+ /* XXXTEST */
+ printf("lapic%u: LINT%u polarity: active-%s\n", apic_id, pin,
+ activehi ? "hi" : "lo");
return (0);
}
int
-lapic_set_lvt_triggermode(u_int apic_id, u_int lvt, u_char edgetrigger)
+lapic_set_lvt_triggermode(u_int apic_id, u_int pin, u_char edgetrigger)
{
- if (lvt > LVT_MAX)
+ if (pin > LVT_MAX)
return (EINVAL);
if (apic_id == APIC_ID_ALL)
- lvts[lvt].lvt_edgetrigger = edgetrigger;
+ lvts[pin].lvt_edgetrigger = edgetrigger;
else {
KASSERT(lapics[apic_id].la_present,
("%s: missing APIC %u", __func__, apic_id));
- lapics[apic_id].la_lvts[lvt].lvt_edgetrigger = edgetrigger;
- lapics[apic_id].la_lvts[lvt].lvt_active = 1;
+ lapics[apic_id].la_lvts[pin].lvt_edgetrigger = edgetrigger;
+ lapics[apic_id].la_lvts[pin].lvt_active = 1;
}
+ /* XXXTEST */
+ printf("lapic%u: LINT%u trigger: %s\n", apic_id, pin,
+ edgetrigger ? "edge" : "level");
return (0);
}
@@ -434,12 +456,37 @@
if (vec == -1)
panic("Couldn't get vector from ISR!");
- isrc = intr_lookup_source(vec);
+ isrc = intr_lookup_source(apic_idt_to_irq(vec));
isrc->is_pic->pic_disable_source(isrc);
lapic->eoi = 0;
intr_execute_handlers(isrc, &frame);
}
+/* Translate between IDT vectors and IRQ vectors. */
+u_int
+apic_irq_to_idt(u_int irq)
+{
+ u_int vector;
+
+ KASSERT(irq < NUM_IO_INTS, ("Invalid IRQ %u", irq));
+ vector = irq + IDT_IO_INTS;
+ if (vector >= IDT_SYSCALL)
+ vector++;
+ return (vector);
+}
+
+u_int
+apic_idt_to_irq(u_int vector)
+{
+
+ KASSERT(vector >= IDT_IO_INTS && vector != IDT_SYSCALL &&
+ vector <= IDT_IO_INTS + NUM_IO_INTS,
+ ("Vector %u does not map to an IRQ line", vector));
+ if (vector > IDT_SYSCALL)
+ vector--;
+ return (vector - IDT_IO_INTS);
+}
+
/*
* APIC probing support code. This includes code to manage enumerators.
*/
==== //depot/projects/hammer/sys/amd64/amd64/mp_machdep.c#15 (text+ko) ====
@@ -76,29 +76,9 @@
#define BIOS_RESET (0x0f)
#define BIOS_WARM (0x0a)
-/*
- * Values to send to the POST hardware.
- */
-#define MP_BOOTADDRESS_POST 0x10
-#define MP_PROBE_POST 0x11
-#define MPTABLE_PASS1_POST 0x12
-
-#define MP_START_POST 0x13
-#define MP_ENABLE_POST 0x14
-#define MPTABLE_PASS2_POST 0x15
-
-#define START_ALL_APS_POST 0x16
-#define INSTALL_AP_TRAMP_POST 0x17
-#define START_AP_POST 0x18
-
-#define MP_ANNOUNCE_POST 0x19
-
/* lock region used by kernel profiling */
int mcount_lock;
-/** XXX FIXME: where does this really belong, isa.h/isa.c perhaps? */
-int current_postcode;
-
int mp_naps; /* # of Applications processors */
int boot_cpu_id = -1; /* designated BSP */
extern int nkpt;
@@ -160,7 +140,6 @@
static int start_all_aps(u_int boot_addr);
static void install_ap_tramp(u_int boot_addr);
static int start_ap(int apic_id, u_int boot_addr);
-void ap_init(void);
static void release_aps(void *dummy);
static int hlt_cpus_mask;
@@ -233,6 +212,16 @@
}
/* At least one CPU was found. */
+ if (mp_ncpus == 1) {
+ /*
+ * One CPU was found, so this must be a UP system with
+ * an I/O APIC.
+ */
+ mp_maxid = 0;
+ return (0);
+ }
+
+ /* At least two CPUs were found. */
KASSERT(mp_maxid >= mp_ncpus - 1,
("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
mp_ncpus));
@@ -311,21 +300,21 @@
printf(" cpu%d (AP): APIC ID: %2d\n", i++, x);
}
}
-
- /* XXX: List I/O APICs? They are done differently now. */
}
/*
- * AP cpu's call this to sync up protected mode.
+ * AP CPU's call this to initialize themselves.
*/
void
init_secondary(void)
{
int gsel_tss;
- int myid = bootAP;
+ int myid;
u_int64_t cr0;
struct pcpu *pc;
+ /* bootAP is set in start_ap() to our ID. */
+ myid = bootAP;
lgdt(&r_gdt); /* does magic intra-segment return */
pc = &__pcpu[myid];
@@ -354,7 +343,74 @@
mp_naps++;
- ap_init(); /* kick things off, this does not return */
+ /* spin until all the AP's are ready */
+ while (!aps_ready)
+ ia32_pause();
+
+ /* set up CPU registers and state */
+ cpu_setregs();
+
+ /* set up FPU state on the AP */
+ npxinit(__INITIAL_NPXCW__);
+
+ /* set up SSE registers */
+ enable_sse();
+
+ /* A quick check from sanity claus */
+ if (PCPU_GET(apic_id) != lapic_id()) {
+ printf("SMP: cpuid = %d\n", PCPU_GET(cpuid));
+ printf("SMP: actual apic_id = %d\n", lapic_id());
+ printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
+ panic("cpuid mismatch! boom!!");
+ }
+
+ /* Init local apic for irq's */
+ lapic_setup();
+
+ /* Set memory range attributes for this CPU to match the BSP */
+ mem_range_AP_init();
+
+ mtx_lock_spin(&ap_boot_mtx);
+
+ smp_cpus++;
+
+ CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", PCPU_GET(cpuid));
+ printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
+
+ /* Determine if we are a logical CPU. */
+ if (logical_cpus > 1 && PCPU_GET(apic_id) % logical_cpus != 0)
+ logical_cpus_mask |= PCPU_GET(cpumask);
+
+ /* Build our map of 'other' CPUs. */
+ PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
+
+#if 0
+ if (bootverbose)
+#endif
+ lapic_dump("AP");
+
+ if (smp_cpus == mp_ncpus) {
+ /* enable IPI's, tlb shootdown, freezes etc */
+ atomic_store_rel_int(&smp_started, 1);
+ smp_active = 1; /* historic */
+ }
+
+ mtx_unlock_spin(&ap_boot_mtx);
+
+ /* wait until all the AP's are up */
+ while (smp_started == 0)
+ ia32_pause();
+
+ /* ok, now grab sched_lock and enter the scheduler */
+ mtx_lock_spin(&sched_lock);
+
+ binuptime(PCPU_PTR(switchtime));
+ PCPU_SET(switchticks, ticks);
+
+ cpu_throw(NULL, choosethread()); /* doesn't return */
+
+ panic("scheduler returned us to %s", __func__);
+ /* NOTREACHED */
}
/*******************************************************************
@@ -781,83 +837,6 @@
/*
- * This is called once the rest of the system is up and running and we're
- * ready to let the AP's out of the pen.
- */
-void
-ap_init(void)
-{
-
- /* spin until all the AP's are ready */
- while (!aps_ready)
- ia32_pause();
-
- /* set up CPU registers and state */
- cpu_setregs();
-
- /* set up FPU state on the AP */
- npxinit(__INITIAL_NPXCW__);
-
- /* set up SSE registers */
- enable_sse();
-
- /* A quick check from sanity claus */
- if (PCPU_GET(apic_id) != lapic_id()) {
- printf("SMP: cpuid = %d\n", PCPU_GET(cpuid));
- printf("SMP: actual apic_id = %d\n", lapic_id());
- printf("SMP: correct apic_id = %d\n", PCPU_GET(apic_id));
- panic("cpuid mismatch! boom!!");
- }
-
- /* Init local apic for irq's */
- lapic_setup();
-
- /* Set memory range attributes for this CPU to match the BSP */
- mem_range_AP_init();
-
- mtx_lock_spin(&ap_boot_mtx);
-
- smp_cpus++;
-
- CTR1(KTR_SMP, "SMP: AP CPU #%d Launched", PCPU_GET(cpuid));
- printf("SMP: AP CPU #%d Launched!\n", PCPU_GET(cpuid));
-
- /* Determine if we are a logical CPU. */
- if (logical_cpus > 1 && PCPU_GET(apic_id) % logical_cpus != 0)
- logical_cpus_mask |= PCPU_GET(cpumask);
-
- /* Build our map of 'other' CPUs. */
- PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
-
-#if 0
- if (bootverbose)
-#endif
- lapic_dump("AP");
-
- if (smp_cpus == mp_ncpus) {
- /* enable IPI's, tlb shootdown, freezes etc */
- atomic_store_rel_int(&smp_started, 1);
- smp_active = 1; /* historic */
- }
-
- mtx_unlock_spin(&ap_boot_mtx);
-
- /* wait until all the AP's are up */
- while (smp_started == 0)
- ia32_pause();
-
- /* ok, now grab sched_lock and enter the scheduler */
- mtx_lock_spin(&sched_lock);
-
- binuptime(PCPU_PTR(switchtime));
- PCPU_SET(switchticks, ticks);
-
- cpu_throw(NULL, choosethread()); /* doesn't return */
-
- panic("scheduler returned us to %s", __func__);
-}
-
-/*
* For statclock, we send an IPI to all CPU's to have them call this
* function.
*/
@@ -966,6 +945,10 @@
lapic_ipi_vectored(ipi, APIC_IPI_DEST_SELF);
}
+/*
+ * This is called once the rest of the system is up and running and we're
+ * ready to let the AP's out of the pen.
+ */
static void
release_aps(void *dummy __unused)
{
@@ -978,7 +961,6 @@
ia32_pause();
mtx_unlock_spin(&sched_lock);
}
-
SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL);
static int
==== //depot/projects/hammer/sys/amd64/amd64/mpboot.s#8 (text+ko) ====
==== //depot/projects/hammer/sys/amd64/include/apicvar.h#6 (text+ko) ====
@@ -131,19 +131,22 @@
IDTVEC(apic_isr1), IDTVEC(apic_isr2), IDTVEC(apic_isr3),
IDTVEC(apic_isr4), IDTVEC(apic_isr5), IDTVEC(spuriousint);
+u_int apic_irq_to_idt(u_int irq);
+u_int apic_idt_to_irq(u_int vector);
void apic_register_enumerator(struct apic_enumerator *enumerator);
void *ioapic_create(uintptr_t addr, int32_t id, int intbase);
int ioapic_disable_pin(void *cookie, u_int pin);
int ioapic_get_vector(void *cookie, u_int pin);
int ioapic_next_logical_cluster(void);
+void ioapic_register(void *cookie);
+int ioapic_remap_vector(void *cookie, u_int pin, int vector);
int ioapic_set_extint(void *cookie, u_int pin);
int ioapic_set_nmi(void *cookie, u_int pin);
int ioapic_set_polarity(void *cookie, u_int pin, char activehi);
int ioapic_set_triggermode(void *cookie, u_int pin, char edgetrigger);
int ioapic_set_smi(void *cookie, u_int pin);
-int ioapic_remap_vector(void *cookie, u_int pin, int vector);
-void ioapic_register(void *cookie);
void lapic_create(u_int apic_id, int boot_cpu);
+void lapic_disable(void);
void lapic_dump(const char *str);
void lapic_enable_intr(u_int vector);
int lapic_id(void);
==== //depot/projects/hammer/sys/amd64/include/intr_machdep.h#4 (text+ko) ====
@@ -31,8 +31,8 @@
#ifdef _KERNEL
-/* With I/O APIC's we can have up to 160 interrupts. */
-#define NUM_IO_INTS 160
+/* With I/O APIC's we can have up to 159 interrupts. */
+#define NUM_IO_INTS 159
#define INTRCNT_COUNT (1 + NUM_IO_INTS * 2)
#ifndef LOCORE
@@ -77,9 +77,6 @@
extern struct mtx icu_lock;
-/* XXX: Does this belong in icu.h? */
-void atpic_startup(void);
-
int intr_add_handler(const char *name, int vector, driver_intr_t handler,
void *arg, enum intr_type flags, void **cookiep);
void intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe);
@@ -89,8 +86,6 @@
void intr_resume(void);
void intr_suspend(void);
-int isa_nmi(int cd);
-
#endif /* !LOCORE */
#endif /* _KERNEL */
#endif /* !__MACHINE_INTR_MACHDEP_H__ */
==== //depot/projects/hammer/sys/amd64/isa/atpic.c#6 (text+ko) ====
@@ -65,16 +65,6 @@
unsigned int imen; /* XXX */
inthand_t
- IDTVEC(atpic_fastintr0), IDTVEC(atpic_fastintr1),
- IDTVEC(atpic_fastintr2), IDTVEC(atpic_fastintr3),
- IDTVEC(atpic_fastintr4), IDTVEC(atpic_fastintr5),
- IDTVEC(atpic_fastintr6), IDTVEC(atpic_fastintr7),
- IDTVEC(atpic_fastintr8), IDTVEC(atpic_fastintr9),
- IDTVEC(atpic_fastintr10), IDTVEC(atpic_fastintr11),
- IDTVEC(atpic_fastintr12), IDTVEC(atpic_fastintr13),
- IDTVEC(atpic_fastintr14), IDTVEC(atpic_fastintr15);
-
-inthand_t
IDTVEC(atpic_intr0), IDTVEC(atpic_intr1), IDTVEC(atpic_intr2),
IDTVEC(atpic_intr3), IDTVEC(atpic_intr4), IDTVEC(atpic_intr5),
IDTVEC(atpic_intr6), IDTVEC(atpic_intr7), IDTVEC(atpic_intr8),
@@ -87,35 +77,26 @@
#define ATPIC(io, base, eoi, imenptr) \
{ { atpic_enable_source, atpic_disable_source, (eoi), \
atpic_enable_intr, atpic_vector, atpic_source_pending, NULL, \
- atpic_resume }, (io), (base), IRQ_TO_IDT(base), (imenptr) }
+ atpic_resume }, (io), (base), IDT_IO_INTS + (base), (imenptr) }
#define INTSRC(irq) \
- { { (struct pic *)(&atpics[(irq) / 8]) }, (irq) % 8, \
- IDTVEC(atpic_fastintr ## irq ), IDTVEC(atpic_intr ## irq ) }
+ { { &atpics[(irq) / 8].at_pic }, (irq) % 8, \
+ IDTVEC(atpic_intr ## irq ) }
struct atpic {
struct pic at_pic;
int at_ioaddr;
int at_irqbase;
- uint16_t at_intbase;
+ uint8_t at_intbase;
uint8_t *at_imen;
};
struct atpic_intsrc {
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list