1 /* $NetBSD: vm86test.c,v 1.2 2003/09/10 15:33:08 drochner Exp $ */
5 * Matthias Drochner. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 #include <sys/types.h>
32 #include <machine/segments.h>
33 #include <machine/sysarch.h>
34 #include <machine/vm86.h>
41 void urghdl(int, siginfo_t
*, void *);
44 * Some code to execute in vm86 mode. Uses INT 0x20 to print some status info
45 * and INT 0x21 to exit.
46 * We don't use an IDT, so the interrupts must be vectored to the user task.
48 const char vmcode
[] = {
60 * XXX before our text segment, must be below 1M to be addressable.
61 * Also chosen to start >=64k, to catch the longstanding kernel bug which
62 * caused the stack segment to be ignored in the !SA_ONSTACK case.
64 #define VMCODEBASE (void *)0x80000
68 urghdl(int sig
, siginfo_t
*si
, void *vuc
)
72 int res
, ip
, eflags
, code
;
74 ip
= uc
->uc_mcontext
.__gregs
[_REG_EIP
];
75 eflags
= uc
->uc_mcontext
.__gregs
[_REG_EFL
];
78 res
= sigaltstack(0, &oss
);
80 err(6, "sigaltstack in handler");
81 fprintf(stderr
, "urghdl called @ip=%04x, code=%04x, ", ip
, code
);
82 fprintf(stderr
, "eflags=%08x, stackflags=%01x\n",
83 eflags
, oss
.ss_flags
);
84 if (code
== VM86_MAKEVAL(VM86_INTx
, 0x21))
88 struct vm86_struct vm
; /* zero inited */
91 main(int argc
, char **argv
)
94 unsigned int codeaddr
;
103 mapaddr
= mmap(VMCODEBASE
, VMSIZE
, PROT_READ
|PROT_WRITE
|PROT_EXEC
,
104 MAP_ANON
|MAP_FIXED
, -1, 0);
105 if (mapaddr
== (void *)-1)
108 memcpy(mapaddr
, vmcode
, sizeof(vmcode
));
110 codeaddr
= (unsigned int)mapaddr
;
111 vm
.substr
.regs
[_REG_CS
] = codeaddr
>> 4;
112 vm
.substr
.regs
[_REG_EIP
] = codeaddr
& 15; /* unnecessary here */
113 vm
.substr
.ss_cpu_type
= VCPU_586
;
114 vm
.int_byuser
[4] = 0x03; /* vector INT 0x20 and 0x21 */
117 ss
.ss_sp
= malloc(SIGSTKSZ
);
118 ss
.ss_size
= SIGSTKSZ
;
120 res
= sigaltstack(&ss
, 0);
122 err (2, "sigaltstack");
124 vm
.substr
.regs
[_REG_SS
] = codeaddr
>> 4;
125 vm
.substr
.regs
[_REG_ESP
] = VMSIZE
- (codeaddr
& 15); /* hmm */
128 sa
.sa_sigaction
= urghdl
;
129 sigemptyset(&sa
.sa_mask
);
130 sa
.sa_flags
= SA_SIGINFO
| (usealtstack
? SA_ONSTACK
: 0);
131 res
= sigaction(SIGURG
, &sa
, 0);
135 res
= i386_vm86(&vm
);