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