From 375b8055e36b3ba2aa9bf2d41c966aefe8641da0 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 17 Aug 2000 17:43:27 +0000 Subject: [PATCH] Added preliminary pci bus scanner svn path=/trunk/; revision=1303 --- reactos/ntoskrnl/hal/x86/misc.c | 23 +- reactos/ntoskrnl/hal/x86/pci.c | 293 ++++++++++++++++++- reactos/ntoskrnl/include/internal/i386/hal.h | 9 +- 3 files changed, 296 insertions(+), 29 deletions(-) diff --git a/reactos/ntoskrnl/hal/x86/misc.c b/reactos/ntoskrnl/hal/x86/misc.c index 50fb2f20c03..1549d6b2c4d 100644 --- a/reactos/ntoskrnl/hal/x86/misc.c +++ b/reactos/ntoskrnl/hal/x86/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.5 2000/08/12 19:33:20 dwelch Exp $ +/* $Id: misc.c,v 1.6 2000/08/17 17:42:53 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -10,7 +10,7 @@ /* INCLUDES *****************************************************************/ #include - +#include /* FUNCTIONS ****************************************************************/ @@ -74,20 +74,23 @@ HalReportResourceUsage ( */ /* - * Initialize PCI, IsaPnP and other busses. + * Initialize PCI bus. + */ + HalpInitPciBus (); +#if 0 + /* + * Initialize IsaPnP bus. + */ + HalpInitIsaPnpBus (); + + /* + * Initialize other busses??? */ -#if 0 /* * Probe for a BIOS32 extension */ Hal_bios32_probe(); - - /* - * Probe for buses attached to the computer - */ - - HalPciProbe(); #endif return; diff --git a/reactos/ntoskrnl/hal/x86/pci.c b/reactos/ntoskrnl/hal/x86/pci.c index e227e06e567..0623d883a19 100644 --- a/reactos/ntoskrnl/hal/x86/pci.c +++ b/reactos/ntoskrnl/hal/x86/pci.c @@ -1,11 +1,14 @@ -/* +/* $Id: pci.c,v 1.5 2000/08/17 17:42:53 ekohl Exp $ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/hal/x86/pci.c * PURPOSE: Interfaces to the PCI bus * PROGRAMMER: David Welch (welch@mcmail.com) + * Eric Kohl (ekohl@rz-online.de) * UPDATE HISTORY: - * 05/06/98: Created + * 05/06/1998: Created + * 17/08/2000: Added preliminary pci bus scanner */ /* @@ -17,20 +20,284 @@ #include #include +#define NDEBUG +#include + + +/* MACROS *****************************************************************/ + +/* access type 1 macros */ +#define PCI_FUNC(devfn) ((devfn) & 0x07) +#define CONFIG_CMD(bus, device_fn, where) \ + (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3)) + +#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) + + /* FUNCTIONS **************************************************************/ -#define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I'<<24)) - -BOOL HalPciProbe() /* - * FUNCTION: Probes for an PCI bus - * RETURNS: True if detected + * Bus access type 1 (recommended) */ +static int +ReadPciConfigUcharType1(UCHAR Bus, + UCHAR device_fn, + UCHAR where, + PUCHAR Value) { - if (Hal_bios32_is_service_present(PCI_SERVICE)) - { - DbgPrint("Detected PCI service\n"); - return(TRUE); - } - return(FALSE); + 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); + } +} + +static NTSTATUS +ScanPciBussesType1(VOID) +{ + ULONG i; + ULONG temp; + + DPRINT("ScanPciBussesType1()\n"); + + DPRINT("Checking if configuration type 1 works\n"); + WRITE_PORT_UCHAR((PUCHAR)0xCFB, 0x01); + temp = READ_PORT_ULONG((PULONG)0xCF8); + WRITE_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; + } + + 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"); + 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) + { + DPRINT("No pci configuration type 2\n"); + return STATUS_UNSUCCESSFUL; + } + + DPRINT("Using configuration type 2\n"); + for (i = 0; i < 8; i++) + { + DPRINT("Scanning PCI bus %u...\n", i); + ScanPciBusType2(i); + } + + return STATUS_UNSUCCESSFUL; +} + + +VOID HalpInitPciBus (VOID) +{ + NTSTATUS Status; + + DPRINT("HalpInitPciBus()\n"); + + Status = ScanPciBussesType1(); + if (NT_SUCCESS(Status)) + { + return; + } + + Status = ScanPciBussesType2(); + if (NT_SUCCESS(Status)) + { + return; + } + + DbgPrint("No pci bus found\n"); +} + +/* EOF */ diff --git a/reactos/ntoskrnl/include/internal/i386/hal.h b/reactos/ntoskrnl/include/internal/i386/hal.h index f7476113043..5a9c56f2f76 100644 --- a/reactos/ntoskrnl/include/internal/i386/hal.h +++ b/reactos/ntoskrnl/include/internal/i386/hal.h @@ -8,12 +8,6 @@ #include #include -/* - * FUNCTION: Probes for a PCI bus - * RETURNS: True if found - */ -BOOL HalPciProbe(void); - /* * FUNCTION: Probes for a BIOS32 extension */ @@ -35,4 +29,7 @@ VOID HalpInitPICs(VOID); /* udelay.c */ VOID HalpCalibrateStallExecution(VOID); +/* pci.c */ +VOID HalpInitPciBus (VOID); + #endif /* __INTERNAL_HAL_HAL_H */