mirror of
https://github.com/revyos/th1520-vendor-uboot.git
synced 2026-06-21 09:02:25 +02:00
153 lines
3.3 KiB
C
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
|
|
}
|