• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@samba.org>                             */
33 /*                                                                            */
34 /* History:     Created - Sep 02 2008 - Paul Mackerras <paulus@samba.org>     */
35 /*              Ported to LTP                                                 */
36 /*                      - Sep 02 2008                                         */
37 /*                      - Subrata Modak <subrata@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__)
setup(void)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 
cleanup(void)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 
sigill(int sig)94 void sigill(int sig)
95 {
96 	got_sigill = 1;
97 	siglongjmp(jb, 1);
98 }
99 
do_le_switch(void)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 
main4(int ac,char ** av,char ** envp,unsigned long * auxv)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 
main(void)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