1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */ 2c4df4bc1SMichal Simek/* 3c4df4bc1SMichal Simek * Exception handling for Microblaze 4c4df4bc1SMichal Simek * 5c4df4bc1SMichal Simek * Rewriten interrupt handling 6c4df4bc1SMichal Simek * 7c4df4bc1SMichal Simek * Copyright (C) 2008-2009 Michal Simek <[email protected]> 8c4df4bc1SMichal Simek * Copyright (C) 2008-2009 PetaLogix 9c4df4bc1SMichal Simek * 10c4df4bc1SMichal Simek * uClinux customisation (C) 2005 John Williams 11c4df4bc1SMichal Simek * 12c4df4bc1SMichal Simek * MMU code derived from arch/ppc/kernel/head_4xx.S: 13c4df4bc1SMichal Simek * Copyright (C) 1995-1996 Gary Thomas <[email protected]> 14c4df4bc1SMichal Simek * Initial PowerPC version. 15c4df4bc1SMichal Simek * Copyright (C) 1996 Cort Dougan <[email protected]> 16c4df4bc1SMichal Simek * Rewritten for PReP 17c4df4bc1SMichal Simek * Copyright (C) 1996 Paul Mackerras <[email protected]> 18c4df4bc1SMichal Simek * Low-level exception handers, MMU support, and rewrite. 19c4df4bc1SMichal Simek * Copyright (C) 1997 Dan Malek <[email protected]> 20c4df4bc1SMichal Simek * PowerPC 8xx modifications. 21c4df4bc1SMichal Simek * Copyright (C) 1998-1999 TiVo, Inc. 22c4df4bc1SMichal Simek * PowerPC 403GCX modifications. 23c4df4bc1SMichal Simek * Copyright (C) 1999 Grant Erickson <[email protected]> 24c4df4bc1SMichal Simek * PowerPC 403GCX/405GP modifications. 25c4df4bc1SMichal Simek * Copyright 2000 MontaVista Software Inc. 26c4df4bc1SMichal Simek * PPC405 modifications 27c4df4bc1SMichal Simek * PowerPC 403GCX/405GP modifications. 28c4df4bc1SMichal Simek * Author: MontaVista Software, Inc. 29c4df4bc1SMichal Simek * [email protected] or [email protected] 30c4df4bc1SMichal Simek * [email protected] 31c4df4bc1SMichal Simek * 32c4df4bc1SMichal Simek * Original code 33c4df4bc1SMichal Simek * Copyright (C) 2004 Xilinx, Inc. 34c4df4bc1SMichal Simek */ 35c4df4bc1SMichal Simek 36c4df4bc1SMichal Simek/* 37c4df4bc1SMichal Simek * Here are the handlers which don't require enabling translation 38c4df4bc1SMichal Simek * and calling other kernel code thus we can keep their design very simple 39c4df4bc1SMichal Simek * and do all processing in real mode. All what they need is a valid current 40c4df4bc1SMichal Simek * (that is an issue for the CONFIG_REGISTER_TASK_PTR case) 41c4df4bc1SMichal Simek * This handlers use r3,r4,r5,r6 and optionally r[current] to work therefore 42c4df4bc1SMichal Simek * these registers are saved/restored 43c4df4bc1SMichal Simek * The handlers which require translation are in entry.S --KAA 44c4df4bc1SMichal Simek * 45c4df4bc1SMichal Simek * Microblaze HW Exception Handler 46c4df4bc1SMichal Simek * - Non self-modifying exception handler for the following exception conditions 47c4df4bc1SMichal Simek * - Unalignment 48c4df4bc1SMichal Simek * - Instruction bus error 49c4df4bc1SMichal Simek * - Data bus error 50c4df4bc1SMichal Simek * - Illegal instruction opcode 51c4df4bc1SMichal Simek * - Divide-by-zero 52c4df4bc1SMichal Simek * 537db29ddeSMichal Simek * - Privileged instruction exception (MMU) 547db29ddeSMichal Simek * - Data storage exception (MMU) 557db29ddeSMichal Simek * - Instruction storage exception (MMU) 567db29ddeSMichal Simek * - Data TLB miss exception (MMU) 577db29ddeSMichal Simek * - Instruction TLB miss exception (MMU) 587db29ddeSMichal Simek * 59c4df4bc1SMichal Simek * Note we disable interrupts during exception handling, otherwise we will 60c4df4bc1SMichal Simek * possibly get multiple re-entrancy if interrupt handles themselves cause 61c4df4bc1SMichal Simek * exceptions. JW 62c4df4bc1SMichal Simek */ 63c4df4bc1SMichal Simek 64c4df4bc1SMichal Simek#include <asm/exceptions.h> 65c4df4bc1SMichal Simek#include <asm/unistd.h> 66c4df4bc1SMichal Simek#include <asm/page.h> 67c4df4bc1SMichal Simek 68c4df4bc1SMichal Simek#include <asm/entry.h> 69c4df4bc1SMichal Simek#include <asm/current.h> 70c4df4bc1SMichal Simek#include <linux/linkage.h> 7165fddcfcSMike Rapoport#include <linux/pgtable.h> 72c4df4bc1SMichal Simek 73c4df4bc1SMichal Simek#include <asm/mmu.h> 743863dbceSMichal Simek#include <asm/signal.h> 7591836710SMichal Simek#include <asm/registers.h> 76c4df4bc1SMichal Simek#include <asm/asm-offsets.h> 77c4df4bc1SMichal Simek 78c06b3a06SMichal Simek#undef DEBUG 79c06b3a06SMichal Simek 80c4df4bc1SMichal Simek/* Helpful Macros */ 81c4df4bc1SMichal Simek#define NUM_TO_REG(num) r ## num 82c4df4bc1SMichal Simek 837db29ddeSMichal Simek #define RESTORE_STATE \ 84ac854ff1SMichal Simek lwi r5, r1, 0; \ 85ac854ff1SMichal Simek mts rmsr, r5; \ 86ac854ff1SMichal Simek nop; \ 877db29ddeSMichal Simek lwi r3, r1, PT_R3; \ 887db29ddeSMichal Simek lwi r4, r1, PT_R4; \ 897db29ddeSMichal Simek lwi r5, r1, PT_R5; \ 907db29ddeSMichal Simek lwi r6, r1, PT_R6; \ 917db29ddeSMichal Simek lwi r11, r1, PT_R11; \ 927db29ddeSMichal Simek lwi r31, r1, PT_R31; \ 936e83557cSMichal Simek lwi r1, r1, PT_R1; 947db29ddeSMichal Simek 95c4df4bc1SMichal Simek#define LWREG_NOP \ 96c4df4bc1SMichal Simek bri ex_handler_unhandled; \ 97c4df4bc1SMichal Simek nop; 98c4df4bc1SMichal Simek 99c4df4bc1SMichal Simek#define SWREG_NOP \ 100c4df4bc1SMichal Simek bri ex_handler_unhandled; \ 101c4df4bc1SMichal Simek nop; 102c4df4bc1SMichal Simek 103c4df4bc1SMichal Simek/* r3 is the source */ 104c4df4bc1SMichal Simek#define R3_TO_LWREG_V(regnum) \ 105c4df4bc1SMichal Simek swi r3, r1, 4 * regnum; \ 106c4df4bc1SMichal Simek bri ex_handler_done; 107c4df4bc1SMichal Simek 108c4df4bc1SMichal Simek/* r3 is the source */ 109c4df4bc1SMichal Simek#define R3_TO_LWREG(regnum) \ 110c4df4bc1SMichal Simek or NUM_TO_REG (regnum), r0, r3; \ 111c4df4bc1SMichal Simek bri ex_handler_done; 112c4df4bc1SMichal Simek 113c4df4bc1SMichal Simek/* r3 is the target */ 114c4df4bc1SMichal Simek#define SWREG_TO_R3_V(regnum) \ 115c4df4bc1SMichal Simek lwi r3, r1, 4 * regnum; \ 116c4df4bc1SMichal Simek bri ex_sw_tail; 117c4df4bc1SMichal Simek 118c4df4bc1SMichal Simek/* r3 is the target */ 119c4df4bc1SMichal Simek#define SWREG_TO_R3(regnum) \ 120c4df4bc1SMichal Simek or r3, r0, NUM_TO_REG (regnum); \ 121c4df4bc1SMichal Simek bri ex_sw_tail; 122c4df4bc1SMichal Simek 1237db29ddeSMichal Simek #define R3_TO_LWREG_VM_V(regnum) \ 1247db29ddeSMichal Simek brid ex_lw_end_vm; \ 1257db29ddeSMichal Simek swi r3, r7, 4 * regnum; 1267db29ddeSMichal Simek 1277db29ddeSMichal Simek #define R3_TO_LWREG_VM(regnum) \ 1287db29ddeSMichal Simek brid ex_lw_end_vm; \ 1297db29ddeSMichal Simek or NUM_TO_REG (regnum), r0, r3; 1307db29ddeSMichal Simek 1317db29ddeSMichal Simek #define SWREG_TO_R3_VM_V(regnum) \ 1327db29ddeSMichal Simek brid ex_sw_tail_vm; \ 1337db29ddeSMichal Simek lwi r3, r7, 4 * regnum; 1347db29ddeSMichal Simek 1357db29ddeSMichal Simek #define SWREG_TO_R3_VM(regnum) \ 1367db29ddeSMichal Simek brid ex_sw_tail_vm; \ 1377db29ddeSMichal Simek or r3, r0, NUM_TO_REG (regnum); 1387db29ddeSMichal Simek 1397db29ddeSMichal Simek /* Shift right instruction depending on available configuration */ 14052ade599SMichal Simek #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL == 0 1417db29ddeSMichal Simek /* Only the used shift constants defined here - add more if needed */ 1427db29ddeSMichal Simek #define BSRLI2(rD, rA) \ 1437db29ddeSMichal Simek srl rD, rA; /* << 1 */ \ 1447db29ddeSMichal Simek srl rD, rD; /* << 2 */ 14552ade599SMichal Simek #define BSRLI4(rD, rA) \ 14652ade599SMichal Simek BSRLI2(rD, rA); \ 14752ade599SMichal Simek BSRLI2(rD, rD) 1487db29ddeSMichal Simek #define BSRLI10(rD, rA) \ 1497db29ddeSMichal Simek srl rD, rA; /* << 1 */ \ 1507db29ddeSMichal Simek srl rD, rD; /* << 2 */ \ 1517db29ddeSMichal Simek srl rD, rD; /* << 3 */ \ 1527db29ddeSMichal Simek srl rD, rD; /* << 4 */ \ 1537db29ddeSMichal Simek srl rD, rD; /* << 5 */ \ 1547db29ddeSMichal Simek srl rD, rD; /* << 6 */ \ 1557db29ddeSMichal Simek srl rD, rD; /* << 7 */ \ 1567db29ddeSMichal Simek srl rD, rD; /* << 8 */ \ 1577db29ddeSMichal Simek srl rD, rD; /* << 9 */ \ 1587db29ddeSMichal Simek srl rD, rD /* << 10 */ 1597db29ddeSMichal Simek #define BSRLI20(rD, rA) \ 1607db29ddeSMichal Simek BSRLI10(rD, rA); \ 1617db29ddeSMichal Simek BSRLI10(rD, rD) 16252ade599SMichal Simek 16352ade599SMichal Simek .macro bsrli, rD, rA, IMM 16452ade599SMichal Simek .if (\IMM) == 2 16552ade599SMichal Simek BSRLI2(\rD, \rA) 16652ade599SMichal Simek .elseif (\IMM) == 10 16752ade599SMichal Simek BSRLI10(\rD, \rA) 16852ade599SMichal Simek .elseif (\IMM) == 12 16952ade599SMichal Simek BSRLI2(\rD, \rA) 17052ade599SMichal Simek BSRLI10(\rD, \rD) 17152ade599SMichal Simek .elseif (\IMM) == 14 17252ade599SMichal Simek BSRLI4(\rD, \rA) 17352ade599SMichal Simek BSRLI10(\rD, \rD) 17452ade599SMichal Simek .elseif (\IMM) == 20 17552ade599SMichal Simek BSRLI20(\rD, \rA) 17652ade599SMichal Simek .elseif (\IMM) == 24 17752ade599SMichal Simek BSRLI4(\rD, \rA) 17852ade599SMichal Simek BSRLI20(\rD, \rD) 17952ade599SMichal Simek .elseif (\IMM) == 28 18052ade599SMichal Simek BSRLI4(\rD, \rA) 18152ade599SMichal Simek BSRLI4(\rD, \rD) 18252ade599SMichal Simek BSRLI20(\rD, \rD) 18352ade599SMichal Simek .else 18452ade599SMichal Simek .error "BSRLI shift macros \IMM" 18552ade599SMichal Simek .endif 18652ade599SMichal Simek .endm 1877db29ddeSMichal Simek #endif 18852ade599SMichal Simek 1897db29ddeSMichal Simek 190c4df4bc1SMichal Simek.extern other_exception_handler /* Defined in exception.c */ 191c4df4bc1SMichal Simek 192c4df4bc1SMichal Simek/* 193c4df4bc1SMichal Simek * hw_exception_handler - Handler for exceptions 194c4df4bc1SMichal Simek * 195c4df4bc1SMichal Simek * Exception handler notes: 196c4df4bc1SMichal Simek * - Handles all exceptions 197c4df4bc1SMichal Simek * - Does not handle unaligned exceptions during load into r17, r1, r0. 198c4df4bc1SMichal Simek * - Does not handle unaligned exceptions during store from r17 (cannot be 199c4df4bc1SMichal Simek * done) and r1 (slows down common case) 200c4df4bc1SMichal Simek * 201c4df4bc1SMichal Simek * Relevant register structures 202c4df4bc1SMichal Simek * 203c4df4bc1SMichal Simek * EAR - |----|----|----|----|----|----|----|----| 204c4df4bc1SMichal Simek * - < ## 32 bit faulting address ## > 205c4df4bc1SMichal Simek * 206c4df4bc1SMichal Simek * ESR - |----|----|----|----|----| - | - |-----|-----| 207c4df4bc1SMichal Simek * - W S REG EXC 208c4df4bc1SMichal Simek * 209c4df4bc1SMichal Simek * 210edf6844eSMichael Opdenacker * STACK FRAME STRUCTURE (for CONFIG_MMU=n) 211edf6844eSMichael Opdenacker * ---------------------------------------- 212c4df4bc1SMichal Simek * 213c4df4bc1SMichal Simek * +-------------+ + 0 214c4df4bc1SMichal Simek * | MSR | 215c4df4bc1SMichal Simek * +-------------+ + 4 216c4df4bc1SMichal Simek * | r1 | 217c4df4bc1SMichal Simek * | . | 218c4df4bc1SMichal Simek * | . | 219c4df4bc1SMichal Simek * | . | 220c4df4bc1SMichal Simek * | . | 221c4df4bc1SMichal Simek * | r18 | 222c4df4bc1SMichal Simek * +-------------+ + 76 223c4df4bc1SMichal Simek * | . | 224c4df4bc1SMichal Simek * | . | 225c4df4bc1SMichal Simek * 2266e83557cSMichal Simek * MMU kernel uses the same 'pt_pool_space' pointed space 2276e83557cSMichal Simek * which is used for storing register values - noMMu style was, that values were 228c4df4bc1SMichal Simek * stored in stack but in case of failure you lost information about register. 229c4df4bc1SMichal Simek * Currently you can see register value in memory in specific place. 230c4df4bc1SMichal Simek * In compare to with previous solution the speed should be the same. 231c4df4bc1SMichal Simek * 232c4df4bc1SMichal Simek * MMU exception handler has different handling compare to no MMU kernel. 233c4df4bc1SMichal Simek * Exception handler use jump table for directing of what happen. For MMU kernel 234c4df4bc1SMichal Simek * is this approach better because MMU relate exception are handled by asm code 235c4df4bc1SMichal Simek * in this file. In compare to with MMU expect of unaligned exception 236c4df4bc1SMichal Simek * is everything handled by C code. 237c4df4bc1SMichal Simek */ 238c4df4bc1SMichal Simek 239c4df4bc1SMichal Simek/* 240c4df4bc1SMichal Simek * every of these handlers is entered having R3/4/5/6/11/current saved on stack 241c4df4bc1SMichal Simek * and clobbered so care should be taken to restore them if someone is going to 242c4df4bc1SMichal Simek * return from exception 243c4df4bc1SMichal Simek */ 244c4df4bc1SMichal Simek 245c4df4bc1SMichal Simek/* wrappers to restore state before coming to entry.S */ 2466e83557cSMichal Simek.section .data 2476e83557cSMichal Simek.align 4 2486e83557cSMichal Simekpt_pool_space: 2496e83557cSMichal Simek .space PT_SIZE 2506e83557cSMichal Simek 251c06b3a06SMichal Simek#ifdef DEBUG 252c06b3a06SMichal Simek/* Create space for exception counting. */ 253c06b3a06SMichal Simek.section .data 254c06b3a06SMichal Simek.global exception_debug_table 255c06b3a06SMichal Simek.align 4 256c06b3a06SMichal Simekexception_debug_table: 257c06b3a06SMichal Simek /* Look at exception vector table. There is 32 exceptions * word size */ 258c06b3a06SMichal Simek .space (32 * 4) 259c06b3a06SMichal Simek#endif /* DEBUG */ 260c06b3a06SMichal Simek 2617db29ddeSMichal Simek.section .rodata 2627db29ddeSMichal Simek.align 4 2637db29ddeSMichal Simek_MB_HW_ExceptionVectorTable: 2647db29ddeSMichal Simek/* 0 - Undefined */ 2657db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2667db29ddeSMichal Simek/* 1 - Unaligned data access exception */ 2677db29ddeSMichal Simek .long TOPHYS(handle_unaligned_ex) 2687db29ddeSMichal Simek/* 2 - Illegal op-code exception */ 2697db29ddeSMichal Simek .long TOPHYS(full_exception_trapw) 2707db29ddeSMichal Simek/* 3 - Instruction bus error exception */ 2717db29ddeSMichal Simek .long TOPHYS(full_exception_trapw) 2727db29ddeSMichal Simek/* 4 - Data bus error exception */ 2737db29ddeSMichal Simek .long TOPHYS(full_exception_trapw) 2747db29ddeSMichal Simek/* 5 - Divide by zero exception */ 2757db29ddeSMichal Simek .long TOPHYS(full_exception_trapw) 2767db29ddeSMichal Simek/* 6 - Floating point unit exception */ 2777db29ddeSMichal Simek .long TOPHYS(full_exception_trapw) 2787db29ddeSMichal Simek/* 7 - Privileged instruction exception */ 2797db29ddeSMichal Simek .long TOPHYS(full_exception_trapw) 2807db29ddeSMichal Simek/* 8 - 15 - Undefined */ 2817db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2827db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2837db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2847db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2857db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2867db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2877db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2887db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2897db29ddeSMichal Simek/* 16 - Data storage exception */ 2907db29ddeSMichal Simek .long TOPHYS(handle_data_storage_exception) 2917db29ddeSMichal Simek/* 17 - Instruction storage exception */ 2927db29ddeSMichal Simek .long TOPHYS(handle_instruction_storage_exception) 2937db29ddeSMichal Simek/* 18 - Data TLB miss exception */ 2947db29ddeSMichal Simek .long TOPHYS(handle_data_tlb_miss_exception) 2957db29ddeSMichal Simek/* 19 - Instruction TLB miss exception */ 2967db29ddeSMichal Simek .long TOPHYS(handle_instruction_tlb_miss_exception) 2977db29ddeSMichal Simek/* 20 - 31 - Undefined */ 2987db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 2997db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3007db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3017db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3027db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3037db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3047db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3057db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3067db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3077db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3087db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3097db29ddeSMichal Simek .long TOPHYS(ex_handler_unhandled) 3107db29ddeSMichal Simek 311c4df4bc1SMichal Simek.global _hw_exception_handler 312c4df4bc1SMichal Simek.section .text 313c4df4bc1SMichal Simek.align 4 314c4df4bc1SMichal Simek.ent _hw_exception_handler 315c4df4bc1SMichal Simek_hw_exception_handler: 3166e83557cSMichal Simek swi r1, r0, TOPHYS(pt_pool_space + PT_R1); /* GET_SP */ 3177db29ddeSMichal Simek /* Save date to kernel memory. Here is the problem 3187db29ddeSMichal Simek * when you came from user space */ 3196e83557cSMichal Simek ori r1, r0, TOPHYS(pt_pool_space); 320c4df4bc1SMichal Simek swi r3, r1, PT_R3 321c4df4bc1SMichal Simek swi r4, r1, PT_R4 322c4df4bc1SMichal Simek swi r5, r1, PT_R5 323c4df4bc1SMichal Simek swi r6, r1, PT_R6 324c4df4bc1SMichal Simek 3257db29ddeSMichal Simek swi r11, r1, PT_R11 3267db29ddeSMichal Simek swi r31, r1, PT_R31 3277db29ddeSMichal Simek lwi r31, r0, TOPHYS(PER_CPU(CURRENT_SAVE)) /* get saved current */ 3287db29ddeSMichal Simek 329ac854ff1SMichal Simek mfs r5, rmsr; 330ac854ff1SMichal Simek nop 331ac854ff1SMichal Simek swi r5, r1, 0; 332b175bcfeSMichal Simek mfs r4, resr 333c4df4bc1SMichal Simek nop 334b175bcfeSMichal Simek mfs r3, rear; 3357db29ddeSMichal Simek nop 336c4df4bc1SMichal Simek 337b175bcfeSMichal Simek andi r5, r4, 0x1F; /* Extract ESR[EXC] */ 338c4df4bc1SMichal Simek 3397db29ddeSMichal Simek /* Calculate exception vector offset = r5 << 2 */ 3407db29ddeSMichal Simek addk r6, r5, r5; /* << 1 */ 3417db29ddeSMichal Simek addk r6, r6, r6; /* << 2 */ 3427db29ddeSMichal Simek 343708e7153SMichal Simek#ifdef DEBUG 3447db29ddeSMichal Simek/* counting which exception happen */ 345c06b3a06SMichal Simek lwi r5, r0, TOPHYS(exception_debug_table) 3467db29ddeSMichal Simek addi r5, r5, 1 347c06b3a06SMichal Simek swi r5, r0, TOPHYS(exception_debug_table) 348c06b3a06SMichal Simek lwi r5, r6, TOPHYS(exception_debug_table) 3497db29ddeSMichal Simek addi r5, r5, 1 350c06b3a06SMichal Simek swi r5, r6, TOPHYS(exception_debug_table) 351708e7153SMichal Simek#endif 3527db29ddeSMichal Simek/* end */ 3537db29ddeSMichal Simek /* Load the HW Exception vector */ 3547db29ddeSMichal Simek lwi r6, r6, TOPHYS(_MB_HW_ExceptionVectorTable) 3557db29ddeSMichal Simek bra r6 3567db29ddeSMichal Simek 3577db29ddeSMichal Simekfull_exception_trapw: 3587db29ddeSMichal Simek RESTORE_STATE 3597db29ddeSMichal Simek bri full_exception_trap 360c4df4bc1SMichal Simek 361c4df4bc1SMichal Simek/* 0x01 - Unaligned data access exception 362c4df4bc1SMichal Simek * This occurs when a word access is not aligned on a word boundary, 363c4df4bc1SMichal Simek * or when a 16-bit access is not aligned on a 16-bit boundary. 364c4df4bc1SMichal Simek * This handler perform the access, and returns, except for MMU when 365c4df4bc1SMichal Simek * the unaligned address is last on a 4k page or the physical address is 366c4df4bc1SMichal Simek * not found in the page table, in which case unaligned_data_trap is called. 367c4df4bc1SMichal Simek */ 368c4df4bc1SMichal Simekhandle_unaligned_ex: 369c4df4bc1SMichal Simek /* Working registers already saved: R3, R4, R5, R6 370b175bcfeSMichal Simek * R4 = ESR 371b175bcfeSMichal Simek * R3 = EAR 372c4df4bc1SMichal Simek */ 373b175bcfeSMichal Simek andi r6, r4, 0x1000 /* Check ESR[DS] */ 3747db29ddeSMichal Simek beqi r6, _no_delayslot /* Branch if ESR[DS] not set */ 3757db29ddeSMichal Simek mfs r17, rbtr; /* ESR[DS] set - return address in BTR */ 376c4df4bc1SMichal Simek nop 3777db29ddeSMichal Simek_no_delayslot: 3783863dbceSMichal Simek /* jump to high level unaligned handler */ 3797db29ddeSMichal Simek RESTORE_STATE; 3807db29ddeSMichal Simek bri unaligned_data_trap 381*05cdf457SMichal Simek 382b175bcfeSMichal Simek andi r6, r4, 0x3E0; /* Mask and extract the register operand */ 383c4df4bc1SMichal Simek srl r6, r6; /* r6 >> 5 */ 384c4df4bc1SMichal Simek srl r6, r6; 385c4df4bc1SMichal Simek srl r6, r6; 386c4df4bc1SMichal Simek srl r6, r6; 387c4df4bc1SMichal Simek srl r6, r6; 388c4df4bc1SMichal Simek /* Store the register operand in a temporary location */ 389c4df4bc1SMichal Simek sbi r6, r0, TOPHYS(ex_reg_op); 390c4df4bc1SMichal Simek 391b175bcfeSMichal Simek andi r6, r4, 0x400; /* Extract ESR[S] */ 392c4df4bc1SMichal Simek bnei r6, ex_sw; 393c4df4bc1SMichal Simekex_lw: 394b175bcfeSMichal Simek andi r6, r4, 0x800; /* Extract ESR[W] */ 395c4df4bc1SMichal Simek beqi r6, ex_lhw; 396b175bcfeSMichal Simek lbui r5, r3, 0; /* Exception address in r3 */ 397c4df4bc1SMichal Simek /* Load a word, byte-by-byte from destination address 398c4df4bc1SMichal Simek and save it in tmp space */ 399c4df4bc1SMichal Simek sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); 400b175bcfeSMichal Simek lbui r5, r3, 1; 401c4df4bc1SMichal Simek sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); 402b175bcfeSMichal Simek lbui r5, r3, 2; 403c4df4bc1SMichal Simek sbi r5, r0, TOPHYS(ex_tmp_data_loc_2); 404b175bcfeSMichal Simek lbui r5, r3, 3; 405c4df4bc1SMichal Simek sbi r5, r0, TOPHYS(ex_tmp_data_loc_3); 406b175bcfeSMichal Simek /* Get the destination register value into r4 */ 407b175bcfeSMichal Simek lwi r4, r0, TOPHYS(ex_tmp_data_loc_0); 408c4df4bc1SMichal Simek bri ex_lw_tail; 409c4df4bc1SMichal Simekex_lhw: 410b175bcfeSMichal Simek lbui r5, r3, 0; /* Exception address in r3 */ 411c4df4bc1SMichal Simek /* Load a half-word, byte-by-byte from destination 412c4df4bc1SMichal Simek address and save it in tmp space */ 413c4df4bc1SMichal Simek sbi r5, r0, TOPHYS(ex_tmp_data_loc_0); 414b175bcfeSMichal Simek lbui r5, r3, 1; 415c4df4bc1SMichal Simek sbi r5, r0, TOPHYS(ex_tmp_data_loc_1); 416b175bcfeSMichal Simek /* Get the destination register value into r4 */ 417b175bcfeSMichal Simek lhui r4, r0, TOPHYS(ex_tmp_data_loc_0); 418c4df4bc1SMichal Simekex_lw_tail: 419c4df4bc1SMichal Simek /* Get the destination register number into r5 */ 420c4df4bc1SMichal Simek lbui r5, r0, TOPHYS(ex_reg_op); 421c4df4bc1SMichal Simek /* Form load_word jump table offset (lw_table + (8 * regnum)) */ 422cd341577SMichal Simek addik r6, r0, TOPHYS(lw_table); 423c4df4bc1SMichal Simek addk r5, r5, r5; 424c4df4bc1SMichal Simek addk r5, r5, r5; 425c4df4bc1SMichal Simek addk r5, r5, r5; 426c4df4bc1SMichal Simek addk r5, r5, r6; 427c4df4bc1SMichal Simek bra r5; 428c4df4bc1SMichal Simekex_lw_end: /* Exception handling of load word, ends */ 429c4df4bc1SMichal Simekex_sw: 430c4df4bc1SMichal Simek /* Get the destination register number into r5 */ 431c4df4bc1SMichal Simek lbui r5, r0, TOPHYS(ex_reg_op); 432c4df4bc1SMichal Simek /* Form store_word jump table offset (sw_table + (8 * regnum)) */ 433cd341577SMichal Simek addik r6, r0, TOPHYS(sw_table); 434c4df4bc1SMichal Simek add r5, r5, r5; 435c4df4bc1SMichal Simek add r5, r5, r5; 436c4df4bc1SMichal Simek add r5, r5, r5; 437c4df4bc1SMichal Simek add r5, r5, r6; 438c4df4bc1SMichal Simek bra r5; 439c4df4bc1SMichal Simekex_sw_tail: 440c4df4bc1SMichal Simek mfs r6, resr; 441c4df4bc1SMichal Simek nop 442c4df4bc1SMichal Simek andi r6, r6, 0x800; /* Extract ESR[W] */ 443c4df4bc1SMichal Simek beqi r6, ex_shw; 444c4df4bc1SMichal Simek /* Get the word - delay slot */ 445b175bcfeSMichal Simek swi r4, r0, TOPHYS(ex_tmp_data_loc_0); 446c4df4bc1SMichal Simek /* Store the word, byte-by-byte into destination address */ 447b175bcfeSMichal Simek lbui r4, r0, TOPHYS(ex_tmp_data_loc_0); 448b175bcfeSMichal Simek sbi r4, r3, 0; 449b175bcfeSMichal Simek lbui r4, r0, TOPHYS(ex_tmp_data_loc_1); 450b175bcfeSMichal Simek sbi r4, r3, 1; 451b175bcfeSMichal Simek lbui r4, r0, TOPHYS(ex_tmp_data_loc_2); 452b175bcfeSMichal Simek sbi r4, r3, 2; 453b175bcfeSMichal Simek lbui r4, r0, TOPHYS(ex_tmp_data_loc_3); 454b175bcfeSMichal Simek sbi r4, r3, 3; 455c4df4bc1SMichal Simek bri ex_handler_done; 456c4df4bc1SMichal Simek 457c4df4bc1SMichal Simekex_shw: 458c4df4bc1SMichal Simek /* Store the lower half-word, byte-by-byte into destination address */ 459b175bcfeSMichal Simek swi r4, r0, TOPHYS(ex_tmp_data_loc_0); 460b175bcfeSMichal Simek lbui r4, r0, TOPHYS(ex_tmp_data_loc_2); 461b175bcfeSMichal Simek sbi r4, r3, 0; 462b175bcfeSMichal Simek lbui r4, r0, TOPHYS(ex_tmp_data_loc_3); 463b175bcfeSMichal Simek sbi r4, r3, 1; 464c4df4bc1SMichal Simekex_sw_end: /* Exception handling of store word, ends. */ 465c4df4bc1SMichal Simek 466c4df4bc1SMichal Simekex_handler_done: 4677db29ddeSMichal Simek RESTORE_STATE; 4687db29ddeSMichal Simek rted r17, 0 4697db29ddeSMichal Simek nop 470c4df4bc1SMichal Simek 4717db29ddeSMichal Simek /* Exception vector entry code. This code runs with address translation 4727db29ddeSMichal Simek * turned off (i.e. using physical addresses). */ 4737db29ddeSMichal Simek 4747db29ddeSMichal Simek /* Exception vectors. */ 4757db29ddeSMichal Simek 4767db29ddeSMichal Simek /* 0x10 - Data Storage Exception 4777db29ddeSMichal Simek * This happens for just a few reasons. U0 set (but we don't do that), 4787db29ddeSMichal Simek * or zone protection fault (user violation, write to protected page). 4797db29ddeSMichal Simek * If this is just an update of modified status, we do that quickly 4807db29ddeSMichal Simek * and exit. Otherwise, we call heavyweight functions to do the work. 4817db29ddeSMichal Simek */ 4827db29ddeSMichal Simek handle_data_storage_exception: 4837db29ddeSMichal Simek /* Working registers already saved: R3, R4, R5, R6 4847db29ddeSMichal Simek * R3 = ESR 4857db29ddeSMichal Simek */ 4867db29ddeSMichal Simek mfs r11, rpid 4877db29ddeSMichal Simek nop 4887db29ddeSMichal Simek /* If we are faulting a kernel address, we have to use the 4897db29ddeSMichal Simek * kernel page tables. 4907db29ddeSMichal Simek */ 491bd1637d6SMichal Simek ori r5, r0, CONFIG_KERNEL_START 492bd1637d6SMichal Simek cmpu r5, r3, r5 493bd1637d6SMichal Simek bgti r5, ex3 4947db29ddeSMichal Simek /* First, check if it was a zone fault (which means a user 4957db29ddeSMichal Simek * tried to access a kernel or read-protected page - always 4967db29ddeSMichal Simek * a SEGV). All other faults here must be stores, so no 4977db29ddeSMichal Simek * need to check ESR_S as well. */ 49891836710SMichal Simek andi r4, r4, ESR_DIZ /* ESR_Z - zone protection */ 4997db29ddeSMichal Simek bnei r4, ex2 5007db29ddeSMichal Simek 5017db29ddeSMichal Simek ori r4, r0, swapper_pg_dir 5027db29ddeSMichal Simek mts rpid, r0 /* TLB will have 0 TID */ 5037db29ddeSMichal Simek nop 5047db29ddeSMichal Simek bri ex4 5057db29ddeSMichal Simek 5067db29ddeSMichal Simek /* Get the PGD for the current thread. */ 5077db29ddeSMichal Simek ex3: 5087db29ddeSMichal Simek /* First, check if it was a zone fault (which means a user 5097db29ddeSMichal Simek * tried to access a kernel or read-protected page - always 5107db29ddeSMichal Simek * a SEGV). All other faults here must be stores, so no 5117db29ddeSMichal Simek * need to check ESR_S as well. */ 51291836710SMichal Simek andi r4, r4, ESR_DIZ /* ESR_Z */ 5137db29ddeSMichal Simek bnei r4, ex2 5147db29ddeSMichal Simek /* get current task address */ 5157db29ddeSMichal Simek addi r4 ,CURRENT_TASK, TOPHYS(0); 5167db29ddeSMichal Simek lwi r4, r4, TASK_THREAD+PGDIR 5177db29ddeSMichal Simek ex4: 5187db29ddeSMichal Simek tophys(r4,r4) 5199f78d3b5SMichal Simek /* Create L1 (pgdir/pmd) address */ 52052ade599SMichal Simek bsrli r5, r3, PGDIR_SHIFT - 2 5219f78d3b5SMichal Simek andi r5, r5, PAGE_SIZE - 4 5227db29ddeSMichal Simek/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */ 5237db29ddeSMichal Simek or r4, r4, r5 5247db29ddeSMichal Simek lwi r4, r4, 0 /* Get L1 entry */ 5259f78d3b5SMichal Simek andi r5, r4, PAGE_MASK /* Extract L2 (pte) base address */ 5267db29ddeSMichal Simek beqi r5, ex2 /* Bail if no table */ 5277db29ddeSMichal Simek 5287db29ddeSMichal Simek tophys(r5,r5) 52952ade599SMichal Simek bsrli r6, r3, PTE_SHIFT /* Compute PTE address */ 5309f78d3b5SMichal Simek andi r6, r6, PAGE_SIZE - 4 5317db29ddeSMichal Simek or r5, r5, r6 5327db29ddeSMichal Simek lwi r4, r5, 0 /* Get Linux PTE */ 5337db29ddeSMichal Simek 5347db29ddeSMichal Simek andi r6, r4, _PAGE_RW /* Is it writeable? */ 5357db29ddeSMichal Simek beqi r6, ex2 /* Bail if not */ 5367db29ddeSMichal Simek 5377db29ddeSMichal Simek /* Update 'changed' */ 5387db29ddeSMichal Simek ori r4, r4, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE 5397db29ddeSMichal Simek swi r4, r5, 0 /* Update Linux page table */ 5407db29ddeSMichal Simek 5417db29ddeSMichal Simek /* Most of the Linux PTE is ready to load into the TLB LO. 5427db29ddeSMichal Simek * We set ZSEL, where only the LS-bit determines user access. 5437db29ddeSMichal Simek * We set execute, because we don't have the granularity to 5447db29ddeSMichal Simek * properly set this at the page level (Linux problem). 5457db29ddeSMichal Simek * If shared is set, we cause a zero PID->TID load. 5467db29ddeSMichal Simek * Many of these bits are software only. Bits we don't set 5477db29ddeSMichal Simek * here we (properly should) assume have the appropriate value. 5487db29ddeSMichal Simek */ 5499f78d3b5SMichal Simek/* Ignore memory coherent, just LSB on ZSEL is used + EX/WR */ 5509f78d3b5SMichal Simek andi r4, r4, PAGE_MASK | TLB_EX | TLB_WR | \ 5519f78d3b5SMichal Simek TLB_ZSEL(1) | TLB_ATTR_MASK 5527db29ddeSMichal Simek ori r4, r4, _PAGE_HWEXEC /* make it executable */ 5537db29ddeSMichal Simek 5547db29ddeSMichal Simek /* find the TLB index that caused the fault. It has to be here*/ 5557db29ddeSMichal Simek mts rtlbsx, r3 5567db29ddeSMichal Simek nop 5577db29ddeSMichal Simek mfs r5, rtlbx /* DEBUG: TBD */ 5587db29ddeSMichal Simek nop 5597db29ddeSMichal Simek mts rtlblo, r4 /* Load TLB LO */ 5607db29ddeSMichal Simek nop 5617db29ddeSMichal Simek /* Will sync shadow TLBs */ 5627db29ddeSMichal Simek 5637db29ddeSMichal Simek /* Done...restore registers and get out of here. */ 5647db29ddeSMichal Simek mts rpid, r11 5657db29ddeSMichal Simek nop 5667db29ddeSMichal Simek bri 4 5677db29ddeSMichal Simek 5687db29ddeSMichal Simek RESTORE_STATE; 5697db29ddeSMichal Simek rted r17, 0 5707db29ddeSMichal Simek nop 5717db29ddeSMichal Simek ex2: 5727db29ddeSMichal Simek /* The bailout. Restore registers to pre-exception conditions 5737db29ddeSMichal Simek * and call the heavyweights to help us out. */ 5747db29ddeSMichal Simek mts rpid, r11 5757db29ddeSMichal Simek nop 5767db29ddeSMichal Simek bri 4 5777db29ddeSMichal Simek RESTORE_STATE; 5787db29ddeSMichal Simek bri page_fault_data_trap 5797db29ddeSMichal Simek 5807db29ddeSMichal Simek 5817db29ddeSMichal Simek /* 0x11 - Instruction Storage Exception 5827db29ddeSMichal Simek * This is caused by a fetch from non-execute or guarded pages. */ 5837db29ddeSMichal Simek handle_instruction_storage_exception: 5847db29ddeSMichal Simek /* Working registers already saved: R3, R4, R5, R6 5857db29ddeSMichal Simek * R3 = ESR 5867db29ddeSMichal Simek */ 5877db29ddeSMichal Simek 5887db29ddeSMichal Simek RESTORE_STATE; 5897db29ddeSMichal Simek bri page_fault_instr_trap 5907db29ddeSMichal Simek 5917db29ddeSMichal Simek /* 0x12 - Data TLB Miss Exception 5927db29ddeSMichal Simek * As the name implies, translation is not in the MMU, so search the 5937db29ddeSMichal Simek * page tables and fix it. The only purpose of this function is to 5947db29ddeSMichal Simek * load TLB entries from the page table if they exist. 5957db29ddeSMichal Simek */ 5967db29ddeSMichal Simek handle_data_tlb_miss_exception: 5977db29ddeSMichal Simek /* Working registers already saved: R3, R4, R5, R6 5987a6bbdc9SMichal Simek * R3 = EAR, R4 = ESR 5997db29ddeSMichal Simek */ 6007db29ddeSMichal Simek mfs r11, rpid 6017db29ddeSMichal Simek nop 6027db29ddeSMichal Simek 6037db29ddeSMichal Simek /* If we are faulting a kernel address, we have to use the 6047db29ddeSMichal Simek * kernel page tables. */ 6057a6bbdc9SMichal Simek ori r6, r0, CONFIG_KERNEL_START 6067a6bbdc9SMichal Simek cmpu r4, r3, r6 6077db29ddeSMichal Simek bgti r4, ex5 6087db29ddeSMichal Simek ori r4, r0, swapper_pg_dir 6097db29ddeSMichal Simek mts rpid, r0 /* TLB will have 0 TID */ 6107db29ddeSMichal Simek nop 6117db29ddeSMichal Simek bri ex6 6127db29ddeSMichal Simek 6137db29ddeSMichal Simek /* Get the PGD for the current thread. */ 6147db29ddeSMichal Simek ex5: 6157db29ddeSMichal Simek /* get current task address */ 6167db29ddeSMichal Simek addi r4 ,CURRENT_TASK, TOPHYS(0); 6177db29ddeSMichal Simek lwi r4, r4, TASK_THREAD+PGDIR 6187db29ddeSMichal Simek ex6: 6197db29ddeSMichal Simek tophys(r4,r4) 6209f78d3b5SMichal Simek /* Create L1 (pgdir/pmd) address */ 62152ade599SMichal Simek bsrli r5, r3, PGDIR_SHIFT - 2 6229f78d3b5SMichal Simek andi r5, r5, PAGE_SIZE - 4 6237db29ddeSMichal Simek/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */ 6247db29ddeSMichal Simek or r4, r4, r5 6257db29ddeSMichal Simek lwi r4, r4, 0 /* Get L1 entry */ 6269f78d3b5SMichal Simek andi r5, r4, PAGE_MASK /* Extract L2 (pte) base address */ 6277db29ddeSMichal Simek beqi r5, ex7 /* Bail if no table */ 6287db29ddeSMichal Simek 6297db29ddeSMichal Simek tophys(r5,r5) 63052ade599SMichal Simek bsrli r6, r3, PTE_SHIFT /* Compute PTE address */ 6319f78d3b5SMichal Simek andi r6, r6, PAGE_SIZE - 4 6327db29ddeSMichal Simek or r5, r5, r6 6337db29ddeSMichal Simek lwi r4, r5, 0 /* Get Linux PTE */ 6347db29ddeSMichal Simek 6357db29ddeSMichal Simek andi r6, r4, _PAGE_PRESENT 6367db29ddeSMichal Simek beqi r6, ex7 6377db29ddeSMichal Simek 6387db29ddeSMichal Simek ori r4, r4, _PAGE_ACCESSED 6397db29ddeSMichal Simek swi r4, r5, 0 6407db29ddeSMichal Simek 6417db29ddeSMichal Simek /* Most of the Linux PTE is ready to load into the TLB LO. 6427db29ddeSMichal Simek * We set ZSEL, where only the LS-bit determines user access. 6437db29ddeSMichal Simek * We set execute, because we don't have the granularity to 6447db29ddeSMichal Simek * properly set this at the page level (Linux problem). 6457db29ddeSMichal Simek * If shared is set, we cause a zero PID->TID load. 6467db29ddeSMichal Simek * Many of these bits are software only. Bits we don't set 6477db29ddeSMichal Simek * here we (properly should) assume have the appropriate value. 6487db29ddeSMichal Simek */ 6493765d695SMichal Simek brid finish_tlb_load 6509f78d3b5SMichal Simek andi r4, r4, PAGE_MASK | TLB_EX | TLB_WR | \ 6519f78d3b5SMichal Simek TLB_ZSEL(1) | TLB_ATTR_MASK 6527db29ddeSMichal Simek ex7: 6537db29ddeSMichal Simek /* The bailout. Restore registers to pre-exception conditions 6547db29ddeSMichal Simek * and call the heavyweights to help us out. 6557db29ddeSMichal Simek */ 6567db29ddeSMichal Simek mts rpid, r11 6577db29ddeSMichal Simek nop 6587db29ddeSMichal Simek bri 4 6597db29ddeSMichal Simek RESTORE_STATE; 6607db29ddeSMichal Simek bri page_fault_data_trap 6617db29ddeSMichal Simek 6627db29ddeSMichal Simek /* 0x13 - Instruction TLB Miss Exception 6637db29ddeSMichal Simek * Nearly the same as above, except we get our information from 6647db29ddeSMichal Simek * different registers and bailout to a different point. 6657db29ddeSMichal Simek */ 6667db29ddeSMichal Simek handle_instruction_tlb_miss_exception: 6677db29ddeSMichal Simek /* Working registers already saved: R3, R4, R5, R6 6687db29ddeSMichal Simek * R3 = ESR 6697db29ddeSMichal Simek */ 6707db29ddeSMichal Simek mfs r11, rpid 6717db29ddeSMichal Simek nop 6727db29ddeSMichal Simek 6737db29ddeSMichal Simek /* If we are faulting a kernel address, we have to use the 6747db29ddeSMichal Simek * kernel page tables. 6757db29ddeSMichal Simek */ 6767db29ddeSMichal Simek ori r4, r0, CONFIG_KERNEL_START 6777db29ddeSMichal Simek cmpu r4, r3, r4 6787db29ddeSMichal Simek bgti r4, ex8 6797db29ddeSMichal Simek ori r4, r0, swapper_pg_dir 6807db29ddeSMichal Simek mts rpid, r0 /* TLB will have 0 TID */ 6817db29ddeSMichal Simek nop 6827db29ddeSMichal Simek bri ex9 6837db29ddeSMichal Simek 6847db29ddeSMichal Simek /* Get the PGD for the current thread. */ 6857db29ddeSMichal Simek ex8: 6867db29ddeSMichal Simek /* get current task address */ 6877db29ddeSMichal Simek addi r4 ,CURRENT_TASK, TOPHYS(0); 6887db29ddeSMichal Simek lwi r4, r4, TASK_THREAD+PGDIR 6897db29ddeSMichal Simek ex9: 6907db29ddeSMichal Simek tophys(r4,r4) 6919f78d3b5SMichal Simek /* Create L1 (pgdir/pmd) address */ 69252ade599SMichal Simek bsrli r5, r3, PGDIR_SHIFT - 2 6939f78d3b5SMichal Simek andi r5, r5, PAGE_SIZE - 4 6947db29ddeSMichal Simek/* Assume pgdir aligned on 4K boundary, no need for "andi r4,r4,0xfffff003" */ 6957db29ddeSMichal Simek or r4, r4, r5 6967db29ddeSMichal Simek lwi r4, r4, 0 /* Get L1 entry */ 6979f78d3b5SMichal Simek andi r5, r4, PAGE_MASK /* Extract L2 (pte) base address */ 6987db29ddeSMichal Simek beqi r5, ex10 /* Bail if no table */ 6997db29ddeSMichal Simek 7007db29ddeSMichal Simek tophys(r5,r5) 70152ade599SMichal Simek bsrli r6, r3, PTE_SHIFT /* Compute PTE address */ 7029f78d3b5SMichal Simek andi r6, r6, PAGE_SIZE - 4 7037db29ddeSMichal Simek or r5, r5, r6 7047db29ddeSMichal Simek lwi r4, r5, 0 /* Get Linux PTE */ 7057db29ddeSMichal Simek 7067db29ddeSMichal Simek andi r6, r4, _PAGE_PRESENT 7073765d695SMichal Simek beqi r6, ex10 7087db29ddeSMichal Simek 7097db29ddeSMichal Simek ori r4, r4, _PAGE_ACCESSED 7107db29ddeSMichal Simek swi r4, r5, 0 7117db29ddeSMichal Simek 7127db29ddeSMichal Simek /* Most of the Linux PTE is ready to load into the TLB LO. 7137db29ddeSMichal Simek * We set ZSEL, where only the LS-bit determines user access. 7147db29ddeSMichal Simek * We set execute, because we don't have the granularity to 7157db29ddeSMichal Simek * properly set this at the page level (Linux problem). 7167db29ddeSMichal Simek * If shared is set, we cause a zero PID->TID load. 7177db29ddeSMichal Simek * Many of these bits are software only. Bits we don't set 7187db29ddeSMichal Simek * here we (properly should) assume have the appropriate value. 7197db29ddeSMichal Simek */ 7203765d695SMichal Simek brid finish_tlb_load 7219f78d3b5SMichal Simek andi r4, r4, PAGE_MASK | TLB_EX | TLB_WR | \ 7229f78d3b5SMichal Simek TLB_ZSEL(1) | TLB_ATTR_MASK 7237db29ddeSMichal Simek ex10: 7247db29ddeSMichal Simek /* The bailout. Restore registers to pre-exception conditions 7257db29ddeSMichal Simek * and call the heavyweights to help us out. 7267db29ddeSMichal Simek */ 7277db29ddeSMichal Simek mts rpid, r11 7287db29ddeSMichal Simek nop 7297db29ddeSMichal Simek bri 4 7307db29ddeSMichal Simek RESTORE_STATE; 7317db29ddeSMichal Simek bri page_fault_instr_trap 7327db29ddeSMichal Simek 7337db29ddeSMichal Simek/* Both the instruction and data TLB miss get to this point to load the TLB. 7347db29ddeSMichal Simek * r3 - EA of fault 7357db29ddeSMichal Simek * r4 - TLB LO (info from Linux PTE) 7367db29ddeSMichal Simek * r5, r6 - available to use 7377db29ddeSMichal Simek * PID - loaded with proper value when we get here 7387db29ddeSMichal Simek * Upon exit, we reload everything and RFI. 7397db29ddeSMichal Simek * A common place to load the TLB. 7407db29ddeSMichal Simek */ 741e02db0aaSMichal Simek.section .data 742e02db0aaSMichal Simek.align 4 743e02db0aaSMichal Simek.global tlb_skip 744e02db0aaSMichal Simek tlb_skip: 745e02db0aaSMichal Simek .long MICROBLAZE_TLB_SKIP 7467db29ddeSMichal Simek tlb_index: 7471451d1d8SMichal Simek /* MS: storing last used tlb index */ 748e02db0aaSMichal Simek .long MICROBLAZE_TLB_SIZE/2 749e02db0aaSMichal Simek.previous 7507db29ddeSMichal Simek finish_tlb_load: 7517db29ddeSMichal Simek /* MS: load the last used TLB index. */ 7527db29ddeSMichal Simek lwi r5, r0, TOPHYS(tlb_index) 7537db29ddeSMichal Simek addik r5, r5, 1 /* MS: inc tlb_index -> use next one */ 7547db29ddeSMichal Simek 7557db29ddeSMichal Simek/* MS: FIXME this is potential fault, because this is mask not count */ 7561451d1d8SMichal Simek andi r5, r5, MICROBLAZE_TLB_SIZE - 1 7577db29ddeSMichal Simek ori r6, r0, 1 7587db29ddeSMichal Simek cmp r31, r5, r6 7593765d695SMichal Simek blti r31, ex12 760e02db0aaSMichal Simek lwi r5, r0, TOPHYS(tlb_skip) 7613765d695SMichal Simek ex12: 7627db29ddeSMichal Simek /* MS: save back current TLB index */ 7637db29ddeSMichal Simek swi r5, r0, TOPHYS(tlb_index) 7647db29ddeSMichal Simek 7657db29ddeSMichal Simek ori r4, r4, _PAGE_HWEXEC /* make it executable */ 7667db29ddeSMichal Simek mts rtlbx, r5 /* MS: save current TLB */ 7677db29ddeSMichal Simek nop 7687db29ddeSMichal Simek mts rtlblo, r4 /* MS: save to TLB LO */ 7697db29ddeSMichal Simek nop 7707db29ddeSMichal Simek 7717db29ddeSMichal Simek /* Create EPN. This is the faulting address plus a static 7727db29ddeSMichal Simek * set of bits. These are size, valid, E, U0, and ensure 7737db29ddeSMichal Simek * bits 20 and 21 are zero. 7747db29ddeSMichal Simek */ 7759f78d3b5SMichal Simek andi r3, r3, PAGE_MASK 7769f78d3b5SMichal Simek ori r3, r3, TLB_VALID | TLB_PAGESZ(PAGESZ_4K) 7777db29ddeSMichal Simek mts rtlbhi, r3 /* Load TLB HI */ 7787db29ddeSMichal Simek nop 7797db29ddeSMichal Simek 7807db29ddeSMichal Simek /* Done...restore registers and get out of here. */ 7817db29ddeSMichal Simek mts rpid, r11 7827db29ddeSMichal Simek nop 7837db29ddeSMichal Simek bri 4 7847db29ddeSMichal Simek RESTORE_STATE; 7857db29ddeSMichal Simek rted r17, 0 7867db29ddeSMichal Simek nop 7877db29ddeSMichal Simek 7887db29ddeSMichal Simek /* extern void giveup_fpu(struct task_struct *prev) 7897db29ddeSMichal Simek * 7907db29ddeSMichal Simek * The MicroBlaze processor may have an FPU, so this should not just 7917db29ddeSMichal Simek * return: TBD. 7927db29ddeSMichal Simek */ 7937db29ddeSMichal Simek .globl giveup_fpu; 7947db29ddeSMichal Simek .align 4; 7957db29ddeSMichal Simek giveup_fpu: 7967db29ddeSMichal Simek bralid r15,0 /* TBD */ 7977db29ddeSMichal Simek nop 7987db29ddeSMichal Simek 7997db29ddeSMichal Simek /* At present, this routine just hangs. - extern void abort(void) */ 8007db29ddeSMichal Simek .globl abort; 8017db29ddeSMichal Simek .align 4; 8027db29ddeSMichal Simek abort: 8037db29ddeSMichal Simek br r0 8047db29ddeSMichal Simek 8057db29ddeSMichal Simek .globl set_context; 8067db29ddeSMichal Simek .align 4; 8077db29ddeSMichal Simek set_context: 8087db29ddeSMichal Simek mts rpid, r5 /* Shadow TLBs are automatically */ 8097db29ddeSMichal Simek nop 8107db29ddeSMichal Simek bri 4 /* flushed by changing PID */ 8117db29ddeSMichal Simek rtsd r15,8 8127db29ddeSMichal Simek nop 8137db29ddeSMichal Simek 814c4df4bc1SMichal Simek.end _hw_exception_handler 815c4df4bc1SMichal Simek 8167db29ddeSMichal Simek/* Unaligned data access exception last on a 4k page for MMU. 8177db29ddeSMichal Simek * When this is called, we are in virtual mode with exceptions enabled 8187db29ddeSMichal Simek * and registers 1-13,15,17,18 saved. 8197db29ddeSMichal Simek * 8207db29ddeSMichal Simek * R3 = ESR 8217db29ddeSMichal Simek * R4 = EAR 8227db29ddeSMichal Simek * R7 = pointer to saved registers (struct pt_regs *regs) 8237db29ddeSMichal Simek * 8247db29ddeSMichal Simek * This handler perform the access, and returns via ret_from_exc. 8257db29ddeSMichal Simek */ 8267db29ddeSMichal Simek.global _unaligned_data_exception 8277db29ddeSMichal Simek.ent _unaligned_data_exception 8287db29ddeSMichal Simek_unaligned_data_exception: 8297db29ddeSMichal Simek andi r8, r3, 0x3E0; /* Mask and extract the register operand */ 83052ade599SMichal Simek bsrli r8, r8, 2; /* r8 >> 2 = register operand * 8 */ 8317db29ddeSMichal Simek andi r6, r3, 0x400; /* Extract ESR[S] */ 8327db29ddeSMichal Simek bneid r6, ex_sw_vm; 8337db29ddeSMichal Simek andi r6, r3, 0x800; /* Extract ESR[W] - delay slot */ 8347db29ddeSMichal Simekex_lw_vm: 8357db29ddeSMichal Simek beqid r6, ex_lhw_vm; 8363863dbceSMichal Simekload1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */ 8377db29ddeSMichal Simek/* Load a word, byte-by-byte from destination address and save it in tmp space*/ 838cd341577SMichal Simek addik r6, r0, ex_tmp_data_loc_0; 8397db29ddeSMichal Simek sbi r5, r6, 0; 8403863dbceSMichal Simekload2: lbui r5, r4, 1; 8417db29ddeSMichal Simek sbi r5, r6, 1; 8423863dbceSMichal Simekload3: lbui r5, r4, 2; 8437db29ddeSMichal Simek sbi r5, r6, 2; 8443863dbceSMichal Simekload4: lbui r5, r4, 3; 8457db29ddeSMichal Simek sbi r5, r6, 3; 8467db29ddeSMichal Simek brid ex_lw_tail_vm; 8477db29ddeSMichal Simek/* Get the destination register value into r3 - delay slot */ 8487db29ddeSMichal Simek lwi r3, r6, 0; 8497db29ddeSMichal Simekex_lhw_vm: 8507db29ddeSMichal Simek /* Load a half-word, byte-by-byte from destination address and 8517db29ddeSMichal Simek * save it in tmp space */ 852cd341577SMichal Simek addik r6, r0, ex_tmp_data_loc_0; 8537db29ddeSMichal Simek sbi r5, r6, 0; 8543863dbceSMichal Simekload5: lbui r5, r4, 1; 8557db29ddeSMichal Simek sbi r5, r6, 1; 8567db29ddeSMichal Simek lhui r3, r6, 0; /* Get the destination register value into r3 */ 8577db29ddeSMichal Simekex_lw_tail_vm: 8587db29ddeSMichal Simek /* Form load_word jump table offset (lw_table_vm + (8 * regnum)) */ 8597db29ddeSMichal Simek addik r5, r8, lw_table_vm; 8607db29ddeSMichal Simek bra r5; 8617db29ddeSMichal Simekex_lw_end_vm: /* Exception handling of load word, ends */ 8627db29ddeSMichal Simek brai ret_from_exc; 8637db29ddeSMichal Simekex_sw_vm: 8647db29ddeSMichal Simek/* Form store_word jump table offset (sw_table_vm + (8 * regnum)) */ 8657db29ddeSMichal Simek addik r5, r8, sw_table_vm; 8667db29ddeSMichal Simek bra r5; 8677db29ddeSMichal Simekex_sw_tail_vm: 868cd341577SMichal Simek addik r5, r0, ex_tmp_data_loc_0; 8697db29ddeSMichal Simek beqid r6, ex_shw_vm; 8707db29ddeSMichal Simek swi r3, r5, 0; /* Get the word - delay slot */ 8717db29ddeSMichal Simek /* Store the word, byte-by-byte into destination address */ 8727db29ddeSMichal Simek lbui r3, r5, 0; 8733863dbceSMichal Simekstore1: sbi r3, r4, 0; 8747db29ddeSMichal Simek lbui r3, r5, 1; 8753863dbceSMichal Simekstore2: sbi r3, r4, 1; 8767db29ddeSMichal Simek lbui r3, r5, 2; 8773863dbceSMichal Simekstore3: sbi r3, r4, 2; 8787db29ddeSMichal Simek lbui r3, r5, 3; 8797db29ddeSMichal Simek brid ret_from_exc; 8803863dbceSMichal Simekstore4: sbi r3, r4, 3; /* Delay slot */ 8817db29ddeSMichal Simekex_shw_vm: 8827db29ddeSMichal Simek /* Store the lower half-word, byte-by-byte into destination address */ 883e3288f31SMichal Simek#ifdef __MICROBLAZEEL__ 884e3288f31SMichal Simek lbui r3, r5, 0; 885e3288f31SMichal Simekstore5: sbi r3, r4, 0; 886e3288f31SMichal Simek lbui r3, r5, 1; 887e3288f31SMichal Simek brid ret_from_exc; 888e3288f31SMichal Simekstore6: sbi r3, r4, 1; /* Delay slot */ 889e3288f31SMichal Simek#else 8907db29ddeSMichal Simek lbui r3, r5, 2; 8913863dbceSMichal Simekstore5: sbi r3, r4, 0; 8927db29ddeSMichal Simek lbui r3, r5, 3; 8937db29ddeSMichal Simek brid ret_from_exc; 8943863dbceSMichal Simekstore6: sbi r3, r4, 1; /* Delay slot */ 895e3288f31SMichal Simek#endif 896e3288f31SMichal Simek 8977db29ddeSMichal Simekex_sw_end_vm: /* Exception handling of store word, ends. */ 8983863dbceSMichal Simek 8993863dbceSMichal Simek/* We have to prevent cases that get/put_user macros get unaligned pointer 9003863dbceSMichal Simek * to bad page area. We have to find out which origin instruction caused it 9013863dbceSMichal Simek * and called fixup for that origin instruction not instruction in unaligned 9023863dbceSMichal Simek * handler */ 9033863dbceSMichal Simekex_unaligned_fixup: 9043863dbceSMichal Simek ori r5, r7, 0 /* setup pointer to pt_regs */ 9053863dbceSMichal Simek lwi r6, r7, PT_PC; /* faulting address is one instruction above */ 9063863dbceSMichal Simek addik r6, r6, -4 /* for finding proper fixup */ 9073863dbceSMichal Simek swi r6, r7, PT_PC; /* a save back it to PT_PC */ 9083863dbceSMichal Simek addik r7, r0, SIGSEGV 9093863dbceSMichal Simek /* call bad_page_fault for finding aligned fixup, fixup address is saved 9103863dbceSMichal Simek * in PT_PC which is used as return address from exception */ 911cd341577SMichal Simek addik r15, r0, ret_from_exc-8 /* setup return address */ 9123863dbceSMichal Simek brid bad_page_fault 9133863dbceSMichal Simek nop 9143863dbceSMichal Simek 9153863dbceSMichal Simek/* We prevent all load/store because it could failed any attempt to access */ 9163863dbceSMichal Simek.section __ex_table,"a"; 9173863dbceSMichal Simek .word load1,ex_unaligned_fixup; 9183863dbceSMichal Simek .word load2,ex_unaligned_fixup; 9193863dbceSMichal Simek .word load3,ex_unaligned_fixup; 9203863dbceSMichal Simek .word load4,ex_unaligned_fixup; 9213863dbceSMichal Simek .word load5,ex_unaligned_fixup; 9223863dbceSMichal Simek .word store1,ex_unaligned_fixup; 9233863dbceSMichal Simek .word store2,ex_unaligned_fixup; 9243863dbceSMichal Simek .word store3,ex_unaligned_fixup; 9253863dbceSMichal Simek .word store4,ex_unaligned_fixup; 9263863dbceSMichal Simek .word store5,ex_unaligned_fixup; 9273863dbceSMichal Simek .word store6,ex_unaligned_fixup; 9283863dbceSMichal Simek.previous; 9297db29ddeSMichal Simek.end _unaligned_data_exception 9307db29ddeSMichal Simek 931ce3266c0SSteven J. Magnani.global ex_handler_unhandled 932c4df4bc1SMichal Simekex_handler_unhandled: 933c4df4bc1SMichal Simek/* FIXME add handle function for unhandled exception - dump register */ 934c4df4bc1SMichal Simek bri 0 935c4df4bc1SMichal Simek 9367db29ddeSMichal Simek/* 9377db29ddeSMichal Simek * hw_exception_handler Jump Table 9387db29ddeSMichal Simek * - Contains code snippets for each register that caused the unalign exception 9397db29ddeSMichal Simek * - Hence exception handler is NOT self-modifying 9407db29ddeSMichal Simek * - Separate table for load exceptions and store exceptions. 9417db29ddeSMichal Simek * - Each table is of size: (8 * 32) = 256 bytes 9427db29ddeSMichal Simek */ 9437db29ddeSMichal Simek 944c4df4bc1SMichal Simek.section .text 945c4df4bc1SMichal Simek.align 4 946c4df4bc1SMichal Simeklw_table: 947c4df4bc1SMichal Simeklw_r0: R3_TO_LWREG (0); 948c4df4bc1SMichal Simeklw_r1: LWREG_NOP; 949c4df4bc1SMichal Simeklw_r2: R3_TO_LWREG (2); 950c4df4bc1SMichal Simeklw_r3: R3_TO_LWREG_V (3); 951c4df4bc1SMichal Simeklw_r4: R3_TO_LWREG_V (4); 952c4df4bc1SMichal Simeklw_r5: R3_TO_LWREG_V (5); 953c4df4bc1SMichal Simeklw_r6: R3_TO_LWREG_V (6); 954c4df4bc1SMichal Simeklw_r7: R3_TO_LWREG (7); 955c4df4bc1SMichal Simeklw_r8: R3_TO_LWREG (8); 956c4df4bc1SMichal Simeklw_r9: R3_TO_LWREG (9); 957c4df4bc1SMichal Simeklw_r10: R3_TO_LWREG (10); 958c4df4bc1SMichal Simeklw_r11: R3_TO_LWREG (11); 959c4df4bc1SMichal Simeklw_r12: R3_TO_LWREG (12); 960c4df4bc1SMichal Simeklw_r13: R3_TO_LWREG (13); 961c4df4bc1SMichal Simeklw_r14: R3_TO_LWREG (14); 962c4df4bc1SMichal Simeklw_r15: R3_TO_LWREG (15); 963c4df4bc1SMichal Simeklw_r16: R3_TO_LWREG (16); 964c4df4bc1SMichal Simeklw_r17: LWREG_NOP; 965c4df4bc1SMichal Simeklw_r18: R3_TO_LWREG (18); 966c4df4bc1SMichal Simeklw_r19: R3_TO_LWREG (19); 967c4df4bc1SMichal Simeklw_r20: R3_TO_LWREG (20); 968c4df4bc1SMichal Simeklw_r21: R3_TO_LWREG (21); 969c4df4bc1SMichal Simeklw_r22: R3_TO_LWREG (22); 970c4df4bc1SMichal Simeklw_r23: R3_TO_LWREG (23); 971c4df4bc1SMichal Simeklw_r24: R3_TO_LWREG (24); 972c4df4bc1SMichal Simeklw_r25: R3_TO_LWREG (25); 973c4df4bc1SMichal Simeklw_r26: R3_TO_LWREG (26); 974c4df4bc1SMichal Simeklw_r27: R3_TO_LWREG (27); 975c4df4bc1SMichal Simeklw_r28: R3_TO_LWREG (28); 976c4df4bc1SMichal Simeklw_r29: R3_TO_LWREG (29); 977c4df4bc1SMichal Simeklw_r30: R3_TO_LWREG (30); 9787db29ddeSMichal Simeklw_r31: R3_TO_LWREG_V (31); 979c4df4bc1SMichal Simek 980c4df4bc1SMichal Simeksw_table: 981c4df4bc1SMichal Simeksw_r0: SWREG_TO_R3 (0); 982c4df4bc1SMichal Simeksw_r1: SWREG_NOP; 983c4df4bc1SMichal Simeksw_r2: SWREG_TO_R3 (2); 984c4df4bc1SMichal Simeksw_r3: SWREG_TO_R3_V (3); 985c4df4bc1SMichal Simeksw_r4: SWREG_TO_R3_V (4); 986c4df4bc1SMichal Simeksw_r5: SWREG_TO_R3_V (5); 987c4df4bc1SMichal Simeksw_r6: SWREG_TO_R3_V (6); 988c4df4bc1SMichal Simeksw_r7: SWREG_TO_R3 (7); 989c4df4bc1SMichal Simeksw_r8: SWREG_TO_R3 (8); 990c4df4bc1SMichal Simeksw_r9: SWREG_TO_R3 (9); 991c4df4bc1SMichal Simeksw_r10: SWREG_TO_R3 (10); 992c4df4bc1SMichal Simeksw_r11: SWREG_TO_R3 (11); 993c4df4bc1SMichal Simeksw_r12: SWREG_TO_R3 (12); 994c4df4bc1SMichal Simeksw_r13: SWREG_TO_R3 (13); 995c4df4bc1SMichal Simeksw_r14: SWREG_TO_R3 (14); 996c4df4bc1SMichal Simeksw_r15: SWREG_TO_R3 (15); 997c4df4bc1SMichal Simeksw_r16: SWREG_TO_R3 (16); 998c4df4bc1SMichal Simeksw_r17: SWREG_NOP; 999c4df4bc1SMichal Simeksw_r18: SWREG_TO_R3 (18); 1000c4df4bc1SMichal Simeksw_r19: SWREG_TO_R3 (19); 1001c4df4bc1SMichal Simeksw_r20: SWREG_TO_R3 (20); 1002c4df4bc1SMichal Simeksw_r21: SWREG_TO_R3 (21); 1003c4df4bc1SMichal Simeksw_r22: SWREG_TO_R3 (22); 1004c4df4bc1SMichal Simeksw_r23: SWREG_TO_R3 (23); 1005c4df4bc1SMichal Simeksw_r24: SWREG_TO_R3 (24); 1006c4df4bc1SMichal Simeksw_r25: SWREG_TO_R3 (25); 1007c4df4bc1SMichal Simeksw_r26: SWREG_TO_R3 (26); 1008c4df4bc1SMichal Simeksw_r27: SWREG_TO_R3 (27); 1009c4df4bc1SMichal Simeksw_r28: SWREG_TO_R3 (28); 1010c4df4bc1SMichal Simeksw_r29: SWREG_TO_R3 (29); 1011c4df4bc1SMichal Simeksw_r30: SWREG_TO_R3 (30); 10127db29ddeSMichal Simeksw_r31: SWREG_TO_R3_V (31); 10137db29ddeSMichal Simek 10147db29ddeSMichal Simeklw_table_vm: 10157db29ddeSMichal Simeklw_r0_vm: R3_TO_LWREG_VM (0); 10167db29ddeSMichal Simeklw_r1_vm: R3_TO_LWREG_VM_V (1); 10177db29ddeSMichal Simeklw_r2_vm: R3_TO_LWREG_VM_V (2); 10187db29ddeSMichal Simeklw_r3_vm: R3_TO_LWREG_VM_V (3); 10197db29ddeSMichal Simeklw_r4_vm: R3_TO_LWREG_VM_V (4); 10207db29ddeSMichal Simeklw_r5_vm: R3_TO_LWREG_VM_V (5); 10217db29ddeSMichal Simeklw_r6_vm: R3_TO_LWREG_VM_V (6); 10227db29ddeSMichal Simeklw_r7_vm: R3_TO_LWREG_VM_V (7); 10237db29ddeSMichal Simeklw_r8_vm: R3_TO_LWREG_VM_V (8); 10247db29ddeSMichal Simeklw_r9_vm: R3_TO_LWREG_VM_V (9); 10257db29ddeSMichal Simeklw_r10_vm: R3_TO_LWREG_VM_V (10); 10267db29ddeSMichal Simeklw_r11_vm: R3_TO_LWREG_VM_V (11); 10277db29ddeSMichal Simeklw_r12_vm: R3_TO_LWREG_VM_V (12); 10287db29ddeSMichal Simeklw_r13_vm: R3_TO_LWREG_VM_V (13); 1029c1138940SMichal Simeklw_r14_vm: R3_TO_LWREG_VM_V (14); 10307db29ddeSMichal Simeklw_r15_vm: R3_TO_LWREG_VM_V (15); 1031c1138940SMichal Simeklw_r16_vm: R3_TO_LWREG_VM_V (16); 10327db29ddeSMichal Simeklw_r17_vm: R3_TO_LWREG_VM_V (17); 10337db29ddeSMichal Simeklw_r18_vm: R3_TO_LWREG_VM_V (18); 1034c1138940SMichal Simeklw_r19_vm: R3_TO_LWREG_VM_V (19); 1035c1138940SMichal Simeklw_r20_vm: R3_TO_LWREG_VM_V (20); 1036c1138940SMichal Simeklw_r21_vm: R3_TO_LWREG_VM_V (21); 1037c1138940SMichal Simeklw_r22_vm: R3_TO_LWREG_VM_V (22); 1038c1138940SMichal Simeklw_r23_vm: R3_TO_LWREG_VM_V (23); 1039c1138940SMichal Simeklw_r24_vm: R3_TO_LWREG_VM_V (24); 1040c1138940SMichal Simeklw_r25_vm: R3_TO_LWREG_VM_V (25); 1041c1138940SMichal Simeklw_r26_vm: R3_TO_LWREG_VM_V (26); 1042c1138940SMichal Simeklw_r27_vm: R3_TO_LWREG_VM_V (27); 1043c1138940SMichal Simeklw_r28_vm: R3_TO_LWREG_VM_V (28); 1044c1138940SMichal Simeklw_r29_vm: R3_TO_LWREG_VM_V (29); 1045c1138940SMichal Simeklw_r30_vm: R3_TO_LWREG_VM_V (30); 10467db29ddeSMichal Simeklw_r31_vm: R3_TO_LWREG_VM_V (31); 10477db29ddeSMichal Simek 10487db29ddeSMichal Simeksw_table_vm: 10497db29ddeSMichal Simeksw_r0_vm: SWREG_TO_R3_VM (0); 10507db29ddeSMichal Simeksw_r1_vm: SWREG_TO_R3_VM_V (1); 10517db29ddeSMichal Simeksw_r2_vm: SWREG_TO_R3_VM_V (2); 10527db29ddeSMichal Simeksw_r3_vm: SWREG_TO_R3_VM_V (3); 10537db29ddeSMichal Simeksw_r4_vm: SWREG_TO_R3_VM_V (4); 10547db29ddeSMichal Simeksw_r5_vm: SWREG_TO_R3_VM_V (5); 10557db29ddeSMichal Simeksw_r6_vm: SWREG_TO_R3_VM_V (6); 10567db29ddeSMichal Simeksw_r7_vm: SWREG_TO_R3_VM_V (7); 10577db29ddeSMichal Simeksw_r8_vm: SWREG_TO_R3_VM_V (8); 10587db29ddeSMichal Simeksw_r9_vm: SWREG_TO_R3_VM_V (9); 10597db29ddeSMichal Simeksw_r10_vm: SWREG_TO_R3_VM_V (10); 10607db29ddeSMichal Simeksw_r11_vm: SWREG_TO_R3_VM_V (11); 10617db29ddeSMichal Simeksw_r12_vm: SWREG_TO_R3_VM_V (12); 10627db29ddeSMichal Simeksw_r13_vm: SWREG_TO_R3_VM_V (13); 1063c1138940SMichal Simeksw_r14_vm: SWREG_TO_R3_VM_V (14); 10647db29ddeSMichal Simeksw_r15_vm: SWREG_TO_R3_VM_V (15); 1065c1138940SMichal Simeksw_r16_vm: SWREG_TO_R3_VM_V (16); 10667db29ddeSMichal Simeksw_r17_vm: SWREG_TO_R3_VM_V (17); 10677db29ddeSMichal Simeksw_r18_vm: SWREG_TO_R3_VM_V (18); 1068c1138940SMichal Simeksw_r19_vm: SWREG_TO_R3_VM_V (19); 1069c1138940SMichal Simeksw_r20_vm: SWREG_TO_R3_VM_V (20); 1070c1138940SMichal Simeksw_r21_vm: SWREG_TO_R3_VM_V (21); 1071c1138940SMichal Simeksw_r22_vm: SWREG_TO_R3_VM_V (22); 1072c1138940SMichal Simeksw_r23_vm: SWREG_TO_R3_VM_V (23); 1073c1138940SMichal Simeksw_r24_vm: SWREG_TO_R3_VM_V (24); 1074c1138940SMichal Simeksw_r25_vm: SWREG_TO_R3_VM_V (25); 1075c1138940SMichal Simeksw_r26_vm: SWREG_TO_R3_VM_V (26); 1076c1138940SMichal Simeksw_r27_vm: SWREG_TO_R3_VM_V (27); 1077c1138940SMichal Simeksw_r28_vm: SWREG_TO_R3_VM_V (28); 1078c1138940SMichal Simeksw_r29_vm: SWREG_TO_R3_VM_V (29); 1079c1138940SMichal Simeksw_r30_vm: SWREG_TO_R3_VM_V (30); 10807db29ddeSMichal Simeksw_r31_vm: SWREG_TO_R3_VM_V (31); 1081c4df4bc1SMichal Simek 1082c4df4bc1SMichal Simek/* Temporary data structures used in the handler */ 1083c4df4bc1SMichal Simek.section .data 1084c4df4bc1SMichal Simek.align 4 1085c4df4bc1SMichal Simekex_tmp_data_loc_0: 1086c4df4bc1SMichal Simek .byte 0 1087c4df4bc1SMichal Simekex_tmp_data_loc_1: 1088c4df4bc1SMichal Simek .byte 0 1089c4df4bc1SMichal Simekex_tmp_data_loc_2: 1090c4df4bc1SMichal Simek .byte 0 1091c4df4bc1SMichal Simekex_tmp_data_loc_3: 1092c4df4bc1SMichal Simek .byte 0 1093c4df4bc1SMichal Simekex_reg_op: 1094c4df4bc1SMichal Simek .byte 0 1095