1 /* 1 2 * This file is subject to the terms and condi 3 * License. See the file "COPYING" in the mai 4 * for more details. 5 * 6 * Copyright (C) 2005 Thiemo Seufer 7 * Copyright (C) 2005 MIPS Technologies, Inc. 8 * Author: Maciej W. Rozycki <macro@mips. 9 */ 10 11 12 #include <asm/addrspace.h> 13 #include <asm/bug.h> 14 #include <asm/cacheflush.h> 15 16 #ifndef CKSEG2 17 #define CKSEG2 CKSSEG 18 #endif 19 #ifndef TO_PHYS_MASK 20 #define TO_PHYS_MASK -1 21 #endif 22 23 /* 24 * FUNC is executed in one of the uncached seg 25 * original address as follows: 26 * 27 * 1. If the original address is in CKSEG0 or 28 * segment used is CKSEG1. 29 * 2. If the original address is in XKPHYS, th 30 * used is XKPHYS(2). 31 * 3. Otherwise it's a bug. 32 * 33 * The same remapping is done with the stack p 34 * works because we don't handle stack argumen 35 * values, so we can avoid sharing the same st 36 * and the uncached mode. 37 */ 38 unsigned long run_uncached(void *func) 39 { 40 register long ret __asm__("$2"); 41 long lfunc = (long)func, ufunc; 42 long usp; 43 long sp; 44 45 __asm__("move %0, $sp" : "=r" (sp)); 46 47 if (sp >= (long)CKSEG0 && sp < (long)C 48 usp = CKSEG1ADDR(sp); 49 #ifdef CONFIG_64BIT 50 else if ((long long)sp >= (long long)P 51 (long long)sp < (long long)PH 52 usp = PHYS_TO_XKPHYS(K_CALG_UN 53 XKPHYS_TO 54 #endif 55 else { 56 BUG(); 57 usp = sp; 58 } 59 if (lfunc >= (long)CKSEG0 && lfunc < ( 60 ufunc = CKSEG1ADDR(lfunc); 61 #ifdef CONFIG_64BIT 62 else if ((long long)lfunc >= (long lon 63 (long long)lfunc < (long long 64 ufunc = PHYS_TO_XKPHYS(K_CALG_ 65 XKPHYS_ 66 #endif 67 else { 68 BUG(); 69 ufunc = lfunc; 70 } 71 72 __asm__ __volatile__ ( 73 " move $16, $sp\n" 74 " move $sp, %1\n" 75 " jalr %2\n" 76 " move $sp, $16" 77 : "=r" (ret) 78 : "r" (usp), "r" (ufunc) 79 : "$16", "$31"); 80 81 return ret; 82 } 83
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.