- Skip unavailable hart in the get_count().
- fu540 set serial env from otp.
- fu540 add mmc0 as a boot target device.
- Update fix_rela_dyn and add absolute reloc addend.
- Andestech PLIC driver will skip unavailable hart.
- Support Andestech V5L2 cache driver.
This commit is contained in:
Tom Rini 2019-09-02 23:21:44 -04:00
commit 83a5df4261
18 changed files with 378 additions and 42 deletions

View file

@ -6,6 +6,7 @@ config RISCV_NDS
imply RISCV_TIMER imply RISCV_TIMER
imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE) imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE)
imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE) imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE)
imply V5L2_CACHE
help help
Run U-Boot on AndeStar V5 platforms and use some specific features Run U-Boot on AndeStar V5 platforms and use some specific features
which are provided by Andes Technology AndeStar V5 families. which are provided by Andes Technology AndeStar V5 families.

View file

@ -5,17 +5,24 @@
*/ */
#include <common.h> #include <common.h>
#include <dm.h>
#include <dm/uclass-internal.h>
#include <cache.h>
#include <asm/csr.h>
#ifdef CONFIG_RISCV_NDS_CACHE
/* mcctlcommand */
#define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc
/* D-cache operation */
#define CCTL_L1D_WBINVAL_ALL 6
#endif
void flush_dcache_all(void) void flush_dcache_all(void)
{ {
/* #ifdef CONFIG_RISCV_NDS_CACHE
* Andes' AX25 does not have a coherence agent. U-Boot must use data csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
* cache flush and invalidate functions to keep data in the system #endif
* coherent.
* The implementation of the fence instruction in the AX25 flushes the
* data cache and is used for this purpose.
*/
asm volatile ("fence" ::: "memory");
} }
void flush_dcache_range(unsigned long start, unsigned long end) void flush_dcache_range(unsigned long start, unsigned long end)
@ -59,11 +66,18 @@ void dcache_enable(void)
{ {
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE #ifdef CONFIG_RISCV_NDS_CACHE
struct udevice *dev = NULL;
asm volatile ( asm volatile (
"csrr t1, mcache_ctl\n\t" "csrr t1, mcache_ctl\n\t"
"ori t0, t1, 0x2\n\t" "ori t0, t1, 0x2\n\t"
"csrw mcache_ctl, t0\n\t" "csrw mcache_ctl, t0\n\t"
); );
uclass_find_first_device(UCLASS_CACHE, &dev);
if (dev)
cache_enable(dev);
#endif #endif
#endif #endif
} }
@ -72,12 +86,19 @@ void dcache_disable(void)
{ {
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#ifdef CONFIG_RISCV_NDS_CACHE #ifdef CONFIG_RISCV_NDS_CACHE
struct udevice *dev = NULL;
csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL);
asm volatile ( asm volatile (
"fence\n\t"
"csrr t1, mcache_ctl\n\t" "csrr t1, mcache_ctl\n\t"
"andi t0, t1, ~0x2\n\t" "andi t0, t1, ~0x2\n\t"
"csrw mcache_ctl, t0\n\t" "csrw mcache_ctl, t0\n\t"
); );
uclass_find_first_device(UCLASS_CACHE, &dev);
if (dev)
cache_disable(dev);
#endif #endif
#endif #endif
} }

View file

