1 #ifndef	CPU_PPC_H
2 #define	CPU_PPC_H
3 
4 /*
5  *  Copyright (C) 2005-2012  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  *  POWER and PowerPC CPU definitions.
32  */
33 
34 #include "misc.h"
35 
36 
37 struct cpu_family;
38 
39 #define	MODE_PPC		0
40 #define	MODE_POWER		1
41 
42 /*  PPC CPU types:  */
43 struct ppc_cpu_type_def {
44 	const char	*name;
45 	int		pvr;
46 	int		bits;
47 	int		flags;
48 	int		icache_shift;
49 	int		ilinesize;
50 	int		iway;
51 	int		dcache_shift;
52 	int		dlinesize;
53 	int		dway;
54 	int		l2cache_shift;
55 	int		l2linesize;
56 	int		l2way;
57 	int		altivec;
58 
59 	/*  TODO: POWER vs PowerPC?  */
60 };
61 
62 /*  Flags:  */
63 #define	PPC_NOFP		1
64 #define	PPC_601			2
65 #define	PPC_603			4
66 #define	PPC_NO_DEC		8	/*  No DEC (decrementer) SPR  */
67 
68 /*
69  *  TODO: Most of these just bogus
70  */
71 
72 #define PPC_CPU_TYPE_DEFS	{					\
73 	{ "PPC405GP",	0x40110000, 32, PPC_NOFP|PPC_NO_DEC,		\
74 					13,5,2, 13,5,2, 0,5,1, 0 },	\
75 	{ "PPC601",	0,          32, PPC_601, 14,5,4, 14,5,4, 0,0,0, 0 },\
76 	{ "PPC603",	0x00030302, 32, PPC_603, 14,5,4, 14,5,4, 0,0,0, 0 },\
77 	{ "PPC603e",	0x00060104, 32, PPC_603, 14,5,4, 14,5,4, 0,0,0, 0 },\
78 	{ "PPC604",	0x00040304, 32, 0, 15,5,4, 15,5,4, 0,0,0, 0 },	\
79 	{ "PPC620",	0x00140000, 64, 0, 15,5,4, 15,5,4, 0,0,0, 0 },	\
80 	{ "MPC7400",	0x000c0000, 32, 0, 15,5,2, 15,5,2, 19,5,1, 1 },	\
81 	{ "PPC750",	0x00084202, 32, 0, 15,5,2, 15,5,2, 20,5,1, 0 },	\
82 	{ "G4e",	0,          32, 0, 15,5,8, 15,5,8, 18,5,8, 1 },	\
83 	{ "PPC970",	0x00390000, 64, 0, 16,7,1, 15,7,2, 19,7,1, 1 },	\
84 	{ NULL,		0,          0,0,0,0,0,0,0,0,0,0,0,0 }		\
85 	}
86 
87 #define	PPC_NGPRS		32
88 #define	PPC_NFPRS		32
89 #define	PPC_NVRS		32
90 #define	PPC_N_TGPRS		4
91 
92 #define	PPC_N_IC_ARGS			3
93 #define	PPC_INSTR_ALIGNMENT_SHIFT	2
94 #define	PPC_IC_ENTRIES_SHIFT		10
95 #define	PPC_IC_ENTRIES_PER_PAGE		(1 << PPC_IC_ENTRIES_SHIFT)
96 #define	PPC_PC_TO_IC_ENTRY(a)		(((a)>>PPC_INSTR_ALIGNMENT_SHIFT) \
97 					& (PPC_IC_ENTRIES_PER_PAGE-1))
98 #define	PPC_ADDR_TO_PAGENR(a)		((a) >> (PPC_IC_ENTRIES_SHIFT \
99 					+ PPC_INSTR_ALIGNMENT_SHIFT))
100 
101 #define	PPC_L2N			17
102 #define	PPC_L3N			18
103 
104 DYNTRANS_MISC_DECLARATIONS(ppc,PPC,uint64_t)
105 DYNTRANS_MISC64_DECLARATIONS(ppc,PPC,uint8_t)
106 
107 #define	PPC_MAX_VPH_TLB_ENTRIES		128
108 
109 
110 struct ppc_cpu {
111 	struct ppc_cpu_type_def cpu_type;
112 
113 	uint64_t	of_emul_addr;
114 
115 	int		mode;		/*  MODE_PPC or MODE_POWER  */
116 	int		bits;		/*  32 or 64  */
117 
118 	int		irq_asserted;	/*  External Interrupt flag  */
119 	int		dec_intr_pending;/* Decrementer interrupt pending  */
120 	uint64_t	zero;		/*  A zero register  */
121 
122 	uint32_t	cr;		/*  Condition Register  */
123 	uint32_t	fpscr;		/*  FP Status and Control Register  */
124 	uint64_t	gpr[PPC_NGPRS];	/*  General Purpose Registers  */
125 	uint64_t	fpr[PPC_NFPRS];	/*  Floating-Point Registers  */
126 
127 	uint64_t	vr_hi[PPC_NVRS];/*  128-bit Vector registers  */
128 	uint64_t	vr_lo[PPC_NVRS];/*  (Hi and lo 64-bit parts)  */
129 
130 	uint64_t	msr;		/*  Machine state register  */
131 	uint64_t	tgpr[PPC_N_TGPRS];/*Temporary gpr 0..3  */
132 
133 	uint32_t	sr[16];		/*  Segment registers.  */
134 	uint64_t	spr[1024];
135 
136 	uint64_t	ll_addr;	/*  Load-linked / store-conditional  */
137 	int		ll_bit;
138 
139 
140 	/*
141 	 *  Instruction translation cache and Virtual->Physical->Host
142 	 *  address translation:
143 	 */
144 	DYNTRANS_ITC(ppc)
145 	VPH_TLBS(ppc,PPC)
146 	VPH32(ppc,PPC)
147 	VPH64(ppc,PPC)
148 };
149 
150 
151 /*  Machine status word bits: (according to Book 3)  */
152 #define	PPC_MSR_SF	(1ULL << 63)	/*  Sixty-Four-Bit Mode  */
153 /*  bits 62..61 are reserved  */
154 #define	PPC_MSR_HV	(1ULL << 60)	/*  Hypervisor  */
155 /*  bits 59..17  are reserved  */
156 #define	PPC_MSR_VEC	(1 << 25)	/*  Altivec Enable  */
157 #define	PPC_MSR_TGPR	(1 << 17)	/*  Temporary gpr0..3  */
158 #define	PPC_MSR_ILE	(1 << 16)	/*  Interrupt Little-Endian Mode  */
159 #define	PPC_MSR_EE	(1 << 15)	/*  External Interrupt Enable  */
160 #define	PPC_MSR_PR	(1 << 14)	/*  Problem/Privilege State  */
161 #define	PPC_MSR_FP	(1 << 13)	/*  Floating-Point Available  */
162 #define	PPC_MSR_ME	(1 << 12)	/*  Machine Check Interrupt Enable  */
163 #define	PPC_MSR_FE0	(1 << 11)	/*  Floating-Point Exception Mode 0  */
164 #define	PPC_MSR_SE	(1 << 10)	/*  Single-Step Trace Enable  */
165 #define	PPC_MSR_BE	(1 << 9)	/*  Branch Trace Enable  */
166 #define	PPC_MSR_FE1	(1 << 8)	/*  Floating-Point Exception Mode 1  */
167 #define	PPC_MSR_IP	(1 << 6)	/*  Vector Table at 0xfff00000  */
168 #define	PPC_MSR_IR	(1 << 5)	/*  Instruction Relocate  */
169 #define	PPC_MSR_DR	(1 << 4)	/*  Data Relocate  */
170 #define	PPC_MSR_PMM	(1 << 2)	/*  Performance Monitor Mark  */
171 #define	PPC_MSR_RI	(1 << 1)	/*  Recoverable Interrupt  */
172 #define	PPC_MSR_LE	(1)		/*  Little-Endian Mode  */
173 
174 /*  Floating-point Status:  */
175 #define	PPC_FPSCR_FX	(1 << 31)	/*  Exception summary  */
176 #define	PPC_FPSCR_FEX	(1 << 30)	/*  Enabled Exception summary  */
177 #define	PPC_FPSCR_VX	(1 << 29)	/*  Invalid Operation summary  */
178 /*  .. TODO  */
179 #define	PPC_FPSCR_VXNAN	(1 << 24)
180 /*  .. TODO  */
181 #define	PPC_FPSCR_FPCC	0x0000f000
182 #define	PPC_FPSCR_FPCC_SHIFT	12
183 #define	PPC_FPSCR_FL	(1 << 15)	/*  Less than  */
184 #define	PPC_FPSCR_FG	(1 << 14)	/*  Greater than  */
185 #define	PPC_FPSCR_FE	(1 << 13)	/*  Equal or Zero  */
186 #define	PPC_FPSCR_FU	(1 << 12)	/*  Unordered or NaN  */
187 
188 /*  Exceptions:  */
189 #define	PPC_EXCEPTION_DSI	0x3	/*  Data Storage Interrupt  */
190 #define	PPC_EXCEPTION_ISI	0x4	/*  Instruction Storage Interrupt  */
191 #define	PPC_EXCEPTION_EI	0x5	/*  External interrupt  */
192 #define	PPC_EXCEPTION_FPU	0x8	/*  Floating-Point unavailable  */
193 #define	PPC_EXCEPTION_DEC	0x9	/*  Decrementer  */
194 #define	PPC_EXCEPTION_SC	0xc	/*  Syscall  */
195 
196 /*  XER bits:  */
197 #define	PPC_XER_SO	(1UL << 31)	/*  Summary Overflow  */
198 #define	PPC_XER_OV	(1 << 30)	/*  Overflow  */
199 #define	PPC_XER_CA	(1 << 29)	/*  Carry  */
200 
201 
202 /*  cpu_ppc.c:  */
203 int ppc_run_instr(struct cpu *cpu);
204 int ppc32_run_instr(struct cpu *cpu);
205 void ppc_exception(struct cpu *cpu, int exception_nr);
206 void ppc_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
207 	unsigned char *host_page, int writeflag, uint64_t paddr_page);
208 void ppc32_update_translation_table(struct cpu *cpu, uint64_t vaddr_page,
209 	unsigned char *host_page, int writeflag, uint64_t paddr_page);
210 void ppc_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
211 void ppc32_invalidate_translation_caches(struct cpu *cpu, uint64_t, int);
212 void ppc_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
213 void ppc32_invalidate_code_translation(struct cpu *cpu, uint64_t, int);
214 void ppc_init_64bit_dummy_tables(struct cpu *cpu);
215 int ppc_memory_rw(struct cpu *cpu, struct memory *mem, uint64_t vaddr,
216 	unsigned char *data, size_t len, int writeflag, int cache_flags);
217 int ppc_cpu_family_init(struct cpu_family *);
218 
219 /*  memory_ppc.c:  */
220 int ppc_translate_v2p(struct cpu *cpu, uint64_t vaddr,
221 	uint64_t *return_addr, int flags);
222 
223 #endif	/*  CPU_PPC_H  */
224