mirror of
https://github.com/ipxe/ipxe
synced 2026-04-16 03:00:10 +03:00
[arm] Add support for 64-bit ARM (Aarch64)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user