asm: add asm inline for system set/clear/test bit
This commit adds asm implementation for the methods: sys_io_set_bit sys_io_clear_bit sys_io_test_bit sys_io_test_and_set_bit sys_io_test_and_clear_bit Change-Id: I144568e113316fa43d943cdc5457cb17e66839c3 Signed-off-by: Juan Manuel Cruz <juan.m.cruz.alcaraz@linux.intel.com> Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
parent
5563290d36
commit
71c289dfbc
3 changed files with 201 additions and 2 deletions
|
@ -65,6 +65,74 @@ static inline __attribute__((always_inline))
|
||||||
return _arc_v2_aux_reg_read(port);
|
return _arc_v2_aux_reg_read(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
void sys_io_set_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
uint32_t reg = 0;
|
||||||
|
|
||||||
|
__asm__ volatile("lr %1, [%0]\n"
|
||||||
|
"bset %1, %1, %2\n"
|
||||||
|
"sr %1, [%0];\n\t"
|
||||||
|
:
|
||||||
|
: "ir" (port),
|
||||||
|
"r" (reg), "Mr" (bit)
|
||||||
|
: "memory", "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
void sys_io_clear_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
uint32_t reg = 0;
|
||||||
|
|
||||||
|
__asm__ volatile("lr %1, [%0]\n"
|
||||||
|
"bclr %1, %1, %2\n"
|
||||||
|
"sr %1, [%0];\n\t"
|
||||||
|
:
|
||||||
|
: "ir" (port),
|
||||||
|
"r" (reg), "Mr" (bit)
|
||||||
|
: "memory", "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
int sys_io_test_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
uint32_t status = _ARC_V2_STATUS32;
|
||||||
|
uint32_t reg = 0;
|
||||||
|
uint32_t ret;
|
||||||
|
|
||||||
|
__asm__ volatile("lr %2, [%1]\n"
|
||||||
|
"btst %2, %3\n"
|
||||||
|
"lr %0, [%4];\n\t"
|
||||||
|
: "=r" (ret)
|
||||||
|
: "ir" (port),
|
||||||
|
"r" (reg), "Mr" (bit), "i" (status)
|
||||||
|
: "memory", "cc");
|
||||||
|
|
||||||
|
return !(ret & _ARC_V2_STATUS32_Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
int sys_io_test_and_set_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sys_io_test_bit(port, bit);
|
||||||
|
sys_io_set_bit(port, bit);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
int sys_io_test_and_clear_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sys_io_test_bit(port, bit);
|
||||||
|
sys_io_clear_bit(port, bit);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void sys_write8(uint8_t data, mm_reg_t addr)
|
void sys_write8(uint8_t data, mm_reg_t addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -286,6 +286,79 @@ static inline __attribute__((always_inline))
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
void sys_io_set_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
uint32_t reg = 0;
|
||||||
|
|
||||||
|
__asm__ volatile("inl %%dx, %%eax\n"
|
||||||
|
"mov %1, 1\n"
|
||||||
|
"shl %%cl, %1\n"
|
||||||
|
"or %%eax, %1\n"
|
||||||
|
"outl %%eax, %%dx;\n\t"
|
||||||
|
:
|
||||||
|
: "d" (port),
|
||||||
|
"r" (reg), "d" (bit)
|
||||||
|
: "memory", "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
void sys_io_clear_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
uint32_t reg = 0;
|
||||||
|
|
||||||
|
__asm__ volatile("inl %%dx, %%eax\n"
|
||||||
|
"mov %1, 1\n"
|
||||||
|
"shl %%cl, %1\n"
|
||||||
|
"and %%eax, %1\n"
|
||||||
|
"outl %%eax, %%dx;\n\t"
|
||||||
|
:
|
||||||
|
: "d" (port),
|
||||||
|
"r" (reg), "d" (bit)
|
||||||
|
: "memory", "cc");
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
int sys_io_test_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
uint32_t ret;
|
||||||
|
|
||||||
|
__asm__ volatile("inl %%dx, %%eax\n"
|
||||||
|
"bt %2, %%eax\n"
|
||||||
|
"lahf\n"
|
||||||
|
"mov %1, %%eax\n"
|
||||||
|
"clc;\n\t"
|
||||||
|
: "=r" (ret)
|
||||||
|
: "d" (port),
|
||||||
|
"Mr" (bit)
|
||||||
|
: "memory", "cc");
|
||||||
|
|
||||||
|
return (ret & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
int sys_io_test_and_set_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sys_io_test_bit(port, bit);
|
||||||
|
sys_io_set_bit(port, bit);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline))
|
||||||
|
int sys_io_test_and_clear_bit(io_port_t port, int bit)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = sys_io_test_bit(port, bit);
|
||||||
|
sys_io_clear_bit(port, bit);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static inline __attribute__((always_inline))
|
static inline __attribute__((always_inline))
|
||||||
void sys_write8(uint8_t data, mm_reg_t addr)
|
void sys_write8(uint8_t data, mm_reg_t addr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,6 +95,64 @@ typedef uint32_t mem_addr_t;
|
||||||
* @return the 32 bits read
|
* @return the 32 bits read
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static inline void sys_io_set_bit(io_port_t port, int bit)
|
||||||
|
* @brief Set the designated bit from port to 1
|
||||||
|
*
|
||||||
|
* This functions takes the designated bit starting from port and sets it to 1.
|
||||||
|
*
|
||||||
|
* @param port the port address from where to look for the bit
|
||||||
|
* @param bit the designated bit to set (from 0 to n)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static inline void sys_io_clear_bit(io_port_t port, int bit)
|
||||||
|
* @brief Clear the designated bit from port to 0
|
||||||
|
*
|
||||||
|
* This functions takes the designated bit starting from port and sets it to 0.
|
||||||
|
*
|
||||||
|
* @param port the port address from where to look for the bit
|
||||||
|
* @param bit the designated bit to clear (from 0 to n)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static inline int sys_io_test_bit(io_port_t port, int bit)
|
||||||
|
* @brief Test the bit from port if it is set or not
|
||||||
|
*
|
||||||
|
* This functions takes the designated bit starting from port and tests its
|
||||||
|
* current setting. It will return the current setting.
|
||||||
|
*
|
||||||
|
* @param port the port address from where to look for the bit
|
||||||
|
* @param bit the designated bit to test (from 0 to n)
|
||||||
|
*
|
||||||
|
* @return 1 if it is set, 0 otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static inline int sys_io_test_and_set_bit(io_port_t port, int bit)
|
||||||
|
* @brief Test the bit from port and set it
|
||||||
|
*
|
||||||
|
* This functions takes the designated bit starting from port, tests its
|
||||||
|
* current setting and sets it. It will return the previous setting.
|
||||||
|
*
|
||||||
|
* @param port the port address from where to look for the bit
|
||||||
|
* @param bit the designated bit to test and set (from 0 to n)
|
||||||
|
*
|
||||||
|
* @return 1 if it was set, 0 otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static inline int sys_io_test_and_clear_bit(io_port_t port, int bit)
|
||||||
|
* @brief Test the bit from port and clear it
|
||||||
|
*
|
||||||
|
* This functions takes the designated bit starting from port, tests its
|
||||||
|
* current setting and clears it. It will return the previous setting.
|
||||||
|
*
|
||||||
|
* @param port the port address from where to look for the bit
|
||||||
|
* @param bit the designated bit to test and clear (from 0 to n)
|
||||||
|
*
|
||||||
|
* @return 0 if it was clear, 1 otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
/* Memory mapped registers I/O functions */
|
/* Memory mapped registers I/O functions */
|
||||||
|
|
||||||
|
@ -190,7 +248,7 @@ typedef uint32_t mem_addr_t;
|
||||||
* @brief Test the bit if it is set or not
|
* @brief Test the bit if it is set or not
|
||||||
*
|
*
|
||||||
* This functions takes the designated bit starting from addr and tests its
|
* This functions takes the designated bit starting from addr and tests its
|
||||||
* current setting. If it return the current setting.
|
* current setting. It will return the current setting.
|
||||||
*
|
*
|
||||||
* @param addr the memory address from where to look for the bit
|
* @param addr the memory address from where to look for the bit
|
||||||
* @param bit the designated bit to test (from 0 to n)
|
* @param bit the designated bit to test (from 0 to n)
|
||||||
|
@ -219,7 +277,7 @@ typedef uint32_t mem_addr_t;
|
||||||
* current setting and clears it. It will return the previous setting.
|
* current setting and clears it. It will return the previous setting.
|
||||||
*
|
*
|
||||||
* @param addr the memory address from where to look for the bit
|
* @param addr the memory address from where to look for the bit
|
||||||
* @param bit the designated bit to test (from 0 to n)
|
* @param bit the designated bit to test and clear (from 0 to n)
|
||||||
*
|
*
|
||||||
* @return 0 if it was clear, 1 otherwise
|
* @return 0 if it was clear, 1 otherwise
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue