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