reactos/hal/halx86
diff -u -r1.10 -r1.11
--- mp.c 20 Jul 2004 21:25:36 -0000 1.10
+++ mp.c 1 Nov 2004 19:01:25 -0000 1.11
@@ -1,4 +1,4 @@
-/* $Id: mp.c,v 1.10 2004/07/20 21:25:36 hbirr Exp $
+/* $Id: mp.c,v 1.11 2004/11/01 19:01:25 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@@ -14,15 +14,14 @@
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
#include <roscfg.h>
+#include <ddk/ntddk.h>
-#define NDEBUG
-#include <internal/debug.h>
#ifdef MP
#include <hal.h>
+#include <halirq.h>
#include <mps.h>
#include <internal/ntoskrnl.h>
@@ -30,6 +29,14 @@
#include <internal/ke.h>
#include <internal/ps.h>
+#endif
+
+#define NDEBUG
+#include <internal/debug.h>
+
+#ifdef MP
+
+
/*
Address of area to be used for communication between Application
Processors (APs) and the BootStrap Processor (BSP)
@@ -56,6 +63,8 @@
MP_CONFIGURATION_INTSRC IRQMap[MAX_IRQ_SOURCE]; /* Map of all IRQs */
ULONG IRQVectorMap[MAX_IRQ_SOURCE]; /* IRQ to vector map */
+ULONG IrqPinMap[MAX_IRQ_SOURCE]; /* IRQ to Pin map */
+ULONG IrqApicMap[MAX_IRQ_SOURCE];
ULONG IRQCount; /* Number of IRQs */
ULONG APICMode; /* APIC mode at startup */
@@ -83,7 +92,6 @@
})
static BOOLEAN MPSInitialized = FALSE; /* Is the MP system initialized? */
-static KDPC RescheduleDpc;
VOID APICDisable(VOID);
static VOID APICSyncArbIDs(VOID);
@@ -105,45 +113,47 @@
/* Functions for handling 8259A PICs */
-VOID Disable8259AIrq(
- ULONG irq)
+VOID Disable8259AIrq(ULONG irq)
{
- ULONG tmp;
+ ULONG tmp;
- if (irq & 8) {
- tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
- tmp |= (1 << irq);
- WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
- } else {
- tmp = READ_PORT_UCHAR((PUCHAR)0x21);
- tmp |= (1 << irq);
- WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
- }
+ if (irq & 8)
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
+ tmp |= (1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
+ }
+ else
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0x21);
+ tmp |= (1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
+ }
}
-VOID Enable8259AIrq(
- ULONG irq)
+VOID Enable8259AIrq(ULONG irq)
{
- ULONG tmp;
+ ULONG tmp;
- if (irq & 8) {
- tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
- tmp &= ~(1 << irq);
- WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
- } else {
- tmp = READ_PORT_UCHAR((PUCHAR)0x21);
- tmp &= ~(1 << irq);
- WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
- }
+ if (irq & 8)
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0xA1);
+ tmp &= ~(1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0xA1, tmp);
+ }
+ else
+ {
+ tmp = READ_PORT_UCHAR((PUCHAR)0x21);
+ tmp &= ~(1 << irq);
+ WRITE_PORT_UCHAR((PUCHAR)0x21, tmp);
+ }
}
/* Functions for handling I/O APICs */
-volatile ULONG IOAPICRead(
- ULONG Apic,
- ULONG Offset)
+volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset)
{
PULONG Base;
@@ -152,10 +162,7 @@
return *((PULONG)((ULONG)Base + IOAPIC_IOWIN));
}
-VOID IOAPICWrite(
- ULONG Apic,
- ULONG Offset,
- ULONG Value)
+VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value)
{
PULONG Base;
@@ -165,65 +172,62 @@
}
-VOID IOAPICClearPin(
- ULONG Apic,
- ULONG Pin)
+VOID IOAPICClearPin(ULONG Apic, ULONG Pin)
{
IOAPIC_ROUTE_ENTRY Entry;
/*
* Disable it in the IO-APIC irq-routing table
*/
- memset(&Entry, 0, sizeof(Entry));
- Entry.mask = 1;
+ memset(&Entry, 0, sizeof(Entry));
+ Entry.mask = 1;
- IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
- IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
+ IOAPICWrite(Apic, IOAPIC_REDTBL + 2 * Pin, *(((PULONG)&Entry) + 0));
+ IOAPICWrite(Apic, IOAPIC_REDTBL + 1 + 2 * Pin, *(((PULONG)&Entry) + 1));
}
-static VOID IOAPICClear(
- ULONG Apic)
+static VOID IOAPICClear(ULONG Apic)
{
- ULONG Pin;
+ ULONG Pin;
- for (Pin = 0; Pin < IOAPICMap[Apic].EntryCount; Pin++)
- IOAPICClearPin(Apic, Pin);
+ for (Pin = 0; Pin < /*IOAPICMap[Apic].EntryCount*/24; Pin++)
+ {
+ IOAPICClearPin(Apic, Pin);
+ }
}
-static VOID IOAPICClearAll(
- VOID)
+static VOID IOAPICClearAll(VOID)
{
ULONG Apic;
- for (Apic = 0; Apic < IOAPICCount; Apic++)
- IOAPICClear(Apic);
+ for (Apic = 0; Apic < IOAPICCount; Apic++)
+ {
+ IOAPICClear(Apic);
+ }
}
/* This is performance critical and should probably be done in assembler */
-VOID IOAPICMaskIrq(
- ULONG Apic,
- ULONG Irq)
+VOID IOAPICMaskIrq(ULONG Irq)
{
IOAPIC_ROUTE_ENTRY Entry;
+ ULONG Apic = IrqApicMap[Irq];
- *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
- Entry.mask = 1;
- IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
+ *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
+ Entry.mask = 1;
+ IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
}
/* This is performance critical and should probably be done in assembler */
-VOID IOAPICUnmaskIrq(
- ULONG Apic,
- ULONG Irq)
+VOID IOAPICUnmaskIrq(ULONG Irq)
{
IOAPIC_ROUTE_ENTRY Entry;
+ ULONG Apic = IrqApicMap[Irq];
- *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*Irq);
+ *((PULONG)&Entry) = IOAPICRead(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq]);
Entry.mask = 0;
-
- IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
+ IOAPICWrite(Apic, IOAPIC_REDTBL+2*IrqPinMap[Irq], *((PULONG)&Entry));
}
static VOID
@@ -235,14 +239,16 @@
/*
* Set the IOAPIC ID to the value stored in the MPC table.
*/
- for (apic = 0; apic < IOAPICCount; apic++) {
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
/* Read the register 0 value */
tmp = IOAPICRead(apic, IOAPIC_ID);
old_id = IOAPICMap[apic].ApicId;
- if (IOAPICMap[apic].ApicId >= 0xf) {
+ if (IOAPICMap[apic].ApicId >= 0xf)
+ {
DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, IOAPICMap[apic].ApicId);
DPRINT1("... fixing up to %d. (tell your hw vendor)\n",
@@ -255,9 +261,15 @@
* if the ID changed.
*/
if (old_id != IOAPICMap[apic].ApicId)
+ {
for (i = 0; i < IRQCount; i++)
+ {
if (IRQMap[i].DstApicId == old_id)
+ {
IRQMap[i].DstApicId = IOAPICMap[apic].ApicId;
+ }
+ }
+ }
/*
* Read the right value from the MPC table and
@@ -275,7 +287,8 @@
* Sanity check
*/
tmp = IOAPICRead(apic, 0);
- if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId) {
+ if (GET_IOAPIC_ID(tmp) != IOAPICMap[apic].ApicId)
+ {
DPRINT1("Could not set I/O APIC ID!\n");
KEBUGCHECK(0);
}
@@ -286,15 +299,15 @@
/*
* EISA Edge/Level control register, ELCR
*/
-static ULONG EISA_ELCR(
- ULONG irq)
+static ULONG EISA_ELCR(ULONG irq)
{
- if (irq < 16) {
- PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
- return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
- }
- DPRINT("Broken MPtable reports ISA irq %d\n", irq);
- return 0;
+ if (irq < 16)
+ {
+ PUCHAR port = (PUCHAR)(0x4d0 + (irq >> 3));
+ return (READ_PORT_UCHAR(port) >> (irq & 7)) & 1;
+ }
+ DPRINT("Broken MPtable reports ISA irq %d\n", irq);
+ return 0;
}
/* EISA interrupts are always polarity zero and can be edge or level
@@ -323,8 +336,7 @@
#define default_MCA_trigger(idx) (1)
#define default_MCA_polarity(idx) (0)
-static ULONG IRQPolarity(
- ULONG idx)
+static ULONG IRQPolarity(ULONG idx)
{
ULONG bus = IRQMap[idx].SrcBusId;
ULONG polarity;
@@ -393,8 +405,7 @@
return polarity;
}
-static ULONG IRQTrigger(
- ULONG idx)
+static ULONG IRQTrigger(ULONG idx)
{
ULONG bus = IRQMap[idx].SrcBusId;
ULONG trigger;
@@ -464,10 +475,9 @@
}
-static ULONG Pin2Irq(
- ULONG idx,
- ULONG apic,
- ULONG pin)
+static ULONG Pin2Irq(ULONG idx,
+ ULONG apic,
+ ULONG pin)
{
ULONG irq, i;
ULONG bus = IRQMap[idx].SrcBusId;
@@ -534,62 +544,68 @@
* shared ISA-space IRQs, so we have to support them. We are super
* fast in the common case, and fast for shared ISA-space IRQs.
*/
-static VOID AddPinToIrq(
- ULONG irq,
- ULONG apic,
- ULONG pin)
-{
- static ULONG first_free_entry = PIC_IRQS;
- struct irq_pin_list *entry = irq_2_pin + irq;
-
- while (entry->next)
- entry = irq_2_pin + entry->next;
-
- if (entry->pin != -1) {
- entry->next = first_free_entry;
- entry = irq_2_pin + entry->next;
- if (++first_free_entry >= PIN_MAP_SIZE) {
- DPRINT1("Ohh no!");
- KEBUGCHECK(0);
- }
- }
- entry->apic = apic;
- entry->pin = pin;
+static VOID AddPinToIrq(ULONG irq,
+ ULONG apic,
+ ULONG pin)
+{
+ static ULONG first_free_entry = PIC_IRQS;
+ struct irq_pin_list *entry = irq_2_pin + irq;
+
+ while (entry->next)
+ {
+ entry = irq_2_pin + entry->next;
+ }
+
+ if (entry->pin != -1)
+ {
+ entry->next = first_free_entry;
+ entry = irq_2_pin + entry->next;
+ if (++first_free_entry >= PIN_MAP_SIZE)
+ {
+ DPRINT1("Ohh no!");
+ KEBUGCHECK(0);
+ }
+ }
+ entry->apic = apic;
+ entry->pin = pin;
}
/*
* Find the IRQ entry number of a certain pin.
*/
-static ULONG IOAPICGetIrqEntry(
- ULONG apic,
- ULONG pin,
- ULONG type)
+static ULONG IOAPICGetIrqEntry(ULONG apic,
+ ULONG pin,
+ ULONG type)
{
- ULONG i;
+ ULONG i;
- for (i = 0; i < IRQCount; i++)
- if (IRQMap[i].IrqType == type &&
- (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId ||
- IRQMap[i].DstApicId == MP_APIC_ALL) &&
- IRQMap[i].DstApicInt == pin)
- return i;
-
- return -1;
+ for (i = 0; i < IRQCount; i++)
+ {
+ if (IRQMap[i].IrqType == type &&
+ (IRQMap[i].DstApicId == IOAPICMap[apic].ApicId || IRQMap[i].DstApicId == MP_APIC_ALL) &&
+ IRQMap[i].DstApicInt == pin)
+ {
+ return i;
+ }
+ }
+ return -1;
}
-static ULONG AssignIrqVector(
- ULONG irq)
+static ULONG AssignIrqVector(ULONG irq)
{
+#if 0
static ULONG current_vector = FIRST_DEVICE_VECTOR, vector_offset = 0;
+#endif
ULONG vector;
-
/* There may already have been assigned a vector for this IRQ */
vector = IRQVectorMap[irq];
if (vector > 0)
+ {
return vector;
-
+ }
+#if 0
if (current_vector > FIRST_SYSTEM_VECTOR) {
vector_offset++;
current_vector = FIRST_DEVICE_VECTOR + vector_offset;
@@ -602,243 +618,281 @@
IRQVectorMap[irq] = vector;
current_vector += 8;
return vector;
+#else
+ vector = IRQ2VECTOR(irq);
+ IRQVectorMap[irq] = vector;
+ return vector;
+#endif
}
-VOID IOAPICSetupIrqs(
- VOID)
+VOID IOAPICSetupIrqs(VOID)
{
- IOAPIC_ROUTE_ENTRY entry;
- ULONG apic, pin, idx, irq, first_notcon = 1, vector;
+ IOAPIC_ROUTE_ENTRY entry;
+ ULONG apic, pin, idx, irq, first_notcon = 1, vector;
- DPRINT("Init IO_APIC IRQs\n");
+ DPRINT("Init IO_APIC IRQs\n");
- for (apic = 0; apic < IOAPICCount; apic++) {
- for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++) {
-
- /*
- * add it to the IO-APIC irq-routing table
- */
- memset(&entry,0,sizeof(entry));
-
- entry.delivery_mode = APIC_DM_LOWEST;
- entry.dest_mode = 1; /* logical delivery */
- entry.mask = 0; /* enable IRQ */
- entry.dest.logical.logical_dest = OnlineCPUs;
-
- idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
- if (idx == -1) {
- if (first_notcon) {
- DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
- first_notcon = 0;
- } else {
- DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
- }
- continue;
- }
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+ for (pin = 0; pin < IOAPICMap[apic].EntryCount; pin++)
+ {
+ /*
+ * add it to the IO-APIC irq-routing table
+ */
+ memset(&entry,0,sizeof(entry));
+
+ entry.delivery_mode = APIC_DM_LOWEST;
+ entry.dest_mode = 1; /* logical delivery */
+ entry.mask = 1; /* disable IRQ */
+#if 0
+ /*
+ * FIXME:
+ * Some drivers are not able to deal with more than one cpu.
+ */
+ entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+ entry.dest.logical.logical_dest = 1 << BootCPU;
+#endif
+ idx = IOAPICGetIrqEntry(apic,pin,INT_VECTORED);
+ if (idx == -1)
+ {
+ if (first_notcon)
+ {
+ DPRINT(" IO-APIC (apicid-pin) %d-%d\n", IOAPICMap[apic].ApicId, pin);
+ first_notcon = 0;
+ }
+ else
+ {
+ DPRINT(", %d-%d\n", IOAPICMap[apic].ApicId, pin);
+ }
+ continue;
+ }
- entry.trigger = IRQTrigger(idx);
- entry.polarity = IRQPolarity(idx);
+ entry.trigger = IRQTrigger(idx);
+ entry.polarity = IRQPolarity(idx);
- if (entry.trigger) {
- entry.trigger = 1;
- entry.mask = 1;
- entry.dest.logical.logical_dest = OnlineCPUs;
- }
+ if (entry.trigger)
+ {
+ entry.trigger = 1;
+ entry.mask = 1; // disable
+#if 0
+ entry.dest.logical.logical_dest = OnlineCPUs;
+#else
+ entry.dest.logical.logical_dest = 1 << BootCPU;
+#endif
+ }
- irq = Pin2Irq(idx, apic, pin);
- AddPinToIrq(irq, apic, pin);
+ irq = Pin2Irq(idx, apic, pin);
+ AddPinToIrq(irq, apic, pin);
- vector = AssignIrqVector(irq);
- entry.vector = vector;
+ vector = AssignIrqVector(irq);
+ entry.vector = vector;
- DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
+ DPRINT("vector 0x%.08x assigned to irq 0x%.02x\n", vector, irq);
- if (irq == 0)
- {
- /* Mask timer IRQ */
- entry.mask = 1;
- }
+ if (irq == 0)
+ {
+ /* Mask timer IRQ */
+ entry.mask = 1;
+ }
- if ((apic == 0) && (irq < 16))
- Disable8259AIrq(irq);
+ if ((apic == 0) && (irq < 16))
+ {
+ Disable8259AIrq(irq);
+ }
+ IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
+ IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
- IOAPICWrite(apic, IOAPIC_REDTBL+2*pin+1, *(((PULONG)&entry)+1));
- IOAPICWrite(apic, IOAPIC_REDTBL+2*pin, *(((PULONG)&entry)+0));
- }
- }
+ IrqPinMap[irq] = pin;
+ IrqApicMap[irq] = apic;
+
+ DPRINT("Vector %x, Pin %x, Irq %x\n", vector, pin, irq);
+ }
+ }
}
-static VOID IOAPICEnable(
- VOID)
+static VOID IOAPICEnable(VOID)
{
- ULONG i, tmp;
+ ULONG i, tmp;
- for (i = 0; i < PIN_MAP_SIZE; i++) {
- irq_2_pin[i].pin = -1;
- irq_2_pin[i].next = 0;
- }
+ for (i = 0; i < PIN_MAP_SIZE; i++)
+ {
+ irq_2_pin[i].pin = -1;
+ irq_2_pin[i].next = 0;
+ }
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
- for (i = 0; i < IOAPICCount; i++) {
- tmp = IOAPICRead(i, IOAPIC_VER);
- IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
- }
+ /*
+ * The number of IO-APIC IRQ registers (== #pins):
+ */
+ for (i = 0; i < IOAPICCount; i++)
+ {
+ tmp = IOAPICRead(i, IOAPIC_VER);
+ IOAPICMap[i].EntryCount = GET_IOAPIC_MRE(tmp) + 1;
+ }
- /*
- * Do not trust the IO-APIC being empty at bootup
- */
- IOAPICClearAll();
+ /*
+ * Do not trust the IO-APIC being empty at bootup
+ */
+ IOAPICClearAll();
}
#if 0
-static VOID IOAPICDisable(
- VOID)
+static VOID IOAPICDisable(VOID)
{
- /*
- * Clear the IO-APIC before rebooting
- */
- IOAPICClearAll();
-
- APICDisable();
+ /*
+ * Clear the IO-APIC before rebooting
+ */
+ IOAPICClearAll();
+ APICDisable();
}
#endif
-static VOID IOAPICSetup(
- VOID)
+static VOID IOAPICSetup(VOID)
{
IOAPICEnable();
IOAPICSetupIds();
- if (0) {
- // FIXME: This causes application processors to not boot if asked to
- APICSyncArbIDs();
- }
+ APICSyncArbIDs();
IOAPICSetupIrqs();
}
VOID IOAPICDump(VOID)
{
- ULONG apic, i;
- ULONG reg0, reg1, reg2=0;
+ ULONG apic, i;
+ ULONG reg0, reg1, reg2=0;
- DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
- for (i = 0; i < IOAPICCount; i++) {
- DbgPrint("Number of IO-APIC #%d registers: %d.\n",
- IOAPICMap[i].ApicId,
- IOAPICMap[i].EntryCount);
- }
+ DbgPrint("Number of MP IRQ sources: %d.\n", IRQCount);
+ for (i = 0; i < IOAPICCount; i++)
+ {
+ DbgPrint("Number of IO-APIC #%d registers: %d.\n",
+ IOAPICMap[i].ApicId,
+ IOAPICMap[i].EntryCount);
+ }
- /*
- * We are a bit conservative about what we expect. We have to
- * know about every hardware change ASAP.
- */
- DbgPrint("Testing the IO APIC.......................\n");
+ /*
+ * We are a bit conservative about what we expect. We have to
+ * know about every hardware change ASAP.
+ */
+ DbgPrint("Testing the IO APIC.......................\n");
- for (apic = 0; apic < IOAPICCount; apic++) {
+ for (apic = 0; apic < IOAPICCount; apic++)
+ {
+ reg0 = IOAPICRead(apic, IOAPIC_ID);
+ reg1 = IOAPICRead(apic, IOAPIC_VER);
+ if (GET_IOAPIC_VERSION(reg1) >= 0x10)
+ {
+ reg2 = IOAPICRead(apic, IOAPIC_ARB);
+ }
- reg0 = IOAPICRead(apic, IOAPIC_ID);
- reg1 = IOAPICRead(apic, IOAPIC_VER);
- if (GET_IOAPIC_VERSION(reg1) >= 0x10) {
- reg2 = IOAPICRead(apic, IOAPIC_ARB);
- }
+ DbgPrint("\n");
+ DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
+ DbgPrint(".... register #00: %08X\n", reg0);
+ DbgPrint("....... : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
+ if (reg0 & 0xF0FFFFFF)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
- DbgPrint("\n");
- DbgPrint("IO APIC #%d......\n", IOAPICMap[apic].ApicId);
- DbgPrint(".... register #00: %08X\n", reg0);
- DbgPrint("....... : physical APIC id: %02X\n", GET_IOAPIC_ID(reg0));
- if (reg0 & 0xF0FFFFFF) {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
+ DbgPrint(".... register #01: %08X\n", reg1);
+ i = GET_IOAPIC_MRE(reg1);
- DbgPrint(".... register #01: %08X\n", reg1);
- i = GET_IOAPIC_MRE(reg1);
+ DbgPrint("....... : max redirection entries: %04X\n", i);
+ if ((i != 0x0f) && /* older (Neptune) boards */
+ (i != 0x17) && /* typical ISA+PCI boards */
+ (i != 0x1b) && /* Compaq Proliant boards */
+ (i != 0x1f) && /* dual Xeon boards */
+ (i != 0x22) && /* bigger Xeon boards */
+ (i != 0x2E) &&
+ (i != 0x3F))
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
- DbgPrint("....... : max redirection entries: %04X\n", i);
- if ((i != 0x0f) && /* older (Neptune) boards */
- (i != 0x17) && /* typical ISA+PCI boards */
- (i != 0x1b) && /* Compaq Proliant boards */
- (i != 0x1f) && /* dual Xeon boards */
- (i != 0x22) && /* bigger Xeon boards */
- (i != 0x2E) &&
- (i != 0x3F)) {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
+ i = GET_IOAPIC_VERSION(reg1);
+ DbgPrint("....... : IO APIC version: %04X\n", i);
+ if ((i != 0x01) && /* 82489DX IO-APICs */
+ (i != 0x10) && /* oldest IO-APICs */
+ (i != 0x11) && /* Pentium/Pro IO-APICs */
+ (i != 0x13)) /* Xeon IO-APICs */
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
- i = GET_IOAPIC_VERSION(reg1);
- DbgPrint("....... : IO APIC version: %04X\n", i);
- if ((i != 0x01) && /* 82489DX IO-APICs */
- (i != 0x10) && /* oldest IO-APICs */
- (i != 0x11) && /* Pentium/Pro IO-APICs */
- (i != 0x13)) { /* Xeon IO-APICs */
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
+ if (reg1 & 0xFF00FF00)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
- if (reg1 & 0xFF00FF00) {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
+ if (GET_IOAPIC_VERSION(reg1) >= 0x10)
+ {
+ DbgPrint(".... register #02: %08X\n", reg2);
+ DbgPrint("....... : arbitration: %02X\n",
+ GET_IOAPIC_ARB(reg2));
+ if (reg2 & 0xF0FFFFFF)
+ {
+ DbgPrint(" WARNING: Unexpected IO-APIC\n");
+ }
+ }
- if (GET_IOAPIC_VERSION(reg1) >= 0x10) {
- DbgPrint(".... register #02: %08X\n", reg2);
- DbgPrint("....... : arbitration: %02X\n",
- GET_IOAPIC_ARB(reg2));
- if (reg2 & 0xF0FFFFFF) {
- DbgPrint(" WARNING: Unexpected IO-APIC\n");
- }
- }
+ DbgPrint(".... IRQ redirection table:\n");
+ DbgPrint(" NR Log Phy Mask Trig IRR Pol"
+ " Stat Dest Deli Vect: \n");
- DbgPrint(".... IRQ redirection table:\n");
- DbgPrint(" NR Log Phy Mask Trig IRR Pol"
- " Stat Dest Deli Vect: \n");
-
- for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++) {
- IOAPIC_ROUTE_ENTRY entry;
-
- *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
- *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
-
- DbgPrint(" %02x %03X %02X ",
- i,
- entry.dest.logical.logical_dest,
- entry.dest.physical.physical_dest
- );
-
- DbgPrint("%C %C %1d %C %C %C %03X %02X\n",
- (entry.mask == 0) ? 'U' : 'M', // Unmasked/masked
- (entry.trigger == 0) ? 'E' : 'L', // Edge/level sensitive
- entry.irr,
- (entry.polarity == 0) ? 'H' : 'L', // Active high/active low
- (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
- (entry.dest_mode == 0) ? 'P' : 'L', // Physical logical
- entry.delivery_mode,
- entry.vector
- );
- }
- }
- DbgPrint("IRQ to pin mappings:\n");
- for (i = 0; i < PIC_IRQS; i++) {
- struct irq_pin_list *entry = irq_2_pin + i;
- if (entry->pin < 0)
- continue;
- DbgPrint("IRQ%d ", i);
- for (;;) {
- DbgPrint("-> %d", entry->pin);
- if (!entry->next)
- break;
- entry = irq_2_pin + entry->next;
- }
- if (i % 2) {
- DbgPrint("\n");
- } else {
- DbgPrint(" ");
- }
- }
+ for (i = 0; i <= GET_IOAPIC_MRE(reg1); i++)
+ {
+ IOAPIC_ROUTE_ENTRY entry;
- DbgPrint(".................................... done.\n");
+ *(((PULONG)&entry)+0) = IOAPICRead(apic, 0x10+i*2);
+ *(((PULONG)&entry)+1) = IOAPICRead(apic, 0x11+i*2);
+
+ DbgPrint(" %02x %03X %02X ",
+ i,
+ entry.dest.logical.logical_dest,
+ entry.dest.physical.physical_dest);
+
+ DbgPrint("%C %C %1d %C %C %C %03X %02X\n",
+ (entry.mask == 0) ? 'U' : 'M', // Unmasked/masked
+ (entry.trigger == 0) ? 'E' : 'L', // Edge/level sensitive
+ entry.irr,
+ (entry.polarity == 0) ? 'H' : 'L', // Active high/active low
+ (entry.delivery_status == 0) ? 'I' : 'S', // Idle / send pending
+ (entry.dest_mode == 0) ? 'P' : 'L', // Physical logical
+ entry.delivery_mode,
+ entry.vector);
+ }
+ }
+ DbgPrint("IRQ to pin mappings:\n");
+ for (i = 0; i < PIC_IRQS; i++)
+ {
+ struct irq_pin_list *entry = irq_2_pin + i;
+ if (entry->pin < 0)
+ {
+ continue;
+ }
+ DbgPrint("IRQ%d ", i);
+ for (;;)
+ {
+ DbgPrint("-> %d", entry->pin);
+ if (!entry->next)
+ {
+ break;
+ }
+ entry = irq_2_pin + entry->next;
+ }
+ if (i % 2)
+ {
+ DbgPrint("\n");
+ }
+ else
+ {
+ DbgPrint(" ");
+ }
+ }
+
+ DbgPrint(".................................... done.\n");
}
@@ -846,8 +900,7 @@
/* Functions for handling local APICs */
#if 0
-volatile inline ULONG APICRead(
- ULONG Offset)
+volatile inline ULONG APICRead(ULONG Offset)
{
PULONG p;
@@ -855,27 +908,23 @@
return *p;
}
#else
-volatile inline ULONG APICRead(
- ULONG Offset)
+volatile inline ULONG APICRead(ULONG Offset)
{
PULONG p;
lastregr = Offset;
lastvalr = 0;
- //DPRINT1("R(0x%X)", Offset);
p = (PULONG)((ULONG)APICBase + Offset);
- lastvalr = *p;
- //DPRINT1("(0x%08X)\n", *p);
+ lastvalr = *p;
return lastvalr;
}
#endif
#if 0
-inline VOID APICWrite(
- ULONG Offset,
- ULONG Value)
+inline VOID APICWrite(ULONG Offset,
+ ULONG Value)
{
PULONG p;
@@ -884,16 +933,14 @@
*p = Value;
}
#else
-inline VOID APICWrite(
- ULONG Offset,
- ULONG Value)
+inline VOID APICWrite(ULONG Offset,
+ ULONG Value)
{
PULONG p;
lastregw = Offset;
lastvalw = Value;
- //DPRINT1("W(0x%X, 0x%08X)\n", Offset, Value);
p = (PULONG)((ULONG)APICBase + Offset);
*p = Value;
@@ -903,8 +950,6 @@
inline VOID APICSendEOI(VOID)
{
- // Dummy read
- APICRead(APIC_SIVR);
// Send the EOI
APICWrite(APIC_EOI, 0);
}
@@ -915,7 +960,9 @@
ULONG tmp;
if (CPUMap[ThisCPU()].MaxLVT > 3)
+ {
APICWrite(APIC_ESR, 0);
+ }
tmp = APICRead(APIC_ESR);
DbgPrint("ESR %08x\n", tmp);
}
@@ -923,19 +970,18 @@
ULONG APICGetMaxLVT(VOID)
{
[truncated at 1000 lines; 1692 more skipped]
reactos/hal/halx86
diff -u -r1.10 -r1.11
--- mpsirql.c 20 Jul 2004 21:25:36 -0000 1.10
+++ mpsirql.c 1 Nov 2004 19:01:25 -0000 1.11
@@ -11,10 +11,12 @@
/* INCLUDES *****************************************************************/
+#include <roscfg.h>
#include <ddk/ntddk.h>
#include <internal/ke.h>
#include <internal/ps.h>
#include <ntos/minmax.h>
+#include <halirq.h>
#include <hal.h>
#include <mps.h>
@@ -23,20 +25,10 @@
/* GLOBALS ******************************************************************/;
-#define IRQ_BASE (0x30)
-#define NR_VECTORS (0x100 - IRQ_BASE)
-
-extern IMPORTED ULONG DpcQueueSize;
-
-static ULONG HalpPendingInterruptCount[NR_VECTORS];
-
-static VOID KeSetCurrentIrql (KIRQL newlvl);
VOID STDCALL
KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
-#define IRQL2TPR(irql) (FIRST_DEVICE_VECTOR + ((irql - DISPATCH_LEVEL /* 2 */ - 1) * 8))
-
/* FUNCTIONS ****************************************************************/
KIRQL STDCALL KeGetCurrentIrql (VOID)
@@ -45,100 +37,66 @@
* RETURNS: The current irq level
*/
{
- if (KeGetCurrentKPCR ()->Irql > HIGH_LEVEL)
+ KIRQL irql;
+ ULONG Flags;
+
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ irql = KeGetCurrentKPCR()->Irql;
+ Ki386RestoreFlags(Flags);
+
+ if (irql > HIGH_LEVEL)
{
- DPRINT1 ("CurrentIrql %x\n", KeGetCurrentKPCR ()->Irql);
+ DPRINT1 ("CurrentIrql %x\n", irql);
KEBUGCHECK (0);
for(;;);
}
-
- return(KeGetCurrentKPCR ()->Irql);
+ return irql;
}
-static VOID KeSetCurrentIrql (KIRQL NewIrql)
+VOID KeSetCurrentIrql (KIRQL NewIrql)
/*
* PURPOSE: Sets the current irq level without taking any action
*/
{
+ ULONG Flags;
if (NewIrql > HIGH_LEVEL)
{
DPRINT1 ("NewIrql %x\n", NewIrql);
KEBUGCHECK (0);
for(;;);
}
-
- KeGetCurrentKPCR ()->Irql = NewIrql;
-}
-
-
-VOID HalpEndSystemInterrupt (KIRQL Irql)
-/*
- * FUNCTION: Enable all irqs with higher priority.
- */
-{
- ULONG flags;
- /* Interrupts should be disabled while enabling irqs */
- Ki386SaveFlags(flags);
+ Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
- APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
- Ki386RestoreFlags(flags);
+ KeGetCurrentKPCR()->Irql = NewIrql;
+ Ki386RestoreFlags(Flags);
}
-VOID STATIC
-HalpExecuteIrqs(KIRQL NewIrql)
-{
- ULONG VectorLimit, i;
-
- VectorLimit = min(IRQL2VECTOR (NewIrql), NR_VECTORS);
- /*
- * For each vector if there have been any deferred interrupts then now
- * dispatch them.
- */
- for (i = 0; i < VectorLimit; i++)
- {
- if (HalpPendingInterruptCount[i] > 0)
- {
- KeSetCurrentIrql (VECTOR2IRQL (i));
-
- while (HalpPendingInterruptCount[i] > 0)
- {
- /*
- * For each deferred interrupt execute all the handlers at DIRQL.
- */
- KiInterruptDispatch2 (i, NewIrql);
- HalpPendingInterruptCount[i]--;
- }
- KeSetCurrentIrql (KeGetCurrentIrql () - 1);
- HalpEndSystemInterrupt (KeGetCurrentIrql ());
- }
- }
-}
-
-
-VOID STATIC
+VOID
HalpLowerIrql(KIRQL NewIrql)
{
- if (NewIrql >= PROFILE_LEVEL)
- {
- KeSetCurrentIrql (NewIrql);
- return;
- }
- HalpExecuteIrqs (NewIrql);
+ PKPCR Pcr = KeGetCurrentKPCR();
if (NewIrql >= DISPATCH_LEVEL)
{
KeSetCurrentIrql (NewIrql);
+ APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
return;
}
- KeSetCurrentIrql (DISPATCH_LEVEL);
- if (DpcQueueSize > 0)
+ if (KeGetCurrentIrql() > APC_LEVEL)
+ {
+ KeSetCurrentIrql (DISPATCH_LEVEL);
+ APICWrite(APIC_TPR, IRQL2TPR (DISPATCH_LEVEL) & APIC_TPR_PRI);
+ if (Pcr->HalReserved[1])
{
- KiDispatchInterrupt ();
+ Pcr->HalReserved[1] = 0;
+ KiDispatchInterrupt();
}
- KeSetCurrentIrql (APC_LEVEL);
+ KeSetCurrentIrql (APC_LEVEL);
+ }
if (NewIrql == APC_LEVEL)
{
return;
@@ -171,10 +129,10 @@
VOID FASTCALL
KfLowerIrql (KIRQL NewIrql)
{
-
- if (NewIrql > KeGetCurrentIrql ())
+ KIRQL oldIrql = KeGetCurrentIrql();
+ if (NewIrql > oldIrql)
{
- DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, KeGetCurrentIrql ());
+ DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
KEBUGCHECK (0);
for(;;);
}
@@ -227,6 +185,7 @@
KfRaiseIrql (KIRQL NewIrql)
{
KIRQL OldIrql;
+ ULONG Flags;
if (NewIrql < KeGetCurrentIrql ())
{
@@ -234,9 +193,15 @@
KEBUGCHECK (0);
for(;;);
}
-
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ if (NewIrql > DISPATCH_LEVEL)
+ {
+ APICWrite (APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
+ }
OldIrql = KeGetCurrentIrql ();
KeSetCurrentIrql (NewIrql);
+ Ki386RestoreFlags(Flags);
return OldIrql;
}
@@ -316,28 +281,34 @@
BOOLEAN STDCALL
HalBeginSystemInterrupt (ULONG Vector,
- KIRQL Irql,
- PKIRQL OldIrql)
+ KIRQL Irql,
+ PKIRQL OldIrql)
{
+ ULONG Flags;
DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql);
+ if (KeGetCurrentIrql () >= Irql)
+ {
+ DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
+ KEBUGCHECK(0);
+ }
+
if (Vector < FIRST_DEVICE_VECTOR ||
- Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
- DPRINT("Not a device interrupt\n");
- return FALSE;
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
+ DPRINT1("Not a device interrupt, vector %x\n", Vector);
+ return FALSE;
}
- HalDisableSystemInterrupt (Vector, 0);
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
APICSendEOI();
- if (KeGetCurrentIrql () >= Irql)
- {
- HalpPendingInterruptCount[Vector]++;
- return(FALSE);
- }
*OldIrql = KeGetCurrentIrql ();
KeSetCurrentIrql (Irql);
+ Ki386RestoreFlags(Flags);
return(TRUE);
}
@@ -351,25 +322,25 @@
*/
{
HalpLowerIrql (Irql);
- HalpEndSystemInterrupt (Irql);
}
BOOLEAN STDCALL
HalDisableSystemInterrupt (ULONG Vector,
- ULONG Unknown2)
+ KIRQL Irql)
{
ULONG irq;
DPRINT ("Vector (0x%X)\n", Vector);
if (Vector < FIRST_DEVICE_VECTOR ||
- Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
- DPRINT("Not a device interrupt\n");
- return FALSE;
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
+ DPRINT1("Not a device interrupt, vector=%x\n", Vector);
+ return FALSE;
}
irq = VECTOR2IRQ (Vector);
- IOAPICMaskIrq (ThisCPU (), irq);
+ IOAPICMaskIrq (irq);
return TRUE;
}
@@ -377,37 +348,42 @@
BOOLEAN STDCALL
HalEnableSystemInterrupt (ULONG Vector,
- ULONG Unknown2,
- ULONG Unknown3)
+ KIRQL Irql,
+ KINTERRUPT_MODE InterruptMode)
{
ULONG irq;
- DPRINT ("Vector (0x%X)\n", Vector);
-
if (Vector < FIRST_DEVICE_VECTOR ||
- Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
+ Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
+ {
DPRINT("Not a device interrupt\n");
- return FALSE;
+ return FALSE;
}
irq = VECTOR2IRQ (Vector);
- IOAPICUnmaskIrq (ThisCPU (), irq);
+ IOAPICUnmaskIrq (irq);
return TRUE;
}
VOID FASTCALL
-HalRequestSoftwareInterrupt(
- IN KIRQL Request)
+HalRequestSoftwareInterrupt(IN KIRQL Request)
{
+ ULONG Flags;
switch (Request)
{
case APC_LEVEL:
- //ApcRequested = TRUE;
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ KeGetCurrentKPCR()->HalReserved[0] = 1;
+ Ki386RestoreFlags(Flags);
break;
case DISPATCH_LEVEL:
- //DpcRequested = TRUE;
+ Ki386SaveFlags(Flags);
+ Ki386DisableInterrupts();
+ KeGetCurrentKPCR()->HalReserved[1] = 1;
+ Ki386RestoreFlags(Flags);
break;
default: