GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
choice
prompt "Target select"
default TARGET_XMFALCON
config TARGET_XMFALCON
bool "Support xmfalcon"
select CPU_V7A
select DM
select CPU_V7A_HAS_NONSEC
help
Support for lotus xmfalcon platform.
config TARGET_XMORCA
bool "Support xmorca"
select CPU_V7A
select DM
select CPU_V7A_HAS_NONSEC
help
Support for lotus xmorca platform.
config TARGET_XMORCA
bool "Support xmorca"
select CPU_V7A
select DM
select CPU_V7A_HAS_NONSEC
help
Support for lotus xmorca platform.
endchoice
source "lotus/machine/xmfalcon/Kconfig"
source "lotus/machine/xmorca/Kconfig"
+4
View File
@@ -0,0 +1,4 @@
# obj-y += $(subst ",,$(CONFIG_SYS_SOC))
obj-$(CONFIG_TARGET_XMFALCON) += xmfalcon/
obj-$(CONFIG_TARGET_XMORCA) += xmorca/
@@ -0,0 +1,15 @@
if TARGET_XMFALCON
# config SYS_BOARD
# default "xmfalcon"
#
# config SYS_VENDOR
# default "lotus"
config SYS_SOC
default "xmfalcon"
config SYS_CONFIG_NAME
default "xmfalcon"
endif
@@ -0,0 +1,3 @@
obj-y += chip.o
obj-y += board.o
@@ -0,0 +1,241 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
#include <common.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
#include <spi_flash.h>
#include <linux/mtd/mtd.h>
#include <nand.h>
#include <netdev.h>
#include <mmc.h>
#include <asm/sections.h>
#include <sdhci.h>
#include <linux/lotus/common.h>
#include <asm/mach-types.h>
#include <env_internal.h>
#include <linux/lotus/chip.h>
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
#endif
static int boot_media __section(.data) = BOOT_MEDIA_UNKNOWN;
int get_boot_media(void)
{
unsigned int reg_val, boot_mode, spi_device_mode;
if (boot_media != BOOT_MEDIA_UNKNOWN)
return boot_media;
reg_val = readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
boot_mode = get_sys_boot_mode(reg_val);
switch (boot_mode) {
case BOOT_FROM_SPI:
spi_device_mode = get_spi_device_type(reg_val);
if (spi_device_mode)
boot_media = BOOT_MEDIA_NAND;
else
boot_media = BOOT_MEDIA_SPIFLASH;
break;
case BOOT_FROM_EMMC:
boot_media = BOOT_MEDIA_EMMC;
break;
default:
boot_media = BOOT_MEDIA_UNKNOWN;
break;
}
return boot_media;
}
void show_boot_media(void)
{
puts("Boot Media: ");
switch (boot_media) {
case BOOT_MEDIA_SPIFLASH:
puts("SPI Nor");
break;
case BOOT_MEDIA_NAND:
puts("SPI Nand");
break;
case BOOT_MEDIA_EMMC:
puts("eMMC");
break;
default:
puts("Unknown");
break;
}
puts("\r\n");
}
#if defined(CONFIG_SHOW_BOOT_PROGRESS)
void show_boot_progress(int progress)
{
printf("Boot reached stage %d\n", progress);
}
#endif
int board_early_init_f(void)
{
return 0;
}
int misc_init_r(void)
{
#ifdef CONFIG_RANDOM_ETHADDR
random_init_r();
#endif
env_set("verify", "n");
return 0;
}
void show_chip_info(void)
{
u32 chip_id = get_chipid();
printf("Chip ID: 0x%X\n", chip_id);
}
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_arch_number = MACH_TYPE_LOTUS;
gd->bd->bi_boot_params = CFG_BOOT_PARAMS;
get_boot_media();
show_boot_media();
show_chip_info();
return 0;
}
u64 get_ddr_size(void)
{
return readl(REG_BASE_SCTL + REG_SC_DDRT12);
}
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->ram_size = get_ddr_size();
return 0;
}
void board_add_ram_info(int use_default)
{
#ifdef CONFIG_SYS_MEM_TOP_HIDE
putc('(');
print_size(CONFIG_SYS_MEM_TOP_HIDE, "");
puts(" Reserved)");
#endif
}
void reset_cpu(ulong addr)
{
/* 0x12345678:writing any value will cause a reset. */
writel(0x12345678, SYS_CTRL_REG_BASE + REG_SC_SYSRES);
while (1);
}
int timer_init(void)
{
/*
* Under uboot, 0xffffffff is set to load register,
* timer_clk equals BUSCLK/2/256.
* e.g. BUSCLK equals 50M, it will roll back after 0xffffffff/timer_clk
* 43980s equals 12hours
*/
__raw_writel(0, TIMER0_REG_BASE + REG_TIMER_CONTROL);
__raw_writel(~0, TIMER0_REG_BASE + REG_TIMER_RELOAD);
/* 32 bit, periodic */
__raw_writel(CFG_TIMER_CTRL, TIMER0_REG_BASE + REG_TIMER_CONTROL);
return 0;
}
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_NET_FEMAC
rc = bspeth_initialize(bis);
#endif
#ifdef CONFIG_FTGMAC030
rc = ftgmac030_initialize(bis);
#endif
return rc;
}
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
int ret = 0;
#ifdef CONFIG_LOTUS_SDHCI
int dev_num = 0;
if (get_boot_media() == BOOT_MEDIA_EMMC) {
ret = sdhci_add_port(dev_num, EMMC_BASE_REG, MMC_TYPE_MMC);
if (!ret) {
ret = lotus_mmc_init(dev_num);
if (ret)
printf("No EMMC device found !\n");
}
dev_num++;
}
#ifdef CONFIG_AUTO_SD_UPDATE
ret = sdhci_add_port(dev_num, SDIO0_BASE_REG, MMC_TYPE_SD);
if (ret)
return ret;
ret = lotus_mmc_init(dev_num);
if (ret)
printf("No SD device found !\n");
#endif
#endif
return ret;
}
#endif
enum env_location env_get_location(enum env_operation op, int prio)
{
int boot_media = get_boot_media();
enum env_location loc;
if (prio)
return ENVL_UNKNOWN;
switch (boot_media) {
case BOOT_MEDIA_SPIFLASH:
loc = ENVL_SPI_FLASH;
break;
case BOOT_MEDIA_NAND:
loc = ENVL_NAND;
break;
case BOOT_MEDIA_EMMC:
loc = ENVL_MMC;
break;
default:
loc = ENVL_UNKNOWN;
break;
}
return loc;
}
@@ -0,0 +1,15 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
unsigned int g_cpu_chipid = 0;
unsigned int get_chipid(void)
{
if (g_cpu_chipid == 0)
g_cpu_chipid = readl(REG_SC_CHIPID);
return g_cpu_chipid;
}
@@ -0,0 +1,162 @@
################################################################################
SHELL := /bin/bash
PWD = $(shell pwd)
HW_CROSS_COMPILE = $(CROSS_COMPILE)
BOOT_TOPDIR ?= $(PWD)/../../../../../
BOOT_OUTDIR ?= $(BOOT_TOPDIR)
include $(BOOT_OUTDIR)/include/autoconf.mk
include $(BOOT_OUTDIR)/include/config/auto.conf
GZIP ?= $(if $(wildcard $(BOOT_TOPDIR)/../../../tools/utils/bin/gzip), $(BOOT_TOPDIR)/../../../tools/utils/bin/gzip, $(BOOT_TOPDIR)/tools/gzip)
SOC := xmfalcon
SRCDIR := $(PWD)
DDR_TYPE ?= $(shell \
ddr=`dd if=.reg bs=1 skip=64 count=64 | \
xxd -p | sed ':label;N;s/\n//g;b label' | \
sed 's/000*/0a/g' | xxd -r -p`; \
echo $${ddr,,} | sed -n 's/.*_\(.*ddr[3,4]\)_.*/\1/gp')
$(info DDR_TYPE=$(DDR_TYPE))
$(info SHELL=$(SHELL))
################################################################################
CC := $(HW_CROSS_COMPILE)gcc
AR := $(HW_CROSS_COMPILE)ar
LD := $(HW_CROSS_COMPILE)ld
OBJCOPY := $(HW_CROSS_COMPILE)objcopy
################################################################################
.PHONY: all $(BOOT).bin
BOOT := u-boot
TEXTBASE := $(CONFIG_SYS_TEXT_BASE_ORI)
CFLAGS :=-Os -fno-builtin -ffreestanding \
-D__KERNEL__ -DTEXT_BASE=$(TEXTBASE) \
-I$(BOOT_TOPDIR)/include \
-I$(BOOT_OUTDIR)/include \
-I$(BOOT_TOPDIR)/arch/arm/include \
-I$(BOOT_TOPDIR)/lib/hw_dec \
-fno-pic -ffunction-sections \
-fdata-sections -fno-common -ffixed-r9 \
-fno-common -pipe -march=armv7-a \
-Wall -Wstrict-prototypes -fno-stack-protector \
-D__LINUX_ARM_ARCH__=7 -D__ARM__ \
-DCONFIG_MMC\
$(MKFLAGS) -fno-strict-aliasing \
$(EXTRA_CFLAGS) \
UBOOT_Z_LDS := u-boot.lds
################################################################################
START := start.o
COBJS := uart.o \
startup.o \
image_data.o \
reset.o \
exceptions.o \
time.o \
tail.o
SSRC := \
lotus/hw_dec/hw_decompress.c \
lotus/hw_dec/hw_decompress_$(SOC).c \
lotus/hw_dec/hw_decompress_v1.c \
lotus/hw_dec/hw_decompress_v1.h \
SRC := $(notdir $(SSRC))
REG := $(wildcard *.reg .reg)
IMAGE_DATA_Z := image_data.gzip
CFLAGS += -DCONFIG_BOOTREG_DEFAULT=\"$(BOOT_OUTDIR)/.reg\"
CFLAGS += -DCONFIG_AUXIMAGE=$(if $(AUXCODE_IMAGE),\"$(AUXCODE_IMAGE)\",\"$(SRCDIR)/auxcode_$(DDR_TYPE).bin\")
CFLAGS += -DCONFIG_AUXCODE_2048_ENABLE=y
LBIST_TEST_PATTERN_IMAGE_SIZE = $(shell wc -c < $(SRCDIR)/lbist_test_pattern.bin)
CFLAGS += -DCONFIG_LBIST_TEST_PATTERN_IMAGE=\"$(SRCDIR)/lbist_test_pattern.bin\"
CFLAGS += -DCONFIG_LBIST_TEST_PATTERN_IMAGE_SIZE=$(LBIST_TEST_PATTERN_IMAGE_SIZE)
CFLAGS += -DCONFIG_LBIST_TEST_PATTERN_HASH_IMAGE=\"$(SRCDIR)/lbist_test_pattern_sha256.bin\"
CFLAGS += -DCONFIG_MCU_FW_IMAGE=\"$(if $(wildcard $(BOOT_OUTDIR)/qs_mcu.bin),$(BOOT_OUTDIR)/qs_mcu.bin,$(SRCDIR)/qs_mcu.bin)\"
################################################################################
.PHONY: all $(BOOT).bin
all: $(BOOT).bin
$(BOOT).bin: $(BOOT).tmp
$(Q)cat $(BOOT).tmp > $(BOOT).bin
$(Q)chmod 754 $(BOOT).bin
$(Q)cp -fv $@ $(BOOT_OUTDIR)/u-boot-$(SOC).bin
$(Q)echo $(BOOT).bin is Ready.
$(BOOT).tmp: $(BOOT).elf
$(OBJCOPY) -O srec $< $(BOOT).srec
$(OBJCOPY) -j .text -O binary $< $(BOOT).text
$(OBJCOPY) --gap-fill=0xff -O binary $< $@
$(BOOT).elf: $(IMAGE_DATA_Z) $(SRC) $(START) $(COBJS) $(UBOOT_Z_LDS)
$(LD) -Bstatic -T $(UBOOT_Z_LDS) -Ttext $(TEXTBASE) $(START) \
$(COBJS) -Map $(BOOT).map -o $@
$(OBJDUMP) -d $@ > $@.asm
.PHONY: regfile
regfile:
@if [ "$(words $(REG))" = "0" ]; then ( \
echo '***' Need '.reg' or '*.reg' file in directory $(PWD); \
exit 1; \
) fi
@if [ "$(words $(REG))" != "1" ]; then ( \
echo '***' Found multi '.reg' or '*.reg' file in directory $(PWD); \
echo '***' Files: $(notdir $(REG)); \
exit 1; \
) fi
################################################################################
$(START): start.S regfile
$(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c
# -1 : --fast -9 : --best
$(IMAGE_DATA_Z): $(BINIMAGE)
ifneq ($(CONFIG_LOTUS_GZIP_BOOT),)
$(GZIP) -fNqc -7 $< > $@
else
cp $< $@
endif
%.o: %.c
$(CC) $(CFLAGS) -Wall -Wstrict-prototypes \
-fno-stack-protector -o $@ $< -c
%.o: %.S
$(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c
image_data.o: image_data.S $(IMAGE_DATA_Z)
$(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c
#############################################################################
$(SRC):
ln -sf $(BOOT_TOPDIR)/$(filter %/$@,$(SSRC)) $@
################################################################################
TMPS := $(COBJS) $(START) $(SRC) \
$(BOOT).map $(BOOT).elf $(BOOT).elf.asm $(BOOT).srec $(BOOT).bin $(BOOT).text $(BOOT).tmp \
$(IMAGE_DATA_Z)
cmd_rm_files = @echo 'RM $(1)';$(shell [[ -n "$(1)" && "$(1)" != "*" ]] && rm -f $(1))
.PHONY: clean distclean
distclean: clean
clean:
$(call cmd_rm_files, $(REG))
$(call cmd_rm_files, $(TMPS))
$(call cmd_rm_files, $(SRC))
################################################################################
.PHONY: clean
FORCE:
################################################################################
@@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* exception handlers */
#include <config.h>
.align 2
_irq_stack_start:
.word CONFIG_SYS_INIT_SP_ADDR
.align 2
.global irq_undefined_instruction
.type irq_undefined_instruction, %function
irq_undefined_instruction:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: undefined instruction\r\nLR: \0"
.align 2
.global irq_software_interrupt
.type irq_software_interrupt, %function
irq_software_interrupt:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: software interrupt\r\nLR: \0"
.align 2
.global irq_prefetch_abort
.type irq_prefetch_abort, %function
irq_prefetch_abort:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: prefetch abort\r\nLR: \0"
.align 2
.global irq_data_abort
.type irq_data_abort, %function
irq_data_abort:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: data abort\r\nLR: \0"
.align 2
.global irq_not_used
.type irq_not_used, %function
irq_not_used:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: not used\r\nLR: \0"
.align 2
.global irq_irq
.type irq_irq, %function
irq_irq:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: interrupt\r\nLR: \0"
.align 2
.global irq_firq
.type irq_firq, %function
irq_firq:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: fast interrupt\r\nLR: \0"
@@ -0,0 +1,9 @@
.section .image,#alloc
.globl input_data
/*gzip source addr must be 16 bytes aligned*/
.balign 16
input_data:
.incbin "image_data.gzip"
.globl input_data_end
input_data_end:
@@ -0,0 +1,18 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
.global reset_cpu
reset_cpu:
ldr r1, rstctl @ get addr for global reset
@ reg
mov r3, #0x2 @ full reset pll + mpu
str r3, [r1] @ force reset
mov r0, r0
_loop_forever:
b _loop_forever
rstctl:
.word SYS_CTRL_REG_BASE + REG_SC_SYSRES
@@ -0,0 +1,415 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <asm-offsets.h>
#include <config.h>
#include <asm/system.h>
#include <linux/linkage.h>
#include <asm/armv7.h>
#include <linux/lotus/step.h>
.globl _start
_start:
/***** Key Area ****/
.=CONFIG_ROOT_RSA_PUB_KEY_N_POS
.fill CONFIG_ROOT_RSA_PUB_KEY_N_LEN, 1, 0
.=CONFIG_ROOT_RSA_PUB_KEY_E_POS
.fill CONFIG_ROOT_RSA_PUB_KEY_E_ZERO_LEN, 1, 0
.=(CONFIG_ROOT_RSA_PUB_KEY_E_POS + CONFIG_ROOT_RSA_PUB_KEY_E_ZERO_LEN)
.word CONFIG_ROOT_RSA_PUB_KEY_E_V
/***** Params Area ****/
.=CONFIG_AUXCODE_AREA_LEN_POS
.word CONFIG_AUXAREA_LEN
.=CONFIG_BOOT_CODE_AREA_LEN_POS
.word _checked_area_end - _checked_area_start
.=CONFIG_TOTAL_BOOT_AREA_LEN_POS
.word (_checked_area_end - _checked_area_start + 0x200)
.=CONFIG_PARAMS_FORM_LEN_POS
.word CONFIG_PARAMS_FORM_LEN
.=CONFIG_BOOT_ENC_FLAG_POS
.word CONFIG_BOOT_ENC_FLAG
.=CONFIG_BOOT_ENTRY_PIONT_POS
.word CONFIG_BOOT_ENTRY_PIONT
.=CONFIG_AUXCODE_AES_IV_POS
.fill 16, 1, 0
.=CONFIG_BOOT_AES_IV_POS
.fill 16, 1, 0
.=CONFIG_PARAMS_FORM_POS
_default_boot_reg_pos:
.incbin CONFIG_BOOTREG_DEFAULT /* reg */
_default_boot_reg_end:
.=CONFIG_LOAD_MCU_FW_FLAG_POS
.word CONFIG_LOAD_MCU_FW_FLAG
.=CONFIG_MCU_FW_AREA_LEN_POS
.word CONFIG_MCU_FW_AREA_LEN
.=CONFIG_LBIST_TEST_PATTERN_OFF_POS
.word (_checked_area_end - _checked_area_start + 0x200 + CONFIG_AUXAREA_LEN + CONFIG_KEY_AREA_LEN + CONFIG_MCU_FW_AREA_LEN)
.=COFNIG_LBIST_TEST_PATTERN_LEN_POS
.word CONFIG_LBIST_TEST_PATTERN_IMAGE_SIZE
.=COFNIG_LBIST_TEST_PATTERN_HASH_POS
.incbin CONFIG_LBIST_TEST_PATTERN_HASH_IMAGE
.=COFNIG_AUXCODE_ALG_FLAG_POS
.word CONFIG_AUXCODE_2048_FLAG
.=CONFIG_RESERVED0_POS
.fill CONFIG_RESERVED0_LEN, 1, 0
.=CONFIG_SIG_PARAMS_POS
.fill CONFIG_SIG_PARAMS_LEN, 1, 0
/**** Uncheck Area ****/
.=CONFIG_SCS_SIMULATE_FLAG_POS
.word CONFIG_SCS_SIMULATE_FLAG
.=CONFIG_BOOT_STORE_ADDR_POS
.word CONFIG_BOOT_STORE_ADDR
.=CONFIG_FLASH_EMPYT_FLAG_POS
.word CONFIG_FLASH_EMPYT_FLAG
.=CONFIG_RESERVED1_POS
.fill CONFIG_RESERVED1_LEN, 1, 0
/**** Auxcode Area *****/
.=CONFIG_IMAGE_INFO_POS
.incbin CONFIG_AUXIMAGE
/* mcu fw */
#if (CONFIG_MCU_FW_AREA_LEN > 0)
.=CONFIG_MCU_FW_AREA_POS
.incbin CONFIG_MCU_FW_IMAGE
#endif
/**** Boot Code Area *****/
.=CONFIG_BOOT_CODE_AREA_POS
.align 4
_checked_area_start:
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
.balignl 64,0xdeadbeef
_undefined_instruction: .word irq_undefined_instruction
_software_interrupt: .word irq_software_interrupt
_prefetch_abort: .word irq_prefetch_abort
_data_abort: .word irq_data_abort
_not_used: .word irq_not_used
_irq: .word irq_irq
_fiq: .word irq_firq
.globl reset
.globl save_boot_params_ret
/* fix text_base,real code position */
.globl _TEXT_BASE
_TEXT_BASE:
.word TEXT_BASE + CONFIG_KEY_AREA_LEN + CONFIG_AUXAREA_LEN
_start_armboot:
.word start_armboot
_bss_start:
.word __bss_start
_bss_end:
.word __bss_end
.globl __checked_area_start
__checked_area_start:
.word _checked_area_start
reset:
step_no_stack 30, r11, r12
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
/*
* 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 V=0 in CP15 SCTLR register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
/* Set vector address in CP15 VBAR register */
adrl r0, _checked_area_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
#endif
normal_start_flow:
/* Early init */
ldr sp, =CONFIG_SYS_INIT_SP_ADDR
step 31
bl timer_init
bl timestamp_init
bl uart_early_init
bl msg_main_cpu_startup
#ifndef CONFIG_SYS_ICACHE_OFF
@enable I-Cache now
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0
#endif
step 32
#ifndef CONFIG_LOTUS_GZIP_BOOT
/* move uboot to final text base */
ldr r1, =CONFIG_SYS_TEXT_BASE
ldr r0, =input_data
ldr r3, =input_data_end
sub r2, r3, r0
/* memcpy(r1, r0, r2) */
bl memcpy
#endif
step 33
clear_bss:
/* clean .bss section */
ldr r0, _bss_start
ldr r1, _bss_end
mov r2, #0x0
next_bss:
str r2, [r0] @ clear BSS location
cmp r0, r1 @ are we at the end yet
add r0, r0, #4 @ increment clear index pointer
bne next_bss @ keep clearing till at end
step 34
relocate:
ldr r0, =_start_armboot
ldr pc, [r0]
bug:
nop
nop
nop
nop
nop
nop
nop
nop
b . /* bug here */
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ void memcpy(r1, r0, r2);
@
.align 2
memcpy:
add r2, r0, r2
memcpy_loop:
ldmia r0!, {r3 - r10}
stmia r1!, {r3 - r10}
cmp r0, r2
ble memcpy_loop
mov pc, lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align 2
msg_main_cpu_startup:
mov r5, lr
add r0, pc, #4
bl uart_early_puts
mov pc, r5
L10:
.ascii "\r\n\r\nSystem startup\r\n\0"
/*------------------------------------------------------------------------------*/
ENTRY(c_runtime_cpu_setup)
/*
* If I-cache is enabled invalidate it
*/
#ifndef CONFIG_SYS_ICACHE_OFF
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
#endif
bx lr
ENDPROC(c_runtime_cpu_setup)
/*************************************************************************
*
* void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
* __attribute__((weak));
*
* Stack pointer is not yet initialized at this moment
* Don't save anything to stack even if compiled with -O0
*
*************************************************************************/
ENTRY(save_boot_params)
b save_boot_params_ret @ back to my caller
ENDPROC(save_boot_params)
.weak save_boot_params
/*************************************************************************
*
* cpu_init_cp15
*
* Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
* CONFIG_SYS_ICACHE_OFF is defined.
*
*************************************************************************/
ENTRY(cpu_init_cp15)
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
/*
* disable MMU stuff and caches
*/
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, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
#endif
mcr p15, 0, r0, c1, c0, 0
#ifdef CONFIG_ARM_ERRATA_716044
mrc p15, 0, r0, c1, c0, 0 @ read system control register
orr r0, r0, #1 << 11 @ set bit #11
mcr p15, 0, r0, c1, c0, 0 @ write system control register
#endif
#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 4 @ set bit #4
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_743622
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 6 @ set bit #6
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_751472
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 11 @ set bit #11
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_761320
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 21 @ set bit #21
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
mov r5, lr @ Store my Caller
mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR)
mov r3, r1, lsr #20 @ get variant field
and r3, r3, #0xf @ r3 has CPU variant
and r4, r1, #0xf @ r4 has CPU revision
mov r2, r3, lsl #4 @ shift variant field for combined value
orr r2, r4, r2 @ r2 has combined CPU variant + revision
#ifdef CONFIG_ARM_ERRATA_798870
cmp r2, #0x30 @ Applies to lower than R3p0
bge skip_errata_798870 @ skip if not affected rev
cmp r2, #0x20 @ Applies to including and above R2p0
blt skip_errata_798870 @ skip if not affected rev
mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg
orr r0, r0, #1 << 7 @ Enable hazard-detect timeout
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_l2aux_ctrl
isb @ Recommended ISB after l2actlr update
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_798870:
#endif
#ifdef CONFIG_ARM_ERRATA_801819
cmp r2, #0x24 @ Applies to lt including R2p4
bgt skip_errata_801819 @ skip if not affected rev
cmp r2, #0x20 @ Applies to including and above R2p0
blt skip_errata_801819 @ skip if not affected rev
mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg
and r0, r0, #1 << 3 @ check REVIDR[3]
cmp r0, #1 << 3
beq skip_errata_801819 @ skip erratum if REVIDR[3] is set
mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate
@ lines allocate in the L1 or L2 cache.
orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate
@ lines allocate in the L1 cache.
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_801819:
#endif
#ifdef CONFIG_ARM_ERRATA_454179
cmp r2, #0x21 @ Only on < r2p1
bge skip_errata_454179
mrc p15, 0, r0, c1, c0, 1 @ Read ACR
orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_454179:
#endif
#ifdef CONFIG_ARM_ERRATA_430973
cmp r2, #0x21 @ Only on < r2p1
bge skip_errata_430973
mrc p15, 0, r0, c1, c0, 1 @ Read ACR
orr r0, r0, #(0x1 << 6) @ Set IBE bit
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_430973:
#endif
#ifdef CONFIG_ARM_ERRATA_621766
cmp r2, #0x21 @ Only on < r2p1
bge skip_errata_621766
mrc p15, 0, r0, c1, c0, 1 @ Read ACR
orr r0, r0, #(0x1 << 5) @ Set L1NEON bit
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_621766:
#endif
mov pc, r5 @ back to my caller
ENDPROC(cpu_init_cp15)
@@ -0,0 +1,162 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
#include <linux/kconfig.h>
#include <asm/io.h>
#include <compiler.h>
#include <linux/lotus/common.h>
#include <linux/lotus/timestamp.h>
#include <linux/lotus/step.h>
#include "time.h"
const uintptr_t image_entry = (CONFIG_SYS_TEXT_BASE);
#ifndef CONFIG_LOTUS_DISABLE_CONSOLE
#define info(_s) uart_early_puts(_s)
#else
#define info(_s)
#endif
#define error(_s) uart_early_puts(_s)
#define putstr(_s) uart_early_puts(_s)
#include "hw_decompress.c"
#define GZIP_SIZE_OFFSET 0x4
#ifndef CONFIG_SYS_ICACHE_OFF
/* Invalidate entire I-cache and branch predictor array */
static void invalidate_icache_all(void)
{
/*
* Invalidate all instruction caches to PoU.
* Also flushes branch target cache.
*/
asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r"(0));
/* Invalidate entire branch predictor array */
asm volatile("mcr p15, 0, %0, c7, c5, 6" : : "r"(0));
/* Full system DSB - make sure that the invalidation is complete */
dsb();
/* ISB - make sure the instruction stream sees it */
isb();
}
#else
static void invalidate_icache_all(void)
{
}
#endif
u32 get_timestamp_count(void)
{
return __raw_readl(TIMESTAMP_CNT_ADDR);
}
void update_timestamp_count(u32 cnt)
{
__raw_writel(cnt, TIMESTAMP_CNT_ADDR);
}
static u64 stopwatch_get_running_timer(void)
{
writel(1 << 2, STOPWATCH_CTRL_REG2);
udelay(4);
u64 value = readl(STOPWATCH_RUNNING_VALUE_REG);
value += (u64)readl(STOPWATCH_RUNNING_VALUE_REG_H) << 32;
return value;
}
void timestamp_init(void)
{
update_timestamp_count(0);
}
void timestamp_mark(const char *func, u32 line, u32 type)
{
#define timestamp_get_time() stopwatch_get_running_timer()
u64 stamp = timestamp_get_time();
u32 cnt = get_timestamp_count();
if (cnt >= TIMESTAMP_MAX_ITEM_CNT) {
uart_early_puts("No timestamp item!\n");
return;
}
timestamp_item *item =
(timestamp_item *)(uintptr_t)TIMESTAMP_ITEM_START_ADDR;
item[cnt].stamp = stamp;
item[cnt].func = (char *)func;
item[cnt].line = line;
item[cnt].type = type;
cnt++;
update_timestamp_count(cnt);
}
/******************************************************************************/
void start_armboot(void)
{
#ifdef CONFIG_LOTUS_GZIP_BOOT
unsigned char *dst = NULL;
unsigned int image_data_len;
int dst_len;
int ret;
int i;
char *p = NULL;
char *q = NULL;
/* timestamp_init(); */
info("\r\nUncompress ");
TIME_STAMP(0);
/* use direct address mode */
hw_dec_type = 0;
/* init hw decompress IP */
hw_dec_init();
step(35);
/* start decompress */
dst = (unsigned char *)image_entry;
image_data_len = input_data_end - input_data;
/* get dets length from compress image */
p = (char *)&dst_len;
q = (char *)(input_data_end - GZIP_SIZE_OFFSET);
for (i = 0; i < sizeof(int); i++)
p[i] = q[i];
ret = hw_dec_decompress(dst, &dst_len, input_data,
image_data_len, NULL);
if (!ret) {
info("Ok!");
} else {
error("Fail!");
while (1);
}
info("\r\n");
step(36);
/* uinit hw decompress IP */
hw_dec_uinit();
#else
uart_early_puts(" OK, non-compressed boot!\n");
#endif
TIME_STAMP(0);
step(36);
void (*uboot)(void);
uboot = (void (*))CONFIG_SYS_TEXT_BASE;
invalidate_icache_all();
step(37);
uboot();
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
.section .tail,#alloc
.align 9 /* align to 0x200 */
.globl _checked_area_end
_checked_area_end:
/* boot code area signature */
_boot_sign_area:
.word CONFIG_BOOT_CODE_AREA_MAGIC
.fill 0x1FC,1,0 /* align to the signature size: 512 bytes */
.globl _total_boot_area_end
_total_boot_area_end:
_lbist_test_pattern:
.incbin CONFIG_LBIST_TEST_PATTERN_IMAGE
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: GPL-2.0
#include <config.h>
#include <div64.h>
#include <linux/io.h>
#include <asm/arch/platform.h>
static struct {
unsigned int timebase_l;
unsigned int timebase_h;
} timebase;
/* Returns tick rate in ticks per second */
unsigned long get_tbclk(void)
{
return CONFIG_SYS_TIMER_RATE;
}
unsigned long timer_read_counter(void)
{
return ~readl(CONFIG_SYS_TIMER_COUNTER);
}
unsigned long long get_ticks(void)
{
unsigned long now = timer_read_counter();
/* increment tbu if tbl has rolled over */
if (now < timebase.timebase_l)
timebase.timebase_h++;
timebase.timebase_l = now;
return ((unsigned long long)timebase.timebase_h << 32) | timebase.timebase_l;
}
unsigned long long usec_to_tick(unsigned long usec)
{
uint64_t tick = usec;
tick *= get_tbclk();
do_div(tick, 1000000);
return tick;
}
void udelay(unsigned long usec)
{
uint64_t tmp;
tmp = get_ticks() + usec_to_tick(usec);
while (get_ticks() < tmp+1)
;
}
int timer_init(void)
{
writel(0, TIMER0_REG_BASE + REG_TIMER_CONTROL);
writel(~0, TIMER0_REG_BASE + REG_TIMER_RELOAD);
writel(CFG_TIMER_CTRL, TIMER0_REG_BASE + REG_TIMER_CONTROL);
return 0;
}
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __EARLY_TIME_H__
#define __EARLY_TIME_H__
int timer_init(void);
void udelay(unsigned long usec);
unsigned long long get_ticks(void);
#endif /* ifndef __EARLY_TIME_H__ */
@@ -0,0 +1,47 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
__image_copy_start =.;
. = ALIGN(4);
.text :
{
__text_start = .;
start.o (.text*)
uart.o (.text*)
image_data.o (.text*)
startup.o(.text*)
reset.o(.text*)
*(.text*)
}
__text_end = .;
. = ALIGN(4);
.image : { *(.image) }
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = ALIGN(4);
.tail :
{
tail.o (.tail)
}
. = ALIGN(4);
__image_copy_end =.;
__bss_start = .;
.bss : { *(.bss) }
__bss_end = .;
_end = .;
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
@******************************************************************************
@
@ void uart_early_init(void);
@
.text
.align 2
.global uart_early_init
.type uart_early_init, %function
uart_early_init:
#ifndef CONFIG_LOTUS_DISABLE_EARLY_UART
ldr a4, uart_base_addr_L0
mov a3, #0
/* Disable UART */
str a3, [a4, #48]
/* Set baud rate to 115200, uart clock:24M */
add a3, a3, #13
str a3, [a4, #36]
mov a3, #1
str a3, [a4, #40]
/* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. */
ldr a3, =112
str a3, [a4, #44]
/* Enable UART */
ldr a3, =769
str a3, [a4, #48]
#endif
bx lr
uart_base_addr_L0:
.word CONFIG_CUR_UART_BASE
@******************************************************************************
@
@ void uart_early_puts(const char *ss);
@
.align 2
.global uart_early_puts
.type uart_early_puts, %function
uart_early_puts:
#ifndef CONFIG_LOTUS_DISABLE_EARLY_UART
ldr a2, uart_base_addr_L1
b next_char
output:
ldr a4, [a2, #24]
tst a4, #32
bne output
str a3, [a2, #0]
add a1, a1, #1
next_char:
ldrb a3, [a1]
cmp a3, #0
bne output
#endif /* CONFIG_LOTUS_DISABLE_EARLY_UART */
bx lr
uart_base_addr_L1:
.word CONFIG_CUR_UART_BASE
@******************************************************************************
@
@ void uart_early_put_hex(int hex);
@
@ call example:
@ mov r0, sp
@ bl uart_early_put_hex
@
.align 2
.global uart_early_put_hex
.type uart_early_put_hex, %function
uart_early_put_hex:
ldr a2, uart_base_addr_L2
mov a3, #28
wait2:
ldr a4, [a2, #24]
tst a4, #32
bne wait2
mov a4, #0xF
and a4, a4, a1, lsr a3
cmp a4, #9
addle a4, a4, #0x30 @ a4 = a4 + '0'
addgt a4, a4, #55 @ a4 = a4 - 10 + 'A'
str a4, [a2, #0]
cmp a3, #0
beq exit2
sub a3, a3, #4
b wait2
exit2:
bx lr
uart_base_addr_L2:
.word CONFIG_CUR_UART_BASE
@******************************************************************************
@
@ void uart_early_putc(int chr);
@
@ call example:
@ mov r0, #'A'
@ bl uart_early_putc
@
.align 2
.global uart_early_putc
.type uart_early_putc, %function
uart_early_putc:
#ifndef CONFIG_LOTUS_DISABLE_EARLY_UART
ldr a2, uart_base_addr_L3
wait3:
ldr a4, [a2, #24]
tst a4, #32
bne wait3
str a1, [a2, #0]
#endif /* CONFIG_LOTUS_DISABLE_EARLY_UART */
bx lr
uart_base_addr_L3:
.word CONFIG_CUR_UART_BASE
@@ -0,0 +1,15 @@
if TARGET_XMORCA
# config SYS_BOARD
# default "xmorca"
#
# config SYS_VENDOR
# default "lotus"
config SYS_SOC
default "xmorca"
config SYS_CONFIG_NAME
default "xmorca"
endif
@@ -0,0 +1,3 @@
obj-y += chip.o
obj-y += board.o
@@ -0,0 +1,263 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
#include <common.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
#include <spi_flash.h>
#include <linux/mtd/mtd.h>
#include <nand.h>
#include <netdev.h>
#include <mmc.h>
#include <asm/sections.h>
#include <sdhci.h>
#include <linux/lotus/common.h>
#include <asm/mach-types.h>
#include <env_internal.h>
#include <linux/lotus/chip.h>
#include <linux/lotus/timestamp.h>
#ifndef CONFIG_SYS_DCACHE_OFF
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
#endif
static int boot_media __section(.data) = BOOT_MEDIA_UNKNOWN;
int get_boot_media(void)
{
unsigned int reg_val, boot_mode;
if (boot_media != BOOT_MEDIA_UNKNOWN)
return boot_media;
reg_val = readl(SYS_CTRL_REG_BASE + REG_SYSSTAT);
boot_mode = get_sys_boot_mode(reg_val);
switch (boot_mode) {
case BOOT_FROM_SPI_NOR:
boot_media = BOOT_MEDIA_SPIFLASH;
break;
case BOOT_FROM_SPI_NAND:
boot_media = BOOT_MEDIA_NAND;
break;
case BOOT_FROM_EMMC_4BITS:
case BOOT_FROM_EMMC_8BITS:
boot_media = BOOT_MEDIA_EMMC;
break;
default:
boot_media = BOOT_MEDIA_UNKNOWN;
break;
}
return boot_media;
}
void show_boot_media(void)
{
puts("Boot Media: ");
switch (boot_media) {
case BOOT_MEDIA_SPIFLASH:
puts("SPI Nor");
break;
case BOOT_MEDIA_NAND:
puts("SPI Nand");
break;
case BOOT_MEDIA_EMMC:
puts("eMMC");
break;
default:
puts("Unknown");
break;
}
puts("\r\n");
}
#if defined(CONFIG_SHOW_BOOT_PROGRESS)
void show_boot_progress(int progress)
{
printf("Boot reached stage %d\n", progress);
}
#endif
int board_early_init_f(void)
{
return 0;
}
int misc_init_r(void)
{
#ifdef CONFIG_RANDOM_ETHADDR
random_init_r();
#endif
env_set("verify", "n");
return 0;
}
void show_chip_info(void)
{
u32 chip_id = get_chipid();
printf("Chip ID: 0x%X\n", chip_id);
}
int board_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->bd->bi_arch_number = MACH_TYPE_LOTUS;
gd->bd->bi_boot_params = CFG_BOOT_PARAMS;
get_boot_media();
show_boot_media();
show_chip_info();
return 0;
}
u64 get_ddr_size(void)
{
return readl(REG_BASE_SCTL + REG_SC_DDRT12);
}
int dram_init(void)
{
DECLARE_GLOBAL_DATA_PTR;
gd->ram_size = get_ddr_size();
return 0;
}
void board_add_ram_info(int use_default)
{
#ifdef CONFIG_SYS_MEM_TOP_HIDE
putc('(');
print_size(CONFIG_SYS_MEM_TOP_HIDE, "");
puts(" Reserved)");
#endif
}
void reset_cpu(ulong addr)
{
stopwatch_clear();
/* Wait uart fifo flushed */
mdelay(100);
/* 0x12345678:writing any value will cause a reset. */
writel(0x12345678, SYS_CTRL_REG_BASE + REG_SC_SYSRES);
mdelay(100);
puts("Reset Failed, Hang!\n");
while (1);
}
int timer_init(void)
{
/*
* Under uboot, 0xffffffff is set to load register,
* timer_clk equals BUSCLK/2/256.
* e.g. BUSCLK equals 50M, it will roll back after 0xffffffff/timer_clk
* 43980s equals 12hours
*/
__raw_writel(0, TIMER0_REG_BASE + REG_TIMER_CONTROL);
__raw_writel(~0, TIMER0_REG_BASE + REG_TIMER_RELOAD);
/* 32 bit, periodic */
__raw_writel(CFG_TIMER_CTRL, TIMER0_REG_BASE + REG_TIMER_CONTROL);
return 0;
}
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_NET_FEMAC
rc = bspeth_initialize(bis);
#endif
#ifdef CONFIG_FTGMAC030
rc = ftgmac030_initialize(bis);
#endif
return rc;
}
#ifdef CONFIG_GENERIC_MMC
int board_mmc_init(bd_t *bis)
{
int ret = 0;
#ifdef CONFIG_LOTUS_SDHCI
int dev_num = 0;
if (get_boot_media() == BOOT_MEDIA_EMMC) {
ret = sdhci_add_port(dev_num, EMMC_BASE_REG, MMC_TYPE_MMC);
if (!ret) {
ret = lotus_mmc_init(dev_num);
if (ret)
printf("No EMMC device found !\n");
}
dev_num++;
}
#ifdef CONFIG_AUTO_SD_UPDATE
ret = sdhci_add_port(dev_num, SDIO0_BASE_REG, MMC_TYPE_SD);
if (ret)
return ret;
ret = lotus_mmc_init(dev_num);
if (ret)
printf("No SD device found !\n");
#endif
#endif
return ret;
}
#endif
enum env_location env_get_location(enum env_operation op, int prio)
{
int boot_media = get_boot_media();
enum env_location loc;
if (prio)
return ENVL_UNKNOWN;
#ifdef CONFIG_ENV_IS_NOWHERE
return ENVL_NOWHERE;
#endif
switch (boot_media) {
case BOOT_MEDIA_SPIFLASH:
loc = ENVL_SPI_FLASH;
break;
case BOOT_MEDIA_NAND:
loc = ENVL_NAND;
break;
case BOOT_MEDIA_EMMC:
loc = ENVL_MMC;
break;
default:
loc = ENVL_UNKNOWN;
break;
}
return loc;
}
#ifdef CONFIG_BOOT_CONSOLE_OPTIONAL
uint32_t boot1_size __attribute__((section(".data")));
void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
{
asm volatile (
"ldr r4, =boot1_size\n"
"str r0, [r4]\n"
"b save_boot_params_ret\n"
);
}
#endif
@@ -0,0 +1,15 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch/platform.h>
unsigned int g_cpu_chipid = 0;
unsigned int get_chipid(void)
{
if (g_cpu_chipid == 0)
g_cpu_chipid = readl(REG_SC_CHIPID);
return g_cpu_chipid;
}
@@ -0,0 +1,163 @@
################################################################################
SHELL := /bin/bash
PWD = $(shell pwd)
HW_CROSS_COMPILE = $(CROSS_COMPILE)
BOOT_TOPDIR ?= $(PWD)/../../../../../
BOOT_OUTDIR ?= $(BOOT_TOPDIR)
include $(BOOT_OUTDIR)/include/autoconf.mk
include $(BOOT_OUTDIR)/include/config/auto.conf
GZIP ?= $(if $(wildcard $(BOOT_TOPDIR)/../../../tools/utils/bin/gzip), $(BOOT_TOPDIR)/../../../tools/utils/bin/gzip, $(BOOT_TOPDIR)/tools/gzip)
SOC := xmorca
SRCDIR := $(PWD)
################################################################################
CC := $(HW_CROSS_COMPILE)gcc
AR := $(HW_CROSS_COMPILE)ar
LD := $(HW_CROSS_COMPILE)ld
OBJCOPY := $(HW_CROSS_COMPILE)objcopy
################################################################################
.PHONY: all $(BOOT).bin
BOOT := u-boot
TEXTBASE := $(CONFIG_SYS_TEXT_BASE_ORI)
CFLAGS :=-Os -fno-builtin -ffreestanding \
-D__KERNEL__ -DTEXT_BASE=$(TEXTBASE) \
-I$(BOOT_TOPDIR)/include \
-I$(BOOT_OUTDIR)/include \
-I$(BOOT_TOPDIR)/arch/arm/include \
-I$(BOOT_TOPDIR)/lib/hw_dec \
-fno-pic -ffunction-sections \
-fdata-sections -fno-common -ffixed-r9 \
-fno-common -pipe -march=armv7-a \
-Wall -Wstrict-prototypes -fno-stack-protector \
-D__LINUX_ARM_ARCH__=7 -D__ARM__ \
-DCONFIG_MMC\
$(MKFLAGS) -fno-strict-aliasing \
$(EXTRA_CFLAGS) \
UBOOT_Z_LDS := u-boot.lds
################################################################################
START := start.o
COBJS := uart.o \
startup.o \
image_data.o \
reset.o \
exceptions.o \
time.o \
tail.o
SSRC := \
lotus/hw_dec/hw_decompress.c \
lotus/hw_dec/hw_decompress_$(SOC).c \
lotus/hw_dec/hw_decompress_v1.c \
lotus/hw_dec/hw_decompress_v1.h \
SRC := $(notdir $(SSRC))
REG := $(wildcard *.reg .reg)
IMAGE_DATA_Z := image_data.gzip
CFLAGS += -DCONFIG_BOOTREG_DEFAULT=\"$(BOOT_OUTDIR)/.reg\"
CFLAGS += -DCONFIG_AUXIMAGE=\"$(SRCDIR)/auxcode$(if $(CONFIG_LOTUS_FPGA),_fpga,).bin\"
CFLAGS += -DCONFIG_AUXCODE_2048_ENABLE=y
CFLAGS += -DCONFIG_MCU_FW_IMAGE=\"$(if $(wildcard $(BOOT_OUTDIR)/qs_mcu.bin),$(BOOT_OUTDIR)/qs_mcu.bin,$(SRCDIR)/qs_mcu.bin)\"
################################################################################
.PHONY: all $(BOOT).bin
all: $(BOOT).bin
ifeq ($(CONFIG_BOOT_CONSOLE_OPTIONAL),y)
$(BOOT).bin: $(BOOT).tmp
$(Q)cp $(CONFIG_BOOTSTRAP_IMAGE) bootstrap.bin
$(Q)BOOTSTRAP_SIZE=$$(stat -c%s bootstrap.bin); \
printf "%08x" $$BOOTSTRAP_SIZE | tac -rs .. | xxd -r -p > middleware.bin; \
dd if=/dev/zero bs=16 count=1 >> middleware.bin 2>/dev/null; \
printf "%08x" 0xdeadbeef | tac -rs .. | xxd -r -p >> middleware.bin
$(Q)cat $(BOOT).tmp middleware.bin bootstrap.bin > $(BOOT).bin
$(Q)rm -f middleware.bin bootstrap.bin
$(Q)chmod 754 $(BOOT).bin
$(Q)cp -fv $@ $(BOOT_OUTDIR)/u-boot-$(SOC).bin
$(Q)echo "$(BOOT).bin is Ready."
else
$(BOOT).bin: $(BOOT).tmp
$(Q)cat $(BOOT).tmp > $(BOOT).bin
$(Q)chmod 754 $(BOOT).bin
$(Q)cp -fv $@ $(BOOT_OUTDIR)/u-boot-$(SOC).bin
$(Q)echo $(BOOT).bin is Ready.
endif
$(BOOT).tmp: $(BOOT).elf
$(OBJCOPY) -O srec $< $(BOOT).srec
$(OBJCOPY) -j .text -O binary $< $(BOOT).text
$(OBJCOPY) --gap-fill=0xff -O binary $< $@
$(BOOT).elf: $(IMAGE_DATA_Z) $(SRC) $(START) $(COBJS) $(UBOOT_Z_LDS)
$(LD) -Bstatic -T $(UBOOT_Z_LDS) -Ttext $(TEXTBASE) $(START) \
$(COBJS) -Map $(BOOT).map -o $@
$(OBJDUMP) -d $@ > $@.asm
.PHONY: regfile
regfile:
@if [ "$(words $(REG))" = "0" ]; then ( \
echo '***' Need '.reg' or '*.reg' file in directory $(PWD); \
exit 1; \
) fi
@if [ "$(words $(REG))" != "1" ]; then ( \
echo '***' Found multi '.reg' or '*.reg' file in directory $(PWD); \
echo '***' Files: $(notdir $(REG)); \
exit 1; \
) fi
################################################################################
$(START): start.S regfile
$(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c
# -1 : --fast -9 : --best
$(IMAGE_DATA_Z): $(BINIMAGE)
ifneq ($(CONFIG_LOTUS_GZIP_BOOT),)
$(GZIP) -fNqc -7 $< > $@
else
cp $< $@
endif
%.o: %.c
$(CC) $(CFLAGS) -Wall -Wstrict-prototypes \
-fno-stack-protector -o $@ $< -c
%.o: %.S
$(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c
image_data.o: image_data.S $(IMAGE_DATA_Z)
$(CC) -D__ASSEMBLY__ $(CFLAGS) -o $@ $< -c
#############################################################################
$(SRC):
ln -sf $(BOOT_TOPDIR)/$(filter %/$@,$(SSRC)) $@
################################################################################
TMPS := $(COBJS) $(START) $(SRC) \
$(BOOT).map $(BOOT).elf $(BOOT).elf.asm $(BOOT).srec $(BOOT).bin $(BOOT).text $(BOOT).tmp \
$(IMAGE_DATA_Z)
cmd_rm_files = @echo 'RM $(1)';$(shell [[ -n "$(1)" && "$(1)" != "*" ]] && rm -f $(1))
.PHONY: clean distclean
distclean: clean
clean:
$(call cmd_rm_files, $(REG))
$(call cmd_rm_files, $(TMPS))
$(call cmd_rm_files, $(SRC))
################################################################################
.PHONY: clean
FORCE:
################################################################################
@@ -0,0 +1,113 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* exception handlers */
#include <config.h>
.align 2
_irq_stack_start:
.word CONFIG_SYS_INIT_SP_ADDR
.align 2
.global irq_undefined_instruction
.type irq_undefined_instruction, %function
irq_undefined_instruction:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: undefined instruction\r\nLR: \0"
.align 2
.global irq_software_interrupt
.type irq_software_interrupt, %function
irq_software_interrupt:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: software interrupt\r\nLR: \0"
.align 2
.global irq_prefetch_abort
.type irq_prefetch_abort, %function
irq_prefetch_abort:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: prefetch abort\r\nLR: \0"
.align 2
.global irq_data_abort
.type irq_data_abort, %function
irq_data_abort:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: data abort\r\nLR: \0"
.align 2
.global irq_not_used
.type irq_not_used, %function
irq_not_used:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: not used\r\nLR: \0"
.align 2
.global irq_irq
.type irq_irq, %function
irq_irq:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: interrupt\r\nLR: \0"
.align 2
.global irq_firq
.type irq_firq, %function
irq_firq:
ldr sp, _irq_stack_start
mov r10, lr
add r0, pc, #20
bl uart_early_puts
mov r0, r10
bl uart_early_put_hex
mov r0, #2000
bl udelay
bl reset_cpu
.ascii "\r\n*** irq: fast interrupt\r\nLR: \0"
@@ -0,0 +1,9 @@
.section .image,#alloc
.globl input_data
/*gzip source addr must be 16 bytes aligned*/
.balign 16
input_data:
.incbin "image_data.gzip"
.globl input_data_end
input_data_end:
@@ -0,0 +1,21 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
.global reset_cpu
reset_cpu:
mov r0, #10000
bl udelay
ldr r1, rstctl @ get addr for global reset
@ reg
mov r3, #0x2 @ full reset pll + mpu
str r3, [r1] @ force reset
mov r0, r0
_loop_forever:
b _loop_forever
rstctl:
.word SYS_CTRL_REG_BASE + REG_SC_SYSRES
@@ -0,0 +1,422 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <asm-offsets.h>
#include <config.h>
#include <asm/system.h>
#include <linux/linkage.h>
#include <asm/armv7.h>
#include <linux/lotus/step.h>
.globl _start
_start:
/***** Key Area ****/
.=CONFIG_ROOT_RSA_PUB_KEY_N_POS
b _checked_area_start
.fill CONFIG_ROOT_RSA_PUB_KEY_N_LEN - 4, 1, 0
.=CONFIG_ROOT_RSA_PUB_KEY_E_POS
.fill CONFIG_ROOT_RSA_PUB_KEY_E_ZERO_LEN, 1, 0
.=(CONFIG_ROOT_RSA_PUB_KEY_E_POS + CONFIG_ROOT_RSA_PUB_KEY_E_ZERO_LEN)
.word CONFIG_ROOT_RSA_PUB_KEY_E_V
/***** Params Area ****/
.=CONFIG_AUXCODE_AREA_LEN_POS
.word CONFIG_AUXAREA_LEN
.=CONFIG_BOOT_CODE_AREA_LEN_POS
.word _checked_area_end - _checked_area_start
.=CONFIG_TOTAL_BOOT_AREA_LEN_POS
.word (_checked_area_end - _checked_area_start + 0x200)
.=CONFIG_PARAMS_FORM_LEN_POS
.word CONFIG_PARAMS_FORM_LEN
.=CONFIG_BOOT_ENC_FLAG_POS
.word CONFIG_BOOT_ENC_FLAG
.=CONFIG_BOOT_ENTRY_PIONT_POS
.word CONFIG_BOOT_ENTRY_PIONT
.=CONFIG_AUXCODE_AES_IV_POS
.fill 16, 1, 0
.=CONFIG_BOOT_AES_IV_POS
.fill 16, 1, 0
.=CONFIG_PARAMS_FORM_POS
_default_boot_reg_pos:
.incbin CONFIG_BOOTREG_DEFAULT /* reg */
_default_boot_reg_end:
.=CONFIG_LOAD_MCU_FW_FLAG_POS
.word CONFIG_LOAD_MCU_FW_FLAG
.=CONFIG_MCU_FW_AREA_LEN_POS
.word CONFIG_MCU_FW_AREA_LEN
.=CONFIG_MCU_FW_BUF_ADDR_POS
.word CONFIG_MCU_FW_BUF_ADDR
.=CONFIG_DDR_PARAM_OFFSET_POS
.word CONFIG_DDR_PARAM_OFFSET
.=CONFIG_DDR_PARAM_SIZE_POS
.word CONFIG_DDR_PARAM_SIZE
.=CONFIG_AUXCODE_WATCHDOG_POS
.word CONFIG_AUXCODE_WATCHDOG
.=CONFIG_AUXCODE_WDT_TIMEOUT_MSECS_POS
.word CONFIG_AUXCODE_WDT_TIMEOUT_MSECS
.=CONFIG_RESERVED0_POS
.fill CONFIG_RESERVED0_LEN, 1, 0
.=CONFIG_SIG_PARAMS_POS
.fill CONFIG_SIG_PARAMS_LEN, 1, 0
/**** Uncheck Area ****/
.=CONFIG_SCS_SIMULATE_FLAG_POS
.word CONFIG_SCS_SIMULATE_FLAG
.=CONFIG_BOOT_STORE_ADDR_POS
.word CONFIG_BOOT_STORE_ADDR
.=CONFIG_FLASH_EMPYT_FLAG_POS
.word CONFIG_FLASH_EMPYT_FLAG
.=CONFIG_AUXCODE_LOG_CTRL_POS
.word CONFIG_AUXCODE_LOG_CTRL
.=CONFIG_AUXCODE_SVB_CTRL_POS
.word CONFIG_AUXCODE_SVB_CTRL
.=CONFIG_RESERVED1_POS
.fill CONFIG_RESERVED1_LEN, 1, 0
/**** Auxcode Area *****/
.=CONFIG_IMAGE_INFO_POS
.incbin CONFIG_AUXIMAGE
/* mcu fw */
#if (CONFIG_MCU_FW_AREA_LEN > 0)
.=CONFIG_MCU_FW_AREA_POS
.incbin CONFIG_MCU_FW_IMAGE
#endif
/**** Boot Code Area *****/
.=CONFIG_BOOT_CODE_AREA_POS
.align 4
_checked_area_start:
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
.balignl 64,0xdeadbeef
_undefined_instruction: .word irq_undefined_instruction
_software_interrupt: .word irq_software_interrupt
_prefetch_abort: .word irq_prefetch_abort
_data_abort: .word irq_data_abort
_not_used: .word irq_not_used
_irq: .word irq_irq
_fiq: .word irq_firq
.globl reset
.globl save_boot_params_ret
/* fix text_base,real code position */
.globl _TEXT_BASE
_TEXT_BASE:
.word TEXT_BASE + CONFIG_KEY_AREA_LEN + CONFIG_AUXAREA_LEN
_start_armboot:
.word start_armboot
_bss_start:
.word __bss_start
_bss_end:
.word __bss_end
.globl __checked_area_start
__checked_area_start:
.word _checked_area_start
reset:
step_no_stack 30, r11, r12
/* Allow the board to save important registers */
b save_boot_params
save_boot_params_ret:
/*
* 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 V=0 in CP15 SCTLR register - for VBAR to point to vector */
mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
bic r0, #CR_V @ V = 0
mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
/* Set vector address in CP15 VBAR register */
adrl r0, _checked_area_start
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_cp15
#endif
normal_start_flow:
/* Early init */
ldr sp, =CONFIG_SYS_INIT_SP_ADDR
step 31
bl timer_init
bl timestamp_init
bl uart_early_init
bl msg_main_cpu_startup
#ifndef CONFIG_SYS_ICACHE_OFF
@enable I-Cache now
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */
mcr p15, 0, r0, c1, c0, 0
#endif
step 32
#ifndef CONFIG_LOTUS_GZIP_BOOT
/* move uboot to final text base */
ldr r1, =CONFIG_SYS_TEXT_BASE
ldr r0, =input_data
ldr r3, =input_data_end
sub r2, r3, r0
/* memcpy(r1, r0, r2) */
bl memcpy
#endif
step 33
clear_bss:
/* clean .bss section */
ldr r0, _bss_start
ldr r1, _bss_end
mov r2, #0x0
next_bss:
str r2, [r0] @ clear BSS location
cmp r0, r1 @ are we at the end yet
add r0, r0, #4 @ increment clear index pointer
bne next_bss @ keep clearing till at end
step 34
relocate:
ldr r0, =_start_armboot
ldr pc, [r0]
bug:
nop
nop
nop
nop
nop
nop
nop
nop
b . /* bug here */
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@
@ void memcpy(r1, r0, r2);
@
.align 2
memcpy:
add r2, r0, r2
memcpy_loop:
ldmia r0!, {r3 - r10}
stmia r1!, {r3 - r10}
cmp r0, r2
ble memcpy_loop
mov pc, lr
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.align 2
msg_main_cpu_startup:
mov r5, lr
add r0, pc, #4
bl uart_early_puts
mov pc, r5
L10:
.ascii "\r\n\r\nSystem startup\r\n\0"
/*------------------------------------------------------------------------------*/
ENTRY(c_runtime_cpu_setup)
/*
* If I-cache is enabled invalidate it
*/
#ifndef CONFIG_SYS_ICACHE_OFF
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
#endif
bx lr
ENDPROC(c_runtime_cpu_setup)
/*************************************************************************
*
* void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
* __attribute__((weak));
*
* Stack pointer is not yet initialized at this moment
* Don't save anything to stack even if compiled with -O0
*
*************************************************************************/
ENTRY(save_boot_params)
b save_boot_params_ret @ back to my caller
ENDPROC(save_boot_params)
.weak save_boot_params
/*************************************************************************
*
* cpu_init_cp15
*
* Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
* CONFIG_SYS_ICACHE_OFF is defined.
*
*************************************************************************/
ENTRY(cpu_init_cp15)
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
mcr p15, 0, r0, c7, c5, 6 @ invalidate BP array
mcr p15, 0, r0, c7, c10, 4 @ DSB
mcr p15, 0, r0, c7, c5, 4 @ ISB
/*
* disable MMU stuff and caches
*/
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, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 11 (Z---) BTB
#ifdef CONFIG_SYS_ICACHE_OFF
bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache
#else
orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache
#endif
mcr p15, 0, r0, c1, c0, 0
#ifdef CONFIG_ARM_ERRATA_716044
mrc p15, 0, r0, c1, c0, 0 @ read system control register
orr r0, r0, #1 << 11 @ set bit #11
mcr p15, 0, r0, c1, c0, 0 @ write system control register
#endif
#if (defined(CONFIG_ARM_ERRATA_742230) || defined(CONFIG_ARM_ERRATA_794072))
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 4 @ set bit #4
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_743622
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 6 @ set bit #6
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_751472
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 11 @ set bit #11
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
#ifdef CONFIG_ARM_ERRATA_761320
mrc p15, 0, r0, c15, c0, 1 @ read diagnostic register
orr r0, r0, #1 << 21 @ set bit #21
mcr p15, 0, r0, c15, c0, 1 @ write diagnostic register
#endif
mov r5, lr @ Store my Caller
mrc p15, 0, r1, c0, c0, 0 @ r1 has Read Main ID Register (MIDR)
mov r3, r1, lsr #20 @ get variant field
and r3, r3, #0xf @ r3 has CPU variant
and r4, r1, #0xf @ r4 has CPU revision
mov r2, r3, lsl #4 @ shift variant field for combined value
orr r2, r4, r2 @ r2 has combined CPU variant + revision
#ifdef CONFIG_ARM_ERRATA_798870
cmp r2, #0x30 @ Applies to lower than R3p0
bge skip_errata_798870 @ skip if not affected rev
cmp r2, #0x20 @ Applies to including and above R2p0
blt skip_errata_798870 @ skip if not affected rev
mrc p15, 1, r0, c15, c0, 0 @ read l2 aux ctrl reg
orr r0, r0, #1 << 7 @ Enable hazard-detect timeout
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_l2aux_ctrl
isb @ Recommended ISB after l2actlr update
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_798870:
#endif
#ifdef CONFIG_ARM_ERRATA_801819
cmp r2, #0x24 @ Applies to lt including R2p4
bgt skip_errata_801819 @ skip if not affected rev
cmp r2, #0x20 @ Applies to including and above R2p0
blt skip_errata_801819 @ skip if not affected rev
mrc p15, 0, r0, c0, c0, 6 @ pick up REVIDR reg
and r0, r0, #1 << 3 @ check REVIDR[3]
cmp r0, #1 << 3
beq skip_errata_801819 @ skip erratum if REVIDR[3] is set
mrc p15, 0, r0, c1, c0, 1 @ read auxilary control register
orr r0, r0, #3 << 27 @ Disables streaming. All write-allocate
@ lines allocate in the L1 or L2 cache.
orr r0, r0, #3 << 25 @ Disables streaming. All write-allocate
@ lines allocate in the L1 cache.
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_801819:
#endif
#ifdef CONFIG_ARM_ERRATA_454179
cmp r2, #0x21 @ Only on < r2p1
bge skip_errata_454179
mrc p15, 0, r0, c1, c0, 1 @ Read ACR
orr r0, r0, #(0x3 << 6) @ Set DBSM(BIT7) and IBE(BIT6) bits
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_454179:
#endif
#ifdef CONFIG_ARM_ERRATA_430973
cmp r2, #0x21 @ Only on < r2p1
bge skip_errata_430973
mrc p15, 0, r0, c1, c0, 1 @ Read ACR
orr r0, r0, #(0x1 << 6) @ Set IBE bit
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_430973:
#endif
#ifdef CONFIG_ARM_ERRATA_621766
cmp r2, #0x21 @ Only on < r2p1
bge skip_errata_621766
mrc p15, 0, r0, c1, c0, 1 @ Read ACR
orr r0, r0, #(0x1 << 5) @ Set L1NEON bit
push {r1-r5} @ Save the cpu info registers
bl v7_arch_cp15_set_acr
pop {r1-r5} @ Restore the cpu info - fall through
skip_errata_621766:
#endif
mov pc, r5 @ back to my caller
ENDPROC(cpu_init_cp15)
@@ -0,0 +1,169 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
#include <linux/kconfig.h>
#include <asm/io.h>
#include <compiler.h>
#include <linux/lotus/common.h>
#include <linux/lotus/timestamp.h>
#include <linux/lotus/step.h>
#include "time.h"
const uintptr_t image_entry = (CONFIG_SYS_TEXT_BASE);
extern char __image_copy_start[];
extern char __image_copy_end[];
#ifndef CONFIG_LOTUS_DISABLE_CONSOLE
#define info(_s) uart_early_puts(_s)
#else
#define info(_s)
#endif
#define error(_s) uart_early_puts(_s)
#define putstr(_s) uart_early_puts(_s)
#include "hw_decompress.c"
#define GZIP_SIZE_OFFSET 0x4
#ifndef CONFIG_SYS_ICACHE_OFF
/* Invalidate entire I-cache and branch predictor array */
static void invalidate_icache_all(void)
{
/*
* Invalidate all instruction caches to PoU.
* Also flushes branch target cache.
*/
asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r"(0));
/* Invalidate entire branch predictor array */
asm volatile("mcr p15, 0, %0, c7, c5, 6" : : "r"(0));
/* Full system DSB - make sure that the invalidation is complete */
dsb();
/* ISB - make sure the instruction stream sees it */
isb();
}
#else
static void invalidate_icache_all(void)
{
}
#endif
u32 get_timestamp_count(void)
{
return __raw_readl(TIMESTAMP_CNT_ADDR);
}
void update_timestamp_count(u32 cnt)
{
__raw_writel(cnt, TIMESTAMP_CNT_ADDR);
}
static u64 stopwatch_get_running_timer(void)
{
writel(1 << 2, STOPWATCH_CTRL_REG2);
udelay(4);
u64 value = readl(STOPWATCH_RUNNING_VALUE_REG);
value += (u64)readl(STOPWATCH_RUNNING_VALUE_REG_H) << 32;
return value;
}
void timestamp_init(void)
{
update_timestamp_count(0);
}
void timestamp_mark(const char *func, u32 line, u32 type)
{
#define timestamp_get_time() stopwatch_get_running_timer()
u64 stamp = timestamp_get_time();
u32 cnt = get_timestamp_count();
if (cnt >= TIMESTAMP_MAX_ITEM_CNT) {
uart_early_puts("No timestamp item!\n");
return;
}
timestamp_item *item =
(timestamp_item *)(uintptr_t)TIMESTAMP_ITEM_START_ADDR;
item[cnt].stamp = stamp;
item[cnt].func = (char *)func;
item[cnt].line = line;
item[cnt].type = type;
cnt++;
update_timestamp_count(cnt);
}
/******************************************************************************/
void start_armboot(void)
{
uint32_t uboot_bin_size = 0;
#ifdef CONFIG_BOOT_CONSOLE_OPTIONAL
uboot_bin_size = (uint32_t)__image_copy_end - CONFIG_SYS_TEXT_BASE_ORI;
#endif
#ifdef CONFIG_LOTUS_GZIP_BOOT
unsigned char *dst = NULL;
unsigned int image_data_len;
int dst_len;
int ret;
int i;
char *p = NULL;
char *q = NULL;
/* timestamp_init(); */
info("\r\nUncompress ");
TIME_STAMP(0);
/* use direct address mode */
hw_dec_type = 0;
/* init hw decompress IP */
hw_dec_init();
step(35);
/* start decompress */
dst = (unsigned char *)image_entry;
image_data_len = input_data_end - input_data;
/* get dets length from compress image */
p = (char *)&dst_len;
q = (char *)(input_data_end - GZIP_SIZE_OFFSET);
for (i = 0; i < sizeof(int); i++)
p[i] = q[i];
ret = hw_dec_decompress(dst, &dst_len, input_data,
image_data_len, NULL);
if (!ret) {
info("Ok!");
} else {
error("Fail!");
while (1);
}
info("\r\n");
step(36);
/* uinit hw decompress IP */
hw_dec_uinit();
#else
uart_early_puts(" OK, non-compressed boot!\n");
#endif
TIME_STAMP(0);
step(36);
void (*uboot)(uint32_t);
uboot = (void (*))CONFIG_SYS_TEXT_BASE;
invalidate_icache_all();
step(37);
uboot(uboot_bin_size);
}
@@ -0,0 +1,20 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
.section .tail,#alloc
.align 9 /* align to 0x200 */
.globl _checked_area_end
_checked_area_end:
/* boot code area signature */
_boot_sign_area:
.word CONFIG_BOOT_CODE_AREA_MAGIC
.fill 0x1FC,1,0 /* align to the signature size: 512 bytes */
.globl _total_boot_area_end
_total_boot_area_end:
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: GPL-2.0
#include <config.h>
#include <div64.h>
#include <linux/io.h>
#include <asm/arch/platform.h>
static struct {
unsigned int timebase_l;
unsigned int timebase_h;
} timebase;
/* Returns tick rate in ticks per second */
unsigned long get_tbclk(void)
{
return CONFIG_SYS_TIMER_RATE;
}
unsigned long timer_read_counter(void)
{
return ~readl(CONFIG_SYS_TIMER_COUNTER);
}
unsigned long long get_ticks(void)
{
unsigned long now = timer_read_counter();
/* increment tbu if tbl has rolled over */
if (now < timebase.timebase_l)
timebase.timebase_h++;
timebase.timebase_l = now;
return ((unsigned long long)timebase.timebase_h << 32) | timebase.timebase_l;
}
unsigned long long usec_to_tick(unsigned long usec)
{
uint64_t tick = usec;
tick *= get_tbclk();
do_div(tick, 1000000);
return tick;
}
void udelay(unsigned long usec)
{
uint64_t tmp;
tmp = get_ticks() + usec_to_tick(usec);
while (get_ticks() < tmp+1)
;
}
int timer_init(void)
{
writel(0, TIMER0_REG_BASE + REG_TIMER_CONTROL);
writel(~0, TIMER0_REG_BASE + REG_TIMER_RELOAD);
writel(CFG_TIMER_CTRL, TIMER0_REG_BASE + REG_TIMER_CONTROL);
return 0;
}
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __EARLY_TIME_H__
#define __EARLY_TIME_H__
int timer_init(void);
void udelay(unsigned long usec);
unsigned long long get_ticks(void);
#endif /* ifndef __EARLY_TIME_H__ */
@@ -0,0 +1,47 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
__image_copy_start =.;
. = ALIGN(4);
.text :
{
__text_start = .;
start.o (.text*)
uart.o (.text*)
image_data.o (.text*)
startup.o(.text*)
reset.o(.text*)
*(.text*)
}
__text_end = .;
. = ALIGN(4);
.image : { *(.image) }
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : { *(.data) }
. = ALIGN(4);
.got : { *(.got) }
. = ALIGN(4);
.tail :
{
tail.o (.tail)
}
. = ALIGN(4);
__image_copy_end =.;
__bss_start = .;
.bss : { *(.bss) }
__bss_end = .;
_end = .;
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) LOTUS. All rights reserved.
*/
#include <config.h>
@******************************************************************************
@
@ void uart_early_init(void);
@
.text
.align 2
.global uart_early_init
.type uart_early_init, %function
uart_early_init:
#ifndef CONFIG_LOTUS_DISABLE_EARLY_UART
ldr a4, uart_base_addr_L0
mov a3, #0
/* Disable UART */
str a3, [a4, #48]
/* Set baud rate to 115200, uart clock:24M */
add a3, a3, #13
str a3, [a4, #36]
mov a3, #1
str a3, [a4, #40]
/* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled. */
ldr a3, =112
str a3, [a4, #44]
/* Enable UART */
ldr a3, =769
str a3, [a4, #48]
#endif
bx lr
uart_base_addr_L0:
.word CONFIG_CUR_UART_BASE
@******************************************************************************
@
@ void uart_early_puts(const char *ss);
@
.align 2
.global uart_early_puts
.type uart_early_puts, %function
uart_early_puts:
#ifndef CONFIG_LOTUS_DISABLE_EARLY_UART
ldr a2, uart_base_addr_L1
b next_char
output:
ldr a4, [a2, #24]
tst a4, #32
bne output
str a3, [a2, #0]
add a1, a1, #1
next_char:
ldrb a3, [a1]
cmp a3, #0
bne output
#endif /* CONFIG_LOTUS_DISABLE_EARLY_UART */
bx lr
uart_base_addr_L1:
.word CONFIG_CUR_UART_BASE
@******************************************************************************
@
@ void uart_early_put_hex(int hex);
@
@ call example:
@ mov r0, sp
@ bl uart_early_put_hex
@
.align 2
.global uart_early_put_hex
.type uart_early_put_hex, %function
uart_early_put_hex:
ldr a2, uart_base_addr_L2
mov a3, #28
wait2:
ldr a4, [a2, #24]
tst a4, #32
bne wait2
mov a4, #0xF
and a4, a4, a1, lsr a3
cmp a4, #9
addle a4, a4, #0x30 @ a4 = a4 + '0'
addgt a4, a4, #55 @ a4 = a4 - 10 + 'A'
str a4, [a2, #0]
cmp a3, #0
beq exit2
sub a3, a3, #4
b wait2
exit2:
bx lr
uart_base_addr_L2:
.word CONFIG_CUR_UART_BASE
@******************************************************************************
@
@ void uart_early_putc(int chr);
@
@ call example:
@ mov r0, #'A'
@ bl uart_early_putc
@
.align 2
.global uart_early_putc
.type uart_early_putc, %function
uart_early_putc:
#ifndef CONFIG_LOTUS_DISABLE_EARLY_UART
ldr a2, uart_base_addr_L3
wait3:
ldr a4, [a2, #24]
tst a4, #32
bne wait3
str a1, [a2, #0]
#endif /* CONFIG_LOTUS_DISABLE_EARLY_UART */
bx lr
uart_base_addr_L3:
.word CONFIG_CUR_UART_BASE