@ -269,7 +269,7 @@ fix_rela_dyn:
/* /*
* skip first reserved entry: address, type, addend * skip first reserved entry: address, type, addend
*/ */
bne t1, t2, 7f j 10f
6: 6:
LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */
@ -280,9 +280,7 @@ fix_rela_dyn:
add t5, t5, t6 /* t5 <-- location to fix up in RAM */ add t5, t5, t6 /* t5 <-- location to fix up in RAM */
add t3, t3, t6 /* t3 <-- location to fix up in RAM */ add t3, t3, t6 /* t3 <-- location to fix up in RAM */
SREG t5, 0(t3) SREG t5, 0(t3)
7: j 10f
addi t1, t1, (REGBYTES*3)
ble t1, t2, 6b
8: 8:
la t4, __dyn_sym_start la t4, __dyn_sym_start
@ -299,13 +297,15 @@ fix_rela_dyn:
li t5, SYM_SIZE li t5, SYM_SIZE
mul t0, t0, t5 mul t0, t0, t5
add s5, t4, t0 add s5, t4, t0
LREG t0, -(REGBYTES)(t1) /* t0 <-- addend */
LREG t5, REGBYTES(s5) LREG t5, REGBYTES(s5)
add t5, t5, t0
add t5, t5, t6 /* t5 <-- location to fix up in RAM */ add t5, t5, t6 /* t5 <-- location to fix up in RAM */
add t3, t3, t6 /* t3 <-- location to fix up in RAM */ add t3, t3, t6 /* t3 <-- location to fix up in RAM */
SREG t5, 0(t3) SREG t5, 0(t3)
10: 10:
addi t1, t1, (REGBYTES*3) addi t1, t1, (REGBYTES*3)
ble t1, t2, 9b ble t1, t2, 6b
/* /*
* trap update * trap update

View file

@ -62,13 +62,18 @@
compatible = "riscv,cpu-intc"; compatible = "riscv,cpu-intc";
}; };
}; };
};
L2: l2-cache@e0500000 { L2: l2-cache@e0500000 {
compatible = "cache"; compatible = "v5l2cache";
cache-level = <2>; cache-level = <2>;
cache-size = <0x40000>; cache-size = <0x40000>;
reg = <0x0 0xe0500000 0x0 0x40000>; reg = <0xe0500000 0x40000>;
}; andes,inst-prefetch = <3>;
andes,data-prefetch = <3>;
/* The value format is <XRAMOCTL XRAMICTL> */
andes,tag-ram-ctl = <0 0>;
andes,data-ram-ctl = <0 0>;
}; };
memory@0 { memory@0 {

View file

@ -62,13 +62,18 @@
compatible = "riscv,cpu-intc"; compatible = "riscv,cpu-intc";
}; };
}; };
};
L2: l2-cache@e0500000 { L2: l2-cache@e0500000 {
compatible = "cache"; compatible = "v5l2cache";
cache-level = <2>; cache-level = <2>;
cache-size = <0x40000>; cache-size = <0x40000>;
reg = <0x0 0xe0500000 0x0 0x40000>; reg = <0x0 0xe0500000 0x0 0x40000>;
}; andes,inst-prefetch = <3>;
andes,data-prefetch = <3>;
/* The value format is <XRAMOCTL XRAMICTL> */
andes,tag-ram-ctl = <0 0>;
andes,data-ram-ctl = <0 0>;
}; };
memory@0 { memory@0 {

View file

@ -44,15 +44,12 @@ static int init_plic(void);
} \ } \
} while (0) } while (0)
static int enable_ipi(int harts) static int enable_ipi(int hart)
{ {
int i; int en;
int en = ENABLE_HART_IPI;
for (i = 0; i < harts; i++) { en = ENABLE_HART_IPI >> hart;
en = en >> i; writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, hart));
writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, i));
}
return 0; return 0;
} }
@ -60,18 +57,35 @@ static int enable_ipi(int harts)
static int init_plic(void) static int init_plic(void)
{ {
struct udevice *dev; struct udevice *dev;
ofnode node;
int ret; int ret;
u32 reg;
ret = uclass_find_first_device(UCLASS_CPU, &dev); ret = uclass_find_first_device(UCLASS_CPU, &dev);
if (ret) if (ret)
return ret; return ret;
if (ret == 0 && dev) { if (ret == 0 && dev) {
ret = cpu_get_count(dev); ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
if (ret < 0) const char *device_type;
return ret;
device_type = ofnode_read_string(node, "device_type");
if (!device_type)
continue;
if (strcmp(device_type, "cpu"))
continue;
/* skip if hart is marked as not available */
if (!ofnode_is_available(node))
continue;
/* read hart ID of CPU */
ret = ofnode_read_u32(node, "reg", &reg);
if (ret == 0)
enable_ipi(reg);
}
enable_ipi(ret);
return 0; return 0;
} }

View file

@ -11,6 +11,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <faraday/ftsmc020.h> #include <faraday/ftsmc020.h>
#include <fdtdec.h> #include <fdtdec.h>
#include <dm.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -93,10 +94,18 @@ int smc_init(void)
return 0; return 0;
} }
static void v5l2_init(void)
{
struct udevice *dev;
uclass_get_device(UCLASS_CACHE, 0, &dev);
}
#ifdef CONFIG_BOARD_EARLY_INIT_F #ifdef CONFIG_BOARD_EARLY_INIT_F
int board_early_init_f(void) int board_early_init_f(void)
{ {
smc_init(); smc_init();
v5l2_init();
return 0; return 0;
} }

View file

