This repository has been archived by the owner on Mar 9, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
/
driver.asm
465 lines (432 loc) · 12 KB
/
driver.asm
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
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
;
; Driver - EBC Driver sample
; Copyright © 2016 Pete Batard <pete@akeo.ie>
;
; 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 3 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, see <http://www.gnu.org/licenses/>.
;
include 'ebc.inc'
include 'efi.inc'
include 'format.inc'
include 'utf8.inc'
DriverVersion = 0x11
struct EFI_CUSTOM_PROTOCOL
Hello VOID_PTR
repeat 16 i:0
MultiParam#i VOID_PTR
end repeat
MaxParams64 VOID_PTR
MaxParamsMixed VOID_PTR
ends
struct EFI_COMPONENT_NAME_PROTOCOL
GetDriverName VOID_PTR
GetControllerName VOID_PTR
SupportedLanguages VOID_PTR
ends
struct EFI_DRIVER_BINDING_PROTOCOL
Supported VOID_PTR
Start VOID_PTR
Stop VOID_PTR
Version UINT32
ImageHandle EFI_HANDLE
DriverBindingHandle EFI_HANDLE
ends
format peebc efiboot
entry DriverInstall
section '.text' code executable readable
; Return a 32 or 64-bit status code for the native arch
ReturnStatus:
CMP64gte R7, R6
JMPcs @0f
MOVId R4, EFI_32BIT_ERROR
MOVsnd R5, R4
CMPlte R5, R6
JMPcc @0f
OR32 R7, R4
@0:
RET
Print:
MOVREL R1, gST
MOV R1, @R1
MOVn R1, @R1(EFI_SYSTEM_TABLE.ConOut)
PUSHn @R0(0,+16)
PUSHn R1
CALLEX @R1(SIMPLE_TEXT_OUTPUT_INTERFACE.OutputString)
MOV R0, R0(+2,0)
RET
PrintHex64:
PUSH R4
MOV R3, R6
NOT R4, R6
MOVREL R7, HexStr64
PUSH R7
MOV R1, @R0(0,+32)
JMP PrintHexCommon
PrintHex32:
PUSH R4
MOVI R3, 8
NOT32 R4, R6
MOVREL R7, HexStr32
PUSH R7
MOV R1, @R0(0,+32)
AND R1, R4
PrintHexCommon:
PUSH R1
ADD R7, R6(4)
MOVREL R5, Digits
@0:
MOV R1, @R0
MOVI R2, 4
MUL R2, R3(-15)
NEG R2, R2
SHR R1, R2
ADD R1, R1
PUSH R5
ADD R5, R1
MOVw @R7, @R5
ADD R7, R6(2)
POP R5
SHR R4, R6(4)
AND @R0, R4
ADD R3, R6(1)
CMPIgte R3, 16
JMPcc @0b
POP R1
; HexStr32 or HexStr64 is on top of stack
CALL Print
POP R1
POP R4
RET
CallFailed:
PUSH R7
PUSH R1
CALL Print
POP R1
CALL PrintHex64
POP R7
JMP ReturnStatus
GetDriverName:
MOVn R1, @R0(+2,+16)
MOVREL @R1, DrvName
MOVI R7, EFI_SUCCESS
RET
BindingSupported:
MOVI R7, EFI_UNSUPPORTED
JMP ReturnStatus
Hello:
MOVREL R1, HelloMsg
PUSH R1
CALL Print
POP R1
MOVI R7, EFI_SUCCESS
RET
InvalidParam32:
MOVREL R4, PrintHex32
JMP InvalidParamCommon
InvalidParam64:
MOVREL R4, PrintHex64
InvalidParamCommon:
MOVREL R1, IPMsg1
PUSH R1
CALL Print
POP R1
CALL R4
POP R1
MOVREL R1, IPMsg2
PUSH R1
CALL Print
POP R1
CALL R4
POP R1
MOVI R7, EFI_INVALID_PARAMETER
JMP ReturnStatus
repeat 16 i:0
MultiParam#i:
MOVI R5, i
JMP MultiParamCommon
end repeat
MultiParamCommon:
XOR R6, R6
MOVI R4, 1
MOVREL R3, Values
MOV R2, R0(+0,+16)
@0:
PUSH R5
AND R5, R4
CMPeq R5, R6
POP R5
JMPcc @1f ; UINTN or UINT64?
MOVn R1, @R3
CMP32eq R1, @R2
JMPcs @3f
PUSH @R2
PUSH R1
JMP InvalidParam32
@3:
MOV R2, R2(+1,+0)
JMP @2f
@1:
MOVqq R1, @R3
CMP64eq R1, @R2
JMPcs @3f
PUSH @R2
PUSH R1
JMP InvalidParam64
@3:
MOV R2, R2(+0,+8)
@2:
ADD R3, R6(8)
SHL R4, R6(1)
CMPIeq R4, 0x10
JMPcc @0b
MOVI R7, EFI_SUCCESS
RET
MaxParams64:
MOVI R1, 0x0B0B0B0B0A0A0A0A
MOVI R2, 0x1010101010101010
MOV R4, R6
MOV R5, R0(+0,+16)
@0:
CMP64eq R1, @R5
JMPcs @1f
PUSH @R5
PUSH R1
JMP InvalidParam64
@1:
MOV R5, R5(+0,+8)
ADD64 R1, R2
ADD R4, R6(1)
CMPlte R4, R6(15)
JMPcs @0b
MOVI R7, EFI_SUCCESS
RET
MaxParamsMixed:
MOVI R1, 0x0A0A0A0A
MOVI R2, 0x1B1B1B1B1A1A1A1A
MOVI R3, 0x2020202020202020
MOV R4, R6
MOV R5, R0(+0,+16)
@0:
CMP32eq R1, @R5
JMPcs @1f
PUSH @R5
PUSH R1
JMP InvalidParam32
@1:
MOV R5, R5(+1,+0)
ADD32 R1, R3
CMP64eq R2, @R5
JMPcs @1f
PUSH @R5
PUSH R2
JMP InvalidParam64
@1:
MOV R5, R5(+0,+8)
ADD64 R2, R3
ADD R4, R6(1)
CMPlte R4, R6(7)
JMPcs @0b
MOVI R7, EFI_SUCCESS
RET
DriverInstall:
XOR R6, R6
MOVREL R1, ImageHandle
MOVn @R1, @R0(EFI_MAIN_PARAMETERS.ImageHandle)
MOVREL R1, gST
MOVn @R1, @R0(EFI_MAIN_PARAMETERS.SystemTable)
; Check for an already running driver
MOVREL R1, CustomProtocolInterface
PUSHn R1
PUSHn R6
MOVREL R1, CustomProtocolGuid
PUSHn R1
MOVREL R1, gST
MOV R1, @R1
MOV R1, @R1(EFI_SYSTEM_TABLE.BootServices)
CALLEX @R1(EFI_BOOT_SERVICES.LocateProtocol)
MOV R0, R0(+3,+0)
CMPI32eq R7, EFI_SUCCESS
JMPcc @0f
MOVREL R1, AIMsg
PUSHn R1
CALL Print
MOV R0, R0(+1,+0)
MOVI R7, EFI_LOAD_ERROR
RET
@0:
; The only valid status we expect is NOT FOUND here
MOVIq R1, EFI_NOT_FOUND
CMP64eq R1, R7
JMPcs @0f
MOVId R1, EFI_NOT_FOUND or EFI_32BIT_ERROR
CMP32eq R1, R7
JMPcs @0f
MOVREL R1, USMsg
PUSHn R1
CALL Print
MOV R0, R0(+1,+0)
RET
@0:
; Fill in the Custom Protocol interface
MOVREL R1, CustomProtocolInterface
EXPORT Hello ; Generate a native -> EBC thunk (in @R7)
MOVn @R1(EFI_CUSTOM_PROTOCOL.Hello), @R7
repeat 16 i:0
EXPORT MultiParam#i
MOVn @R1(EFI_CUSTOM_PROTOCOL.MultiParam#i), @R7
end repeat
EXPORT MaxParamsMixed
MOVn @R1(EFI_CUSTOM_PROTOCOL.MaxParamsMixed), @R7
EXPORT MaxParams64
MOVn @R1(EFI_CUSTOM_PROTOCOL.MaxParams64), @R7
; Fill in the Component Name interfaces
MOVREL R1, ComponentName
EXPORT GetDriverName
MOVn @R1(EFI_COMPONENT_NAME_PROTOCOL.GetDriverName), @R7
MOVn @R1(EFI_COMPONENT_NAME_PROTOCOL.GetControllerName), R6
MOVREL R3, Eng
MOVn @R1(EFI_COMPONENT_NAME_PROTOCOL.SupportedLanguages), R3
MOVREL R1, ComponentName2
MOVn @R1(EFI_COMPONENT_NAME_PROTOCOL.GetDriverName), @R7
MOVn @R1(EFI_COMPONENT_NAME_PROTOCOL.GetControllerName), R6
MOVREL R3, En
MOVn @R1(EFI_COMPONENT_NAME_PROTOCOL.SupportedLanguages), R3
; Fill in DriverBinding
MOVREL R1, DriverBinding
EXPORT BindingSupported
MOVn @R1(EFI_DRIVER_BINDING_PROTOCOL.Supported), @R7
MOVn @R1(EFI_DRIVER_BINDING_PROTOCOL.Start), R6
MOVn @R1(EFI_DRIVER_BINDING_PROTOCOL.Stop), R6
MOVI R2, DriverVersion
MOVd @R1(EFI_DRIVER_BINDING_PROTOCOL.Version), R2
MOVREL R2, ImageHandle
MOVn @R1(EFI_DRIVER_BINDING_PROTOCOL.ImageHandle), @R2
MOVn @R1(EFI_DRIVER_BINDING_PROTOCOL.DriverBindingHandle), @R2
; Install the interface
MOVREL R1, CustomProtocolInterface
PUSHn R1
PUSHn R6 ; EFI_NATIVE_INTERFACE = 0
MOVREL R1, CustomProtocolGuid
PUSHn R1
MOVREL R1, CustomProtocolHandle
PUSHn R1
MOVREL R1, gST
MOV R1, @R1
MOV R1, @R1(EFI_SYSTEM_TABLE.BootServices)
CALLEX @R1(EFI_BOOT_SERVICES.InstallProtocolInterface)
MOV R0, R0(+4,+0)
MOVREL R1, IPIMsg
CMPI32eq R7, EFI_SUCCESS
JMPcc CallFailed
; Grab a handle to this image, so that we can add an unload to our driver
MOVI R1, EFI_OPEN_PROTOCOL_GET_PROTOCOL
PUSHn R1
PUSHn R6
MOVREL R2, ImageHandle
PUSHn @R2
MOVREL R1, LoadedImage
PUSHn R1
MOVREL R1, gEfiLoadedImageProtocolGuid
PUSHn R1
PUSHn @R2
MOVREL R1, gST
MOV R1, @R1
MOV R1, @R1(EFI_SYSTEM_TABLE.BootServices)
CALLEX @R1(EFI_BOOT_SERVICES.OpenProtocol)
MOV R0, R0(+6,+0)
MOVREL R1, OPMsg
CMPI32eq R7, EFI_SUCCESS
JMPcc CallFailed
; Install driver
PUSHn R6
MOVREL R2, ComponentName
PUSHn R2
MOVREL R1, gEfiComponentName2ProtocolGuid
PUSHn R1
PUSHn R2
MOVREL R1, gEfiComponentNameProtocolGuid
PUSHn R1
MOVREL R2, DriverBinding
PUSHn R2
MOVREL R1, gEfiDriverBindingProtocolGuid
PUSHn R1
MOV R2, R2(EFI_DRIVER_BINDING_PROTOCOL.DriverBindingHandle)
PUSHn R2
MOVREL R1, gST
MOV R1, @R1
MOV R1, @R1(EFI_SYSTEM_TABLE.BootServices)
CALLEX @R1(EFI_BOOT_SERVICES.InstallMultipleProtocolInterfaces)
MOV R0, R0(+8,+0)
MOVREL R1, IMPIMsg
CMPI32eq R7, EFI_SUCCESS
JMPcc CallFailed
MOVI R7, EFI_SUCCESS
RET
section '.exports' data readable writeable
; Any function that may be called from native must be declared with the EXPORT keyword
; in a data section, and provide a C-like call signature in parenthesis.
; Then, during application init, EXPORT should be invoked, with the same function name
; (but without the signature) so that native -> EBC thunks are created through BREAK 5.
EXPORT Hello(VOID)
repeat 16 i:0
; Custom export declaration for the MultiParam## calls
_MultiParam#i:
dd MultiParam#i - $ - 4
dd EBC_CALL_SIGNATURE or i
end repeat
EXPORT MaxParams64(UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64, UINT64)
EXPORT MaxParamsMixed(UINTN, UINT64, UINTN, UINT64, UINTN, UINT64, UINTN, UINT64, UINTN, UINT64, UINTN, UINT64, UINTN, UINT64, UINTN, UINT64)
EXPORT BindingSupported(VOID*, VOID*, VOID*)
EXPORT GetDriverName(VOID*, CHAR8*, CHAR16*)
section '.data' data readable writeable
gST: dq ?
LoadedImage:
dq ?
CustomProtocolHandle:
dq ?
ImageHandle:
dq ?
Values:
dq 0x1B1B1B1B1A1A1A1A, 0x2B2B2B2B2A2A2A2A, 0x3B3B3B3B3A3A3A3A, 0x4B4B4B4B4A4A4A4A
CustomProtocolInterface:
rb EFI_CUSTOM_PROTOCOL.__size
ComponentName:
rb EFI_COMPONENT_NAME_PROTOCOL.__size
ComponentName2:
rb EFI_COMPONENT_NAME_PROTOCOL.__size
DriverBinding:
rb EFI_DRIVER_BINDING_PROTOCOL.__size
gEfiLoadedImageProtocolGuid:
EFI_GUID { 0x5b1b31a1, 0x9562, 0x11d2, { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } }
gEfiDriverBindingProtocolGuid:
EFI_GUID { 0x18a031ab, 0xb443, 0x4d1a, { 0xa5, 0xc0, 0x0c, 0x09, 0x26, 0x1e, 0x9f, 0x71 } }
gEfiComponentNameProtocolGuid:
EFI_GUID { 0x107a772c, 0xd5e1, 0x11d4, { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
gEfiComponentName2ProtocolGuid:
EFI_GUID { 0x6a7a5cff, 0xe8d9, 0x4f70, { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14 } }
CustomProtocolGuid:
EFI_GUID { 0x230aa93e, 0x3d8a, 0x4bbd, { 0x8d, 0x48, 0x77, 0xd3, 0xed, 0x9c, 0xa7, 0x9b } }
Digits: du "0123456789ABCDEF"
HexStr32: du "0x12345678", 0x0D, 0x0A, 0x00
HexStr64: du "0x1234567812345678", 0x0D, 0x0A, 0x00
AIMsg: du "This driver has already been installed", 0x0D, 0x0A, 0x00
USMsg: du "Unexpected initial status", 0x0D, 0x0A, 0x00
OPMsg: du "Error OpenProtocol: ", 0x00
IPIMsg: du "Error InstallProtocolInterface: ", 0x00
IMPIMsg: du "Error InstallMultipleProtocolInterfaces: ", 0x00
HelloMsg: du "Hello from EBC driver", 0x0D, 0x0A, 0x00
DrvName: du "EBC Driver v1.1", 0x00
En: db "en", 0x00
Eng: db "eng", 0x00
IPMsg1: du "Expected: ", 0x00
IPMsg2: du "Received: ", 0x00