summaryrefslogtreecommitdiffstats
path: root/drivers/bios_emulator/include/x86emu/regs.h
blob: a7fedd2f6ca1caa7d56de1cf54bec54300bdb872 (plain)
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/****************************************************************************
*
*			Realmode X86 Emulator Library
*
*		Copyright (C) 1991-2004 SciTech Software, Inc.
*		     Copyright (C) David Mosberger-Tang
*		       Copyright (C) 1999 Egbert Eich
*
*  ========================================================================
*
*  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.
*
*  ========================================================================
*
* Language:	ANSI C
* Environment:	Any
* Developer:	Kendall Bennett
*
* Description:	Header file for x86 register definitions.
*
****************************************************************************/

#ifndef __X86EMU_REGS_H
#define __X86EMU_REGS_H

/*---------------------- Macros and type definitions ----------------------*/

#pragma pack(1)

/*
 * 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__

typedef struct {
	u32 e_reg;
} I32_reg_t;

typedef struct {
	u16 filler0, x_reg;
} I16_reg_t;

typedef struct {
	u8 filler0, filler1, h_reg, l_reg;
} I8_reg_t;

#else				/* !__BIG_ENDIAN__ */

typedef struct {
	u32 e_reg;
} I32_reg_t;

typedef struct {
	u16 x_reg;
} I16_reg_t;

typedef struct {
	u8 l_reg, h_reg;
} I8_reg_t;

#endif				/* BIG_ENDIAN */

typedef union {
	I32_reg_t I32_reg;
	I16_reg_t I16_reg;
	I8_reg_t I8_reg;
} i386_general_register;

struct i386_general_regs {
	i386_general_register A, B, C, D;
};

typedef struct i386_general_regs Gen_reg_t;

struct i386_special_regs {
	i386_general_register SP, BP, SI, DI, IP;
	u32 FLAGS;
};

/*
 * Segment registers here represent the 16 bit quantities
 * CS, DS, ES, SS.
 */

#undef CS
#undef DS
#undef SS
#undef ES
#undef FS
#undef GS

struct i386_segment_regs {
	u16 CS, DS, SS, ES, FS, GS;
};

/* 8 bit registers */
#define R_AH  gen.A.I8_reg.h_reg
#define R_AL  gen.A.I8_reg.l_reg
#define R_BH  gen.B.I8_reg.h_reg
#define R_BL  gen.B.I8_reg.l_reg
#define R_CH  gen.C.I8_reg.h_reg
#define R_CL  gen.C.I8_reg.l_reg
#define R_DH  gen.D.I8_reg.h_reg
#define R_DL  gen.D.I8_reg.l_reg

/* 16 bit registers */
#define R_AX  gen.A.I16_reg.x_reg
#define R_BX  gen.B.I16_reg.x_reg
#define R_CX  gen.C.I16_reg.x_reg
#define R_DX  gen.D.I16_reg.x_reg

/* 32 bit extended registers */
#define R_EAX  gen.A.I32_reg.e_reg
#define R_EBX  gen.B.I32_reg.e_reg
#define R_ECX  gen.C.I32_reg.e_reg
#define R_EDX  gen.D.I32_reg.e_reg

/* special registers */
#define R_SP  spc.SP.I16_reg.x_reg
#define R_BP  spc.BP.I16_reg.x_reg
#define R_SI  spc.SI.I16_reg.x_reg
#define R_DI  spc.DI.I16_reg.x_reg
#define R_IP  spc.IP.I16_reg.x_reg
#define R_FLG spc.FLAGS

/* special registers */
#define R_SP  spc.SP.I16_reg.x_reg
#define R_BP  spc.BP.I16_reg.x_reg
#define R_SI  spc.SI.I16_reg.x_reg
#define R_DI  spc.DI.I16_reg.x_reg
#define R_IP  spc.IP.I16_reg.x_reg
#define R_FLG spc.FLAGS

/* special registers */
#define R_ESP  spc.SP.I32_reg.e_reg
#define R_EBP  spc.BP.I32_reg.e_reg
#define R_ESI  spc.SI.I32_reg.e_reg
#define R_EDI  spc.DI.I32_reg.e_reg
#define R_EIP  spc.IP.I32_reg.e_reg
#define R_EFLG spc.FLAGS

/* segment registers */
#define R_CS  seg.CS
#define R_DS  seg.DS
#define R_SS  seg.SS
#define R_ES  seg.ES
#define R_FS  seg.FS
#define R_GS  seg.GS

/* flag conditions   */
#define FB_CF 0x0001		/* CARRY flag  */
#define FB_PF 0x0004		/* PARITY flag */
#define FB_AF 0x0010		/* AUX	flag   */
#define FB_ZF 0x0040		/* ZERO flag   */
#define FB_SF 0x0080		/* SIGN flag   */
#define FB_TF 0x0100		/* TRAP flag   */
#define FB_IF 0x0200		/* INTERRUPT ENABLE flag */
#define FB_DF 0x0400		/* DIR flag    */
#define FB_OF 0x0800		/* OVERFLOW flag */

/* 80286 and above always have bit#1 set */
#define F_ALWAYS_ON  (0x0002)	/* flag bits always on */

/*
 * Define a mask for only those flag bits we will ever pass back
 * (via PUSHF)
 */
