aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2013-08-07 11:55:35 -0400
committerChris Metcalf <cmetcalf@tilera.com>2013-08-13 16:26:05 -0400
commitba02f0eb826da6dbdc5a2958ac52304ee441234f (patch)
tree8b50a046b6dd1a4cbc1379ae43c1c673c39e8d3d
parentbc1a298f4e04833db4c430df59b90039f0170515 (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.h14
-rw-r--r--arch/tile/include/hv/hypervisor.h16
-rw-r--r--arch/tile/kernel/head_64.S24
3 files changed, 23 insertions, 31 deletions
diff --git a/arch/tile/include/asm/unaligned.h b/arch/tile/include/asm/unaligned.h
index 37dfbe598872..5a58a0d11449 100644
--- a/arch/tile/include/asm/unaligned.h
+++ b/arch/tile/include/asm/unaligned.h
@@ -15,11 +15,15 @@
15#ifndef _ASM_TILE_UNALIGNED_H 15#ifndef _ASM_TILE_UNALIGNED_H
16#define _ASM_TILE_UNALIGNED_H 16#define _ASM_TILE_UNALIGNED_H
17 17
18#include <linux/unaligned/le_struct.h> 18/*
19#include <linux/unaligned/be_byteshift.h> 19 * We could implement faster get_unaligned_[be/le]64 using the ldna
20#include <linux/unaligned/generic.h> 20 * instruction on tilegx; however, we need to either copy all of the
21#define get_unaligned __get_unaligned_le 21 * other generic functions to here (which is pretty ugly) or else
22#define put_unaligned __put_unaligned_le 22 * modify both the generic code and other arch code to allow arch
23 * specific unaligned data access functions. Given these functions
24 * are not often called, we'll stick with the generic version.
25 */
26#include <asm-generic/unaligned.h>
23 27
24/* 28/*
25 * Is the kernel doing fixups of unaligned accesses? If <0, no kernel 29 * 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 f882ebcf43a9..0971ebbde1b7 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);
564/** Tile coordinate */ 564/** Tile coordinate */
565typedef struct 565typedef struct
566{ 566{
567#ifndef __BIG_ENDIAN__
568 /** X coordinate, relative to supervisor's top-left coordinate */ 567 /** X coordinate, relative to supervisor's top-left coordinate */
569 int x; 568 int x;
570 569
571 /** Y coordinate, relative to supervisor's top-left coordinate */ 570 /** Y coordinate, relative to supervisor's top-left coordinate */
572 int y; 571 int y;
573#else
574 int y;
575 int x;
576#endif
577} HV_Coord; 572} HV_Coord;
578 573
579 574
@@ -1119,13 +1114,8 @@ HV_VirtAddrRange hv_inquire_virtual(int idx);
1119/** A range of ASID values. */ 1114/** A range of ASID values. */
1120typedef struct 1115typedef struct
1121{ 1116{
1122#ifndef __BIG_ENDIAN__
1123 HV_ASID start; /**< First ASID in the range. */ 1117 HV_ASID start; /**< First ASID in the range. */
1124 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1118 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
1125#else
1126 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
1127 HV_ASID start; /**< First ASID in the range. */
1128#endif
1129} HV_ASIDRange; 1119} HV_ASIDRange;
1130 1120
1131/** Returns information about a range of ASIDs. 1121/** Returns information about a range of ASIDs.
@@ -1449,7 +1439,6 @@ typedef enum
1449/** Message recipient. */ 1439/** Message recipient. */
1450typedef struct 1440typedef struct
1451{ 1441{
1452#ifndef __BIG_ENDIAN__
1453 /** X coordinate, relative to supervisor's top-left coordinate */ 1442 /** X coordinate, relative to supervisor's top-left coordinate */
1454 unsigned int x:11; 1443 unsigned int x:11;
1455 1444
@@ -1458,11 +1447,6 @@ typedef struct
1458 1447
1459 /** Status of this recipient */ 1448 /** Status of this recipient */
1460 HV_Recip_State state:10; 1449 HV_Recip_State state:10;
1461#else //__BIG_ENDIAN__
1462 HV_Recip_State state:10;
1463 unsigned int y:11;
1464 unsigned int x:11;
1465#endif
1466} HV_Recipient; 1450} HV_Recipient;
1467 1451
1468/** Send a message to a set of recipients. 1452/** 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 e23e5f7b91d9..ed51320847ce 100644
--- a/arch/tile/kernel/head_64.S
+++ b/arch/tile/kernel/head_64.S
@@ -25,6 +25,15 @@
25#include <arch/chip.h> 25#include <arch/chip.h>
26#include <arch/spr_def.h> 26#include <arch/spr_def.h>
27 27
28/* Extract two 32-bit bit values that were read into one register. */
29#ifdef __BIG_ENDIAN__
30#define GET_FIRST_INT(rd, rs) shrsi rd, rs, 32
31#define GET_SECOND_INT(rd, rs) addxi rd, rs, 0
32#else
33#define GET_FIRST_INT(rd, rs) addxi rd, rs, 0
34#define GET_SECOND_INT(rd, rs) shrsi rd, rs, 32
35#endif
36
28/* 37/*
29 * This module contains the entry code for kernel images. It performs the 38 * This module contains the entry code for kernel images. It performs the
30 * minimal setup needed to call the generic C routines. 39 * minimal setup needed to call the generic C routines.
@@ -61,7 +70,7 @@ ENTRY(_start)
61 * other CPUs should see a properly-constructed page table. 70 * other CPUs should see a properly-constructed page table.
62 */ 71 */
63 { 72 {
64 v4int_l r2, zero, r0 /* ASID for hv_install_context */ 73 GET_FIRST_INT(r2, r0) /* ASID for hv_install_context */
65 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET) 74 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
66 } 75 }
67 { 76 {
@@ -131,19 +140,14 @@ ENTRY(_start)
131 shl16insli r0, r0, hw0(MEM_SV_START) 140 shl16insli r0, r0, hw0(MEM_SV_START)
132 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0 141 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
133 142
134 /* 143 /* Get our processor number and save it away in SAVE_K_0. */
135 * Get our processor number and save it away in SAVE_K_0.
136 * Extract stuff from the topology structure: r4 = y, r6 = x,
137 * r5 = width. FIXME: consider whether we want to just make these
138 * 64-bit values (and if so fix smp_topology write below, too).
139 */
140 jal hv_inquire_topology 144 jal hv_inquire_topology
141 { 145 {
142 v4int_l r5, zero, r1 /* r5 = width */ 146 GET_FIRST_INT(r5, r1) /* r5 = width */
143 shrui r4, r0, 32 /* r4 = y */ 147 GET_SECOND_INT(r4, r0) /* r4 = y */
144 } 148 }
145 { 149 {
146 v4int_l r6, zero, r0 /* r6 = x */ 150 GET_FIRST_INT(r6, r0) /* r6 = x */
147 mul_lu_lu r4, r4, r5 151 mul_lu_lu r4, r4, r5
148 } 152 }
149 { 153 {