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>
This commit is contained in:
parent
bc1a298f4e
commit
ba02f0eb82
3 changed files with 23 additions and 31 deletions
|
@ -15,11 +15,15 @@
|
||||||
#ifndef _ASM_TILE_UNALIGNED_H
|
#ifndef _ASM_TILE_UNALIGNED_H
|
||||||
#define _ASM_TILE_UNALIGNED_H
|
#define _ASM_TILE_UNALIGNED_H
|
||||||
|
|
||||||
#include <linux/unaligned/le_struct.h>
|
/*
|
||||||
#include <linux/unaligned/be_byteshift.h>
|
* We could implement faster get_unaligned_[be/le]64 using the ldna
|
||||||
#include <linux/unaligned/generic.h>
|
* instruction on tilegx; however, we need to either copy all of the
|
||||||
#define get_unaligned __get_unaligned_le
|
* other generic functions to here (which is pretty ugly) or else
|
||||||
#define put_unaligned __put_unaligned_le
|
* 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
|
* Is the kernel doing fixups of unaligned accesses? If <0, no kernel
|
||||||
|
|
|
@ -564,16 +564,11 @@ int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len);
|
||||||
/** Tile coordinate */
|
/** Tile coordinate */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
#ifndef __BIG_ENDIAN__
|
|
||||||
/** X coordinate, relative to supervisor's top-left coordinate */
|
/** X coordinate, relative to supervisor's top-left coordinate */
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
/** Y coordinate, relative to supervisor's top-left coordinate */
|
/** Y coordinate, relative to supervisor's top-left coordinate */
|
||||||
int y;
|
int y;
|
||||||
#else
|
|
||||||
int y;
|
|
||||||
int x;
|
|
||||||
#endif
|
|
||||||
} HV_Coord;
|
} HV_Coord;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1119,13 +1114,8 @@ HV_VirtAddrRange hv_inquire_virtual(int idx);
|
||||||
/** A range of ASID values. */
|
/** A range of ASID values. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
#ifndef __BIG_ENDIAN__
|
|
||||||
HV_ASID start; /**< First ASID in the range. */
|
HV_ASID start; /**< First ASID in the range. */
|
||||||
unsigned int size; /**< Number of ASIDs. Zero for an invalid 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;
|
} HV_ASIDRange;
|
||||||
|
|
||||||
/** Returns information about a range of ASIDs.
|
/** Returns information about a range of ASIDs.
|
||||||
|
@ -1449,7 +1439,6 @@ typedef enum
|
||||||
/** Message recipient. */
|
/** Message recipient. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
#ifndef __BIG_ENDIAN__
|
|
||||||
/** X coordinate, relative to supervisor's top-left coordinate */
|
/** X coordinate, relative to supervisor's top-left coordinate */
|
||||||
unsigned int x:11;
|
unsigned int x:11;
|
||||||
|
|
||||||
|
@ -1458,11 +1447,6 @@ typedef struct
|
||||||
|
|
||||||
/** Status of this recipient */
|
/** Status of this recipient */
|
||||||
HV_Recip_State state:10;
|
HV_Recip_State state:10;
|
||||||
#else //__BIG_ENDIAN__
|
|
||||||
HV_Recip_State state:10;
|
|
||||||
unsigned int y:11;
|
|
||||||
unsigned int x:11;
|
|
||||||
#endif
|
|
||||||
} HV_Recipient;
|
} HV_Recipient;
|
||||||
|
|
||||||
/** Send a message to a set of recipients.
|
/** Send a message to a set of recipients.
|
||||||
|
|
|
@ -25,6 +25,15 @@
|
||||||
#include <arch/chip.h>
|
#include <arch/chip.h>
|
||||||
#include <arch/spr_def.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
|
* This module contains the entry code for kernel images. It performs the
|
||||||
* minimal setup needed to call the generic C routines.
|
* minimal setup needed to call the generic C routines.
|
||||||
|
@ -61,7 +70,7 @@ ENTRY(_start)
|
||||||
* other CPUs should see a properly-constructed page table.
|
* 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)
|
moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -131,19 +140,14 @@ ENTRY(_start)
|
||||||
shl16insli r0, r0, hw0(MEM_SV_START)
|
shl16insli r0, r0, hw0(MEM_SV_START)
|
||||||
mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
|
mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
|
||||||
|
|
||||||
/*
|
/* Get our processor number and save it away in SAVE_K_0. */
|
||||||
* 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).
|
|
||||||
*/
|
|
||||||
jal hv_inquire_topology
|
jal hv_inquire_topology
|
||||||
{
|
{
|
||||||
v4int_l r5, zero, r1 /* r5 = width */
|
GET_FIRST_INT(r5, r1) /* r5 = width */
|
||||||
shrui r4, r0, 32 /* r4 = y */
|
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
|
mul_lu_lu r4, r4, r5
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue