This commit is contained in:
2025-12-24 17:21:08 +09:00
parent a96323de19
commit 96dc62d8dc
2302 changed files with 455822 additions and 0 deletions

View File

@@ -0,0 +1 @@
build/

View File

@@ -0,0 +1,29 @@
/*
* Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.
*/
;#RWDT
;#R-CarH3 77. RCLK Watchdog Timer
.EQU RWDT_RWTCNT , 0xE6020000 ;#RCLK watchdog timer counter
.EQU RWDT_RWTCSRA , 0xE6020004 ;#RCLK watchdog timer control/status register A
.EQU RWDT_RWTCSRB , 0xE6020008 ;#RCLK watchdog timer control/status register B
;#SystemWDT
;#R-CarH3 78. System Watchdog Timer
.EQU SYSWDT_WTCNT , 0xE6030000 ;#watchdog timer counter
.EQU SYSWDT_WTCSRA , 0xE6030004 ;#watchdog timer control/status register A
.EQU SYSWDT_WTCSRB , 0xE6030008 ;#watchdog timer control/status register B
.EQU PRR , 0xFFF00044 ;#Product Register
.macro STARTFUNC name
.global \name
.func \name
\name:
.endm
.macro ENDFUNC name
.type \name, %function
.endfunc
.endm

View File

@@ -0,0 +1,165 @@
/*
* Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.
*/
;# W0-W30 : 32bit Register (W30=Link Register)
;# X0-X30 : 64bit Register (X30=Link Register)
;# WZR : 32bit Zero Register
;# XZR : 64bit Zero Register
;# WSP : 32bit Stack Pointer
;# SP : 64bit Stack Pointer
.INCLUDE "boot_mon.h"
.ALIGN 4
;# Initialize registers
Register_init:
LDR X0, =0
LDR X1, =0
LDR X2, =0
LDR X3, =0
LDR X4, =0
LDR X5, =0
LDR X6, =0
LDR X7, =0
LDR X8, =0
LDR X9, =0
LDR X10, =0
LDR X11, =0
LDR X12, =0
LDR X13, =0
LDR X14, =0
LDR X15, =0
LDR X16, =0
LDR X17, =0
LDR X18, =0
LDR X19, =0
LDR X20, =0
LDR X21, =0
LDR X22, =0
LDR X23, =0
LDR X24, =0
LDR X25, =0
LDR X26, =0
LDR X27, =0
LDR X28, =0
LDR X29, =0
LDR X30, =0
Set_EnableRAM:
;# LDR X0, =0xE67F0018
;# LDR W1, =0x00000001 ;#Enable DRAM/SECRAM/PUBRAM
;# STR W1, [X0]
MRS X0, CurrentEL
CMP X0, #0x0000000C
BEQ current_EL3
current_EL1:
;# Loader
LDR x0, =__STACKS_END__
;# MSR SP_EL0,x0
;# MSR SP_EL1,x0
;# MSR SP_EL2,x0
MOV sp,x0
MOV x0, #0x50000000
MSR ELR_EL1,x0
;# MSR ELR_EL2,x0
;# MSR ELR_EL3,x0
MOV x0, #0x03C5
MSR SPSR_EL1,x0
;# MSR SPSR_EL2,x0
;# MSR SPSR_EL3,x0
;# Enable cache
;# mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
mrs x0, sctlr_el1
orr x0, x0, #(0x1 << 12)
orr x0, x0, #(0x1 << 1)
orr x0, x0, #(0x1 << 3)
msr sctlr_el1, x0
isb
b bss_clr
current_EL3:
;# Loader
LDR x0, =__STACKS_END__
;# MSR SP_EL0,x0
;# MSR SP_EL1,x0
;# MSR SP_EL2,x0
MOV sp,x0
MOV x0, #0xE38
MSR SCR_EL3, x0
MOV x0, #0x44100000
;# MSR ELR_EL1,x0
;# MSR ELR_EL2,x0
MSR ELR_EL3,x0
MOV x0, #0x03C5
;# MSR SPSR_EL1,x0
;# MSR SPSR_EL2,x0
MSR SPSR_EL3,x0
;# Board Initialize
.ifdef Area0Boot
Init_set_WDT:
LDR W0, =RWDT_RWTCSRA
LDR W1, =0xA5A5A500 ;#Timer disabled
STR W1, [X0]
Init_set_SYSWDT:
LDR W0, =SYSWDT_WTCSRA
LDR W1, =0xA5A5A500 ;#Timer disabled (Enable -> disabled)
STR W1, [X0]
.endif
;# Enable cache
;# mov x1, #(SCTLR_I_BIT | SCTLR_A_BIT | SCTLR_SA_BIT)
mrs x0, sctlr_el3
orr x0, x0, #(0x1 << 12)
orr x0, x0, #(0x1 << 1)
orr x0, x0, #(0x1 << 3)
msr sctlr_el3, x0
isb
/* clear bss section */
bss_clr:
mov X0, #0x0
ldr X1, =__BSS_START__
ldr X2, =__BSS_SIZE__
bss_loop:
subs X2, X2, #4
bcc bss_end
str W0, [X1, X2]
b bss_loop
bss_end:
.ifdef Area0Boot
/* copy data section */
ldr X0, =__DATA_COPY_START__
ldr X1, =__DATA_START__
ldr X2, =__DATA_SIZE__
data_loop:
subs X2, X2, #4
bcc data_end
ldr W3, [X0, X2]
str W3, [X1, X2]
b data_loop
.endif
data_end:
;# BL InitScif
BL Main
mov X1, #0x50000000
BR X1
.END

View File

@@ -0,0 +1,14 @@
/*
* Copyright (c) 2021 Renesas Electronics Corporation. All rights reserved.
*/
#ifndef D_ARMASM_H
#define D_ARMASM_H
void DCacheEnable();
void WriteTCR_EL3(uint64_t data);
void WriteMAIR_EL3(uint64_t data);
void WriteTTBR0_EL3(uint64_t data);
#endif /* D_ARMASM_H */

View File

