Version bump, assorted CPU documentation tweaks, and more machine redirects
This commit is contained in:
parent
a5b9e0cae7
commit
4acf39f83e
178 changed files with 392 additions and 328 deletions
|
|
@ -1,13 +1,14 @@
|
|||
---
|
||||
layout: page
|
||||
title: "Intel 80286 CPU Documentation: Real Mode"
|
||||
title: "Intel 80286 CPU: Real Mode Emulation"
|
||||
permalink: /pubs/pc/reference/intel/80286/real_mode/
|
||||
---
|
||||
|
||||
Intel 80286 CPU Documentation: Real Mode
|
||||
Intel 80286 CPU: Real Mode Emulation
|
||||
---
|
||||
|
||||
[The following information is from an undated 15-page Intel document titled "Undocumented iAPX 286 Test Instruction"]
|
||||
[The following information is from an undated 15-page Intel document titled "Undocumented iAPX 286 Test Instruction",
|
||||
pp. 4-12]
|
||||
|
||||
### Executing Real Mode Programs in Protected Mode
|
||||
|
||||
|
|
@ -16,7 +17,7 @@ it and other programs. All segment register semantics of iAPX 86 real mode can b
|
|||
of the real mode program can also be limited to less than 1 megabyte and be relocated anywhere in the 16 Megabyte
|
||||
physical address space. The following sections describe several aspects of this emulation.
|
||||
|
||||
### Address space relocation and control ###
|
||||
#### Address space relocation and control ####
|
||||
|
||||
iAPX 86 real mode emulation requires any segment register load instruction cause a protection exception.
|
||||
An error code with bits 1-0 being zero and bits 15-2 being non-zero identify a segment register load exception.
|
||||
|
|
@ -38,9 +39,9 @@ error code of 0. No memory reference will occur. This case can be identified by
|
|||
contain a value of 0-3. These exceptions are also restartable.
|
||||
|
||||
Limits can be enforced on the size of the emulated iAPX 86 address space. An iAPX 86 paragraph ID that is outside
|
||||
the defined memory area can be loaded, but the segment register can be marked invalid for memory addressing. [LOADALL](../loadall/)
|
||||
can be used to load the iAPX 86 paragraph ID into the segment register, but the descriptor cache entry is marked
|
||||
invalid. The paragraph ID can still be read without causing a protection exception.
|
||||
the defined memory area can be loaded, but the segment register can be marked invalid for memory addressing.
|
||||
[LOADALL](../loadall/) can be used to load the iAPX 86 paragraph ID into the segment register, but the descriptor
|
||||
cache entry is marked invalid. The paragraph ID can still be read without causing a protection exception.
|
||||
|
||||
If a selector value is loaded whose segment overruns the end of the defined physical memory area, the limit field
|
||||
can be set less than 65535 to prevent accesses outside the defined memory area with that segment register.
|
||||
|
|
@ -49,7 +50,7 @@ The emulated iAPX 86/88 address space can be relocated anywhere in the 16 Mbyte
|
|||
adding a 24-bit relocation factor to the 20-bit iAPX 86/88 physical address value associated with the iAPX 86
|
||||
paragraph ID.
|
||||
|
||||
### iAPX 86/88 Interrupt Table Simulation ###
|
||||
#### iAPX 86/88 Interrupt Table Simulation ####
|
||||
|
||||
The [LOADALL](../loadall/) instruction allows a protected mode 80286 to provide a simulated iAPX 86/88 interrupt
|
||||
table to iAPX 86/88 programs. The protected mode iAPX 286 interrupt table is different from iAPX 86/88 since it must
|
||||
|
|
@ -69,13 +70,13 @@ Interrupt handlers for external interrupts can pass control to an iAPX 86 real m
|
|||
interrupt handler for an iAPX 86 interrupt must determine if the interrupt is for a real mode program; if so,
|
||||
then it emulates a real mode interrupt the same way as for the INT instruction.
|
||||
|
||||
### Allowing writes into a code segment ###
|
||||
#### Allowing writes into a code segment ####
|
||||
|
||||
Code segment writes are possible by using writable data segment descriptors for the CS cache entry.
|
||||
Normally the code segment is write protected. If the code segment descriptor is always marked writable,
|
||||
then writes using the CS prefix will work correctly.
|
||||
|
||||
### Allowing temporaries to be placed into segment registers ###
|
||||
#### Allowing temporaries to be placed into segment registers ####
|
||||
|
||||
A temporary value which does not correspond to a valid segment causes exception 13. It is possible to place
|
||||
that value into the program visible segment register, but mark the descriptor cache entry invalid. The invalid
|
||||
|
|
@ -84,10 +85,10 @@ but prevents any memory reference instruction from using the segment register to
|
|||
|
||||
This feature requires an error handler to know that exception 13 with an error code which is an invalid segment
|
||||
selector value indicates a potential temporary value problem. The exception handler must simulate the segment load
|
||||
instruction to place the error code into the appropriate segment register and use [LOADALL](../loadall/) to mark the descriptor
|
||||
cache entry invalid. The program may then be resumed after the segment load instruction.
|
||||
instruction to place the error code into the appropriate segment register and use [LOADALL](../loadall/) to mark the
|
||||
descriptor cache entry invalid. The program may then be resumed after the segment load instruction.
|
||||
|
||||
### Simulating I/O ###
|
||||
#### Simulating I/O ####
|
||||
|
||||
All I/O instructions of the iAPX 86 program can be simulated. When the IOPL (I/O privilege level) is less than
|
||||
the CPL of the simulated iAPX 86 program, exception 13 will occur, with an error code of 0, on IN, OUT, STI, CLI,
|
||||
|
|
@ -98,7 +99,7 @@ The LOCK instruction prefix causes exception 13 when CPL is greater than IOPL. F
|
|||
could be ignored. Restarting the program after the LOCK prefix would be acceptable. In special cases, the LOCKED
|
||||
instruction may need to be run with a lower CPL.
|
||||
|
||||
### Mixing emulated real mode software with native protected mode software ###
|
||||
#### Mixing emulated real mode software with native protected mode software ####
|
||||
|
||||
A system which emulates a real mode program may also run protected mode software. If the GDT and IDT has all
|
||||
entries marked level 2 or less, the emulated program cannot use them if it runs at level 3. The emulated program
|
||||
|
|
@ -114,8 +115,8 @@ reloaded with protected selectors without a protection exception. Interrupting f
|
|||
does not affect interrupt latency.
|
||||
|
||||
Returning from an interrupt requires some checks. The return from the interrupt handler must check whether an
|
||||
iAPX 86 real mode program had been executing. If so, the return sequence must use the [LOADALL](../loadall/) instruction to reload
|
||||
all the registers rather than the normal IRET instruction.
|
||||
iAPX 86 real mode program had been executing. If so, the return sequence must use the [LOADALL](../loadall/)
|
||||
instruction to reload all the registers rather than the normal IRET instruction.
|
||||
|
||||
Depending on the iAPX 86 paragraph IDs used, the IRET instruction might not cause a protection exception on
|
||||
returning to an emulated iAPX 86 program. The CS value of an interrupted iAPX 86 program saved on the stack or
|
||||
|
|
@ -127,7 +128,7 @@ code segment at an incorrect address.
|
|||
The interrupt handler should test whether an emulated iAPX 86 program was executing. An interrupted protected mode
|
||||
program can be restarted in the normal manner while an emulated program requires [LOADALL](../loadall/).
|
||||
|
||||
### Emulating an 8087 with the 80287 ###
|
||||
#### Emulating an 8087 with the 80287 ####
|
||||
|
||||
The instruction and data addresses saved in the protected mode 80287 environment area are in a different format
|
||||
than from the 8087. In real mode, the 80287 environment is in the same format as the 8087. In protected mode,
|
||||
|
|
@ -252,9 +253,9 @@ Extending the Address Space of Current iAPX 86 Software
|
|||
---
|
||||
|
||||
Current iAPX 86 real mode programs can use the extended address space of the iAPX 286 in a limited manner.
|
||||
To address the extended memory, [LOADALL](../loadall/) must be used to load the descriptor cache with an base address beyond
|
||||
the normal 1 Mbyte address range. That segment register must not be changed by software, else the segment register
|
||||
will point back into the 1 Mbyte address space.
|
||||
To address the extended memory, [LOADALL](../loadall/) must be used to load the descriptor cache with an base address
|
||||
beyond the normal 1 Mbyte address range. That segment register must not be changed by software, else the segment
|
||||
register will point back into the 1 Mbyte address space.
|
||||
|
||||
Two types of systems are examined: accessing a single large database in a limited manner, or splitting software
|
||||
into normal and extended areas. The first is the easiest to implement, while the second is more general.
|
||||
|
|
@ -263,24 +264,25 @@ Access to a large data area outside the 1 Mbyte address space could be provided
|
|||
scans the large data structure to locate the necessary item, then copy all data between the normal address space
|
||||
and the extended address space.
|
||||
|
||||
Interrupts must be disabled while the subroutine uses segment registers that have been set by [LOADALL](../loadall/). The reload
|
||||
of segment registers inside an interrupt routine would change the actual physical address from that loaded by [LOADALL](../loadall/)
|
||||
before the interrupt. After all accesses in the extended area are done, interrupts may be enabled.
|
||||
Interrupts must be disabled while the subroutine uses segment registers that have been set by [LOADALL](../loadall/).
|
||||
The reload of segment registers inside an interrupt routine would change the actual physical address from that loaded
|
||||
by [LOADALL](../loadall/) before the interrupt. After all accesses in the extended area are done, interrupts may be
|
||||
enabled.
|
||||
|
||||
Returning the address of an extended data structure requires passing data through a segment register. For example,
|
||||
the ES register could have been changed by [LOADALL](../loadall/) to point at a data area outside the bottom megabyte of physical
|
||||
memory. The subroutine must not reload ES while it runs. The value stored in ES is not important since it is not
|
||||
related to the physical address. Interrupts must not be allowed since the interrupt routine may reload ES.
|
||||
the ES register could have been changed by [LOADALL](../loadall/) to point at a data area outside the bottom megabyte
|
||||
of physical memory. The subroutine must not reload ES while it runs. The value stored in ES is not important since it
|
||||
is not related to the physical address. Interrupts must not be allowed since the interrupt routine may reload ES.
|
||||
|
||||
A second technique uses special paragraph IDs (i.e. FFFFH) to signal that a piece of software is running in extended
|
||||
mode. All interrupt handlers in the system must look when they return to the interrupted program to see if any of the
|
||||
segment registers contain FFFFH. If so, then that segment register points at extended memory. [LOADALL](../loadall/) must be used
|
||||
to load all the registers and the segment base address used last. The [LOADALL](../loadall/) memory area should contain that value
|
||||
left there from the previous usage. Descriptors for the other segment registers with normal paragraph IDs must be
|
||||
constructed before executing [LOADALL](../loadall/).
|
||||
segment registers contain FFFFH. If so, then that segment register points at extended memory. [LOADALL](../loadall/)
|
||||
must be used to load all the registers and the segment base address used last. The [LOADALL](../loadall/) memory area
|
||||
should contain that value left there from the previous usage. Descriptors for the other segment registers with normal
|
||||
paragraph IDs must be constructed before executing [LOADALL](../loadall/).
|
||||
|
||||
A semaphore must be placed around software that writes into the [LOADALL](../loadall/) area such that once written into, the software
|
||||
can execute [LOADALL](../loadall/) without interruption.
|
||||
A semaphore must be placed around software that writes into the [LOADALL](../loadall/) area such that once written into,
|
||||
the software can execute [LOADALL](../loadall/) without interruption.
|
||||
|
||||
Mixing Real Mode and Protected Mode
|
||||
---
|
||||
|
|
@ -290,8 +292,8 @@ bottom megabyte of memory, while others execute in protected mode in the upper 1
|
|||
gate could RESET the 80286, independent of the rest of the system, to force it to enter real mode. A short routine
|
||||
at the power up address could redirect the software to the correct real mode program.
|
||||
|
||||
After executing the real mode program, [LOADALL](../loadall/) could then quickly restart the protected mode software. [LOADALL](../loadall/) can
|
||||
be used as a form of task switch from real mode to a protected mode task.
|
||||
After executing the real mode program, [LOADALL](../loadall/) could then quickly restart the protected mode software.
|
||||
[LOADALL](../loadall/) can be used as a form of task switch from real mode to a protected mode task.
|
||||
|
||||
One operating system could service both the real and protected mode software. Any operating system call from the real
|
||||
mode program would cause a switch to protected mode. The protected mode software could then construct descriptors that
|
||||
|
|
@ -302,3 +304,5 @@ Interrupts must be handled specially. Interrupt handlers for both real mode and
|
|||
times. If an interrupt handler needs to access a data area, that data area must be addressable from both real and
|
||||
protected mode. The real mode interrupt table would be would be kept at location 000000H. The protected mode IDT could
|
||||
be anywhere. [LOADALL](../loadall/) will switch to the protected interrupt table.
|
||||
|
||||
[Return to [Intel 80286 CPU Information](/pubs/pc/reference/intel/80286/)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue