Skip to content

Commit 48ca830

Browse files
hdpmi: VCPI pm calls made NMI-safe
1 parent ccbc605 commit 48ca830

File tree

9 files changed

+148
-65
lines changed

9 files changed

+148
-65
lines changed

Src/HDPMI/EXTERNAL.INC

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,9 @@ externdef rawjmp_rm_all:near
312312
if 0;?JHDPMI
313313
externdef jhdpmicall:near
314314
endif
315+
if ?NMISAFE
316+
externdef oldint02rm:dword
317+
endif
315318
_TEXT16 ends
316319

317320
BEGGRP16 segment

Src/HDPMI/HDPMI.ASM

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ ifnb <r0exclbl>
220220
else
221221
jz exclbl
222222
endif
223-
if ?KDSUPP or ?ALLOWR0IRQ
223+
if ?KDSUPP or ?ALLOWR0IRQ or ?NMISAFE
224224
push eax
225225
lea eax, [esp+R3FAULT32+4]
226226
cmp eax, ss:[dwHostStack]
@@ -2075,8 +2075,22 @@ endif
20752075
pop edx
20762076
pop ecx
20772077
pop eax
2078+
if ?NMISAFE
2079+
cmp [ebp+4].LCEFR.dwExc,2 ;v3.24: avoid IRETD for NMI
2080+
jz @F
2081+
endif
20782082
pop ebp
20792083
iretd
2084+
if ?NMISAFE
2085+
@@:
2086+
mov ebp,[ebp+4].LCEFR.r.rFL
2087+
xchg ebp,[esp+1*4] ;set flags, get eip
2088+
xchg ebp,[esp+2*4] ;set eip, get cs
2089+
mov [esp+3*4],ebp ;set cs
2090+
pop ebp
2091+
popfd
2092+
retd
2093+
endif
20802094
align 4
20812095
lpms_call_exc endp
20822096

@@ -2705,41 +2719,61 @@ endif
27052719
intr01 endp
27062720

27072721
intr02 proc
2708-
cmp word ptr [esp.IRET32.rCS],_CSSEL_ ;NMI in ring 0?
2709-
if ?NMI2RM
2710-
jz intr02_r0 ; v3.24: route NMI in PL0 to real-mode
2722+
;--- v3.24: check PL, not CS
2723+
; cmp word ptr [esp.IRET32.rCS],_CSSEL_ ;NMI in ring 0?
2724+
push eax
2725+
lar eax,[esp+4].IRET32.rCSd
2726+
and ah,60h
2727+
pop eax
2728+
;--- v3.24: route NMI in PL0 to real-mode for NMI-safe variant
2729+
if ?NMISAFE
2730+
jz intr02_r0
27112731
else
27122732
jz iretexit ; skip NMI in PL0
27132733
endif
27142734
@exception 02
27152735
@mapexc2int 02
2716-
if ?NMI2RM
2736+
if ?NMISAFE
27172737
;--- v3.24: route NMI to real-mode if it occured in ring 0
27182738
intr02_r0:
2739+
push eax
27192740
;--- save pm segment regs, they will be undefined after @rawjmp_pm
27202741
push ds
27212742
push es
27222743
push fs
27232744
push gs
27242745
;--- save/restore global vars that may be modified by mode switches
2725-
push ss:[taskseg._Eax]
27262746
push ss:[dwPmDest]
2747+
push ss:[taskseg._Eax]
27272748
push ss:[dwHostStack]
27282749
mov ss:[dwHostStack],esp
2729-
@rawjmp_rm @F
2730-
_TEXT16 segment
2750+
mov ax, offset intr02_rm1
2751+
cmp ss:[oldint02rm],0
2752+
jnz @F
2753+
mov ax, offset intr02_rm2
27312754
@@:
2755+
@rawjmp_rm ax
2756+
_TEXT16 segment
2757+
intr02_rm1:
2758+
pushf
2759+
db 9ah
2760+
oldint02rm dd 0
2761+
@rawjmp_pm intr02_pm
2762+
intr02_rm2:
27322763
int 02
2733-
@rawjmp_pm @F
2764+
@rawjmp_pm intr02_pm
27342765
_TEXT16 ends
2735-
@@:
2766+
;--- v86iret segregs weren't modified; NMI still masked
2767+
intr02_pm:
27362768
pop ss:[dwHostStack]
2737-
pop ss:[dwPmDest]
27382769
pop ss:[taskseg._Eax]
2770+
pop ss:[dwPmDest]
27392771
pop gs
27402772
pop fs
27412773
pop es
27422774
pop ds
2775+
@NMI_ON ;intr02 (wait until all seg regs are restored!)
2776+
pop eax
27432777
iretd
27442778
endif
27452779
intr02 endp
@@ -3303,7 +3337,7 @@ irqrm2pm_1:
33033337
mov fs, ss:pmstate.rFS
33043338
mov gs, ss:pmstate.rGS
33053339