@@ -0,0 +1,288 @@
/**********************************************************/
/* Sample program : Debug ARM Assembly Program */
/* File Name : d_armasm.s */
/* Copyright (C) Renesas Electronics Corp. 2015. */
/**********************************************************/
.INCLUDE "boot_mon.h"
.ALIGN 4
;# uint32_t MonCp15Mpidr(void);
STARTFUNC MonCp15Mpidr
MRS X0, VMPIDR_EL2 ;# read Multiprocessor ID register
RET
ENDFUNC MonCp15Mpidr
;# uint32_t MonCp15Midr(void);
STARTFUNC MonCp15Midr
MRS X0, VPIDR_EL2 ;# read Processor ID Register
RET
ENDFUNC MonCp15Midr
;# void WriteTCR_EL3( uint64_t data );
;# data[63:39]=RES0
;# data[38][37][36][35][34:32]=TBI1,TBI0,AS,RES0,IPS
;# data[31:30][29:28][27:26][25:24][23][22][21:16]=TG1,SH1,ORGN1,IRGN1,EPD1,A1 ,T1SZ
;# data[15:14][13:12][11:10][09:08][07][06][05:00]=TG0,SH0,ORGN0,IRGN0,EPD0,RES0,T0SZ
STARTFUNC WriteTCR_EL3
MSR TCR_EL3, X0
RET
ENDFUNC WriteTCR_EL3
;# void WriteMAIR_EL3( uint64_t data );
;# data[63:56][55:48][47:40][39:32]=Attr7,Attr6,Attr5,Attr4
;# data[31:24][23:16][15: 8][ 7: 0]=Attr3,Attr2,Attr1,Attr0
STARTFUNC WriteMAIR_EL3
MSR MAIR_EL3, X0
RET
ENDFUNC WriteMAIR_EL3
;# void WriteTTBR0_EL3( uint64_t data );
;# data[63:48]=ASID
;# data[47: 0]=BADDR
STARTFUNC WriteTTBR0_EL3
MSR TTBR0_EL3, X0
RET
ENDFUNC WriteTTBR0_EL3
;# void CleaningAndInvalidateICache(void);
STARTFUNC CleaningAndInvalidateICache
IC IALLUIS
ISB SY
RET
ENDFUNC CleaningAndInvalidateICache
;# Refer: DEN0024A_v8_architecture_PG.pdf
;# void CleaningDCache(void);
STARTFUNC CleaningDCache
MRS X0, CLIDR_EL1
AND W3, W0, #0x07000000 // Get 2 x Level of Coherence
LSR W3, W3, #23
CBZ W3, DC_Finished
MOV W10, #0 // W10 = 2 x cache level
MOV W8, #1 // W8 = constant 0b1
DC_Loop1:
ADD W2, W10, W10, LSR #1 // Calculate 3 x cache level
LSR W1, W0, W2 // extract 3-bit cache type for this level
AND W1, W1, #0x7
CMP W1, #2
B.LT DC_Skip // No data or unified cache at this level
MSR CSSELR_EL1, X10 // Select this cache level
ISB // Synchronize change of CSSELR
MRS X1, CCSIDR_EL1 // Read CCSIDR
AND W2, W1, #7 // W2 = log2(linelen)-4
ADD W2, W2, #4 // W2 = log2(linelen)
UBFX W4, W1, #3, #10 // W4 = max way number, right aligned
CLZ W5, W4 // W5 = 32-log2(ways), bit position of way in DC operand
LSL W9, W4, W5 // W9 = max way number, aligned to position in DC operand
LSL W16, W8, W5 // W16 = amount to decrement way number per iteration
DC_Loop2:
UBFX W7, W1, #13, #15 // W7 = max set number, right aligned
LSL W7, W7, W2 // W7 = max set number, aligned to position in DC operand
LSL W17, W8, W2 // W17 = amount to decrement set number per iteration
DC_Loop3:
ORR W11, W10, W9 // W11 = combine way number and cache number...
ORR W11, W11, W7 // ... and set number for DC operand
DC CSW, X11 // Do data cache clean by set and way
SUBS W7, W7, W17 // Decrement set number
B.GE DC_Loop3
SUBS X9, X9, X16 // Decrement way number
B.GE DC_Loop2
DC_Skip:
ADD W10, W10, #2 // Increment 2 x cache level
CMP W3, W10
DSB SY // Ensure completion of previous cache maintenance operation
B.GT DC_Loop1
DC_Finished:
DSB SY ;# Add DSB
ISB ;# Add ISB
RET
ENDFUNC CleaningDCache
;# Refer: DEN0024A_v8_architecture_PG.pdf
;# uint32_t CleaningAndInvalidateDCache(void);
STARTFUNC CleaningAndInvalidateDCache
MRS X0, CLIDR_EL1
AND W3, W0, #0x07000000 // Get 2 x Level of Coherence
LSR W3, W3, #23
CBZ W3, DCI_Finished
MOV W10, #0 // W10 = 2 x cache level
MOV W8, #1 // W8 = constant 0b1
DCI_Loop1:
ADD W2, W10, W10, LSR #1 // Calculate 3 x cache level
LSR W1, W0, W2 // extract 3-bit cache type for this level
AND W1, W1, #0x7
CMP W1, #2
B.LT DCI_Skip // No data or unified cache at this level
MSR CSSELR_EL1, X10 // Select this cache level
ISB // Synchronize change of CSSELR
MRS X1, CCSIDR_EL1 // Read CCSIDR
AND W2, W1, #7 // W2 = log2(linelen)-4
ADD W2, W2, #4 // W2 = log2(linelen)
UBFX W4, W1, #3, #10 // W4 = max way number, right aligned
CLZ W5, W4 // W5 = 32-log2(ways), bit position of way in DC operand
LSL W9, W4, W5 // W9 = max way number, aligned to position in DC operand
LSL W16, W8, W5 // W16 = amount to decrement way number per iteration
DCI_Loop2:
UBFX W7, W1, #13, #15 // W7 = max set number, right aligned
LSL W7, W7, W2 // W7 = max set number, aligned to position in DC operand
LSL W17, W8, W2 // W17 = amount to decrement set number per iteration
DCI_Loop3:
ORR W11, W10, W9 // W11 = combine way number and cache number...
ORR W11, W11, W7 // ... and set number for DC operand
DC CISW, X11 // Do data cache clean and invalidate by set and way
SUBS W7, W7, W17 // Decrement set number
B.GE DCI_Loop3
SUBS X9, X9, X16 // Decrement way number
B.GE DCI_Loop2
DCI_Skip:
ADD W10, W10, #2 // Increment 2 x cache level
CMP W3, W10
DSB SY // Ensure completion of previous cache maintenance operation
B.GT DCI_Loop1
DCI_Finished:
DSB SY ;# Add DSB
ISB ;# Add ISB
RET
ENDFUNC CleaningAndInvalidateDCache
;# void DCacheEnable(void);
STARTFUNC DCacheEnable
MOV X20, X30 ;# Save LR data to X20
BL SetVmsaTable ;# MMU Table setting
ISB ;# The ISB forces these changes to be seen before the MMU is enabled.
MRS X0, SCTLR_EL3 ;# Read System Control Register configuration data
ORR X0, X0, #1 ;# Set [M] bit and enable the MMU.
ORR X0, X0, #4 ;# Set [C] bit and enable the Data Cache.
DSB SY
MSR SCTLR_EL3, X0 ;# Write System Control Register configuration data
ISB ;# The ISB forces these changes to be seen by the next instruction
MOV X30, X20 ;# Load LR data from X20
RET
ENDFUNC DCacheEnable
;# void DCacheDisable(void);
STARTFUNC DCacheDisable
MOV X20, X30 ;# Save LR data to X20
DSB SY
ISB ;#
MRS X0, SCTLR_EL3 ;#
;# ORR X0, X0, #1 ;# Set [M] bit and enable the MMU.
;# ORR X0, X0, #4 ;# Set [C] bit and enable the Data Cache.
bic X0, X0, #1 ;# Set [M] bit and disable the MMU.
bic X0, X0, #4 ;# Set [C] bit and disable the Data Cache.
DSB SY
MSR SCTLR_EL3, X0 ;#
DSB SY
ISB ;#
BL CleaningDCache
BL CleaningAndInvalidateDCache
DSB SY
ISB ;#
MOV X30, X20 ;# Load LR data from X20
RET
ENDFUNC DCacheDisable
STARTFUNC InterruptDisableDAIF
MRS X0, DAIF ;# Read DAIF
LDR W2, =0xC0 ;# bit[7]:IRQ mask bit, bit[6]:FIQ mask bit
ORR X0,X0,X2 ;# => 0:Exception not masked, 1: Exception masked
MSR DAIF, X0 ;# Write DAIF
RET
ENDFUNC InterruptDisableDAIF
STARTFUNC ReadSCR_EL3
MRS X0, SCR_EL3 ;# Read SCR_EL3
RET
ENDFUNC ReadSCR_EL3
STARTFUNC InterruptDisableSCR_EL3
MRS X0, SCR_EL3 ;# Read SCR_EL3
LDR W2, =0x6 ;# bit[2]:Physical FIQ Routing, bit[1]:Physical IRQ Routing
BIC X0,X0,X2 ;# => 0:Interrupt not taken, 1: Interrupt are taken
MSR SCR_EL3, X0 ;# Write SCR_EL3
RET
ENDFUNC InterruptDisableSCR_EL3
STARTFUNC DropToEl1
MRS X0, HCR_EL2 ;# Read HCR_EL2
LDR W2, =0x80000000 ;# bit[31]:EL1 is AArch64
ORR X0,X0,X2 ;# => 0:Lower levels are all AArch32 1:EL1 is AArch64
MSR HCR_EL2, X0 ;# Write HCR_EL2
MRS X0, SCR_EL3 ;# Read SCR_EL3
LDR W2, =0x400 ;# bit[10]:EL1 is AArch64
ORR X0,X0,X2 ;# => 0:Lower levels are all AArch32 1:EL2/1 are AArch64
MSR SCR_EL3, X0 ;# Write SCR_EL3
LDR W0, =0x3C5 ;# bit[3:0]:EL1h
MSR SPSR_EL3, X0 ;# Write SPSR_EL3
MOV X0, SP
MSR SP_EL1,X0
MOV X0, X30
MSR ELR_EL3,X0
ERET
ENDFUNC DropToEl1
STARTFUNC UpToEl3
LDR W0, =0x3CD ;# bit[3:0]:EL3h
MSR SPSR_EL3, X0 ;# Write SPSR_EL3
MRS X0, SP_EL1 ;# Read SP_EL1
MOV SP, X0
;# MOV X0, X30
;# MRS X0, ELR_EL1 ;# Read ELR_EL1
;# MSR ELR_EL3,X0
RET
ENDFUNC UpToEl3
STARTFUNC ChangeNonSecure
MRS X0, SCR_EL3 ;# Read SCR_EL3
LDR W2, =0x1 ;# bit[0]:Non-secure bit
;# LDR W2, =0x481 ;# bit[0]:Non-secure bit
ORR X0,X0,X2 ;# => 0:Secure, 1:Non-secure
MSR SCR_EL3, X0 ;# Write SCR_EL3
RET
ENDFUNC ChangeNonSecure
STARTFUNC ChangeSecure
MRS X0, SCR_EL3 ;# Read SCR_EL3
LDR W2, =0x0 ;# bit[0]:Non-secure bit
ORR X0,X0,X2 ;# => 0:Secure, 1:Non-secure
MSR SCR_EL3, X0 ;# Write SCR_EL3
RET
ENDFUNC ChangeSecure
;# void SoftDelayAsm(uint32_t count); <20>L<EFBFBD><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56>ON<4F>̏ꍇ<CC8F>A2clock<63><6B>1<EFBFBD><31><EFBFBD>”\ (AArch64)
STARTFUNC SoftDelayAsm ;# <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂܂܌<DC82><DC8C>Z<EFBFBD>Ɏg<C98E>p<EFBFBD><70><EFBFBD><EFBFBD>
SUBS W0, W0, #1 ;# <20>t<EFBFBD><74><EFBFBD>O<EFBFBD><4F><EFBFBD>X<EFBFBD>V<EFBFBD><56><EFBFBD>‚Œ<C282><C28C>Z 1step
BNE SoftDelayAsm ;# R0==0<>ɂȂ<C982><C882>܂Ń<DC82><C583>[<5B>v 1step
RET ;# <20>Ăяo<D18F><6F><EFBFBD><EFBFBD><EFBFBD>ɖ߂<C996>
ENDFUNC SoftDelayAsm
.END

