summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjlemon <jlemon@FreeBSD.org>1998-07-27 16:45:05 +0000
committerjlemon <jlemon@FreeBSD.org>1998-07-27 16:45:05 +0000
commitd757cde4ede5b9a44050419d6c70beb820bd8102 (patch)
treef5139dc03745c7891f0b4a500e24e76c3e54086e /sys/i386
parent3f4090e1b74c9bd804e625d65274580eaca5d5cd (diff)
downloadFreeBSD-src-d757cde4ede5b9a44050419d6c70beb820bd8102.zip
FreeBSD-src-d757cde4ede5b9a44050419d6c70beb820bd8102.tar.gz
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.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/locore.s11
-rw-r--r--sys/i386/i386/vm86.c90
-rw-r--r--sys/i386/i386/vm86bios.s42
3 files changed, 87 insertions, 56 deletions
diff --git a/sys/i386/i386/locore.s b/sys/i386/i386/locore.s
index ff28a23..e788b7c 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 0811948..ff97ea9 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 6b51351..61cd38c 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
OpenPOWER on IntegriCloud