2021-01-12 18:22:11 +00:00
|
|
|
/* SPDX-License-Identifier: MIT */
|
|
|
|
|
|
|
|
#ifndef UTILS_H
|
|
|
|
#define UTILS_H
|
|
|
|
|
|
|
|
#include "types.h"
|
|
|
|
|
|
|
|
#define printf debug_printf
|
|
|
|
|
2021-01-14 09:18:07 +00:00
|
|
|
static inline u64 read64(u64 addr)
|
|
|
|
{
|
|
|
|
u64 data;
|
|
|
|
__asm__ volatile("ldr\t%0, [%1]" : "=r"(data) : "r"(addr));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void write64(u64 addr, u64 data)
|
|
|
|
{
|
|
|
|
__asm__ volatile("str\t%0, [%1]" : : "r"(data), "r"(addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u64 set64(u64 addr, u64 set)
|
|
|
|
{
|
|
|
|
u64 data;
|
|
|
|
__asm__ volatile("ldr\t%0, [%1]\n"
|
|
|
|
"\torr\t%0, %0, %2\n"
|
|
|
|
"\tstr\t%0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u64 clear64(u64 addr, u64 clear)
|
|
|
|
{
|
|
|
|
u64 data;
|
|
|
|
__asm__ volatile("ldr\t%0, [%1]\n"
|
|
|
|
"\tbic\t%0, %0, %2\n"
|
|
|
|
"\tstr\t%0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u64 mask64(u64 addr, u64 clear, u64 set)
|
|
|
|
{
|
|
|
|
u64 data;
|
|
|
|
__asm__ volatile("ldr\t%0, [%1]\n"
|
|
|
|
"\tbic\t%0, %0, %3\n"
|
|
|
|
"\torr\t%0, %0, %2\n"
|
|
|
|
"\tstr\t%0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2021-01-12 18:22:11 +00:00
|
|
|
static inline u32 read32(u64 addr)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
__asm__ volatile("ldr\t%w0, [%1]" : "=r"(data) : "r"(addr));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void write32(u64 addr, u32 data)
|
|
|
|
{
|
|
|
|
__asm__ volatile("str\t%w0, [%1]" : : "r"(data), "r"(addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 set32(u64 addr, u32 set)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
__asm__ volatile("ldr\t%w0, [%1]\n"
|
|
|
|
"\torr\t%w0, %w0, %w2\n"
|
|
|
|
"\tstr\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 clear32(u64 addr, u32 clear)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
__asm__ volatile("ldr\t%w0, [%1]\n"
|
|
|
|
"\tbic\t%w0, %w0, %w2\n"
|
|
|
|
"\tstr\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 mask32(u64 addr, u32 clear, u32 set)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
__asm__ volatile("ldr\t%w0, [%1]\n"
|
|
|
|
"\tbic\t%w0, %w0, %w3\n"
|
|
|
|
"\torr\t%w0, %w0, %w2\n"
|
|
|
|
"\tstr\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u16 read16(u64 addr)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
__asm__ volatile("ldrh\t%w0, [%1]" : "=r"(data) : "r"(addr));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void write16(u64 addr, u16 data)
|
|
|
|
{
|
|
|
|
__asm__ volatile("strh\t%w0, [%1]" : : "r"(data), "r"(addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u16 set16(u64 addr, u16 set)
|
|
|
|
{
|
|
|
|
u16 data;
|
|
|
|
__asm__ volatile("ldrh\t%w0, [%1]\n"
|
|
|
|
"\torr\t%w0, %w0, %w2\n"
|
|
|
|
"\tstrh\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set)
|
|
|
|
|
|
|
|
);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u16 clear16(u64 addr, u16 clear)
|
|
|
|
{
|
|
|
|
u16 data;
|
|
|
|
__asm__ volatile("ldrh\t%w0, [%1]\n"
|
|
|
|
"\tbic\t%w0, %w0, %w2\n"
|
|
|
|
"\tstrh\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u16 mask16(u64 addr, u16 clear, u16 set)
|
|
|
|
{
|
|
|
|
u16 data;
|
|
|
|
__asm__ volatile("ldrh\t%w0, [%1]\n"
|
2021-01-14 09:18:07 +00:00
|
|
|
"\tbic\t%w0, %w0, %w3\n"
|
2021-01-12 18:22:11 +00:00
|
|
|
"\torr\t%w0, %w0, %w2\n"
|
|
|
|
"\tstrh\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u8 read8(u64 addr)
|
|
|
|
{
|
|
|
|
u32 data;
|
|
|
|
__asm__ volatile("ldrb\t%w0, [%1]" : "=r"(data) : "r"(addr));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void write8(u64 addr, u8 data)
|
|
|
|
{
|
|
|
|
__asm__ volatile("strb\t%w0, [%1]" : : "r"(data), "r"(addr));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u8 set8(u64 addr, u8 set)
|
|
|
|
{
|
|
|
|
u8 data;
|
|
|
|
__asm__ volatile("ldrb\t%w0, [%1]\n"
|
|
|
|
"\torr\t%w0, %w0, %w2\n"
|
|
|
|
"\tstrb\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u8 clear8(u64 addr, u8 clear)
|
|
|
|
{
|
|
|
|
u8 data;
|
|
|
|
__asm__ volatile("ldrb\t%w0, [%1]\n"
|
|
|
|
"\tbic\t%w0, %w0, %w2\n"
|
|
|
|
"\tstrb\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u8 mask8(u64 addr, u8 clear, u8 set)
|
|
|
|
{
|
|
|
|
u8 data;
|
|
|
|
__asm__ volatile("ldrb\t%w0, [%1]\n"
|
|
|
|
"\tbic\t%w0, %w0, %w3\n"
|
|
|
|
"\torr\t%w0, %w0, %w2\n"
|
|
|
|
"\tstrb\t%w0, [%1]"
|
|
|
|
: "=&r"(data)
|
|
|
|
: "r"(addr), "r"(set), "r"(clear));
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These functions are guaranteed to copy by reading from src and writing to dst
|
|
|
|
* in <n>-bit units If size is not aligned, the remaining bytes are not copied
|
|
|
|
*/
|
2021-01-14 09:18:07 +00:00
|
|
|
void memset64(void *dst, u64 value, size_t size);
|
|
|
|
void memcpy64(void *dst, void *src, size_t size);
|
|
|
|
void memset32(void *dst, u32 value, size_t size);
|
|
|
|
void memcpy32(void *dst, void *src, size_t size);
|
|
|
|
void memset16(void *dst, u16 value, size_t size);
|
|
|
|
void memcpy16(void *dst, void *src, size_t size);
|
|
|
|
void memset8(void *dst, u8 value, size_t size);
|
|
|
|
void memcpy8(void *dst, void *src, size_t size);
|
|
|
|
|
|
|
|
void hexdump(const void *d, size_t len);
|
2021-01-12 18:22:11 +00:00
|
|
|
void regdump(u64 addr, int len);
|
|
|
|
int sprintf(char *str, const char *fmt, ...);
|
|
|
|
int debug_printf(const char *fmt, ...);
|
|
|
|
void udelay(u32 d);
|
|
|
|
|
|
|
|
#endif
|