1/*
2 * Copyright 2003-2004, Axel D��rfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _KERNEL_ARCH_PPC_CPU_H
6#define _KERNEL_ARCH_PPC_CPU_H
7
8
9#include <arch/ppc/arch_thread_types.h>
10#include <arch/ppc/cpu.h>
11#include <kernel.h>
12
13
14#define CPU_MAX_CACHE_LEVEL	8
15#define CACHE_LINE_SIZE		128
16	// 128 Byte lines on PPC970
17
18
19#define set_ac()
20#define clear_ac()
21
22
23struct iframe {
24	uint32 vector;
25	uint32 srr0;
26	uint32 srr1;
27	uint32 dar;
28	uint32 dsisr;
29	uint32 lr;
30	uint32 cr;
31	uint32 xer;
32	uint32 ctr;
33	uint32 fpscr;
34	uint32 r31;
35	uint32 r30;
36	uint32 r29;
37	uint32 r28;
38	uint32 r27;
39	uint32 r26;
40	uint32 r25;
41	uint32 r24;
42	uint32 r23;
43	uint32 r22;
44	uint32 r21;
45	uint32 r20;
46	uint32 r19;
47	uint32 r18;
48	uint32 r17;
49	uint32 r16;
50	uint32 r15;
51	uint32 r14;
52	uint32 r13;
53	uint32 r12;
54	uint32 r11;
55	uint32 r10;
56	uint32 r9;
57	uint32 r8;
58	uint32 r7;
59	uint32 r6;
60	uint32 r5;
61	uint32 r4;
62	uint32 r3;
63	uint32 r2;
64	uint32 r1;
65	uint32 r0;
66	double f31;
67	double f30;
68	double f29;
69	double f28;
70	double f27;
71	double f26;
72	double f25;
73	double f24;
74	double f23;
75	double f22;
76	double f21;
77	double f20;
78	double f19;
79	double f18;
80	double f17;
81	double f16;
82	double f15;
83	double f14;
84	double f13;
85	double f12;
86	double f11;
87	double f10;
88	double f9;
89	double f8;
90	double f7;
91	double f6;
92	double f5;
93	double f4;
94	double f3;
95	double f2;
96	double f1;
97	double f0;
98};
99
100enum machine_state {
101	MSR_EXCEPTIONS_ENABLED			= 1L << 15,		// EE
102	MSR_PRIVILEGE_LEVEL				= 1L << 14,		// PR
103	MSR_FP_AVAILABLE				= 1L << 13,		// FP
104	MSR_MACHINE_CHECK_ENABLED		= 1L << 12,		// ME
105	MSR_EXCEPTION_PREFIX			= 1L << 6,		// IP
106	MSR_INST_ADDRESS_TRANSLATION	= 1L << 5,		// IR
107	MSR_DATA_ADDRESS_TRANSLATION	= 1L << 4,		// DR
108};
109
110struct block_address_translation;
111
112typedef struct arch_cpu_info {
113	int null;
114} arch_cpu_info;
115
116
117#define eieio()	asm volatile("eieio")
118#define isync() asm volatile("isync")
119#define tlbsync() asm volatile("tlbsync")
120#define ppc_sync() asm volatile("sync")
121#define tlbia() asm volatile("tlbia")
122#define tlbie(addr) asm volatile("tlbie %0" :: "r" (addr))
123
124// adjust thread priority on PowerPC (Shared resource hints)
125#define SRH_very_low() asm volatile("or 31,31,31")
126#define SRH_low() asm volatile("or 1,1,1")
127#define SRH_medium_low() asm volatile("or 6,6,6")
128#define SRH_medium() asm volatile("or 2,2,2")
129#define SRH_medium_high() asm volatile("or 5,5,5")
130#define SRH_high() asm volatile("or 3,3,3")
131
132
133#ifdef __cplusplus
134extern "C" {
135#endif
136
137extern uint32 get_sdr1(void);
138extern void set_sdr1(uint32 value);
139extern uint32 get_sr(void *virtualAddress);
140extern void set_sr(void *virtualAddress, uint32 value);
141extern uint32 get_msr(void);
142extern uint32 set_msr(uint32 value);
143extern uint32 get_pvr(void);
144
145extern void set_ibat0(struct block_address_translation *bat);
146extern void set_ibat1(struct block_address_translation *bat);
147extern void set_ibat2(struct block_address_translation *bat);
148extern void set_ibat3(struct block_address_translation *bat);
149extern void set_dbat0(struct block_address_translation *bat);
150extern void set_dbat1(struct block_address_translation *bat);
151extern void set_dbat2(struct block_address_translation *bat);
152extern void set_dbat3(struct block_address_translation *bat);
153
154extern void get_ibat0(struct block_address_translation *bat);
155extern void get_ibat1(struct block_address_translation *bat);
156extern void get_ibat2(struct block_address_translation *bat);
157extern void get_ibat3(struct block_address_translation *bat);
158extern void get_dbat0(struct block_address_translation *bat);
159extern void get_dbat1(struct block_address_translation *bat);
160extern void get_dbat2(struct block_address_translation *bat);
161extern void get_dbat3(struct block_address_translation *bat);
162
163extern void reset_ibats(void);
164extern void reset_dbats(void);
165
166//extern void sethid0(unsigned int val);
167//extern unsigned int getl2cr(void);
168//extern void setl2cr(unsigned int val);
169extern long long get_time_base(void);
170
171void __ppc_setup_system_time(vint32 *cvFactor);
172	// defined in libroot: os/arch/system_time.c
173int64 __ppc_get_time_base(void);
174	// defined in libroot: os/arch/system_time_asm.S
175
176extern void ppc_context_switch(void **_oldStackPointer, void *newStackPointer);
177
178extern bool ppc_set_fault_handler(addr_t *handlerLocation, addr_t handler)
179	__attribute__((noinline));
180
181
182static inline void
183arch_cpu_pause(void)
184{
185	// TODO: PowerPC review logic of setting very low for pause
186	SRH_very_low();
187}
188
189
190static inline void
191arch_cpu_idle(void)
192{
193	// TODO: PowerPC CPU idle call
194}
195
196
197#ifdef __cplusplus
198}
199#endif
200
201// PowerPC processor version (the upper 16 bits of the PVR).
202enum ppc_processor_version {
203	MPC601		= 0x0001,
204	MPC603		= 0x0003,
205	MPC604		= 0x0004,
206	MPC602		= 0x0005,
207	MPC603e		= 0x0006,
208	MPC603ev	= 0x0007,
209	MPC750		= 0x0008,
210	MPC604ev	= 0x0009,
211	MPC7400		= 0x000c,
212	MPC620		= 0x0014,
213	IBM403		= 0x0020,
214	IBM401A1	= 0x0021,
215	IBM401B2	= 0x0022,
216	IBM401C2	= 0x0023,
217	IBM401D2	= 0x0024,
218	IBM401E2	= 0x0025,
219	IBM401F2	= 0x0026,
220	IBM401G2	= 0x0027,
221	IBMPOWER3	= 0x0041,
222	MPC860		= 0x0050,
223	MPC8240		= 0x0081,
224	AMCC460EX	= 0x1302,
225	IBM405GP	= 0x4011,
226	IBM405L		= 0x4161,
227	AMCC440EP	= 0x4222,
228	IBM750FX	= 0x7000,
229	MPC7450		= 0x8000,
230	MPC7455		= 0x8001,
231	MPC7457		= 0x8002,
232	MPC7447A	= 0x8003,
233	MPC7448		= 0x8004,
234	MPC7410		= 0x800c,
235	MPC8245		= 0x8081,
236};
237
238
239/*
240	Use of (some) special purpose registers.
241
242	SPRG0: per CPU physical address pointer to an ppc_cpu_exception_context
243	       structure
244	SPRG1: scratch
245	SPRG2: current Thread*
246	SPRG3: TLS base pointer (only for userland threads)
247*/
248
249#endif	/* _KERNEL_ARCH_PPC_CPU_H */
250