Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Introduction

The zero stage boot is the XuanTie processor init code before opensbi. Before zero_stage_boot, SoC vendors must prepare ddr_init and CPU reset procedures. All harts would get into zero_stage_boot together, and the first one would duty to relocate GOT & offset variable, and others wait. Every hart would init its CSRs by their CPUID versions separately, allowing different harts to work together, e.g., 4*c908 + 2*c910. You could compile standard opensbi and Linux kernel binaries from open-source repositories, all compatible with XuanTie processors. Here is the simple boot flow:

[Jtag gdbinit] -> [zero_stage_boot] -> [opensbi] -> [Linux]

opensbi: https://github.com/riscv-software-src/opensbi
Linux:   https://kernel.org/

Compile zero_stage_boot

CROSS_COMPILE=riscv64-unknown-linux-gnu- make

DTS Example

The T-HEAD C9xx DTB provided to OpenSBI generic firmware will usually have "riscv,clint0", "thead,c900-plic", compatible strings.

/dts-v1/;
/ {
	model = "Test Sample";
	compatible = "test,sample";
	#address-cells = <2>;
	#size-cells = <2>;

	memory@60000000 {
		device_type = "memory";
		reg = <0x0 0x60000000 0x1 0x00000000>;
	};

	cpus {
		#address-cells = <1>;
		#size-cells = <0>;
		timebase-frequency = <25000000>;
		cpu@0 {
			device_type = "cpu";
			reg = <0>;
			status = "okay";
			compatible = "riscv";
			riscv,isa = "rv64ima";
			mmu-type = "riscv,sv57";
			cpu0_intc: interrupt-controller {
				#address-cells = <0>;
				#interrupt-cells = <1>;
				compatible = "riscv,cpu-intc";
				interrupt-controller;
			};
		};
		cpu@1 {
			device_type = "cpu";
			reg = <1>;
			status = "okay";
			compatible = "riscv";
			riscv,isa = "rv64ima";
			mmu-type = "riscv,sv57";
			cpu1_intc: interrupt-controller {
				#address-cells = <0>;
				#interrupt-cells = <1>;
				compatible = "riscv,cpu-intc";
				interrupt-controller;
			};
		};
		cpu@2 {
			device_type = "cpu";
			reg = <2>;
			status = "okay";
			compatible = "riscv";
			riscv,isa = "rv64ima";
			mmu-type = "riscv,sv57";
			cpu2_intc: interrupt-controller {
				#address-cells = <0>;
				#interrupt-cells = <1>;
				compatible = "riscv,cpu-intc";
				interrupt-controller;
			};
		};
		cpu@3 {
			device_type = "cpu";
			reg = <3>;
			status = "okay";
			compatible = "riscv";
			riscv,isa = "rv64ima";
			mmu-type = "riscv,sv57";
			cpu3_intc: interrupt-controller {
				#address-cells = <0>;
				#interrupt-cells = <1>;
				compatible = "riscv,cpu-intc";
				interrupt-controller;
			};
		};
	};


	soc {
		#address-cells = <2>;
		#size-cells = <2>;
		compatible = "simple-bus";
		ranges;

		clint0: clint@c000000 {
			compatible = "thead,c900-clint";
			interrupts-extended = <
				&cpu0_intc  3 &cpu0_intc  7
				&cpu1_intc  3 &cpu1_intc  7
				&cpu2_intc  3 &cpu2_intc  7
				&cpu3_intc  3 &cpu3_intc  7
				>;
			reg = <0x0 0x0c000000 0x0 0x04000000>;
			clint,has-no-64bit-mmio;
		};

		intc: interrupt-controller@8000000 {
			#address-cells = <0>;
			#interrupt-cells = <1>;
			compatible = "thead,c900-plic";
			reg = <0x0 0x08000000 0x0 0x04000000>;
			riscv,ndev = <80>;
			interrupt-controller;
			interrupts-extended = <
				&cpu0_intc  0xffffffff &cpu0_intc  9
				&cpu1_intc  0xffffffff &cpu1_intc  9
				&cpu2_intc  0xffffffff &cpu2_intc  9
				&cpu3_intc  0xffffffff &cpu3_intc  9
				>;
		};
	};
};

CPU gdbinit script

# Set gdb environment
set confirm off
set height  0
monitor set resume-bkpt-exception on

# memory layout
set $opensbi_addr = 0x60000000
set $vmlinux_addr = $opensbi_addr + 0x00400000
set $rootfs_addr  = $opensbi_addr + 0x04000000
set $dtb_addr     = $rootfs_addr  - 0x00100000
set $zsb_addr     = $rootfs_addr  - 0x00008000
set $dyninfo_addr = $rootfs_addr  - 0x40
set $flag_addr    = $rootfs_addr  - 0x100

# Load kernel
restore zero_stage_boot.bin binary          $zsb_addr
restore <preceding dts example>.dtb binary  $dtb_addr
restore fw_dynamic.bin binary               $opensbi_addr
restore Image binary                        $vmlinux_addr

# Set opensbi dynamic info param
set *(unsigned long *)($dyninfo_addr)      = 0x4942534f
set *(unsigned long *)($dyninfo_addr + 8)  = 2
set *(unsigned long *)($dyninfo_addr + 16) = $vmlinux_addr
set *(unsigned long *)($dyninfo_addr + 24) = 1
set *(unsigned long *)($dyninfo_addr + 32) = 0
set *(unsigned long *)($dyninfo_addr + 40) = -1

# Set boot flag for CPU functional setting
# BIT[0]: Enable RV64XT32 by setting mxstatus.[63]=1
# set *(unsigned int *)$flag_addr = 0x1
set *(unsigned int *)$flag_addr = 0x0

# Set all harts reset address
set *0x18030010 = $zsb_addr
set *0x18030018 = $zsb_addr
set *0x18030020 = $zsb_addr
set *0x18030028 = $zsb_addr
set *0x18030030 = $zsb_addr
set $pc         = $zsb_addr

# Release all harts from reset
set *0x18030000 = 0x7f

Run

Start Jtag Server with local-semihosting mode(opensbi requirements).

DebugServerConsole -prereset -ls

Then use gdb connect the Jtag Server.

riscv64-elf-gdb -ex "tar remote <Jtag Server ip:port>" -x <your soc gdbinit> -x <preceding cpu gdbinit> -ex "c"

Use ctrl+c to get into the gdb shell.

file vmlinux
source gdbmarcos.txt
dmesg

gdbmacros.txt:

vmlinux: The Linux kernel ELF file

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages