[arm] Add support for 64-bit ARM (Aarch64)

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2016-05-08 00:20:20 +01:00
parent edea3a434c
commit 17c6f322ee
21 changed files with 1055 additions and 15 deletions
+5
View File
@@ -84,5 +84,10 @@ PROVIDE_IOAPI_INLINE ( arm, writew );
PROVIDE_IOAPI_INLINE ( arm, writel );
PROVIDE_IOAPI_INLINE ( arm, iodelay );
PROVIDE_IOAPI_INLINE ( arm, mb );
#ifdef __aarch64__
PROVIDE_IOAPI_INLINE ( arm, readq );
PROVIDE_IOAPI_INLINE ( arm, writeq );
#else
PROVIDE_IOAPI ( arm, readq, arm32_readq );
PROVIDE_IOAPI ( arm, writeq, arm32_writeq );
#endif
+9
View File
@@ -10,12 +10,21 @@
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
/* Hypercall registers */
#ifdef __aarch64__
#define XEN_HC "x16"
#define XEN_REG1 "x0"
#define XEN_REG2 "x1"
#define XEN_REG3 "x2"
#define XEN_REG4 "x3"
#define XEN_REG5 "x4"
#else
#define XEN_HC "r12"
#define XEN_REG1 "r0"
#define XEN_REG2 "r1"
#define XEN_REG3 "r2"
#define XEN_REG4 "r3"
#define XEN_REG5 "r4"
#endif
/**
* Issue hypercall with one argument
+30 -14
View File
@@ -43,34 +43,46 @@ IOAPI_INLINE ( arm, bus_to_phys ) ( unsigned long bus_addr ) {
*
*/
#define ARM_READX( _api_func, _type, _insn_suffix ) \
#define ARM_READX( _api_func, _type, _insn_suffix, _reg_prefix ) \
static inline __always_inline _type \
IOAPI_INLINE ( arm, _api_func ) ( volatile _type *io_addr ) { \
_type data; \
__asm__ __volatile__ ( "ldr" _insn_suffix " %0, %1" \
__asm__ __volatile__ ( "ldr" _insn_suffix " %" _reg_prefix "0, %1" \
: "=r" ( data ) : "Qo" ( *io_addr ) ); \
return data; \
}
ARM_READX ( readb, uint8_t, "b" );
ARM_READX ( readw, uint16_t, "h" );
ARM_READX ( readl, uint32_t, "" );
#ifdef __aarch64__
ARM_READX ( readb, uint8_t, "b", "w" );
ARM_READX ( readw, uint16_t, "h", "w" );
ARM_READX ( readl, uint32_t, "", "w" );
ARM_READX ( readq, uint64_t, "", "" );
#else
ARM_READX ( readb, uint8_t, "b", "" );
ARM_READX ( readw, uint16_t, "h", "" );
ARM_READX ( readl, uint32_t, "", "" );
#endif
#define ARM_WRITEX( _api_func, _type, _insn_suffix ) \
#define ARM_WRITEX( _api_func, _type, _insn_suffix, _reg_prefix ) \
static inline __always_inline void \
IOAPI_INLINE ( arm, _api_func ) ( _type data, \
volatile _type *io_addr ) { \
__asm__ __volatile__ ( "str" _insn_suffix " %0, %1" \
IOAPI_INLINE ( arm, _api_func ) ( _type data, volatile _type *io_addr ) { \
__asm__ __volatile__ ( "str" _insn_suffix " %" _reg_prefix "0, %1" \
: : "r" ( data ), "Qo" ( *io_addr ) ); \
}
ARM_WRITEX ( writeb, uint8_t, "b" );
ARM_WRITEX ( writew, uint16_t, "h" );
ARM_WRITEX ( writel, uint32_t, "" );
#ifdef __aarch64__
ARM_WRITEX ( writeb, uint8_t, "b", "w" );
ARM_WRITEX ( writew, uint16_t, "h", "w" );
ARM_WRITEX ( writel, uint32_t, "", "w" );
ARM_WRITEX ( writeq, uint64_t, "", "" );
#else
ARM_WRITEX ( writeb, uint8_t, "b", "" );
ARM_WRITEX ( writew, uint16_t, "h", "" );
ARM_WRITEX ( writel, uint32_t, "", "" );
#endif
/*
* Slow down I/O
*
*/
static inline __always_inline void
IOAPI_INLINE ( arm, iodelay ) ( void ) {
/* Nothing to do */
@@ -80,10 +92,14 @@ IOAPI_INLINE ( arm, iodelay ) ( void ) {
* Memory barrier
*
*/
static inline __always_inline void
IOAPI_INLINE ( arm, mb ) ( void ) {
#ifdef __aarch64__
__asm__ __volatile__ ( "dmb sy" );
#else
__asm__ __volatile__ ( "dmb" );
#endif
}
#endif /* _IPXE_ARM_IO_H */