- Changed/rewrote parts of the mp code to get my ASUS p2b-ds motherboard to working.

svn path=/trunk/; revision=11521
This commit is contained in:
Hartmut Birr 2004-11-01 19:01:25 +00:00
parent 3edce321a2
commit f23530ddc9
6 changed files with 1198 additions and 990 deletions

View file

@ -5,10 +5,8 @@
* FIXME: This does not work if we have more than 24 IRQs (ie. more than one * FIXME: This does not work if we have more than 24 IRQs (ie. more than one
* I/O APIC) * I/O APIC)
*/ */
#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8) #define IRQL2VECTOR(irql) IRQ2VECTOR(PROFILE_LEVEL - (irql))
#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR) #define IRQL2TPR(irql) (((irql) == PASSIVE_LEVEL) ? 0 : ((irql) >= CLOCK1_LEVEL ? 0xff : IRQL2VECTOR(irql)))
#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector))
#define IRQL2VECTOR(irql) (IRQ2VECTOR(irql - DISPATCH_LEVEL /* 2 */ - 1))
#define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */ #define APIC_DEFAULT_BASE 0xFEE00000 /* Default Local APIC Base Register Address */
@ -39,11 +37,12 @@
#define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */ #define APIC_CCRT 0x0390 /* Current Count Register for Timer (R) */
#define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */ #define APIC_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
#define APIC_ID_MASK (0xF << 24) #define APIC_ID_MASK (0xF << 24)
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24) #define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
#define APIC_VER_MASK 0xFF00FF #define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
#define GET_APIC_VERSION(x)((x) & 0xFF) #define APIC_VER_MASK 0xFF00FF
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF) #define GET_APIC_VERSION(x) ((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_TPR_PRI 0xFF #define APIC_TPR_PRI 0xFF
#define APIC_TPR_INT 0xF0 #define APIC_TPR_INT 0xF0
@ -207,22 +206,21 @@ typedef struct _IOAPIC_INFO
* to work around the 'lost local interrupt if more than 2 IRQ * to work around the 'lost local interrupt if more than 2 IRQ
* sources per level' errata. * sources per level' errata.
*/ */
#define LOCAL_TIMER_VECTOR 0xEF #define LOCAL_TIMER_VECTOR 0xEF
#define CALL_FUNCTION_VECTOR 0xFB #define CALL_FUNCTION_VECTOR 0xFB
#define RESCHEDULE_VECTOR 0xFC #define RESCHEDULE_VECTOR 0xFC
#define INVALIDATE_TLB_VECTOR 0xFD #define INVALIDATE_TLB_VECTOR 0xFD
#define ERROR_VECTOR 0xFE #define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */ #define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
/* #if 0
* First APIC vector available to drivers: (vectors 0x30-0xEE) /* This values are defined in halirql.h */
* we start at 0x31 to spread out vectors evenly between priority #define FIRST_DEVICE_VECTOR 0x30
* levels. #define FIRST_SYSTEM_VECTOR 0xEF
*/ #endif
#define FIRST_DEVICE_VECTOR 0x31
#define FIRST_SYSTEM_VECTOR 0xEF #define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/* MP Floating Pointer Structure */ /* MP Floating Pointer Structure */
@ -430,8 +428,8 @@ typedef enum {
VOID HalpInitMPS(VOID); VOID HalpInitMPS(VOID);
volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset); volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset);
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value); VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
VOID IOAPICMaskIrq(ULONG Apic, ULONG Irq); VOID IOAPICMaskIrq(ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Apic, ULONG Irq); VOID IOAPICUnmaskIrq(ULONG Irq);
volatile inline ULONG APICRead(ULONG Offset); volatile inline ULONG APICRead(ULONG Offset);
inline VOID APICWrite(ULONG Offset, ULONG Value); inline VOID APICWrite(ULONG Offset, ULONG Value);
inline VOID APICSendEOI(VOID); inline VOID APICSendEOI(VOID);

View file

