/[gxemul]/trunk/src/include/cpu_x86.h
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/src/include/cpu_x86.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (show annotations)
Mon Oct 8 16:19:23 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 11271 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1055 2005/11/25 22:48:36 debug Exp $
20051031	Adding disassembly support for more ARM instructions (clz,
		smul* etc), and adding a hack to support "new tiny" pages
		for StrongARM.
20051101	Minor documentation updates (NetBSD 2.0.2 -> 2.1, and OpenBSD
		3.7 -> 3.8, and lots of testing).
		Changing from 1-sector PIO mode 0 transfers to 128-sector PIO
		mode 3 (in dev_wdc).
		Various minor ARM dyntrans updates (pc-relative loads from
		within the same page as the instruction are now treated as
		constant "mov").
20051102	Re-enabling instruction combinations (they were accidentally
		disabled).
		Dyntrans TLB entries are now overwritten using a round-robin
		scheme instead of randomly. This increases performance.
		Fixing a typo in file.c (thanks to Chuan-Hua Chang for
		noticing it).
		Experimenting with adding ATAPI support to dev_wdc (to make
		emulated *BSD detect cdroms as cdroms, not harddisks).
20051104	Various minor updates.
20051105	Continuing on the ATAPI emulation. Seems to work well enough
		for a NetBSD/cats installation, but not OpenBSD/cats.
		Various other updates.
20051106	Modifying the -Y command line option to allow scaleup with
		certain graphic controllers (only dev_vga so far), not just
		scaledown.
		Some minor dyntrans cleanups.
20051107	Beginning a cleanup up the PCI subsystem (removing the
		read_register hack, etc).
20051108	Continuing the cleanup; splitting up some pci devices into a
		normal autodev device and some separate pci glue code.
20051109	Continuing on the PCI bus stuff; all old pci_*.c have been
		incorporated into normal devices and/or rewritten as glue code
		only, adding a dummy Intel 82371AB PIIX4 for Malta (not really
		tested yet).
		Minor pckbc fix so that Linux doesn't complain.
		Working on the DEC 21143 NIC (ethernet mac rom stuff mostly).
		Various other minor fixes.
20051110	Some more ARM dyntrans fine-tuning (e.g. some instruction
		combinations (cmps followed by conditional branch within the
		same page) and special cases for DPIs with regform when the
		shifter isn't used).
20051111	ARM dyntrans updates: O(n)->O(1) for just-mark-as-non-
		writable in the generic pc_to_pointers function, and some other
		minor hacks.
		Merging Cobalt and evbmips (Malta) ISA interrupt handling,
		and some minor fixes to allow Linux to accept harddisk irqs.
20051112	Minor device updates (pckbc, dec21143, lpt, ...), most
		importantly fixing the ALI M1543/M5229 so that harddisk irqs
		work with Linux/CATS.
20051113	Some more generalizations of the PCI subsystem.
		Finally took the time to add a hack for SCSI CDROM TOCs; this
		enables OpenBSD to use partition 'a' (as needed by the OpenBSD
		installer), and Windows NT's installer to get a bit further.
		Also fixing dev_wdc to allow Linux to detect ATAPI CDROMs.
		Continuing on the DEC 21143.
20051114	Minor ARM dyntrans tweaks; ARM cmps+branch optimization when
		comparing with 0, and generalizing the xchg instr. comb.
		Adding disassembly of ARM mrrc/mcrr and q{,d}{add,sub}.
20051115	Continuing on various PPC things (BATs, other address trans-
		lation things, various loads/stores, BeBox emulation, etc.).
		Beginning to work on PPC interrupt/exception support.
20051116	Factoring out some code which initializes legacy ISA devices
		from those machines that use them (bus_isa).
		Continuing on PPC interrupt/exception support.
20051117	Minor Malta fixes: RTC year offset = 80, disabling a speed hack
		which caused NetBSD to detect a too fast cpu, and adding a new
		hack to make Linux detect a faster cpu.
		Continuing on the Artesyn PM/PPC emulation mode.
		Adding an Algor emulation skeleton (P4032 and P5064);
		implementing some of the basics.
		Continuing on PPC emulation in general; usage of unimplemented
		SPRs is now easier to track, continuing on memory/exception
		related issues, etc.
20051118	More work on PPC emulation (tgpr0..3, exception handling,
		memory stuff, syscalls, etc.).
20051119	Changing the ARM dyntrans code to mostly use cpu->pc, and not
		necessarily use arm reg 15. Seems to work.
		Various PPC updates; continuing on the PReP emulation mode.
20051120	Adding a workaround/hack to dev_mc146818 to allow NetBSD/prep
		to detect the clock.
20051121	More cleanup of the PCI bus (memory and I/O bases, etc).
		Continuing on various PPC things (decrementer and timebase,
		WDCs on obio (on PReP) use irq 13, not 14/15).
20051122	Continuing on the CPC700 controller (interrupts etc) for PMPPC,
		and on PPC stuff in general.
		Finally! After some bug fixes to the virtual to physical addr
		translation, NetBSD/{prep,pmppc} 2.1 reach userland and are
		stable enough to be interacted with.
		More PCI updates; reverse-endian device access for PowerPC etc.
20051123	Generalizing the IEEE floating point subsystem (moving it out
		from src/cpus/cpu_mips_coproc.c into a new src/float_emul.c).
		Input via slave xterms was sometimes not really working; fixing
		this for ns16550, and a warning message is now displayed if
		multiple non-xterm consoles are active.
		Adding some PPC floating point support, etc.
		Various interrupt related updates (dev_wdc, _ns16550, _8259,
		and the isa32 common code in machine.c).
		NetBSD/prep can now be installed! :-) (Well, with some manual
		commands necessary before running sysinst.) Updating the
		documentation and various other things to reflect this.
