VirtualBox

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

最後變更 在這個檔案從4534是 1197,由 vboxsync 提交於 18 年 前

export

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 26.7 KB
 
1; $Id: SUPDrvA-os2.asm 1197 2007-03-04 20:58:39Z 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 <[email protected]>
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, uint16_t *pcbParm)
317 ;
318VBoxDrvEP_GenIOCtl_Fast:
319 mov ax, [es:bx + PKTIOCTL.pData + 2] ; LDT selector to flat address.
320 shr ax, 3
321 shl eax, 16
322 mov ax, [es:bx + PKTIOCTL.pData]
323 push eax ; 08h - pointer to the rc buffer.
324
325 ; function.
326 movzx edx, byte [es:bx + PKTIOCTL.fun]
327 push edx ; 04h
328
329 ; system file number.
330 movzx eax, word [es:bx + PKTIOCTL.sfn]
331 push eax ; 00h
332
333 ; go to the 32-bit code
334 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Fast_32) wrt FLAT
335 db 066h
336 db 0eah
337 dd NAME(VBoxDrvEP_GenIOCtl_Fast_32) ;wrt FLAT
338 dw TEXT32 wrt FLAT
339segment TEXT32
340GLOBALNAME VBoxDrvEP_GenIOCtl_Fast_32
341
342 ; switch stack to 32-bit.
343 mov ax, DATA32 wrt FLAT
344 mov ds, ax
345 mov es, ax
346 call KernThunkStackTo32
347
348 ; call the C code (don't cleanup the stack).
349 call NAME(VBoxDrvIOCtlFast)
350
351 ; switch back the stack.
352 push eax
353 call KernThunkStackTo16
354 pop eax
355
356 ; jump back to the 16-bit code.
357 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Fast_16) wrt CODE16
358 db 066h
359 db 0eah
360 dw NAME(VBoxDrvEP_GenIOCtl_Fast_16) wrt CODE16
361 dw CODE16
362segment CODE16
363GLOBALNAME VBoxDrvEP_GenIOCtl_Fast_16
364 les bx, [bp - 4] ; Reload the packet pointer.
365 or eax, eax
366 jnz near VBoxDrvEP_GeneralFailure
367
368 ; setup output stuff.
369 mov edx, esp
370 mov eax, [ss:edx + 0ch] ; output sizes.
371 mov [es:bx + PKTIOCTL.cbParm], eax ; update cbParm and cbData.
372 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
373
374 mov sp, bp
375 pop ebp
376 retf
377
378 ;
379 ; Other IOCtl (slow)
380 ;
381VBoxDrvEP_GenIOCtl_Other:
382 mov eax, [es:bx + PKTIOCTL.cbParm] ; Load cbParm and cbData
383 push eax ; 1eh - in/out data size.
384 ; 1ch - in/out parameter size.
385 push edx ; 18h - pointer to data size (filled in later).
386 push ecx ; 14h - pointer to param size (filled in later).
387
388 ; pData (convert to flat 32-bit)
389 mov ax, word [es:bx + PKTIOCTL.pData + 2] ; selector
390 cmp ax, 3 ; <= 3 -> nil selector...
391 jbe .no_data
392 movzx esi, word [es:bx + PKTIOCTL.pData] ; offset
393 mov dl, DevHlp_VirtToLin
394 call far [NAME(g_fpfnDevHlp)]
395 jc near VBoxDrvEP_GeneralFailure
396 jmp .finish_data
397.no_data:
398 xor eax, eax
399.finish_data:
400 push eax ; 10h
401
402 ; pParm (convert to flat 32-bit)
403 mov ax, word [es:bx + PKTIOCTL.pParm + 2] ; selector
404 cmp ax, 3 ; <= 3 -> nil selector...
405 jbe .no_parm
406 movzx esi, word [es:bx + PKTIOCTL.pParm] ; offset
407 mov dl, DevHlp_VirtToLin
408 call far [NAME(g_fpfnDevHlp)]
409 jc near VBoxDrvEP_GeneralFailure
410 jmp .finish_parm
411.no_parm:
412 xor eax, eax
413.finish_parm:
414 push eax ; 0ch
415
416 ; function.
417 movzx edx, byte [es:bx + PKTIOCTL.fun]
418 push edx ; 08h
419
420 ; category.
421 movzx ecx, byte [es:bx + PKTIOCTL.cat]
422 push ecx ; 04h
423
424 ; system file number.
425 movzx eax, word [es:bx + PKTIOCTL.sfn]
426 push eax ; 00h
427
428 ; go to the 32-bit code
429 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Other_32) wrt FLAT
430 db 066h
431 db 0eah
432 dd NAME(VBoxDrvEP_GenIOCtl_Other_32) ;wrt FLAT
433 dw TEXT32 wrt FLAT
434segment TEXT32
435GLOBALNAME VBoxDrvEP_GenIOCtl_Other_32
436
437 ; switch stack to 32-bit.
438 mov ax, DATA32 wrt FLAT
439 mov ds, ax
440 mov es, ax
441 call KernThunkStackTo32
442
443 ; update in/out parameter pointers
444 lea eax, [esp + 1ch]
445 mov [esp + 14h], eax
446 lea edx, [esp + 1eh]
447 mov [esp + 18h], edx
448
449 ; call the C code (don't cleanup the stack).
450 call NAME(VBoxDrvIOCtl)
451
452 ; switch back the stack.
453 push eax
454 call KernThunkStackTo16
455 pop eax
456
457 ; jump back to the 16-bit code.
458 ;jmp far dword NAME(VBoxDrvEP_GenIOCtl_Other_16) wrt CODE16
459 db 066h
460 db 0eah
461 dw NAME(VBoxDrvEP_GenIOCtl_Other_16) wrt CODE16
462 dw CODE16
463segment CODE16
464GLOBALNAME VBoxDrvEP_GenIOCtl_Other_16
465 les bx, [bp - 4] ; Reload the packet pointer.
466 or eax, eax
467 jnz near VBoxDrvEP_GeneralFailure
468
469 ; setup output stuff.
470 mov edx, esp
471 mov eax, [ss:edx + 1ch] ; output sizes.
472 mov [es:bx + PKTIOCTL.cbParm], eax ; update cbParm and cbData.
473 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
474
475 mov sp, bp
476 pop ebp
477 retf
478
479
480 ;
481 ; Less Performance Critical Requests.
482 ;
483VBoxDrvEP_NotGenIOCtl:
484 cmp byte [es:bx + PKTHDR.cmd], 0dh ; Open
485 je VBoxDrvEP_Open
486 cmp byte [es:bx + PKTHDR.cmd], 0eh ; Close
487 je VBoxDrvEP_Close
488 cmp byte [es:bx + PKTHDR.cmd], 00h ; Init
489 je VBoxDrvEP_Init
490 cmp byte [es:bx + PKTHDR.cmd], 04h ; Read
491 je near VBoxDrvEP_Read
492 jmp near VBoxDrvEP_NotSupported
493
494
495 ;
496 ; Open Request. w/ ring-0 init.
497 ;
498VBoxDrvEP_Open:
499 cmp byte [NAME(g_fInitialized)], 1
500 jne VBoxDrvEP_OpenOther
501
502 ; First argument, the system file number.
503 movzx eax, word [es:bx + PKTOPEN.sfn]
504 push eax
505
506 ; go to the 32-bit code
507 ;jmp far dword NAME(VBoxDrvEP_Open_32) wrt FLAT
508 db 066h
509 db 0eah
510 dd NAME(VBoxDrvEP_Open_32) ;wrt FLAT
511 dw TEXT32 wrt FLAT
512segment TEXT32
513GLOBALNAME VBoxDrvEP_Open_32
514
515 ; switch stack to 32-bit.
516 mov ax, DATA32 wrt FLAT
517 mov ds, ax
518 mov es, ax
519 call KernThunkStackTo32
520
521 ; call the C code.
522 call NAME(VBoxDrvOpen)
523
524 ; switch back the stack.
525 push eax
526 call KernThunkStackTo16
527 pop eax
528
529 ; jump back to the 16-bit code.
530 ;jmp far dword NAME(VBoxDrvEP_Open_32) wrt CODE16
531 db 066h
532 db 0eah
533 dw NAME(VBoxDrvEP_Open_16) wrt CODE16
534 dw CODE16
535segment CODE16
536GLOBALNAME VBoxDrvEP_Open_16
537 les bx, [bp - 4] ; Reload the packet pointer.
538 or eax, eax
539 jnz near VBoxDrvEP_GeneralFailure
540 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
541 jmp near VBoxDrvEP_Done
542
543 ; Initializing or failed init?
544VBoxDrvEP_OpenOther:
545 cmp byte [NAME(g_fInitialized)], 0
546 jne VBoxDrvEP_OpenFailed
547
548 mov byte [NAME(g_fInitialized)], -1
549 call NAME(VBoxDrvRing0Init)
550 cmp byte [NAME(g_fInitialized)], 1
551 je VBoxDrvEP_Open
552
553VBoxDrvEP_OpenFailed:
554 mov word [es:bx + PKTHDR.status], 0810fh ; error, done, init failed.
555 jmp near VBoxDrvEP_Done
556
557
558 ;
559 ; Close Request.
560 ;
561VBoxDrvEP_Close:
562 ; First argument, the system file number.
563 movzx eax, word [es:bx + PKTOPEN.sfn]
564 push eax
565
566 ; go to the 32-bit code
567 ;jmp far dword NAME(VBoxDrvEP_Close_32) wrt FLAT
568 db 066h
569 db 0eah
570 dd NAME(VBoxDrvEP_Close_32) ;wrt FLAT
571 dw TEXT32 wrt FLAT
572segment TEXT32
573GLOBALNAME VBoxDrvEP_Close_32
574
575 ; switch stack to 32-bit.
576 mov ax, DATA32 wrt FLAT
577 mov ds, ax
578 mov es, ax
579 call KernThunkStackTo32
580
581 ; call the C code.
582 call NAME(VBoxDrvClose)
583
584 ; switch back the stack.
585 push eax
586 call KernThunkStackTo16
587 pop eax
588
589 ; jump back to the 16-bit code.
590 ;jmp far dword NAME(VBoxDrvEP_Close_32) wrt CODE16
591 db 066h
592 db 0eah
593 dw NAME(VBoxDrvEP_Close_16) wrt CODE16
594 dw CODE16
595segment CODE16
596GLOBALNAME VBoxDrvEP_Close_16
597 les bx, [bp - 4] ; Reload the packet pointer.
598 or eax, eax
599 jnz near VBoxDrvEP_GeneralFailure
600 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
601 jmp near VBoxDrvEP_Done
602
603
604 ;
605 ; Init Request.
606 ; The other driver header will do this.
607 ;
608VBoxDrvEP_Init:
609 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
610 mov byte [es:bx + PKTINITOUT.cUnits], 0
611 mov word [es:bx + PKTINITOUT.cbCode16], NAME(g_InitCodeStart) wrt CODE16
612 mov word [es:bx + PKTINITOUT.cbData16], NAME(g_InitDataStart) wrt DATA16
613 mov dword [es:bx + PKTINITOUT.fpaBPBs], 0
614 jmp near VBoxDrvEP_Done
615
616
617 ;
618 ; Read Request.
619 ; Return log data.
620 ;
621VBoxDrvEP_Read:
622 ; Any log data available?
623 xor dx, dx
624 mov ax, [NAME(g_offLogTail)]
625 cmp ax, [NAME(g_offLogHead)]
626 jz near .log_done
627
628 ; create a temporary mapping of the physical buffer. Docs claims it trashes nearly everything...
629 push ebp
630 mov cx, [es:bx + PKTRW.cbTrans]
631 push cx
632 mov ax, [es:bx + PKTRW.PhysTrans + 2]
633 mov bx, [es:bx + PKTRW.PhysTrans]
634 mov dh, 1
635 mov dl, DevHlp_PhysToVirt
636 call far [NAME(g_fpfnDevHlp)]
637 pop bx ; bx = cbTrans
638 pop ebp
639 jc near .log_phystovirt_failed
640 ; es:di -> the output buffer.
641
642 ; setup the copy operation.
643 mov ax, [NAME(g_offLogTail)]
644 xor dx, dx ; dx tracks the number of bytes copied.
645.log_loop:
646 mov cx, [NAME(g_offLogHead)]
647 cmp ax, cx
648 je .log_done
649 jb .log_loop_before
650 mov cx, LOG_SIZE
651.log_loop_before: ; cx = end offset
652 sub cx, ax ; cx = sequential bytes to copy.
653 cmp cx, bx
654 jbe .log_loop_min
655 mov cx, bx ; output buffer is smaller than available data.
656.log_loop_min:
657 mov si, NAME(g_szLog)
658 add si, ax ; ds:si -> the log buffer.
659 add dx, cx ; update output counter
660 add ax, cx ; calc new offLogTail
661 and ax, LOG_SIZE - 1
662 rep movsb ; do the copy
663 mov [NAME(g_offLogTail)], ax ; commit the read.
664 jmp .log_loop
665
666.log_done:
667 les bx, [bp - 4] ; Reload the packet pointer.
668 mov word [es:bx + PKTRW.cbTrans], dx
669 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
670 jmp near VBoxDrvEP_Done
671
672.log_phystovirt_failed:
673 les bx, [bp - 4] ; Reload the packet pointer.
674 jmp VBoxDrvEP_GeneralFailure
675
676
677 ;
678 ; Return 'unknown command' error.
679 ;
680VBoxDrvEP_NotSupported:
681 mov word [es:bx + PKTHDR.status], 08103h ; error, done, unknown command.
682 jmp VBoxDrvEP_Done
683
684 ;
685 ; Return 'general failure' error.
686 ;
687VBoxDrvEP_GeneralFailure:
688 mov word [es:bx + PKTHDR.status], 0810ch ; error, done, general failure.
689 jmp VBoxDrvEP_Done
690
691 ;
692 ; Non-optimized return path.
693 ;
694VBoxDrvEP_Done:
695 mov sp, bp
696 pop ebp
697 retf
698ENDPROC VBoxDrvEP
699
700
701;;
702; The helper device entry point.
703;
704; This is only used to do the DosOpen on the main driver so we can
705; do ring-3 init and report failures.
706;
707GLOBALNAME VBoxDrvInitEP
708 ; The only request we're servicing is the 'init' one.
709 cmp word [es:bx + PKTHDR.cmd], 0
710 je near NAME(VBoxDrvInitEPServiceInitReq)
711
712 ; Ok, it's not the init request, just fail it.
713 mov word [es:bx + PKTHDR.status], 08103h ; error, done, unknown command.
714 retf
715
716
717;
718; The 16-bit init code.
719;
720segment CODE16_INIT
721GLOBALNAME g_InitCodeStart
722
723;; The device name for DosOpen.
724g_szDeviceName:
725 db '\DEV\vboxdrv$', 0
726
727; icsdebug can't see where stuff starts otherwise. (kDevTest)
728int3
729int3
730int3
731int3
732int3
733int3
734
735;;
736; The Ring-3 init code.
737;
738BEGINPROC VBoxDrvInitEPServiceInitReq
739 push ebp
740 mov ebp, esp
741 push es ; bp - 2
742 push sp ; bp - 4
743 push -1 ; bp - 6: hfOpen
744 push 0 ; bp - 8: usAction
745 and sp, 0fffch
746
747 ; check for the init package.
748 cmp word [es:bx + PKTHDR.cmd], 0
749 jne near .not_init
750
751 ;
752 ; Copy the data out of the init packet.
753 ;
754 mov eax, [es:bx + PKTINITIN.fpfnDevHlp]
755 mov [NAME(g_fpfnDevHlp)], eax
756 mov edx, [es:bx + PKTINITIN.fpszArgs]
757 mov [g_fpszArgs], edx
758
759 ;
760 ; Open the first driver, close it, and check status.
761 ;
762
763 ; APIRET _Pascal DosOpen(PSZ pszFname, PHFILE phfOpen, PUSHORT pusAction,
764 ; ULONG ulFSize, USHORT usAttr, USHORT fsOpenFlags,
765 ; USHORT fsOpenMode, ULONG ulReserved);
766 push seg g_szDeviceName ; pszFname
767 push g_szDeviceName
768 push ss ; phfOpen
769 lea dx, [bp - 6]
770 push dx
771 push ss ; pusAction
772 lea dx, [bp - 8]
773 push dx
774 push dword 0 ; ulFSize
775 push 0 ; usAttr = FILE_NORMAL
776 push 1 ; fsOpenFlags = FILE_OPEN
777 push 00040h ; fsOpenMode = OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY
778 push dword 0 ; ulReserved
779 call far DOS16OPEN
780
781 push ax ; Quickly flush any text.
782 call NAME(VBoxDrvInitFlushText)
783 pop ax
784
785 or ax, ax
786 jnz .done_err
787
788 ; APIRET APIENTRY DosClose(HFILE hf);
789 mov cx, [bp - 6]
790 push cx
791 call far DOS16CLOSE
792 or ax, ax
793 jnz .done_err ; This can't happen (I hope).
794
795 ;
796 ; Ok, we're good.
797 ;
798 mov word [es:bx + PKTHDR.status], 00100h ; done, ok.
799 mov byte [es:bx + PKTINITOUT.cUnits], 0
800 mov word [es:bx + PKTINITOUT.cbCode16], NAME(g_InitCodeStart) wrt CODE16
801 mov word [es:bx + PKTINITOUT.cbData16], NAME(g_InitDataStart) wrt DATA16
802 mov dword [es:bx + PKTINITOUT.fpaBPBs], 0
803 jmp .done
804
805 ;
806 ; Init failure.
807 ;
808.done_err:
809 mov word [es:bx + PKTHDR.status], 0810fh ; error, done, init failed.
810 mov byte [es:bx + PKTINITOUT.cUnits], 0
811 mov word [es:bx + PKTINITOUT.cbCode16], 0
812 mov word [es:bx + PKTINITOUT.cbData16], 0
813 mov dword [es:bx + PKTINITOUT.fpaBPBs], 0
814 jmp .done
815
816 ;
817 ; Not init, return 'unknown command'.
818 ;
819.not_init:
820 mov word [es:bx + PKTHDR.status], 08103h ; error, done, unknown command.
821 jmp .done
822
823 ;
824 ; Request done.
825 ;
826.done:
827 mov sp, bp
828 pop ebp
829 retf
830ENDPROC VBoxDrvInitEPServiceInitReq
831
832
833;;
834; The Ring-0 init code.
835;
836BEGINPROC VBoxDrvRing0Init
837 push es
838 push esi
839 push ebp
840 mov ebp, esp
841 and sp, 0fffch
842
843 ;
844 ; Thunk the argument string pointer first.
845 ;
846 movzx esi, word [g_fpszArgs] ; offset
847 mov ax, [g_fpszArgs + 2] ; selector
848 mov dl, DevHlp_VirtToLin
849 call far [NAME(g_fpfnDevHlp)]
850 jc near VBoxDrvRing0Init_done ; eax is non-zero on failure (can't happen)
851 push eax ; 00h - pszArgs (for VBoxDrvInit).
852
853 ;
854 ; Do 16-bit init?
855 ;
856
857
858 ;
859 ; Do 32-bit init
860 ;
861 ;jmp far dword NAME(VBoxDrvRing0Init_32) wrt FLAT
862 db 066h
863 db 0eah
864 dd NAME(VBoxDrvRing0Init_32) ;wrt FLAT
865 dw TEXT32 wrt FLAT
866segment TEXT32
867GLOBALNAME VBoxDrvRing0Init_32
868
869 ; switch stack to 32-bit.
870 mov ax, DATA32 wrt FLAT
871 mov ds, ax
872 mov es, ax
873 call KernThunkStackTo32
874
875 ; call the C code.
876 call NAME(VBoxDrvInit)
877
878 ; switch back the stack and reload ds.
879 push eax
880 call KernThunkStackTo16
881 pop eax
882
883 mov dx, seg NAME(g_fInitialized)
884 mov ds, dx
885
886 ; jump back to the 16-bit code.
887 ;jmp far dword NAME(VBoxDrvRing0Init_16) wrt CODE16
888 db 066h
889 db 0eah
890 dw NAME(VBoxDrvRing0Init_16) wrt CODE16
891 dw CODE16_INIT
892segment CODE16_INIT
893GLOBALNAME VBoxDrvRing0Init_16
894
895 ; check the result and set g_fInitialized on success.
896 or eax, eax
897 jnz VBoxDrvRing0Init_done
898 mov byte [NAME(g_fInitialized)], 1
899
900VBoxDrvRing0Init_done:
901 mov sp, bp
902 pop ebp
903 pop esi
904 pop es
905 ret
906ENDPROC VBoxDrvRing0Init
907
908
909;;
910; Flush any text in the text buffer.
911;
912BEGINPROC VBoxDrvInitFlushText
913 push bp
914 mov bp, sp
915
916 ; Anything in the buffer?
917 mov ax, [NAME(g_cchInitText)]
918 or ax, ax
919 jz .done
920
921%if 1
922 ; Write it to STDOUT.
923 ; APIRET _Pascal DosWrite(HFILE hf, PVOID pvBuf, USHORT cbBuf, PUSHORT pcbBytesWritten);
924 push ax ; bp - 2 : cbBytesWritten
925 mov cx, sp
926 push 1 ; STDOUT
927 push seg NAME(g_szInitText) ; pvBuf
928 push NAME(g_szInitText)
929 push ax ; cbBuf
930 push ss ; pcbBytesWritten
931 push cx
932%if 0 ; wlink generates a non-aliased fixup here which results in 16-bit offset with the flat 32-bit selector.
933 call far DOS16WRITE
934%else
935 ; convert flat pointer to a far pointer using the tiled algorithm.
936 push ds
937 mov ax, DATA32 wrt FLAT
938 mov ds, ax
939 mov eax, g_pfnDos16Write wrt FLAT
940 movzx eax, word [eax + 2] ; High word of the flat address (in DATA32).
941 shl ax, 3
942 or ax, 0007h
943 pop ds
944 mov [NAME(g_fpfnDos16Write) + 2], ax ; Update the selector (in DATA16_INIT).
945 ; do the call
946 call far [NAME(g_fpfnDos16Write)]
947%endif
948
949%else ; alternative workaround for the wlink issue.
950 ; Use the save message devhlp.
951 push esi
952 push ebx
953 xor bx, bx
954 mov si, NAME(g_MsgTab)
955 mov dx, seg NAME(g_MsgTab)
956 mov ds, dx
957 mov dl, DevHlp_SAVE_MESSAGE
958 call far [NAME(g_fpfnDevHlp)]
959 pop ebx
960 pop esi
961%endif
962
963 ; Empty the buffer.
964 mov word [NAME(g_cchInitText)], 0
965 mov byte [NAME(g_szInitText)], 0
966
967.done:
968 mov sp, bp
969 pop bp
970 ret
971ENDPROC VBoxDrvInitFlushText
972
973
974
975;;
976; This must be present
977segment DATA32
978g_pfnDos16Write:
979 dd DOS16WRITE ; flat
980
981
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette