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