tile: improve big-endian support
authorChris Metcalf <cmetcalf@tilera.com>
Wed, 7 Aug 2013 15:55:35 +0000 (11:55 -0400)
committerChris Metcalf <cmetcalf@tilera.com>
Tue, 13 Aug 2013 20:26:05 +0000 (16:26 -0400)
First, fix a bug in asm/unaligned.h; we need to just use the asm-generic
unaligned.h so we properly choose endian-correct flavors.

Second, keep the hv/hypervisor.h ABI fully "native" in the sense that
we don't have __BIG_ENDIAN__ ifdefs there.  Instead, we use macros in
the head_NN.S assembly code to properly extract two 32-bit structure
members from a 64-bit register holding the structure.

Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
arch/tile/include/asm/unaligned.h
arch/tile/include/hv/hypervisor.h
arch/tile/kernel/head_64.S

index 37dfbe5988722d4810c20693400bec5480b7d6c6..5a58a0d11449522c705a446a79f1f0b99fd06c1c 100644 (file)
 #ifndef _ASM_TILE_UNALIGNED_H
 #define _ASM_TILE_UNALIGNED_H
 
-#include <linux/unaligned/le_struct.h>
-#include <linux/unaligned/be_byteshift.h>
-#include <linux/unaligned/generic.h>
-#define get_unaligned  __get_unaligned_le
-#define put_unaligned  __put_unaligned_le
+/*
+ * We could implement faster get_unaligned_[be/le]64 using the ldna
+ * instruction on tilegx; however, we need to either copy all of the
+ * other generic functions to here (which is pretty ugly) or else
+ * modify both the generic code and other arch code to allow arch
+ * specific unaligned data access functions.  Given these functions
+ * are not often called, we'll stick with the generic version.
+ */
+#include <asm-generic/unaligned.h>
 
 /*
  * Is the kernel doing fixups of unaligned accesses?  If <0, no kernel
index f882ebcf43a9eaa03e2fa2b8c4d22229408828f0..0971ebbde1b7fbc70116165725be1e8c12c9bd35 100644 (file)
@@ -564,16 +564,11 @@ int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len);
 /** Tile coordinate */
 typedef struct
 {
-#ifndef __BIG_ENDIAN__
   /** X coordinate, relative to supervisor's top-left coordinate */
   int x;
 
   /** Y coordinate, relative to supervisor's top-left coordinate */
   int y;
-#else
-  int y;
-  int x;
-#endif
 } HV_Coord;
 
 
@@ -1119,13 +1114,8 @@ HV_VirtAddrRange hv_inquire_virtual(int idx);
 /** A range of ASID values. */
 typedef struct
 {
-#ifndef __BIG_ENDIAN__
   HV_ASID start;        /**< First ASID in the range. */
   unsigned int size;    /**< Number of ASIDs. Zero for an invalid range. */
-#else
-  unsigned int size;    /**< Number of ASIDs. Zero for an invalid range. */
-  HV_ASID start;        /**< First ASID in the range. */
-#endif
 } HV_ASIDRange;
 
 /** Returns information about a range of ASIDs.
@@ -1449,7 +1439,6 @@ typedef enum
 /** Message recipient. */
 typedef struct
 {
-#ifndef __BIG_ENDIAN__
   /** X coordinate, relative to supervisor's top-left coordinate */
   unsigned int x:11;
 
@@ -1458,11 +1447,6 @@ typedef struct
 
   /** Status of this recipient */
   HV_Recip_State state:10;
-#else //__BIG_ENDIAN__
-  HV_Recip_State state:10;
-  unsigned int y:11;
-  unsigned int x:11;
-#endif
 } HV_Recipient;
 
 /** Send a message to a set of recipients.
index e23e5f7b91d9a997c502853d93e7c340fa8fec84..ed51320847ce8cfb2eec5a90d859dc4de38ec6a1 100644 (file)
 #include <arch/chip.h>
 #include <arch/spr_def.h>
 
+/* Extract two 32-bit bit values that were read into one register. */
+#ifdef __BIG_ENDIAN__
+#define GET_FIRST_INT(rd, rs) shrsi rd, rs, 32
+#define GET_SECOND_INT(rd, rs) addxi rd, rs, 0
+#else
+#define GET_FIRST_INT(rd, rs) addxi rd, rs, 0
+#define GET_SECOND_INT(rd, rs) shrsi rd, rs, 32
+#endif
+
 /*
  * This module contains the entry code for kernel images. It performs the
  * minimal setup needed to call the generic C routines.
@@ -61,7 +70,7 @@ ENTRY(_start)
         * other CPUs should see a properly-constructed page table.
         */
        {
-         v4int_l r2, zero, r0    /* ASID for hv_install_context */
+         GET_FIRST_INT(r2, r0)    /* ASID for hv_install_context */
          moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
        }
        {
@@ -131,19 +140,14 @@ ENTRY(_start)
        shl16insli r0, r0, hw0(MEM_SV_START)
        mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
 
-       /*
-        * Get our processor number and save it away in SAVE_K_0.
-        * Extract stuff from the topology structure: r4 = y, r6 = x,
-        * r5 = width.  FIXME: consider whether we want to just make these
-        * 64-bit values (and if so fix smp_topology write below, too).
-        */
+       /* Get our processor number and save it away in SAVE_K_0. */
        jal hv_inquire_topology
        {
-         v4int_l r5, zero, r1    /* r5 = width */
-         shrui r4, r0, 32        /* r4 = y */
+         GET_FIRST_INT(r5, r1)   /* r5 = width */
+         GET_SECOND_INT(r4, r0)  /* r4 = y */
        }
        {
-         v4int_l r6, zero, r0    /* r6 = x */
+         GET_FIRST_INT(r6, r0)   /* r6 = x */
          mul_lu_lu r4, r4, r5
        }
        {