From df18b87eab89e52142f36de8ae0aca817482baa4 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 6 May 2003 16:36:42 +0000 Subject: [PATCH] Added PnP-BIOS detection. svn path=/trunk/; revision=4651 --- freeldr/freeldr/Makefile | 3 +- freeldr/freeldr/arch/i386/hardware.c | 315 +++++++++++++++++++-------- freeldr/freeldr/arch/i386/hardware.h | 176 +++++++++++++++ freeldr/freeldr/arch/i386/i386cpu.S | 6 + freeldr/freeldr/arch/i386/i386pnp.S | 297 +++++++++++++++++++++++++ 5 files changed, 700 insertions(+), 97 deletions(-) create mode 100644 freeldr/freeldr/arch/i386/hardware.h create mode 100644 freeldr/freeldr/arch/i386/i386pnp.S diff --git a/freeldr/freeldr/Makefile b/freeldr/freeldr/Makefile index 54372157f63..eff4bf3dbc2 100644 --- a/freeldr/freeldr/Makefile +++ b/freeldr/freeldr/Makefile @@ -196,6 +196,8 @@ ARCH_OBJS = fathelp.o \ arch.o \ i386idt.o \ i386trap.o \ + i386cpu.o \ + i386pnp.o \ boot.o \ linux.o \ mb.o \ @@ -207,7 +209,6 @@ ARCH_OBJS = fathelp.o \ i386disk.o \ portio.o \ hardware.o \ - i386cpu.o \ _alloca.o # For Mingw32 builds RTL_OBJS = print.o \ diff --git a/freeldr/freeldr/arch/i386/hardware.c b/freeldr/freeldr/arch/i386/hardware.c index 9cbe5989b69..08a9e0f2ff6 100644 --- a/freeldr/freeldr/arch/i386/hardware.c +++ b/freeldr/freeldr/arch/i386/hardware.c @@ -27,6 +27,7 @@ #include #include "../../reactos/registry.h" +#include "hardware.h" #define MILLISEC (10) @@ -37,29 +38,6 @@ #define LATCH (CLOCK_TICK_RATE / HZ) -typedef enum -{ - InterfaceTypeUndefined = -1, - Internal, - Isa, - Eisa, - MicroChannel, - TurboChannel, - PCIBus, - VMEBus, - NuBus, - PCMCIABus, - CBus, - MPIBus, - MPSABus, - ProcessorInternal, - InternalPowerBus, - PNPISABus, - MaximumInterfaceType -} INTERFACE_TYPE, *PINTERFACE_TYPE; - - -typedef U64 PHYSICAL_ADDRESS; typedef struct _CM_INT13_DRIVE_PARAMETER @@ -81,70 +59,35 @@ typedef struct _CM_DISK_GEOMETRY_DEVICE_DATA } CM_DISK_GEOMETRY_DEVICE_DATA, *PCM_DISK_GEOMETRY_DEVICE_DATA; -typedef struct -{ - U8 Type; - U8 ShareDisposition; - U16 Flags; - union - { - struct - { - PHYSICAL_ADDRESS Start; - U32 Length; - } __attribute__((packed)) Port; - struct - { - U32 Level; - U32 Vector; - U32 Affinity; - } __attribute__((packed)) Interrupt; - struct - { - PHYSICAL_ADDRESS Start; - U32 Length; - } __attribute__((packed)) Memory; - struct - { - U32 Channel; - U32 Port; - U32 Reserved1; - } __attribute__((packed)) Dma; - struct - { - U32 DataSize; - U32 Reserved1; - U32 Reserved2; - } __attribute__((packed)) DeviceSpecificData; - } __attribute__((packed)) u; -} __attribute__((packed)) CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR; -typedef struct -{ - U16 Version; - U16 Revision; - U32 Count; - CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; -} __attribute__((packed))CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST; - - -typedef struct -{ - INTERFACE_TYPE InterfaceType; - U32 BusNumber; - CM_PARTIAL_RESOURCE_LIST PartialResourceList; -} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR; - - -typedef struct _DEVICE_NODE +typedef struct _CM_PNP_BIOS_DEVICE_NODE { U16 Size; U8 Node; - U8 ProductId[4]; + U32 ProductId; U8 DeviceType[3]; U16 DeviceAttributes; -} PACKED DEVICE_NODE, *PDEVICE_NODE; +} __attribute__((packed)) CM_PNP_BIOS_DEVICE_NODE, *PCM_PNP_BIOS_DEVICE_NODE; + + +typedef struct _CM_PNP_BIOS_INSTALLATION_CHECK +{ + U8 Signature[4]; + U8 Revision; + U8 Length; + U16 ControlField; + U8 Checksum; + U32 EventFlagAddress; + U16 RealModeEntryOffset; + U16 RealModeEntrySegment; + U16 ProtectedModeEntryOffset; + U32 ProtectedModeCodeBaseAddress; + U32 OemDeviceId; + U16 RealModeDataBaseAddress; + U32 ProtectedModeDataBaseAddress; +} __attribute__((packed)) CM_PNP_BIOS_INSTALLATION_CHECK, *PCM_PNP_BIOS_INSTALLATION_CHECK; + typedef struct _MPS_CONFIG_TABLE_HEADER { @@ -163,6 +106,7 @@ typedef struct _MPS_CONFIG_TABLE_HEADER U8 Reserved; } PACKED MPS_CONFIG_TABLE_HEADER, *PMPS_CONFIG_TABLE_HEADER; + typedef struct _MPS_PROCESSOR_ENTRY { U8 EntryType; @@ -175,20 +119,10 @@ typedef struct _MPS_PROCESSOR_ENTRY U32 Reserved2; } PACKED MPS_PROCESSOR_ENTRY, *PMPS_PROCESSOR_ENTRY; + static char Hex[] = "0123456789ABCDEF"; static unsigned int delay_count = 1; -/* PROTOTYPES ***************************************************************/ - -/* i386cpu.S */ - -U32 CpuidSupported(VOID); -VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx); - -U32 MpsSupported(VOID); -U32 MpsGetDefaultConfiguration(VOID); -U32 MpsGetConfigurationTable(PVOID ConfigTable); - /* FUNCTIONS ****************************************************************/ @@ -299,6 +233,184 @@ HalpCalibrateStallExecution(VOID) } +VOID +SetComponentInformation(HKEY ComponentKey, + U32 Flags, + U32 Key, + U32 Affinity) +{ + CM_COMPONENT_INFORMATION CompInfo; + S32 Error; + + CompInfo.Flags = Flags; + CompInfo.Version = 0; + CompInfo.Key = Key; + CompInfo.Affinity = Affinity; + + /* Set 'Component Information' value */ + Error = RegSetValue(ComponentKey, + "Component Information", + REG_BINARY, + (PU8)&CompInfo, + sizeof(CM_COMPONENT_INFORMATION)); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error)); + } +} + + +static VOID +DetectPnpBios(HKEY SystemKey, U32 *BusNumber) +{ + PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + PCM_PNP_BIOS_DEVICE_NODE DeviceNode; + char Buffer[80]; + HKEY BusKey; + U32 x; + U32 NodeSize = 0; + U32 NodeCount = 0; + U8 NodeNumber; + U32 FoundNodeCount; + int i; + U32 PnpBufferSize; + U32 Size; + char *Ptr; + S32 Error; + + x = PnpBiosSupported((PVOID)DISKREADBUFFER); + if (!x) + { + printf(" PnP-BIOS not supported\n"); + return; + } + + x = PnpBiosGetDeviceNodeCount(&NodeSize, &NodeCount); + if (x != 0 || NodeSize == 0 || NodeCount == 0) + { + DbgPrint((DPRINT_HWDETECT, "PnP-BIOS failed to enumerate device nodes\n"); + return; + } + DbgPrint((DPRINT_HWDETECT, + "PnP-BIOS supported: found %u device nodes\n", + (unsigned int)NodeCount)); + + FoundNodeCount = 0; + + PnpBufferSize = 0; + for (i = 0; i < 0x255; i++) + { + NodeNumber = (U8)i; + + x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER); + if (x == 0) + { + DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER; + PnpBufferSize += DeviceNode->Size; + + FoundNodeCount++; + if (FoundNodeCount >= NodeCount) + break; + } + } + PnpBufferSize += sizeof(CM_PNP_BIOS_INSTALLATION_CHECK); + DbgPrint((DPRINT_HWDETECT, "PnpBufferSize: %u\n", PnpBufferSize)); + + /* Create new bus key */ + sprintf(Buffer, + "MultifunctionAdapter\\%u", *BusNumber); + Error = RegCreateKey(SystemKey, + Buffer, + &BusKey); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, "RegCreateKey() failed (Error %u)\n", (int)Error)); + return; + } + + /* Increment bus number */ + (*BusNumber)++; + + /* Set 'Identifier' value */ + Error = RegSetValue(BusKey, + "Identifier", + REG_SZ, + (PU8)"PNP BIOS", + 9); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, "RegSetValue() failed (Error %u)\n", (int)Error)); + return; + } + + /* Set 'Configuration Data' value */ + Size = sizeof(CM_FULL_RESOURCE_DESCRIPTOR) + PnpBufferSize; + FullResourceDescriptor = MmAllocateMemory(Size); + if (FullResourceDescriptor == NULL) + { + DbgPrint((DPRINT_HWDETECT, + "Failed to allocate resource descriptor\n")); + return; + } + + /* Initialize resource descriptor */ + memset(FullResourceDescriptor, 0, Size); + FullResourceDescriptor->InterfaceType = Internal; + FullResourceDescriptor->BusNumber = 0; + FullResourceDescriptor->PartialResourceList.Count = 1; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Type = + CmResourceTypeDeviceSpecific; + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].ShareDisposition = + CmResourceShareUndetermined; +// FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].Flags = + FullResourceDescriptor->PartialResourceList.PartialDescriptors[0].u.DeviceSpecificData.DataSize = + PnpBufferSize; + + Ptr = (char *)((PVOID)FullResourceDescriptor) + sizeof(CM_FULL_RESOURCE_DESCRIPTOR); + + /* Set instalation check data */ + PnpBiosSupported((PVOID)DISKREADBUFFER); + memcpy (Ptr, (PVOID)DISKREADBUFFER, sizeof(CM_PNP_BIOS_INSTALLATION_CHECK)); + + Ptr = (char *)((PVOID)Ptr + sizeof(CM_PNP_BIOS_INSTALLATION_CHECK)); + + /* Copy device nodes */ + for (i = 0; i < 0x255; i++) + { + NodeNumber = (U8)i; + + x = PnpBiosGetDeviceNode(&NodeNumber, (PVOID)DISKREADBUFFER); + if (x == 0) + { + DeviceNode = (PCM_PNP_BIOS_DEVICE_NODE)DISKREADBUFFER; + + memcpy (Ptr, + DeviceNode, + DeviceNode->Size); + Ptr = (char *)((U32)Ptr + DeviceNode->Size); + + FoundNodeCount++; + if (FoundNodeCount >= NodeCount) + break; + } + } + + /* Set 'Configuration Data' value */ + Error = RegSetValue(BusKey, + "Configuration Data", + REG_FULL_RESOURCE_DESCRIPTOR, + (PU8) FullResourceDescriptor, + Size); + MmFreeMemory(FullResourceDescriptor); + if (Error != ERROR_SUCCESS) + { + DbgPrint((DPRINT_HWDETECT, + "RegSetValue(Configuration Data) failed (Error %u)\n", + (int)Error)); + } +} + + static VOID DetectCPU(HKEY CpuKey, HKEY FpuKey) @@ -372,7 +484,9 @@ DetectCPU(HKEY CpuKey, FeatureSet = 0; } - /* FIXME: Set 'Configuration Data' value (CPU and FPU) */ + /* Set 'Conmponent Information' value (CPU and FPU) */ + SetComponentInformation(CpuInstKey, 0, 0, 1); + SetComponentInformation(FpuInstKey, 0, 0, 1); /* Set 'FeatureSet' value (CPU only) */ DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet)); @@ -492,7 +606,16 @@ SetMpsProcessor(HKEY CpuKey, /* Get FeatureSet */ FeatureSet = CpuEntry->FeatureFlags; - /* FIXME: Set 'Configuration Data' value (CPU and FPU) */ + /* Set 'Configuration Data' value (CPU and FPU) */ + SetComponentInformation(CpuInstKey, + 0, + CpuEntry->LocalApicId, + 1 << CpuEntry->LocalApicId); + + SetComponentInformation(FpuInstKey, + 0, + CpuEntry->LocalApicId, + 1 << CpuEntry->LocalApicId); /* Set 'FeatureSet' value (CPU only) */ DbgPrint((DPRINT_HWDETECT, "FeatureSet: %x\n", FeatureSet)); @@ -660,7 +783,7 @@ DetectCPUs(HKEY SystemKey) return; } - /* Create the 'CentralProcessor' key */ + /* Create the 'FloatingPointProcessor' key */ Error = RegCreateKey(SystemKey, "FloatingPointProcessor", &FpuKey); @@ -1044,14 +1167,14 @@ DetectHardware(VOID) return; } -// DetectBiosData (); +// DetectSystemData (); DetectCPUs (SystemKey); /* Detect buses */ // DetectPciBios (&BusNumber); // DetectApmBios (&BusNumber); -// DetectPnpBios (&BusNumber); + DetectPnpBios (SystemKey, &BusNumber); DetectIsaBios (SystemKey, &BusNumber); // DetectAcpiBios (&BusNumber); diff --git a/freeldr/freeldr/arch/i386/hardware.h b/freeldr/freeldr/arch/i386/hardware.h new file mode 100644 index 00000000000..1291540a08c --- /dev/null +++ b/freeldr/freeldr/arch/i386/hardware.h @@ -0,0 +1,176 @@ +/* + * FreeLoader + * + * Copyright (C) 2003 Eric Kohl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __I386_HARDWARE_H_ +#define __I386_HARDWARE_H_ + +typedef enum +{ + InterfaceTypeUndefined = -1, + Internal, + Isa, + Eisa, + MicroChannel, + TurboChannel, + PCIBus, + VMEBus, + NuBus, + PCMCIABus, + CBus, + MPIBus, + MPSABus, + ProcessorInternal, + InternalPowerBus, + PNPISABus, + MaximumInterfaceType +} INTERFACE_TYPE, *PINTERFACE_TYPE; + + +typedef enum _CM_RESOURCE_TYPE +{ + CmResourceTypeNull = 0, + CmResourceTypePort, + CmResourceTypeInterrupt, + CmResourceTypeMemory, + CmResourceTypeDma, + CmResourceTypeDeviceSpecific, + CmResourceTypeMaximum +} CM_RESOURCE_TYPE; + + +typedef enum _CM_SHARE_DISPOSITION +{ + CmResourceShareUndetermined = 0, + CmResourceShareDeviceExclusive, + CmResourceShareDriverExclusive, + CmResourceShareShared +} CM_SHARE_DISPOSITION; + + +typedef U64 PHYSICAL_ADDRESS; + +typedef struct +{ + U8 Type; + U8 ShareDisposition; + U16 Flags; + union + { + struct + { + PHYSICAL_ADDRESS Start; + U32 Length; + } __attribute__((packed)) Port; + struct + { + U32 Level; + U32 Vector; + U32 Affinity; + } __attribute__((packed)) Interrupt; + struct + { + PHYSICAL_ADDRESS Start; + U32 Length; + } __attribute__((packed)) Memory; + struct + { + U32 Channel; + U32 Port; + U32 Reserved1; + } __attribute__((packed)) Dma; + struct + { + U32 DataSize; + U32 Reserved1; + U32 Reserved2; + } __attribute__((packed)) DeviceSpecificData; + } __attribute__((packed)) u; +} __attribute__((packed)) CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR; + + +typedef struct +{ + U16 Version; + U16 Revision; + U32 Count; + CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]; +} __attribute__((packed))CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST; + + +typedef struct +{ + INTERFACE_TYPE InterfaceType; + U32 BusNumber; + CM_PARTIAL_RESOURCE_LIST PartialResourceList; +} __attribute__((packed)) CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR; + + +typedef struct _CM_COMPONENT_INFORMATION +{ + U32 Flags; + U32 Version; + U32 Key; + U32 Affinity; +} __attribute__((packed)) CM_COMPONENT_INFORMATION, *PCM_COMPONENT_INFORMATION; + + +/* CM_COMPONENT_INFORMATION.Flags */ +#define Failed 0x00000001 +#define ReadOnly 0x00000002 +#define Removable 0x00000004 +#define ConsoleIn 0x00000008 +#define ConsoleOut 0x00000010 +#define Input 0x00000020 +#define Output 0x00000040 + + +/* PROTOTYPES ***************************************************************/ + +/* hardware.c */ +VOID SetComponentInformation(HKEY ComponentKey, + U32 Flags, + U32 Key, + U32 Affinity); + +/* hwcpu.c */ + +/* i386cpu.S */ +U32 CpuidSupported(VOID); +VOID GetCpuid(U32 Level, + U32 *eax, + U32 *ebx, + U32 *ecx, + U32 *edx); + +U32 MpsSupported(VOID); +U32 MpsGetDefaultConfiguration(VOID); +U32 MpsGetConfigurationTable(PVOID ConfigTable); + +/* i386pnp.S */ +//U32 PnpBiosSupported(VOID); +U32 PnpBiosSupported(PVOID InstallationCheck); +U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize, + U32 *NodeCount); +U32 PnpBiosGetDeviceNode(U8 *NodeId, + U8 *NodeBuffer); + +#endif /* __I386_HARDWARE_H_ */ + +/* EOF */ diff --git a/freeldr/freeldr/arch/i386/i386cpu.S b/freeldr/freeldr/arch/i386/i386cpu.S index 77a3ada9661..26bb9e7b862 100644 --- a/freeldr/freeldr/arch/i386/i386cpu.S +++ b/freeldr/freeldr/arch/i386/i386cpu.S @@ -122,6 +122,8 @@ EXTERN(_GetCpuid) * * RETURNS: */ + + .code16 _mps_supported: .long 0 _mps_fp_table_offset: @@ -190,6 +192,7 @@ mps_not_found: * * RETURNS: */ + .code16 _mps_default_configuration: .long 0 @@ -239,6 +242,7 @@ EXTERN(_MpsGetDefaultConfiguration) * * RETURNS: */ + .code16 _mps_buffer_segment: .word 0 _mps_buffer_offset: @@ -311,7 +315,9 @@ EXTERN(_MpsGetConfigurationTable) movw _mps_config_offset,%si /* init DS */ +.code32 movw _mps_config_segment,%ax +.code16 pushw %ds pushw %ax popw %ds diff --git a/freeldr/freeldr/arch/i386/i386pnp.S b/freeldr/freeldr/arch/i386/i386pnp.S new file mode 100644 index 00000000000..be02af4b2fa --- /dev/null +++ b/freeldr/freeldr/arch/i386/i386pnp.S @@ -0,0 +1,297 @@ +/* + * FreeLoader + * Copyright (C) 2003 Eric Kohl + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + .text + .code16 + +#define ASM + +#include + + +/* + * U32 PnpBiosSupported(PVOID InstallationCheck); + * + * RETURNS: + */ +_pnp_support_result: + .long 0 +_pnp_entry_point: + .word 0 +_pnp_code_segment: + .word 0 +_pnp_data_segment: + .word 0 + +EXTERN(_PnpBiosSupported) + .code32 + + pushal + push %es + + /* convert pointer to node buffer to segment/offset */ + movl 0x08(%ebp),%eax + shrl $4,%eax + andl $0xf000,%eax + movw %ax,_pnp_buffer_segment + movl 0x08(%ebp),%eax + andl $0xffff,%eax + movw %ax,_pnp_buffer_offset + + call switch_to_real + + .code16 + + /* init ES */ + pushw $0xF000 + popw %es + + /* init cx */ + movw $0xFFF0,%si + +pnp_again: + movw %es:(%si),%ax + cmp $0x5024,%ax /* "$P" */ + jne pnp_next + + push %si + add $2,%si + movw %es:(%si),%ax + cmp $0x506E,%ax /* "nP" */ + pop %si + je pnp_found + +pnp_next: + cmp $0,%si + je pnp_not_found + + sub $0x10,%si + jmp pnp_again + +pnp_found: + movzwl %si,%eax + movl %eax,_pnp_support_result + + add $0x0D,%si + movw %es:(%si),%ax + movw %ax,_pnp_entry_point + + add $0x02,%si + movw %es:(%si),%ax + movw %ax,_pnp_code_segment + + add $0x0C,%si + movw %es:(%si),%ax + movw %ax,_pnp_data_segment + + /* copy data to buffer */ + push %ds + movw %es, %ax + movw %ax, %ds + movl _pnp_support_result, %esi + movw _pnp_buffer_segment, %es + movw _pnp_buffer_offset, %di + movw $0x21, %cx + rep movsb + + pop %ds +pnp_not_found: + + call switch_to_prot + + .code32 + + pop %es + popal + + movl _pnp_support_result,%eax + + ret + + +/* + * U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize, U32 *NodeCount); + * + * RETURNS: + */ +_entry_point: + .long 0 +_pnp_node_size: + .word 0 +_pnp_node_count: + .word 0 + +EXTERN(_PnpBiosGetDeviceNodeCount) + .code32 + + pushl %ebp + movl %esp,%ebp + + pushal + push %es + + call switch_to_real + + .code16 + + movw _pnp_data_segment,%ax + pushw %ax + + pushw %cs + movw $(_pnp_node_size),%ax + pushw %ax + + pushw %cs + movw $(_pnp_node_count),%ax + pushw %ax + + pushw $0 + + movw _pnp_code_segment,%ax + movzwl %ax,%ecx + shll $16,%ecx + movw _pnp_entry_point,%ax + movzwl %ax,%ebx + orl %ebx,%ecx + movl %ecx,_entry_point + + lcall *_entry_point + addw $12,%sp + + movzwl %ax,%ecx + movl %ecx,_pnp_support_result + + + call switch_to_prot + + .code32 + + movl 0x08(%ebp),%esi + movw _pnp_node_size,%ax + movzwl %ax,%ecx + movl %ecx, (%esi) + + movl 0x0C(%ebp),%esi + movw _pnp_node_count,%ax + movzwl %ax,%ecx + movl %eax, (%esi) + + pop %es + popal + + movl %ebp,%esp + popl %ebp + + movl _pnp_support_result,%eax + + ret + + +/* + * U32 PnpBiosGetDeviceNode(U8 *NodeId, U8 *NodeBuffer); + * + * RETURNS: + */ +_pnp_buffer_segment: + .word 0 +_pnp_buffer_offset: + .word 0 + +_pnp_node_number: + .byte 0 + + +EXTERN(_PnpBiosGetDeviceNode) + .code32 + + pushl %ebp + movl %esp,%ebp + + pushal + push %es + + /* get current node number */ + movl 0x08(%ebp),%esi + movb (%esi),%al + movb %al,_pnp_node_number + + /* convert pointer to node buffer to segment/offset */ + movl 0x0C(%ebp),%eax + shrl $4,%eax + andl $0xf000,%eax + movw %ax,_pnp_buffer_segment + movl 0x0C(%ebp),%eax + andl $0xffff,%eax + movw %ax,_pnp_buffer_offset + + call switch_to_real + + .code16 + + /* push bios segment */ + movw _pnp_data_segment,%ax + pushw %ax + + /* push control flag */ + pushw $0x0001 + + /* push pointer to node buffer (segment/offset) */ + movw _pnp_buffer_segment,%ax + pushw %ax + movw _pnp_buffer_offset,%ax + pushw %ax + + /* push pointer to node number (segment/offset) */ + pushw %cs + movw $(_pnp_node_number),%ax + pushw %ax + + /* push function number */ + pushw $1 + + /* call entry point */ + lcall *_entry_point + addw $14,%sp + + movzwl %ax,%ecx + movl %ecx,_pnp_support_result + + + call switch_to_prot + + .code32 + + + /* update node number */ + movl 0x08(%ebp),%esi + movb _pnp_node_number,%al + movb %al,(%esi) + + + pop %es + popal + + movl %ebp,%esp + popl %ebp + + movl _pnp_support_result,%eax + + ret + +/* EOF */