@ -1,4 +1,4 @@
/* $Id: misc.c,v 1.6 2004/10/31 19:45:16 ekohl Exp $ /* $Id: misc.c,v 1.7 2004/11/01 19:01:25 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -9,11 +9,19 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <roscfg.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <hal.h> #include <hal.h>
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
#ifdef MP
VOID
HaliReconfigurePciInterrupts(VOID);
#endif
VOID STDCALL VOID STDCALL
HalHandleNMI(ULONG Unused) HalHandleNMI(ULONG Unused)
{ {
@ -82,8 +90,11 @@ HalReportResourceUsage(VOID)
/* Initialize PCI bus. */ /* Initialize PCI bus. */
HalpInitPciBus (); HalpInitPciBus ();
#ifdef MP
HaliReconfigurePciInterrupts();
#endif
return;
} }
/* EOF */ /* EOF */

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: mps.S,v 1.2 2004/11/01 14:37:19 hbirr Exp $ /* $Id: mps.S,v 1.3 2004/11/01 19:01:25 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -36,19 +36,6 @@
popl %ds; \ popl %ds; \
popa; popa;
.globl _MpsTimerInterrupt
_MpsTimerInterrupt:
/* Save registers */
BEFORE
/* Call the C handler */
call _MpsTimerHandler
/* Return to the caller */
AFTER
iret
.globl _MpsErrorInterrupt .globl _MpsErrorInterrupt
_MpsErrorInterrupt: _MpsErrorInterrupt:
/* Save registers */ /* Save registers */
@ -74,4 +61,36 @@ _MpsSpuriousInterrupt:
AFTER AFTER
iret iret
.global _MpsTimerInterrupt
_MpsTimerInterrupt:
cld
pusha
movl $0xef,%ebx
pushl %ds
pushl %es
pushl %fs
pushl %gs
movl $0xceafbeef,%eax
pushl %eax
movl $(KERNEL_DS),%eax
movl %eax,%ds
movl %eax,%es
movl %eax,%gs
movl $(PCR_SELECTOR),%eax
movl %eax,%fs
pushl %esp
pushl %ebx
call _MpsTimerHandler
popl %eax
popl %eax
popl %eax
popl %gs
popl %fs
popl %es
popl %ds
popa
iret
/* EOF */ /* EOF */

View file

