1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422
|
/*
* Creation Date: <2001/01/27 16:25:14 samuel>
* Time-stamp: <2001/06/24 13:32:31 samuel>
*
* <traps.S>
*
*
*
* Copyright (C) 2000, 2001 Samuel Rydh (samuel@ibrium.se)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation
*
*/
#include "compat.h"
#include "processor.h" /* avoid <asm/processor.h> (bogus SPRN_TBWU/L) */
#include "asm_offsets.h"
#include "asmdefs.h"
#include "molasm.h"
#include "reloc.h"
#include "rvec.h"
#include "constants.h"
#include "mac_registers.h"
#include "mmu.h" /* for kSplitModeXXX */
#include "os_interface.h"
#include "kernel_vars.h"
/************************************************************************/
/* DEBUG Settings */
/************************************************************************/
//#define DISABLE_DEC // Disable DEC code
//#define DISABLE_DEC_REG // Disable mtdec/mfdec
//#define DBG_TRACE // Enable Tracing
#ifdef DBG_TRACE
#define TRACE( a,b ) TRACE_VAL a,b
#else
#define TRACE( a,b )
#endif
/************************************************************************/
/* Exception Vector Definitions */
/************************************************************************/
.data
ACTION_SYMBOL( Action_LI_PHYS, ACTION_LI_PHYS )
ACTION_SYMBOL( k_session_table, ACTION_KVARS_TABLE )
ACTION_SYMBOL( k_session_table_virt, ACTION_KVARS_TABLE_VIRT )
ACTION_SYMBOL( Action_RELOC_HOOK, ACTION_RELOC_HOOK )
ACTION_SYMBOL( Action_VRET, ACTION_VRET )
ACTION_SYMBOL( Action_HOOK_FUNCTION, ACTION_HOOK_FUNCTION )
ACTION_SYMBOL( Action_FRET, ACTION_FRET )
.text
GLOBAL_SYMBOL(r__reloctable_start):
.macro EXCEPTION_PREAMBLE
// SPRG1 = r1, SPRG0 = r3, r3=CR, r1=MOL_STACK
stw r3,xCR(r1)
mfsprg1 r3 // SPRG1 = r1
stw r2,xGPR2(r1)
stw r0,xGPR0(r1)
mfsprg0 r2 // SPRG0 = r3
stw r4,xGPR4(r1)
lwz r0,xFLAG_BITS(r1)
mflr r4
stw r3,xGPR1(r1)
stw r5,xGPR5(r1)
mtcr r0
stw r2,xGPR3(r1)
stw r4,xLINK(r1)
// saved: r0-r5, cr, lr
// r1 = stack, cr5-7=flag_bits
.endm
save_middle_regs: // save r6-r12 (r13-r31 should always be in regs)
stw r6,xGPR6(r1)
stw r7,xGPR7(r1)
stw r8,xGPR8(r1)
mfctr r6
stw r9,xGPR9(r1)
stw r10,xGPR10(r1)
mfxer r7
stw r11,xGPR11(r1)
stw r12,xGPR12(r1)
mfsrr0 r8
stw r6,xCTR(r1)
stw r7,xXER(r1)
stw r8,xNIP(r1)
blr
.macro RESTORE_MIDDLE_REGS // In the unlikely case we need to reverse save_middle_regs...
lwz r11,xCTR(r1) // Restore registers
lwz r12,xXER(r1)
lwz r6,xGPR6(r1)
lwz r7,xGPR7(r1)
mtctr r11
lwz r8,xGPR8(r1)
lwz r9,xGPR9(r1)
lwz r10,xGPR10(r1)
mtxer r12
lwz r11,xGPR11(r1)
lwz r12,xGPR12(r1)
.endm
#define EXCEPTION_SAVE_ALL \
EXCEPTION_PREAMBLE ;\
bl save_middle_regs ;
#define VECTOR_KERNEL( v, dummy_name, secint ) \
VECTOR( v, dummy_name, secint ) ;\
EXCEPTION_SAVE_ALL ;\
TAKE_EXCEPTION ;
#define VECTOR_RESERVED( v, dummy_name, secint ) \
VECTOR( v, dummy_name, secint ) ;\
DEBUGGER_SAVE( v ) ;
#define MAC_EXIT( rvec_code ) \
li r3,rvec_code ;\
b mac_exit ;
#define MAC_EXIT_SAVE( rvec_code ) \
bl save_middle_regs ;\
li r3,rvec_code ;\
b mac_exit ;
#define MAC_TRAP( trap_num ) \
li r2,trap_num ;\
b mac_trap ;
#define DEBUGGER(n) li r4,n ; MAC_EXIT( RVEC_DEBUGGER );
#define DEBUGGER_SAVE(n) li r4,n ; MAC_EXIT_SAVE( RVEC_DEBUGGER );
/************************************************************************/
/* Reserved / Kernel Vectors */
/************************************************************************/
VECTOR_KERNEL( 0x100, "System Reset", secint_bad )
VECTOR_KERNEL( 0x500, "External Interrupt", secint_bad )
VECTOR_KERNEL( 0x1400, "System Management Interrupt", secint_bad )
VECTOR_KERNEL( 0x1700, "Thermal Management Interrupt", secint_bad )
VECTOR_RESERVED( 0x200, "Machine Check", secint_bad )
VECTOR_RESERVED( 0xa00, "Reserved", secint_bad )
VECTOR_RESERVED( 0xb00, "Reserved", secint_bad )
VECTOR_RESERVED( 0xe00, "FPU Assist", secint_bad )
VECTOR_RESERVED( 0xf00, "Performance Monitor Interrupt", secint_bad )
//VECTOR_RESERVED( 0x1000, "InstructionTLBMiss-603", secint_bad )
//VECTOR_RESERVED( 0x1100, "DataLoadTLBMiss-603", secint_bad )
//VECTOR_RESERVED( 0x1200, "DataLoadTLBMiss-603", secint_bad )
/************************************************************************/
/* DSI Exceptions */
/************************************************************************/
VECTOR( 0x300, "DSI", secint_lr_call )
EXCEPTION_PREAMBLE
TRACE(0x300, "DSI")
mfsrr0 r4
bl _get_instr_opcode // m: r0,r2-r3, ret: r4=opcode
stw r4,xINST_OPCODE(r1)
bl check_pthash_hit // m: r0,r2-r5
bl splitmode_dsi // Handle splitmode DSI exceptions
bl save_middle_regs
bl check_io_page
dsi_cont:
LI_VIRT( r3, dsi_exception )
mfdar r4 // We might need to do this earlier
mfdsisr r5 // when the splitmode code is activated...
b call_kernel
/************************************************************************/
/* ISI Exceptions */
/************************************************************************/
VECTOR( 0x400, "ISI", secint_bad )
EXCEPTION_PREAMBLE
TRACE(0x400, "ISI")
bl split_sr_no_execute
bl save_middle_regs
LI_VIRT( r3, isi_exception )
mfsrr0 r4
mfsrr1 r5
b call_kernel
/************************************************************************/
/* Alignement Exception */
/************************************************************************/
VECTOR( 0x600, "Alignment", secint_lr_call )
EXCEPTION_SAVE_ALL
TRACE(0x400, "Alignment")
alignment_cont:
mfdar r4
mfdsisr r5
MAC_EXIT( RVEC_ALIGNMENT_TRAP )
/************************************************************************/
/* Program Exception */
/************************************************************************/
VECTOR_( 0x700, "Program", secint_bad, mac_entry_test )
EXCEPTION_PREAMBLE
TRACE(0x700, "Program")
b emulate_instr
/************************************************************************/
/* FPU Unavailable Exception */
/************************************************************************/
// FPU_STATE_IN_USE - we own the fpu and its ready for use
// FPU_STATE_DIRTY - fr13 & fpscr are not loaded (everything else is).
// FPU_STATE_HALF_SAVED - fr14-fr31 are loaded.
// FPU_STATE_SAVED - fr14-fr31 are loaded (but also saved in mregs).
//
// FPU_STATE_DIRTY in the *emulator* means that all floating point
// registers *EXCEPT* fr13 and fpscr are valid.
VECTOR( 0x800, "FPU Unavailable", secint_lr_call )
EXCEPTION_PREAMBLE
TRACE(0x800, "FPU Unavailable")
fpu_cont:
lwz r2,xMSR(r1)
andi. r4,r2,MSR_FP
beq- mac_fpu_unavailable
lwz r4,xFPU_STATE(r1)
cmpwi r4,FPU_STATE_IN_USE // We are currently the owner of the FPU
beq 22f
lwz r3,K_EMULATOR_MSR(r1)
andi. r4,r3,MSR_FP
bne+ enable_fpu
MAC_EXIT_SAVE( RVEC_ENABLE_FPU )
mac_fpu_unavailable:
li r5,0 // r5 = srr1 bits
MAC_TRAP( 0x800 )
enable_fpu:
ENABLE_MSR_FP /**/ r4 // Enable kernel FPU
// flag the fpu dirty
lwz r3,xFPU_STATE(r1)
lfd fr13,xFPSCR-4(r1) // fp13 and fpscr are *ALWAYS* saved
cmpwi r3,FPU_STATE_HALF_SAVED
mtfsf 0xff,fr13
li r4,FPU_STATE_IN_USE
lfd fr13,xFPR13(r1)
bne 1f
xLOAD_LOW_FPU r1 // load fr0-fr12
1:
stw r4,xFPU_STATE(r1) //
22: lwz r3,x_MSR(r1) // Enable MSR_FP
ori r3,r3,MSR_FP
mtsrr1 r3 // Update both srr1 and x_MSR
stw r3,x_MSR(r1)
b exception_return
/************************************************************************/
/* Decrementer Exception */
/************************************************************************/
// The 0x900 decrementer vector is in dec.S
/************************************************************************/
/* System Call Exception */
/************************************************************************/
VECTOR( 0xc00, "System Call", secint_bad )
EXCEPTION_PREAMBLE
TRACE( 0xc00, "System Call")
lwz r3,xGPR3(r1)
LOADI r5,OSI_SC_MAGIC_R3
lwz r4,xGPR4(r1)
LOADI r2,OSI_SC_MAGIC_R4
cmpw cr1,r3,r5
cmpw cr0,r4,r2
crand eq,eq,cr1*4+eq
beq+ 2f
li r5,0 // r5=srr1 bits
MAC_TRAP(0xc00)
2:
MAC_EXIT_SAVE( RVEC_OSI_SYSCALL )
/************************************************************************/
/* Trace Exception */
/************************************************************************/
VECTOR( 0xd00, "Trace", secint_bad )
trace_vector:
EXCEPTION_PREAMBLE
TRACE(0xd00, "Trace")
MAC_EXIT_SAVE( RVEC_TRACE_TRAP );
/************************************************************************/
/* AltiVec Exception */
/************************************************************************/
VECTOR( 0xf20, "AltiVec", secint_lr_call )
EXCEPTION_PREAMBLE
TRACE(0xf20, "AltiVec")
altivec_cont:
lwz r4,xNO_ALTIVEC(r1) // AltiVec support disabled?
cmpwi r4,0
bne- mac_altivec_unavailable
lwz r2,xMSR(r1)
rlwinm. r4,r2,0,6,6 // bit 6 = MSR_VEC
beq- mac_altivec_unavailable
lwz r3,K_EMULATOR_MSR(r1)
rlwinm. r4,r3,0,6,6 // bit 6 = MSR_VEC
bne+ enable_altivec
MAC_EXIT_SAVE( RVEC_ENABLE_ALTIVEC )
mac_altivec_unavailable:
MAC_EXIT_SAVE( RVEC_ALTIVEC_UNAVAIL_TRAP )
enable_altivec:
// We don't need to load any registers since the emulator
// won't touch the altivec unit (at least for now).
lwz r3,x_MSR(r1)
oris r3,r3,MSR_VEC@h
mtsrr1 r3
stw r3,x_MSR(r1)
b exception_return
VECTOR( 0x1600, "AltiVec Assist", secint_bad )
EXCEPTION_SAVE_ALL
TRACE(0x1600, "AltiVec Assist")
mfsrr1 r4
MAC_EXIT( RVEC_ALTIVEC_ASSIST ) // r4 = srr1
/************************************************************************/
/* Instruction Breakpoint */
/************************************************************************/
VECTOR( 0x1300, "Instruction Breakpoint", secint_bad )
EXCEPTION_SAVE_ALL
TRACE(0x1300, "IABR")
DEBUGGER(0x1300)
/************************************************************************/
/* RunMode-601 (trace) */
/************************************************************************/
VECTOR( 0x2000, "RunMode-601", secint_bad )
b trace_vector
/************************************************************************/
/* Secondary Interrupt Handlers */
/************************************************************************/
//////////////////////////////////////////////////////////////////////
// secint_xxx
//
// r1: stack (sprg1 = old r1)
// r3: vector addr (sprg0 = old r3)
// srr0/srr1: kernel nip/msr
//
// secint_lr_call:
// lr secondary interrupt handler
secint_bad:
TRACE(0xbad, "secint_bad")
mr r4,r3
MAC_EXIT( RVEC_INTERNAL_ERROR )
secint_lr_call:
blrl
li r4,0x6666
MAC_EXIT( RVEC_INTERNAL_ERROR )
/**************************************************************
* Includes
**************************************************************/
// We need to be sure this code is contiguous, the simplest/safest
// method is using only a single file. This will also effectively
// reduce the size of the relocation table.
#include "entry.S"
#include "dec.S"
#include "603.S"
#include "emulation.S"
#include "iopage.S"
#include "splitmode.S"
#include "linux.S"
#include "ptintercept.S"
GLOBAL_SYMBOL(r__reloctable_end):
|