summaryrefslogtreecommitdiffstats
path: root/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-BiosInt15hE820.asm
blob: 6b3c66e4b524832b6f799fcf613664295108db5f (plain)
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