From 3ea944faa0a3cf1e2fdcd8279ea45c038d5173cf Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 27 Sep 2006 19:32:26 +0000 Subject: 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 --- sys/boot/i386/btx/btx/btx.S | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) (limited to 'sys') diff --git a/sys/boot/i386/btx/btx/btx.S b/sys/boot/i386/btx/btx/btx.S index f7d848f3fbe1..569ba9d5fb55 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 -- cgit v1.3