@ -122,10 +122,20 @@ static void fu540_setup_macaddr(u32 serialnum)
int misc_init_r(void) int misc_init_r(void)
{ {
/* Set ethaddr environment variable if not set */ u32 serial_num;
if (!env_get("ethaddr")) char buf[9] = {0};
fu540_setup_macaddr(fu540_read_serialnum());
/* Set ethaddr environment variable from board serial number */
if (!env_get("serial#")) {
serial_num = fu540_read_serialnum();
if (!serial_num) {
WARN(true, "Board serial number should not be 0 !!\n");
return 0;
}
snprintf(buf, sizeof(buf), "%08x", serial_num);
env_set("serial#", buf);
fu540_setup_macaddr(serial_num);
}
return 0; return 0;
} }

View file

@ -22,4 +22,13 @@ config L2X0_CACHE
ARMv7(32-bit) devices. The driver configures the cache settings ARMv7(32-bit) devices. The driver configures the cache settings
found in the device tree. found in the device tree.
config V5L2_CACHE
bool "Andes V5L2 cache driver"
select CACHE
depends on RISCV_NDS_CACHE
help
Support Andes V5L2 cache controller in AE350 platform.
It will configure tag and data ram timing control from the
device tree and enable L2 cache.
endmenu endmenu

View file

@ -2,3 +2,4 @@
obj-$(CONFIG_CACHE) += cache-uclass.o obj-$(CONFIG_CACHE) += cache-uclass.o
obj-$(CONFIG_SANDBOX) += sandbox_cache.o obj-$(CONFIG_SANDBOX) += sandbox_cache.o
obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o
obj-$(CONFIG_V5L2_CACHE) += cache-v5l2.o

View file

