riscvarchive/riscv-edk2-platforms

Create platform for Allwinner Nezha D1

JohnAZoidberg opened this issue · 3 comments

Instruction set: RV64IMAFDCVU (RV64GCV)
Official Website (chinese): https://d1.docs.aw-ol.com/
Linux branch: https://github.com/smaeul/linux/commits/riscv/d1-wip
U-Boot branch: https://github.com/smaeul/u-boot/tree/d1-wip

D1 Manual: https://dl.linux-sunxi.org/D1/D1_User_Manual_V0.1_Draft_Version.pdf
Sunxi D1 Wiki page: https://linux-sunxi.org/D1
Sunxi Nezha Wiki page: https://linux-sunxi.org/Allwinner_Nezha
Nezha Schematics: https://dl.linux-sunxi.org/D1/D1_Nezha_development_board_schematic_diagram_20210224.pdf
Fedora wiki: https://fedoraproject.org/wiki/Architectures/RISC-V/Allwinner
xfel: https://github.com/xboot/xfel
xfel tutorial: https://github.com/xboot/xboot/blob/master/src/arch/riscv64/mach-d1/README-en-US.md

Model after RaspberryPi3/4 support:

WIP Branch:

Status: No work done yet

Information

  • Where to put EDK2? Where is U-Boot?

Features

  • Required for UEFI Shell
    • Cores? @1GHZ (XuanTie C906 RISC-V CPU)
      • PcdFwStartAddress (0x40000000), PcdFwEndAddress (auto calulated)
      • PcdHartCount (1), PcdBootHartId (0), PcdBootableHartNumber (1)
      • 32 KB I-cache + 32 KB D-cache
    • 1GiB DRAM (Trained by previous stage)
    • 256MB SPI NAND flash
    • Serial console via GPIO UART0 16550-style (at 0x2500000, baud 115200, clock 24000000)
    • CLINT (at 0x14000000 compatible with SiFive, generic OpenSBI platform gets it via DT)
    • PLIC (at 0x10000000 compatible with SiFive, generic OpenSBI platform gets it via DT)
    • Add Nezha Device Tree
    • RTC 1kHz
  • Extras
    • 1x micro SD card
    • 1x USB2.0 Type A host port
    • 1x USB-C OTG port
    • 1x 1GBps Ethernet (Realtek RTL8211F)
    • 1x HDMI port (Type A)
    • 1x "OK" Button
    • GPIO pins (create a Driver/Library for it)
  • Won't (need) support in UEFI
    • 1x 3.5mm audio jack
    • 1x 802.11 b/g/n WiFi
    • 1x Bluetooth
    • Power with USB Type-C
    • 1x "FEL" Button to trigger FEL mode for

Memory Map

Module Address Size
N-BROM 0x0000 0000 - 0x0000 BFFF 48KB
PLIC 0x1000 0000
SRAM A1 32KB
GPIO 0x0200 0000 - 0x0200 07FF 2KB
LEDC 0x0200 8000 - 0x0200 83FF 1KB
UART0 0x0250 0000 - 0x0250 03FF 1KB
UART1 0x0250 0400 - 0x0250 07FF 1KB
UART2 0x0250 0800 - 0x0250 0BFF 1KB
UART3 0x0250 0C00 - 0x0250 0FFF 1KB
UART4 0x0250 1000 - 0x0250 13FF 1KB
UART5 0x0250 1400 - 0x0250 17FF 1KB
SPI0 0x0402 5000 - 0x0402 5FFF 4KB
SPI1 0x0402 6000 - 0x0402 6FFF 4KB
DRAM 0x4000 0000 - 0xBFFF FFFF 2GB

Interrupts

Interrupt Number Interrupt Source Interrupt Vector
31 SPI0 0x007C
32 SPI1 0x0080

LED at 9.12 (page 1270)

Compatible with industry-standard 16450/16550 UARTs

Boot Source (2.2.3.1 Boot ROM (BROM), 3.3 BROM System)

  • On-chip memory
  • Supports system boot from the following devices:
    • SD card
    • eMMC (What's this? Not SD card?
    • SPI NOR Flash
    • SPI NAND Flash
  • Supports mandatory upgrade process through USB and SD card
  • Suppots GPIO pin and eFuse module to select the boot media type

Boot:

  1. First instruction is fetched from BROM (address 0x0)

Device Trees

https://github.com/smaeul/u-boot/blob/65f26c1c94521c9e54ddceb4d463a0e21ce13047/arch/riscv/dts/sun20i-d1-nezha.dts

{
	aliases {
		mmc0 = &mmc0;
		mmc1 = &mmc1;
		mmc2 = &mmc2;
		serial0 = &uart0;
		spi0 = &spi0;
	};
	chosen {
		stdout-path = "serial0:115200n8";
	};

	&gpio {
		ledc_pc0_pin: ledc-pc0-pin {
			pins = "PC0";
			function = "ledc";
		};
	};

	&ledc {
		pinctrl-0 = <&ledc_pc0_pin>;
		pinctrl-names = "default";
		status = "okay";
	};
	led@0 {
		reg = <0x0>;
		color = <LED_COLOR_ID_RGB>;
		function = LED_FUNCTION_INDICATOR;
	};
};

Seems we need to add this tool to build a TOC1 image: smaeul/u-boot@fe858f9

https://linux-sunxi.org/Allwinner_Nezha#Mainline_U-Boot

boot0 expects to load a TOC1 image containing OpenSBI and U-Boot (and a DTB). This is similar to, but incompatible with, mainline U-Boot SPL, which expects a FIT image.

The version of mkimage you just compiled contains rudimentary support for making TOC1 images. Since a TOC1 can contain multiple items, we must create a config file telling mkimage where to find them. Use the following content, adjusting the path to OpenSBI as needed:

[opensbi]
file = ../opensbi/build/platform/generic/firmware/fw_dynamic.bin
addr = 0x40000000
[dtb]
file = arch/riscv/dts/sun20i-d1-nezha.dtb
addr = 0x44000000
[u-boot]
file = u-boot-nodtb.bin
addr = 0x4a000000

Now, continuing in the U-Boot build directory, create the TOC1:

vim toc1.cfg # or your editor of choice; see above
tools/mkimage -T sunxi_toc1 -d toc1.cfg u-boot.toc1

You should get output that looks like this:

Allwinner TOC1 Image
Size: 592896 bytes
Contents: 3 items
 00000000:00000490 Headers
 00000600:00018720 => 40000000 opensbi
 00018e00:00007387 => 44000000 dtb
 00020200:00070820 => 4a000000 u-boot

Now you can write this TOC1 to your SD card. Note the large (16+ MiB) offset! You will need to leave a gap before your first partition; 20 MiB should be plenty. (Or you can change UBOOT_START_SECTOR_IN_SDMMC in include/spare_head.h in boot0.)

sudo dd if=u-boot.toc1 of=/dev/sdX bs=512 seek=32800

UART baud rates

image

Additional TODO: Create a PPI/protocol to control GPIOs.
Could use the same headers as: https://github.com/MarvellEmbeddedProcessors/edk2/blob/master/Omap35xxPkg/Gpio/Gpio.c