From 1e97f195437d14c584654c2619cc6c985765efe0 Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Tue, 1 Mar 2022 11:22:07 -0800 Subject: Move NPCM7XX bootrom to a subdirectory --- npcm7xx/Makefile | 37 +++++++++++ npcm7xx/README.md | 44 +++++++++++++ npcm7xx/bootrom.ld | 56 ++++++++++++++++ npcm7xx/image.c | 118 ++++++++++++++++++++++++++++++++++ npcm7xx/start.S | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 438 insertions(+) create mode 100644 npcm7xx/Makefile create mode 100644 npcm7xx/README.md create mode 100644 npcm7xx/bootrom.ld create mode 100644 npcm7xx/image.c create mode 100644 npcm7xx/start.S (limited to 'npcm7xx') diff --git a/npcm7xx/Makefile b/npcm7xx/Makefile new file mode 100644 index 0000000..3b2b2f3 --- /dev/null +++ b/npcm7xx/Makefile @@ -0,0 +1,37 @@ +# Copyright 2020 Google LLC +# +# Licensed 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. + +CROSS_COMPILE ?= arm-none-eabi- + +CC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +CFLAGS = -Os -g -mcpu=cortex-a9 +ASFLAGS = $(CFLAGS) -Wa,-mcpu=cortex-a9+mp +LDSCRIPT = bootrom.ld +LDFLAGS = -Wl,--build-id=none -static -nostdlib -T $(LDSCRIPT) + +OBJS := start.o image.o + +.PHONY: all clean +all: npcm7xx_bootrom.bin + +clean: + rm -f *.o *.bin *.elf + +npcm7xx_bootrom.bin: npcm7xx_bootrom.elf + $(OBJCOPY) -O binary $< $@ + +npcm7xx_bootrom.elf: $(OBJS) $(LDSCRIPT) + $(CC) -o $@ $(LDFLAGS) $(OBJS) diff --git a/npcm7xx/README.md b/npcm7xx/README.md new file mode 100644 index 0000000..808781d --- /dev/null +++ b/npcm7xx/README.md @@ -0,0 +1,44 @@ +# Virtual Boot ROM for NPCM7xx SoCs + +This is not an officially supported Google product. + +This is a super simple Boot ROM that is intended to be used as a `-bios` image +for [QEMU](http://www.qemu.org/) when emulating an NPCM7xx-based machine. + +## Building + +If you have a 32-bit ARM compiler installed as `arm-none-eabi-gcc`, simply run +`make`. + +If your ARM compiler has a different name, you'll need to override the +`CROSS_COMPILE` prefix, e.g. like this: + +``` +make CROSS_COMPILE=arm-linux-gnueabi- +``` + +If either case is successful, a `npcm7xx_bootrom.bin` file will be produced. + +## Using + +The Boot ROM image may be passed to a QEMU system emulator using the `-bios` option. For example like this: + +``` +qemu-system-arm -machine quanta-gsj -nographic \ + -bios "${IMAGES}/npcm7xx_bootrom.bin" + -drive file="${IMAGES}/image-bmc,if=mtd,bus=0,unit=0,format=raw,snapshot=on" +``` + +## Limitations + +* Secure boot is not supported. +* Only booting from offset 0 of the flash at SPI0 CS0 is implemented. +* Fallback images (if the first image doesn't boot) are not implemented. +* Exception vectors are copied to SRAM, but not remapped. +* Most OTP bits and straps are not honored. +* The reset type bits are not updated. +* OTP protection is not implemented. +* No clock initialization is performed. +* UART programming protocol is not implemented. +* Host notification through the PCI mailbox is not implemented. +* Most fields in the ROM status structure are not set. diff --git a/npcm7xx/bootrom.ld b/npcm7xx/bootrom.ld new file mode 100644 index 0000000..34d59ad --- /dev/null +++ b/npcm7xx/bootrom.ld @@ -0,0 +1,56 @@ +/* + * Linker script for the Boot ROM. + * + * Copyright 2020 Google LLC + * + * Licensed 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. + */ + +MEMORY +{ + rom (rx) : ORIGIN = 0xFFFF0000, LENGTH = 64K + ram (a!rx) : ORIGIN = 0xFFFD0000, LENGTH = 128K +} + +SECTIONS +{ + /* Vectors are loaded into ROM, and copied into SRAM. */ + .text.vectors : { + *(.text.vectors) + . = 0x100; + } >ram AT>rom + /* The rest of the code follows the vectors, but is not copied. */ + .text : { + *(.text .text.*) + *(.rodata .rodata.*) + . = ALIGN(32); + _etext = .; + } >rom + /* + * Data follows the code in ROM, and is copied after the vectors in RAM. + * 32-byte aligned so we can use simple and fast copy loops. + */ + .data : { + _data = .; + *(.data.rom_status) + *(.data .data.*) + . = ALIGN(32); + _edata = .; + } >ram AT>rom + /* BSS lives in RAM, after the data section. */ + .bss : { + *(.bss .bss.*) + . = ALIGN(32); + _end = .; + } >ram +} diff --git a/npcm7xx/image.c b/npcm7xx/image.c new file mode 100644 index 0000000..08fe3f5 --- /dev/null +++ b/npcm7xx/image.c @@ -0,0 +1,118 @@ +/* + * Boot image parsing and loading. + * + * Copyright 2020 Google LLC + * + * Licensed 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. + */ + +#include + +#define SPI0CS0 0x80000000 +#define GCR 0xf0800000 +#define CLK 0xf0801000 +#define FIU0 0xfb000000 + +#define CLK_CLKDIV3 0x58 + +#define FIU_DRD_CFG 0x00 +#define FIU_CFG 0x78 + +#define BOOT_MAGIC0 0x000 +#define BOOT_MAGIC1 0x004 +#define BOOT_FIU_DRD_CFG 0x108 +#define BOOT_FIU_CLK_DIV 0x10c +#define BOOT_DEST_ADDR 0x140 +#define BOOT_CODE_SIZE 0x144 +#define BOOT_VERSION 0x148 +#define BOOT_CODE_OFFSET 0x200 + +#define BOOT_MAGIC0_VALUE 0xaa550750 +#define BOOT_MAGIC1_VALUE 0x424f4f54 + +/* + * This structure must reside at offset 0x100 in SRAM. + * + * See the Check_ROMCode_Status function in the Nuvoton bootblock: + * https://github.com/Nuvoton-Israel/bootblock/blob/master/Src/bootblock_main.c#L795 + */ +struct rom_status { + uint8_t reserved[12]; + uint8_t start_tag[8]; + uint32_t status; +} rom_status __attribute__((section(".data.rom_status"))) = { + .status = 0x21, /* SPI0 CS0 offset 0 */ +}; + +extern void panic(const char *); + +static void reg_write(uintptr_t base, uintptr_t offset, uint32_t value) +{ + asm volatile("str %0, [%1, %2]" + : + : "r"(value), "r"(base), "i"(offset) + : "memory"); +} + +static uint32_t image_read_u8(uintptr_t base, uintptr_t offset) +{ + return *(uint8_t *)(base + offset); +} + +static uint32_t image_read_u32(uintptr_t base, uintptr_t offset) +{ + return *(uint32_t *)(base + offset); +} + +void copy_boot_image(uintptr_t dest_addr, uintptr_t src_addr, int32_t len) +{ + uint32_t *dst = (uint32_t *)dest_addr; + uint32_t *src = (uint32_t *)src_addr; + + while (len > 0) { + *dst++ = *src++; + len -= sizeof(*dst); + } +} + +uintptr_t load_boot_image(void) +{ + uintptr_t dest_addr; + uint32_t drd_cfg; + uint8_t clk_div; + + reg_write(FIU0, FIU_CFG, 0x0000000b); + + if (image_read_u32(SPI0CS0, BOOT_MAGIC0) != BOOT_MAGIC0_VALUE) { + panic("Bad image magic0 value"); + } + if (image_read_u32(SPI0CS0, BOOT_MAGIC1) != BOOT_MAGIC1_VALUE) { + panic("Bad image magic1 value"); + } + + clk_div = image_read_u8(SPI0CS0, BOOT_FIU_CLK_DIV); + if (clk_div != 0) { + reg_write(FIU0, FIU_DRD_CFG, image_read_u32(SPI0CS0, BOOT_FIU_DRD_CFG)); + reg_write(CLK, CLK_CLKDIV3, clk_div << 6); + } + + dest_addr = image_read_u32(SPI0CS0, BOOT_DEST_ADDR); + if (dest_addr == 0) { + return SPI0CS0 + 0x200; + } + + copy_boot_image(dest_addr, SPI0CS0, + image_read_u32(SPI0CS0, BOOT_CODE_SIZE) + 0x200); + + return dest_addr + 0x200; +} diff --git a/npcm7xx/start.S b/npcm7xx/start.S new file mode 100644 index 0000000..ca7aaf6 --- /dev/null +++ b/npcm7xx/start.S @@ -0,0 +1,183 @@ +/* + * Top-level entry points to the Boot ROM. This includes: + * - Reset, exception and interrupt vectors. + * - C run-time initialization. + * - Secondary CPU boot code. + * + * Copyright 2020 Google LLC + * + * Licensed 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. + */ + +#define KiB (1024) + +#define SRAM_SIZE (128 * KiB) + + .section .text.vectors, "ax" + + .global _start + .type _start, %function +_start: + ldr pc, reset_addr + . = 0x04 + b undefined_instruction + . = 0x08 + b software_interrupt + . = 0x0c + b prefetch_abort + . = 0x10 + b data_abort + . = 0x18 + b interrupt + . = 0x1c + b fast_interrupt + + .align 2 +reset_addr: + .word reset + +undefined_instruction: + mov r0, #1 + ldr pc, handle_exception_addr + +software_interrupt: + mov r0, #2 + ldr pc, handle_exception_addr + +prefetch_abort: + mov r0, #3 + ldr pc, handle_exception_addr + +data_abort: + mov r0, #4 + ldr pc, handle_exception_addr + +interrupt: + mov r0, #6 + ldr pc, handle_exception_addr + +fast_interrupt: + mov r0, #7 + ldr pc, handle_exception_addr + +handle_exception_addr: + .word handle_exception + +vectors_end: + + . = 0xf8 +chip_id: + .word 0x00a92750 + + . = 0xfc +rom_version: + .word 0x00010055 + + .text + .align 2 +handle_exception: + + .global panic + .type panic, %function +panic: +1: wfi + b 1b + .size panic, . - panic + + .type reset, %function +reset: + mov r0, #0 + // Read the CPU ID from MPIDR. + mrc p15, 0, r1, c0, c0, 5 + tst r1, #0x03 + beq cpu0_init + + // Not CPU0 -- clear the SCRPAD register and wait for it to change. + ldr r2, scrpad_addr + str r0, [r2] + dsb st + sev +1: wfe + ldr r3, [r2] + cmp r3, #0 + beq 1b + + // SCRPAD is no longer NULL, so jump there. + bx r3 + .size reset, . - reset + + .type scrpad_addr, %object +scrpad_addr: + .word 0xF080013C + .size scrpad_addr, . - scrpad_addr + + .type cpu0_init, %function +cpu0_init: + ldr r1, sram_base_addr + add sp, r1, #SRAM_SIZE + + // Copy vectors from ROM to SRAM. + ldr r3, rom_base_addr + mov r2, #0x100 +1: ldmia r3!, {r4 - r11} + stmia r1!, {r4 - r11} + subs r2, #32 + bgt 1b + + // Copy data from ROM to SRAM. + ldr r3, etext_addr + ldr r2, edata_addr +1: ldmia r3!, {r4 - r11} + stmia r1!, {r4 - r11} + cmp r1, r2 + blt 1b + + // Zero the BSS section. + ldr r2, end_addr +1: stmia r1!, {r0} + cmp r1, r2 + blt 1b + + // Load the boot image into SRAM. Returns the entry address. + bl load_boot_image + + // Jump to the boot image. Panic if it returns back to us. + blx r0 + b panic + + .size cpu0_init, . - cpu0_init + + .type sram_base_addr, %object +sram_base_addr: + .word 0xFFFD0000 + .size sram_base_addr, . - sram_base_addr + + .type rom_base_addr, %object +rom_base_addr: + .word 0xFFFF0000 + .size rom_base_addr, . - rom_base_addr + + .type etext_addr, %object +etext_addr: + .word _etext + .size etext_addr, . - etext_addr + + .type edata_addr, %object +edata_addr: + .word _edata + .size edata_addr, . - edata_addr + + .type end_addr, %object +end_addr: + .word _end + .size end_addr, . - end_addr -- cgit v1.1