@ -17,6 +17,26 @@ int cache_get_info(struct udevice *dev, struct cache_info *info)
return ops->get_info(dev, info); return ops->get_info(dev, info);
} }
int cache_enable(struct udevice *dev)
{
struct cache_ops *ops = cache_get_ops(dev);
if (!ops->enable)
return -ENOSYS;
return ops->enable(dev);
}
int cache_disable(struct udevice *dev)
{
struct cache_ops *ops = cache_get_ops(dev);
if (!ops->disable)
return -ENOSYS;
return ops->disable(dev);
}
UCLASS_DRIVER(cache) = { UCLASS_DRIVER(cache) = {
.id = UCLASS_CACHE, .id = UCLASS_CACHE,
.name = "cache", .name = "cache",

186
drivers/cache/cache-v5l2.c vendored Normal file
View file

@ -0,0 +1,186 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Andes Technology Corporation
* Rick Chen, Andes Technology Corporation <rick@andestech.com>
*/
#include <common.h>
#include <command.h>
#include <cache.h>
#include <dm.h>
#include <asm/io.h>
#include <dm/ofnode.h>
struct l2cache {
volatile u64 configure;
volatile u64 control;
volatile u64 hpm0;
volatile u64 hpm1;
volatile u64 hpm2;
volatile u64 hpm3;
volatile u64 error_status;
volatile u64 ecc_error;
volatile u64 cctl_command0;
volatile u64 cctl_access_line0;
volatile u64 cctl_command1;
volatile u64 cctl_access_line1;
volatile u64 cctl_command2;
volatile u64 cctl_access_line2;
volatile u64 cctl_command3;
volatile u64 cctl_access_line4;
volatile u64 cctl_status;
};
/* Control Register */
#define L2_ENABLE 0x1
/* prefetch */
#define IPREPETCH_OFF 3
#define DPREPETCH_OFF 5
#define IPREPETCH_MSK (3 << IPREPETCH_OFF)
#define DPREPETCH_MSK (3 << DPREPETCH_OFF)
/* tag ram */
#define TRAMOCTL_OFF 8
#define TRAMICTL_OFF 10
#define TRAMOCTL_MSK (3 << TRAMOCTL_OFF)
#define TRAMICTL_MSK BIT(TRAMICTL_OFF)
/* data ram */
#define DRAMOCTL_OFF 11
#define DRAMICTL_OFF 13
#define DRAMOCTL_MSK (3 << DRAMOCTL_OFF)
#define DRAMICTL_MSK BIT(DRAMICTL_OFF)
/* CCTL Command Register */
#define CCTL_CMD_REG(base, hart) ((ulong)(base) + 0x40 + (hart) * 0x10)
#define L2_WBINVAL_ALL 0x12
/* CCTL Status Register */
#define CCTL_STATUS_MSK(hart) (0xf << ((hart) * 4))
#define CCTL_STATUS_IDLE(hart) (0 << ((hart) * 4))
#define CCTL_STATUS_PROCESS(hart) (1 << ((hart) * 4))
#define CCTL_STATUS_ILLEGAL(hart) (2 << ((hart) * 4))
DECLARE_GLOBAL_DATA_PTR;
struct v5l2_plat {
struct l2cache *regs;
u32 iprefetch;
u32 dprefetch;
u32 tram_ctl[2];
u32 dram_ctl[2];
};
static int v5l2_enable(struct udevice *dev)
{
struct v5l2_plat *plat = dev_get_platdata(dev);
volatile struct l2cache *regs = plat->regs;
if (regs)
setbits_le32(&regs->control, L2_ENABLE);
return 0;
}
static int v5l2_disable(struct udevice *dev)
{
struct v5l2_plat *plat = dev_get_platdata(dev);
volatile struct l2cache *regs = plat->regs;
u8 hart = gd->arch.boot_hart;
void __iomem *cctlcmd = (void __iomem *)CCTL_CMD_REG(regs, hart);
if ((regs) && (readl(&regs->control) & L2_ENABLE)) {
writel(L2_WBINVAL_ALL, cctlcmd);
while ((readl(&regs->cctl_status) & CCTL_STATUS_MSK(hart))) {
if ((readl(&regs->cctl_status) & CCTL_STATUS_ILLEGAL(hart))) {
printf("L2 flush illegal! hanging...");
hang();
}
}
clrbits_le32(&regs->control, L2_ENABLE);
}
return 0;
}
static int v5l2_ofdata_to_platdata(struct udevice *dev)
{
struct v5l2_plat *plat = dev_get_platdata(dev);
struct l2cache *regs;
regs = (struct l2cache *)dev_read_addr(dev);
plat->regs = regs;
plat->iprefetch = -EINVAL;
plat->dprefetch = -EINVAL;
plat->tram_ctl[0] = -EINVAL;
plat->dram_ctl[0] = -EINVAL;
/* Instruction and data fetch prefetch depth */
dev_read_u32(dev, "andes,inst-prefetch", &plat->iprefetch);
dev_read_u32(dev, "andes,data-prefetch", &plat->dprefetch);
/* Set tag RAM and data RAM setup and output cycle */
dev_read_u32_array(dev, "andes,tag-ram-ctl", plat->tram_ctl, 2);
dev_read_u32_array(dev, "andes,data-ram-ctl", plat->dram_ctl, 2);
return 0;
}
static int v5l2_probe(struct udevice *dev)
{
struct v5l2_plat *plat = dev_get_platdata(dev);
struct l2cache *regs = plat->regs;
u32 ctl_val;
ctl_val = readl(&regs->control);
if (!(ctl_val & L2_ENABLE))
ctl_val |= L2_ENABLE;
if (plat->iprefetch != -EINVAL) {
ctl_val &= ~(IPREPETCH_MSK);
ctl_val |= (plat->iprefetch << IPREPETCH_OFF);
}
if (plat->dprefetch != -EINVAL) {
ctl_val &= ~(DPREPETCH_MSK);
ctl_val |= (plat->dprefetch << DPREPETCH_OFF);
}
if (plat->tram_ctl[0] != -EINVAL) {
ctl_val &= ~(TRAMOCTL_MSK | TRAMICTL_MSK);
ctl_val |= plat->tram_ctl[0] << TRAMOCTL_OFF;
ctl_val |= plat->tram_ctl[1] << TRAMICTL_OFF;
}
if (plat->dram_ctl[0] != -EINVAL) {
ctl_val &= ~(DRAMOCTL_MSK | DRAMICTL_MSK);
ctl_val |= plat->dram_ctl[0] << DRAMOCTL_OFF;
ctl_val |= plat->dram_ctl[1] << DRAMICTL_OFF;
}
writel(ctl_val, &regs->control);
return 0;
}
static const struct udevice_id v5l2_cache_ids[] = {
{ .compatible = "v5l2cache" },
{}
};
static const struct cache_ops v5l2_cache_ops = {
.enable = v5l2_enable,
.disable = v5l2_disable,
};
U_BOOT_DRIVER(v5l2_cache) = {
.name = "v5l2_cache",
.id = UCLASS_CACHE,
.of_match = v5l2_cache_ids,
.ofdata_to_platdata = v5l2_ofdata_to_platdata,
.probe = v5l2_probe,
.platdata_auto_alloc_size = sizeof(struct v5l2_plat),
.ops = &v5l2_cache_ops,
.flags = DM_FLAG_PRE_RELOC,
};

View file

@ -17,8 +17,21 @@ static int sandbox_get_info(struct udevice *dev, struct cache_info *info)
return 0; return 0;
} }
static int sandbox_enable(struct udevice *dev)
{
return 0;
}
static int snadbox_disable(struct udevice *dev)
{
return 0;
}
static const struct cache_ops sandbox_cache_ops = { static const struct cache_ops sandbox_cache_ops = {
.get_info = sandbox_get_info, .get_info = sandbox_get_info,
.enable = sandbox_enable,
.disable = snadbox_disable,
}; };
static const struct udevice_id sandbox_cache_ids[] = { static const struct udevice_id sandbox_cache_ids[] = {

View file

@ -46,6 +46,10 @@ static int riscv_cpu_get_count(struct udevice *dev)
ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
const char *device_type; const char *device_type;
/* skip if hart is marked as not available in the device tree */
if (!ofnode_is_available(node))
continue;
device_type = ofnode_read_string(node, "device_type"); device_type = ofnode_read_string(node, "device_type");
if (!device_type) if (!device_type)
continue; continue;

View file

@ -22,6 +22,22 @@ struct cache_ops {
* @return 0 if OK, -ve on error * @return 0 if OK, -ve on error
*/ */
int (*get_info)(struct udevice *dev, struct cache_info *info); int (*get_info)(struct udevice *dev, struct cache_info *info);
/**
* enable() - Enable cache
*
* @dev: Device to check (UCLASS_CACHE)
* @return 0 if OK, -ve on error
*/
int (*enable)(struct udevice *dev);
/**
* disable() - Flush and disable cache
*
* @dev: Device to check (UCLASS_CACHE)
* @return 0 if OK, -ve on error
*/
int (*disable)(struct udevice *dev);
}; };
#define cache_get_ops(dev) ((struct cache_ops *)(dev)->driver->ops) #define cache_get_ops(dev) ((struct cache_ops *)(dev)->driver->ops)
@ -35,4 +51,19 @@ struct cache_ops {
*/ */
int cache_get_info(struct udevice *dev, struct cache_info *info); int cache_get_info(struct udevice *dev, struct cache_info *info);
/**
* cache_enable() - Enable cache
*
* @dev: Device to check (UCLASS_CACHE)
* @return 0 if OK, -ve on error
*/
int cache_enable(struct udevice *dev);
/**
* cache_disable() - Flush and disable cache
*
* @dev: Device to check (UCLASS_CACHE)
* @return 0 if OK, -ve on error
*/
int cache_disable(struct udevice *dev);
#endif #endif

View file

@ -26,6 +26,7 @@
#define CONFIG_ENV_SIZE SZ_128K #define CONFIG_ENV_SIZE SZ_128K
#define BOOT_TARGET_DEVICES(func) \ #define BOOT_TARGET_DEVICES(func) \
func(MMC, mmc, 0) \
func(DHCP, dhcp, na) func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h> #include <config_distro_bootcmd.h>

View file

@ -14,6 +14,8 @@ static int dm_test_reset(struct unit_test_state *uts)
ut_assertok(uclass_get_device(UCLASS_CACHE, 0, &dev_cache)); ut_assertok(uclass_get_device(UCLASS_CACHE, 0, &dev_cache));
ut_assertok(cache_get_info(dev, &info)); ut_assertok(cache_get_info(dev, &info));
ut_assertok(cache_enable(dev));
ut_assertok(cache_disable(dev));
return 0; return 0;
} }

View file

@ -27,6 +27,8 @@
#define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu) #define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu)
#define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu) #define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu)
#define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu) #define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu)
#define cpu_to_target32 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 32)
#define cpu_to_target64 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 64)
static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr) static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
{ {
@ -92,9 +94,9 @@ static void prelink_bonn(void *data)
if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE) if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
*((uintnn_t*) buf) = r->r_addend; *((uintnn_t*) buf) = r->r_addend;
else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32) else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32)
*((uint32_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value; *((uint32_t*) buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend));
else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64) else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64)
*((uint64_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value; *((uint64_t*) buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend));
} }
} }
@ -113,6 +115,8 @@ static void prelink_bonn(void *data)
#undef target32_to_cpu #undef target32_to_cpu
#undef target64_to_cpu #undef target64_to_cpu
#undef targetnn_to_cpu #undef targetnn_to_cpu
#undef cpu_to_target32
#undef cpu_to_target64
#undef CONCAT_IMPL #undef CONCAT_IMPL
#undef CONCAT #undef CONCAT