1/* 2 * Copyright 2006-2010, Ingo Weinhold <ingo_weinhold@gmx.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 * 5 * Copyright 2003, Travis Geiselbrecht. All rights reserved. 6 * Distributed under the terms of the NewOS License. 7 */ 8 9 10#include "asm_offsets.h" 11 12#define FUNCTION(x) .global x; .type x,@function; x 13 14#define MSR_EXCEPTIONS_ENABLED 15 15 16.text 17 18// ToDo: fixme 19FUNCTION(reboot): 20 b . 21 22 23/* void arch_int_enable_interrupts(void) */ 24FUNCTION(arch_int_enable_interrupts): 25 mfmsr %r3 // load msr 26 27 li %r4, 1 28 insrwi %r3, %r4, 1, 31 - MSR_EXCEPTIONS_ENABLED 29 // sets bit 15, EE 30 31 mtmsr %r3 // put it back into the msr 32 isync 33 blr 34 35 36/* int arch_int_disable_interrupts(void) 37 * r3 38 */ 39FUNCTION(arch_int_disable_interrupts): 40 mfmsr %r4 // load msr 41 42 mr %r3, %r4 // save old state 43 rlwinm %r4, %r4, 0, 32 - MSR_EXCEPTIONS_ENABLED, 30 - MSR_EXCEPTIONS_ENABLED 44 // clears bit 15, EE 45 46 mtmsr %r4 // put it back into the msr 47 isync 48 blr 49 50 51/* void arch_int_restore_interrupts(int oldState) 52 * r3 53 */ 54FUNCTION(arch_int_restore_interrupts): 55 mfmsr %r4 56 57 rlwimi %r4, %r3, 0, 31 - MSR_EXCEPTIONS_ENABLED, 31 - MSR_EXCEPTIONS_ENABLED 58 // clear or set bit 15, EE to the same state as in r3, oldState 59 60 mtmsr %r4 61 isync 62 blr 63 64/* bool arch_int_are_interrupts_enabled(void) */ 65FUNCTION(arch_int_are_interrupts_enabled): 66 mfmsr %r3 // load msr 67 extrwi %r3, %r3, 1, 31 - MSR_EXCEPTIONS_ENABLED 68 // mask out the EE bit 69 blr 70 71 72// ToDo: fixme 73FUNCTION(dbg_save_registers): 74 blr 75 76/* long long get_time_base(void) */ 77FUNCTION(get_time_base): 781: 79 mftbu %r3 // get the upper time base register 80 mftb %r4 // get the lower time base register 81 mftbu %r5 // get the upper again 82 cmpw %r5, %r3 // see if it changed while we were reading the lower 83 bne- 1b // if so, repeat 84 blr 85 86/* void getibats(int bats[8]); */ 87FUNCTION(getibats): 88 mfibatu %r0,0 89 stw %r0,0(%r3) 90 mfibatl %r0,0 91 stwu %r0,4(%r3) 92 mfibatu %r0,1 93 stwu %r0,4(%r3) 94 mfibatl %r0,1 95 stwu %r0,4(%r3) 96 mfibatu %r0,2 97 stwu %r0,4(%r3) 98 mfibatl %r0,2 99 stwu %r0,4(%r3) 100 mfibatu %r0,3 101 stwu %r0,4(%r3) 102 mfibatl %r0,3 103 stwu %r0,4(%r3) 104 blr 105 106// void setibats(int bats[8]); 107FUNCTION(setibats): 108 lwz %r0,0(%r3) 109 mtibatu 0,%r0 110 isync 111 lwzu %r0,4(%r3) 112 mtibatl 0,%r0 113 isync 114 lwzu %r0,4(%r3) 115 mtibatu 1,%r0 116 isync 117 lwzu %r0,4(%r3) 118 mtibatl 1,%r0 119 isync 120 lwzu %r0,4(%r3) 121 mtibatu 2,%r0 122 isync 123 lwzu %r0,4(%r3) 124 mtibatl 2,%r0 125 isync 126 lwzu %r0,4(%r3) 127 mtibatu 3,%r0 128 isync 129 lwzu %r0,4(%r3) 130 mtibatl 3,%r0 131 isync 132 133 blr 134 135// void getdbats(int bats[8]); 136FUNCTION(getdbats): 137 mfdbatu %r0,0 138 stw %r0,0(%r3) 139 mfdbatl %r0,0 140 stwu %r0,4(%r3) 141 mfdbatu %r0,1 142 stwu %r0,4(%r3) 143 mfdbatl %r0,1 144 stwu %r0,4(%r3) 145 mfdbatu %r0,2 146 stwu %r0,4(%r3) 147 mfdbatl %r0,2 148 stwu %r0,4(%r3) 149 mfdbatu %r0,3 150 stwu %r0,4(%r3) 151 mfdbatl %r0,3 152 stwu %r0,4(%r3) 153 blr 154 155// void setdbats(int bats[8]); 156FUNCTION(setdbats): 157 lwz %r0,0(%r3) 158 mtdbatu 0,%r0 159 lwzu %r0,4(%r3) 160 mtdbatl 0,%r0 161 lwzu %r0,4(%r3) 162 mtdbatu 1,%r0 163 lwzu %r0,4(%r3) 164 mtdbatl 1,%r0 165 lwzu %r0,4(%r3) 166 mtdbatu 2,%r0 167 lwzu %r0,4(%r3) 168 mtdbatl 2,%r0 169 lwzu %r0,4(%r3) 170 mtdbatu 3,%r0 171 lwzu %r0,4(%r3) 172 mtdbatl 3,%r0 173 sync 174 175 blr 176 177// unsigned int gethid0(); 178FUNCTION(gethid0): 179 mfspr %r3, 1008 180 blr 181 182// void sethid0(unsigned int val); 183FUNCTION(sethid0): 184 isync 185 mtspr 1008, %r3 186 isync 187 blr 188 189// unsigned int getl2cr(); 190FUNCTION(getl2cr): 191 mfspr %r3, 1017 192 blr 193 194// void setl2cr(unsigned int val); 195FUNCTION(setl2cr): 196 isync 197 mtspr 1017, %r3 198 isync 199 blr 200 201 202// void ppc_context_switch(addr_t *old_sp, addr_t new_sp); 203FUNCTION(ppc_context_switch): 204 205 // regs to push on the stack: f13-f31, r13-r31, cr, r2, lr 206 207 // push the old regs we need to save on the stack 208 // f31-13 209 stfdu %f31, -8(%r1) 210 stfdu %f30, -8(%r1) 211 stfdu %f29, -8(%r1) 212 stfdu %f28, -8(%r1) 213 stfdu %f27, -8(%r1) 214 stfdu %f26, -8(%r1) 215 stfdu %f25, -8(%r1) 216 stfdu %f24, -8(%r1) 217 stfdu %f23, -8(%r1) 218 stfdu %f22, -8(%r1) 219 stfdu %f21, -8(%r1) 220 stfdu %f20, -8(%r1) 221 stfdu %f19, -8(%r1) 222 stfdu %f18, -8(%r1) 223 stfdu %f17, -8(%r1) 224 stfdu %f16, -8(%r1) 225 stfdu %f15, -8(%r1) 226 stfdu %f14, -8(%r1) 227 stfdu %f13, -8(%r1) 228 229 // r31-13, r2 230 stwu %r31, -4(%r1) 231 stwu %r30, -4(%r1) 232 stwu %r29, -4(%r1) 233 stwu %r28, -4(%r1) 234 stwu %r27, -4(%r1) 235 stwu %r26, -4(%r1) 236 stwu %r25, -4(%r1) 237 stwu %r24, -4(%r1) 238 stwu %r23, -4(%r1) 239 stwu %r22, -4(%r1) 240 stwu %r21, -4(%r1) 241 stwu %r20, -4(%r1) 242 stwu %r19, -4(%r1) 243 stwu %r18, -4(%r1) 244 stwu %r17, -4(%r1) 245 stwu %r16, -4(%r1) 246 stwu %r15, -4(%r1) 247 stwu %r14, -4(%r1) 248 stwu %r13, -4(%r1) 249 stwu %r2, -4(%r1) 250 251 // CR and LR 252 mfcr %r0 253 stwu %r0, -4(%r1) 254 mflr %r0 255 stwu %r0, -4(%r1) 256 257 // save the old stack pointer 258 stwu %r1, 0(%r3) 259 260 // restore the new stack pointer 261 mr %r1, %r4 262 263 // restore the new regs 264 // LR and CR 265 lwz %r0, 0(%r1) 266 mtlr %r0 267 lwzu %r0, 4(%r1) 268 mtcr %r0 269 270 // r2, r13-31 271 lwzu %r2, 4(%r1) 272 lwzu %r13, 4(%r1) 273 lwzu %r14, 4(%r1) 274 lwzu %r15, 4(%r1) 275 lwzu %r16, 4(%r1) 276 lwzu %r17, 4(%r1) 277 lwzu %r18, 4(%r1) 278 lwzu %r19, 4(%r1) 279 lwzu %r20, 4(%r1) 280 lwzu %r21, 4(%r1) 281 lwzu %r22, 4(%r1) 282 lwzu %r23, 4(%r1) 283 lwzu %r24, 4(%r1) 284 lwzu %r25, 4(%r1) 285 lwzu %r26, 4(%r1) 286 lwzu %r27, 4(%r1) 287 lwzu %r28, 4(%r1) 288 lwzu %r29, 4(%r1) 289 lwzu %r30, 4(%r1) 290 lwzu %r31, 4(%r1) 291 292 // f13-31 293 lfdu %f13, 4(%r1) 294 lfdu %f14, 8(%r1) 295 lfdu %f15, 8(%r1) 296 lfdu %f16, 8(%r1) 297 lfdu %f17, 8(%r1) 298 lfdu %f18, 8(%r1) 299 lfdu %f19, 8(%r1) 300 lfdu %f20, 8(%r1) 301 lfdu %f21, 8(%r1) 302 lfdu %f22, 8(%r1) 303 lfdu %f23, 8(%r1) 304 lfdu %f24, 8(%r1) 305 lfdu %f25, 8(%r1) 306 lfdu %f26, 8(%r1) 307 lfdu %f27, 8(%r1) 308 lfdu %f28, 8(%r1) 309 lfdu %f29, 8(%r1) 310 lfdu %f30, 8(%r1) 311 lfdu %f31, 8(%r1) 312 313 addi %r1, %r1, 8 314 315 blr 316 317 318// ppc_kernel_thread_root(): parameters in r13-r15, the functions to call 319// (in that order). The function is used when spawing threads. It usually calls 320// an initialization function, the actual thread function, and a function that 321// destroys the thread. 322FUNCTION(ppc_kernel_thread_root): 323 mtlr %r13 324 blrl 325 mtlr %r14 326 blrl 327 mtlr %r15 328 blrl 329 330 // We should never get here. If we do, it's time to enter the kernel 331 // debugger (without a message at the moment). 332 li %r3, 0 333 b kernel_debugger 334 335 336/*! \fn void arch_debug_call_with_fault_handler(cpu_ent* cpu, 337 jmp_buf jumpBuffer, void (*function)(void*), void* parameter) 338 339 Called by debug_call_with_fault_handler() to do the dirty work of setting 340 the fault handler and calling the function. If the function causes a page 341 fault, the arch_debug_call_with_fault_handler() calls longjmp() with the 342 given \a jumpBuffer. Otherwise it returns normally. 343 344 debug_call_with_fault_handler() has already saved the CPU's fault_handler 345 and fault_handler_stack_pointer and will reset them later, so 346 arch_debug_call_with_fault_handler() doesn't need to care about it. 347 348 \param cpu The \c cpu_ent for the current CPU. 349 \param jumpBuffer Buffer to be used for longjmp(). 350 \param function The function to be called. 351 \param parameter The parameter to be passed to the function to be called. 352*/ 353FUNCTION(arch_debug_call_with_fault_handler): 354 // prolog: setup stack frame (16-byte aligned) 355 mflr %r0 356 stw %r0, 4(%r1) // store LR 357 stwu %r1, -16(%r1) // store back chain 358 stw %r4, 8(%r1) // store jumpBuffer 359 360 // set cpu->fault_handler_stack_pointer 361 stw %r1, CPU_ENT_fault_handler_stack_pointer(%r3) 362 363 // set cpu->fault_handler 364 lis %r11, 1f@ha 365 ori %r11, %r11, 1f@l 366 stw %r11, CPU_ENT_fault_handler(%r3) 367 368 // call the given function 369 mr %r3, %r6 370 mtlr %r5 371 blrl 372 373 // epilog: restore stack frame 374 lwz %r0, 16 + 4(%r1) // load LR 375 mtlr %r0 376 addi %r1, %r1, 16 // restore SP 377 378 blr 379 380 // fault -- return via longjmp(jumpBuffer, 1) 3811: 382 lwz %r3, 8(%r1) // load jumpBuffer 383 384 // call longjmp 385 li %r4, 1 386 lis %r0, longjmp@ha 387 ori %r0, %r0, longjmp@l 388 mtlr %r0 389 blr 390