1/* Trampoline support for MeP 2 Copyright (C) 2004-2015 Free Software Foundation, Inc. 3 Contributed by Red Hat Inc. 4 5This file is free software; you can redistribute it and/or modify it 6under the terms of the GNU General Public License as published by the 7Free Software Foundation; either version 3 of the License, or (at your 8option) any later version. 9 10This file is distributed in the hope that it will be useful, but 11WITHOUT ANY WARRANTY; without even the implied warranty of 12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13General Public License for more details. 14 15Under Section 7 of GPL version 3, you are granted additional 16permissions described in the GCC Runtime Library Exception, version 173.1, as published by the Free Software Foundation. 18 19You should have received a copy of the GNU General Public License and 20a copy of the GCC Runtime Library Exception along with this program; 21see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 22<http://www.gnu.org/licenses/>. */ 23 24/* 25 7a0a ldc $10,$pc 26 c0ae000a lw $0,10($10) 27 caae000e lw $10,14($10) 28 10ae jmp $10 29 00000000 static chain 30 00000000 function address 31*/ 32 33static inline int 34cache_config_register(void) { 35 int rv; 36 asm ("ldc\t%0, $ccfg" : "=r" (rv)); 37 return rv; 38} 39 40#define ICACHE_SIZE ((cache_config_register() >> 16) & 0x7f) 41#define DCACHE_SIZE (cache_config_register() & 0x7f) 42 43#define ICACHE_DATA_BASE 0x00300000 44#define ICACHE_TAG_BASE 0x00310000 45#define DCACHE_DATA_BASE 0x00320000 46#define DCACHE_TAG_BASE 0x00330000 47 48static inline void 49flush_dcache (int addr) 50{ 51 asm volatile ("cache\t0, (%0)" : : "r" (addr)); 52} 53 54void 55__mep_trampoline_helper (unsigned long *tramp, 56 int function_address, 57 int static_chain); 58 59void 60__mep_trampoline_helper (unsigned long *tramp, 61 int function_address, 62 int static_chain) 63{ 64 int dsize, isize; 65 66#ifdef __LITTLE_ENDIAN__ 67 tramp[0] = 0xc0ae7a0a; 68 tramp[1] = 0xcaae000a; 69 tramp[2] = 0x10ae000e; 70#else 71 tramp[0] = 0x7a0ac0ae; 72 tramp[1] = 0x000acaae; 73 tramp[2] = 0x000e10ae; 74#endif 75 tramp[3] = static_chain; 76 tramp[4] = function_address; 77 78 dsize = DCACHE_SIZE; 79 isize = ICACHE_SIZE; 80 81 if (dsize) 82 { 83 flush_dcache ((int)tramp); 84 flush_dcache ((int)tramp+16); 85 } 86 87 if (isize) 88 { 89 int imask = (isize * 1024) - 1; 90 int tmask = ~imask; 91 unsigned int i; 92 volatile unsigned int *tags; 93 94 imask &= 0xffe0; 95 96 for (i=(unsigned int)tramp; i<(unsigned int)tramp+20; i+=16) 97 { 98 tags = (unsigned int *)(ICACHE_TAG_BASE + (i & imask)); 99 if ((*tags & tmask) == (i & tmask)) 100 *tags &= ~1; 101 } 102 } 103} 104