View File

@@ -0,0 +1,11 @@
/*
* Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.
*/
.section writer_stack, "aw", %nobits
.align 5
stacks:
.space (8*1024), 0
.end

View File

@@ -0,0 +1 @@
Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.

View File

@@ -0,0 +1,346 @@
#
# Copyright (c) 2020 Renesas Electronics Corporation. All rights reserved.
#
define add_define
DEFINES += -D$(1)$(if $(value $(1)),=$(value $(1)),)
endef
V=@
# LSI setting common define
RCAR_S4:=0
RCAR_V4H:=1
RCAR_V4M:=2
NORMAL:=0
SECURE:=1
HS400:=0
HS200:=1
HIGH_SPEED:=2
NO_HIGH_SPEED:=3
$(eval $(call add_define,RCAR_S4))
$(eval $(call add_define,RCAR_V4H))
$(eval $(call add_define,RCAR_V4M))
$(eval $(call add_define,NORMAL))
$(eval $(call add_define,SECURE))
$(eval $(call add_define,HS400))
$(eval $(call add_define,HS200))
$(eval $(call add_define,HIGH_SPEED))
$(eval $(call add_define,NO_HIGH_SPEED))
ifneq ("$(FORCE_115200)", "")
$(eval $(call add_define,FORCE_115200))
endif
$(eval $(call add_define,MOBIS_PRK3))
#/* Select LSI("S4" or "V4H" or "V4M")***********************
ifeq ("$(LSI)", "")
LSI = V4H
endif
ifeq (${LSI},V4H)
RCAR_LSI:=${RCAR_V4H}
else
$(error "Error: ${LSI} is not supported.")
endif
$(eval $(call add_define,RCAR_LSI))
ifndef BOOT_MODE
BOOT_MODE:=${NORMAL}
else
ifeq (${BOOT_MODE},NORMAL)
BOOT_MODE:=${NORMAL}
else ifeq (${BOOT_MODE},SECURE)
BOOT_MODE:=${SECURE}
ifeq (${LSI},V4H)
$(eval $(call add_define,TARGET_CORTEX_A))
$(eval $(call add_define,TARGET_DEVICE_V4H))
endif
else
$(error "Error: ${BOOT_MODE} is not supported.")
endif
$(eval $(call add_define,BOOT_MODE))
endif
$(eval $(call add_define,AARCH64))
ifndef EMMC_TRANS_MODE
EMMC_TRANS_MODE:=${HS400}
else
ifeq (${EMMC_TRANS_MODE},HS400)
EMMC_TRANS_MODE:=${HS400}
else ifeq (${EMMC_TRANS_MODE},HS200)
EMMC_TRANS_MODE:=${HS200}
else ifeq (${EMMC_TRANS_MODE},HIGH_SPEED)
EMMC_TRANS_MODE:=${HIGH_SPEED}
else ifeq (${EMMC_TRANS_MODE},NO_HIGH_SPEED)
EMMC_TRANS_MODE:=${NO_HIGH_SPEED}
else
$(error "Error: ${EMMC_TRANS_MODE} is not supported.")
endif
$(eval $(call add_define,EMMC_TRANS_MODE))
endif
RTOS_LOAD_NUM := 1
$(eval $(call add_define,RTOS_LOAD_NUM))
BOOT = ICUMXA
AArch = 64
CPU = -march=armv8-a
AS_NEON =
CC_NEON = # -mgeneral-regs-only
ALIGN = -mstrict-align
AArch32_64 = AArch64
BOOTDIR = AArch64_boot
OUTPUT_DIR = build/release
OBJECT_DIR = build/obj
CROSS_COMPILE ?= aarch64-elf-
MEMORY_DEF = memory_cx_ipl.def
FILE_NAME = $(OUTPUT_DIR)/ca76_loader
INCLUDE_DIR = -I$(BOOTDIR) -I./include -I../V4H_Cx_Loader/include
OUTPUT_FILE = $(FILE_NAME).axf
#Object file
OBJ_FILE_BOOT = \
$(OBJECT_DIR)/boot_mon.o \
$(OBJECT_DIR)/stack.o
SRC_FILE := \
main.c \
common/string.c \
common/log/log.c \
common/log/scif.c \
common/timer/generic_timer.c \
loader/loader_main_common.c \
image_load/image_load.c
SRC_FILE += \
ip/emmc/emmc_boot.c \
ip/emmc/emmc_cmd.c \
ip/emmc/emmc_init.c \
ip/emmc/emmc_interrupt.c \
ip/emmc/emmc_mount.c \
ip/emmc/emmc_multiboot.c \
ip/emmc/emmc_read.c \
ip/emmc/emmc_utility.c
ifeq (${BOOT_MODE},SECURE)
SRC_FILE += secure/secure_boot.c \
secure/src/comm_drv/icum_d_comm_pe.c \
secure/src/icumif_lib/r_icumif.c \
secure/shared/src/mem_info_def.c \
secure/user_api/user_icumif_api.c
INCLUDE_DIR += -Isecure/src/comm_drv -Isecure/src/icumif_lib \
-Isecure/icumif -Isecure/include -Isecure/user_api \
-Isecure/shared/src
endif
ifeq ("$(DCACHE)", "1")
OBJ_FILE_BOOT += $(OBJECT_DIR)/d_armasm.o
SRC_FILE += vmsatable.c
endif
ifeq ("$(BOOT)", "WRITER_WITH_CERT")
SRC_FILE += cert_param.c
endif
###################################################
# Process access protection flag
# 0:Disable 1:Enable
ifndef ACC_PROT_ENABLE
ACC_PROT_ENABLE := 0
$(eval $(call add_define,ACC_PROT_ENABLE))
else
ifeq (${ACC_PROT_ENABLE},0)
$(eval $(call add_define,ACC_PROT_ENABLE))
else ifeq (${ACC_PROT_ENABLE},1)
$(eval $(call add_define,ACC_PROT_ENABLE))
else
$(error "Error:ACC_PROT_ENABLE=${ACC_PROT_ENABLE} is not supported.")
endif
endif
# Debug build
DEBUG:=0
# Process DEBUG flag
$(eval $(call assert_boolean,DEBUG))
$(eval $(call add_define,DEBUG))
ifeq (${DEBUG},0)
$(eval $(call add_define,NDEBUG))
CFLAGS += -Os
else
CFLAGS += -g
endif
# timing measurement
ifeq ("$(MEASURE_TIME)", "")
MEASURE_TIME = 0
else
$(eval $(call add_define,MEASURE_TIME))
# Set log level to Error, so we dont waste time with unnecessary prints
LOG_LEVEL := 1
SRC_FILE += \
common/scmt_checkpoint.c \
common/timer/scmt.c
endif
ifneq ("$(BE_QUIET)", "")
$(eval $(call add_define,BE_QUIET))
endif
# Process OPTEE_LOAD_ENABLE flag
ifeq ($(filter ${LSI},V4H V4M),${LSI})
ifndef OPTEE_LOAD_ENABLE
OPTEE_LOAD_ENABLE := 1
$(eval $(call add_define,OPTEE_LOAD_ENABLE))
else
ifeq (${OPTEE_LOAD_ENABLE},0)
$(eval $(call add_define,OPTEE_LOAD_ENABLE))
else ifeq (${OPTEE_LOAD_ENABLE},1)
$(eval $(call add_define,OPTEE_LOAD_ENABLE))
else
$(error "Error:OPTEE_LOAD_ENABLE=${OPTEE_LOAD_ENABLE} is not supported.")
endif
endif
endif
# Process BL2_LOAD_ENABLE flag
ifeq (${LSI},V4H)
ifndef BL2_LOAD_ENABLE
BL2_LOAD_ENABLE := 1
$(eval $(call add_define,BL2_LOAD_ENABLE))
else
ifeq (${BL2_LOAD_ENABLE},0)
$(eval $(call add_define,BL2_LOAD_ENABLE))
else ifeq (${BL2_LOAD_ENABLE},1)
$(eval $(call add_define,BL2_LOAD_ENABLE))
else
$(error "Error:BL2_LOAD_ENABLE=${BL2_LOAD_ENABLE} is not supported.")
endif
endif
endif
# Process QNX_OS_LOAD_ENABLE flag
ifeq (${LSI},V4H)
ifndef QNX_OS_LOAD_ENABLE
QNX_OS_LOAD_ENABLE := 1
$(eval $(call add_define,QNX_OS_LOAD_ENABLE))
else
ifeq (${QNX_OS_LOAD_ENABLE},0)
$(eval $(call add_define,QNX_OS_LOAD_ENABLE))
else ifeq (${QNX_OS_LOAD_ENABLE},1)
$(eval $(call add_define,QNX_OS_LOAD_ENABLE))
else
$(error "Error:QNX_OS_LOAD_ENABLE=${QNX_OS_LOAD_ENABLE} is not supported.")
endif
endif
endif
# Process LOG_LEVEL
ifndef LOG_LEVEL
LOG_LEVEL := 2
endif
$(eval $(call add_define,LOG_LEVEL))
###################################################
#C compiler
CC = $(CROSS_COMPILE)gcc
#Assembler
AS = $(CROSS_COMPILE)as
#Linker
LD = $(CROSS_COMPILE)ld
#Liblary
AR = $(CROSS_COMPILE)ar
#Object dump
OBJDMP = $(CROSS_COMPILE)objdump
#Object copy
OBJCOPY = $(CROSS_COMPILE)objcopy
#clean
CL = rm -rf
OBJ_FILE := $(addprefix $(OBJECT_DIR)/,$(patsubst %.c,%.o,$(SRC_FILE)))
#Dependency File
DEPEND_FILE = $(patsubst %.lib, ,$(OBJ_FILE:%.o=%.d))
CFLAGS += -ffreestanding -Wall \
-Wmissing-include-dirs \
-std=c99 -c \
-D__CX_IPL__ \
$(DEFINES)
LDFLAGS = --fatal-warnings -O1 -lm
BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
LIBS = -L$(subst libc.a, ,$(shell $(CC) -print-file-name=libc.a 2> /dev/null)) -lc
LIBS += -L$(subst libgcc.a, ,$(shell $(CC) -print-libgcc-file-name 2> /dev/null)) -lgcc
###################################################
# Suffixes
.SUFFIXES : .s .c .o
###################################################
# Command
.PHONY: all
all: $(OBJECT_DIR) $(OUTPUT_DIR) $(OBJ_FILE_BOOT) $(OBJ_FILE) $(OUTPUT_FILE)
#------------------------------------------
# Make Directory
#------------------------------------------
$(OBJECT_DIR):
-mkdir -p "$(OBJECT_DIR)"
$(OUTPUT_DIR):
-mkdir -p "$(OUTPUT_DIR)"
#------------------------------------------
# Compile
#------------------------------------------
$(OBJECT_DIR)/%.o:$(BOOTDIR)/%.s
$(V)$(AS) -g $(AS_NEON) --MD $(patsubst %.o,%.d,$@) \
$(INCLUDE_DIR) $< -o $@ --defsym $(AArch32_64)=0
$(OBJECT_DIR)/%.o:%.c
@if [ ! -e `dirname $@` ]; then mkdir -p `dirname $@`; fi
$(V)$(CC) $(ALIGN) $(CPU) $(CC_NEON) -MMD -MP -c \
$(INCLUDE_DIR) $< -o $@ -D$(AArch32_64)=0 $(DEFINES) $(CFLAGS)
#------------------------------------------
# Linker
#------------------------------------------
$(OUTPUT_FILE): $(OBJ_FILE_BOOT) $(OBJ_FILE) $(MEMORY_DEF)
@echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP);' | \
$(CC) $(CFLAGS) -xc - -o $(OBJECT_DIR)/build_message.o
$(V)$(LD) $(OBJ_FILE_BOOT) $(OBJ_FILE) $(OBJECT_DIR)/build_message.o \
-T '$(MEMORY_DEF)' \
-o '$(OUTPUT_FILE)' \
$(LDFLAGS) \
-Map '$(FILE_NAME).map' \
-static \
$(LIBS)
$(V)$(OBJCOPY) -O srec --srec-forceS3 "$(OUTPUT_FILE)" "$(FILE_NAME).srec"
$(V)$(OBJCOPY) -O binary "$(OUTPUT_FILE)" "$(FILE_NAME).bin"
$(V)$(OBJDMP) -d -S "$(OUTPUT_FILE)" > "$(FILE_NAME)_disasm.txt"
@chmod 644 $(FILE_NAME).*
ifneq ("$(V)", "")
@echo "Build complete: $(OUTPUT_FILE)"
@echo "Output files:"
@echo " - $(FILE_NAME).srec"
endif
.PHONY: clean
clean:
@$(CL) $(OBJECT_DIR)/* $(OUTPUT_DIR)/*
distclean: clean
@$(CL) build
-include $(DEPEND_FILE)

View File

@@ -0,0 +1,16 @@
/*
* Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.
*/
/* 0xE6300400 */
const unsigned int __attribute__ ((section (".boot_param"))) boot_param = 0x00000000;
/* 0xE630048C */
const unsigned int __attribute__ ((section (".cert_offset"))) reserved = 0x00000000;
/* 0xE63005D4 */
const unsigned int __attribute__ ((section (".cert_addr"))) cert_addr = 0xE6304000;
/* 0xE63006E4 */
const unsigned int __attribute__ ((section (".cert_size"))) cert_size = 0x00001000;
/* 0xE6301154 */
const unsigned int __attribute__ ((section (".cert_addr2"))) cert_addr2 = 0xE6304000;
/* 0xE6301264 */
const unsigned int __attribute__ ((section (".cert_size2"))) cert_size2 = 0x00001000;

