Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+23 -31
+9 -5
arch/tile/include/asm/unaligned.h
··· 15 15 #ifndef _ASM_TILE_UNALIGNED_H 16 16 #define _ASM_TILE_UNALIGNED_H 17 17 18 - #include <linux/unaligned/le_struct.h> 19 - #include <linux/unaligned/be_byteshift.h> 20 - #include <linux/unaligned/generic.h> 21 - #define get_unaligned __get_unaligned_le 22 - #define put_unaligned __put_unaligned_le 18 + /* 19 + * We could implement faster get_unaligned_[be/le]64 using the ldna 20 + * instruction on tilegx; however, we need to either copy all of the 21 + * other generic functions to here (which is pretty ugly) or else 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 29 * Is the kernel doing fixups of unaligned accesses? If <0, no kernel
-16
arch/tile/include/hv/hypervisor.h
··· 564 564 /** Tile coordinate */ 565 565 typedef struct 566 566 { 567 - #ifndef __BIG_ENDIAN__ 568 567 /** X coordinate, relative to supervisor's top-left coordinate */ 569 568 int x; 570 569 571 570 /** Y coordinate, relative to supervisor's top-left coordinate */ 572 571 int y; 573 - #else 574 - int y; 575 - int x; 576 - #endif 577 572 } HV_Coord; 578 573 579 574 ··· 1114 1119 /** A range of ASID values. */ 1115 1120 typedef struct 1116 1121 { 1117 - #ifndef __BIG_ENDIAN__ 1118 1122 HV_ASID start; /**< First ASID in the range. */ 1119 1123 unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1120 - #else 1121 - unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */ 1122 - HV_ASID start; /**< First ASID in the range. */ 1123 - #endif 1124 1124 } HV_ASIDRange; 1125 1125 1126 1126 /** Returns information about a range of ASIDs. ··· 1439 1449 /** Message recipient. */ 1440 1450 typedef struct 1441 1451 { 1442 - #ifndef __BIG_ENDIAN__ 1443 1452 /** X coordinate, relative to supervisor's top-left coordinate */ 1444 1453 unsigned int x:11; 1445 1454 ··· 1447 1458 1448 1459 /** Status of this recipient */ 1449 1460 HV_Recip_State state:10; 1450 - #else //__BIG_ENDIAN__ 1451 - HV_Recip_State state:10; 1452 - unsigned int y:11; 1453 - unsigned int x:11; 1454 - #endif 1455 1461 } HV_Recipient; 1456 1462 1457 1463 /** Send a message to a set of recipients.
+14 -10
arch/tile/kernel/head_64.S
··· 25 25 #include <arch/chip.h> 26 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 38 * This module contains the entry code for kernel images. It performs the 30 39 * minimal setup needed to call the generic C routines. ··· 70 61 * other CPUs should see a properly-constructed page table. 71 62 */ 72 63 { 73 - v4int_l r2, zero, r0 /* ASID for hv_install_context */ 64 + GET_FIRST_INT(r2, r0) /* ASID for hv_install_context */ 74 65 moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET) 75 66 } 76 67 { ··· 140 131 shl16insli r0, r0, hw0(MEM_SV_START) 141 132 mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0 142 133 143 - /* 144 - * Get our processor number and save it away in SAVE_K_0. 145 - * Extract stuff from the topology structure: r4 = y, r6 = x, 146 - * r5 = width. FIXME: consider whether we want to just make these 147 - * 64-bit values (and if so fix smp_topology write below, too). 148 - */ 134 + /* Get our processor number and save it away in SAVE_K_0. */ 149 135 jal hv_inquire_topology 150 136 { 151 - v4int_l r5, zero, r1 /* r5 = width */ 152 - shrui r4, r0, 32 /* r4 = y */ 137 + GET_FIRST_INT(r5, r1) /* r5 = width */ 138 + GET_SECOND_INT(r4, r0) /* r4 = y */ 153 139 } 154 140 { 155 - v4int_l r6, zero, r0 /* r6 = x */ 141 + GET_FIRST_INT(r6, r0) /* r6 = x */ 156 142 mul_lu_lu r4, r4, r5 157 143 } 158 144 {