VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/os2/SUPDrvA-os2.asm

Last change on this file was 69249, checked in by vboxsync, 7 years ago

Support: scm updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.3 KB
Line 
1; $Id: SUPDrvA-os2.asm 69249 2017-10-24 19:05:34Z vboxsync $
2;; @file
3; VBoxDrv - OS/2 assembly file, the first file in the link.
4;
5
6;
7; Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
8;
9; Permission is hereby granted, free of charge, to any person
10; obtaining a copy of this software and associated documentation
11; files (the "Software"), to deal in the Software without
12; restriction, including without limitation the rights to use,
13; copy, modify, merge, publish, distribute, sublicense, and/or sell
14; copies of the Software, and to permit persons to whom the
15; Software is furnished to do so, subject to the following
16; conditions:
17;
18; The above copyright notice and this permission notice shall be
19; included in all copies or substantial portions of the Software.
20;
21; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28; OTHER DEALINGS IN THE SOFTWARE.
29;
30
31
32;*******************************************************************************
33;* Header Files *
34;*******************************************************************************
35%define RT_INCL_16BIT_SEGMENTS
36%include "iprt/asmdefs.mac"
37
38
39;*******************************************************************************
40;* Structures and Typedefs *
41;*******************************************************************************
42;;
43; Request packet header.
44struc PKTHDR
45 .cb resb 1
46 .unit resb 1
47 .cmd resb 1
48 .status resw 1
49 .res1 resd 1
50 .link resd 1
51endstruc
52
53
54;;
55; Init request packet - input.
56struc PKTINITIN
57 .cb resb 1
58 .unit resb 1
59 .cmd resb 1
60 .status resw 1
61 .res1 resd 1
62 .link resd 1
63
64 .data_1 resb 1
65 .fpfnDevHlp resd 1
66 .fpszArgs resd 1
67 .data_2 resb 1
68endstruc
69
70;;
71; Init request packet - output.
72struc PKTINITOUT
73 .cb resb 1
74 .unit resb 1
75 .cmd resb 1
76 .status resw 1
77 .res1 resd 1
78 .link resd 1
79
80 .cUnits resb 1 ; block devs only.
81 .cbCode16 resw 1
82 .cbData16 resw 1
83 .fpaBPBs resd 1 ; block devs only.
84 .data_2 resb 1
85endstruc
86
87;;
88; Open request packet.
89struc PKTOPEN
90 .cb resb 1
91 .unit resb 1
92 .cmd resb 1
93 .status resw 1
94 .res1 resd 1
95 .link resd 1
96 .sfn resw 1
97endstruc
98
99;;
100; Close request packet.
101struc PKTCLOSE
102 .cb resb 1
103 .unit resb 1
104 .cmd resb 1
105 .status resw 1
106 .res1 resd 1
107 .link resd 1
108 .sfn resw 1
109endstruc
110
111;;
112; IOCtl request packet.
113struc PKTIOCTL
114 .cb resb 1
115 .unit resb 1
116 .cmd resb 1
117 .status resw 1
118 .res1 resd 1
119 .link resd 1
120
121 .cat resb 1
122 .fun resb 1
123 .pParm resd 1
124 .pData resd 1
125 .sfn resw 1
126 .cbParm resw 1
127 .cbData resw 1
128endstruc
129
130;;
131; Read/Write request packet
132struc PKTRW
133 .cb resb 1
134 .unit resb 1
135 .cmd resb 1
136 .status resw 1
137 .res1 resd 1
138 .link resd 1
139
140 .media resb 1
141 .PhysTrans resd 1
142 .cbTrans resw 1
143 .start resd 1
144 .sfn resw 1
145endstruc
146
147
148
149;;
150; The two device headers.
151segment DATA16
152
153; Some devhdr.inc stuff.
154%define DEVLEV_3 0180h
155%define DEV_30 0800h
156%define DEV_CHAR_DEV 8000h
157%define DEV_16MB 0002h
158%define DEV_IOCTL2 0001h
159
160; Some dhcalls.h stuff.
161%define DevHlp_VirtToLin 05bh
162%define DevHlp_SAVE_MESSAGE 03dh
163%define DevHlp_PhysToVirt 015h
164
165; Fast IOCtl category, also defined in SUPDrvIOC.h
166%define SUP_CTL_CATEGORY_FAST 0c1h
167
168
169;*******************************************************************************
170;* External Symbols *
171;*******************************************************************************
172extern KernThunkStackTo32
173extern KernThunkStackTo16
174extern DOS16OPEN
175extern DOS16CLOSE
176extern DOS16WRITE
177extern NAME(VBoxDrvInit)
178extern NAME(VBoxDrvOpen)
179extern NAME(VBoxDrvClose)
180extern NAME(VBoxDrvIOCtl)
181extern NAME(VBoxDrvIOCtlFast)
182
183
184;;
185; Device headers. The first one is the one we'll be opening and the
186; latter is only used for 32-bit initialization.
187GLOBALNAME g_VBoxDrvHdr1
188 dw NAME(g_VBoxDrvHdr2) wrt DATA16 ; NextHeader.off
189 dw DATA16 ; NextHeader.sel
190 dw DEVLEV_3 | DEV_30 | DEV_CHAR_DEV; SDevAtt
191 dw NAME(VBoxDrvEP) wrt CODE16 ; StrategyEP
192 dw 0 ; InterruptEP
193 db 'vboxdrv$' ; DevName
194 dw 0 ; SDevProtCS
195 dw 0 ; SDevProtDS
196 dw 0 ; SDevRealCS
197 dw 0 ; SDevRealDS
198 dd DEV_16MB | DEV_IOCTL2 ; SDevCaps
199
200align 4
201GLOBALNAME g_VBoxDrvHdr2
202 dd 0ffffffffh ; NextHeader (NIL)
203 dw DEVLEV_3 | DEV_30 | DEV_CHAR_DEV; SDevAtt
204 dw NAME(VBoxDrvInitEP) wrt CODE16 ; StrategyEP
205 dw 0 ; InterruptEP
206 db 'vboxdr1$' ; DevName
207 dw 0 ; SDevProtCS
208 dw 0 ; SDevProtDS
209 dw 0 ; SDevRealCS
210 dw 0 ; SDevRealDS
211 dd DEV_16MB | DEV_IOCTL2 ; SDevCaps
212
213
214;; Tristate 32-bit initialization indicator [0 = need init, -1 = init failed, 1 init succeeded].
215; Check in the open path of the primary driver. The secondary driver will
216; open the primary one during it's init and thereby trigger the 32-bit init.
217GLOBALNAME g_fInitialized
218 db 0
219
220align 4
221;; Pointer to the device helper service routine
222; This is set during the initialization of the 2nd device driver.
223GLOBALNAME g_fpfnDevHlp
224 dd 0
225
226
227;; Where we write to the log.
228GLOBALNAME g_offLogHead
229 dw 0
230;; Where we read from the log.
231GLOBALNAME g_offLogTail
232 dw 0
233;; The size of the log. (power of two!)
234%define LOG_SIZE 16384
235GLOBALNAME g_cchLogMax
236 dw LOG_SIZE
237;; The log buffer.
238GLOBALNAME g_szLog
239 times LOG_SIZE db 0
240
241
242;
243; The init data.
244;
245segment DATA16_INIT
246GLOBALNAME g_InitDataStart
247
248;; Far pointer to the device argument.
249g_fpszArgs:
250 dd 0
251
252%if 0
253;; Message table for the Save_Message device helper.
254GLOBALNAME g_MsgTab
255 dw 1178 ; MsgId - 'MSG_REPLACEMENT_STRING'.
256 dw 1 ; cMsgStrings
257 dw NAME(g_szInitText) ; MsgStrings[0]
258 dw seg NAME(g_szInitText)
259%else
260;; Far pointer to DOS16WRITE (corrected set before called).
261; Just a temporary hack to work around a wlink issue.
262GLOBALNAME g_fpfnDos16Write
263 dw DOS16WRITE
264 dw seg DOS16WRITE
265%endif
266
267;; Size of the text currently in the g_szInitText buffer.
268GLOBALNAME g_cchInitText
269 dw 0
270;; The max size of text that can fit into the g_szInitText buffer.
271GLOBALNAME g_cchInitTextMax
272 dw 512
273;; The init text buffer.
274GLOBALNAME g_szInitText
275 times 512 db 0
276
277;
278; The 16-bit code segment.
279;
280segment CODE16
281
282
283;;
284; The strategy entry point (vboxdrv$).
285;
286; ss:bx -> request packet
287; ds:si -> device header
288;
289; Can clobber any registers it likes except SP.
290;
291BEGINPROC VBoxDrvEP
292 push ebp
293 mov ebp, esp
294 push es ; bp - 2
295 push bx ; bp - 4
296 and sp, 0fffch
297
298 ;
299 ; Check for the most frequent first.
300 ;
301 cmp byte [es:bx + PKTHDR.cmd], 10h ; Generic IOCtl
302 jne near VBoxDrvEP_NotGenIOCtl
303
304
305 ;
306 ; Generic I/O Control Request.
307 ;
308VBoxDrvEP_GenIOCtl:
309
310 ; Fast IOCtl?
311 cmp byte [es:bx + PKTIOCTL.cat], SUP_CTL_CATEGORY_FAST
312 jne VBoxDrvEP_GenIOCtl_Other
313
314 ;
315 ; Fast IOCtl.
316 ; DECLASM(int) VBoxDrvIOCtlFast(uint16_t sfn, uint8_t iFunction)
317 ;
318VBoxDrvEP_GenIOCtl_Fast:
319 ; function.
320 movzx edx, byte [es:bx + PKTIOCTL.fun]
321 push edx ; 04h
322
323 ; system file number.
324 movzx eax, word [es:bx + PKTIOCTL.sfn]
325 push eax ; 00h
326
327 ; go to the 32-bit code
328 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Fast_32) wrt FLAT
329 db 066h
330 db 0eah
331 dd NAME(VBoxDrvEP_GenIOCtl_Fast_32) ;wrt FLAT
332 dw TEXT32 wrt FLAT
333segment TEXT32
334GLOBALNAME VBoxDrvEP_GenIOCtl_Fast_32
335
336 ; switch stack to 32-bit.
337 mov ax, DATA32 wrt FLAT
338 mov ds, ax
339 mov es, ax
340 call KernThunkStackTo32
341
342 ; call the C code (don't cleanup the stack).
343 call NAME(VBoxDrvIOCtlFast)
344
345 ; switch back the stack.
346 push eax
347 call KernThunkStackTo16
348 pop eax
349
350 ; jump back to the 16-bit code.
351 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Fast_16) wrt CODE16
352 db 066h
353 db 0eah
354 dw NAME(VBoxDrvEP_GenIOCtl_Fast_16) wrt CODE16
355 dw CODE16
356segment CODE16
357GLOBALNAME VBoxDrvEP_GenIOCtl_Fast_16
358 les bx, [bp - 4] ; Reload the packet pointer.
359 or eax, eax
360 jnz near VBoxDrvEP_GeneralFailure
361
362 ; setup output stuff.
363 xor eax, eax
364 mov [es:bx + PKTIOCTL.cbParm], eax ; update cbParm and cbData.
365 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
366
367 mov sp, bp
368 pop ebp
369 retf
370
371 ;
372 ; Other IOCtl (slow)
373 ;
374VBoxDrvEP_GenIOCtl_Other:
375 mov eax, [es:bx + PKTIOCTL.cbParm] ; Load cbParm and cbData
376 push eax ; 1eh - in/out data size.
377 ; 1ch - in/out parameter size.
378 push edx ; 18h - pointer to data size (filled in later).
379 push ecx ; 14h - pointer to param size (filled in later).
380
381 ; pData (convert to flat 32-bit)
382 mov ax, word [es:bx + PKTIOCTL.pData + 2] ; selector
383 cmp ax, 3 ; <= 3 -> nil selector...
384 jbe .no_data
385 movzx esi, word [es:bx + PKTIOCTL.pData] ; offset
386 mov dl, DevHlp_VirtToLin
387 call far [NAME(g_fpfnDevHlp)]
388 jc near VBoxDrvEP_GeneralFailure
389 jmp .finish_data
390.no_data:
391 xor eax, eax
392.finish_data:
393 push eax ; 10h
394
395 ; pParm (convert to flat 32-bit)
396 mov ax, word [es:bx + PKTIOCTL.pParm + 2] ; selector
397 cmp ax, 3 ; <= 3 -> nil selector...
398 jbe .no_parm
399 movzx esi, word [es:bx + PKTIOCTL.pParm] ; offset
400 mov dl, DevHlp_VirtToLin
401 call far [NAME(g_fpfnDevHlp)]
402 jc near VBoxDrvEP_GeneralFailure
403 jmp .finish_parm
404.no_parm:
405 xor eax, eax
406.finish_parm:
407 push eax ; 0ch
408
409 ; function.
410 movzx edx, byte [es:bx + PKTIOCTL.fun]
411 push edx ; 08h
412
413 ; category.
414 movzx ecx, byte [es:bx + PKTIOCTL.cat]
415 push ecx ; 04h
416
417 ; system file number.
418 movzx eax, word [es:bx + PKTIOCTL.sfn]
419 push eax ; 00h
420
421 ; go to the 32-bit code
422 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Other_32) wrt FLAT
423 db 066h
424 db 0eah
425 dd NAME(VBoxDrvEP_GenIOCtl_Other_32) ;wrt FLAT
426 dw TEXT32 wrt FLAT
427segment TEXT32
428GLOBALNAME VBoxDrvEP_GenIOCtl_Other_32
429
430 ; switch stack to 32-bit.
431 mov ax, DATA32 wrt FLAT
432 mov ds, ax
433 mov es, ax
434 call KernThunkStackTo32
435
436 ; update in/out parameter pointers
437 lea eax, [esp + 1ch]
438 mov [esp + 14h], eax
439 lea edx, [esp + 1eh]
440 mov [esp + 18h], edx
441
442 ; call the C code (don't cleanup the stack).
443 call NAME(VBoxDrvIOCtl)
444
445 ; switch back the stack.
446 push eax
447 call KernThunkStackTo16
448 pop eax
449
450 ; jump back to the 16-bit code.
451 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Other_16) wrt CODE16
452 db 066h
453 db 0eah
454 dw NAME(VBoxDrvEP_GenIOCtl_Other_16) wrt CODE16
455 dw CODE16
456segment CODE16
457GLOBALNAME VBoxDrvEP_GenIOCtl_Other_16
458 les bx, [bp - 4] ; Reload the packet pointer.
459 or eax, eax
460 jnz near VBoxDrvEP_GeneralFailure
461
462 ; setup output stuff.
463 mov edx, esp
464 mov eax, [ss:edx + 1ch] ; output sizes.
465 mov [es:bx + PKTIOCTL.cbParm], eax ; update cbParm and cbData.
466 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
467
468 mov sp, bp
469 pop ebp
470 retf
471
472
473 ;
474 ; Less Performance Critical Requests.
475 ;
476VBoxDrvEP_NotGenIOCtl:
477 cmp byte [es:bx + PKTHDR.cmd], 0dh ; Open
478 je VBoxDrvEP_Open
479 cmp byte [es:bx + PKTHDR.cmd], 0eh ; Close
480 je VBoxDrvEP_Close
481 cmp byte [es:bx + PKTHDR.cmd], 00h ; Init
482 je VBoxDrvEP_Init
483 cmp byte [es:bx + PKTHDR.cmd], 04h ; Read
484 je near VBoxDrvEP_Read
485 jmp near VBoxDrvEP_NotSupported
486
487
488 ;
489 ; Open Request. w/ ring-0 init.
490 ;
491VBoxDrvEP_Open:
492 cmp byte [NAME(g_fInitialized)], 1
493 jne VBoxDrvEP_OpenOther
494
495 ; First argument, the system file number.
496 movzx eax, word [es:bx + PKTOPEN.sfn]
497 push eax
498
499 ; go to the 32-bit code
500 ;jmp far dword NAME(VBoxDrvEP_Open_32) wrt FLAT
501 db 066h
502 db 0eah
503 dd NAME(VBoxDrvEP_Open_32) ;wrt FLAT
504 dw TEXT32 wrt FLAT
505segment TEXT32
506GLOBALNAME VBoxDrvEP_Open_32
507
508 ; switch stack to 32-bit.
509 mov ax, DATA32 wrt FLAT
510 mov ds, ax
511 mov es, ax
512 call KernThunkStackTo32
513
514 ; call the C code.
515 call NAME(VBoxDrvOpen)
516
517 ; switch back the stack.
518 push eax
519 call KernThunkStackTo16
520 pop eax
521
522 ; jump back to the 16-bit code.
523 ;jmp far dword NAME(VBoxDrvEP_Open_32) wrt CODE16
524 db 066h
525 db 0eah
526 dw NAME(VBoxDrvEP_Open_16) wrt CODE16
527 dw CODE16
528segment CODE16
529GLOBALNAME VBoxDrvEP_Open_16
530 les bx, [bp - 4] ; Reload the packet pointer.
531 or eax, eax
532 jnz near VBoxDrvEP_GeneralFailure
533 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
534 jmp near VBoxDrvEP_Done
535
536 ; Initializing or failed init?
537VBoxDrvEP_OpenOther:
538 cmp byte [NAME(g_fInitialized)], 0
539 jne VBoxDrvEP_OpenFailed
540
541 mov byte [NAME(g_fInitialized)], -1
542 call NAME(VBoxDrvRing0Init)
543 cmp byte [NAME(g_fInitialized)], 1
544 je VBoxDrvEP_Open
545
546VBoxDrvEP_OpenFailed:
547 mov word [es:bx + PKTHDR.status], 0810fh ; error, done, init failed.
548 jmp near VBoxDrvEP_Done
549
550
551 ;
552 ; Close Request.
553 ;
554VBoxDrvEP_Close:
555 ; First argument, the system file number.
556 movzx eax, word [es:bx + PKTOPEN.sfn]
557 push eax
558
559 ; go to the 32-bit code
560 ;jmp far dword NAME(VBoxDrvEP_Close_32) wrt FLAT
561 db 066h
562 db 0eah
563 dd NAME(VBoxDrvEP_Close_32) ;wrt FLAT
564 dw TEXT32 wrt FLAT
565segment TEXT32
566GLOBALNAME VBoxDrvEP_Close_32
567
568 ; switch stack to 32-bit.
569 mov ax, DATA32 wrt FLAT
570 mov ds, ax
571 mov es, ax
572 call KernThunkStackTo32
573
574 ; call the C code.
575 call NAME(VBoxDrvClose)
576
577 ; switch back the stack.
578 push eax
579 call KernThunkStackTo16
580 pop eax
581
582 ; jump back to the 16-bit code.
583 ;jmp far dword NAME(VBoxDrvEP_Close_32) wrt CODE16
584 db 066h
585 db 0eah
586 dw NAME(VBoxDrvEP_Close_16) wrt CODE16
587 dw CODE16
588segment CODE16
589GLOBALNAME VBoxDrvEP_Close_16
590 les bx, [bp - 4] ; Reload the packet pointer.
591 or eax, eax
592 jnz near VBoxDrvEP_GeneralFailure
593 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
594 jmp near VBoxDrvEP_Done
595
596
597 ;
598 ; Init Request.
599 ; The other driver header will do this.
600 ;
601VBoxDrvEP_Init:
602 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
603 mov byte [es:bx + PKTINITOUT.cUnits], 0
604 mov word [es:bx + PKTINITOUT.cbCode16], NAME(g_InitCodeStart) wrt CODE16
605 mov word [es:bx + PKTINITOUT.cbData16], NAME(g_InitDataStart) wrt DATA16
606 mov dword [es:bx + PKTINITOUT.fpaBPBs], 0
607 jmp near VBoxDrvEP_Done
608
609
610 ;
611 ; Read Request.
612 ; Return log data.
613 ;
614VBoxDrvEP_Read:
615 ; Any log data available?
616 xor dx, dx
617 mov ax, [NAME(g_offLogTail)]
618 cmp ax, [NAME(g_offLogHead)]
619 jz near .log_done
620
621 ; create a temporary mapping of the physical buffer. Docs claims it trashes nearly everything...
622 push ebp
623 mov cx, [es:bx + PKTRW.cbTrans]
624 push cx
625 mov ax, [es:bx + PKTRW.PhysTrans + 2]
626 mov bx, [es:bx + PKTRW.PhysTrans]
627 mov dh, 1
628 mov dl, DevHlp_PhysToVirt
629 call far [NAME(g_fpfnDevHlp)]
630 pop bx ; bx = cbTrans
631 pop ebp
632 jc near .log_phystovirt_failed
633 ; es:di -> the output buffer.
634
635 ; setup the copy operation.
636 mov ax, [NAME(g_offLogTail)]
637 xor dx, dx ; dx tracks the number of bytes copied.
638.log_loop:
639 mov cx, [NAME(g_offLogHead)]
640 cmp ax, cx
641 je .log_done
642 jb .log_loop_before
643 mov cx, LOG_SIZE
644.log_loop_before: ; cx = end offset
645 sub cx, ax ; cx = sequential bytes to copy.
646 cmp cx, bx
647 jbe .log_loop_min
648 mov cx, bx ; output buffer is smaller than available data.
649.log_loop_min:
650 mov si, NAME(g_szLog)
651 add si, ax ; ds:si -> the log buffer.
652 add dx, cx ; update output counter
653 add ax, cx ; calc new offLogTail
654 and ax, LOG_SIZE - 1
655 rep movsb ; do the copy
656 mov [NAME(g_offLogTail)], ax ; commit the read.
657 jmp .log_loop
658
659.log_done:
660 les bx, [bp - 4] ; Reload the packet pointer.
661 mov word [es:bx + PKTRW.cbTrans], dx
662 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
663 jmp near VBoxDrvEP_Done
664
665.log_phystovirt_failed:
666 les bx, [bp - 4] ; Reload the packet pointer.
667 jmp VBoxDrvEP_GeneralFailure
668
669
670 ;
671 ; Return 'unknown command' error.
672 ;
673VBoxDrvEP_NotSupported:
674 mov word [es:bx + PKTHDR.status], 08103h ; error, done, unknown command.
675 jmp VBoxDrvEP_Done
676
677 ;
678 ; Return 'general failure' error.
679 ;
680VBoxDrvEP_GeneralFailure:
681 mov word [es:bx + PKTHDR.status], 0810ch ; error, done, general failure.
682 jmp VBoxDrvEP_Done
683
684 ;
685 ; Non-optimized return path.
686 ;
687VBoxDrvEP_Done:
688 mov sp, bp
689 pop ebp
690 retf
691ENDPROC VBoxDrvEP
692
693
694;;
695; The helper device entry point.
696;
697; This is only used to do the DosOpen on the main driver so we can
698; do ring-3 init and report failures.
699;
700GLOBALNAME VBoxDrvInitEP
701 ; The only request we're servicing is the 'init' one.
702 cmp word [es:bx + PKTHDR.cmd], 0
703 je near NAME(VBoxDrvInitEPServiceInitReq)
704
705 ; Ok, it's not the init request, just fail it.
706 mov word [es:bx + PKTHDR.status], 08103h ; error, done, unknown command.
707 retf
708
709
710;
711; The 16-bit init code.
712;
713segment CODE16_INIT
714GLOBALNAME g_InitCodeStart
715
716;; The device name for DosOpen.
717g_szDeviceName:
718 db '\DEV\vboxdrv$', 0
719
720; icsdebug can't see where stuff starts otherwise. (kDevTest)
721int3
722int3
723int3
724int3
725int3
726int3
727
728;;
729; The Ring-3 init code.
730;
731BEGINPROC VBoxDrvInitEPServiceInitReq
732 push ebp
733 mov ebp, esp
734 push es ; bp - 2
735 push sp ; bp - 4
736 push -1 ; bp - 6: hfOpen
737 push 0 ; bp - 8: usAction
738 and sp, 0fffch
739
740 ; check for the init package.
741 cmp word [es:bx + PKTHDR.cmd], 0
742 jne near .not_init
743
744 ;
745 ; Copy the data out of the init packet.
746 ;
747 mov eax, [es:bx + PKTINITIN.fpfnDevHlp]
748 mov [NAME(g_fpfnDevHlp)], eax
749 mov edx, [es:bx + PKTINITIN.fpszArgs]
750 mov [g_fpszArgs], edx
751
752 ;
753 ; Open the first driver, close it, and check status.
754 ;
755
756 ; APIRET _Pascal DosOpen(PSZ pszFname, PHFILE phfOpen, PUSHORT pusAction,
757 ; ULONG ulFSize, USHORT usAttr, USHORT fsOpenFlags,
758 ; USHORT fsOpenMode, ULONG ulReserved);
759 push seg g_szDeviceName ; pszFname
760 push g_szDeviceName
761 push ss ; phfOpen
762 lea dx, [bp - 6]
763 push dx
764 push ss ; pusAction
765 lea dx, [bp - 8]
766 push dx
767 push dword 0 ; ulFSize
768 push 0 ; usAttr = FILE_NORMAL
769 push 1 ; fsOpenFlags = FILE_OPEN
770 push 00040h ; fsOpenMode = OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY
771 push dword 0 ; ulReserved
772 call far DOS16OPEN
773
774 push ax ; Quickly flush any text.
775 call NAME(VBoxDrvInitFlushText)
776 pop ax
777
778 or ax, ax
779 jnz .done_err
780
781 ; APIRET APIENTRY DosClose(HFILE hf);
782 mov cx, [bp - 6]
783 push cx
784 call far DOS16CLOSE
785 or ax, ax
786 jnz .done_err ; This can't happen (I hope).
787
788 ;
789 ; Ok, we're good.
790 ;
791 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
792 mov byte [es:bx + PKTINITOUT.cUnits], 0
793 mov word [es:bx + PKTINITOUT.cbCode16], NAME(g_InitCodeStart) wrt CODE16
794 mov word [es:bx + PKTINITOUT.cbData16], NAME(g_InitDataStart) wrt DATA16
795 mov dword [es:bx + PKTINITOUT.fpaBPBs], 0
796 jmp .done
797
798 ;
799 ; Init failure.
800 ;
801.done_err:
802 mov word [es:bx + PKTHDR.status], 0810fh ; error, done, init failed.
803 mov byte [es:bx + PKTINITOUT.cUnits], 0
804 mov word [es:bx + PKTINITOUT.cbCode16], 0
805 mov word [es:bx + PKTINITOUT.cbData16], 0
806 mov dword [es:bx + PKTINITOUT.fpaBPBs], 0
807 jmp .done
808
809 ;
810 ; Not init, return 'unknown command'.
811 ;
812.not_init:
813 mov word [es:bx + PKTHDR.status], 08103h ; error, done, unknown command.
814 jmp .done
815
816 ;
817 ; Request done.
818 ;
819.done:
820 mov sp, bp
821 pop ebp
822 retf
823ENDPROC VBoxDrvInitEPServiceInitReq
824
825
826;;
827; The Ring-0 init code.
828;
829BEGINPROC VBoxDrvRing0Init
830 push es
831 push esi
832 push ebp
833 mov ebp, esp
834 and sp, 0fffch
835
836 ;
837 ; Thunk the argument string pointer first.
838 ;
839 movzx esi, word [g_fpszArgs] ; offset
840 mov ax, [g_fpszArgs + 2] ; selector
841 mov dl, DevHlp_VirtToLin
842 call far [NAME(g_fpfnDevHlp)]
843 jc near VBoxDrvRing0Init_done ; eax is non-zero on failure (can't happen)
844 push eax ; 00h - pszArgs (for VBoxDrvInit).
845
846 ;
847 ; Do 16-bit init?
848 ;
849
850
851 ;
852 ; Do 32-bit init
853 ;
854 ;jmp far dword NAME(VBoxDrvRing0Init_32) wrt FLAT
855 db 066h
856 db 0eah
857 dd NAME(VBoxDrvRing0Init_32) ;wrt FLAT
858 dw TEXT32 wrt FLAT
859segment TEXT32
860GLOBALNAME VBoxDrvRing0Init_32
861
862 ; switch stack to 32-bit.
863 mov ax, DATA32 wrt FLAT
864 mov ds, ax
865 mov es, ax
866 call KernThunkStackTo32
867
868 ; call the C code.
869 call NAME(VBoxDrvInit)
870
871 ; switch back the stack and reload ds.
872 push eax
873 call KernThunkStackTo16
874 pop eax
875
876 mov dx, seg NAME(g_fInitialized)
877 mov ds, dx
878
879 ; jump back to the 16-bit code.
880 ;jmp far dword NAME(VBoxDrvRing0Init_16) wrt CODE16
881 db 066h
882 db 0eah
883 dw NAME(VBoxDrvRing0Init_16) wrt CODE16
884 dw CODE16_INIT
885segment CODE16_INIT
886GLOBALNAME VBoxDrvRing0Init_16
887
888 ; check the result and set g_fInitialized on success.
889 or eax, eax
890 jnz VBoxDrvRing0Init_done
891 mov byte [NAME(g_fInitialized)], 1
892
893VBoxDrvRing0Init_done:
894 mov sp, bp
895 pop ebp
896 pop esi
897 pop es
898 ret
899ENDPROC VBoxDrvRing0Init
900
901
902;;
903; Flush any text in the text buffer.
904;
905BEGINPROC VBoxDrvInitFlushText
906 push bp
907 mov bp, sp
908
909 ; Anything in the buffer?
910 mov ax, [NAME(g_cchInitText)]
911 or ax, ax
912 jz .done
913
914%if 1
915 ; Write it to STDOUT.
916 ; APIRET _Pascal DosWrite(HFILE hf, PVOID pvBuf, USHORT cbBuf, PUSHORT pcbBytesWritten);
917 push ax ; bp - 2 : cbBytesWritten
918 mov cx, sp
919 push 1 ; STDOUT
920 push seg NAME(g_szInitText) ; pvBuf
921 push NAME(g_szInitText)
922 push ax ; cbBuf
923 push ss ; pcbBytesWritten
924 push cx
925%if 0 ; wlink generates a non-aliased fixup here which results in 16-bit offset with the flat 32-bit selector.
926 call far DOS16WRITE
927%else
928 ; convert flat pointer to a far pointer using the tiled algorithm.
929 push ds
930 mov ax, DATA32 wrt FLAT
931 mov ds, ax
932 mov eax, g_pfnDos16Write wrt FLAT
933 movzx eax, word [eax + 2] ; High word of the flat address (in DATA32).
934 shl ax, 3
935 or ax, 0007h
936 pop ds
937 mov [NAME(g_fpfnDos16Write) + 2], ax ; Update the selector (in DATA16_INIT).
938 ; do the call
939 call far [NAME(g_fpfnDos16Write)]
940%endif
941
942%else ; alternative workaround for the wlink issue.
943 ; Use the save message devhlp.
944 push esi
945 push ebx
946 xor bx, bx
947 mov si, NAME(g_MsgTab)
948 mov dx, seg NAME(g_MsgTab)
949 mov ds, dx
950 mov dl, DevHlp_SAVE_MESSAGE
951 call far [NAME(g_fpfnDevHlp)]
952 pop ebx
953 pop esi
954%endif
955
956 ; Empty the buffer.
957 mov word [NAME(g_cchInitText)], 0
958 mov byte [NAME(g_szInitText)], 0
959
960.done:
961 mov sp, bp
962 pop bp
963 ret
964ENDPROC VBoxDrvInitFlushText
965
966
967
968;;
969; This must be present
970segment DATA32
971g_pfnDos16Write:
972 dd DOS16WRITE ; flat
973
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use