3306-
@NMI_ON 0
3340+
@NMI_ON ;initrmcb_pm
33073341

33083342
ifdef _DEBUG
33093343
verw word ptr ss:pmstate.rSSd

Src/HDPMI/HDPMI.INC

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,6 @@ endif
273273
ifndef ?NMISAFE
274274
?NMISAFE equ 0 ;std 0; 1=NMI masked during mode switches
275275
endif
276-
if ?NMISAFE
277-
?NMI2RM equ 1 ;std 1; 1=route NMIs in PL0 to real-mode; 0=skip NMIs in PL0
278-
else
279-
?NMI2RM equ 0
280-
endif
281276
;----------------------------------------------------------------
282277

283278
if ?32BIT
@@ -1397,30 +1392,30 @@ endm
13971392
db 0Fh,0A2h
13981393
endm
13991394

1400-
@NMI_ON macro bSave:=<1>
1395+
@NMI_ON macro SaveReg
14011396
if ?NMISAFE
1402-
if bSave
1403-
push eax
1397+
ifnb <SaveReg>
1398+
push SaveReg
14041399
endif
14051400
mov al,0
14061401
out 70h,al
14071402
in al,71h
1408-
if bSave
1409-
pop eax
1403+
ifnb <SaveReg>
1404+
pop SaveReg
14101405
endif
14111406
endif
14121407
endm
14131408

1414-
@NMI_OFF macro bSave:=<1>
1409+
@NMI_OFF macro SaveReg
14151410
if ?NMISAFE
1416-
if bSave
1417-
push eax
1411+
ifnb <SaveReg>
1412+
push SaveReg
14181413
endif
14191414
mov al,80h
14201415
out 70h,al
14211416
in al,71h
1422-
if bSave
1423-
pop eax
1417+
ifnb <SaveReg>
1418+
pop SaveReg
14241419
endif
14251420
endif
14261421
endm
@@ -1449,7 +1444,11 @@ endm
14491444
endm
14501445

14511446
@rawjmp_rm macro dest
1447+
if (opattr dest) and 4
14521448
mov ss:[wRmDest], offset dest
1449+
else
1450+
mov ss:[wRmDest], dest
1451+
endif
14531452
jmp _rawjmp_rm
14541453
endm
14551454

Src/HDPMI/HDPMI.TXT

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//////////////////////////////////////////////////////////////////////////////
22
/ /
3-
/ HDPMI - DPMI Server (Version 3.23) /
3+
/ HDPMI - DPMI Server (Version 3.24) /
44
/ /
55
//////////////////////////////////////////////////////////////////////////////
66

Src/HDPMI/HDPMIHIS.TXT

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
� optional extension a for cmdline option -x added.
77
� int 31h, ax=508h: top of memory check (?TOPMEM) activated.
8-
� optional variant added that will mask NMIs during mode switches and
9-
route NMIs that occur in PL0 to real-mode.
8+
� optional variant added that's "NMI-safe" and routes NMIs occuring
9+
in PL0 to real-mode.
1010

1111
13.10.2025, version 3.23
1212

Src/HDPMI/I2FHDPMI.ASM

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
if ?VENDORAPI
1212

1313
@wofs macro ofs
14-
dw offset ofs - offset start168a
14+
dw offset ofs - $
1515
endm
1616

1717
ifdef _DEBUG
@@ -25,53 +25,66 @@ _TEXT32 segment
2525
_I2f168A_Hdpmi proc near public
2626

