GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
+32
@@ -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"
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+162
@@ -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"
|
||||
+9
@@ -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
|
||||
+415
@@ -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)
|
||||
|
||||
|
||||
+162
@@ -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__ */
|
||||
+47
@@ -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:
|
||||
################################################################################
|
||||
+113
@@ -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"
|
||||
+9
@@ -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)
|
||||
|
||||
|
||||
+169
@@ -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__ */
|
||||
+47
@@ -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
|
||||
Reference in New Issue
Block a user