Re-arrange the page layout used by vm86_bioscall so that we can
potentially re-use the stack page. Cosmetic cleanup of the code to de-obfuscate it and make it easier to follow. There should be no functional changes in this commit.
This commit is contained in:
parent
3f4090e1b7
commit
d757cde4ed
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
|
||||
* $Id: locore.s,v 1.109 1998/06/21 18:02:34 bde Exp $
|
||||
* $Id: locore.s,v 1.110 1998/06/30 03:01:35 jmg Exp $
|
||||
*
|
||||
* originally from: locore.s, by William F. Jolitz
|
||||
*
|
||||
@ -134,6 +134,8 @@ _proc0paddr: .long 0 /* address of proc 0 address space */
|
||||
p0upa: .long 0 /* phys addr of proc0's UPAGES */
|
||||
|
||||
#ifdef VM86
|
||||
vm86phystk: .long 0 /* PA of vm86/bios stack */
|
||||
|
||||
.globl _vm86paddr, _vm86pa
|
||||
_vm86paddr: .long 0 /* address of vm86 region */
|
||||
_vm86pa: .long 0 /* phys addr of vm86 region */
|
||||
@ -786,7 +788,10 @@ over_symalloc:
|
||||
movl %esi, R(_proc0paddr)
|
||||
|
||||
#ifdef VM86
|
||||
ALLOCPAGES(4) /* IOPAGES + ext + stack */
|
||||
ALLOCPAGES(1) /* vm86/bios stack */
|
||||
movl %esi,R(vm86phystk)
|
||||
|
||||
ALLOCPAGES(3) /* pgtable + ext + IOPAGES */
|
||||
movl %esi,R(_vm86pa)
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(_vm86paddr)
|
||||
@ -860,7 +865,7 @@ map_read_write:
|
||||
|
||||
#ifdef VM86
|
||||
/* Map space for the vm86 region */
|
||||
movl R(_vm86pa), %eax
|
||||
movl R(vm86phystk), %eax
|
||||
movl $4, %ecx
|
||||
fillkptphys($PG_RW)
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
|
||||
* $Id: locore.s,v 1.109 1998/06/21 18:02:34 bde Exp $
|
||||
* $Id: locore.s,v 1.110 1998/06/30 03:01:35 jmg Exp $
|
||||
*
|
||||
* originally from: locore.s, by William F. Jolitz
|
||||
*
|
||||
@ -134,6 +134,8 @@ _proc0paddr: .long 0 /* address of proc 0 address space */
|
||||
p0upa: .long 0 /* phys addr of proc0's UPAGES */
|
||||
|
||||
#ifdef VM86
|
||||
vm86phystk: .long 0 /* PA of vm86/bios stack */
|
||||
|
||||
.globl _vm86paddr, _vm86pa
|
||||
_vm86paddr: .long 0 /* address of vm86 region */
|
||||
_vm86pa: .long 0 /* phys addr of vm86 region */
|
||||
@ -786,7 +788,10 @@ over_symalloc:
|
||||
movl %esi, R(_proc0paddr)
|
||||
|
||||
#ifdef VM86
|
||||
ALLOCPAGES(4) /* IOPAGES + ext + stack */
|
||||
ALLOCPAGES(1) /* vm86/bios stack */
|
||||
movl %esi,R(vm86phystk)
|
||||
|
||||
ALLOCPAGES(3) /* pgtable + ext + IOPAGES */
|
||||
movl %esi,R(_vm86pa)
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(_vm86paddr)
|
||||
@ -860,7 +865,7 @@ map_read_write:
|
||||
|
||||
#ifdef VM86
|
||||
/* Map space for the vm86 region */
|
||||
movl R(_vm86pa), %eax
|
||||
movl R(vm86phystk), %eax
|
||||
movl $4, %ecx
|
||||
fillkptphys($PG_RW)
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
|
||||
* $Id: locore.s,v 1.109 1998/06/21 18:02:34 bde Exp $
|
||||
* $Id: locore.s,v 1.110 1998/06/30 03:01:35 jmg Exp $
|
||||
*
|
||||
* originally from: locore.s, by William F. Jolitz
|
||||
*
|
||||
@ -134,6 +134,8 @@ _proc0paddr: .long 0 /* address of proc 0 address space */
|
||||
p0upa: .long 0 /* phys addr of proc0's UPAGES */
|
||||
|
||||
#ifdef VM86
|
||||
vm86phystk: .long 0 /* PA of vm86/bios stack */
|
||||
|
||||
.globl _vm86paddr, _vm86pa
|
||||
_vm86paddr: .long 0 /* address of vm86 region */
|
||||
_vm86pa: .long 0 /* phys addr of vm86 region */
|
||||
@ -786,7 +788,10 @@ over_symalloc:
|
||||
movl %esi, R(_proc0paddr)
|
||||
|
||||
#ifdef VM86
|
||||
ALLOCPAGES(4) /* IOPAGES + ext + stack */
|
||||
ALLOCPAGES(1) /* vm86/bios stack */
|
||||
movl %esi,R(vm86phystk)
|
||||
|
||||
ALLOCPAGES(3) /* pgtable + ext + IOPAGES */
|
||||
movl %esi,R(_vm86pa)
|
||||
addl $KERNBASE, %esi
|
||||
movl %esi, R(_vm86paddr)
|
||||
@ -860,7 +865,7 @@ map_read_write:
|
||||
|
||||
#ifdef VM86
|
||||
/* Map space for the vm86 region */
|
||||
movl R(_vm86pa), %eax
|
||||
movl R(vm86phystk), %eax
|
||||
movl $4, %ecx
|
||||
fillkptphys($PG_RW)
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: vm86.c,v 1.11 1998/03/24 16:47:12 jlemon Exp $
|
||||
* $Id: vm86.c,v 1.12 1998/04/15 17:45:08 bde Exp $
|
||||
*/
|
||||
|
||||
#include "opt_vm86.h"
|
||||
@ -334,55 +334,71 @@ vm86_emulate(vmf)
|
||||
return (SIGBUS);
|
||||
}
|
||||
|
||||
#define PGTABLE_SIZE ((1024 + 64) * 1024 / PAGE_SIZE)
|
||||
#define INTMAP_SIZE 32
|
||||
#define IOMAP_SIZE ctob(IOPAGES)
|
||||
#define TSS_SIZE \
|
||||
(sizeof(struct pcb_ext) - sizeof(struct segment_descriptor) + \
|
||||
INTMAP_SIZE + IOMAP_SIZE + 1)
|
||||
|
||||
struct vm86_layout {
|
||||
pt_entry_t vml_pgtbl[PGTABLE_SIZE];
|
||||
struct pcb vml_pcb;
|
||||
struct pcb_ext vml_ext;
|
||||
char vml_intmap[INTMAP_SIZE];
|
||||
char vml_iomap[IOMAP_SIZE];
|
||||
char vml_iomap_trailer;
|
||||
};
|
||||
|
||||
static void
|
||||
vm86_initialize(void)
|
||||
{
|
||||
int i, offset;
|
||||
int i;
|
||||
u_long *addr;
|
||||
struct vm86_layout *vml = (struct vm86_layout *)vm86paddr;
|
||||
struct pcb *pcb;
|
||||
struct pcb_ext *ext;
|
||||
struct segment_descriptor sd;
|
||||
struct soft_segment_descriptor ssd = {
|
||||
0, /* segment base address (overwritten) */
|
||||
ctob(IOPAGES + 1) - 1, /* length */
|
||||
0, /* length (overwritten) */
|
||||
SDT_SYS386TSS, /* segment type */
|
||||
0, /* priority level */
|
||||
1, /* descriptor present */
|
||||
0, 0,
|
||||
0, /* default 32 size */
|
||||
0, /* default 16 size */
|
||||
0 /* granularity */
|
||||
};
|
||||
|
||||
/*
|
||||
* this should be a compile time error, but cpp doesn't grok sizeof().
|
||||
*/
|
||||
if (sizeof(struct vm86_layout) > ctob(3))
|
||||
panic("struct vm86_layout exceeds space allocated in locore.s");
|
||||
|
||||
/*
|
||||
* Below is the memory layout that we use for the vm86 region.
|
||||
*
|
||||
* The last byte of the i/o map must be followed by an 0xff byte.
|
||||
* We arbitrarily allocate 16 bytes here, to keep the starting
|
||||
* address on a doubleword boundary.
|
||||
*
|
||||
* If a ~2K stack is enough for interrupt handling, then
|
||||
* it may be possible to get the page count down to 3 pages.
|
||||
*
|
||||
* +--------+ +--------+
|
||||
* | | |Page Tbl| 1M + 64K = 272 entries = 1088 bytes
|
||||
* | | +--------+
|
||||
* | page 0 |
|
||||
* +--------+
|
||||
* | |
|
||||
* | |
|
||||
* | page 0 |
|
||||
* | | +--------+
|
||||
* | | | stack |
|
||||
* +--------+ +--------+
|
||||
* +--------+ +--------+
|
||||
* | | | PCB | size: ~240 bytes
|
||||
* | | |PCB Ext | size: ~140 bytes (includes TSS)
|
||||
* +--------+ +--------+ <--------- vm86paddr
|
||||
* | | |Page Tbl| 1M + 64K = 272 entries = 1088 bytes
|
||||
* | | +--------+
|
||||
* | page 1 |
|
||||
* | | | PCB | size: ~240 bytes
|
||||
* | page 1 | |PCB Ext | size: ~140 bytes (includes TSS)
|
||||
* | | +--------+
|
||||
* | | |int map |
|
||||
* | | +--------+ <-- &(PAGE 1) - 16
|
||||
* | | +--------+
|
||||
* +--------+ | |
|
||||
* | page 2 | | I/O |
|
||||
* +--------+ | bitmap |
|
||||
* | page 3 | | |
|
||||
* +--------+ +--------+
|
||||
* | | +--------+
|
||||
* +--------+
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -398,35 +414,37 @@ vm86_initialize(void)
|
||||
* pcb_fs = saved TSS descriptor, word 0
|
||||
* pcb_gs = saved TSS descriptor, word 1
|
||||
*/
|
||||
#define new_ptd pcb_esi
|
||||
#define vm86_frame pcb_ebp
|
||||
#define pgtable_va pcb_ebx
|
||||
|
||||
pcb = (struct pcb *)(vm86paddr + PAGE_SIZE);
|
||||
bzero(pcb, sizeof(struct pcb));
|
||||
pcb->pcb_esi = vm86pa | PG_V | PG_RW | PG_U;
|
||||
pcb->pcb_ebp = vm86paddr + PAGE_SIZE - sizeof(struct vm86frame);
|
||||
pcb->pcb_ebx = vm86paddr;
|
||||
pcb = &vml->vml_pcb;
|
||||
ext = &vml->vml_ext;
|
||||
|
||||
ext = (struct pcb_ext *)((u_int)pcb + sizeof(struct pcb));
|
||||
bzero(pcb, sizeof(struct pcb));
|
||||
pcb->new_ptd = vm86pa | PG_V | PG_RW | PG_U;
|
||||
pcb->vm86_frame = vm86paddr - sizeof(struct vm86frame);
|
||||
pcb->pgtable_va = vm86paddr;
|
||||
pcb->pcb_ext = ext;
|
||||
|
||||
bzero(ext, sizeof(struct pcb_ext));
|
||||
ext->ext_tss.tss_esp0 = vm86paddr + PAGE_SIZE;
|
||||
ext->ext_tss.tss_esp0 = vm86paddr;
|
||||
ext->ext_tss.tss_ss0 = GSEL(GDATA_SEL, SEL_KPL);
|
||||
|
||||
offset = PAGE_SIZE - 16;
|
||||
ext->ext_tss.tss_ioopt =
|
||||
(offset - ((u_int)&ext->ext_tss & PAGE_MASK)) << 16;
|
||||
ext->ext_iomap = (caddr_t)(offset + ((u_int)&ext->ext_tss & PG_FRAME));
|
||||
((u_int)vml->vml_iomap - (u_int)&ext->ext_tss) << 16;
|
||||
ext->ext_iomap = vml->vml_iomap;
|
||||
ext->ext_vm86.vm86_intmap = vml->vml_intmap;
|
||||
|
||||
ext->ext_vm86.vm86_intmap = ext->ext_iomap - 32;
|
||||
if (cpu_feature & CPUID_VME)
|
||||
ext->ext_vm86.vm86_has_vme = (rcr4() & CR4_VME ? 1 : 0);
|
||||
|
||||
addr = (u_long *)ext->ext_vm86.vm86_intmap;
|
||||
for (i = 0; i < (ctob(IOPAGES) + 32 + 16) / sizeof(u_long); i++)
|
||||
for (i = 0; i < (INTMAP_SIZE + IOMAP_SIZE) / sizeof(u_long); i++)
|
||||
*addr++ = 0;
|
||||
vml->vml_iomap_trailer = 0xff;
|
||||
|
||||
ssd.ssd_base = (u_int)&ext->ext_tss;
|
||||
ssd.ssd_limit -= ((u_int)&ext->ext_tss & PAGE_MASK);
|
||||
ssd.ssd_limit = TSS_SIZE - 1;
|
||||
ssdtosd(&ssd, &ext->ext_tssd);
|
||||
|
||||
vm86pcb = pcb;
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: vm86bios.s,v 1.1 1998/03/23 19:52:39 jlemon Exp $
|
||||
* $Id: vm86bios.s,v 1.2 1998/03/24 16:51:36 jlemon Exp $
|
||||
*/
|
||||
|
||||
#include "opt_vm86.h"
|
||||
@ -33,6 +33,14 @@
|
||||
|
||||
#include "assym.s"
|
||||
|
||||
#define SCR_NEWPTD PCB_ESI /* readability macros */
|
||||
#define SCR_VMFRAME PCB_EBP /* see vm86.c for explanation */
|
||||
#define SCR_STACK PCB_ESP
|
||||
#define SCR_PGTABLE PCB_EBX
|
||||
#define SCR_ARGFRAME PCB_EIP
|
||||
#define SCR_TSS0 PCB_FS
|
||||
#define SCR_TSS1 PCB_GS
|
||||
|
||||
.data
|
||||
ALIGN_DATA
|
||||
|
||||
@ -47,9 +55,9 @@ _vm86pcb: .long 0
|
||||
* vm86_bioscall(struct trapframe_vm86 *vm86)
|
||||
*/
|
||||
ENTRY(vm86_bioscall)
|
||||
movl _vm86pcb,%edx /* data area, see vm86.c for layout */
|
||||
movl _vm86pcb,%edx /* scratch data area */
|
||||
movl 4(%esp),%eax
|
||||
movl %eax,PCB_EIP(%edx) /* save argument pointer */
|
||||
movl %eax,SCR_ARGFRAME(%edx) /* save argument pointer */
|
||||
pushl %ebx
|
||||
pushl %ebp
|
||||
pushl %esi
|
||||
@ -78,9 +86,9 @@ ENTRY(vm86_bioscall)
|
||||
#endif
|
||||
|
||||
1:
|
||||
movl PCB_EBP(%edx),%ebx /* target frame location */
|
||||
movl SCR_VMFRAME(%edx),%ebx /* target frame location */
|
||||
movl %ebx,%edi /* destination */
|
||||
movl PCB_EIP(%edx),%esi /* source (set on entry) */
|
||||
movl SCR_ARGFRAME(%edx),%esi /* source (set on entry) */
|
||||
movl $21,%ecx /* sizeof(struct vm86frame)/4 */
|
||||
cld
|
||||
rep
|
||||
@ -95,7 +103,7 @@ ENTRY(vm86_bioscall)
|
||||
orl $PG_V|PG_RW|PG_U,%ebx /* XXX assembler error?? */
|
||||
#endif
|
||||
orl $0x7,%ebx
|
||||
movl PCB_EBX(%edx),%eax /* va of vm86 page table */
|
||||
movl SCR_PGTABLE(%edx),%eax /* va of vm86 page table */
|
||||
movl %ebx,4(%eax) /* set vm86 PTE entry 1 */
|
||||
1:
|
||||
movl _curpcb,%eax
|
||||
@ -106,10 +114,10 @@ ENTRY(vm86_bioscall)
|
||||
movl _my_tr,%esi
|
||||
leal _gdt(,%esi,8),%ebx /* entry in GDT */
|
||||
movl 0(%ebx),%eax
|
||||
movl %eax,PCB_FS(%edx) /* save first word */
|
||||
movl %eax,SCR_TSS0(%edx) /* save first word */
|
||||
movl 4(%ebx),%eax
|
||||
andl $~0x200, %eax /* flip 386BSY -> 386TSS */
|
||||
movl %eax,PCB_GS(%edx) /* save second word */
|
||||
movl %eax,SCR_TSS1(%edx) /* save second word */
|
||||
|
||||
movl PCB_EXT(%edx),%edi /* vm86 tssd entry */
|
||||
movl 0(%edi),%eax
|
||||
@ -132,13 +140,13 @@ ENTRY(vm86_bioscall)
|
||||
pushl %eax /* old ptde != 0 when booting */
|
||||
pushl %ebx /* keep for reuse */
|
||||
|
||||
movl %esp,PCB_ESP(%edx) /* save current stack location */
|
||||
movl %esp,SCR_STACK(%edx) /* save current stack location */
|
||||
|
||||
movl PCB_ESI(%edx),%eax /* mapping for vm86 page table */
|
||||
movl SCR_NEWPTD(%edx),%eax /* mapping for vm86 page table */
|
||||
movl %eax,0(%ebx) /* ... install as PTD entry 0 */
|
||||
|
||||
movl %ecx,%cr3 /* new page tables */
|
||||
movl PCB_EBP(%edx),%esp /* switch to new stack */
|
||||
movl SCR_VMFRAME(%edx),%esp /* switch to new stack */
|
||||
|
||||
call _vm86_prepcall /* finish setup */
|
||||
|
||||
@ -170,13 +178,13 @@ ENTRY(vm86_biosret)
|
||||
movl _vm86pcb,%edx /* data area */
|
||||
|
||||
movl 4(%esp),%esi /* source */
|
||||
movl PCB_EIP(%edx),%edi /* destination */
|
||||
movl SCR_ARGFRAME(%edx),%edi /* destination */
|
||||
movl $21,%ecx /* size */
|
||||
cld
|
||||
rep
|
||||
movsl /* copy frame to original frame */
|
||||
|
||||
movl PCB_ESP(%edx),%esp /* back to old stack */
|
||||
movl SCR_STACK(%edx),%esp /* back to old stack */
|
||||
popl %ebx /* saved va of Idle PTD */
|
||||
popl %eax
|
||||
movl %eax,0(%ebx) /* restore old pte */
|
||||
@ -184,21 +192,21 @@ ENTRY(vm86_biosret)
|
||||
movl %eax,%cr3 /* install old page table */
|
||||
|
||||
movl $0,_in_vm86call /* reset trapflag */
|
||||
movl PCB_EBX(%edx),%ebx /* va of vm86 page table */
|
||||
movl SCR_PGTABLE(%edx),%ebx /* va of vm86 page table */
|
||||
movl $0,4(%ebx) /* ...clear entry 1 */
|
||||
|
||||
movl _my_tr,%esi
|
||||
leal _gdt(,%esi,8),%ebx /* entry in GDT */
|
||||
movl PCB_FS(%edx),%eax
|
||||
movl SCR_TSS0(%edx),%eax
|
||||
movl %eax,0(%ebx) /* restore first word */
|
||||
movl PCB_GS(%edx),%eax
|
||||
movl SCR_TSS1(%edx),%eax
|
||||
movl %eax,4(%ebx) /* restore second word */
|
||||
shll $3,%esi /* GSEL(entry, SEL_KPL) */
|
||||
ltr %si
|
||||
|
||||
popl _curpcb /* restore curpcb/curproc */
|
||||
popl _curproc
|
||||
movl PCB_EIP(%edx),%edx /* original stack frame */
|
||||
movl SCR_ARGFRAME(%edx),%edx /* original stack frame */
|
||||
movl TF_TRAPNO(%edx),%eax /* return (trapno) */
|
||||
|
||||
popl %gs
|
||||
|
Loading…
Reference in New Issue
Block a user