#pragma option -3 #include #include "biosl.h" #define NULL (void *)(0) static int read_config_area(byte function, byte bus_number, byte device_and_function, byte register_number, dword *data); int pci_bios_present(byte *hardware_mechanism, word *interface_level_version, byte *last_pci_bus_number) { int ret_status; /* Function Return Status. */ byte bios_present_status;/* Indicates if PCI bios present */ dword pci_signature; /* PCI Signature ('P', 'C', 'I', ' ') */ word ax, bx, cx, flags; /* Temporary variables to hold register values */ /* Load entry registers for PCI BIOS */ _AH = PCI_FUNCTION_ID; _AL = PCI_BIOS_PRESENT; /* Call PCI BIOS Int 1Ah interface */ geninterrupt(0x1a); /* Save registers before overwritten by compiler usage of registers */ ax = _AX; bx = _BX; cx = _CX; pci_signature = _EDX; flags = _FLAGS; bios_present_status = HIGH_BYTE(ax); /* First check if CARRY FLAG Set, if so, BIOS not present */ if ((flags & CARRY_FLAG) == 0) { /* Next, must check that AH (BIOS Present Status) == 0 */ if (bios_present_status == 0) { /* Check bytes in pci_signature for PCI Signature */ if ((pci_signature & 0xff) == 'P' && ((pci_signature >> 8) & 0xff) == 'C' && ((pci_signature >> 16) & 0xff) == 'I' && ((pci_signature >> 24) & 0xff) == ' ') { /* Indicate to caller that PCI bios present */ ret_status = SUCCESSFUL; /* Extract calling parameters from saved registers */ if (hardware_mechanism != NULL) *hardware_mechanism = LOW_BYTE(ax); if (interface_level_version != NULL) *interface_level_version = bx; if (last_pci_bus_number != NULL) *last_pci_bus_number = LOW_BYTE(cx); } } else ret_status = NOT_SUCCESSFUL; } else ret_status = NOT_SUCCESSFUL; return (ret_status); } int find_pci_device(word device_id, word vendor_id, word index, byte *bus_number, byte *device_and_function) { int ret_status; /* Function Return Status */ word ax, bx, flags; /* Temporary variables to hold register values */ /* Load entry registers for PCI BIOS */ _CX = device_id; _DX = vendor_id; _SI = index; _AH = PCI_FUNCTION_ID; _AL = FIND_PCI_DEVICE; /* Call PCI BIOS Int 1Ah interface */ geninterrupt(0x1a); /* Save registers before overwritten by compiler usage of registers */ ax = _AX; bx = _BX; flags = _FLAGS; /* First check if CARRY FLAG Set, if so, error has occurred */ if ((flags & CARRY_FLAG) == 0) { /* Get Return code from BIOS */ ret_status = HIGH_BYTE(ax); if (ret_status == SUCCESSFUL) { /* Assign Bus Number, Device & Function if successful */ if (bus_number != NULL) *bus_number = HIGH_BYTE(bx); if (device_and_function != NULL) *device_and_function = LOW_BYTE(bx); } } else ret_status = NOT_SUCCESSFUL; return (ret_status); } int read_config_word(byte bus_number, byte device_and_function, byte register_number, word *word_read) { int ret_status; /* Function Return Status */ dword data; /* Call read_config_area function with word data */ ret_status = read_config_area(READ_CONFIG_WORD, bus_number, device_and_function, register_number, &data); if (ret_status == SUCCESSFUL) { /* Extract word */ *word_read = (word)(data & 0xffff); } return (ret_status); } static int read_config_area(byte function, byte bus_number, byte device_and_function, byte register_number, dword *data) { int ret_status; /* Function Return Status */ word ax, flags; /* Temporary variables to hold register values */ dword ecx; /* Temporary variable to hold ECX register value */ /* Load entry registers for PCI BIOS */ _BH = bus_number; _BL = device_and_function; _DI = register_number; _AH = PCI_FUNCTION_ID; _AL = function; /* Call PCI BIOS Int 1Ah interface */ geninterrupt(0x1a); /* Save registers before overwritten by compiler usage of registers */ ecx = _ECX; ax = _AX; flags = _FLAGS; /* First check if CARRY FLAG Set, if so, error has occurred */ if ((flags & CARRY_FLAG) == 0) { /* Get Return code from BIOS */ ret_status = HIGH_BYTE(ax); /* If successful, return data */ if (ret_status == SUCCESSFUL) *data = ecx; } else ret_status = NOT_SUCCESSFUL; return (ret_status); }