summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2006-09-27 19:32:26 +0000
committerjhb <jhb@FreeBSD.org>2006-09-27 19:32:26 +0000
commitf6b387ce531fb4ba91958db5aadcb53f89d4ed1b (patch)
treedb00a20450f4f883314f68fd467bbfb2a660a1c2 /sys/boot
parent28bd6c86994b994b1ab6f80d0b81317307ed85df (diff)
downloadFreeBSD-src-f6b387ce531fb4ba91958db5aadcb53f89d4ed1b.zip
FreeBSD-src-f6b387ce531fb4ba91958db5aadcb53f89d4ed1b.tar.gz
Emulate moving cr0, cr2, cr3, or cr4 into any i386 general register
rather than just emulating mov cr0, eax. This fixes some Compaq/HP BIOS with DMA (as the BIOS tried to read cr3 so it could translate addresses if paging was enabled). MFC after: 1 week
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/i386/btx/btx/btx.S26
1 files changed, 19 insertions, 7 deletions
diff --git a/sys/boot/i386/btx/btx/btx.S b/sys/boot/i386/btx/btx/btx.S
index f7d848f..569ba9d 100644
--- a/sys/boot/i386/btx/btx/btx.S
+++ b/sys/boot/i386/btx/btx/btx.S
@@ -493,9 +493,7 @@ v86mon.3: cmpb $0xf,%al # Prefixed instruction?
je v86wrmsr # Yes
cmpb $0x32,(%esi) # Is it a RDMSR?
je v86rdmsr # Yes
- cmpb $0x20,(%esi) # Is this a
- jne v86mon.4 # MOV EAX,CR0
- cmpb $0xc0,0x1(%esi) # instruction?
+ cmpb $0x20,(%esi) # Is this a MOV reg,CRx?
je v86mov # Yes
v86mon.4: cmpb $0xfa,%al # CLI?
je v86cli # Yes
@@ -527,10 +525,24 @@ v86mon.7: subl %edi,%esi # From linear
leal 0x8(%esp,1),%esp # Discard int no, error
iret # To V86 mode
/*
- * Emulate MOV EAX,CR0.
- */
-v86mov: movl %cr0,%eax # CR0 to
- movl %eax,0x1c(%ebp) # saved EAX
+ * Emulate MOV reg,CRx.
+ */
+v86mov: movb 0x1(%esi),%bl # Fetch Mod R/M byte
+ testb $0x10,%bl # Read CR2 or CR3?
+ jnz v86mov.1 # Yes
+ movl %cr0,%eax # Read CR0
+ testb $0x20,%bl # Read CR4 instead?
+ jz v86mov.2 # No
+ movl %cr4,%eax # Read CR4
+ jmp v86mov.2
+v86mov.1: movl %cr2,%eax # Read CR2
+ testb $0x08,%bl # Read CR3 instead?
+ jz v86mov.2 # No
+ movl %cr3,%eax # Read CR3
+v86mov.2: andl $0x7,%ebx # Compute offset in
+ shl $2,%ebx # frame of destination
+ neg %ebx # register
+ movl %eax,0x1c(%ebp,%ebx,1) # Store CR to reg
incl %esi # Adjust IP
/*
* Return from emulating a 0x0f prefixed instruction
OpenPOWER on IntegriCloud