Skip to content

Commit

Permalink
arm64/imx9: provide EL3 bootloader support for iMX9
Browse files Browse the repository at this point in the history
This provides a capable bootloader that may be run from OCRAM.
The OCRAM contains regions that are always zero, so the linker
file avoids those with best effort.

iMX9 infrastructure expects:
  - 0x20480000 (Start of OCRAM, AHAB)
  - 0x2049a000 (NuttX or SPL)
  - 0x204e0000 (ARM Trustzone, not used)

When started from sd-card, the offsets are:
  - 0x1f000 with AHAB
  - 0xa000  without AHAB

Signed-off-by: Eero Nurkkala <[email protected]>
  • Loading branch information
eenurkka committed May 16, 2024
1 parent 9bdc760 commit 56387f5
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 7 deletions.
8 changes: 8 additions & 0 deletions arch/arm64/src/imx9/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ config IMX9_FLEXIO_PWM
select PWM_MULTICHAN
default n

config IMX9_BOOTLOADER
bool "Bootloader"
select ARM64_DECODEFIQ
default n
---help---
Configure NuttX as the bootloader. NuttX will be compiled
into OCRAM. It will run in EL3 secure state.

menu "i.MX9 Peripheral Selection"

config IMX9_EDMA
Expand Down
39 changes: 33 additions & 6 deletions arch/arm64/src/imx9/imx9_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,39 @@
#include "imx9_gpio.h"
#include "imx9_lowputc.h"

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

#define CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC 1700000000

/****************************************************************************
* Private Data
****************************************************************************/

#ifdef CONFIG_IMX9_BOOTLOADER
extern uint8_t _szbootloader[];
#endif

static const struct arm_mmu_region g_mmu_regions[] =
{
MMU_REGION_FLAT_ENTRY("DEVICE_REGION",
CONFIG_DEVICEIO_BASEADDR, CONFIG_DEVICEIO_SIZE,
MT_DEVICE_NGNRNE | MT_RW | MT_SECURE),
MMU_REGION_FLAT_ENTRY("DEVICE_REGION",
CONFIG_DEVICEIO_BASEADDR, CONFIG_DEVICEIO_SIZE,
MT_DEVICE_NGNRNE | MT_RW | MT_SECURE),

MMU_REGION_FLAT_ENTRY("DRAM0_S0",
CONFIG_RAMBANK1_ADDR, CONFIG_RAMBANK1_SIZE,
MT_NORMAL | MT_RW | MT_SECURE),
#ifdef CONFIG_IMX9_BOOTLOADER
/* OCRAM secure region protection keeps the binary at RO mode,
* overriding any MMU settings. However, data and heap accesses
* beyond the binary require RW access.
*/

MMU_REGION_FLAT_ENTRY("DRAM0_S0",
CONFIG_RAMBANK1_ADDR, CONFIG_RAMBANK1_SIZE,
MT_NORMAL | MT_RW | MT_SECURE),
MMU_REGION_FLAT_ENTRY("BOOTLOADER",
(uint64_t)_stext, (uint64_t)_szbootloader,
MT_NORMAL | MT_RW | MT_SECURE),
#endif
};

const struct arm_mmu_config g_mmu_config =
Expand Down Expand Up @@ -84,6 +104,11 @@ const struct arm_mmu_config g_mmu_config =

void arm64_el_init(void)
{
#ifdef CONFIG_ARCH_BOOT_EL3
/* At EL3, cntfrq_el0 is uninitialized. It must be set. */

write_sysreg(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, cntfrq_el0);
#endif
}

/****************************************************************************
Expand Down Expand Up @@ -111,7 +136,9 @@ void arm64_chip_boot(void)
#endif

#if defined(CONFIG_SMP) || defined(CONFIG_ARCH_HAVE_PSCI)
#ifndef CONFIG_IMX9_BOOTLOADER
arm64_psci_init("smc");
#endif
#endif

/* Initialize pin interrupt support */
Expand Down
65 changes: 65 additions & 0 deletions boards/arm64/imx9/imx93-evk/configs/bootloader/defconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm64"
CONFIG_ARCH_ARM64=y
CONFIG_ARCH_BOARD="imx93-evk"
CONFIG_ARCH_BOARD_IMX93_EVK=y
CONFIG_ARCH_BOOT_EL3=y
CONFIG_ARCH_CHIP="imx9"
CONFIG_ARCH_CHIP_IMX93=y
CONFIG_ARCH_CHIP_IMX9=y
CONFIG_ARCH_INTERRUPTSTACK=4096
CONFIG_ARM64_DCACHE_DISABLE=y
CONFIG_ARM64_DECODEFIQ=y
CONFIG_BUILTIN=y
CONFIG_DEBUG_ASSERTIONS=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_DEFAULT_TASK_STACKSIZE=8192
CONFIG_DEV_ZERO=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_EXPERIMENTAL=y
CONFIG_FS_PROCFS=y
CONFIG_FS_ROMFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=8192
CONFIG_IMX9_BOOTLOADER=y
CONFIG_IMX9_GPIO_IRQ=y
CONFIG_IMX9_LPUART1=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_LPUART1_SERIAL_CONSOLE=y
CONFIG_MM_FILL_ALLOCATIONS=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAMLOG=y
CONFIG_RAM_SIZE=548864
CONFIG_RAM_START=0x2049a000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_HPWORKPRIORITY=192
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_LPWORKPRIORITY=50
CONFIG_SPINLOCK=y
CONFIG_STACK_COLORATION=y
CONFIG_START_MONTH=3
CONFIG_START_YEAR=2022
CONFIG_SYMTAB_ORDEREDBYNAME=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_SYSTEM=y
CONFIG_SYSTEM_TIME64=y
CONFIG_TESTING_GETPRIME=y
CONFIG_TESTING_OSTEST=y
7 changes: 6 additions & 1 deletion boards/arm64/imx9/imx93-evk/scripts/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@

