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 set_ac() 22#define clear_ac() 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 42struct 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 56struct 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 71struct 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 100struct mc680x0_type_0_frame { 101 uint16 sr; 102 addr_t pc; 103 uint16 type:4; 104 uint16 vector:12; 105}; 106 107struct mc680x0_type_1_frame { 108 uint16 sr; 109 addr_t pc; 110 uint16 type:4; 111 uint16 vector:12; 112}; 113 114struct 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 122struct 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 130struct 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 153struct 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 162struct 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 177struct 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 200struct 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 220struct mc680x0_null_fpu_state { 221 uint8 version; // 0 222 uint8 type; // undefined 223 uint16 dummy; 224}; 225 226struct mc680x0_type_00_fpu_state { 227 uint8 version; 228 uint8 type; // 0 229 uint16 dummy; 230}; 231 232struct 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 240struct 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: 250struct 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 258struct 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 274struct mc680x0_fp_data_reg { 275 uint8 data[12]; 276}; 277 278struct 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 287struct 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 */ 379enum 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 392typedef struct arch_cpu_info { 393 int null; 394} arch_cpu_info; 395 396 397#ifdef __cplusplus 398extern "C" { 399#endif 400 401#if 0 402//PPC stuff 403extern uint32 get_sdr1(void); 404extern void set_sdr1(uint32 value); 405extern uint32 get_sr(void *virtualAddress); 406extern void set_sr(void *virtualAddress, uint32 value); 407extern uint32 get_msr(void); 408extern uint32 set_msr(uint32 value); 409extern uint32 get_pvr(void); 410 411extern void set_ibat0(struct block_address_translation *bat); 412extern void set_ibat1(struct block_address_translation *bat); 413extern void set_ibat2(struct block_address_translation *bat); 414extern void set_ibat3(struct block_address_translation *bat); 415extern void set_dbat0(struct block_address_translation *bat); 416extern void set_dbat1(struct block_address_translation *bat); 417extern void set_dbat2(struct block_address_translation *bat); 418extern void set_dbat3(struct block_address_translation *bat); 419 420extern void get_ibat0(struct block_address_translation *bat); 421extern void get_ibat1(struct block_address_translation *bat); 422extern void get_ibat2(struct block_address_translation *bat); 423extern void get_ibat3(struct block_address_translation *bat); 424extern void get_dbat0(struct block_address_translation *bat); 425extern void get_dbat1(struct block_address_translation *bat); 426extern void get_dbat2(struct block_address_translation *bat); 427extern void get_dbat3(struct block_address_translation *bat); 428 429extern void reset_ibats(void); 430extern 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); 436extern long long get_time_base(void); 437 438void __m68k_setup_system_time(vint32 *cvFactor); 439 // defined in libroot: os/arch/system_time.c 440int64 __m68k_get_time_base(void); 441 // defined in libroot: os/arch/system_time_asm.S 442 443extern void m68k_context_switch(void **_oldStackPointer, void *newStackPointer); 444 445extern bool m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler) 446 __attribute__((noinline)); 447 448extern bool m68k_is_hw_register_readable(addr_t address); 449extern bool m68k_is_hw_register_writable(addr_t address, uint16 value); 450 // defined in kernel: arch/m68k/cpu_asm.S 451 452 453static inline void 454arch_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 463static inline void 464arch_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 476struct 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 486extern 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. 504enum 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 518enum 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 529enum 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 539extern int arch_cpu_type; 540extern int arch_fpu_type; 541extern int arch_mmu_type; 542extern int arch_platform; 543extern 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