1/*
2 * PROJECT:     FreeLoader
3 * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE:     PnP BIOS helper functions
5 * COPYRIGHT:   Copyright 2003 Eric Kohl <eric.kohl@reactos.org>
6 *              Copyright 2011 Timo Kreuzer <timo.kreuzer@reactos.org>
7 */
8
9#include <asm.inc>
10#include <arch/pc/x86common.h>
11
12EXTERN CallRealMode:PROC
13
14.code64
15
16/*
17 * U32 PnpBiosSupported(VOID);
18 *
19 * RETURNS:
20 */
21PUBLIC PnpBiosSupported
22PnpBiosSupported:
23
24    push rdi
25    push rsi
26    push rcx
27    push rdx
28
29    xor rdi, rdi
30
31    /* init rsi */
32    mov rsi, HEX(0F0000)
33
34pnp_again:
35    mov eax, [rsi]
36    cmp eax, HEX(506E5024)  /* "$PnP" */
37    je pnp_found
38
39    cmp rsi, HEX(0FFFF0)
40    je pnp_not_found
41
42pnp_add:
43    add rsi, 16
44    jmp pnp_again
45
46pnp_found:
47    /* first calculate the checksum */
48    push rsi
49
50    push HEX(21)
51    pop rcx
52    xor edx, edx
53
54pnp_loop:
55    lodsb
56    add dl, al
57    loop pnp_loop
58
59    test dl, dl
60    pop rsi
61    jnz pnp_add
62
63    mov rdi, rsi
64
65    /* Calculate the bios entry point (far pointer) */
66    xor eax, eax
67    mov ax, [rsi + HEX(0F)]
68    shl eax, 16
69    mov ax, [rsi + HEX(0D)]
70    mov dword ptr [BSS_PnpBiosEntryPoint], eax
71
72    /* Store bios data segment */
73    mov ax, [rsi + HEX(1B)]
74    mov word ptr [BSS_PnpBiosDataSegment], ax
75
76pnp_not_found:
77    mov rax, rdi
78
79    pop rdx
80    pop rcx
81    pop rsi
82    pop rdi
83
84    ret
85
86
87/*
88 * U32 PnpBiosGetDeviceNodeCount(U32 *NodeSize<rcx>, U32 *NodeCount<rdx>);
89 *
90 * RETURNS:
91 */
92PUBLIC PnpBiosGetDeviceNodeCount
93PnpBiosGetDeviceNodeCount:
94
95    /* Save registers */
96    push rbx
97    push rcx
98    push rdx
99
100    /* Call the real mode function */
101    mov bx, FNID_PnpBiosGetDeviceNodeCount
102    call CallRealMode
103
104    /* Restore param-regs */
105    pop rdx
106    pop rcx
107    pop rbx
108
109    xor eax, eax
110    mov ax, [BSS_PnpNodeSize]
111    mov [rcx], eax
112    mov ax, [BSS_PnpNodeCount]
113    mov [rdx], eax
114
115    mov eax, dword ptr [BSS_PnpResult]
116
117    ret
118
119
120
121/*
122 * U32 PnpBiosGetDeviceNode(U8 *NodeId<rcx>, U8 *NodeBuffer<rdx>);
123 *
124 * RETURNS:
125 */
126PUBLIC PnpBiosGetDeviceNode
127PnpBiosGetDeviceNode:
128
129    /* get current node number */
130    mov al, [rcx]
131    mov byte ptr [BSS_PnpNodeNumber], al
132
133    /* convert pointer to node buffer to segment/offset */
134    mov rax, rdx
135    shr eax, 4
136    mov word ptr [BSS_PnpBiosBufferSegment], ax
137    mov rax, rdx
138    and eax, HEX(0f)
139    mov word ptr [BSS_PnpBiosBufferOffset], ax
140
141    /* Save registers */
142    push rcx
143    push rbx
144
145    /* Call the real mode function */
146    mov bx, FNID_PnpBiosGetDeviceNode
147    call CallRealMode
148
149    /* Restore registers */
150    pop rbx
151    pop rcx
152
153    /* update node number */
154    mov al, byte ptr [BSS_PnpNodeNumber]
155    mov [rcx], al
156
157    mov eax, [BSS_PnpResult]
158
159    ret
160
161
162/*
163 * U32 PnpBiosGetDockStationInformation(U8 *DockingStationInfo<rcx>);
164 *
165 * RETURNS:
166 */
167PUBLIC PnpBiosGetDockStationInformation
168PnpBiosGetDockStationInformation:
169
170    /* Convert pointer to info structure to segment/offset */
171    mov rax, rcx
172    shr eax, 4
173    mov word ptr [BSS_PnpBiosBufferSegment], ax
174    mov rax, rcx
175    and eax, HEX(0f)
176    mov word ptr [BSS_PnpBiosBufferOffset], ax
177
178    /* Save registers */
179    push rcx
180    push rbx
181
182    /* Call the real mode function */
183    mov bx, FNID_PnpBiosGetDockStationInformation
184    call CallRealMode
185
186    /* Restore registers */
187    pop rbx
188    pop rcx
189
190    mov eax, dword ptr [BSS_PnpResult]
191
192    ret
193
194END
195/* EOF */
196