/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 20 - (hide 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 dpavlin 4 #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 dpavlin 20 * $Id: cpu_x86.h,v 1.39 2005/11/16 21:15:19 debug Exp $
32 dpavlin 4 */
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 dpavlin 6 #define x86_reg_names_bytes { \
45     "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh" }
46 dpavlin 4
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 dpavlin 6 #define x86_seg_names { "es", "cs", "ss", "ds", "fs", "gs", "segr6", "segr7" }
67 dpavlin 4
68     #define N_X86_CREGS 8
69    
70 dpavlin 6 #define N_X86_DREGS 8
71    
72 dpavlin 4 #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 dpavlin 6 #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 dpavlin 4
82     struct x86_model {
83     int model_number;
84     char *name;
85     };
86    
87     #define x86_models { \
88     { X86_MODEL_8086, "8086" }, \
89 dpavlin 6 { X86_MODEL_80286, "80286" }, \
90 dpavlin 4 { X86_MODEL_80386, "80386" }, \
91 dpavlin 6 { X86_MODEL_80486, "80486" }, \
92 dpavlin 4 { X86_MODEL_PENTIUM, "PENTIUM" }, \
93     { X86_MODEL_AMD64, "AMD64" }, \
94     { 0, NULL } \
95     }
96    
97 dpavlin 12 #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 dpavlin 4
104 dpavlin 12 struct x86_instr_call {
105     void (*f)(struct cpu *, struct x86_instr_call *);
106 dpavlin 20 int len;
107 dpavlin 12 size_t arg[X86_N_IC_ARGS];
108     };
109    
110     /* Translation cache struct for each physical page: */
111     struct x86_tc_physpage {
112 dpavlin 18 struct x86_instr_call ics[X86_IC_ENTRIES_PER_PAGE + 1];
113 dpavlin 12 uint32_t next_ofs; /* or 0 for end of chain */
114 dpavlin 18 int flags;
115 dpavlin 12 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 dpavlin 20 uint8_t valid;
123     uint8_t writeflag;
124     unsigned char *host_page;
125 dpavlin 12 int64_t timestamp;
126     uint64_t vaddr_page;
127     uint64_t paddr_page;
128     };
129    
130 dpavlin 6 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 dpavlin 4 struct x86_cpu {
144     struct x86_model model;
145    
146 dpavlin 6 int halted;
147     int interrupt_asserted;
148 dpavlin 4
149 dpavlin 6 int cursegment; /* NOTE: 0..N_X86_SEGS-1 */
150     int seg_override; /* 0 or 1 */
151 dpavlin 4
152 dpavlin 6 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 dpavlin 4 uint64_t rflags;
167 dpavlin 6 uint64_t cr[N_X86_CREGS]; /* control registers */
168     uint64_t dr[N_X86_DREGS]; /* debug registers */
169 dpavlin 4
170 dpavlin 6 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 dpavlin 12
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 dpavlin 20 void (*combination_check)(struct cpu *,
195     struct x86_instr_call *, int low_addr);
196 dpavlin 12
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 dpavlin 18
211     uint32_t phystranslation[X86_N_VPH_ENTRIES/32];
212 dpavlin 20 uint8_t vaddr_to_tlbindex[X86_N_VPH_ENTRIES];
213 dpavlin 4 };
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 dpavlin 6 #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 dpavlin 4
234 dpavlin 6 #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 dpavlin 4
246 dpavlin 6 #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 dpavlin 4 /* cpu_x86.c: */
331 dpavlin 6 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 dpavlin 4 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 dpavlin 20 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 dpavlin 4 int x86_cpu_family_init(struct cpu_family *);
345    
346 dpavlin 20
347 dpavlin 14 /* memory_x86.c: */
348     int x86_translate_address(struct cpu *cpu, uint64_t vaddr,
349     uint64_t *return_addr, int flags);
350 dpavlin 4
351     #endif /* CPU_X86_H */

  ViewVC Help
Powered by ViewVC 1.1.26