xref: /haiku/headers/private/kernel/arch/m68k/arch_cpu.h (revision 6c2abee2f5e73c3fc81c33da51ac610f8bf1117a)
1 /*
2 ** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
3 ** Distributed under the terms of the Haiku License.
4 */
5 #ifndef _KERNEL_ARCH_M68K_CPU_H
6 #define _KERNEL_ARCH_M68K_CPU_H
7 
8 #ifndef _ASSEMBLER
9 
10 #include <arch/m68k/arch_thread_types.h>
11 #include <kernel.h>
12 
13 #endif	// !_ASSEMBLER
14 
15 
16 #define CPU_MAX_CACHE_LEVEL	8
17 
18 #define CACHE_LINE_SIZE		16
19 
20 
21 #define SR_IP_MASK 0x0700
22 #define SR_S 0x2000
23 #define M68K_SR_S 13
24 #define M68K_SR_T_MASK 0xC000
25 #define M68K_SR_T0 14
26 #define M68K_SR_T1 15
27 
28 #ifndef _ASSEMBLER
29 
30 /* 68k has many different possible stack frames, differentiated by a 4 bit number,
31  * but they also depend on the cpu type.
32  * cf. mint/sys/arch/check_exc.h
33  */
34 
35 /* definitions for special status word */
36 
37 // 020 as well
38 struct mc68030_ssw {
39 	uint16 fc:1;
40 	uint16 fb:1;
41 	uint16 rc:1;
42 	uint16 rb:1;
43 	uint16 :3;
44 	uint16 df:1;
45 	uint16 rm:1;
46 	uint16 rw:1;
47 	uint16 size:2;
48 	uint16 :1;
49 	uint16 as:3;
50 } _PACKED;
51 
52 struct mc68040_ssw {
53 	uint16 cp:1;
54 	uint16 cu:1;
55 	uint16 ct:1;
56 	uint16 cm:1;
57 	uint16 ma:1;
58 	uint16 atc:1;
59 	uint16 lk:1;
60 	uint16 rw:1;
61 	uint16 :1;
62 	uint16 size:2;
63 	uint16 tt:2;
64 	uint16 tm:3;
65 } _PACKED;
66 
67 struct mc68060_fslw {
68 	uint32 :4;
69 	uint32 ma:1;
70 	uint32 :1;
71 	uint32 lk:1;
72 	uint32 rw:2; //XXX ??
73 	uint32 size:2;
74 	uint32 tt:2;
75 	uint32 tm:2;
76 	uint32 io:1;
77 	uint32 pbe:1;
78 	uint32 sbe:1;
79 	uint32 pta:1;
80 	uint32 ptb:1;
81 	uint32 il:1;
82 	uint32 pf:1;
83 	uint32 sb:1;
84 	uint32 wp:1;
85 	uint32 twe:1;
86 	uint32 re:1;
87 	uint32 we:1;
88 	uint32 ttr:1;
89 	uint32 bpe:1;
90 	uint32 :1;
91 	uint32 see:1;
92 } _PACKED;
93 
94 /* raw exception frames */
95 
96 struct mc680x0_type_0_frame {
97 	uint16 sr;
98 	addr_t pc;
99 	uint16 type:4;
100 	uint16 vector:12;
101 };
102 
103 struct mc680x0_type_1_frame {
104 	uint16 sr;
105 	addr_t pc;
106 	uint16 type:4;
107 	uint16 vector:12;
108 };
109 
110 struct mc680x0_type_2_frame {
111 	uint16 sr;
112 	addr_t pc;
113 	uint16 type:4;
114 	uint16 vector:12;
115 	addr_t instruction_address;
116 };
117 
118 struct mc680x0_type_3_frame {
119 	uint16 sr;
120 	addr_t pc;
121 	uint16 type:4;
122 	uint16 vector:12;
123 	addr_t effective_address;
124 };
125 
126 struct mc68040_type_7_frame {
127 	uint16 sr;
128 	addr_t pc;
129 	uint16 type:4;
130 	uint16 vector:12;
131 	addr_t effective_address;
132 	struct mc68040_ssw ssw;
133 	// write-back status
134 	uint16 wb3s;
135 	uint16 wb2s;
136 	uint16 wb1s;
137 	addr_t fault_address;
138 	addr_t wb3a;
139 	uint32 wb3d;
140 	addr_t wb2a;
141 	uint32 wb2d;
142 	addr_t wb1a;
143 	uint32 wb1d; // also pd0
144 	uint32 pd1;
145 	uint32 pd2;
146 	uint32 pd3;
147 };
148 
149 struct mc680x0_type_9_frame {
150 	uint16 sr;
151 	addr_t pc;
152 	uint16 type:4;
153 	uint16 vector:12;
154 	addr_t instruction_address;
155 	uint16 intregs[4];
156 };
157 
158 struct mc68030_type_a_frame {
159 	uint16 sr;
160 	addr_t pc;
161 	uint16 type:4;
162 	uint16 vector:12;
163 	uint16 intreg1;
164 	struct mc68030_ssw ssw;
165 	uint16 instpipe_c;
166 	uint16 instpipe_b;
167 	addr_t fault_address;
168 	uint16 intregs2[2];
169 	uint32 dataout;
170 	uint16 intregs3[2];
171 };
172 
173 struct mc68030_type_b_frame {
174 	uint16 sr;
175 	addr_t pc;
176 	uint16 type:4;
177 	uint16 vector:12;
178 	uint16 intreg1;
179 	struct mc68030_ssw ssw;
180 	uint16 instpipe_c;
181 	uint16 instpipe_b;
182 	addr_t fault_address;
183 	uint16 intregs2[2];
184 	uint32 dataout;
185 	uint16 intregs3[4];
186 	uint32 stbaddr;
187 	uint16 intregs4[2];
188 	uint32 datain;
189 	uint16 intregs5[3];
190 	uint16 intinfo;
191 	uint16 intregs6[18];
192 };
193 
194 //XXX: add 060 frames
195 
196 struct mc680x0_frame {
197 	union {
198 		struct {
199 			uint16 sr;
200 			addr_t pc;
201 			uint16 type:4;
202 			uint16 vector:12;
203 		};
204 		struct mc680x0_type_0_frame type_0;
205 		struct mc680x0_type_1_frame type_1;
206 		struct mc680x0_type_3_frame type_3;
207 		struct mc680x0_type_2_frame type_2;
208 		struct mc68040_type_7_frame type_7;
209 		struct mc680x0_type_9_frame type_9;
210 		struct mc68030_type_a_frame type_a;
211 		struct mc68030_type_b_frame type_b;
212 		// XXX: add 060 frames
213 	};
214 };
215 
216 struct mc680x0_null_fpu_state {
217 	uint8 version; // 0
218 	uint8 type; // undefined
219 	uint16 dummy;
220 };
221 
222 struct mc680x0_type_00_fpu_state {
223 	uint8 version;
224 	uint8 type; // 0
225 	uint16 dummy;
226 };
227 
228 struct mc680x0_type_28_fpu_state {
229 	uint8 version;
230 	uint8 type; // 0x28
231 	uint16 dummy;
232 	// XXX: replace dummies
233 	uint32 dummies[0x28/4];
234 };
235 
236 struct mc680x0_type_60_fpu_state {
237 	uint8 version;
238 	uint8 type; // 0x60
239 	uint16 dummy;
240 	// XXX: replace dummies
241 	uint32 dummies[0x60/4];
242 };
243 
244 //XXX: those are 040, add others
245 // biggest known:
246 struct mc68882_type_d4_fpu_state {
247 	uint8 version;
248 	uint8 type; // 0xd4
249 	uint16 dummy;
250 	// XXX: replace dummies
251 	uint32 dummies[0xd4/4];
252 };
253 
254 struct mc680x0_fpu_state {
255 	union {
256 		struct {
257 			uint8 version;
258 			uint8 type; // 0x60
259 			uint16 dummy;
260 		};
261 		struct mc680x0_null_fpu_state null;
262 		struct mc680x0_type_00_fpu_state type_00;
263 		struct mc680x0_type_28_fpu_state type_28;
264 		struct mc680x0_type_60_fpu_state type_60;
265 		struct mc68882_type_d4_fpu_state type_d4;
266 	};
267 };
268 
269 // 96-bit format
270 struct mc680x0_fp_data_reg {
271 	uint8 data[12];
272 };
273 
274 struct mc680x0_fp_control_regs {
275 	uint32 fpcr;
276 	uint32 fpsr;
277 	uint32 fpiar;
278 };
279 
280 
281 
282 #warning M68K: check for missing regs/movem
283 struct iframe {
284 	/* fpu data registers */
285 #warning M68K: sizeof(fp*)
286 	struct mc680x0_fp_data_reg fp[8];
287 	/* fpu control registers */
288 	struct mc680x0_fp_control_regs fpc;
289 	/* fpu state */
290 	struct mc680x0_fpu_state fpu;
291 
292 	/* data and address registers */
293 	uint32 d[8];
294 	uint32 a[7];
295 	/* cpu exception frame, including sr, pc, format and vector */
296 	struct mc680x0_frame cpu;
297 
298 /*	uint32 vector;
299 	uint32 srr0;
300 	uint32 srr1;
301 	uint32 dar;
302 	uint32 dsisr;
303 	uint32 lr;
304 	uint32 cr;
305 	uint32 xer;
306 	uint32 ctr;
307 	uint32 fpscr;
308 	uint32 r31;
309 	uint32 r30;
310 	uint32 r29;
311 	uint32 r28;
312 	uint32 r27;
313 	uint32 r26;
314 	uint32 r25;
315 	uint32 r24;
316 	uint32 r23;
317 	uint32 r22;
318 	uint32 r21;
319 	uint32 r20;
320 	uint32 r19;
321 	uint32 r18;
322 	uint32 r17;
323 	uint32 r16;
324 	uint32 r15;
325 	uint32 r14;
326 	uint32 r13;
327 	uint32 r12;
328 	uint32 r11;
329 	uint32 r10;
330 	uint32 r9;
331 	uint32 r8;
332 	uint32 r7;
333 	uint32 r6;
334 	uint32 r5;
335 	uint32 r4;
336 	uint32 r3;
337 	uint32 r2;
338 	uint32 r1;
339 	uint32 r0;
340 	double f31;
341 	double f30;
342 	double f29;
343 	double f28;
344 	double f27;
345 	double f26;
346 	double f25;
347 	double f24;
348 	double f23;
349 	double f22;
350 	double f21;
351 	double f20;
352 	double f19;
353 	double f18;
354 	double f17;
355 	double f16;
356 	double f15;
357 	double f14;
358 	double f13;
359 	double f12;
360 	double f11;
361 	double f10;
362 	double f9;
363 	double f8;
364 	double f7;
365 	double f6;
366 	double f5;
367 	double f4;
368 	double f3;
369 	double f2;
370 	double f1;
371 	double f0;*/
372 } _PACKED;
373 
374 #if 0 /* ppc */
375 enum machine_state {
376 	MSR_EXCEPTIONS_ENABLED			= 1L << 15,		// EE
377 	MSR_PRIVILEGE_LEVEL				= 1L << 14,		// PR
378 	MSR_FP_AVAILABLE				= 1L << 13,		// FP
379 	MSR_MACHINE_CHECK_ENABLED		= 1L << 12,		// ME
380 	MSR_EXCEPTION_PREFIX			= 1L << 6,		// IP
381 	MSR_INST_ADDRESS_TRANSLATION	= 1L << 5,		// IR
382 	MSR_DATA_ADDRESS_TRANSLATION	= 1L << 4,		// DR
383 };
384 
385 //struct block_address_translation;
386 #endif
387 
388 typedef struct arch_cpu_info {
389 	int null;
390 } arch_cpu_info;
391 
392 
393 #ifdef __cplusplus
394 extern "C" {
395 #endif
396 
397 #if 0
398 //PPC stuff
399 extern uint32 get_sdr1(void);
400 extern void set_sdr1(uint32 value);
401 extern uint32 get_sr(void *virtualAddress);
402 extern void set_sr(void *virtualAddress, uint32 value);
403 extern uint32 get_msr(void);
404 extern uint32 set_msr(uint32 value);
405 extern uint32 get_pvr(void);
406 
407 extern void set_ibat0(struct block_address_translation *bat);
408 extern void set_ibat1(struct block_address_translation *bat);
409 extern void set_ibat2(struct block_address_translation *bat);
410 extern void set_ibat3(struct block_address_translation *bat);
411 extern void set_dbat0(struct block_address_translation *bat);
412 extern void set_dbat1(struct block_address_translation *bat);
413 extern void set_dbat2(struct block_address_translation *bat);
414 extern void set_dbat3(struct block_address_translation *bat);
415 
416 extern void get_ibat0(struct block_address_translation *bat);
417 extern void get_ibat1(struct block_address_translation *bat);
418 extern void get_ibat2(struct block_address_translation *bat);
419 extern void get_ibat3(struct block_address_translation *bat);
420 extern void get_dbat0(struct block_address_translation *bat);
421 extern void get_dbat1(struct block_address_translation *bat);
422 extern void get_dbat2(struct block_address_translation *bat);
423 extern void get_dbat3(struct block_address_translation *bat);
424 
425 extern void reset_ibats(void);
426 extern void reset_dbats(void);
427 #endif
428 
429 //extern void sethid0(unsigned int val);
430 //extern unsigned int getl2cr(void);
431 //extern void setl2cr(unsigned int val);
432 extern long long get_time_base(void);
433 
434 void __m68k_setup_system_time(vint32 *cvFactor);
435 	// defined in libroot: os/arch/system_time.c
436 int64 __m68k_get_time_base(void);
437 	// defined in libroot: os/arch/system_time_asm.S
438 
439 extern void m68k_context_switch(void **_oldStackPointer, void *newStackPointer);
440 
441 extern bool m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler)
442 	__attribute__((noinline));
443 
444 extern bool m68k_is_hw_register_readable(addr_t address);
445 extern bool m68k_is_hw_register_writable(addr_t address, uint16 value);
446 	// defined in kernel: arch/m68k/cpu_asm.S
447 
448 
449 static inline void
450 arch_cpu_idle(void)
451 {
452 	// TODO: M68K CPU idle call
453 	// there isn't really any insn for this. Maybe NOP/FNOP?
454 	// TODO: make a 060 module using LPSTOP
455 	//asm volatile ("lpstop");
456 }
457 
458 
459 static inline void
460 arch_cpu_pause(void)
461 {
462 	// TODO: M68K STOP call
463 	// the problem is STOP wants an immediate to put into SR
464 	// but we don't want to overwrite it.
465 	//asm volatile("stop #0" : : : "memory");
466 }
467 
468 #ifdef __cplusplus
469 }
470 #endif
471 
472 struct m68k_cpu_ops {
473 	void (*flush_insn_pipeline)(void);
474 	void (*flush_atc_all)(void);
475 	void (*flush_atc_user)(void);
476 	void (*flush_atc_addr)(addr_t addr);
477 	void (*flush_dcache)(addr_t address, size_t len);
478 	void (*flush_icache)(addr_t address, size_t len);
479 	void (*idle)(void);
480 };
481 
482 extern struct m68k_cpu_ops cpu_ops;
483 
484 //#define
485 
486 #if 0
487 #define eieio()	asm volatile("eieio")
488 #define isync() asm volatile("isync")
489 #define tlbsync() asm volatile("tlbsync")
490 #define ppc_sync() asm volatile("sync")
491 #define tlbia() asm volatile("tlbia")
492 #define tlbie(addr) asm volatile("tlbie %0" :: "r" (addr))
493 #endif
494 
495 #if 0
496 
497 // XXX: not used: we just use decimal chip number, like 68030
498 
499 // m68k processor version.
500 enum m68k_processor_version {
501 	/* those two we don't support */
502 	CPU_68000		= 0x0000,
503 	CPU_68010		= 0x0001,
504 	/* maybe with a pmmu and fpu */
505 	CPU_68020		= 0x0002,
506 	/* should work */
507 	CPU_68030		= 0x0003,
508 	CPU_68040		= 0x0004,
509 	CPU_68060		= 0x0006,
510 	/* mask */
511 	CPU_MASK		= 0x000F
512 };
513 
514 enum m68k_fpu_version {
515 	/* we don't support */
516 	FPU_NONE		= 0x0000,
517 	FPU_68881		= 0x0010,
518 	FPU_68882		= 0x0020,
519 	FPU_030			= 0x0030,
520 	FPU_040			= 0x0040,
521 	FPU_060			= 0x0060,
522 	FPU_MASK		= 0x00F0
523 };
524 
525 enum m68k_mmu_version {
526 	MMU_NONE		= 0x0000,
527 	MMU_68551		= 0x0100,
528 	MMU_68030		= 0x0300,
529 	MMU_68040		= 0x0400,
530 	MMU_68060		= 0x0600,
531 	MMU_MASK		= 0x0F00
532 };
533 #endif
534 
535 extern int arch_cpu_type;
536 extern int arch_fpu_type;
537 extern int arch_mmu_type;
538 extern int arch_platform;
539 extern int arch_machine;
540 
541 /*
542 	Use of (some) special purpose registers.
543 	XXX: those regs aren't implemented/accessed the same way on different cpus...
544 
545 	SRP[63-32]: current Thread*
546 	SRP[31-0] :
547 	CAAR      : can we use it ??
548 	MSP       :
549 
550 	PPC:
551 	SPRG0: per CPU physical address pointer to an ppc_cpu_exception_context
552 	       structure
553 	SPRG1: scratch
554 	SPRG2: current Thread*
555 	SPRG3: TLS base pointer (only for userland threads)
556 */
557 
558 #endif	// !_ASSEMBLER
559 
560 #endif	/* _KERNEL_ARCH_PPC_CPU_H */
561