diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-07 11:55:35 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-13 16:26:05 -0400 |
commit | ba02f0eb826da6dbdc5a2958ac52304ee441234f (patch) | |
tree | 8b50a046b6dd1a4cbc1379ae43c1c673c39e8d3d | |
parent | bc1a298f4e04833db4c430df59b90039f0170515 (diff) |
tile: improve big-endian support
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>
-rw-r--r-- | arch/tile/include/asm/unaligned.h | 14 | ||||
-rw-r--r-- | arch/tile/include/hv/hypervisor.h | 16 | ||||
-rw-r--r-- | arch/tile/kernel/head_64.S | 24 |
3 files changed, 23 insertions, 31 deletions
diff --git a/arch/tile/include/asm/unaligned.h b/arch/tile/include/asm/unaligned.h index 37dfbe59887..5a58a0d1144 100644 --- a/arch/tile/include/asm/unaligned.h +++ b/arch/tile/include/asm/unaligned.h @@ -15,11 +15,15 @@ #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 diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h index f882ebcf43a..0971ebbde1b 100644 --- a/arch/tile/include/hv/hypervisor.h +++ b/arch/tile/include/hv/hypervisor.h @@ -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. diff --git a/arch/tile/kernel/head_64.S b/arch/tile/kernel/head_64.S index e23e5f7b91d..ed51320847c 100644 --- a/arch/tile/kernel/head_64.S +++ b/arch/tile/kernel/head_64.S @@ -25,6 +25,15 @@ #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 } { |