From 2d987b06e5315f7038c5e78bcea04af4a6903baa Mon Sep 17 00:00:00 2001 From: YuzukiTsuru Date: Sat, 30 Dec 2023 12:02:34 +0800 Subject: [PATCH] [board] add longanpi 4B T527 platform --- board/longanpi-4b/CMakeLists.txt | 18 ++ board/longanpi-4b/README.md | 29 +++ board/longanpi-4b/board.c | 99 +++++++++ board/longanpi-4b/eabi_compat.c | 14 ++ board/longanpi-4b/hello_world/CMakeLists.txt | 5 + board/longanpi-4b/hello_world/main.c | 30 +++ board/longanpi-4b/start.S | 218 +++++++++++++++++++ cmake/board/longanpi-4b.cmake | 56 +++++ 8 files changed, 469 insertions(+) create mode 100644 board/longanpi-4b/CMakeLists.txt create mode 100644 board/longanpi-4b/README.md create mode 100644 board/longanpi-4b/board.c create mode 100644 board/longanpi-4b/eabi_compat.c create mode 100644 board/longanpi-4b/hello_world/CMakeLists.txt create mode 100644 board/longanpi-4b/hello_world/main.c create mode 100644 board/longanpi-4b/start.S create mode 100644 cmake/board/longanpi-4b.cmake diff --git a/board/longanpi-4b/CMakeLists.txt b/board/longanpi-4b/CMakeLists.txt new file mode 100644 index 00000000..c97801b8 --- /dev/null +++ b/board/longanpi-4b/CMakeLists.txt @@ -0,0 +1,18 @@ +set(APP_COMMON_SOURCE + ${CMAKE_CURRENT_SOURCE_DIR}/start.S + ${CMAKE_CURRENT_SOURCE_DIR}/board.c + ${CMAKE_CURRENT_SOURCE_DIR}/eabi_compat.c + ${CMAKE_CURRENT_SOURCE_DIR}/payloads/init_dram_bin.c +) + +add_subdirectory(hello_world) + +add_subdirectory(init_dram) + +add_subdirectory(cli_test) + +add_subdirectory(arm64_test) + +add_subdirectory(smhc_test) + +add_subdirectory(syter_boot) \ No newline at end of file diff --git a/board/longanpi-4b/README.md b/board/longanpi-4b/README.md new file mode 100644 index 00000000..fc121158 --- /dev/null +++ b/board/longanpi-4b/README.md @@ -0,0 +1,29 @@ +# SyterKit Common + +## start.S + +This code snippet is an ARM assembly language program that includes initialization settings and exception handlers. Here's a breakdown of its functionalities: + +1. Initialization Settings: It sets registers and writes specific values to configure the processor's working mode, interrupt enable, etc. + +2. Set Vector Table: It writes the address of the vector table to the Vector Base Address Register, which is used for handling exceptions and interrupts. + +3. Enable NEON/VFP Unit: It configures the processor to enable the NEON (Advanced SIMD) and VFP (Floating-Point) units. + +4. Clear BSS Section: It zeroes out variables in the BSS section. + +5. Disable Interrupts: It disables FIQ and IRQ interrupts and switches the processor to SVC32 mode. + +6. Set Timer Frequency: It sets the timer frequency to 24M. + +7. Call the main Function: It jumps to the main function to execute the main logic. + +## eabi_compat.c + +This code snippet appears to be providing implementations for the functions `abort`, `raise`, and `__aeabi_unwind_cpp_pr0`. Here's a breakdown of their functionalities: + +1. `void abort(void)`: This function creates an infinite loop, causing the program to hang indefinitely. It is typically used to indicate a critical error or unrecoverable condition in a program. + +2. `int raise(int signum)`: This function is a placeholder and always returns 0. In standard C, this function is used to raise a signal and initiate the corresponding signal handler. However, in this implementation, it does nothing and simply returns 0. + +3. `void __aeabi_unwind_cpp_pr0(void)`: This is a dummy function that serves as a placeholder to avoid linker complaints. Its purpose is to satisfy the linker when using C++ exceptions and unwinding, but it does not contain any actual functionality. diff --git a/board/longanpi-4b/board.c b/board/longanpi-4b/board.c new file mode 100644 index 00000000..ff61fd8d --- /dev/null +++ b/board/longanpi-4b/board.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +#include + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +sunxi_serial_t uart_dbg = { + .base = SUNXI_UART0_BASE, + .id = 0, + .gpio_tx = {GPIO_PIN(GPIO_PORTH, 0), GPIO_PERIPH_MUX2}, + .gpio_rx = {GPIO_PIN(GPIO_PORTH, 1), GPIO_PERIPH_MUX2}, +}; + +sunxi_spi_t sunxi_spi0 = { + .base = SUNXI_SPI0_BASE, + .id = 0, + .clk_rate = 75 * 1000 * 1000, + .gpio_cs = {GPIO_PIN(GPIO_PORTC, 1), GPIO_PERIPH_MUX4}, + .gpio_sck = {GPIO_PIN(GPIO_PORTC, 0), GPIO_PERIPH_MUX4}, + .gpio_mosi = {GPIO_PIN(GPIO_PORTC, 2), GPIO_PERIPH_MUX4}, + .gpio_miso = {GPIO_PIN(GPIO_PORTC, 3), GPIO_PERIPH_MUX4}, + .gpio_wp = {GPIO_PIN(GPIO_PORTC, 4), GPIO_PERIPH_MUX4}, + .gpio_hold = {GPIO_PIN(GPIO_PORTC, 5), GPIO_PERIPH_MUX4}, +}; + +sdhci_t sdhci0 = { + .name = "sdhci0", + .reg = (sdhci_reg_t *) SUNXI_SMHC0_BASE, + .voltage = MMC_VDD_27_36, + .width = MMC_BUS_WIDTH_4, + .clock = MMC_CLK_50M, + .removable = 0, + .isspi = FALSE, + .gpio_clk = {GPIO_PIN(GPIO_PORTF, 2), GPIO_PERIPH_MUX2}, + .gpio_cmd = {GPIO_PIN(GPIO_PORTF, 3), GPIO_PERIPH_MUX2}, + .gpio_d0 = {GPIO_PIN(GPIO_PORTF, 1), GPIO_PERIPH_MUX2}, + .gpio_d1 = {GPIO_PIN(GPIO_PORTF, 0), GPIO_PERIPH_MUX2}, + .gpio_d2 = {GPIO_PIN(GPIO_PORTF, 5), GPIO_PERIPH_MUX2}, + .gpio_d3 = {GPIO_PIN(GPIO_PORTF, 4), GPIO_PERIPH_MUX2}, +}; + +sunxi_i2c_t i2c_pmu_axp717 = { + .base = SUNXI_RTWI_BASE, + .id = SUNXI_R_I2C0, + .speed = 4000000, + .gpio_scl = {GPIO_PIN(GPIO_PORTL, 0), GPIO_PERIPH_MUX3}, + .gpio_sda = {GPIO_PIN(GPIO_PORTL, 1), GPIO_PERIPH_MUX3}, +}; + + +sunxi_i2c_t i2c_pmu_axp323 = { + .base = SUNXI_RTWI_BASE, + .id = SUNXI_R_I2C1, + .speed = 4000000, + .gpio_scl = {GPIO_PIN(GPIO_PORTL, 0), GPIO_PERIPH_MUX3}, + .gpio_sda = {GPIO_PIN(GPIO_PORTL, 1), GPIO_PERIPH_MUX3}, +}; + +void neon_enable(void) { + /* set NSACR, both Secure and Non-secure access are allowed to NEON */ + asm volatile("MRC p15, 0, r0, c1, c1, 2"); + asm volatile("ORR r0, r0, #(0x3<<10) @ enable fpu/neon"); + asm volatile("MCR p15, 0, r0, c1, c1, 2"); + /* Set the CPACR for access to CP10 and CP11*/ + asm volatile("LDR r0, =0xF00000"); + asm volatile("MCR p15, 0, r0, c1, c0, 2"); + /* Set the FPEXC EN bit to enable the FPU */ + asm volatile("MOV r3, #0x40000000"); + /*@VMSR FPEXC, r3*/ + asm volatile("MCR p10, 7, r3, c8, c0, 0"); +} + +void clean_syterkit_data(void) { + /* Disable MMU, data cache, instruction cache, interrupts */ + arm32_mmu_disable(); + printk(LOG_LEVEL_INFO, "disable mmu ok...\n"); + arm32_dcache_disable(); + printk(LOG_LEVEL_INFO, "disable dcache ok...\n"); + arm32_icache_disable(); + printk(LOG_LEVEL_INFO, "disable icache ok...\n"); + arm32_interrupt_disable(); + printk(LOG_LEVEL_INFO, "free interrupt ok...\n"); +} diff --git a/board/longanpi-4b/eabi_compat.c b/board/longanpi-4b/eabi_compat.c new file mode 100644 index 00000000..93303d89 --- /dev/null +++ b/board/longanpi-4b/eabi_compat.c @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +void abort(void) { + while (1) + ; +} + +int raise(int signum) { + return 0; +} + +/* Dummy function to avoid linker complaints */ +void __aeabi_unwind_cpp_pr0(void) { +} \ No newline at end of file diff --git a/board/longanpi-4b/hello_world/CMakeLists.txt b/board/longanpi-4b/hello_world/CMakeLists.txt new file mode 100644 index 00000000..b5ce1ea5 --- /dev/null +++ b/board/longanpi-4b/hello_world/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_syterkit_app(helloworld + main.c +) \ No newline at end of file diff --git a/board/longanpi-4b/hello_world/main.c b/board/longanpi-4b/hello_world/main.c new file mode 100644 index 00000000..dd16f216 --- /dev/null +++ b/board/longanpi-4b/hello_world/main.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include +#include +#include +#include + +#include + +#include + +#include + +extern sunxi_serial_t uart_dbg; + +int main(void) { + sunxi_serial_init(&uart_dbg); + + show_banner(); + + sunxi_clk_init(); + + sunxi_clk_dump(); + + printk(LOG_LEVEL_INFO, "Hello World!\n"); + + abort(); + + return 0; +} \ No newline at end of file diff --git a/board/longanpi-4b/start.S b/board/longanpi-4b/start.S new file mode 100644 index 00000000..091199ea --- /dev/null +++ b/board/longanpi-4b/start.S @@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#define ARMV7_USR_MODE 0x10 +#define ARMV7_FIQ_MODE 0x11 +#define ARMV7_IRQ_MODE 0x12 +#define ARMV7_SVC_MODE 0x13 +#define ARMV7_MON_MODE 0x16 +#define ARMV7_ABT_MODE 0x17 +#define ARMV7_UND_MODE 0x1b +#define ARMV7_SYSTEM_MODE 0x1f +#define ARMV7_MODE_MASK 0x1f +#define ARMV7_FIQ_MASK 0x40 +#define ARMV7_IRQ_MASK 0x80 + +.arm +.globl reset +.text + +reset: + /* Boot head information for BROM */ + .long 0xea000016 + .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' + .long 0x12345678 /* checksum */ + .long __spl_size /* spl size */ + .long 0x30 /* boot header size */ + .long 0x30303033 /* boot header version */ + .long 0x00020000 /* return value */ + .long 0x00028000 /* run address */ + .long 0x0 /* eGON version */ + .byte 0x00, 0x00, 0x00, 0x00 /* platform information - 8byte */ + .byte 0x34, 0x2e, 0x30, 0x00 + + /* + * The actual reset code + */ + mrs r0, cpsr + bic r0, r0, #ARMV7_MODE_MASK + orr r0, r0, #ARMV7_SVC_MODE + orr r0, r0, #(ARMV7_IRQ_MASK | ARMV7_FIQ_MASK) + bic r0, r0, #(1<<9) @set little-endian + msr cpsr_c, r0 + + /* Set vector base address register */ + + ldr r0, =_vector + mcr p15, 0, r0, c12, c0, 0 + mrc p15, 0, r0, c1, c0, 0 + bic r0, #(1 << 13) + mcr p15, 0, r0, c1, c0, 0 + + mrc p15, 0, r0, c1, c0, 0 + bic r0, r0, #0x00002000 @ clear bits 13 (--V-) + bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) + orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB + bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache + mcr p15, 0, r0, c1, c0, 0 + + /* Set stack pointer */ + ldr sp, =__stack_srv_end + + bl clear_bss + + /* + * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode, + * except if in HYP mode already + */ + mrs r0, cpsr + and r1, r0, #0x1f @ mask mode bits + teq r1, #0x1a @ test for HYP mode + bicne r0, r0, #0x1f @ clear all mode bits + orrne r0, r0, #0x13 @ set SVC mode + orr r0, r0, #0xc0 @ disable FIQ and IRQ + msr cpsr,r0 + + @set cntfrq to 24M + ldr r0, =24000000 + mcr p15, 0, r0, c14, c0, 0 + + bl set_timer_count + + bl main + +clear_bss: + ldr r0, =_sbss + ldr r1, =_ebss + mov r2, #0 + +clbss_1: + stmia r0!, {r2} + cmp r0, r1 + blt clbss_1 + + mov pc, lr + +_vector: + b reset + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +_undefined_instruction: + .word undefined_instruction +_software_interrupt: + .word software_interrupt +_prefetch_abort: + .word prefetch_abort +_data_abort: + .word data_abort +_not_used: + .word not_used +_irq: + .word irq +_fiq: + .word fiq + +.macro save_regs + str lr, [sp, #-4] + mrs lr, spsr_all + str lr, [sp, #-8] + str r1, [sp, #-12] + str r0, [sp, #-16] + mov r0, sp + cps #0x13 + ldr r1, [r0, #-4] + str r1, [sp, #-4]! + ldr r1, [r0, #-8] + str r1, [sp, #-(4 * 16)] + ldr r1, [r0, #-12] + ldr r0, [r0, #-16] + stmdb sp, {r0 - r14}^ + sub sp, sp, #(4 * 16) + ldr r4, [sp] + and r0, r4, #0x1f + cmp r0, #0x10 + beq 10f + cmp r0, #0x13 + beq 11f + b . +11: add r1, sp, #(4 * 17) + str r1, [sp, #(4 * 14)] + str lr, [sp, #(4 * 15)] +10: add r1, sp, #(4 * 17) + str r1, [sp, #-4]! + mov r0, sp +.endm + +.macro restore_regs + mov r12, sp + ldr sp, [r12], #4 + ldr r1, [r12], #4 + msr spsr_cxsf, r1 + and r0, r1, #0x1f + cmp r0, #0x10 + beq 20f + cmp r0, #0x13 + beq 21f + b . +20: ldr lr, [r12, #(4 * 15)] + ldmia r12, {r0 - r14}^ + movs pc, lr +21: ldm r12, {r0 - r15}^ + mov r0, r0 +.endm + + /* + * Exception handlers + */ + .align 5 +undefined_instruction: + sub lr, lr, #4 + save_regs + bl arm32_do_undefined_instruction + restore_regs + + .align 5 +software_interrupt: + sub lr, lr, #4 + save_regs + bl arm32_do_software_interrupt + restore_regs + + .align 5 +prefetch_abort: + sub lr, lr, #4 + save_regs + bl arm32_do_prefetch_abort + restore_regs + + .align 5 +data_abort: + sub lr, lr, #8 + save_regs + bl arm32_do_data_abort + restore_regs + + .align 5 +not_used: + b . + + .align 5 +irq: + sub lr, lr, #4 + save_regs + bl arm32_do_irq + restore_regs + + .align 5 +fiq: + sub lr, lr, #4 + save_regs + bl arm32_do_fiq + restore_regs diff --git a/cmake/board/longanpi-4b.cmake b/cmake/board/longanpi-4b.cmake new file mode 100644 index 00000000..85fd9650 --- /dev/null +++ b/cmake/board/longanpi-4b.cmake @@ -0,0 +1,56 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(CONFIG_ARCH_ARM32 True) +set(CONFIG_ARCH_ARM32_ARM64 True) +set(CONFIG_CHIP_SUN55IW3 True) +set(CONFIG_CHIP_WITHPMU True) +set(CONFIG_BOARD_LONGANPI-4B True) + +add_definitions(-DCONFIG_CHIP_SUN55IW3) + +set(CONFIG_USE_DRAM_PAYLOAD True) +set(CONFIG_USE_PREBUILT_DRAM_PAYLOAD False) +set(CONFIG_USE_DRAM_PAYLOAD_SOURCE_PATH "${CMAKE_SOURCE_DIR}/payloads/sun55iw3_libdram") +set(CONFIG_USE_DRAM_PAYLOAD_BIN_PATH "${CONFIG_USE_DRAM_PAYLOAD_SOURCE_PATH}/output/ddr.bin") +set(CONFIG_USE_DRAM_PAYLOAD_FILE_PATH "${CMAKE_SOURCE_DIR}/board/longanpi-4b/payloads/init_dram_bin.c") +set(CONFIG_USE_DRAM_PAYLOAD_SECTION "init_dram_bin") + +# Set the cross-compile toolchain +set(CROSS_COMPILE "arm-none-eabi-") +set(CROSS_COMPILE ${CROSS_COMPILE} CACHE STRING "CROSS_COMPILE Toolchain") + +# Set the C and C++ compilers +set(CMAKE_C_COMPILER "${CROSS_COMPILE}gcc") +set(CMAKE_CXX_COMPILER "${CROSS_COMPILE}g++") + +set(CMAKE_COMMON_FLAGS "-nostdlib -Os -mcpu=cortex-a55") + +# Disable specific warning flags for C and C++ compilers +set(CMAKE_C_DISABLE_WARN_FLAGS "-Wno-int-to-pointer-cast -Wno-implicit-function-declaration -Wno-discarded-qualifiers") +set(CMAKE_CXX_DISABLE_WARN_FLAGS "-Wno-int-to-pointer-cast") + +set(ARCH_BIN_START_ADDRESS "0x00044000") +set(ARCH_BIN_SRAM_LENGTH "128K") + +set(ARCH_FEL_START_ADDRESS "0x0004c000") +set(ARCH_FEL_SRAM_LENGTH "128K") + +if(CONFIG_USE_PREBUILT_DRAM_PAYLOAD) + # Create an external project and build it + ExternalProject_Add( + init_dram + PREFIX init_dram + SOURCE_DIR "${CONFIG_USE_DRAM_PAYLOAD_SOURCE_PATH}" + INSTALL_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND make -C ${CONFIG_USE_DRAM_PAYLOAD_SOURCE_PATH} + BUILD_IN_SOURCE 1 + ) + + # Create inital init dram bin file for build + add_custom_command( + TARGET init_dram + POST_BUILD COMMAND ${CMAKE_BIN2ARRAY} ${CONFIG_USE_DRAM_PAYLOAD_BIN_PATH} ${CONFIG_USE_DRAM_PAYLOAD_FILE_PATH} ${CONFIG_USE_DRAM_PAYLOAD_SECTION} + COMMENT "Generate DRAM LIB Payload ${CONFIG_USE_DRAM_PAYLOAD_BIN_PATH} for ${CONFIG_USE_DRAM_PAYLOAD_FILE_PATH}" + ) +endif() \ No newline at end of file