include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/tools/imx9/Config.mk
include $(TOPDIR)/arch/arm64/src/Toolchain.defs

LDSCRIPT = dramboot.ld
ifeq ($(CONFIG_IMX9_BOOTLOADER),y)
LDSCRIPT = ocramboot.ld
else
LDSCRIPT = dramboot.ld
endif

ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)

Expand Down
155 changes: 155 additions & 0 deletions boards/arm64/imx9/imx93-evk/scripts/ocramboot.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/****************************************************************************
* boards/arm64/imx9/imx93-evk/scripts/ocramboot.ld
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

OUTPUT_ARCH(aarch64)

ENTRY(__start)
EXTERN(__start)

/* Memory is organized as follows:
* - ahab reserves memory from 2048k to 0x2049a000
* - NuttX is compiled into 0x2049a000, ahab expects NuttX here
* - Heap memory is allocated from ocram end to idlestack top
*/

MEMORY
{
ocram (rx) : ORIGIN = 0x2049a000, LENGTH = 0x37ff0
ocram_data (rw) : ORIGIN = 0x204e0000, LENGTH = 0x2000
ocram_noload (rw) : ORIGIN = 0x204f0000, LENGTH = 0x30000
}

PHDRS
{
/* R = 100, W = 010, X = 001 */

text PT_LOAD FLAGS(5); /* RX */
rodata PT_LOAD FLAGS(4); /* R */
data PT_LOAD FLAGS(6); /* RW */
}

SECTIONS
{
.text :
{
_stext = ABSOLUTE(.); /* Text section */
*(.start .start.*) /* Place __start here */
*(.text .text.*)
*(.text.cold)
*(.text.unlikely)
*(.fixup)
*(.gnu.warning)
} > ocram :text

.init_section :
{
_sinit = ABSOLUTE(.);
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP(*(.init_array .ctors))
_einit = ABSOLUTE(.);
} > ocram :text

/* Vector table must be page aligned */

.vector : ALIGN(4096)
{
_vector_start = ABSOLUTE(.);
KEEP(*(.exc_vector_table))
KEEP(*(".exc_vector_table.*"))
KEEP(*(.vectors))
_vector_end = ABSOLUTE(.);
} > ocram :text

_etext = .;

.rodata : ALIGN(8)
{
_srodata = ABSOLUTE(.); /* Read-only data */
*(.rodata .rodata.*)
*(.data.rel.ro)
*(.data.rel.ro.*)
} > ocram :rodata

_erodata = .; /* End of read-only data */
_eronly = .; /* End of read-only data */

.data : ALIGN(8)
{
_sdata = ABSOLUTE(.);
*(.data.page_aligned)
*(.data .data.*)
. = ALIGN(8);
*(.data.rel)
*(.data.rel.*)
CONSTRUCTORS
. = ALIGN(8);
_edata = ABSOLUTE(.);
} > ocram_data :data

.bss (NOLOAD) :
{
. = ALIGN(8);
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
. = ALIGN(8);
_ebss = ABSOLUTE(.);
} > ocram_noload

.initstack :
{
_s_initstack = ABSOLUTE(.);
*(.initstack)
} > ocram_noload

/* End of data must be page aligned */

. = ALIGN(4096);

g_idle_topstack = .;
_e_initstack = .;

/* This makes sure arm64_mmu.c doesn't touch MMU regions,
* we handle it at imx9_boot.c.
*/
_sztext = 0;
_szrodata = 0;
_szbss = 0;
_szdata = 0;

/* Sections to be discarded */
/DISCARD/ : {
*(.exit.text)
*(.exit.data)
*(.exitcall.exit)
*(.eh_frame)
}

/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
}

_heapend = ORIGIN(ocram_noload) + LENGTH(ocram_noload);
_szbootloader = _heapend - _stext;
33 changes: 33 additions & 0 deletions tools/imx9/Config.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
############################################################################
# tools/imx9/Config.mk
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################

# These are the macros that will be used in the NuttX make system to compile
# and assembly source files and to insert the resulting object files into an
# archive. These replace the default definitions at tools/Config.mk

# POSTBUILD -- Perform post build operations

ifeq ($(CONFIG_IMX9_BOOTLOADER),y)
define POSTBUILD
$(Q) echo "Removing sections"
$(Q) $(OBJCOPY) -O binary -R .bss -R .initstack $(BIN) nuttx.bin
$(Q) ([ $$? -eq 0 ] && echo "Done.")
endef
endif

0 comments on commit 56387f5

Please sign in to comment.