Files
thead-uboot/arch/riscv/cpu/c9xx/cpu.c
2024-01-31 16:19:17 +08:00

153 lines
3.3 KiB
C

/*
* Copyright (C) 2017-2020 Alibaba Group Holding Limited
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/types.h>
#include <asm/asm.h>
#include <asm/csr.h>
#include <common.h>
#include <cpu_func.h>
#include <fdt_support.h>
#ifdef CONFIG_TARGET_ICE_C910
static phys_addr_t opensbi_addr, dtb_addr;
void (*image_entry)(u32, phys_addr_t);
extern bootm_headers_t images;
static inline void boot_core_vector(void)
{
/* Set pmp regs */
csr_write(pmpaddr0, 0x0 >> 2 | ((0x100000000 - 1) >> 3));
csr_write(pmpaddr1, 0x3f0000000 >> 2 | ((0x10000000 - 1) >> 3));
csr_write(pmpaddr6, 0x00000000 >> 2 | ((0x10000000 - 1) >> 3));
csr_write(pmpaddr7, 0xffffffffff >> 2);
csr_write(pmpcfg0, 0x8898000000001b1f);
/* Set cpu regs */
csr_write(CSR_MCOR, 0x70013);
csr_write(CSR_MCCR2, 0xe0410009);
csr_write(CSR_MHCR, 0x11ff);
csr_write(CSR_MXSTATUS, 0x638000);
csr_write(CSR_MHINT, 0x16e30c);
image_entry(0xdeadbeef, dtb_addr);
}
static void set_vector_cpu(void)
{
int node, cpu;
const void *blob = (const void *)dtb_addr;
node = fdt_path_offset(blob, "/cpus");
if (node < 0)
return;
for (cpu = fdt_first_subnode(blob, node);
cpu >= 0; cpu = fdt_next_subnode(blob, cpu)) {
if (!strcmp("okay", fdt_getprop(blob, cpu, "status", NULL)))
fdt_status_fail((void *)blob, cpu);
else if (!strcmp("fail", fdt_getprop(blob, cpu, "status", NULL)))
fdt_status_okay((void *)blob, cpu);
}
}
static void prep_core_vector(void)
{
printf("Boot vector core(cpu2) only\n");
dtb_addr = (phys_addr_t)images.ft_addr;
opensbi_addr = simple_strtol(env_get("opensbi_addr"), NULL, 0);
image_entry = (void (*)(u32, phys_addr_t))(opensbi_addr);
set_vector_cpu();
csr_write(mrvbr, &boot_core_vector);
csr_write(mrmr, 0x5);
while (1);
}
#endif
/*
* cleanup_before_linux() is called just before we call linux
* it prepares the processor for linux
*
* we disable interrupt and caches.
*/
int cleanup_before_linux(void)
{
cache_flush();
#ifdef CONFIG_TARGET_ICE_C910
if ((simple_strtol(env_get("boot_vector"), NULL, 0)) == 1)
prep_core_vector();
#endif
return 0;
}
void flush_dcache_range(unsigned long start, unsigned long end)
{
register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
asm volatile(".long 0x0295000b"); /* dcache.cpa a0 */
sync_is();
}
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
asm volatile(".long 0x02b5000b"); /* dcache.cipa a0 */
sync_is();
}
void invalid_dcache_range(unsigned long start, unsigned long end)
{
register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
asm volatile(".long 0x02a5000b"); /* dcache.ipa a0 */
sync_is();
}
void icache_enable(void)
{
#ifdef CONFIG_SPL_BUILD
#ifdef CONFIG_SPL_RISCV_MMODE
#ifdef CONFIG_TARGET_LIGHT_C910
// mhcr is 0x7c1
asm volatile (
"csrr x29, 0x7c1\n\t"
"ori x28, x29, 0x1\n\t"
"csrw 0x7c1, x28\n\t"
);
#endif
#endif
#endif
}
void dcache_enable(void)
{
#ifdef CONFIG_SPL_BUILD
#ifdef CONFIG_SPL_RISCV_MMODE
#ifdef CONFIG_TARGET_LIGHT_C910
asm volatile (
"csrr x29, 0x7c1\n\t"
"ori x28, x29, 0x2\n\t"
"csrw 0x7c1, x28\n\t"
);
#endif
#endif
#endif
}