1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * (C) Copyright 2000-2002 3*4882a593Smuzhiyun * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+ 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun/* 9*4882a593Smuzhiyun * This file contains all the macros and symbols which define 10*4882a593Smuzhiyun * a PowerPC assembly language environment. 11*4882a593Smuzhiyun */ 12*4882a593Smuzhiyun#ifndef __PPC_ASM_TMPL__ 13*4882a593Smuzhiyun#define __PPC_ASM_TMPL__ 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun#include <config.h> 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun/*************************************************************************** 18*4882a593Smuzhiyun * 19*4882a593Smuzhiyun * These definitions simplify the ugly declarations necessary for GOT 20*4882a593Smuzhiyun * definitions. 21*4882a593Smuzhiyun * 22*4882a593Smuzhiyun * Stolen from prepboot/bootldr.h, (C) 1998 Gabriel Paubert, paubert@iram.es 23*4882a593Smuzhiyun * 24*4882a593Smuzhiyun * Uses r12 to access the GOT 25*4882a593Smuzhiyun */ 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun#define START_GOT \ 28*4882a593Smuzhiyun .section ".got2","aw"; \ 29*4882a593Smuzhiyun.LCTOC1 = .+32768 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun#define END_GOT \ 32*4882a593Smuzhiyun .text 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun#define GET_GOT \ 35*4882a593Smuzhiyun bl 1f ; \ 36*4882a593Smuzhiyun .text 2 ; \ 37*4882a593Smuzhiyun0: .long .LCTOC1-1f ; \ 38*4882a593Smuzhiyun .text ; \ 39*4882a593Smuzhiyun1: mflr r12 ; \ 40*4882a593Smuzhiyun lwz r0,0b-1b(r12) ; \ 41*4882a593Smuzhiyun add r12,r0,r12 ; 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun#define GOT_ENTRY(NAME) .L_ ## NAME = . - .LCTOC1 ; .long NAME 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun#define GOT(NAME) .L_ ## NAME (r12) 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun/*************************************************************************** 49*4882a593Smuzhiyun * Register names 50*4882a593Smuzhiyun */ 51*4882a593Smuzhiyun#define r0 0 52*4882a593Smuzhiyun#define r1 1 53*4882a593Smuzhiyun#define r2 2 54*4882a593Smuzhiyun#define r3 3 55*4882a593Smuzhiyun#define r4 4 56*4882a593Smuzhiyun#define r5 5 57*4882a593Smuzhiyun#define r6 6 58*4882a593Smuzhiyun#define r7 7 59*4882a593Smuzhiyun#define r8 8 60*4882a593Smuzhiyun#define r9 9 61*4882a593Smuzhiyun#define r10 10 62*4882a593Smuzhiyun#define r11 11 63*4882a593Smuzhiyun#define r12 12 64*4882a593Smuzhiyun#define r13 13 65*4882a593Smuzhiyun#define r14 14 66*4882a593Smuzhiyun#define r15 15 67*4882a593Smuzhiyun#define r16 16 68*4882a593Smuzhiyun#define r17 17 69*4882a593Smuzhiyun#define r18 18 70*4882a593Smuzhiyun#define r19 19 71*4882a593Smuzhiyun#define r20 20 72*4882a593Smuzhiyun#define r21 21 73*4882a593Smuzhiyun#define r22 22 74*4882a593Smuzhiyun#define r23 23 75*4882a593Smuzhiyun#define r24 24 76*4882a593Smuzhiyun#define r25 25 77*4882a593Smuzhiyun#define r26 26 78*4882a593Smuzhiyun#define r27 27 79*4882a593Smuzhiyun#define r28 28 80*4882a593Smuzhiyun#define r29 29 81*4882a593Smuzhiyun#define r30 30 82*4882a593Smuzhiyun#define r31 31 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun#if defined(CONFIG_MPC8xx) 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun/* Some special registers */ 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun#define ICR 148 /* Interrupt Cause Register (37-44) */ 89*4882a593Smuzhiyun#define DER 149 90*4882a593Smuzhiyun#define COUNTA 150 /* Breakpoint Counter (37-44) */ 91*4882a593Smuzhiyun#define COUNTB 151 /* Breakpoint Counter (37-44) */ 92*4882a593Smuzhiyun#define LCTRL1 156 /* Load/Store Support (37-40) */ 93*4882a593Smuzhiyun#define LCTRL2 157 /* Load/Store Support (37-41) */ 94*4882a593Smuzhiyun#define ICTRL 158 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun#endif /* CONFIG_MPC8xx */ 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun#if defined(CONFIG_MPC8xx) 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun/* Registers in the processor's internal memory map that we use. 102*4882a593Smuzhiyun*/ 103*4882a593Smuzhiyun#define SYPCR 0x00000004 104*4882a593Smuzhiyun#define BR0 0x00000100 105*4882a593Smuzhiyun#define OR0 0x00000104 106*4882a593Smuzhiyun#define BR1 0x00000108 107*4882a593Smuzhiyun#define OR1 0x0000010c 108*4882a593Smuzhiyun#define BR2 0x00000110 109*4882a593Smuzhiyun#define OR2 0x00000114 110*4882a593Smuzhiyun#define BR3 0x00000118 111*4882a593Smuzhiyun#define OR3 0x0000011c 112*4882a593Smuzhiyun#define BR4 0x00000120 113*4882a593Smuzhiyun#define OR4 0x00000124 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun#define MAR 0x00000164 116*4882a593Smuzhiyun#define MCR 0x00000168 117*4882a593Smuzhiyun#define MAMR 0x00000170 118*4882a593Smuzhiyun#define MBMR 0x00000174 119*4882a593Smuzhiyun#define MSTAT 0x00000178 120*4882a593Smuzhiyun#define MPTPR 0x0000017a 121*4882a593Smuzhiyun#define MDR 0x0000017c 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun#define TBSCR 0x00000200 124*4882a593Smuzhiyun#define TBREFF0 0x00000204 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun#define PLPRCR 0x00000284 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun#endif 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun#define curptr r2 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun#define SYNC \ 133*4882a593Smuzhiyun sync; \ 134*4882a593Smuzhiyun isync 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun/* 137*4882a593Smuzhiyun * Macros for storing registers into and loading registers from 138*4882a593Smuzhiyun * exception frames. 139*4882a593Smuzhiyun */ 140*4882a593Smuzhiyun#define SAVE_GPR(n, base) stw n,GPR0+4*(n)(base) 141*4882a593Smuzhiyun#define SAVE_2GPRS(n, base) SAVE_GPR(n, base); SAVE_GPR(n+1, base) 142*4882a593Smuzhiyun#define SAVE_4GPRS(n, base) SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base) 143*4882a593Smuzhiyun#define SAVE_8GPRS(n, base) SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base) 144*4882a593Smuzhiyun#define SAVE_10GPRS(n, base) SAVE_8GPRS(n, base); SAVE_2GPRS(n+8, base) 145*4882a593Smuzhiyun#define REST_GPR(n, base) lwz n,GPR0+4*(n)(base) 146*4882a593Smuzhiyun#define REST_2GPRS(n, base) REST_GPR(n, base); REST_GPR(n+1, base) 147*4882a593Smuzhiyun#define REST_4GPRS(n, base) REST_2GPRS(n, base); REST_2GPRS(n+2, base) 148*4882a593Smuzhiyun#define REST_8GPRS(n, base) REST_4GPRS(n, base); REST_4GPRS(n+4, base) 149*4882a593Smuzhiyun#define REST_10GPRS(n, base) REST_8GPRS(n, base); REST_2GPRS(n+8, base) 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun/* 152*4882a593Smuzhiyun * GCC sometimes accesses words at negative offsets from the stack 153*4882a593Smuzhiyun * pointer, although the SysV ABI says it shouldn't. To cope with 154*4882a593Smuzhiyun * this, we leave this much untouched space on the stack on exception 155*4882a593Smuzhiyun * entry. 156*4882a593Smuzhiyun */ 157*4882a593Smuzhiyun#define STACK_UNDERHEAD 64 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun/* 160*4882a593Smuzhiyun * Exception entry code. This code runs with address translation 161*4882a593Smuzhiyun * turned off, i.e. using physical addresses. 162*4882a593Smuzhiyun * We assume sprg3 has the physical address of the current 163*4882a593Smuzhiyun * task's thread_struct. 164*4882a593Smuzhiyun */ 165*4882a593Smuzhiyun#define EXCEPTION_PROLOG(reg1, reg2) \ 166*4882a593Smuzhiyun mtspr SPRG0,r20; \ 167*4882a593Smuzhiyun mtspr SPRG1,r21; \ 168*4882a593Smuzhiyun mfcr r20; \ 169*4882a593Smuzhiyun subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\ 170*4882a593Smuzhiyun stw r20,_CCR(r21); /* save registers */ \ 171*4882a593Smuzhiyun stw r22,GPR22(r21); \ 172*4882a593Smuzhiyun stw r23,GPR23(r21); \ 173*4882a593Smuzhiyun mfspr r20,SPRG0; \ 174*4882a593Smuzhiyun stw r20,GPR20(r21); \ 175*4882a593Smuzhiyun mfspr r22,SPRG1; \ 176*4882a593Smuzhiyun stw r22,GPR21(r21); \ 177*4882a593Smuzhiyun mflr r20; \ 178*4882a593Smuzhiyun stw r20,_LINK(r21); \ 179*4882a593Smuzhiyun mfctr r22; \ 180*4882a593Smuzhiyun stw r22,_CTR(r21); \ 181*4882a593Smuzhiyun mfspr r20,XER; \ 182*4882a593Smuzhiyun stw r20,_XER(r21); \ 183*4882a593Smuzhiyun mfspr r20, DAR_DEAR; \ 184*4882a593Smuzhiyun stw r20,_DAR(r21); \ 185*4882a593Smuzhiyun mfspr r22,reg1; \ 186*4882a593Smuzhiyun mfspr r23,reg2; \ 187*4882a593Smuzhiyun stw r0,GPR0(r21); \ 188*4882a593Smuzhiyun stw r1,GPR1(r21); \ 189*4882a593Smuzhiyun stw r2,GPR2(r21); \ 190*4882a593Smuzhiyun stw r1,0(r21); \ 191*4882a593Smuzhiyun mr r1,r21; /* set new kernel sp */ \ 192*4882a593Smuzhiyun SAVE_4GPRS(3, r21); 193*4882a593Smuzhiyun/* 194*4882a593Smuzhiyun * Note: code which follows this uses cr0.eq (set if from kernel), 195*4882a593Smuzhiyun * r21, r22 (SRR0), and r23 (SRR1). 196*4882a593Smuzhiyun */ 197*4882a593Smuzhiyun 198*4882a593Smuzhiyun/* 199*4882a593Smuzhiyun * Exception vectors. 200*4882a593Smuzhiyun * 201*4882a593Smuzhiyun * The data words for `hdlr' and `int_return' are initialized with 202*4882a593Smuzhiyun * OFFSET values only; they must be relocated first before they can 203*4882a593Smuzhiyun * be used! 204*4882a593Smuzhiyun */ 205*4882a593Smuzhiyun#define COPY_EE(d, s) rlwimi d,s,0,16,16 206*4882a593Smuzhiyun#define NOCOPY(d, s) 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun#ifdef CONFIG_E500 209*4882a593Smuzhiyun#define EXC_XFER_TEMPLATE(n, label, hdlr, msr, copyee) \ 210*4882a593Smuzhiyun stw r22,_NIP(r21); \ 211*4882a593Smuzhiyun stw r23,_MSR(r21); \ 212*4882a593Smuzhiyun li r23,n; \ 213*4882a593Smuzhiyun stw r23,TRAP(r21); \ 214*4882a593Smuzhiyun li r20,msr; \ 215*4882a593Smuzhiyun copyee(r20,r23); \ 216*4882a593Smuzhiyun rlwimi r20,r23,0,25,25; \ 217*4882a593Smuzhiyun mtmsr r20; \ 218*4882a593Smuzhiyun bl 1f; \ 219*4882a593Smuzhiyun1: mflr r23; \ 220*4882a593Smuzhiyun addis r23,r23,(hdlr - 1b)@ha; \ 221*4882a593Smuzhiyun addi r23,r23,(hdlr - 1b)@l; \ 222*4882a593Smuzhiyun b transfer_to_handler 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun#define STD_EXCEPTION(n, label, hdlr) \ 225*4882a593Smuzhiyun.align 4; \ 226*4882a593Smuzhiyunlabel: \ 227*4882a593Smuzhiyun EXCEPTION_PROLOG(SRR0, SRR1); \ 228*4882a593Smuzhiyun addi r3,r1,STACK_FRAME_OVERHEAD; \ 229*4882a593Smuzhiyun EXC_XFER_TEMPLATE(n, label, hdlr, MSR_KERNEL, NOCOPY) \ 230*4882a593Smuzhiyun 231*4882a593Smuzhiyun#define CRIT_EXCEPTION(n, label, hdlr) \ 232*4882a593Smuzhiyun.align 4; \ 233*4882a593Smuzhiyunlabel: \ 234*4882a593Smuzhiyun EXCEPTION_PROLOG(CSRR0, CSRR1); \ 235*4882a593Smuzhiyun addi r3,r1,STACK_FRAME_OVERHEAD; \ 236*4882a593Smuzhiyun EXC_XFER_TEMPLATE(n, label, hdlr, \ 237*4882a593Smuzhiyun MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ 238*4882a593Smuzhiyun 239*4882a593Smuzhiyun#define MCK_EXCEPTION(n, label, hdlr) \ 240*4882a593Smuzhiyun.align 4; \ 241*4882a593Smuzhiyunlabel: \ 242*4882a593Smuzhiyun EXCEPTION_PROLOG(MCSRR0, MCSRR1); \ 243*4882a593Smuzhiyun addi r3,r1,STACK_FRAME_OVERHEAD; \ 244*4882a593Smuzhiyun EXC_XFER_TEMPLATE(n, label, hdlr, \ 245*4882a593Smuzhiyun MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun#else /* !E500 */ 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun#define EXC_XFER_TEMPLATE(label, hdlr, msr, copyee) \ 250*4882a593Smuzhiyun bl 1f; \ 251*4882a593Smuzhiyun1: mflr r20; \ 252*4882a593Smuzhiyun lwz r20,(.L_ ## label)-1b+8(r20); \ 253*4882a593Smuzhiyun mtlr r20; \ 254*4882a593Smuzhiyun li r20,msr; \ 255*4882a593Smuzhiyun copyee(r20,r23); \ 256*4882a593Smuzhiyun rlwimi r20,r23,0,25,25; \ 257*4882a593Smuzhiyun blrl; \ 258*4882a593Smuzhiyun.L_ ## label : \ 259*4882a593Smuzhiyun .long hdlr - _start + _START_OFFSET; \ 260*4882a593Smuzhiyun .long int_return - _start + _START_OFFSET; \ 261*4882a593Smuzhiyun .long transfer_to_handler - _start + _START_OFFSET 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun#define STD_EXCEPTION(n, label, hdlr) \ 264*4882a593Smuzhiyun . = n; \ 265*4882a593Smuzhiyunlabel: \ 266*4882a593Smuzhiyun EXCEPTION_PROLOG(SRR0, SRR1); \ 267*4882a593Smuzhiyun addi r3,r1,STACK_FRAME_OVERHEAD; \ 268*4882a593Smuzhiyun EXC_XFER_TEMPLATE(label, hdlr, MSR_KERNEL, NOCOPY) \ 269*4882a593Smuzhiyun 270*4882a593Smuzhiyun#define CRIT_EXCEPTION(n, label, hdlr) \ 271*4882a593Smuzhiyun . = n; \ 272*4882a593Smuzhiyunlabel: \ 273*4882a593Smuzhiyun EXCEPTION_PROLOG(CSRR0, CSRR1); \ 274*4882a593Smuzhiyun addi r3,r1,STACK_FRAME_OVERHEAD; \ 275*4882a593Smuzhiyun EXC_XFER_TEMPLATE(label, hdlr, \ 276*4882a593Smuzhiyun MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun#define MCK_EXCEPTION(n, label, hdlr) \ 279*4882a593Smuzhiyun . = n; \ 280*4882a593Smuzhiyunlabel: \ 281*4882a593Smuzhiyun EXCEPTION_PROLOG(MCSRR0, MCSRR1); \ 282*4882a593Smuzhiyun addi r3,r1,STACK_FRAME_OVERHEAD; \ 283*4882a593Smuzhiyun EXC_XFER_TEMPLATE(label, hdlr, \ 284*4882a593Smuzhiyun MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE), NOCOPY) \ 285*4882a593Smuzhiyun 286*4882a593Smuzhiyun#endif /* !E500 */ 287*4882a593Smuzhiyun#endif /* __PPC_ASM_TMPL__ */ 288