https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9d06e79373bdc39ee69b70bba2b3293341874b27

commit 9d06e79373bdc39ee69b70bba2b3293341874b27
Author:     Dmitry Borisov <[email protected]>
AuthorDate: Wed Oct 19 20:48:27 2022 +0600
Commit:     GitHub <[email protected]>
CommitDate: Wed Oct 19 16:48:27 2022 +0200

    [FREELDR] Partially implement docking station detection (#4751)
---
 boot/freeldr/freeldr/arch/amd64/pnpbios.S        | 55 +++++++++++++++-------
 boot/freeldr/freeldr/arch/i386/pc/machpc.c       | 59 ++++++++++++++++++++++++
 boot/freeldr/freeldr/arch/i386/pnpbios.S         | 57 ++++++++++++++++-------
 boot/freeldr/freeldr/arch/realmode/amd64.S       |  2 +
 boot/freeldr/freeldr/arch/realmode/i386.S        |  2 +
 boot/freeldr/freeldr/arch/realmode/pnp.inc       | 25 ++++++++++
 boot/freeldr/freeldr/include/arch/pc/hardware.h  |  1 +
 boot/freeldr/freeldr/include/arch/pc/pcbios.h    |  6 +++
 boot/freeldr/freeldr/include/arch/pc/x86common.h |  1 +
 9 files changed, 175 insertions(+), 33 deletions(-)

diff --git a/boot/freeldr/freeldr/arch/amd64/pnpbios.S 
b/boot/freeldr/freeldr/arch/amd64/pnpbios.S
index 8dd44e933ca..4651f3bb0b0 100644
--- a/boot/freeldr/freeldr/arch/amd64/pnpbios.S
+++ b/boot/freeldr/freeldr/arch/amd64/pnpbios.S
@@ -1,21 +1,9 @@
 /*
- *  FreeLoader
- *  Copyright (C) 2003  Eric Kohl
- *  Copyright (C) 2011 Timo Kreuzer
- *
- *  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.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * PROJECT:     FreeLoader
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     PnP BIOS helper functions
+ * COPYRIGHT:   Copyright 2003 Eric Kohl <[email protected]>
+ *              Copyright 2011 Timo Kreuzer <[email protected]>
  */
 
 #include <asm.inc>
@@ -170,5 +158,38 @@ PnpBiosGetDeviceNode:
 
     ret
 
+
+/*
+ * U32 PnpBiosGetDockStationInformation(U8 *DockingStationInfo<rcx>);
+ *
+ * RETURNS:
+ */
+PUBLIC PnpBiosGetDockStationInformation
+PnpBiosGetDockStationInformation:
+
+    /* Convert pointer to info structure to segment/offset */
+    mov rax, rcx
+    shr eax, 4
+    mov word ptr [BSS_PnpBiosBufferSegment], ax
+    mov rax, rcx
+    and eax, HEX(0f)
+    mov word ptr [BSS_PnpBiosBufferOffset], ax
+
+    /* Save registers */
+    push rcx
+    push rbx
+
+    /* Call the real mode function */
+    mov bx, FNID_PnpBiosGetDockStationInformation
+    call CallRealMode
+
+    /* Restore registers */
+    pop rbx
+    pop rcx
+
+    mov eax, dword ptr [BSS_PnpResult]
+
+    ret
+
 END
 /* EOF */
diff --git a/boot/freeldr/freeldr/arch/i386/pc/machpc.c 
b/boot/freeldr/freeldr/arch/i386/pc/machpc.c
index 8ac4139442a..43baec3b491 100644
--- a/boot/freeldr/freeldr/arch/i386/pc/machpc.c
+++ b/boot/freeldr/freeldr/arch/i386/pc/machpc.c
@@ -177,6 +177,63 @@ PcGetHarddiskConfigurationData(UCHAR DriveNumber, ULONG* 
pSize)
     return PartialResourceList;
 }
 
