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