Home | History | Annotate | Download | only in switch
      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