+static
+VOID
+DetectDockingStation(
+    _Inout_ PCONFIGURATION_COMPONENT_DATA BusKey)
+{
+    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
+    PCONFIGURATION_COMPONENT_DATA PeripheralKey;
+    PDOCKING_STATE_INFORMATION DockingState;
+    ULONG Size, Result;
+
+    Result = PnpBiosGetDockStationInformation(DiskReadBuffer);
+
+    /* Build full device descriptor */
+    Size = sizeof(CM_PARTIAL_RESOURCE_LIST) +
+           sizeof(DOCKING_STATE_INFORMATION);
+    PartialResourceList = FrLdrHeapAlloc(Size, TAG_HW_RESOURCE_LIST);
+    if (PartialResourceList == NULL)
+    {
+        ERR("Failed to allocate resource descriptor\n");
+        return;
+    }
+
+    /* Initialize resource descriptor */
+    RtlZeroMemory(PartialResourceList, Size);
+    PartialResourceList->Version = 0;
+    PartialResourceList->Revision = 0;
+    PartialResourceList->Count = 1;
+
+    /* Set device specific data */
+    PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
+    PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
+    PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
+    PartialDescriptor->Flags = 0;
+    PartialDescriptor->u.DeviceSpecificData.DataSize = 
sizeof(DOCKING_STATE_INFORMATION);
+
+    DockingState = 
(PDOCKING_STATE_INFORMATION)&PartialResourceList->PartialDescriptors[1];
+    DockingState->ReturnCode = Result;
+    if (Result == 0)
+    {
+        /* FIXME: Add more device specific data */
+        ERR("FIXME: System docked\n");
+    }
+
+    /* Create controller key */
+    FldrCreateComponentKey(BusKey,
+                           PeripheralClass,
+                           DockingInformation,
+                           0,
+                           0,
+                           0xFFFFFFFF,
+                           "Docking State Information",
+                           PartialResourceList,
+                           Size,
+                           &PeripheralKey);
+}
+
 static
 VOID
 DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
@@ -308,6 +365,8 @@ DetectPnpBios(PCONFIGURATION_COMPONENT_DATA SystemKey, 
ULONG *BusNumber)
                            Size,
                            &BusKey);
 
+    DetectDockingStation(BusKey);
+
     (*BusNumber)++;
 }
 
diff --git a/boot/freeldr/freeldr/arch/i386/pnpbios.S 
b/boot/freeldr/freeldr/arch/i386/pnpbios.S
index e77b43fb201..018af55ca86 100644
--- a/boot/freeldr/freeldr/arch/i386/pnpbios.S
+++ b/boot/freeldr/freeldr/arch/i386/pnpbios.S
@@ -1,20 +1,8 @@
 /*
- *  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.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * PROJECT:     FreeLoader
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     PnP BIOS helper functions
+ * COPYRIGHT:   Copyright 2003 Eric Kohl <[email protected]>
  */
 
 #include <asm.inc>
@@ -179,6 +167,43 @@ _PnpBiosGetDeviceNode:
 
     ret
 
+
+/*
+ * U32 PnpBiosGetDockStationInformation(U8 *DockingStationInfo);
+ *
+ * RETURNS:
+ */
+PUBLIC _PnpBiosGetDockStationInformation
+_PnpBiosGetDockStationInformation:
+
+    push ebp
+    mov ebp, esp
+
+    pusha
+    push es
+
+    /* Convert pointer to info structure to segment/offset */
+    mov eax, [ebp + 8]
+    shr eax, 4
+    and eax, HEX(0f000)
+    mov word ptr ds:[BSS_PnpBiosBufferSegment], ax
+    mov eax, [ebp + 8]
+    and eax, HEX(0ffff)
+    mov word ptr ds:[BSS_PnpBiosBufferOffset], ax
+
+    mov bx, FNID_PnpBiosGetDockStationInformation
+    call i386CallRealMode
+
+    pop es
+    popa
+
+    mov esp, ebp
+    pop ebp
+
+    mov eax, [BSS_PnpResult]
+
+    ret
+
 END
 
 /* EOF */
diff --git a/boot/freeldr/freeldr/arch/realmode/amd64.S 
b/boot/freeldr/freeldr/arch/realmode/amd64.S
index d948df6eead..28ade6be943 100644
--- a/boot/freeldr/freeldr/arch/realmode/amd64.S
+++ b/boot/freeldr/freeldr/arch/realmode/amd64.S
@@ -360,6 +360,7 @@ LongModeEntryPoint:
     int HEX(16)
     jmp Reboot
 
+/* FNID_* functions */
 CallbackTable:
     .word Int386
     .word Reboot
@@ -367,6 +368,7 @@ CallbackTable:
     .word PxeCallApi
     .word PnpBiosGetDeviceNodeCount
     .word PnpBiosGetDeviceNode
+    .word PnpBiosGetDockStationInformation
 
     /* 16-bit stack pointer */
 stack16:
diff --git a/boot/freeldr/freeldr/arch/realmode/i386.S 
b/boot/freeldr/freeldr/arch/realmode/i386.S
index 5f4d35f70db..d2bcd7b9288 100644
--- a/boot/freeldr/freeldr/arch/realmode/i386.S
+++ b/boot/freeldr/freeldr/arch/realmode/i386.S
@@ -140,6 +140,7 @@ pm_entrypoint:
     .long 0 // receives address of PE entry point
     nop
 
