diff --git a/sys/amd64/amd64/locore.S b/sys/amd64/amd64/locore.S index ff28a23bdd51..e788b7cea887 100644 --- a/sys/amd64/amd64/locore.S +++ b/sys/amd64/amd64/locore.S @@ -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) diff --git a/sys/amd64/amd64/locore.s b/sys/amd64/amd64/locore.s index ff28a23bdd51..e788b7cea887 100644 --- a/sys/amd64/amd64/locore.s +++ b/sys/amd64/amd64/locore.s @@ -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) diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s index ff28a23bdd51..e788b7cea887 100644 --- a/sys/i386/i386/locore.s +++ b/sys/i386/i386/locore.s @@ -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) diff --git a/sys/i386/i386/vm86.c b/sys/i386/i386/vm86.c index 0811948abf6d..ff97ea9d11fa 100644 --- a/sys/i386/i386/vm86.c +++ b/sys/i386/i386/vm86.c @@ -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; diff --git a/sys/i386/i386/vm86bios.s b/sys/i386/i386/vm86bios.s index 6b51351905b1..61cd38c35454 100644 --- a/sys/i386/i386/vm86bios.s +++ b/sys/i386/i386/vm86bios.s @@ -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