@ -11,10 +11,12 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <roscfg.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/ke.h> #include <internal/ke.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <ntos/minmax.h> #include <ntos/minmax.h>
#include <halirq.h>
#include <hal.h> #include <hal.h>
#include <mps.h> #include <mps.h>
@ -23,20 +25,10 @@
/* GLOBALS ******************************************************************/; /* 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 VOID STDCALL
KiInterruptDispatch2 (ULONG Irq, KIRQL old_level); KiInterruptDispatch2 (ULONG Irq, KIRQL old_level);
#define IRQL2TPR(irql) (FIRST_DEVICE_VECTOR + ((irql - DISPATCH_LEVEL /* 2 */ - 1) * 8))
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
KIRQL STDCALL KeGetCurrentIrql (VOID) KIRQL STDCALL KeGetCurrentIrql (VOID)
@ -45,100 +37,66 @@ KIRQL STDCALL KeGetCurrentIrql (VOID)
* RETURNS: The current irq level * 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); KEBUGCHECK (0);
for(;;); for(;;);
} }
return irql;
return(KeGetCurrentKPCR ()->Irql);
} }
static VOID KeSetCurrentIrql (KIRQL NewIrql) VOID KeSetCurrentIrql (KIRQL NewIrql)
/* /*
* PURPOSE: Sets the current irq level without taking any action * PURPOSE: Sets the current irq level without taking any action
*/ */
{ {
ULONG Flags;
if (NewIrql > HIGH_LEVEL) if (NewIrql > HIGH_LEVEL)
{ {
DPRINT1 ("NewIrql %x\n", NewIrql); DPRINT1 ("NewIrql %x\n", NewIrql);
KEBUGCHECK (0); KEBUGCHECK (0);
for(;;); for(;;);
} }
Ki386SaveFlags(Flags);
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);
Ki386DisableInterrupts(); Ki386DisableInterrupts();
APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI); KeGetCurrentKPCR()->Irql = NewIrql;
Ki386RestoreFlags(flags); 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) HalpLowerIrql(KIRQL NewIrql)
{ {
if (NewIrql >= PROFILE_LEVEL) PKPCR Pcr = KeGetCurrentKPCR();
{
KeSetCurrentIrql (NewIrql);
return;
}
HalpExecuteIrqs (NewIrql);
if (NewIrql >= DISPATCH_LEVEL) if (NewIrql >= DISPATCH_LEVEL)
{ {
KeSetCurrentIrql (NewIrql); KeSetCurrentIrql (NewIrql);
APICWrite(APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
return; return;
} }
KeSetCurrentIrql (DISPATCH_LEVEL); if (KeGetCurrentIrql() > APC_LEVEL)
if (DpcQueueSize > 0) {
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) if (NewIrql == APC_LEVEL)
{ {
return; return;
@ -171,10 +129,10 @@ HalpLowerIrql(KIRQL NewIrql)
VOID FASTCALL VOID FASTCALL
KfLowerIrql (KIRQL NewIrql) KfLowerIrql (KIRQL NewIrql)
{ {
KIRQL oldIrql = KeGetCurrentIrql();
if (NewIrql > KeGetCurrentIrql ()) if (NewIrql > oldIrql)
{ {
DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, KeGetCurrentIrql ()); DPRINT1 ("NewIrql %x CurrentIrql %x\n", NewIrql, oldIrql);
KEBUGCHECK (0); KEBUGCHECK (0);
for(;;); for(;;);
} }
@ -227,6 +185,7 @@ KIRQL FASTCALL
KfRaiseIrql (KIRQL NewIrql) KfRaiseIrql (KIRQL NewIrql)
{ {
KIRQL OldIrql; KIRQL OldIrql;
ULONG Flags;
if (NewIrql < KeGetCurrentIrql ()) if (NewIrql < KeGetCurrentIrql ())
{ {
@ -234,9 +193,15 @@ KfRaiseIrql (KIRQL NewIrql)
KEBUGCHECK (0); KEBUGCHECK (0);
for(;;); for(;;);
} }
Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
if (NewIrql > DISPATCH_LEVEL)
{
APICWrite (APIC_TPR, IRQL2TPR (NewIrql) & APIC_TPR_PRI);
}
OldIrql = KeGetCurrentIrql (); OldIrql = KeGetCurrentIrql ();
KeSetCurrentIrql (NewIrql); KeSetCurrentIrql (NewIrql);
Ki386RestoreFlags(Flags);
return OldIrql; return OldIrql;
} }
@ -316,28 +281,34 @@ KeRaiseIrqlToSynchLevel (VOID)
BOOLEAN STDCALL BOOLEAN STDCALL
HalBeginSystemInterrupt (ULONG Vector, HalBeginSystemInterrupt (ULONG Vector,
KIRQL Irql, KIRQL Irql,
PKIRQL OldIrql) PKIRQL OldIrql)
{ {
ULONG Flags;
DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql); DPRINT("Vector (0x%X) Irql (0x%X)\n", Vector, Irql);
if (Vector < FIRST_DEVICE_VECTOR ||
Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS) {
DPRINT("Not a device interrupt\n");
return FALSE;
}
HalDisableSystemInterrupt (Vector, 0);
APICSendEOI();
if (KeGetCurrentIrql () >= Irql) if (KeGetCurrentIrql () >= Irql)
{ {
HalpPendingInterruptCount[Vector]++; DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
return(FALSE); KEBUGCHECK(0);
} }
if (Vector < FIRST_DEVICE_VECTOR ||
Vector >= FIRST_DEVICE_VECTOR + NUMBER_DEVICE_VECTORS)
{
DPRINT1("Not a device interrupt, vector %x\n", Vector);
return FALSE;
}
Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
APICWrite (APIC_TPR, IRQL2TPR (Irql) & APIC_TPR_PRI);
APICSendEOI();
*OldIrql = KeGetCurrentIrql (); *OldIrql = KeGetCurrentIrql ();
KeSetCurrentIrql (Irql); KeSetCurrentIrql (Irql);
Ki386RestoreFlags(Flags);
return(TRUE); return(TRUE);
} }
@ -351,25 +322,25 @@ HalEndSystemInterrupt (KIRQL Irql,
*/ */
{ {
HalpLowerIrql (Irql); HalpLowerIrql (Irql);
HalpEndSystemInterrupt (Irql);
} }
BOOLEAN STDCALL BOOLEAN STDCALL
HalDisableSystemInterrupt (ULONG Vector, HalDisableSystemInterrupt (ULONG Vector,
ULONG Unknown2) KIRQL Irql)
{ {
ULONG irq; ULONG irq;
DPRINT ("Vector (0x%X)\n", Vector); DPRINT ("Vector (0x%X)\n", Vector);
if (Vector < FIRST_DEVICE_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; DPRINT1("Not a device interrupt, vector=%x\n", Vector);
return FALSE;
} }
irq = VECTOR2IRQ (Vector); irq = VECTOR2IRQ (Vector);
IOAPICMaskIrq (ThisCPU (), irq); IOAPICMaskIrq (irq);
return TRUE; return TRUE;
} }
@ -377,37 +348,42 @@ HalDisableSystemInterrupt (ULONG Vector,
BOOLEAN STDCALL BOOLEAN STDCALL
HalEnableSystemInterrupt (ULONG Vector, HalEnableSystemInterrupt (ULONG Vector,
ULONG Unknown2, KIRQL Irql,
ULONG Unknown3) KINTERRUPT_MODE InterruptMode)
{ {
ULONG irq; ULONG irq;
DPRINT ("Vector (0x%X)\n", Vector);
if (Vector < FIRST_DEVICE_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"); DPRINT("Not a device interrupt\n");
return FALSE; return FALSE;
} }
irq = VECTOR2IRQ (Vector); irq = VECTOR2IRQ (Vector);
IOAPICUnmaskIrq (ThisCPU (), irq); IOAPICUnmaskIrq (irq);
return TRUE; return TRUE;
} }
VOID FASTCALL VOID FASTCALL
HalRequestSoftwareInterrupt( HalRequestSoftwareInterrupt(IN KIRQL Request)
IN KIRQL Request)
{ {
ULONG Flags;
switch (Request) switch (Request)
{ {
case APC_LEVEL: case APC_LEVEL:
//ApcRequested = TRUE; Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
KeGetCurrentKPCR()->HalReserved[0] = 1;
Ki386RestoreFlags(Flags);
break; break;
case DISPATCH_LEVEL: case DISPATCH_LEVEL:
//DpcRequested = TRUE; Ki386SaveFlags(Flags);
Ki386DisableInterrupts();
KeGetCurrentKPCR()->HalReserved[1] = 1;
Ki386RestoreFlags(Flags);
break; break;
default: default:

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: irq.c,v 1.52 2004/11/01 14:37:19 hbirr Exp $ /* $Id: irq.c,v 1.53 2004/11/01 19:01:25 hbirr Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/irq.c * FILE: ntoskrnl/ke/i386/irq.c
@ -126,11 +126,10 @@ B16(F)
L(x,8), L(x,9), L(x,A), L(x,B), \ L(x,8), L(x,9), L(x,A), L(x,B), \
L(x,C), L(x,D), L(x,E), L(x,F) L(x,C), L(x,D), L(x,E), L(x,F)
static ULONG irq_handler[NR_IRQS] = { static ULONG irq_handler[ROUND_UP(NR_IRQS, 16)] = {
L16(3), L16(4), L16(5), L16(6), L16(3), L16(4), L16(5), L16(6),
L16(7), L16(8), L16(9), L16(A), L16(7), L16(8), L16(9), L16(A),
L16(B), L16(C), L16(D), L16(E), L16(B), L16(C), L16(D), L16(E)
L16(F)
}; };
#undef L #undef L