Sync usage with man page.
[netbsd-mini2440.git] / regress / sys / arch / i386 / vm86 / vm86test.c
bloba77af37a8400b25b6b44fd45c9bd7a8dfd53e814
1 /* $NetBSD: vm86test.c,v 1.2 2003/09/10 15:33:08 drochner Exp $ */
3 /*
4 * Copyright (c) 2003
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
9 * are met:
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
26 * SUCH DAMAGE.
29 #include <sys/types.h>
30 #include <signal.h>
31 #include <ucontext.h>
32 #include <machine/segments.h>
33 #include <machine/sysarch.h>
34 #include <machine/vm86.h>
35 #include <sys/mman.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <err.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[] = {
49 0xcd, /* INTxx */
50 0x20,
51 0xfb, /* STI */
52 0xcd, /* INTxx */
53 0x20,
54 0xfa, /* CLI */
55 0xcd, /* INTxx */
56 0x21,
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
65 #define VMSIZE 0x4000
67 void
68 urghdl(int sig, siginfo_t *si, void *vuc)
70 stack_t oss;
71 ucontext_t *uc = vuc;
72 int res, ip, eflags, code;
74 ip = uc->uc_mcontext.__gregs[_REG_EIP];
75 eflags = uc->uc_mcontext.__gregs[_REG_EFL];
76 code = si->si_trap;
78 res = sigaltstack(0, &oss);
79 if (res < 0)
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))
85 exit (0);
88 struct vm86_struct vm; /* zero inited */
90 int
91 main(int argc, char **argv)
93 void *mapaddr;
94 unsigned int codeaddr;
95 struct sigaction sa;
96 int usealtstack, res;
97 stack_t ss;
99 usealtstack = 0;
100 if (argc > 1)
101 usealtstack = 1;
103 mapaddr = mmap(VMCODEBASE, VMSIZE, PROT_READ|PROT_WRITE|PROT_EXEC,
104 MAP_ANON|MAP_FIXED, -1, 0);
105 if (mapaddr == (void *)-1)
106 err(1, "mmap");
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 */
116 if (usealtstack) {
117 ss.ss_sp = malloc(SIGSTKSZ);
118 ss.ss_size = SIGSTKSZ;
119 ss.ss_flags = 0;
120 res = sigaltstack(&ss, 0);
121 if (res < 0)
122 err (2, "sigaltstack");
123 } else {
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);
132 if (res < 0)
133 err(3, "sigaction");
135 res = i386_vm86(&vm);
136 if (res < 0)
137 err(4, "vm86");
139 /* NOTREACHED */
140 exit (5);