aboutsummaryrefslogtreecommitdiff
path: root/sys/contrib/x86emu/x86emu.h
blob: ddaeea4df9059ed51c6ed0b9e5e36fc7ec711f9a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*	$NetBSD: x86emu.h,v 1.1 2007/12/01 20:14:10 joerg Exp $	*/
/*	$OpenBSD: x86emu.h,v 1.3 2009/06/06 03:45:05 matthieu Exp $ */
/*	$FreeBSD: src/sys/contrib/x86emu/x86emu.h,v 1.2.2.2.4.1 2010/12/21 17:09:25 kensmith Exp $	*/

/****************************************************************************
*
*  Realmode X86 Emulator Library
*
*  Copyright (C) 1996-1999 SciTech Software, Inc.
*  Copyright (C) David Mosberger-Tang
*  Copyright (C) 1999 Egbert Eich
*  Copyright (C) 2007 Joerg Sonnenberger
*
*  ========================================================================
*
*  Permission to use, copy, modify, distribute, and sell this software and
*  its documentation for any purpose is hereby granted without fee,
*  provided that the above copyright notice appear in all copies and that
*  both that copyright notice and this permission notice appear in
*  supporting documentation, and that the name of the authors not be used
*  in advertising or publicity pertaining to distribution of the software
*  without specific, written prior permission.  The authors makes no
*  representations about the suitability of this software for any purpose.
*  It is provided "as is" without express or implied warranty.
*
*  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
*  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
*  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
*  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
*  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
*  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
*  PERFORMANCE OF THIS SOFTWARE.
*
****************************************************************************/

#ifndef __X86EMU_X86EMU_H
#define __X86EMU_X86EMU_H

#include <sys/types.h>
#include <sys/endian.h>

#ifdef _KERNEL
#include <sys/systm.h>
#include <machine/setjmp.h>
#else
#include <setjmp.h>
#endif

/*
 * General EAX, EBX, ECX, EDX type registers.  Note that for
 * portability, and speed, the issue of byte swapping is not addressed
 * in the registers.  All registers are stored in the default format
 * available on the host machine.  The only critical issue is that the
 * registers should line up EXACTLY in the same manner as they do in
 * the 386.  That is:
 *
 * EAX & 0xff  === AL
 * EAX & 0xffff == AX
 *
 * etc.  The result is that alot of the calculations can then be
 * done using the native instruction set fully.
 */

#ifdef	__BIG_ENDIAN__

struct x86emu_register32 {
	uint32_t e_reg;
};

struct x86emu_register16 {
	uint16_t filler0;
	uint16_t x_reg;
};

struct x86emu_register8 {
	uint8_t filler0, filler1;
	uint8_t h_reg, l_reg;
};

#else /* !__BIG_ENDIAN__ */

struct x86emu_register32 {
	uint32_t e_reg;
};

struct x86emu_register16 {
	uint16_t x_reg;
};

struct x86emu_register8 {
	uint8_t l_reg, h_reg;
};

#endif /* BIG_ENDIAN */

union x86emu_register {
	struct x86emu_register32	I32_reg;
	struct x86emu_register16	I16_reg;
	struct x86emu_register8		I8_reg;
};

struct x86emu_regs {
	uint16_t		register_cs;
	uint16_t		register_ds;
	uint16_t		register_es;
	uint16_t		register_fs;
	uint16_t		register_gs;
	uint16_t		register_ss;
	uint32_t		register_flags;
	union x86emu_register	register_a;
	union x86emu_register	register_b;
	union x86emu_register	register_c;
	union x86emu_register	register_d;

	union x86emu_register	register_sp;
	union x86emu_register	register_bp;
	union x86emu_register	register_si;
	union x86emu_register	register_di;
	union x86emu_register	register_ip;

	/*
	 * MODE contains information on:
	 *  REPE prefix             2 bits  repe,repne
	 *  SEGMENT overrides       5 bits  normal,DS,SS,CS,ES
	 *  Delayed flag set        3 bits  (zero, signed, parity)
	 *  reserved                6 bits
	 *  interrupt #             8 bits  instruction raised interrupt
	 *  BIOS video segregs      4 bits  
	 *  Interrupt Pending       1 bits  
	 *  Extern interrupt        1 bits
	 *  Halted                  1 bits
	 */
	uint32_t		mode;
	volatile int		intr;   /* mask of pending interrupts */
	uint8_t			intno;
	uint8_t			__pad[3];
};

struct x86emu {
	char			*mem_base;
	size_t			mem_size;
	void        		*sys_private;
	struct x86emu_regs	x86;

	jmp_buf		exec_state;

	uint64_t	cur_cycles;

	unsigned int	cur_mod:2;
	unsigned int	cur_rl:3;
	unsigned int	cur_rh:3;
	uint32_t	cur_offset;

	uint8_t  	(*emu_rdb)(struct x86emu *, uint32_t addr);
	uint16_t 	(*emu_rdw)(struct x86emu *, uint32_t addr);
	uint32_t 	(*emu_rdl)(struct x86emu *, uint32_t addr);
	void		(*emu_wrb)(struct x86emu *, uint32_t addr,uint8_t val);
	void		(*emu_wrw)(struct x86emu *, uint32_t addr, uint16_t val);
	void		(*emu_wrl)(struct x86emu *, uint32_t addr, uint32_t val);

	uint8_t  	(*emu_inb)(struct x86emu *, uint16_t addr);
	uint16_t 	(*emu_inw)(struct x86emu *, uint16_t addr);
	uint32_t 	(*emu_inl)(struct x86emu *, uint16_t addr);
	void		(*emu_outb)(struct x86emu *, uint16_t addr, uint8_t val);
	void		(*emu_outw)(struct x86emu *, uint16_t addr, uint16_t val);
	void		(*emu_outl)(struct x86emu *, uint16_t addr, uint32_t val);

	void 		(*_x86emu_intrTab[256])(struct x86emu *, int);
};

__BEGIN_DECLS

void	x86emu_init_default(struct x86emu *);

/* decode.c */

void 	x86emu_exec(struct x86emu *);
void	x86emu_exec_call(struct x86emu *, uint16_t, uint16_t);
void	x86emu_exec_intr(struct x86emu *, uint8_t);
void 	x86emu_halt_sys(struct x86emu *) __dead2;

__END_DECLS

#endif /* __X86EMU_X86EMU_H */