Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Oct 2003 17:06:34 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 39483 for review
Message-ID:  <200310110006.h9B06YeQ042833@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=39483

Change 39483 by peter@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) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310110006.h9B06YeQ042833>