1/* 2 * File: arch/blackfin/mach-common/cplbhdlr.S 3 * Based on: 4 * Author: LG Soft India 5 * 6 * Created: ? 7 * Description: CPLB exception handler 8 * 9 * Modified: 10 * Copyright 2004-2006 Analog Devices Inc. 11 * 12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, see the file COPYING, or write 26 * to the Free Software Foundation, Inc., 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 28 */ 29 30#include <linux/linkage.h> 31#include <asm/cplb.h> 32#include <asm/entry.h> 33 34#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 35.section .l1.text 36#else 37.text 38#endif 39 40.type _cplb_mgr, STT_FUNC; 41.type _panic_cplb_error, STT_FUNC; 42 43.align 2 44 45ENTRY(__cplb_hdr) 46 R2 = SEQSTAT; 47 48 /* Mask the contents of SEQSTAT and leave only EXCAUSE in R2 */ 49 R2 <<= 26; 50 R2 >>= 26; 51 52 R1 = 0x23; /* Data access CPLB protection violation */ 53 CC = R2 == R1; 54 IF !CC JUMP .Lnot_data_write; 55 R0 = 2; /* is a write to data space*/ 56 JUMP .Lis_icplb_miss; 57 58.Lnot_data_write: 59 R1 = 0x2C; /* CPLB miss on an instruction fetch */ 60 CC = R2 == R1; 61 R0 = 0; /* is_data_miss == False*/ 62 IF CC JUMP .Lis_icplb_miss; 63 64 R1 = 0x26; 65 CC = R2 == R1; 66 IF !CC JUMP .Lunknown; 67 68 R0 = 1; /* is_data_miss == True*/ 69 70.Lis_icplb_miss: 71 72#if defined(CONFIG_BLKFIN_CACHE) || defined(CONFIG_BLKFIN_DCACHE) 73# if defined(CONFIG_BLKFIN_CACHE) && !defined(CONFIG_BLKFIN_DCACHE) 74 R1 = CPLB_ENABLE_ICACHE; 75# endif 76# if !defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE) 77 R1 = CPLB_ENABLE_DCACHE; 78# endif 79# if defined(CONFIG_BLKFIN_CACHE) && defined(CONFIG_BLKFIN_DCACHE) 80 R1 = CPLB_ENABLE_DCACHE | CPLB_ENABLE_ICACHE; 81# endif 82#else 83 R1 = 0; 84#endif 85 86 [--SP] = RETS; 87 CALL _cplb_mgr; 88 RETS = [SP++]; 89 CC = R0 == 0; 90 IF !CC JUMP .Lnot_replaced; 91 RTS; 92 93/* 94 * Diagnostic exception handlers 95 */ 96.Lunknown: 97 R0 = CPLB_UNKNOWN_ERR; 98 JUMP .Lcplb_error; 99 100.Lnot_replaced: 101 CC = R0 == CPLB_NO_UNLOCKED; 102 IF !CC JUMP .Lnext_check; 103 R0 = CPLB_NO_UNLOCKED; 104 JUMP .Lcplb_error; 105 106.Lnext_check: 107 CC = R0 == CPLB_NO_ADDR_MATCH; 108 IF !CC JUMP .Lnext_check2; 109 R0 = CPLB_NO_ADDR_MATCH; 110 JUMP .Lcplb_error; 111 112.Lnext_check2: 113 CC = R0 == CPLB_PROT_VIOL; 114 IF !CC JUMP .Lstrange_return_from_cplb_mgr; 115 R0 = CPLB_PROT_VIOL; 116 JUMP .Lcplb_error; 117 118.Lstrange_return_from_cplb_mgr: 119 IDLE; 120 CSYNC; 121 JUMP .Lstrange_return_from_cplb_mgr; 122 123.Lcplb_error: 124 R1 = sp; 125 SP += -12; 126 call _panic_cplb_error; 127 SP += 12; 128 JUMP _handle_bad_cplb; 129 130ENDPROC(__cplb_hdr) 131