- 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
* I/O APIC)
*/
#define VECTOR2IRQ(vector) (((vector) - FIRST_DEVICE_VECTOR) / 8)
#define IRQ2VECTOR(vector) ((vector * 8) + FIRST_DEVICE_VECTOR)
#define VECTOR2IRQL(vector) (DISPATCH_LEVEL /* 2 */ + 1 + VECTOR2IRQ(vector))
#define IRQL2VECTOR(irql) (IRQ2VECTOR(irql - DISPATCH_LEVEL /* 2 */ - 1))
#define IRQL2VECTOR(irql) IRQ2VECTOR(PROFILE_LEVEL - (irql))
#define IRQL2TPR(irql) (((irql) == PASSIVE_LEVEL) ? 0 : ((irql) >= CLOCK1_LEVEL ? 0xff : IRQL2VECTOR(irql)))
#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_TDCR 0x03E0 /* Timer Divide Configuration Register (R/W) */
#define APIC_ID_MASK (0xF << 24)
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
#define APIC_VER_MASK 0xFF00FF
#define GET_APIC_VERSION(x)((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_ID_MASK (0xF << 24)
#define GET_APIC_ID(x) (((x) & APIC_ID_MASK) >> 24)
#define GET_APIC_LOGICAL_ID(x) (((x)>>24)&0xFF)
#define APIC_VER_MASK 0xFF00FF
#define GET_APIC_VERSION(x) ((x) & 0xFF)
#define GET_APIC_MAXLVT(x) (((x) >> 16) & 0xFF)
#define APIC_TPR_PRI 0xFF
#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
* sources per level' errata.
*/
#define LOCAL_TIMER_VECTOR 0xEF
#define LOCAL_TIMER_VECTOR 0xEF
#define CALL_FUNCTION_VECTOR 0xFB
#define RESCHEDULE_VECTOR 0xFC
#define INVALIDATE_TLB_VECTOR 0xFD
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
#define CALL_FUNCTION_VECTOR 0xFB
#define RESCHEDULE_VECTOR 0xFC
#define INVALIDATE_TLB_VECTOR 0xFD
#define ERROR_VECTOR 0xFE
#define SPURIOUS_VECTOR 0xFF /* Must be 0xXF */
/*
* First APIC vector available to drivers: (vectors 0x30-0xEE)
* we start at 0x31 to spread out vectors evenly between priority
* levels.
*/
#define FIRST_DEVICE_VECTOR 0x31
#define FIRST_SYSTEM_VECTOR 0xEF
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
#if 0
/* This values are defined in halirql.h */
#define FIRST_DEVICE_VECTOR 0x30
#define FIRST_SYSTEM_VECTOR 0xEF
#endif
#define NUMBER_DEVICE_VECTORS (FIRST_SYSTEM_VECTOR - FIRST_DEVICE_VECTOR)
/* MP Floating Pointer Structure */
@ -430,8 +428,8 @@ typedef enum {
VOID HalpInitMPS(VOID);
volatile ULONG IOAPICRead(ULONG Apic, ULONG Offset);
VOID IOAPICWrite(ULONG Apic, ULONG Offset, ULONG Value);
VOID IOAPICMaskIrq(ULONG Apic, ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Apic, ULONG Irq);
VOID IOAPICMaskIrq(ULONG Irq);
VOID IOAPICUnmaskIrq(ULONG Irq);
volatile inline ULONG APICRead(ULONG Offset);
inline VOID APICWrite(ULONG Offset, ULONG Value);
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
* PROJECT: ReactOS kernel
@ -9,11 +9,19 @@
/* INCLUDES *****************************************************************/
#include <roscfg.h>
#include <ddk/ntddk.h>
#include <hal.h>
/* FUNCTIONS ****************************************************************/
#ifdef MP
VOID
HaliReconfigurePciInterrupts(VOID);
#endif
VOID STDCALL
HalHandleNMI(ULONG Unused)
{
@ -82,8 +90,11 @@ HalReportResourceUsage(VOID)
/* Initialize PCI bus. */
HalpInitPciBus ();
#ifdef MP
HaliReconfigurePciInterrupts();
#endif
return;
}
/* 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
* PROJECT: ReactOS kernel
@ -36,19 +36,6 @@
popl %ds; \
popa;
.globl _MpsTimerInterrupt
_MpsTimerInterrupt:
/* Save registers */
BEFORE
/* Call the C handler */
call _MpsTimerHandler
/* Return to the caller */
AFTER
iret
.globl _MpsErrorInterrupt
_MpsErrorInterrupt:
/* Save registers */
@ -74,4 +61,36 @@ _MpsSpuriousInterrupt:
AFTER
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 */

View file

@ -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 @@ KIRQL STDCALL KeGetCurrentIrql (VOID)
* 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 @@ HalpLowerIrql(KIRQL NewIrql)
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 @@ KIRQL FASTCALL
KfRaiseIrql (KIRQL NewIrql)
{
KIRQL OldIrql;
ULONG Flags;
if (NewIrql < KeGetCurrentIrql ())
{
@ -234,9 +193,15 @@ KfRaiseIrql (KIRQL NewIrql)
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 @@ KeRaiseIrqlToSynchLevel (VOID)
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 (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)
{
HalpPendingInterruptCount[Vector]++;
return(FALSE);
DPRINT1("current irql %d, new irql %d\n", KeGetCurrentIrql(), Irql);
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 ();
KeSetCurrentIrql (Irql);
Ki386RestoreFlags(Flags);
return(TRUE);
}
@ -351,25 +322,25 @@ HalEndSystemInterrupt (KIRQL Irql,
*/
{
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 @@ HalDisableSystemInterrupt (ULONG Vector,
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:

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* 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,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(7), L16(8), L16(9), L16(A),
L16(B), L16(C), L16(D), L16(E),
L16(F)
L16(B), L16(C), L16(D), L16(E)
};
#undef L