1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
; $Id: bs3-mode-BiosInt15hE820.asm $
;; @file
; BS3Kit - Bs3BiosInt15hE820
;
;
; Copyright (C) 2021-2023 Oracle and/or its affiliates.
;
; This file is part of VirtualBox base platform packages, as
; available from https://www.virtualbox.org.
;
; 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, in version 3 of the
; License.
;
; 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, see <https://www.gnu.org/licenses>.
;
; The contents of this file may alternatively be used under the terms
; of the Common Development and Distribution License Version 1.0
; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
; in the VirtualBox distribution, in which case the provisions of the
; CDDL are applicable instead of those of the GPL.
;
; You may elect to license modified versions of this file under the
; terms and conditions of either the GPL or the CDDL or both.
;
; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
;
;*********************************************************************************************************************************
;* Header Files *
;*********************************************************************************************************************************
%include "bs3kit-template-header.mac"
;*********************************************************************************************************************************
;* Defined Constants And Macros *
;*********************************************************************************************************************************
;; Signature: 'SMAP'
%define INT15_E820_SIGNATURE 0534d4150h
;*********************************************************************************************************************************
;* External symbols *
;*********************************************************************************************************************************
TMPL_BEGIN_TEXT
extern TMPL_NM(Bs3SwitchToRM)
BS3_BEGIN_TEXT16
extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm)
;;
; Performs a int 15h function 0xe820 call.
;
; @cproto BS3_MODE_PROTO_STUB(bool, Bs3BiosInt15hE820,(INT15E820ENTRY BS3_FAR *pEntry, uint32_t BS3_FAR *pcbEntry,
; uint32_t BS3_FAR *puContinuationValue));
;
; @returns Success indicator.
; @param pEntry The return buffer.
; @param pcbEntry Input: The size of the buffer (min 20 bytes);
; Output: The size of the returned data.
; @param puContinuationValue Where to get and return the continuation value (EBX)
; Set to zero the for the first call. Returned as zero
; after the last entry.
;
; @remarks ASSUMES we're in ring-0 when not in some kind of real mode.
; @remarks ASSUMES we're on a 16-bit suitable stack.
;
; @uses rax
;
TMPL_BEGIN_TEXT
BS3_PROC_BEGIN_MODE Bs3BiosInt15hE820, BS3_PBC_HYBRID
push xBP
mov xBP, xSP
sPUSHF
cli
push sBX
push sCX
push sDX
push sSI
push sDI
%ifdef TMPL_16BIT
push ds
push es
%endif
; Load/Save parameters.
%define a_pEntry [xBP + xCB + cbCurRetAddr + sCB*0]
%define a_pcbEntry [xBP + xCB + cbCurRetAddr + sCB*1]
%define a_puContinuationValue [xBP + xCB + cbCurRetAddr + sCB*2]
%ifdef TMPL_64BIT
mov a_pEntry, rcx ; save pEntry
mov a_pcbEntry, rdx ; save pcbEntry
mov a_puContinuationValue, r8 ; save a_puContinuationValue
mov ebx, [r8] ; uContinuationValue for int15
mov ecx, [rdx] ; Buffer size for int15.
%elifdef TMPL_16BIT
les bx, a_pcbEntry
mov ecx, [es:bx] ; Buffer size for int15.
les bx, a_puContinuationValue
mov ebx, [es:bx] ; Buffer size for int15.
%else
mov ecx, a_pcbEntry
mov ecx, [ecx] ; Buffer size for int15.
mov ebx, a_puContinuationValue
mov ebx, [ebx] ; uContinuationValue for int15
%endif
;
; Check that the cbEntry isn't too big or too small before doing
; the stack allocation. (Our BIOS doesn't check if too small.)
;
cmp ecx, 100h
jae .failed
cmp cl, 14h
jb .failed
%if TMPL_MODE != BS3_MODE_RM
sub xSP, xCX ; allocate a temporary buffer on the stack.
and xSP, ~0fh
%endif
;
; Switch to real mode, first we just ot the 16-bit text segment.
; This preserve all 32-bit register values.
;
%if TMPL_MODE != BS3_MODE_RM
%ifndef TMPL_16BIT
jmp .to_text16
BS3_BEGIN_TEXT16
.to_text16:
BS3_SET_BITS TMPL_BITS
%endif
call TMPL_NM(Bs3SwitchToRM)
BS3_SET_BITS 16
%endif
;
; Make the call.
;
%if TMPL_MODE == BS3_MODE_RM
les di, a_pEntry
%else
push ss ; es:di -> ss:sp
pop es
mov di, sp
%endif
mov edx, INT15_E820_SIGNATURE
mov eax, 0e820h ; BIOS function number
int 15h
;
; Switch back.
;
%if TMPL_MODE != BS3_MODE_RM
call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_Safe_rm)
BS3_SET_BITS TMPL_BITS
%ifndef TMPL_16BIT
jmp .from_text16
TMPL_BEGIN_TEXT
.from_text16:
%endif
%endif
;
; Check that we didn't failed.
;
jc .failed
cmp eax, INT15_E820_SIGNATURE
jc .failed
cmp ecx, 20
jb .failed
;
; Save the continuation value.
;
%ifdef TMPL_16BIT
mov eax, ebx
lds bx, a_puContinuationValue
mov [bx], eax
%else
mov xAX, a_puContinuationValue
mov [xAX], ebx
%endif
;
; Save the entry size.
;
%ifdef TMPL_16BIT
lds bx, a_pcbEntry
%else
mov xBX, a_pcbEntry
%endif
mov [xBX], ecx
%if TMPL_MODE != BS3_MODE_RM
;
; Copy the returned stuff into the caller's buffer.
;
mov xSI, xSP
%ifdef TMPL_16BIT
push ss
pop es
lds di, a_pEntry
%else
mov xDI, a_pEntry
%endif
cld
rep movsb
%endif
;
; Return success
;
mov al, 1
.return:
%ifdef TMPL_16BIT
lea xSP, [xBP - sCB * 6 - xCB*2]
pop es
pop ds
%else
lea xSP, [xBP - sCB * 6]
%endif
pop sDI
pop sSI
pop sDX
pop sCX
pop sBX
sPOPF
leave
BS3_HYBRID_RET
;
; Failed.
;
.failed:
xor al, al
jmp .return
BS3_PROC_END_MODE Bs3BiosInt15hE820
|