Make SH port work for packagers that don't differentiate between SH4 and SH4A
authorJens Axboe <jaxboe@fusionio.com>
Thu, 25 Aug 2011 12:24:03 +0000 (14:24 +0200)
committerJens Axboe <jaxboe@fusionio.com>
Thu, 25 Aug 2011 12:24:03 +0000 (14:24 +0200)
Generic bits done by me, SH specific bits implemented by
Nobuhiro Iwamatsu <iwamatsu@nigauri.org>.

Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
arch/arch-sh.h
arch/arch.h
fio.c

index 08c5fb3dbf68b98b503e0dfbf6e165a40c746465..ef4ee032f1ca0922014baca2e0697f210b3a37d7 100644 (file)
 
 #define nop             __asm__ __volatile__ ("nop": : :"memory")
 
 
 #define nop             __asm__ __volatile__ ("nop": : :"memory")
 
-#if defined(__SH4A__)
-#define        mb()            __asm__ __volatile__ ("synco": : :"memory")
-#else
-#define mb()           __asm__ __volatile__ (" " : : : "memory")
-#endif
+#define mb()                                                           \
+       do {                                                            \
+               if (arch_flags & ARCH_FLAG_1)                           \
+                       __asm__ __volatile__ ("synco": : :"memory");    \
+               else                                                    \
+                       __asm__ __volatile__ (" " : : : "memory");      \
+       } while (0)
 
 #define read_barrier() mb()
 #define write_barrier()        mb()
 
 
 #define read_barrier() mb()
 #define write_barrier()        mb()
 
+#define CPU_HAS_LLSC   0x0040
+
+static inline int arch_init(char *envp[])
+{
+       Elf32_auxv_t *auxv;
+
+       while (*envp++ != NULL)
+               ;
+
+       for (auxv = (Elf32_auxv_t *) envp; auxv->a_type != AT_NULL; auxv++) {
+               if (auxv->a_type == AT_HWCAP) {
+                       if (auxv->a_un.a_val & CPU_HAS_LLSC) {
+                               arch_flags |= ARCH_FLAG_1;
+                               break;
+                       }
+               }
+       }
+
+       return 0;
+}
+
+#define ARCH_HAVE_INIT
+
 #endif
 #endif
index 8cafa118af2c036e7afc88a93bb7602ca221626b..16f4c3ab2f7b40a06e638c1fed1da7b96d921aa5 100644 (file)
@@ -58,4 +58,18 @@ enum {
 #include "../lib/ffz.h"
 #endif
 
 #include "../lib/ffz.h"
 #endif
 
+#ifndef ARCH_HAVE_INIT
+static inline int arch_init(char *envp[])
+{
+       return 0;
+}
+#endif
+
+enum {
+       ARCH_FLAG_1     = 1 << 0,
+       ARCH_FLAG_2     = 1 << 1,
+       ARCH_FLAG_3     = 1 << 2,
+       ARCH_FLAG_4     = 1 << 3,
+};
+
 #endif
 #endif
diff --git a/fio.c b/fio.c
index 73964214d3468d93a4f0ed72f4ecbd330f57b9c6..9c1bed379df586ba8f3efea187aaaf319ce2d387 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -70,6 +70,8 @@ static pthread_t disk_util_thread;
 static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 
 static struct flist_head *cgroup_list;
 static char *cgroup_mnt;
 
+unsigned long arch_flags = 0;
+
 struct io_log *agg_io_log[2];
 
 #define TERMINATE_ALL          (-1)
 struct io_log *agg_io_log[2];
 
 #define TERMINATE_ALL          (-1)
@@ -1690,10 +1692,12 @@ static void run_threads(void)
        fio_unpin_memory();
 }
 
        fio_unpin_memory();
 }
 
-int main(int argc, char *argv[])
+int main(int argc, char *argv[], char *envp[])
 {
        long ps;
 
 {
        long ps;
 
+       arch_init(envp);
+
        sinit();
        init_rand(&__fio_rand_state);
 
        sinit();
        init_rand(&__fio_rand_state);