View File

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.
*/
#ifndef BIT_H
#define BIT_H
#define BIT0 0x00000001
#define BIT1 0x00000002
#define BIT2 0x00000004
#define BIT3 0x00000008
#define BIT4 0x00000010
#define BIT5 0x00000020
#define BIT6 0x00000040
#define BIT7 0x00000080
#define BIT8 0x00000100
#define BIT9 0x00000200
#define BIT10 0x00000400
#define BIT11 0x00000800
#define BIT12 0x00001000
#define BIT13 0x00002000
#define BIT14 0x00004000
#define BIT15 0x00008000
#define BIT16 0x00010000
#define BIT17 0x00020000
#define BIT18 0x00040000
#define BIT19 0x00080000
#define BIT20 0x00100000
#define BIT21 0x00200000
#define BIT22 0x00400000
#define BIT23 0x00800000
#define BIT24 0x01000000
#define BIT25 0x02000000
#define BIT26 0x04000000
#define BIT27 0x08000000
#define BIT28 0x10000000
#define BIT29 0x20000000
#define BIT30 0x40000000
#define BIT31 0x80000000
#endif /* BIT_H */

View File

@@ -0,0 +1,12 @@
/**********************************************************/
/* Sample program : VMSA Table Header */
/* File Name : vmsatable.h */
/* Copyright (C) Renesas Electronics Corp. 2015. */
/**********************************************************/
#ifndef _VMSATABLE_H_
#define _VMSATABLE_H_
uint32_t SetVmsaTable(void);
#endif