+/* FNID_* functions */
 CallbackTable:
     .word Int386
     .word Reboot
@@ -147,6 +148,7 @@ CallbackTable:
     .word PxeCallApi
     .word PnpBiosGetDeviceNodeCount
     .word PnpBiosGetDeviceNode
+    .word PnpBiosGetDockStationInformation
 
 
     /* 16-bit stack pointer */
diff --git a/boot/freeldr/freeldr/arch/realmode/pnp.inc 
b/boot/freeldr/freeldr/arch/realmode/pnp.inc
index dde53fcbf00..610bd1fba79 100644
--- a/boot/freeldr/freeldr/arch/realmode/pnp.inc
+++ b/boot/freeldr/freeldr/arch/realmode/pnp.inc
@@ -54,3 +54,28 @@ PnpBiosGetDeviceNode:
     mov dword ptr ds:[BSS_PnpResult], ecx
 
     ret
+
+
+PnpBiosGetDockStationInformation:
+
+    /* push bios segment */
+    mov ax, word ptr ds:[BSS_PnpBiosDataSegment]
+    push ax
+
+    /* push pointer to info structure (segment/offset) */
+    mov ax, word ptr ds:[BSS_PnpBiosBufferSegment]
+    push ax
+    mov ax, word ptr ds:[BSS_PnpBiosBufferOffset]
+    push ax
+
+    /* push function number */
+    push 5
+
+    /* call entry point */
+    call dword ptr ds:[BSS_PnpBiosEntryPoint]
+    add sp, 8
+
+    movzx ecx, ax
+    mov dword ptr ds:[BSS_PnpResult], ecx
+
+    ret
diff --git a/boot/freeldr/freeldr/include/arch/pc/hardware.h 
b/boot/freeldr/freeldr/include/arch/pc/hardware.h
index fb547212ea8..de408b74cd9 100644
--- a/boot/freeldr/freeldr/include/arch/pc/hardware.h
+++ b/boot/freeldr/freeldr/include/arch/pc/hardware.h
@@ -87,6 +87,7 @@ ULONG __cdecl PnpBiosGetDeviceNodeCount(ULONG *NodeSize,
                   ULONG *NodeCount);
 ULONG __cdecl PnpBiosGetDeviceNode(UCHAR *NodeId,
              UCHAR *NodeBuffer);
+ULONG __cdecl PnpBiosGetDockStationInformation(UCHAR *DockingStationInfo);
 
 /* i386pxe.S */
 USHORT __cdecl PxeCallApi(USHORT Segment, USHORT Offset, USHORT Service, VOID* 
Parameter);
diff --git a/boot/freeldr/freeldr/include/arch/pc/pcbios.h 
b/boot/freeldr/freeldr/include/arch/pc/pcbios.h
index 3b03a32dbc7..f3539d21426 100644
--- a/boot/freeldr/freeldr/include/arch/pc/pcbios.h
+++ b/boot/freeldr/freeldr/include/arch/pc/pcbios.h
@@ -79,6 +79,12 @@ typedef struct _ACPI_BIOS_DATA
     BIOS_MEMORY_MAP MemoryMap[1]; /* Count of BIOS memory map entries */
 } ACPI_BIOS_DATA, *PACPI_BIOS_DATA;
 
+typedef struct _DOCKING_STATE_INFORMATION
+{
+    USHORT Unused[5];
+    USHORT ReturnCode;
+} DOCKING_STATE_INFORMATION, *PDOCKING_STATE_INFORMATION;
+
 #include <pshpack1.h>
 typedef struct
 {
diff --git a/boot/freeldr/freeldr/include/arch/pc/x86common.h 
b/boot/freeldr/freeldr/include/arch/pc/x86common.h
index e4c304bb38c..27c377039d5 100644
--- a/boot/freeldr/freeldr/include/arch/pc/x86common.h
+++ b/boot/freeldr/freeldr/include/arch/pc/x86common.h
@@ -58,6 +58,7 @@
 #define FNID_PxeCallApi 3
 #define FNID_PnpBiosGetDeviceNodeCount  4
 #define FNID_PnpBiosGetDeviceNode       5
+#define FNID_PnpBiosGetDockStationInformation  6
 
 /* Flag Masks */
 #define CR0_PE_SET    HEX(00000001)    /* OR this value with CR0 to enable 
pmode */

Reply via email to