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 33 struct 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 47 struct 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 62 struct 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 91 struct mc680x0_type_0_frame { 92 uint16 sr; 93 addr_t pc; 94 uint16 type:4; 95 uint16 vector:12; 96 }; 97 98 struct mc680x0_type_1_frame { 99 uint16 sr; 100 addr_t pc; 101 uint16 type:4; 102 uint16 vector:12; 103 }; 104 105 struct 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 113 struct 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 121 struct 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 144 struct 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 153 struct 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 168 struct 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 191 struct 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 211 struct mc680x0_null_fpu_state { 212 uint8 version; // 0 213 uint8 type; // undefined 214 uint16 dummy; 215 }; 216 217 struct mc680x0_type_00_fpu_state { 218 uint8 version; 219 uint8 type; // 0 220 uint16 dummy; 221 }; 222 223 struct 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 231 struct 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: 241 struct 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 249 struct 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 265 struct mc680x0_fp_data_reg { 266 uint8 data[12]; 267 }; 268 269 struct 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 278 struct 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 */ 370 enum 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 383 typedef struct arch_cpu_info { 384 int null; 385 } arch_cpu_info; 386 387 388 #ifdef __cplusplus 389 extern "C" { 390 #endif 391 392 #if 0 393 //PPC stuff 394 extern uint32 get_sdr1(void); 395 extern void set_sdr1(uint32 value); 396 extern uint32 get_sr(void *virtualAddress); 397 extern void set_sr(void *virtualAddress, uint32 value); 398 extern uint32 get_msr(void); 399 extern uint32 set_msr(uint32 value); 400 extern uint32 get_pvr(void); 401 402 extern void set_ibat0(struct block_address_translation *bat); 403 extern void set_ibat1(struct block_address_translation *bat); 404 extern void set_ibat2(struct block_address_translation *bat); 405 extern void set_ibat3(struct block_address_translation *bat); 406 extern void set_dbat0(struct block_address_translation *bat); 407 extern void set_dbat1(struct block_address_translation *bat); 408 extern void set_dbat2(struct block_address_translation *bat); 409 extern void set_dbat3(struct block_address_translation *bat); 410 411 extern void get_ibat0(struct block_address_translation *bat); 412 extern void get_ibat1(struct block_address_translation *bat); 413 extern void get_ibat2(struct block_address_translation *bat); 414 extern void get_ibat3(struct block_address_translation *bat); 415 extern void get_dbat0(struct block_address_translation *bat); 416 extern void get_dbat1(struct block_address_translation *bat); 417 extern void get_dbat2(struct block_address_translation *bat); 418 extern void get_dbat3(struct block_address_translation *bat); 419 420 extern void reset_ibats(void); 421 extern 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); 427 extern long long get_time_base(void); 428 429 void __m68k_setup_system_time(vint32 *cvFactor); 430 // defined in libroot: os/arch/system_time.c 431 int64 __m68k_get_time_base(void); 432 // defined in libroot: os/arch/system_time_asm.S 433 434 extern void m68k_context_switch(void **_oldStackPointer, void *newStackPointer); 435 436 extern bool m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler) 437 __attribute__((noinline)); 438 439 extern bool m68k_is_hw_register_readable(addr_t address); 440 extern 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 447 struct 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 457 extern 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. 475 enum 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 489 enum 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 500 enum 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 510 extern int arch_cpu_type; 511 extern int arch_fpu_type; 512 extern int arch_mmu_type; 513 extern int arch_platform; 514 extern 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 struct 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 struct thread* 530 SPRG3: TLS base pointer (only for userland threads) 531 */ 532 533 #endif // !_ASSEMBLER 534 535 #endif /* _KERNEL_ARCH_PPC_CPU_H */ 536