1/* $NetBSD: x86emu.h,v 1.1 2007/12/01 20:14:10 joerg Exp $ */
2
3/****************************************************************************
4*
5* Realmode X86 Emulator Library
6*
7* Copyright (C) 1996-1999 SciTech Software, Inc.
8* Copyright (C) David Mosberger-Tang
9* Copyright (C) 1999 Egbert Eich
10* Copyright (C) 2007 Joerg Sonnenberger
11*
12* ========================================================================
13*
14* Permission to use, copy, modify, distribute, and sell this software and
15* its documentation for any purpose is hereby granted without fee,
16* provided that the above copyright notice appear in all copies and that
17* both that copyright notice and this permission notice appear in
18* supporting documentation, and that the name of the authors not be used
19* in advertising or publicity pertaining to distribution of the software
20* without specific, written prior permission. The authors makes no
21* representations about the suitability of this software for any purpose.
22* It is provided "as is" without express or implied warranty.
23*
24* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
26* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
28* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30* PERFORMANCE OF THIS SOFTWARE.
31*
32****************************************************************************/
33
34#ifndef __X86EMU_X86EMU_H
35#define __X86EMU_X86EMU_H
36
37#include <sys/types.h>
38#include <sys/endian.h>
39
40#ifdef _KERNEL
41#include <sys/systm.h>
42#else
43#include <setjmp.h>
44#endif
45
46/*
47 * General EAX, EBX, ECX, EDX type registers. Note that for
48 * portability, and speed, the issue of byte swapping is not addressed
49 * in the registers. All registers are stored in the default format
50 * available on the host machine. The only critical issue is that the
51 * registers should line up EXACTLY in the same manner as they do in
52 * the 386. That is:
53 *
54 * EAX & 0xff === AL
55 * EAX & 0xffff == AX
56 *
57 * etc. The result is that alot of the calculations can then be
58 * done using the native instruction set fully.
59 */
60
61#ifdef __BIG_ENDIAN__
62
63struct X86EMU_register32 {
64 uint32_t e_reg;
65};
66
67struct X86EMU_register16 {
68 uint16_t filler0;
69 uint16_t x_reg;
70};
71
72struct X86EMU_register8 {
73 uint8_t filler0, filler1;
74 uint8_t h_reg, l_reg;
75};
76
77#else /* !__BIG_ENDIAN__ */
78
79struct X86EMU_register32 {
80 uint32_t e_reg;
81};
82
83struct X86EMU_register16 {
84 uint16_t x_reg;
85};
86
87struct X86EMU_register8 {
88 uint8_t l_reg, h_reg;
89};
90
91#endif /* BIG_ENDIAN */
92
93union X86EMU_register {
94 struct X86EMU_register32 I32_reg;
95 struct X86EMU_register16 I16_reg;
96 struct X86EMU_register8 I8_reg;
97};
98
99struct X86EMU_regs {
100 uint16_t register_cs;
101 uint16_t register_ds;
102 uint16_t register_es;
103 uint16_t register_fs;
104 uint16_t register_gs;
105 uint16_t register_ss;
106 uint32_t register_flags;
107 union X86EMU_register register_a;
108 union X86EMU_register register_b;
109 union X86EMU_register register_c;
110 union X86EMU_register register_d;
111
112 union X86EMU_register register_sp;
113 union X86EMU_register register_bp;
114 union X86EMU_register register_si;
115 union X86EMU_register register_di;
116 union X86EMU_register register_ip;
117
118 /*
119 * MODE contains information on:
120 * REPE prefix 2 bits repe,repne
121 * SEGMENT overrides 5 bits normal,DS,SS,CS,ES
122 * Delayed flag set 3 bits (zero, signed, parity)
123 * reserved 6 bits
124 * interrupt # 8 bits instruction raised interrupt
125 * BIOS video segregs 4 bits
126 * Interrupt Pending 1 bits
127 * Extern interrupt 1 bits
128 * Halted 1 bits
129 */
130 uint32_t mode;
131 volatile int intr; /* mask of pending interrupts */
132 uint8_t intno;
133 uint8_t __pad[3];
134};
135
136struct X86EMU {
137 char *mem_base;
138 size_t mem_size;
139 void *sys_private;
140 struct X86EMU_regs x86;
141
142#ifdef _KERNEL
143 label_t exec_state;
144#else
145 jmp_buf exec_state;
146#endif
147
148 uint64_t cur_cycles;
149
150 unsigned int cur_mod:2;
151 unsigned int cur_rl:3;
152 unsigned int cur_rh:3;
153 uint32_t cur_offset;
154
155 uint8_t (*emu_rdb)(struct X86EMU *, uint32_t addr);
156 uint16_t (*emu_rdw)(struct X86EMU *, uint32_t addr);
157 uint32_t (*emu_rdl)(struct X86EMU *, uint32_t addr);
158 void (*emu_wrb)(struct X86EMU *, uint32_t addr,uint8_t val);
159 void (*emu_wrw)(struct X86EMU *, uint32_t addr, uint16_t val);
160 void (*emu_wrl)(struct X86EMU *, uint32_t addr, uint32_t val);
161
162 uint8_t (*emu_inb)(struct X86EMU *, uint16_t addr);
163 uint16_t (*emu_inw)(struct X86EMU *, uint16_t addr);
164 uint32_t (*emu_inl)(struct X86EMU *, uint16_t addr);
165 void (*emu_outb)(struct X86EMU *, uint16_t addr, uint8_t val);
166 void (*emu_outw)(struct X86EMU *, uint16_t addr, uint16_t val);
167 void (*emu_outl)(struct X86EMU *, uint16_t addr, uint32_t val);
168
169 void (*_X86EMU_intrTab[256])(struct X86EMU *, int);
170};
171
172__BEGIN_DECLS
173
174void X86EMU_init_default(struct X86EMU *);
175
176/* decode.c */
177
178void X86EMU_exec(struct X86EMU *);
179void X86EMU_exec_call(struct X86EMU *, uint16_t, uint16_t);
180void X86EMU_exec_intr(struct X86EMU *, uint8_t);
181void X86EMU_halt_sys(struct X86EMU *) __dead;
182
183__END_DECLS
184
185#endif /* __X86EMU_X86EMU_H */
186