david/ipxe
david
/
ipxe
Archived
1
0
Fork 0
This repository has been archived on 2020-12-06. You can view files and clone it, but cannot push or open issues or pull requests.
ipxe/src/arch/arm/include/ipxe/arm_io.h

106 lines
2.3 KiB
C

#ifndef _IPXE_ARM_IO_H
#define _IPXE_ARM_IO_H
/** @file
*
* iPXE I/O API for ARM
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#ifdef IOAPI_ARM
#define IOAPI_PREFIX_arm
#else
#define IOAPI_PREFIX_arm __arm_
#endif
/*
* Memory space mappings
*
*/
/** Page shift */
#define PAGE_SHIFT 12
/*
* Physical<->Bus address mappings
*
*/
static inline __always_inline unsigned long
IOAPI_INLINE ( arm, phys_to_bus ) ( unsigned long phys_addr ) {
return phys_addr;
}
static inline __always_inline unsigned long
IOAPI_INLINE ( arm, bus_to_phys ) ( unsigned long bus_addr ) {
return bus_addr;
}
/*
* MMIO reads and writes up to native word size
*
*/
#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 " %" _reg_prefix "0, %1" \
: "=r" ( data ) : "Qo" ( *io_addr ) ); \
return data; \
}
#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, _reg_prefix ) \
static inline __always_inline void \
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 ) ); \
}
#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 */
}
/*
* 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 */