View File

View File

View File

@@ -0,0 +1,196 @@
/*
* Copyright (c) 2018-2023 Renesas Electronics Corporation. All rights reserved.
*/
#include <stdio.h>
#include <rcar_def.h>
#include <scif.h>
#include <timer.h>
#include <log.h>
#include "d_armasm.h"
#include <image_load.h>
#include <loader_main.h>
#include <loader_main_common.h>
#include <cpu_on.h>
#include <emmc_def.h>
#include <emmc_boot.h>
#if (BOOT_MODE == SECURE)
#include "secure_boot.h"
#endif /* BOOT_MODE == SECURE */
/* Time analysis */
#if (1 == (MEASURE_TIME))
#include <scmt.h>
#include <scmt_checkpoint.h>
#else
#define scmt_wait_ticks(x)
#define store_time_checkpoint(x,y)
#define print_time_checkpoints(x)
#endif
#include <android_ab.h>
#define _SECURE_BOOT_MARK (0x41DFFFF8U)
#define IS_SECURE_BOOT NORMAL_BOOT
#define OS_LOAD_FAIL (0xBAADF00DU)
extern const uint8_t __RO_START__[1];
extern const uint8_t __STACKS_END__[1];
extern const char build_message[];
void Main(void)
{
uint32_t ca_load_num; /* number of load for CA program */
uint32_t loop;
uint32_t reg; /* store register value */
int slot = 0;
__attribute__((unused))const char *str;
#if (BOOT_MODE == SECURE)
uint32_t bootmode; /* store boot mode */
#endif /* BOOT_MODE == SECURE */
LOAD_INFO li[MAX_PLACED];
#if (RCAR_LSI != RCAR_V4H)
#error "RCAR_V4H only"
#endif
#if (1 == (MEASURE_TIME))
scmt_module_start();
store_time_checkpoint("loader_main", 0);
#endif
/*****************************************************************************
* Initialize Hardware
*****************************************************************************/
/* ip_control/ip_init() */
scif_init();
import_mmc_drv_obj();
store_time_checkpoint("emmc_initialize", 0);
/*****************************************************************************
* Output boot message
*****************************************************************************/
NOTICE("CA76 Loader Program Rev.%s\n", IPL_VERSION);
NOTICE("%s\n", build_message);
/* Get PRR */
reg = mem_read32(PRR);
switch (reg & PRR_PRODUCT_MASK) {
case PRR_PRODUCT_V4H:
str = "V4H";
break;
default:
str = "unknown";
break;
}
NOTICE("PRR is R-Car %s Ver.%d.%d\n", str,
((int)(reg & PRR_MAJOR_MASK) >> PRR_MAJOR_SHIFT)
+ PRR_MAJOR_OFFSET, (int)(reg & PRR_MINOR_MASK));
store_time_checkpoint("init_done", 0);
/*****************************************************************************
* Load Certficate
*****************************************************************************/
/* Load content certificate */
ca_load_num = mem_read32(CONTENT_CERT_DEST_ADDR);
/* Get load information */
load_init(li, ca_load_num);
#if (BOOT_MODE == SECURE)
secureboot_init();
/* LCS judgement for secure boot */
bootmode = judge_bootmode();
if (NORMAL_BOOT != bootmode)
{
/* Content cert certification */
secureboot_verify(li, CA_OPTIONAL_ID, CA_OPTIONAL_ID + ca_load_num);
store_time_checkpoint("verify_cert_done", 0);
#ifdef MOBIS_PRK3
/* because of SECURE_BOOT == 0x0,
we use NORMAL_BOOT as secure boot flag */
mem_write32(_SECURE_BOOT_MARK, IS_SECURE_BOOT);
#endif
}
#endif /* BOOT_MODE == SECURE */
/*****************************************************************************
* Load CA Program#2--#8
*****************************************************************************/
reg = mem_read32(AB_INFO_FLAG_ADDR);
if (reg & AB_INFO_SELECT_2nd)
slot = 1;
NOTICE("slot: %d\n", slot);
load_update_part_num(li, ca_load_num, slot);
/* Start loading CA Program#n image */
for (loop = 0U; loop < ca_load_num; loop++)
{
#ifdef MOBIS_PRK3
if (loop == (CA_BL2_ID - CA_OPTIONAL_ID))
continue;
#endif
/* Loading start */
load_image(&li[CA_OPTIONAL_ID + loop]);
store_time_checkpoint("load_CA_#_done", li[CA_OPTIONAL_ID + loop].image_size);
#if (BOOT_MODE == SECURE)
/* Decryption image and Image certification */
if (NORMAL_BOOT != bootmode)
{
#ifdef MOBIS_PRK3
if (loop == (CA_QNX_OS_ID - CA_OPTIONAL_ID)) {
int ret = secureboot_image(&li[CA_OPTIONAL_ID + loop], 0);
if (ret != 0) {
ERROR("secureboot_image failed for %s\n", li[CA_OPTIONAL_ID + loop].name);
mem_write32(_SECURE_BOOT_MARK, OS_LOAD_FAIL);
}
} else
#endif
secureboot_image(&li[CA_OPTIONAL_ID + loop], 1);
store_time_checkpoint("verify_CA_#_done", 0);
}
#endif /* BOOT_MODE == SECURE */
}
/* Set Secure Monitor parameter */
smoni_set_param(li[CA_OPTIONAL_ID].boot_addr, /* BL31 */
li[CA_OPTIONAL_ID + 1U].boot_addr, /* U-Boot */
li[CA_OPTIONAL_ID + 2U].boot_addr); /* TEE-OS */
/*****************************************************************************
* Exit Hardware
*****************************************************************************/
EMMC_ERROR_CODE result = EMMC_ERR;
result = emmc_terminate();
if(EMMC_SUCCESS != result)
{
ERROR("ip_release error (emmc_terminate).\n");
panic;
}
NOTICE("Load finish.(CA76 Loader)\n");
/*****************************************************************************
* Jump to BL31
*****************************************************************************/
void (*bl31_func)(void);
bl31_func = (void (*)(void))(uintptr_t)li[CA_OPTIONAL_ID].boot_addr;
store_time_checkpoint("Jump to BL31", 0);
print_time_checkpoints();
#if !defined(BE_QUIET) && (LOG_LEVEL < LOG_NOTICE)
log_printf("%s\n", build_message);
#if (BOOT_MODE == SECURE)
if (NORMAL_BOOT != bootmode) {
log_printf("Secure boot(CA76 Loader)\n");
} else {
log_printf("Normal boot(CA76 Loader)\n");
}
#else
log_printf("Boot(CA76 Loader)\n");
#endif
#endif
bl31_func(); /* Jump to BL31 */
}

