1 /******************************************************************************/ 2 /* */ 3 /* Copyright (c) International Business Machines Corp., 2008 */ 4 /* Copyright 2008 Paul Mackerras, IBM Corp. */ 5 /* */ 6 /* This program is free software; you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation; either version 2 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* This program is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ 14 /* the GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with this program; if not, write to the Free Software */ 18 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 19 /* */ 20 /******************************************************************************/ 21 /******************************************************************************/ 22 /* */ 23 /* File: endian_switch01.c */ 24 /* */ 25 /* Description: Test little-endian mode switch system call. Requires a 64-bit */ 26 /* processor that supports little-endian mode,such as POWER6. */ 27 /* */ 28 /* Total Tests: 1 */ 29 /* */ 30 /* Test Name: endian_switch01 */ 31 /* */ 32 /* Author: Paul Mackerras <paulus (at) samba.org> */ 33 /* */ 34 /* History: Created - Sep 02 2008 - Paul Mackerras <paulus (at) samba.org> */ 35 /* Ported to LTP */ 36 /* - Sep 02 2008 */ 37 /* - Subrata Modak <subrata (at) linux.vnet.ibm.com> */ 38 /* */ 39 /******************************************************************************/ 40 41 #include <stdio.h> 42 #include <stdlib.h> 43 #include <elf.h> 44 #include <signal.h> 45 #include <setjmp.h> 46 #include "test.h" 47 #include <errno.h> 48 #include <sys/stat.h> 49 #include <sys/types.h> 50 #include <sys/syscall.h> 51 #include <fcntl.h> 52 #include <sys/utsname.h> 53 #include <unistd.h> 54 #include "linux_syscall_numbers.h" 55 56 #if defined (__powerpc64__) || (__powerpc__) 57 static void setup(); 58 #endif 59 60 static void cleanup(); 61 62 char *TCID = "endian_switch01"; 63 int TST_TOTAL = 1; 64 65 #if defined (__powerpc64__) || (__powerpc__) 66 void setup(void) 67 { 68 69 tst_sig(FORK, DEF_HANDLER, cleanup); 70 71 TEST_PAUSE; 72 73 } 74 75 extern int main4(int ac, char **av, char **envp, unsigned long *auxv) 76 __asm("main"); 77 #endif 78 79 void cleanup(void) 80 { 81 82 } 83 84 #if defined (__powerpc64__) || (__powerpc__) 85 #ifndef PPC_FEATURE_TRUE_LE 86 #define PPC_FEATURE_TRUE_LE 0x00000002 87 #endif 88 89 #include <asm/cputable.h> 90 91 volatile int got_sigill; 92 sigjmp_buf jb; 93 94 void sigill(int sig) 95 { 96 got_sigill = 1; 97 siglongjmp(jb, 1); 98 } 99 100 void do_le_switch(void) 101 { 102 register int r0 asm("r0"); 103 104 r0 = 0x1ebe; 105 asm volatile ("sc; .long 0x02000044":"=&r" (r0):"0"(r0) 106 :"cr0", "r9", "r10", "r11", "r12"); 107 } 108 109 int main4(int ac, char **av, char **envp, unsigned long *auxv) 110 { 111 112 if ((tst_kvercmp(2, 6, 26)) < 0) { 113 tst_brkm(TCONF, 114 NULL, 115 "This test can only run on kernels that are 2.6.26 and higher"); 116 } 117 setup(); 118 for (; *auxv != AT_NULL && *auxv != AT_HWCAP; auxv += 2) ; 119 if (!(auxv[0] == AT_HWCAP && (auxv[1] & PPC_FEATURE_TRUE_LE))) { 120 tst_brkm(TCONF, cleanup, 121 "Processor does not support little-endian mode"); 122 } 123 signal(SIGILL, sigill); 124 if (sigsetjmp(jb, 1) == 0) 125 do_le_switch(); 126 if (got_sigill) { 127 tst_brkm(TFAIL, NULL, "Got SIGILL - test failed"); 128 } 129 tst_resm(TPASS, "endian_switch() syscall tests passed"); 130 tst_exit(); 131 } 132 133 #else 134 135 int main(void) 136 { 137 138 tst_brkm(TCONF, cleanup, 139 "This system does not support running of switch() syscall"); 140 } 141 142 #endif 143