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 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 */ |
565 | typedef struct | 565 | typedef 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. */ |
1120 | typedef struct | 1115 | typedef 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. */ |
1450 | typedef struct | 1440 | typedef 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 | { |