View File

@@ -0,0 +1,62 @@
MEMORY {
RAM (rwxa): ORIGIN = 0x41D00000, LENGTH = 0x000F8000
MMU_CPU0 : ORIGIN = 0x41DF8000, LENGTH = 16K
SHARED_RAM (rwa): ORIGIN = 0x41C00000, LENGTH = 0x0000C000
SHARED_SDRAM (rwa): ORIGIN = 0x41E00000, LENGTH = 0x00200000
}
SECTIONS
{
.text : {
__RO_START__ = .;
*(.text*)
*(.rodata*)
. = NEXT(64);
__RO_END__ = .;
} > RAM
.data : {
__DATA_START__ = .;
*(.data)
. = NEXT(64);
__DATA_END__ = .;
} > RAM
__DATA_SIZE__ = SIZEOF(.data);
.bss.SHARED_TOP : {
__SHARED_TOP_START__ = .;
*(.bss.SHARED_TOP)
*(.bss.SHARED_LCS)
*(.bss.SHARED_CMAC)
*(.bss.SHARED_HASH)
. = NEXT(0x00200000);
__SHARED__END__ = .;
} > SHARED_SDRAM
.SHARED_RAM : {
__FWRAM_START__ = .;
. += 0;
. = NEXT(0x0000C000);
__FWRAM_END__ = .;
} > SHARED_RAM
.bss : {
__BSS_START__ = .;
*(.bss)
*(COMMON)
. = NEXT(64);
__BSS_END__ = .;
} > RAM
stacks (NOLOAD) : ALIGN(64) {
__STACKS_START__ = .;
KEEP(*(writer_stack))
__STACKS_END__ = .;
} > RAM
__BSS_SIZE__ = SIZEOF(.bss);
}
MMU_BASE_CPU0 = ORIGIN(MMU_CPU0);

View File

@@ -0,0 +1,50 @@
#!/bin/bash
set -e
set -o pipefail
export CROSS_COMPILE=`pwd`/../gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf/bin/aarch64-none-elf-
export LANG=C
_no_clean=0
_loglevel=1
_secure="SECURE"
_build_param=""
_default_b="LSI=V4H FORCE_115200=1 EMMC_TRANS_MODE=HS400 \
OPTEE_LOAD_ENABLE=1 \
BL2_LOAD_ENABLE=1 \
QNX_OS_LOAD_ENABLE=1 \
"
_echo="@"
while getopts "sl:pvcqh" opt; do
case $opt in
s) _secure="NORMAL"
;;
l) _loglevel=$OPTARG
;;
p) _build_param="${_build_param} MEASURE_TIME=1"
;;
v) _echo=""
;;
c) _no_clean=1
;;
q) _build_param="${_build_param} BE_QUIET=1"
;;
h)
echo "usage: $0 [option]"
echo " -s toggle boot_mode (default: $_secure)"
echo " -l set loglevel (default: $_loglevel)"
echo " -p enable MEASURE_TIME"
echo " -q be quiet"
echo ""
echo " -c do not clean before build"
echo " -v build verbosely"
exit 0
esac
done
shift $((OPTIND-1))
if [ $_no_clean -ne 1 ]; then
make clean
fi
BUILD_PARAM="${BUILD_PARAM} ${_build_param} LOG_LEVEL=$_loglevel"
make ${_default_b} ${BUILD_PARAM} BOOT_MODE=$_secure V=$_echo $*

View File

View File