20051124	Various minor documentation updates.
		Continuing the work on the DEC 21143 NIC.
20051125	LOTS of work on the 21143. Both OpenBSD and NetBSD work fine
		with it now, except that OpenBSD sometimes gives a time-out
		warning.
		Minor documentation updates.

==============  RELEASE 0.3.7  ==============


1 #ifndef CPU_X86_H
2 #define CPU_X86_H
3
4 /*
5 * Copyright (C) 2005 Anders Gavare. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
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.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 *
31 * $Id: cpu_x86.h,v 1.39 2005/11/16 21:15:19 debug Exp $
32 */
33
34 #include "misc.h"
35
36
37 struct cpu_family;
38
39 #define N_X86_REGS 16
40
41 #define x86_reg_names { \
42 "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", \
43 "08", "09", "10", "11", "12", "13", "14", "15" }
44 #define x86_reg_names_bytes { \
45 "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }
46
47 #define X86_R_AX 0
48 #define X86_R_CX 1
49 #define X86_R_DX 2
50 #define X86_R_BX 3
51 #define X86_R_SP 4
52 #define X86_R_BP 5
53 #define X86_R_SI 6
54 #define X86_R_DI 7
55
56 #define N_X86_SEGS 8
57 /* (All of these 8 are not actually used.) */
58
59 #define X86_S_ES 0
60 #define X86_S_CS 1
61 #define X86_S_SS 2
62 #define X86_S_DS 3
63 #define X86_S_FS 4
64 #define X86_S_GS 5
65
66 #define x86_seg_names { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
67
68 #define N_X86_CREGS 8
69
70 #define N_X86_DREGS 8
71
72 #define x86_cond_names { "o", "b", "z", "be", "s", "p", "l", "le" }
73 #define N_X86_CONDS 8
74
75 #define X86_MODEL_8086 1
76 #define X86_MODEL_80286 2
77 #define X86_MODEL_80386 3
78 #define X86_MODEL_80486 4
79 #define X86_MODEL_PENTIUM 5
80 #define X86_MODEL_AMD64 6
81
82 struct x86_model {
83 int model_number;
84 char *name;
85 };
86
87 #define x86_models { \
88 { X86_MODEL_8086, "8086" }, \
89 { X86_MODEL_80286, "80286" }, \
90 { X86_MODEL_80386, "80386" }, \
91 { X86_MODEL_80486, "80486" }, \
92 { X86_MODEL_PENTIUM, "PENTIUM" }, \
93 { X86_MODEL_AMD64, "AMD64" }, \
94 { 0, NULL } \
95 }
96
97 #define X86_N_IC_ARGS 3
98 #define X86_INSTR_ALIGNMENT_SHIFT 0
99 #define X86_IC_ENTRIES_SHIFT 12
100 #define X86_IC_ENTRIES_PER_PAGE (1 << X86_IC_ENTRIES_SHIFT)
101 #define X86_PC_TO_IC_ENTRY(a) ((a) & (X86_IC_ENTRIES_PER_PAGE-1))
102 #define X86_ADDR_TO_PAGENR(a) ((a) >> X86_IC_ENTRIES_SHIFT)
103
104 struct x86_instr_call {
105 void (*f)(struct cpu *, struct x86_instr_call *);
106 int len;
107 size_t arg[X86_N_IC_ARGS];
108 };
109
110 /* Translation cache struct for each physical page: */
111 struct x86_tc_physpage {
112 struct x86_instr_call ics[X86_IC_ENTRIES_PER_PAGE + 1];
113 uint32_t next_ofs; /* or 0 for end of chain */
114 int flags;
115 uint64_t physaddr;
116 };
117
118 #define X86_N_VPH_ENTRIES 1048576
119
120 #define X86_MAX_VPH_TLB_ENTRIES 256
121 struct x86_vpg_tlb_entry {
122 uint8_t valid;
123 uint8_t writeflag;
124 unsigned char *host_page;
125 int64_t timestamp;
126 uint64_t vaddr_page;
127 uint64_t paddr_page;
128 };
129
130 struct descriptor_cache {
131 int valid;
132 int default_op_size;
133 int access_rights;
134 int descr_type;
135 int readable;
136 int writable;
137 int granularity;
138 uint64_t base;
139 uint64_t limit;
140 };
141
142
143 struct x86_cpu {
144 struct x86_model model;
145
146 int halted;
147 int interrupt_asserted;
148
149 int cursegment; /* NOTE: 0..N_X86_SEGS-1 */
150 int seg_override; /* 0 or 1 */
151
152 uint64_t tsc; /* time stamp counter */
153
154 uint64_t gdtr; /* global descriptor table */
155 uint32_t gdtr_limit;
156 uint64_t idtr; /* interrupt descriptor table */
157 uint32_t idtr_limit;
158
159 uint16_t tr; /* task register */
160 uint64_t tr_base;
161 uint32_t tr_limit;
162 uint16_t ldtr; /* local descriptor table register */
163 uint64_t ldtr_base;
164 uint32_t ldtr_limit;
165
166 uint64_t rflags;
167 uint64_t cr[N_X86_CREGS]; /* control registers */
168 uint64_t dr[N_X86_DREGS]; /* debug registers */
169
170 uint16_t s[N_X86_SEGS]; /* segment selectors */
171 struct descriptor_cache descr_cache[N_X86_SEGS];
172
173 uint64_t r[N_X86_REGS]; /* GPRs */
174
175 /* FPU: */
176 uint16_t fpu_sw; /* status word */
177 uint16_t fpu_cw; /* control word */
178
179 /* MSRs: */
180 uint64_t efer;
181
182
183 /*
184 * Instruction translation cache:
185 */
186
187 /* cur_ic_page is a pointer to an array of X86_IC_ENTRIES_PER_PAGE
188 instruction call entries. next_ic points to the next such
189 call to be executed. */
190 struct x86_tc_physpage *cur_physpage;
191 struct x86_instr_call *cur_ic_page;
192 struct x86_instr_call *next_ic;
193
194 void (*combination_check)(struct cpu *,
195 struct x86_instr_call *, int low_addr);
196
197 /*
198 * Virtual -> physical -> host address translation:
199 *
200 * host_load and host_store point to arrays of X86_N_VPH_ENTRIES
201 * pointers (to host pages); phys_addr points to an array of
202 * X86_N_VPH_ENTRIES uint32_t.
203 */
204
205 struct x86_vpg_tlb_entry vph_tlb_entry[X86_MAX_VPH_TLB_ENTRIES];
206 unsigned char *host_load[X86_N_VPH_ENTRIES];
207 unsigned char *host_store[X86_N_VPH_ENTRIES];
208 uint32_t phys_addr[X86_N_VPH_ENTRIES];
209 struct x86_tc_physpage *phys_page[X86_N_VPH_ENTRIES];
210
211 uint32_t phystranslation[X86_N_VPH_ENTRIES/32];
212 uint8_t vaddr_to_tlbindex[X86_N_VPH_ENTRIES];
213 };
214
215
216 #define X86_FLAGS_CF (1) /* Carry Flag */
217 #define X86_FLAGS_PF (4) /* Parity Flag */
218 #define X86_FLAGS_AF (16) /* Adjust/AuxilaryCarry Flag */
219 #define X86_FLAGS_ZF (64) /* Zero Flag */
220 #define X86_FLAGS_SF (128) /* Sign Flag */
221 #define X86_FLAGS_TF (256) /* Trap Flag */
222 #define X86_FLAGS_IF (512) /* Interrupt Enable Flag */
223 #define X86_FLAGS_DF (1024) /* Direction Flag */
224 #define X86_FLAGS_OF (2048) /* Overflow Flag */
225 /* Bits 12 and 13 are I/O Privilege Level */
226 #define X86_FLAGS_NT (1<<14) /* Nested Task Flag */
227 #define X86_FLAGS_RF (1<<16) /* Resume Flag */
228 #define X86_FLAGS_VM (1<<17) /* VM86 Flag */
229 #define X86_FLAGS_AC (1<<18) /* Alignment Check */
230 #define X86_FLAGS_VIF (1<<19) /* ? */
231 #define X86_FLAGS_VIP (1<<20) /* ? */
232 #define X86_FLAGS_ID (1<<21) /* CPUID present */
233
234 #define X86_CR0_PE 0x00000001 /* Protection Enable */
235 #define X86_CR0_MP 0x00000002
236 #define X86_CR0_EM 0x00000004
237 #define X86_CR0_TS 0x00000008
238 #define X86_CR0_ET 0x00000010
239 #define X86_CR0_NE 0x00000020
240 #define X86_CR0_WP 0x00010000
241 #define X86_CR0_AM 0x00040000
242 #define X86_CR0_NW 0x20000000
243 #define X86_CR0_CD 0x40000000
244 #define X86_CR0_PG 0x80000000 /* Paging Enable */
245
246 #define X86_CR4_OSXMEX 0x00000400
247 #define X86_CR4_OSFXSR 0x00000200
248 #define X86_CR4_PCE 0x00000100
249 #define X86_CR4_PGE 0x00000080
250 #define X86_CR4_MCE 0x00000040
251 #define X86_CR4_PAE 0x00000020
252 #define X86_CR4_PSE 0x00000010
253 #define X86_CR4_DE 0x00000008
254 #define X86_CR4_TSD 0x00000004 /* Time Stamp Disable */
255 #define X86_CR4_PVI 0x00000002
256 #define X86_CR4_VME 0x00000001
257
258 /* EFER bits: */
259 #define X86_EFER_FFXSR 0x00004000
260 #define X86_EFER_LMSLE 0x00002000
261 #define X86_EFER_NXE 0x00000800
262 #define X86_EFER_LMA 0x00000400
263 #define X86_EFER_LME 0x00000100 /* Long Mode (64-bit) */
264 #define X86_EFER_SCE 0x00000001
265
266 /* CPUID feature bits: */
267 #define X86_CPUID_ECX_ETPRD 0x00004000
268 #define X86_CPUID_ECX_CX16 0x00002000 /* cmpxchg16b */
269 #define X86_CPUID_ECX_CID 0x00000400
270 #define X86_CPUID_ECX_TM2 0x00000100
271 #define X86_CPUID_ECX_EST 0x00000080
272 #define X86_CPUID_ECX_DSCPL 0x00000010
273 #define X86_CPUID_ECX_MON 0x00000004
274 #define X86_CPUID_ECX_SSE3 0x00000001
275 #define X86_CPUID_EDX_PBE 0x80000000 /* pending break event */
276 #define X86_CPUID_EDX_IA64 0x40000000
277 #define X86_CPUID_EDX_TM1 0x20000000 /* thermal interrupt */
278 #define X86_CPUID_EDX_HTT 0x10000000 /* hyper threading */
279 #define X86_CPUID_EDX_SS 0x08000000 /* self-snoop */
280 #define X86_CPUID_EDX_SSE2 0x04000000
281 #define X86_CPUID_EDX_SSE 0x02000000
282 #define X86_CPUID_EDX_FXSR 0x01000000
283 #define X86_CPUID_EDX_MMX 0x00800000
284 #define X86_CPUID_EDX_ACPI 0x00400000
285 #define X86_CPUID_EDX_DTES 0x00200000
286 #define X86_CPUID_EDX_CLFL 0x00080000
287 #define X86_CPUID_EDX_PSN 0x00040000
288 #define X86_CPUID_EDX_PSE36 0x00020000
289 #define X86_CPUID_EDX_PAT 0x00010000
290 #define X86_CPUID_EDX_CMOV 0x00008000
291 #define X86_CPUID_EDX_MCA 0x00004000
292 #define X86_CPUID_EDX_PGE 0x00002000 /* global bit in PDE/PTE */
293 #define X86_CPUID_EDX_MTRR 0x00001000
294 #define X86_CPUID_EDX_SEP 0x00000800 /* sysenter/sysexit */
295 #define X86_CPUID_EDX_APIC 0x00000200
296 #define X86_CPUID_EDX_CX8 0x00000100 /* cmpxchg8b */
297 #define X86_CPUID_EDX_MCE 0x00000080
298 #define X86_CPUID_EDX_PAE 0x00000040
299 #define X86_CPUID_EDX_MSR 0x00000020
300 #define X86_CPUID_EDX_TSC 0x00000010
301 #define X86_CPUID_EDX_PSE 0x00000008
302 #define X86_CPUID_EDX_DE 0x00000004
303 #define X86_CPUID_EDX_VME 0x00000002
304 #define X86_CPUID_EDX_FPU 0x00000001
305
306 /* Extended CPUID flags: */
307 #define X86_CPUID_EXT_ECX_CR8D 0x00000010
308 #define X86_CPUID_EXT_ECX_CMP 0x00000002
309 #define X86_CPUID_EXT_ECX_AHF64 0x00000001
310 #define X86_CPUID_EXT_EDX_LM 0x20000000 /* AMD64 Long Mode */
311 #define X86_CPUID_EXT_EDX_FFXSR 0x02000000
312 /* TODO: Many bits are duplicated in the Extended CPUID bits! */
313
314 #define X86_IO_BASE 0x1000000000ULL
315
316 /* Privilege level in the lowest 2 bits of a selector: */
317 #define X86_PL_MASK 0x0003
318 #define X86_RING0 0
319 #define X86_RING1 1
320 #define X86_RING2 2
321 #define X86_RING3 3
322
323 #define DESCR_TYPE_CODE 1
324 #define DESCR_TYPE_DATA 2
325
326
327 #define PROTECTED_MODE (cpu->cd.x86.cr[0] & X86_CR0_PE)
328 #define REAL_MODE (!PROTECTED_MODE)
329
330 /* cpu_x86.c: */
331 void reload_segment_descriptor(struct cpu *cpu, int segnr, int selector,
332 uint64_t *curpcp);
333 int x86_interrupt(struct cpu *cpu, int nr, int errcode);
334 int x86_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
335 unsigned char *data, size_t len, int writeflag, int cache_flags);
336 void x86_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
337 unsigned char *host_page, int writeflag, uint64_t paddr_page);
338 void x8632_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
339 unsigned char *host_page, int writeflag, uint64_t paddr_page);
340 void x86_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
341 void x8632_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
342 void x86_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
343 void x8632_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
344 int x86_cpu_family_init(struct cpu_family *);
345
346
347 /* memory_x86.c: */
348 int x86_translate_address(struct cpu *cpu, uint64_t vaddr,
349 uint64_t *return_addr, int flags);
350
351 #endif /* CPU_X86_H */

  ViewVC Help
Powered by ViewVC 1.1.26