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:
jlemon 1998-07-27 16:45:05 +00:00
parent 3f4090e1b7
commit d757cde4ed
5 changed files with 103 additions and 62 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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