mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implemented access to PCI configuration space
svn path=/trunk/; revision=1967
This commit is contained in:
parent
dbb696c65d
commit
d8f25b3cb8
5 changed files with 942 additions and 826 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
/* $Id: isa.c,v 1.6 2000/04/09 15:58:13 ekohl Exp $
|
||||
/* $Id: isa.c,v 1.7 2001/06/13 22:17:01 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -12,9 +12,7 @@
|
|||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
|
||||
typedef struct _BUS_HANDLER *PBUS_HANDLER;
|
||||
#include <internal/hal/bus.h>
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
@ -36,34 +34,29 @@ BOOL HalIsaProbe(VOID)
|
|||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
HalpTranslateIsaBusAddress (
|
||||
PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress
|
||||
)
|
||||
BOOLEAN STDCALL
|
||||
HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress)
|
||||
{
|
||||
BOOLEAN Result;
|
||||
BOOLEAN Result;
|
||||
|
||||
Result = HalTranslateBusAddress (PCIBus,
|
||||
BusNumber,
|
||||
BusAddress,
|
||||
AddressSpace,
|
||||
TranslatedAddress);
|
||||
Result = HalTranslateBusAddress(PCIBus,
|
||||
BusNumber,
|
||||
BusAddress,
|
||||
AddressSpace,
|
||||
TranslatedAddress);
|
||||
if (Result != FALSE)
|
||||
return Result;
|
||||
|
||||
if (Result != FALSE)
|
||||
return Result;
|
||||
|
||||
Result = HalTranslateBusAddress (Internal,
|
||||
BusNumber,
|
||||
BusAddress,
|
||||
AddressSpace,
|
||||
TranslatedAddress);
|
||||
|
||||
return Result;
|
||||
Result = HalTranslateBusAddress(Internal,
|
||||
BusNumber,
|
||||
BusAddress,
|
||||
AddressSpace,
|
||||
TranslatedAddress);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: pci.c,v 1.6 2001/03/16 18:11:21 dwelch Exp $
|
||||
/* $Id: pci.c,v 1.7 2001/06/13 22:17:01 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -9,294 +9,486 @@
|
|||
* UPDATE HISTORY:
|
||||
* 05/06/1998: Created
|
||||
* 17/08/2000: Added preliminary pci bus scanner
|
||||
* 13/06/2001: Implemented access to pci configuration space
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTES: Sections copied from the Linux pci support
|
||||
*/
|
||||
|
||||
/* INCLUDES ***************************************************************/
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <internal/hal/bus.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/* MACROS *****************************************************************/
|
||||
/* MACROS ******************************************************************/
|
||||
|
||||
/* access type 1 macros */
|
||||
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
||||
#define CONFIG_CMD(bus, device_fn, where) \
|
||||
#define PCI_FUNC(devfn) \
|
||||
((devfn) & 0x07)
|
||||
#define CONFIG_CMD(bus, device_fn, where) \
|
||||
(0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
|
||||
|
||||
/* access type 2 macros */
|
||||
#define IOADDR(devfn, where) \
|
||||
((0xC000 | ((devfn & 0x78) << 5)) + where)
|
||||
#define FUNC(devfn) \
|
||||
(((devfn & 7) << 1) | 0xf0)
|
||||
|
||||
|
||||
#define PCIBIOS_SUCCESSFUL 0x00
|
||||
#define PCIBIOS_DEVICE_NOT_FOUND 0x86
|
||||
#define PCIBIOS_BAD_REGISTER_NUMBER 0x87
|
||||
|
||||
// access type 2 macros
|
||||
#define IOADDR(devfn, where) ((0xC000 | ((devfn & 0x78) << 5)) + where)
|
||||
#define FUNC(devfn) (((devfn & 7) << 1) | 0xf0)
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static ULONG BusConfigType = 0; /* undetermined config type */
|
||||
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
/*
|
||||
* Bus access type 1 (recommended)
|
||||
*/
|
||||
static int
|
||||
ReadPciConfigUcharType1(UCHAR Bus,
|
||||
UCHAR device_fn,
|
||||
UCHAR where,
|
||||
PUCHAR Value)
|
||||
{
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus,device_fn,where));
|
||||
*Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (where&3));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
ReadPciConfigUshortType1(UCHAR Bus,
|
||||
UCHAR device_fn,
|
||||
UCHAR where,
|
||||
PUSHORT Value)
|
||||
{
|
||||
if ((where & 1) != 0)
|
||||
{
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus,device_fn,where));
|
||||
*value = READ_PORT_USHORT((PUSHORT)0xCFC + (where&1));
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ReadPciConfigUlongType1(UCHAR Bus,
|
||||
UCHAR device_fn,
|
||||
UCHAR where,
|
||||
PULONG Value)
|
||||
{
|
||||
if ((where & 3) != 0)
|
||||
{
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus,device_fn,where));
|
||||
*Value = READ_PORT_ULONG((PULONG)0xCFC);
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void
|
||||
ScanPciBusType1(ULONG Bus)
|
||||
{
|
||||
USHORT dev_fn;
|
||||
UCHAR hdr_type;
|
||||
ULONG foo;
|
||||
|
||||
for (dev_fn = 0; dev_fn < 256; dev_fn++)
|
||||
{
|
||||
if (PCI_FUNC(dev_fn) == 0)
|
||||
{
|
||||
/* 0E=PCI_HEADER_TYPE */
|
||||
ReadPciConfigUcharType1(Bus, dev_fn, 0x0E, &hdr_type);
|
||||
}
|
||||
else if ((hdr_type & 0x80) == 0)
|
||||
{
|
||||
/* not a multi-function device */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 00=PCI_VENDOR_ID */
|
||||
ReadPciConfigUlongType1(Bus, dev_fn, 0x00, &foo);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (foo == 0xFFFFFFFF || foo == 0)
|
||||
{
|
||||
hdr_type = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
DbgPrint("dev_fn=%3u, Vendor 0x%04lX, Device 0x%04lX\n",
|
||||
dev_fn, foo & 0xFFFF, (foo >> 16) & 0xFFFF);
|
||||
}
|
||||
}
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static NTSTATUS
|
||||
ScanPciBussesType1(VOID)
|
||||
ReadPciConfigUchar(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
PUCHAR Value)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG temp;
|
||||
switch (BusConfigType)
|
||||
{
|
||||
case 1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
*Value = READ_PORT_UCHAR((PUCHAR)0xCFC + (Offset & 3));
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
DPRINT("ScanPciBussesType1()\n");
|
||||
case 2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(Slot, Offset)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DPRINT("Checking if configuration type 1 works\n");
|
||||
|
||||
static NTSTATUS
|
||||
ReadPciConfigUshort(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
PUSHORT Value)
|
||||
{
|
||||
if ((Offset & 1) != 0)
|
||||
{
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
switch (BusConfigType)
|
||||
{
|
||||
case 1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
*Value = READ_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1));
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case 2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
ReadPciConfigUlong(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
PULONG Value)
|
||||
{
|
||||
if ((Offset & 3) != 0)
|
||||
{
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
switch (BusConfigType)
|
||||
{
|
||||
case 1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
*Value = READ_PORT_ULONG((PULONG)0xCFC);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case 2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
WritePciConfigUchar(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
UCHAR Value)
|
||||
{
|
||||
switch (BusConfigType)
|
||||
{
|
||||
case 1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFC + (Offset&3), Value);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case 2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
WRITE_PORT_UCHAR((PUCHAR)(IOADDR(Slot,Offset)), Value);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
WritePciConfigUshort(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
USHORT Value)
|
||||
{
|
||||
if ((Offset & 1) != 0)
|
||||
{
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
switch (BusConfigType)
|
||||
{
|
||||
case 1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
WRITE_PORT_USHORT((PUSHORT)0xCFC + (Offset & 1), Value);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case 2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
WRITE_PORT_USHORT((PUSHORT)(IOADDR(Slot, Offset)), Value);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
WritePciConfigUlong(UCHAR Bus,
|
||||
UCHAR Slot,
|
||||
UCHAR Offset,
|
||||
ULONG Value)
|
||||
{
|
||||
if ((Offset & 3) != 0)
|
||||
{
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
}
|
||||
|
||||
switch (BusConfigType)
|
||||
{
|
||||
case 1:
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, CONFIG_CMD(Bus, Slot, Offset));
|
||||
WRITE_PORT_ULONG((PULONG)0xCFC, Value);
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
case 2:
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(Slot));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
WRITE_PORT_ULONG((PULONG)(IOADDR(Slot, Offset)), Value);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
static ULONG STDCALL
|
||||
HalpGetPciData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length)
|
||||
{
|
||||
PVOID Ptr = Buffer;
|
||||
ULONG Address = Offset;
|
||||
ULONG Len = Length;
|
||||
ULONG Vendor;
|
||||
UCHAR HeaderType;
|
||||
|
||||
DPRINT("HalpGetPciData() called.\n");
|
||||
DPRINT(" BusNumber %lu\n", BusNumber);
|
||||
DPRINT(" SlotNumber %lu\n", SlotNumber);
|
||||
DPRINT(" Offset 0x%lx\n", Offset);
|
||||
DPRINT(" Length 0x%lx\n", Length);
|
||||
|
||||
if ((Length == 0) || (BusConfigType == 0))
|
||||
return 0;
|
||||
|
||||
/* 0E=PCI_HEADER_TYPE */
|
||||
ReadPciConfigUchar(BusNumber,
|
||||
SlotNumber & 0xF8,
|
||||
0x0E,
|
||||
&HeaderType);
|
||||
if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
|
||||
return 0;
|
||||
|
||||
ReadPciConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
0x00,
|
||||
&Vendor);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (Vendor == 0xFFFFFFFF || Vendor == 0)
|
||||
return 0;
|
||||
|
||||
if ((Address & 1) && (Len >= 1))
|
||||
{
|
||||
ReadPciConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
if ((Address & 2) && (Len >= 2))
|
||||
{
|
||||
ReadPciConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
while (Len >= 4)
|
||||
{
|
||||
ReadPciConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 4;
|
||||
Address += 4;
|
||||
Len -= 4;
|
||||
}
|
||||
|
||||
if (Len >= 2)
|
||||
{
|
||||
ReadPciConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
if (Len >= 1)
|
||||
{
|
||||
ReadPciConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
return Length - Len;
|
||||
}
|
||||
|
||||
|
||||
static ULONG STDCALL
|
||||
HalpSetPciData(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG SlotNumber,
|
||||
PVOID Buffer,
|
||||
ULONG Offset,
|
||||
ULONG Length)
|
||||
{
|
||||
PVOID Ptr = Buffer;
|
||||
ULONG Address = Offset;
|
||||
ULONG Len = Length;
|
||||
ULONG Vendor;
|
||||
UCHAR HeaderType;
|
||||
|
||||
DPRINT("HalpSetPciData() called.\n");
|
||||
DPRINT(" BusNumber %lu\n", BusNumber);
|
||||
DPRINT(" SlotNumber %lu\n", SlotNumber);
|
||||
DPRINT(" Offset 0x%lx\n", Offset);
|
||||
DPRINT(" Length 0x%lx\n", Length);
|
||||
|
||||
if ((Length == 0) || (BusConfigType == 0))
|
||||
return 0;
|
||||
|
||||
/* 0E=PCI_HEADER_TYPE */
|
||||
ReadPciConfigUchar(BusNumber,
|
||||
SlotNumber & 0xF8,
|
||||
0x0E,
|
||||
&HeaderType);
|
||||
if (((HeaderType & 0x80) == 0) && ((SlotNumber & 0x07) != 0))
|
||||
return 0;
|
||||
|
||||
ReadPciConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
0x00,
|
||||
&Vendor);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (Vendor == 0xFFFFFFFF || Vendor == 0)
|
||||
return 0;
|
||||
|
||||
if ((Address & 1) && (Len >= 1))
|
||||
{
|
||||
WritePciConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUCHAR)Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
if ((Address & 2) && (Len >= 2))
|
||||
{
|
||||
WritePciConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUSHORT)Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
while (Len >= 4)
|
||||
{
|
||||
WritePciConfigUlong(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PULONG)Ptr);
|
||||
Ptr = Ptr + 4;
|
||||
Address += 4;
|
||||
Len -= 4;
|
||||
}
|
||||
|
||||
if (Len >= 2)
|
||||
{
|
||||
WritePciConfigUshort(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUSHORT)Ptr);
|
||||
Ptr = Ptr + 2;
|
||||
Address += 2;
|
||||
Len -= 2;
|
||||
}
|
||||
|
||||
if (Len >= 1)
|
||||
{
|
||||
WritePciConfigUchar(BusNumber,
|
||||
SlotNumber,
|
||||
Address,
|
||||
*(PUCHAR)Ptr);
|
||||
Ptr = Ptr + 1;
|
||||
Address++;
|
||||
Len--;
|
||||
}
|
||||
|
||||
return Length - Len;
|
||||
}
|
||||
|
||||
|
||||
static ULONG
|
||||
GetBusConfigType(VOID)
|
||||
{
|
||||
ULONG Value;
|
||||
|
||||
DPRINT("GetBusConfigType() called\n");
|
||||
|
||||
DPRINT("Checking configuration type 1:");
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01);
|
||||
temp = READ_PORT_ULONG((PULONG)0xCF8);
|
||||
Value = READ_PORT_ULONG((PULONG)0xCF8);
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, 0x80000000);
|
||||
if (READ_PORT_ULONG((PULONG)0xCF8) != 0x80000000)
|
||||
if (READ_PORT_ULONG((PULONG)0xCF8) == 0x80000000)
|
||||
{
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, temp);
|
||||
DPRINT("No pci configuration type 1\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, Value);
|
||||
DPRINT(" Success!\n");
|
||||
return 1;
|
||||
}
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, Value);
|
||||
DPRINT(" Unsuccessful!\n");
|
||||
|
||||
DPRINT("Using configuration type 1\n");
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, temp);
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
DPRINT("Scanning PCI bus %u...\n", i);
|
||||
ScanPciBusType1(i);
|
||||
}
|
||||
WRITE_PORT_ULONG((PULONG)0xCF8, temp);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bus access type 2 (should not be used any longer)
|
||||
*/
|
||||
static int
|
||||
ReadPciConfigUcharType2 (UCHAR Bus,
|
||||
UCHAR device_fn,
|
||||
UCHAR where,
|
||||
PUCHAR Value)
|
||||
{
|
||||
if ((device_fn & 0x80) != 0)
|
||||
{
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(device_fn));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_UCHAR((PUCHAR)(IOADDR(device_fn,where)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
ReadPciConfigUshortType2(UCHAR Bus,
|
||||
UCHAR device_fn,
|
||||
UCHAR where,
|
||||
PUSHORT Value)
|
||||
{
|
||||
if ((device_fn & 0x80) != 0)
|
||||
{
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(device_fn));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_USHORT((PUSHORT)(IOADDR(device_fn,where)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ReadPciConfigUlongType2(UCHAR Bus,
|
||||
UCHAR device_fn,
|
||||
UCHAR where,
|
||||
PULONG Value)
|
||||
{
|
||||
if ((device_fn & 0x80) != 0)
|
||||
{
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, FUNC(device_fn));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, Bus);
|
||||
*Value = READ_PORT_ULONG((PULONG)(IOADDR(device_fn,where)));
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0);
|
||||
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static void
|
||||
ScanPciBusType2(ULONG Bus)
|
||||
{
|
||||
USHORT dev_fn;
|
||||
UCHAR hdr_type;
|
||||
ULONG foo;
|
||||
|
||||
for (dev_fn = 0; dev_fn < 256; dev_fn++)
|
||||
{
|
||||
if (PCI_FUNC(dev_fn) == 0)
|
||||
{
|
||||
/* 0E=PCI_HEADER_TYPE */
|
||||
ReadPciConfigUcharType2(Bus, dev_fn, 0x0E, &hdr_type);
|
||||
}
|
||||
else if ((hdr_type & 0x80) == 0)
|
||||
{
|
||||
/* not a multi-function device */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 00=PCI_VENDOR_ID */
|
||||
ReadPciConfigUlongType2(Bus, dev_fn, 0x00, &foo);
|
||||
/* some broken boards return 0 if a slot is empty: */
|
||||
if (foo == 0xFFFFFFFF || foo == 0)
|
||||
{
|
||||
hdr_type = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
DbgPrint("dev_fn=%3u, Vendor 0x%04lX, Device 0x%04lX\n",
|
||||
dev_fn, foo & 0xFFFF, (foo >> 16) & 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
static NTSTATUS
|
||||
ScanPciBussesType2(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
DPRINT("Checking if configuration type 2 works\n");
|
||||
DPRINT("Checking configuration type 2:");
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x00);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCF8, 0x00);
|
||||
WRITE_PORT_UCHAR((PUCHAR)0xCFA, 0x00);
|
||||
if (READ_PORT_UCHAR((PUCHAR)0xCF8) != 0x00 ||
|
||||
READ_PORT_UCHAR((PUCHAR)0xCFB) != 0x00)
|
||||
if (READ_PORT_UCHAR((PUCHAR)0xCF8) == 0x00 &&
|
||||
READ_PORT_UCHAR((PUCHAR)0xCFB) == 0x00)
|
||||
{
|
||||
DPRINT("No pci configuration type 2\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT(" Success!\n");
|
||||
return 2;
|
||||
}
|
||||
DPRINT(" Unsuccessful!\n");
|
||||
|
||||
DPRINT("Using configuration type 2\n");
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
DPRINT("Scanning PCI bus %u...\n", i);
|
||||
ScanPciBusType2(i);
|
||||
}
|
||||
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
DPRINT("No pci bus found!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
VOID HalpInitPciBus (VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PBUS_HANDLER BusHandler;
|
||||
|
||||
DPRINT("HalpInitPciBus()\n");
|
||||
DPRINT("HalpInitPciBus() called.\n");
|
||||
|
||||
Status = ScanPciBussesType1();
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
BusConfigType = GetBusConfigType();
|
||||
if (BusConfigType == 0)
|
||||
return;
|
||||
|
||||
Status = ScanPciBussesType2();
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
DPRINT("Bus configuration %lu used\n", BusConfigType);
|
||||
|
||||
DbgPrint("No pci bus found\n");
|
||||
/* pci bus (bus 0) handler */
|
||||
BusHandler = HalpAllocateBusHandler(PCIBus,
|
||||
PCIConfiguration,
|
||||
0);
|
||||
BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
|
||||
BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
|
||||
// BusHandler->GetInterruptVector =
|
||||
// (pGetInterruptVector)HalpGetPciInterruptVector;
|
||||
// BusHandler->AdjustResourceList =
|
||||
// (pGetSetBusData)HalpAdjustPciResourceList;
|
||||
// BusHandler->AssignSlotResources =
|
||||
// (pGetSetBusData)HalpAssignPciSlotResources;
|
||||
|
||||
|
||||
/* agp bus (bus 1) handler */
|
||||
BusHandler = HalpAllocateBusHandler(PCIBus,
|
||||
PCIConfiguration,
|
||||
1);
|
||||
BusHandler->GetBusData = (pGetSetBusData)HalpGetPciData;
|
||||
BusHandler->SetBusData = (pGetSetBusData)HalpSetPciData;
|
||||
// BusHandler->GetInterruptVector =
|
||||
// (pGetInterruptVector)HalpGetPciInterruptVector;
|
||||
// BusHandler->AdjustResourceList =
|
||||
// (pGetSetBusData)HalpAdjustPciResourceList;
|
||||
// BusHandler->AssignSlotResources =
|
||||
// (pGetSetBusData)HalpAssignPciSlotResources;
|
||||
|
||||
DPRINT("HalpInitPciBus() finished.\n");
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: sysbus.c,v 1.2 2001/02/25 12:54:37 chorns Exp $
|
||||
/* $Id: sysbus.c,v 1.3 2001/06/13 22:17:01 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -12,61 +12,53 @@
|
|||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
|
||||
typedef struct _BUS_HANDLER *PBUS_HANDLER;
|
||||
#include <internal/hal/bus.h>
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
ULONG
|
||||
STDCALL
|
||||
HalpGetSystemInterruptVector (
|
||||
PVOID BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG BusInterruptLevel,
|
||||
ULONG BusInterruptVector,
|
||||
PKIRQL Irql,
|
||||
PKAFFINITY Affinity
|
||||
)
|
||||
ULONG STDCALL
|
||||
HalpGetSystemInterruptVector(PVOID BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG BusInterruptLevel,
|
||||
ULONG BusInterruptVector,
|
||||
PKIRQL Irql,
|
||||
PKAFFINITY Affinity)
|
||||
{
|
||||
*Irql = HIGH_LEVEL - BusInterruptVector;
|
||||
*Irql = HIGH_LEVEL - BusInterruptVector;
|
||||
*Affinity = 0xFFFFFFFF;
|
||||
return BusInterruptVector;
|
||||
return BusInterruptVector;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
HalpTranslateSystemBusAddress (
|
||||
PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress
|
||||
)
|
||||
BOOLEAN STDCALL
|
||||
HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress)
|
||||
{
|
||||
ULONG BaseAddress = 0;
|
||||
ULONG BaseAddress = 0;
|
||||
|
||||
if (*AddressSpace == 0)
|
||||
{
|
||||
/* memory space */
|
||||
if (*AddressSpace == 0)
|
||||
{
|
||||
/* memory space */
|
||||
|
||||
}
|
||||
else if (*AddressSpace == 1)
|
||||
{
|
||||
/* io space */
|
||||
}
|
||||
else if (*AddressSpace == 1)
|
||||
{
|
||||
/* io space */
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* other */
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* other */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
|
||||
TranslatedAddress->QuadPart = BusAddress.QuadPart + BaseAddress;
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
104
reactos/ntoskrnl/include/internal/hal/bus.h
Normal file
104
reactos/ntoskrnl/include/internal/hal/bus.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __INTERNAL_HAL_BUS_H
|
||||
#define __INTERNAL_HAL_BUS_H
|
||||
|
||||
struct _BUS_HANDLER;
|
||||
|
||||
typedef NTSTATUS (STDCALL *pAdjustResourceList) (
|
||||
IN struct _BUS_HANDLER *BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN OUT PCM_RESOURCE_LIST Resources
|
||||
);
|
||||
|
||||
typedef NTSTATUS (STDCALL *pAssignSlotResources) (
|
||||
IN struct _BUS_HANDLER *BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN PUNICODE_STRING RegistryPath,
|
||||
IN PUNICODE_STRING DriverClassName,
|
||||
IN PDRIVER_OBJECT DriverObject,
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN ULONG SlotNumber,
|
||||
IN OUT PCM_RESOURCE_LIST *AllocatedResources
|
||||
);
|
||||
|
||||
typedef ULONG (STDCALL *pGetSetBusData) (
|
||||
IN struct _BUS_HANDLER *BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN ULONG SlotNumber,
|
||||
OUT PVOID Buffer,
|
||||
IN ULONG Offset,
|
||||
IN ULONG Length
|
||||
);
|
||||
|
||||
typedef ULONG (STDCALL *pGetInterruptVector) (
|
||||
IN struct _BUS_HANDLER *BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN ULONG BusInterruptLevel,
|
||||
IN ULONG BusInterruptVector,
|
||||
OUT PKIRQL Irql,
|
||||
OUT PKAFFINITY Affinity
|
||||
);
|
||||
|
||||
typedef ULONG (STDCALL *pTranslateBusAddress) (
|
||||
IN struct _BUS_HANDLER *BusHandler,
|
||||
IN ULONG BusNumber,
|
||||
IN PHYSICAL_ADDRESS BusAddress,
|
||||
IN OUT PULONG AddressSpace,
|
||||
OUT PPHYSICAL_ADDRESS TranslatedAddress
|
||||
);
|
||||
|
||||
typedef struct _BUS_HANDLER
|
||||
{
|
||||
LIST_ENTRY Entry;
|
||||
INTERFACE_TYPE InterfaceType;
|
||||
BUS_DATA_TYPE BusDataType;
|
||||
ULONG BusNumber;
|
||||
ULONG RefCount;
|
||||
|
||||
pGetSetBusData GetBusData;
|
||||
pGetSetBusData SetBusData;
|
||||
pAdjustResourceList AdjustResourceList;
|
||||
pAssignSlotResources AssignSlotResources;
|
||||
pGetInterruptVector GetInterruptVector;
|
||||
pTranslateBusAddress TranslateBusAddress;
|
||||
} BUS_HANDLER, *PBUS_HANDLER;
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/* bus.c */
|
||||
PBUS_HANDLER
|
||||
HalpAllocateBusHandler(INTERFACE_TYPE InterfaceType,
|
||||
BUS_DATA_TYPE BusDataType,
|
||||
ULONG BusNumber);
|
||||
|
||||
/* sysbus.h */
|
||||
ULONG STDCALL
|
||||
HalpGetSystemInterruptVector(PVOID BusHandler,
|
||||
ULONG BusNumber,
|
||||
ULONG BusInterruptLevel,
|
||||
ULONG BusInterruptVector,
|
||||
PKIRQL Irql,
|
||||
PKAFFINITY Affinity);
|
||||
|
||||
BOOLEAN STDCALL
|
||||
HalpTranslateSystemBusAddress(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress);
|
||||
|
||||
/* isa.c */
|
||||
BOOLEAN STDCALL
|
||||
HalpTranslateIsaBusAddress(PBUS_HANDLER BusHandler,
|
||||
ULONG BusNumber,
|
||||
PHYSICAL_ADDRESS BusAddress,
|
||||
PULONG AddressSpace,
|
||||
PPHYSICAL_ADDRESS TranslatedAddress);
|
||||
|
||||
#endif /* __INTERNAL_HAL_BUS_H */
|
||||
|
||||
/* EOF */
|
Loading…
Reference in a new issue