#define F_MSK (FB_CF|FB_PF|FB_AF|FB_ZF|FB_SF|FB_TF|FB_IF|FB_DF|FB_OF)

/* following bits masked in to a 16bit quantity */

#define F_CF 0x0001		/* CARRY flag  */
#define F_PF 0x0004		/* PARITY flag */
#define F_AF 0x0010		/* AUX	flag   */
#define F_ZF 0x0040		/* ZERO flag   */
#define F_SF 0x0080		/* SIGN flag   */
#define F_TF 0x0100		/* TRAP flag   */
#define F_IF 0x0200		/* INTERRUPT ENABLE flag */
#define F_DF 0x0400		/* DIR flag    */
#define F_OF 0x0800		/* OVERFLOW flag */

#define TOGGLE_FLAG(flag)	(M.x86.R_FLG ^= (flag))
#define SET_FLAG(flag)		(M.x86.R_FLG |= (flag))
#define CLEAR_FLAG(flag)	(M.x86.R_FLG &= ~(flag))
#define ACCESS_FLAG(flag)	(M.x86.R_FLG & (flag))
#define CLEARALL_FLAG(m)	(M.x86.R_FLG = 0)

#define CONDITIONAL_SET_FLAG(COND,FLAG) \
  if (COND) SET_FLAG(FLAG); else CLEAR_FLAG(FLAG)

#define F_PF_CALC 0x010000	/* PARITY flag has been calced	  */
#define F_ZF_CALC 0x020000	/* ZERO flag has been calced	  */
#define F_SF_CALC 0x040000	/* SIGN flag has been calced	  */

#define F_ALL_CALC	0xff0000	/* All have been calced	  */

/*
 * Emulator machine state.
 * Segment usage control.
 */
#define SYSMODE_SEG_DS_SS	0x00000001
#define SYSMODE_SEGOVR_CS	0x00000002
#define SYSMODE_SEGOVR_DS	0x00000004
#define SYSMODE_SEGOVR_ES	0x00000008
#define SYSMODE_SEGOVR_FS	0x00000010
#define SYSMODE_SEGOVR_GS	0x00000020
#define SYSMODE_SEGOVR_SS	0x00000040
#define SYSMODE_PREFIX_REPE	0x00000080
#define SYSMODE_PREFIX_REPNE	0x00000100
#define SYSMODE_PREFIX_DATA	0x00000200
#define SYSMODE_PREFIX_ADDR	0x00000400
#define SYSMODE_INTR_PENDING	0x10000000
#define SYSMODE_EXTRN_INTR	0x20000000
#define SYSMODE_HALTED		0x40000000

#define SYSMODE_SEGMASK (SYSMODE_SEG_DS_SS	| \
			 SYSMODE_SEGOVR_CS	| \
			 SYSMODE_SEGOVR_DS	| \
			 SYSMODE_SEGOVR_ES	| \
			 SYSMODE_SEGOVR_FS	| \
			 SYSMODE_SEGOVR_GS	| \
			 SYSMODE_SEGOVR_SS)
#define SYSMODE_CLRMASK (SYSMODE_SEG_DS_SS	| \
			 SYSMODE_SEGOVR_CS	| \
			 SYSMODE_SEGOVR_DS	| \
			 SYSMODE_SEGOVR_ES	| \
			 SYSMODE_SEGOVR_FS	| \
			 SYSMODE_SEGOVR_GS	| \
			 SYSMODE_SEGOVR_SS	| \
			 SYSMODE_PREFIX_DATA	| \
			 SYSMODE_PREFIX_ADDR)

#define	 INTR_SYNCH	      0x1
#define	 INTR_ASYNCH	      0x2
#define	 INTR_HALTED	      0x4

typedef struct {
	struct i386_general_regs gen;
	struct i386_special_regs spc;
	struct i386_segment_regs seg;
	/*
	 * 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
	 */
	long mode;
	u8 intno;
	volatile int intr;	/* mask of pending interrupts */
	int debug;
#ifdef DEBUG
	int check;
	u16 saved_ip;
	u16 saved_cs;
	int enc_pos;
	int enc_str_pos;
	char decode_buf[32];	/* encoded byte stream	*/
	char decoded_buf[256];	/* disassembled strings */
#endif
} X86EMU_regs;

/****************************************************************************
REMARKS:
Structure maintaining the emulator machine state.

MEMBERS:
x86		- X86 registers
mem_base	- Base real mode memory for the emulator
mem_size	- Size of the real mode memory block for the emulator
****************************************************************************/
#undef x86
typedef struct {
	X86EMU_regs x86;
	u8 *mem_base;
	u32 mem_size;
	void *private;
} X86EMU_sysEnv;

#pragma pack()

/*----------------------------- Global Variables --------------------------*/

#ifdef	__cplusplus
extern "C" {			/* Use "C" linkage when in C++ mode */
#endif

/* Global emulator machine state.
 *
 * We keep it global to avoid pointer dereferences in the code for speed.
 */

	extern X86EMU_sysEnv _X86EMU_env;
#define	  M		_X86EMU_env

/*-------------------------- Function Prototypes --------------------------*/

/* Function to log information at runtime */

#ifndef __KERNEL__
	void printk(const char *fmt, ...);
#endif

#ifdef	__cplusplus
}				/* End of "C" linkage for C++	    */
#endif
#endif				/* __X86EMU_REGS_H */
OpenPOWER on IntegriCloud