@@ -0,0 +1,284 @@
/**********************************************************/
/* Sample program : VMSA Table Generate */
/* File Name : vmsatable.c */
/* Copyright (C) Renesas Electronics Corp. 2015. */
/**********************************************************/
// #include "common.h"
#include <stdint.h>
#include "vmsatable.h"
#include "d_armasm.h"
#ifdef AArch64
extern const char MMU_BASE_CPU0[];
#endif
#ifdef AArch32
#define MMU_BASE_CPU0 0xE6300000
#endif
#define TBL_SIZE 4096
#define TBL_NUM (TBL_SIZE/8)
#define Lvl1VmsaTbl ((uintptr_t)MMU_BASE_CPU0+0x0000) // +0kB
#define Lvl2VmsaTbl ((uintptr_t)MMU_BASE_CPU0+0x1000) // +4kB
#define Lvl3VmsaTbl ((uintptr_t)MMU_BASE_CPU0+0x2000) // +8kB
#define Lvl1StartAddr (0x0000000000)
#define Lvl1BlockSize (0x0040000000) // 1GB
#define Lvl1BlockShift (30) // BIT30
#define Lvl2StartAddr (0x00C0000000)
#define Lvl2BlockSize (0x0000200000) // 2MB
#define Lvl2BlockShift (21) // BIT21
#define Lvl3StartAddr (0x00E6200000)
#define Lvl3BlockSize (0x0000001000) // 4KB
#define Lvl3BlockShift (12) // BIT12
#define BIT47_12 0x0000FFFFFFFFF000
typedef struct vmsaTable{
uint64_t vAddr;
uint64_t pAddr;
uint64_t unit;
uint64_t upperAttr;
uint64_t lowerAttr;
}vmsaTable;
//------------------------------------------------------------------
// Referenced: DDI0487A_f_armv8_arm.pdf
// D4.4 VMSAv8-64 translation table format descriptors
//------------------------------------------------------------------
#define ATTR_TBL 0x444444FF0C080400 // MAIR_EL1
// // [63:56]Attr7=0x44 : ----------------- (Blank)
// // [55:48]Attr6=0x44 : ----------------- (Blank)
// // [47:40]Attr5=0x44 : NORMAL_NON_CACHEABLE Normal Memory Non-Cacheable
// // [39:32]Attr4=0x77 : NORMAL_WRITE_BACK Normal Memory Write-back transient
// // [31:24]Attr3=0x0C : DEVICE_GRE_MEM Device-GRE memory
// // [23:16]Attr2=0x08 : DEVICE_NGRE_MEM Device-nGRE memory
// // [15: 8]Attr1=0x04 : DEVICE_NGNRE_MEM Device-nGnRE memory
// // [ 7: 0]Attr0=0x00 : DEVICE_NGNRNE_MEM Device-nGnRnE memory
// CPU0 VMSA table Level1 (4kB)
// Virtual address == Physical Address
const vmsaTable ArmVmsaTblLvl1Cpu0ForDDR4ch[] = {
// [MEM]Memory Address ...BIT[1:0]=01
// [TBL]Next Level Table Address ...BIT[1:0]=11
// Virtual Address Physical Address BLOCK Upper Lower Attr
// (Input) or units, Attributes Attributes nG AF SH AP NS Indx [1:0]
// Next Level Table (1GBxN) [63:52] [11:00] [1:0][2:1] [2:0]
{ 0x0000000000, 0x0000000000, 1, 0x000, 0x411 }, // [MEM]CS0/1,PCIe 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0040000000, 0x0040000000, 1, 0x000, 0x411 }, // [MEM]DRAM 1st 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0080000000, 0x0080000000, 1, 0x000, 0x411 }, // [MEM]DRAM 2nd 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x00C0000000, Lvl2VmsaTbl , 1, 0x000, 0x003 }, // [TBL]IPs 1GB 0 0 00 00 0 000 11 (Next Level Table)
{ 0x0400000000, 0x0400000000, 4, 0x000, 0x411 }, // [MEM]DDR0 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0500000000, 0x0500000000, 4, 0x000, 0x411 }, // [MEM]DDR1 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0600000000, 0x0600000000, 4, 0x000, 0x411 }, // [MEM]DDR2 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0700000000, 0x0700000000, 4, 0x000, 0x411 }, // [MEM]DDR3 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0000000000, 0x0000000000, 0, 0x000, 0x000 }, // ---------- END of Table ----------
};
// CPU0 VMSA table Level1 (4kB)
// Virtual address == Physical Address
const vmsaTable ArmVmsaTblLvl1Cpu0ForDDR2ch[] = {
// [MEM]Memory Address ...BIT[1:0]=01
// [TBL]Next Level Table Address ...BIT[1:0]=11
// Virtual Address Physical Address BLOCK Upper Lower Attr
// (Input) or units, Attributes Attributes nG AF SH AP NS Indx [1:0]
// Next Level Table (1GBxN) [63:52] [11:00] [1:0][2:1] [2:0]
{ 0x0000000000, 0x0000000000, 1, 0x000, 0x411 }, // [MEM]CS0/1,PCIe 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0040000000, 0x0040000000, 1, 0x000, 0x411 }, // [MEM]DRAM 1st 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0080000000, 0x0080000000, 1, 0x000, 0x411 }, // [MEM]DRAM 2nd 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x00C0000000, Lvl2VmsaTbl , 1, 0x000, 0x003 }, // [TBL]IPs 1GB 0 0 00 00 0 000 11 (Next Level Table)
{ 0x0400000000, 0x0400000000, 4, 0x000, 0x411 }, // [MEM]DDR0 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0600000000, 0x0600000000, 4, 0x000, 0x411 }, // [MEM]DDR2 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0000000000, 0x0000000000, 0, 0x000, 0x000 }, // ---------- END of Table ----------
};
// CPU0 VMSA table Level1 (4kB)
// Virtual address == Physical Address
const vmsaTable ArmVmsaTblLvl1Cpu0ForDDR1ch[] = {
// [MEM]Memory Address ...BIT[1:0]=01
// [TBL]Next Level Table Address ...BIT[1:0]=11
// Virtual Address Physical Address BLOCK Upper Lower Attr
// (Input) or units, Attributes Attributes nG AF SH AP NS Indx [1:0]
// Next Level Table (1GBxN) [63:52] [11:00] [1:0][2:1] [2:0]
{ 0x0000000000, 0x0000000000, 1, 0x000, 0x411 }, // [MEM]CS0/1,PCIe 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0040000000, 0x0040000000, 1, 0x000, 0x411 }, // [MEM]DRAM 1st 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0080000000, 0x0080000000, 1, 0x000, 0x411 }, // [MEM]DRAM 2nd 1GB 0 1 00 00 0 100 01 (Normal Memory Write-back transient)
{ 0x00C0000000, Lvl2VmsaTbl , 1, 0x000, 0x003 }, // [TBL]IPs 1GB 0 0 00 00 0 000 11 (Next Level Table)
{ 0x0400000000, 0x0400000000, 4, 0x000, 0x411 }, // [MEM]DDR0 4GB 0 1 10 00 0 100 01 (Normal Memory Write-back transient)
{ 0x0000000000, 0x0000000000, 0, 0x000, 0x000 }, // ---------- END of Table ----------
};
// CPU0 VMSA table Level2 (4kB)
// Virtual address == Physical Address
const vmsaTable ArmVmsaTblLvl2Cpu0[] = {
// [MEM]Memory Address ...BIT[1:0]=01
// [TBL]Next Level Table Address ...BIT[1:0]=11
// Virtual Address Physical Address BLOCK Upper Lower Attr
// (Input) or units, Attributes Attributes nG AF SH AP NS Indx [1:0]
// Next Level Table (2MBxN) [63:52] [11:00] [1:0][2:1] [2:0]
{ 0x00E6200000, Lvl3VmsaTbl , 1, 0x000, 0x003 }, // [TBL]IPs 2MB 0 0 00 00 0 000 11 (Next Level Table)
{ 0x00EB200000, 0x00EB200000, 1, 0x000, 0x411 }, // [MEM]RT-SRAM 2MB 0 1 00 00 0 100 01 (Normal Memory Write-back transient) @V3U
{ 0x0000000000, 0x0000000000, 0, 0x000, 0x000 }, // ---------- END of Table ----------
};
#ifdef SYSTEM_DEF_FALCON
// CPU0 VMSA table Level3 (4kB) @V3U CPUボード到着後に上のvmsaTable ArmVmsaTblLvl3Cpu0[]と入れ替え
// Virtual address == Physical Address
const vmsaTable ArmVmsaTblLvl3Cpu0[] = {
// [INV]Invalid ...BIT[1:0]=x0
// [RES]Reserved ...BIT[1:0]=01
// [MEM]Memory Address ...BIT[1:0]=11 <-- Select
// Virtual Address Physical Address BLOCK Upper Lower Attr
// (Input) or units, Attributes Attributes nG AF SH AP NS Indx [1:0]
// Next Level Table (4KBxN) [63:52] [11:00] [1:0][2:1] [2:0]
{ 0x00E6200000, 0x00E6200000, 256, 0x000, 0x403 }, // [MEM]IPs 1MB 0 1 00 00 0 000 11 (Device-nGnRnE memory)
{ 0x00E6300000, 0x00E6300000, 256, 0x000, 0x413 }, // [MEM]SystemRAM 1MB 0 1 00 00 0 100 11 (Normal Memory Write-back transient) @V3U
{ 0x0000000000, 0x0000000000, 0, 0x000, 0x000 }, // ---------- END of Table ----------
};
#else
// CPU0 VMSA table Level3 (4kB) @V3H
// Virtual address == Physical Address
const vmsaTable ArmVmsaTblLvl3Cpu0[] = {
// [INV]Invalid ...BIT[1:0]=x0
// [RES]Reserved ...BIT[1:0]=01
// [MEM]Memory Address ...BIT[1:0]=11 <-- Select
// Virtual Address Physical Address BLOCK Upper Lower Attr
// (Input) or units, Attributes Attributes nG AF SH AP NS Indx [1:0]
// Next Level Table (4KBxN) [63:52] [11:00] [1:0][2:1] [2:0]
{ 0x00E6200000, 0x00E6200000, 256, 0x000, 0x403 }, // [MEM]IPs 1MB 0 1 00 00 0 000 11 (Device-nGnRnE memory)
{ 0x00E6300000, 0x00E6300000, 48, 0x000, 0x413 }, // [MEM]SystemRAM 192KB 0 1 00 00 0 100 11 (Normal Memory Write-back transient)
{ 0x00E6330000, 0x00E6330000, 48, 0x000, 0x413 }, // [MEM]SystemRAM 192KB 0 1 00 00 0 100 11 (Normal Memory Write-back transient)
{ 0x00E6360000, 0x00E6360000, 160, 0x000, 0x403 }, // [MEM]SystemRAM 640KB 0 1 00 00 0 000 11 (Device-nGnRnE memory)
{ 0x0000000000, 0x0000000000, 0, 0x000, 0x000 }, // ---------- END of Table ----------
};
#endif
static void MakeVmsaTable(uint64_t *vmsaTblSadd, vmsaTable *vmsaSrcTbl, uint64_t startAddr, uint64_t blockShift);
uint32_t SetVmsaTable(void)
{
uint64_t *vmsaTblSadd;
vmsaTable *vmsaSrcTbl;
uint64_t startAddr;
uint64_t blockShift;
// TCR_EL3, Translation Control Register (EL3)
// [31] Reserved-1: 1
// [30:29] Reserved-0: 0
//
// When ARMv8.2-TTPBHA is implemented
// [28] HWU62 : 0 :Bit[62] of each stage 1 translation table Block or Page entry cannot be used by hardware for an IMPLEMENTATION DEFINED purpose.
// [27] HWU61 : 0 :Bit[61] of each stage 1 translation table Block or Page entry cannot be used by hardware for an IMPLEMENTATION DEFINED purpose.
// [26] HWU60 : 0 :Bit[60] of each stage 1 translation table Block or Page entry cannot be used by hardware for an IMPLEMENTATION DEFINED purpose.
// [25] HWU59 : 0 :Bit[59] of each stage 1 translation table Block or Page entry cannot be used by hardware for an IMPLEMENTATION DEFINED purpose.
// -The Effective value of this field is 0 if the value of TCR_EL3.HPD is 0.
// -This field resets to an architecturally UNKNOWN value.
// [24] HPD : 0 :Hierarchical Permission Disables.
// Otherwise
// [28:24] Reserved-0: 00000
//
// [23] Reserved-1: 1
// When ARMv8.1-TTHM is implemented
// [22] HD : 0 :Hardware management of dirty state in stage 1 translations from EL3.
// [21] HA : 0 :Hardware Access flag update in stage 1 translations from EL3.
// Otherwise
// [22:21] Reserved-0: 00
//
// [20] TBI : 0 : Top Byte used in the address calculation.
// [19] Reserved-0: 0
// [18:16] PS : 001 : Physical Address Size 000=32bit, 001=36bit, 010=40bit, 011=42bit, 100=44bit, 101=48bit
// [15:14] TG0 : 00 : translation table 00=4KB, 01=64KB, 10=16KB
// [13:12] SH0 : 10 : translation table memory 00=Non-shareable, 10=Outer Shareable, 11=Inner Shareable
// [11:10] ORGN0 : 01 : Outer 01=Write-Back Write-Allocate Cacheable
// [09:08] IRGN0 : 01 : Inner 01=Write-Back Write-Allocate Cacheable
// [07:06] Reserved : 00
// [05:00] T0SZ : 011100 : The region size is 2^(64-T0SZ) byte. 2^(64-28)=2^36=0x10_0000_0000
WriteTCR_EL3(0x8081251C);
WriteMAIR_EL3(ATTR_TBL);
WriteTTBR0_EL3((uint64_t)Lvl1VmsaTbl); // ASID=0
#ifdef SYSTEM_DEF_FALCON
// VMSA Table Level1 for Main
vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl1Cpu0ForDDR4ch;
#else
// VMSA Table Level1 for Main
// if( CHK_H3 && (!CHK_H3N) ){ vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl1Cpu0ForDDR4ch; } // 4ch : H3
// else if( CHK_M3 ){ vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl1Cpu0ForDDR2ch; } // 2ch : M3
// else if( CHK_H3N ){ vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl1Cpu0ForDDR2ch; } // 2ch : H3N
// else { vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl1Cpu0ForDDR1ch; } // 1ch : M3N,V3H,V3M,D3,E3
#endif
vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl1Cpu0ForDDR4ch;
vmsaTblSadd = (uint64_t*)Lvl1VmsaTbl;
startAddr = Lvl1StartAddr;
blockShift = Lvl1BlockShift;
MakeVmsaTable(vmsaTblSadd, vmsaSrcTbl, startAddr, blockShift);
// VMSA Table Level2 for IPs
vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl2Cpu0;
vmsaTblSadd = (uint64_t*)Lvl2VmsaTbl;
startAddr = Lvl2StartAddr;
blockShift = Lvl2BlockShift;
MakeVmsaTable(vmsaTblSadd, vmsaSrcTbl, startAddr, blockShift);
// VMSA Table Level3 for IPs
vmsaSrcTbl = (vmsaTable*)ArmVmsaTblLvl3Cpu0;
vmsaTblSadd = (uint64_t*)Lvl3VmsaTbl;
startAddr = Lvl3StartAddr;
blockShift = Lvl3BlockShift;
MakeVmsaTable(vmsaTblSadd, vmsaSrcTbl, startAddr, blockShift);
return 0;
}
static void MakeVmsaTable(uint64_t *vmsaTblSadd, vmsaTable *vmsaSrcTbl, uint64_t startAddr, uint64_t blockShift)
{
uint32_t i,j;
uint64_t setData;
uint64_t *setAddr;
uint64_t upperAttr; // Attribute fields for VMSAv8-64 ([63:52])
uint64_t lowerAttr; // Attribute fields for VMSAv8-64 ([11:0])
uint64_t virAdd;
uint64_t phyAdd;
uint64_t block;
uint64_t blockSize;
blockSize = (1<<blockShift);
// Level1 : make default table (non-cacheable)
upperAttr = 0x000; // [63:52] : [52]=Contiguous=1? (T.B.D.)
lowerAttr = 0x401; // [11:0] : nG=0, AF=1, SH=00, AP=00, NS=0, AttrIndx=000, [1:0]=01
setAddr = vmsaTblSadd;
setData = (upperAttr<<52)|(startAddr&BIT47_12)|(lowerAttr);
for(i=0;i<TBL_NUM;i++){
*setAddr = setData;
setAddr++; // Virtual Address (+1GB)(+2MB)
setData += blockSize; // Physical Address (+1GB)(+2MB)
}
// Level1 :
// Descriptor Address[47:12] = TTBR[47:12]
// Descriptor Address[11:03] = Input Address[38:30]
// Descriptor Address[02:00] = 0,0,0
// ----------
// Descriptor[47:12] = Physical Address[47:12] or Level2 table address[47:12]
for(i=0; vmsaSrcTbl[i].unit!=0 ;i++){
virAdd = vmsaSrcTbl[i].vAddr;
phyAdd = vmsaSrcTbl[i].pAddr;
setAddr = (uint64_t*)(uintptr_t)((uintptr_t)vmsaTblSadd + ((virAdd-startAddr)>>(blockShift-3)));
setData = vmsaSrcTbl[i].upperAttr<<52; // [63:52]
setData |= phyAdd; // [47:12]
setData |= vmsaSrcTbl[i].lowerAttr; // [11:00]
block = vmsaSrcTbl[i].unit;
for(j=0; j<block; j++){
*setAddr = setData;
setAddr++; // Virtual Address (+1GB)(+2MB)
setData += blockSize; // Physical Address (+1GB)(+2MB)
}
}
}