diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h index d2ead4736..c9667450f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/core.h @@ -73,7 +73,7 @@ Modification: #include "cortex_a55.h" -#define NR_CPU 1 // maximum number of CPUs +#define NR_CPU 4 // maximum number of CPUs __attribute__((always_inline)) static inline uint64_t EL0_mode() // Set ARM mode to EL0 { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/Makefile index 708c59ae5..6ae1c0359 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/Makefile @@ -1,5 +1,6 @@ SRC_FILES := boot.S \ smp.c \ + smccc-call.S \ cortexA55.S include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smccc-call.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smccc-call.S new file mode 100644 index 000000000..467508dca --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smccc-call.S @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, Linaro Limited + * + * SPDX-License-Identifier: GPL-2.0 + */ +.global __arm_smccc_smc + .macro SMCCC instr + .cfi_startproc + \instr #0 + ldr x4, [sp] + stp x0, x1, [x4, #0] + stp x2, x3, [x4, #16] + ldr x4, [sp, #8] + cbz x4, 1f /* no quirk structure */ + ldr x9, [x4, #0] + cmp x9, #1 + b.ne 1f + str x6, [x4, 8] +1: ret + .cfi_endproc + .endm + +/* + * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + * unsigned long a3, unsigned long a4, unsigned long a5, + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, + * struct arm_smccc_quirk *quirk) + */ + .func __arm_smccc_smc +__arm_smccc_smc: + SMCCC smc + .endfunc + \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smp.c b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smp.c index c1e84b58c..c26a4235c 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smp.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/arm/armv8-a/cortex-a55/preboot_for_3568/smp.c @@ -48,14 +48,42 @@ Modification: #include #define PSCI_CPUON 0xc4000003 +struct arm_smccc_res { + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; +}; extern void _boot_start(); -void psci_call(uint64_t fn, uint8_t cpuid, uint64_t entry, uint64_t ctxid); +extern void __print(); +extern void __arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, unsigned long a5, + unsigned long a6, unsigned long a7, struct arm_smccc_res *res); + +static struct arm_smccc_res __invoke_sip_fn_smc(unsigned long function_id, + unsigned long arg0, + unsigned long arg1, + unsigned long arg2) +{ + struct arm_smccc_res res; + + __arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res); + return res; +} void cpu_start_secondary(uint8_t cpu_id) { - psci_call(PSCI_CPUON, cpu_id, (uintptr_t)&_boot_start, 0); + //psci_call(PSCI_CPUON, cpu_id, (uintptr_t)&_boot_start, 0); + __invoke_sip_fn_smc(PSCI_CPUON, cpu_id, (uintptr_t)__print, 0); } + +//void psci_call(uint64_t fn, uint8_t cpuid, uint64_t entry, uint64_t ctxid); +// int psci_cpu_on(unsigned long cpuid, unsigned long entry_point) +// { +// __invoke_sip_fn_smc(PSCI_CPUON, cpuid, entry_point, 0); +// } + void start_smp_cache_broadcast(int cpu_id) { return; diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c index e2b9e8465..8b19d959f 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/cache/cache_common_ope.c @@ -92,7 +92,7 @@ static inline void invalidate_icache(uintptr_t start, uintptr_t end) static inline void invalidate_icache_all(void) { - InvalidateL1IcacheAll(); + // InvalidateL1IcacheAll(); } /**************************************************************************** @@ -151,7 +151,7 @@ static inline void flush_dcache(uintptr_t start, uintptr_t end) static inline void flush_dcache_all(void) { - FlushL1DcacheAll(); + // FlushL1DcacheAll(); // FlushL2CacheAll(); } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/bootmmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/bootmmu.c index 4101d2c32..4bafd4307 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/bootmmu.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv8-a/cortex-a55/bootmmu.c @@ -166,6 +166,88 @@ static inline unsigned int current_el(void) asm volatile("mrs %0, CurrentEL" : "=r"(el) : : "cc"); return el >> 2; } +#include "ns16550.h" +#define UART_LCRVAL UART_LCR_8N1 /* 8 data, 1 stop, no parity */ +#define UART_MCRVAL (UART_MCR_DTR | UART_MCR_RTS) /* RTS/DTR */ + +#define out_le32(a, v) (*(volatile uint32_t*)(a) = (v)) +#define in_le32(a) (*(volatile uint32_t*)(a)) + +#ifndef CONFIG_SYS_NS16550_IER +#define CONFIG_SYS_NS16550_IER 0x00 +#endif /* CONFIG_SYS_NS16550_IER */ + +#define serial_dout(reg, value) \ + serial_out_shift((char*)com_port + ((char*)reg - (char*)com_port) * (1 << 2), \ + 2, value) +#define serial_din(reg) \ + serial_in_shift((char*)com_port + ((char*)reg - (char*)com_port) * (1 << 2), \ + 2) + +#define DIV_ROUND_CLOSEST(x, divisor) ( \ + { \ + typeof(x) __x = x; \ + typeof(divisor) __d = divisor; \ + (((typeof(x))-1) > 0 || ((typeof(divisor))-1) > 0 || (__x) > 0) ? (((__x) + ((__d) / 2)) / (__d)) : (((__x) - ((__d) / 2)) / (__d)); \ + }) + +int _ns16550_calc_divisor(NS16550_t port, int clock, int baudrate) +{ + const unsigned int mode_x_div = 16; + + return DIV_ROUND_CLOSEST(clock, mode_x_div * baudrate); +} +static inline void serial_out_shift(void* addr, int shift, int value) +{ + out_le32(addr, value); +} + +static inline int serial_in_shift(void* addr, int shift) +{ + return in_le32(addr); +} + +void __debug_uart_init(void) +{ + struct NS16550* com_port = (struct NS16550*)0xFE660000ULL; + + /* + * We copy the code from above because it is already horribly messy. + * Trying to refactor to nicely remove the duplication doesn't seem + * feasible. The better fix is to move all users of this driver to + * driver model. + */ + int baud_divisor = _ns16550_calc_divisor(com_port, 24000000, + 1500000); + serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER); + serial_dout(&com_port->mcr, UART_MCRVAL); + serial_dout(&com_port->fcr, UART_FCR_DEFVAL); + + serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL); + serial_dout(&com_port->dll, baud_divisor & 0xff); + serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff); + serial_dout(&com_port->lcr, UART_LCRVAL); +} + +void __debug_uart_putc(int ch) +{ + static struct NS16550* com_port = (struct NS16550*)0xFE660000ULL; + + if (ch == '\n') { + _debug_uart_putc('\r'); + } + + while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) + ; + serial_dout(&com_port->thr, ch); +} + +void __print(){ + __debug_uart_init(); + for(int i = 0; i < 10; i++){ + __debug_uart_putc((int)'+'); + } +} extern void main(void); static bool _bss_inited = false;