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 --- Makefile | 37 ----------- README.md | 44 ------------- bootrom.ld | 56 ---------------- image.c | 118 ---------------------------------- npcm7xx/Makefile | 37 +++++++++++ npcm7xx/README.md | 44 +++++++++++++ npcm7xx/bootrom.ld | 56 ++++++++++++++++ npcm7xx/image.c | 118 ++++++++++++++++++++++++++++++++++ npcm7xx/start.S | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++ start.S | 183 ----------------------------------------------------- 10 files changed, 438 insertions(+), 438 deletions(-) delete mode 100644 Makefile delete mode 100644 README.md delete mode 100644 bootrom.ld delete mode 100644 image.c 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 delete mode 100644 start.S diff --git a/Makefile b/Makefile deleted file mode 100644 index 3b2b2f3..0000000 --- a/Makefile +++ /dev/null @@ -1,37 +0,0 @@ -# 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/README.md b/README.md deleted file mode 100644 index 808781d..0000000 --- a/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# 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/bootrom.ld b/bootrom.ld deleted file mode 100644 index 34d59ad..0000000 --- a/bootrom.ld +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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/image.c b/image.c deleted file mode 100644 index 08fe3f5..0000000 --- a/image.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * 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/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 diff --git a/start.S b/start.S deleted file mode 100644 index ca7aaf6..0000000 --- a/start.S +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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 From 2d0c401b32687ac0ae90525238e652bd5ea9efaf Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Tue, 1 Mar 2022 11:27:27 -0800 Subject: Add NPCM8XX simple bootrom --- npcm8xx/Makefile | 37 ++++++++++++++ npcm8xx/README.md | 44 ++++++++++++++++ npcm8xx/bootrom.ld | 56 ++++++++++++++++++++ npcm8xx/image.c | 86 +++++++++++++++++++++++++++++++ npcm8xx/start.S | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 369 insertions(+) create mode 100644 npcm8xx/Makefile create mode 100644 npcm8xx/README.md create mode 100644 npcm8xx/bootrom.ld create mode 100644 npcm8xx/image.c create mode 100644 npcm8xx/start.S diff --git a/npcm8xx/Makefile b/npcm8xx/Makefile new file mode 100644 index 0000000..4796326 --- /dev/null +++ b/npcm8xx/Makefile @@ -0,0 +1,37 @@ +# Copyright 2022 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 ?= aarch64-linux-gnu- + +CC = $(CROSS_COMPILE)gcc +OBJCOPY = $(CROSS_COMPILE)objcopy + +CFLAGS = -Os -g -mcpu=cortex-a35 +ASFLAGS = $(CFLAGS) -Wa,-mcpu=cortex-a35 +LDSCRIPT = bootrom.ld +LDFLAGS = -Wl,--build-id=none -static -nostdlib -T $(LDSCRIPT) + +OBJS := start.o image.o + +.PHONY: all clean +all: npcm8xx_bootrom.bin + +clean: + rm -f *.o *.bin *.elf + +npcm8xx_bootrom.bin: npcm8xx_bootrom.elf + $(OBJCOPY) -O binary $< $@ + +npcm8xx_bootrom.elf: $(OBJS) $(LDSCRIPT) + $(CC) -o $@ $(LDFLAGS) $(OBJS) diff --git a/npcm8xx/README.md b/npcm8xx/README.md new file mode 100644 index 0000000..6341583 --- /dev/null +++ b/npcm8xx/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 NPCM8xx-based machine. + +## Building + +If you have a 64-bit ARM compiler installed as `aarch64-linux-gnu-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=aarch64-linux-gnueabi- +``` + +If either case is successful, a `npcm8xx_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-aarch64 -machine npcm845-evb -nographic \ + -bios "${IMAGES}/npcm8xx_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/npcm8xx/bootrom.ld b/npcm8xx/bootrom.ld new file mode 100644 index 0000000..412bf3a --- /dev/null +++ b/npcm8xx/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 = 0x00000000, LENGTH = 32K + ram (a!rx) : ORIGIN = 0xFFFB0000, LENGTH = 256K +} + +SECTIONS +{ + /* Vectors are loaded into ROM, and copied into SRAM. */ + .text.vectors : { + *(.text.vectors) + . = 0x100; + } >rom AT>ram + /* 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 = .; + } >rom AT>ram + /* BSS lives in RAM, after the data section. */ + .bss : { + *(.bss .bss.*) + . = ALIGN(32); + _end = .; + } >ram +} diff --git a/npcm8xx/image.c b/npcm8xx/image.c new file mode 100644 index 0000000..f799774 --- /dev/null +++ b/npcm8xx/image.c @@ -0,0 +1,86 @@ +/* + * Boot image parsing and loading. + * + * Copyright 2022 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 CLK 0xf0801000 +#define FIU0 0xfb000000 +#define CLK_CLKSEL 0x04 +#define CLK_CLKSEL_DEFAULT 0x1f18fc9 +#define FIU_DRD_CFG 0x00 + +/* + * 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 %w0, [%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 = 0x8000; + + /* Set CLKSEL to similar values as NPCM7XX */ + reg_write(CLK, CLK_CLKSEL, CLK_CLKSEL_DEFAULT); + + /* Load the U-BOOT image to DRAM */ + copy_boot_image(dest_addr, SPI0CS0 + 0x20200, 0xa6e80); + /* Set FIU to use 4 byte mode, similar to what TIP does in reality. */ + reg_write(FIU0, FIU_DRD_CFG, 0x0301100b); + + return dest_addr; +} diff --git a/npcm8xx/start.S b/npcm8xx/start.S new file mode 100644 index 0000000..58b04da --- /dev/null +++ b/npcm8xx/start.S @@ -0,0 +1,146 @@ +/* + * Top-level entry points to the Boot ROM. This includes: + * - Reset, exception and interrupt vectors. + * - C run-time initialization. + * - Secondary CPU boot code. + * + * Copyright 2022 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 (256 * KiB) + +.section .text.vectors, "ax" + +.global _start +.type _start, %function +_start: +b reset +. = 0x04 +b undefined_instruction +. = 0x08 +b software_interrupt +. = 0x0c +b prefetch_abort +. = 0x10 +b data_abort +. = 0x18 +b interrupt +. = 0x1c +b fast_interrupt + +undefined_instruction: +mov x0, #1 +b handle_exception + +software_interrupt: +mov x0, #2 +b handle_exception + +prefetch_abort: +mov x0, #3 +b handle_exception + +data_abort: +mov x0, #4 +b handle_exception + +interrupt: +mov x0, #6 +b handle_exception + +fast_interrupt: +mov x0, #7 +b handle_exception + +vectors_end: + +.text +.align 2 +handle_exception: + +.global panic +.type panic, %function +panic: +1: wfi +b 1b +.size panic, . - panic + +.type reset, %function +reset: +mov x0, #0 +// Read the CPU ID from MPIDR_EL1. +mrs x1, MPIDR_EL1 +and x1, x1, #0x03 +cbz x1, cpu0_init + +// Not CPU0 -- clear the SCRPAD register and wait for it to change. +ldr x2, scrpad_addr +str x0, [x2] +dsb st +sev +1: wfe +ldr x3, [x2] +cmp x3, #0 +beq 1b + +// SCRPAD is no longer NULL, so jump there. +ret x3 +.size reset, . - reset + +.type scrpad_addr, %object +scrpad_addr: +.dword 0xF0800E00 +.size scrpad_addr, . - scrpad_addr + +.type cpu0_init, %function +cpu0_init: +ldr x1, sram_base_addr +add sp, x1, #SRAM_SIZE + +// 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. +ret x0 +b panic + +.size cpu0_init, . - cpu0_init + +.type sram_base_addr, %object +sram_base_addr: +.dword 0xFFFB0000 +.size sram_base_addr, . - sram_base_addr + +.type sdram_base_addr, %object +sdram_base_addr: +.dword 0x00000000 +.size sdram_base_addr, . - sdram_base_addr + +.type etext_addr, %object +etext_addr: +.dword _etext +.size etext_addr, . - etext_addr + +.type edata_addr, %object +edata_addr: +.dword _edata +.size edata_addr, . - edata_addr + +.type end_addr, %object +end_addr: +.dword _end +.size end_addr, . - end_addr -- cgit v1.1 From 1e1e1186b8a5c69527e65c1555f70943f9e4942b Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Wed, 23 Mar 2022 15:27:17 -0700 Subject: Add a simple README file to describe each subdir --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..1d0f248 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# Virtual Boot ROM for NPCM SoCs + +This repository contains simple Boot ROMs for Nuvoton based +BMC images that are intended to be used by [QEMU](http://www.qemu.org) +when emulating NPCM based machines. + +## Subdirectories + +npcm7xx: This subdir contains Boot ROM for NPCM7XX, a 32-bit ARM image. +npcm8xx: This subdir contains Boot ROM for NPCM8XX, a 64-bit ARM image. -- cgit v1.1