2727
push offset iret_with_CF_mod
28-
cmp ax, MAX168A
29-
jb @F
30-
stc
31-
ret
32-
@@:
3328
push ebx
34-
movzx ebx, ax
35-
mov bx, cs:[ebx*2+offset tab168a]
36-
add ebx, offset start168a
29+
push ecx
30+
push edx
31+
32+
APIFUNCS = 1 shl 4 ;4
33+
ifdef _DEBUG
34+
APIFUNCS = APIFUNCS or (1111b shl 0) ;0-3
35+
endif
36+
if ?VM
37+
APIFUNCS = APIFUNCS or (1 shl 5) ;5
38+
endif
39+
if ?PMIOPL eq 0
40+
APIFUNCS = APIFUNCS or (1111b shl 6) ;6-9 (10 rsvd)
41+
endif
42+
if ?NMISAFE
43+
APIFUNCS = APIFUNCS or (1 shl 11) ;11
44+
endif
45+
mov edx,APIFUNCS
46+
mov ebx,offset tab168a-2
47+
@@:
48+
bsf ecx,edx
49+
jz error
50+
btr edx,ecx
51+
add ebx,2
52+
cmp ax,cx
53+
jnz @B
54+
movzx ecx, word ptr cs:[ebx]
55+
add ebx,ecx
56+
pop edx
57+
pop ecx
3758
xchg ebx,[esp]
3859
ret
60+
error:
61+
pop edx
62+
pop ecx
63+
pop ebx
64+
stc
65+
ret
3966
align 2
4067
tab168a label word
4168
ifdef _DEBUG
4269
@wofs is0000
4370
@wofs is0001
4471
@wofs is0002
4572
@wofs is0003
46-
else
47-
@wofs error
48-
@wofs error
49-
@wofs error
50-
@wofs error
5173
endif
5274
@wofs is0004 ; "disable" host
53-
5475
if ?VM
5576
@wofs is0005 ; set/reset HDPMI=32 (VM)
56-
else
57-
@wofs error
5877
endif
59-
6078
if ?PMIOPL eq 0
61-
6279
@wofs is0006 ; trap port range
6380
@wofs is0007 ; release trapped port range
6481
@wofs simio ; Simulate IO
6582
@wofs is0009 ; trap CLI/STI
66-
; @wofs is000A ; Simulate HW interrupt
67-
83+
; @wofs is000A ; Simulate HW interrupt (not yet implemented)
84+
endif
85+
if ?NMISAFE
86+
@wofs is000B ; get/set real-mode NMI address
6887
endif
69-
MAX168A equ ($ - offset tab168a) / sizeof word
70-
71-
start168a:
72-
error:
73-
stc
74-
ret
7588
ifdef _DEBUG
7689
is0000:
7790
and ss:gbl.fMode2,not FM2_LOG
@@ -554,6 +567,15 @@ is0009 endp
554567
555568
endif ; ?PMIOPL eq 0
556569

570+
if ?NMISAFE
571+
;--- temporary, will be removed when PL0 exceptions work
572+
is000B proc
573+
xchg dx, word ptr ss:[oldint02rm+0]
574+
xchg cx, word ptr ss:[oldint02rm+2]
575+
ret
576+
is000B endp
577+
endif
578+
557579
_TEXT32 ends
558580

559581
endif

Src/HDPMI/I31SWT.ASM

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,6 @@ else
254254
xor ecx, ecx
255255
mov ds, ecx
256256

257-
@NMI_ON 0
258-
259257
@dprintf "rmcb: will try to alloc a rm-selector"
260258

261259
mov bx, ss:v86iret.rSS
@@ -310,6 +308,7 @@ if _LTRACE_ and ?RMCBLOG
310308
endif
311309
endif
312310
push eax
311+
@NMI_ON ;rmcb_pm
313312
jmp lpms_call_int ;switch to LPMS
314313
align 4
315314

@@ -531,8 +530,13 @@ endif
531530
havecsip:
532531
if ?SAFE301
533532
sub eax,5*2
533+
if ?NMISAFE
534+
mov es:[edx+eax],cx ;flags (will be popped before RETF)
535+
mov es:[edx+eax+2],esi
536+
else
534537
mov es:[edx+eax],esi
535538
mov es:[edx+eax+4],cx ;flags (will be popped by an IRET)
539+
endif
536540
mov si,ss:[wHostSeg]
537541
shl esi,16
538542
mov si,offset callrmproc_rm2
@@ -586,7 +590,12 @@ error1x:
586590
_TEXT16 segment
587591
callrmproc_rm:
588592
if ?SAFE301
593+
if ?NMISAFE
594+
popf
595+
retf
596+
else
589597
iret
598+
endif
590599
callrmproc_rm2:
591600
else
592601
popf
@@ -1113,7 +1122,7 @@ endif
11131122
mov [esp].IRET32.rSP, ebx
11141123
mov [esp].IRET32.rSSd, edx
11151124

1116-
@NMI_ON 0
1125+
@NMI_ON ;rm2pm
11171126

11181127
@checkhoststack
11191128

0 commit comments

Comments
 (0)