diff --git a/.gitmodules b/.gitmodules
index f2a4be1d4..d959d5918 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -160,3 +160,9 @@
[submodule "software/example-lim"]
path = software/example-lim
url = https://github.com/sifive/example-lim.git
+[submodule "software/example-emmc"]
+ path = software/example-emmc
+ url = https://github.com/sifive/example-emmc.git
+[submodule "software/example-flash"]
+ path = software/example-flash
+ url = https://github.com/sifive/example-flash.git
diff --git a/bsp/sifive-nb2/core.dts b/bsp/sifive-nb2/core.dts
new file mode 100644
index 000000000..d9335377f
--- /dev/null
+++ b/bsp/sifive-nb2/core.dts
@@ -0,0 +1,387 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "SiFive,FU700-dev", "fu700-dev", "sifive-dev";
+ model = "SiFive,FU700";
+
+chosen {
+metal,boothart = <&L10>;
+stdout-path = "/soc/nb2uart0@302011000:9600";
+};
+ L47: cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ L10: cpu@0 {
+ clock-frequency = <0>;
+ compatible = "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-tlb-sets = <1>;
+ d-tlb-size = <40>;
+ device_type = "cpu";
+ hardware-exec-breakpoint-count = <2>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ i-tlb-sets = <1>;
+ i-tlb-size = <40>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&L42>;
+ reg = <0x0>;
+ riscv,isa = "rv64imafdc";
+ riscv,pmpregions = <4>;
+ sifive,buserror = <&L9>;
+ status = "okay";
+ timebase-frequency = <1000000>;
+ tlb-split;
+ L7: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ L14: cpu@1 {
+ clock-frequency = <0>;
+ compatible = "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-tlb-sets = <1>;
+ d-tlb-size = <40>;
+ device_type = "cpu";
+ hardware-exec-breakpoint-count = <2>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ i-tlb-sets = <1>;
+ i-tlb-size = <40>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&L42>;
+ reg = <0x1>;
+ riscv,isa = "rv64imafdc";
+ riscv,pmpregions = <4>;
+ sifive,buserror = <&L13>;
+ status = "disable";
+ timebase-frequency = <1000000>;
+ tlb-split;
+ L11: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ L18: cpu@2 {
+ clock-frequency = <0>;
+ compatible = "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-tlb-sets = <1>;
+ d-tlb-size = <40>;
+ device_type = "cpu";
+ hardware-exec-breakpoint-count = <2>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ i-tlb-sets = <1>;
+ i-tlb-size = <40>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&L42>;
+ reg = <0x2>;
+ riscv,isa = "rv64imafdc";
+ riscv,pmpregions = <4>;
+ sifive,buserror = <&L17>;
+ status = "disable";
+ timebase-frequency = <1000000>;
+ tlb-split;
+ L15: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ L22: cpu@3 {
+ clock-frequency = <0>;
+ compatible = "sifive,bullet0", "riscv";
+ d-cache-block-size = <64>;
+ d-cache-sets = <128>;
+ d-cache-size = <32768>;
+ d-tlb-sets = <1>;
+ d-tlb-size = <40>;
+ device_type = "cpu";
+ hardware-exec-breakpoint-count = <2>;
+ i-cache-block-size = <64>;
+ i-cache-sets = <256>;
+ i-cache-size = <32768>;
+ i-tlb-sets = <1>;
+ i-tlb-size = <40>;
+ mmu-type = "riscv,sv39";
+ next-level-cache = <&L42>;
+ reg = <0x3>;
+ riscv,isa = "rv64imafdc";
+ riscv,pmpregions = <4>;
+ sifive,buserror = <&L21>;
+ status = "disable";
+ timebase-frequency = <1000000>;
+ tlb-split;
+ L19: interrupt-controller {
+ #interrupt-cells = <1>;
+ compatible = "riscv,cpu-intc";
+ interrupt-controller;
+ };
+ };
+ };
+ L30: memory@800000000 {
+ compatible = "sifive,axi4-mem-port", "sifive,axi4-port", "sifive,mem-port";
+ device_type = "memory";
+ reg = <0x8 0x0 0x2 0x0>;
+ sifive,port-width-bytes = <16>;
+ };
+ L46: soc {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "SiFive,FU700-soc", "fu700-soc", "sifive-soc", "simple-bus";
+ ranges;
+ L23: authentication-controller {
+ authentication-types = "password";
+ compatible = "sifive,authentication0";
+ };
+ L32: axi4-periph-port@100000000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "sifive,axi4-periph-port", "sifive,axi4-port", "sifive,periph-port", "simple-external-bus", "simple-bus";
+ ranges = <0x1 0x0 0x1 0x0 0x4 0x0>;
+ sifive,port-width-bytes = <16>;
+ };
+ L31: axi4-sys-port@c00000000 {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ compatible = "sifive,axi4-sys-port", "sifive,axi4-port", "sifive,sys-port", "simple-external-bus", "simple-bus";
+ ranges = <0xc 0x0 0xc 0x0 0x2 0x0>;
+ sifive,port-width-bytes = <16>;
+ };
+ L9: bus-error-unit@1700000 {
+ compatible = "sifive,buserror0";
+ interrupt-parent = <&L3>;
+ interrupts = <134>;
+ reg = <0x0 0x1700000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L13: bus-error-unit@1701000 {
+ compatible = "sifive,buserror0";
+ interrupt-parent = <&L3>;
+ interrupts = <135>;
+ reg = <0x0 0x1701000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L17: bus-error-unit@1702000 {
+ compatible = "sifive,buserror0";
+ interrupt-parent = <&L3>;
+ interrupts = <136>;
+ reg = <0x0 0x1702000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L21: bus-error-unit@1703000 {
+ compatible = "sifive,buserror0";
+ interrupt-parent = <&L3>;
+ interrupts = <137>;
+ reg = <0x0 0x1703000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L42: cache-controller@2010000 {
+ cache-block-size = <64>;
+ cache-level = <2>;
+ cache-sets = <2048>;
+ cache-size = <2097152>;
+ cache-unified;
+ compatible = "sifive,ccache0", "cache";
+ interrupt-parent = <&L3>;
+ interrupts = <130 131 132 133>;
+ next-level-cache = <&L1 &L30>;
+ reg = <0x0 0x2010000 0x0 0x4000 0x0 0x8000000 0x0 0x200000>;
+ reg-names = "control", "sideband";
+ sifive,a-mshr-count = <20>;
+ sifive,bank-count = <4>;
+ sifive,ecc-granularity = <8>;
+ };
+ L4: clint@2000000 {
+ compatible = "riscv,clint0";
+ interrupts-extended = <&L7 3 &L7 7 &L11 3 &L11 7 &L15 3 &L15 7 &L19 3 &L19 7>;
+ reg = <0x0 0x2000000 0x0 0x10000>;
+ reg-names = "control";
+ };
+ L5: debug-controller@0 {
+ compatible = "sifive,debug-013", "riscv,debug-013";
+ debug-attach = "jtag";
+ interrupts-extended = <&L7 65535 &L11 65535 &L15 65535 &L19 65535>;
+ reg = <0x0 0x0 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L2: error-device@3000 {
+ compatible = "sifive,error0";
+ reg = <0x0 0x3000 0x0 0x1000>;
+ };
+ L25: global-external-interrupts {
+ compatible = "sifive,global-external-interrupts0";
+ interrupt-parent = <&L3>;
+ interrupts = <3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129>;
+ };
+ L24: hca@20000000 {
+ clocks = <&L0>;
+ compatible = "sifive,hca-0.5.3";
+ interrupt-parent = <&L3>;
+ interrupts = <1 2>;
+ reg = <0x0 0x20000000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L3: interrupt-controller@c000000 {
+ #interrupt-cells = <1>;
+ compatible = "riscv,plic0";
+ interrupt-controller;
+ interrupts-extended = <&L7 11 &L7 9 &L11 11 &L11 9 &L15 11 &L15 9 &L19 11 &L19 9>;
+ reg = <0x0 0xc000000 0x0 0x4000000>;
+ reg-names = "control";
+ riscv,max-priority = <7>;
+ riscv,ndev = <137>;
+ };
+ L26: local-external-interrupts-0 {
+ compatible = "sifive,local-external-interrupts0";
+ interrupt-parent = <&L7>;
+ interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
+ };
+ L27: local-external-interrupts-1 {
+ compatible = "sifive,local-external-interrupts0";
+ interrupt-parent = <&L11>;
+ interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
+ };
+ L28: local-external-interrupts-2 {
+ compatible = "sifive,local-external-interrupts0";
+ interrupt-parent = <&L15>;
+ interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
+ };
+ L29: local-external-interrupts-3 {
+ compatible = "sifive,local-external-interrupts0";
+ interrupt-parent = <&L19>;
+ interrupts = <16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31>;
+ };
+ L39: rom@10000 {
+ compatible = "sifive,maskrom0";
+ reg = <0x0 0x10000 0x0 0x10000>;
+ reg-names = "mem";
+ };
+ L1: rom@a000000 {
+ compatible = "ucbbar,cacheable-zero0";
+ reg = <0x0 0xa000000 0x0 0x2000000>;
+ };
+ L0: subsystem_pbus_clock {
+ #clock-cells = <0>;
+ clock-frequency = <5000000>;
+ clock-output-names = "subsystem_pbus_clock";
+ compatible = "fixed-clock";
+ };
+ L38: teststatus@4000 {
+ compatible = "sifive,test0";
+ reg = <0x0 0x4000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L33: trace-encoder-0@10000000 {
+ compatible = "sifive,trace";
+ reg = <0x0 0x10000000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L34: trace-encoder-1@10001000 {
+ compatible = "sifive,trace";
+ reg = <0x0 0x10001000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L35: trace-encoder-2@10002000 {
+ compatible = "sifive,trace";
+ reg = <0x0 0x10002000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L36: trace-encoder-3@10003000 {
+ compatible = "sifive,trace";
+ reg = <0x0 0x10003000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L37: trace-funnel@10008000 {
+ compatible = "sifive,trace";
+ reg = <0x0 0x10008000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L51: nb2uart0@302011000 {
+ compatible = "sifive,nb2uart0";
+ interrupt-parent = <&L3>;
+ interrupts = <64>;
+ reg = <0x3 0x02011000 0x0 0x1000>;
+ reg-names = "control";
+ clocks = <&L0>;
+ };
+ L52: nb2uart0@302012000 {
+ compatible = "sifive,nb2uart0";
+ interrupt-parent = <&L3>;
+ interrupts = <65>;
+ reg = <0x3 0x02012000 0x0 0x1000>;
+ reg-names = "control";
+ clocks = <&L0>;
+ };
+ L53: nb2wdt@302058000 {
+ compatible = "sifive,nb2wdt";
+ interrupt-parent = <&L3>;
+ interrupts = <4>;
+ reg = <0x03 0x02058000 0x00 0x1000>;
+ reg-names = "control";
+ clocks = <&L0>;
+ };
+ L54: nb2gpio@302040000 {
+ //gpio instance 1
+ compatible = "sifive,nb2gpio0";
+ interrupt-parent = <&L3>;
+ interrupts = <69>;
+ reg = <0x3 0x02040000 0x0 0x1000>;
+ reg-names = "control";
+ };
+ L55: nb2qspi0@261010000 {
+ compatible = "sifive,nb2qspi0";
+ interrupt-parent = <&L3>;
+ interrupts = <62>;
+ reg = <0x2 0x61010000 0x0 0x1000>;
+ axi-base-addr=<0x2 0x80000000 0x0 0x04000000>;
+ reg-names = "control";
+ clocks = <&L0>;
+ };
+ L56: nb2emmc@301007000 {
+ compatible = "sifive,nb2emmc";
+ interrupt-parent = <&L3>;
+ interrupts = <45 46>;
+ reg = <0x3 0x01007000 0x0 0x1000>;
+ bus-width =<4>;
+ dma-enable =<0>;
+ max-frequency = <26000000>;
+ reg-names = "mem";
+ clocks = <&L0>;
+ };
+ L57: nb2i2c0@60000 {
+ compatible = "synopsys,i2c_v2_02a_standard";
+ interrupt-parent = <&L3>;
+ interrupts = <60>;
+ reg = <0x3 0x02021000 0x0 0x1000>;
+ reg-names = "control";
+ clocks = <&L0>;
+ };
+ L58: flash {
+ compatible = "sifive,flash";
+ baud = <100000>;
+ chip-select = <1>;
+ spi-max-frequency = <2000000>;
+ jedec-id = <0xc2 0x80 0x3a>;
+ label = "MX25UM512";
+ size = <0x2000000>;
+ erase-block-size = <0x10000>;
+ write-block-size = <1>;
+ };
+ };
+};
diff --git a/bsp/sifive-nb2/design.dts b/bsp/sifive-nb2/design.dts
new file mode 100644
index 000000000..76db5c908
--- /dev/null
+++ b/bsp/sifive-nb2/design.dts
@@ -0,0 +1,24 @@
+/include/ "core.dts"
+/ {
+ chosen {
+ metal,entry = <&testram1 0 0>;
+ metal,boothart = <&L10>;
+ metal,eccscrub = <1>;
+ metal,itim = <&L30 0 0>;
+ metal,ram = <&L30 0 0>;
+ };
+};
+&L32 {
+ testram1: testram@100000000 {
+ compatible = "sifive,testram0";
+ reg = <0x1 0x0 0x0 0x1fffffff>;
+ reg-names = "mem";
+ };
+};
+&L31 {
+ testram2: testram@c00000000 {
+ compatible = "sifive,testram0";
+ reg = <0x8 0x0 0x0 0x1fffffff>;
+ reg-names = "mem";
+ };
+};
diff --git a/bsp/sifive-nb2/design.svd b/bsp/sifive-nb2/design.svd
new file mode 100644
index 000000000..404026b7a
--- /dev/null
+++ b/bsp/sifive-nb2/design.svd
@@ -0,0 +1,1045 @@
+
+
+ SiFive_FU700
+ 0.1
+ From SiFive,FU700,model device generator
+ 8
+ 32
+ 32
+ read-write
+
+
+ sifive_ccache0_0
+ From sifive,ccache0,control peripheral generator
+ 0x2010000
+
+ 0
+ 0x4000
+ registers
+
+
+
+ config
+ Information about the Cache Configuration
+ 0x0
+
+
+ banks
+ Number of banks in the cache
+ [7:0]
+ read-only
+
+
+ ways
+ Number of ways per bank
+ [15:8]
+ read-only
+
+
+ lgsets
+ Base-2 logarithm of the sets per bank
+ [23:16]
+ read-only
+
+
+ lgblockbytes
+ Base-2 logarithm of the bytes per cache block
+ [31:24]
+ read-only
+
+
+
+
+ wayenable
+ The index of the largest way which has been enabled. May only be increased.
+ 0x8
+
+
+ l2perfevent0
+ The L2 performance event0 control register.
+ 0x2000
+
+
+ l2perfevent1
+ The L2 performance event1 control register.
+ 0x2008
+
+
+ l2clientfilter
+ The L2 Client Filterregister.
+ 0x2800
+
+
+ l2pmcounter0
+ The L2 performance monitor counter0 register.
+ 0x3000
+
+
+ l2pmcounter1
+ The L2 performance monitor counter1 register.
+ 0x3008
+
+
+ l2pmcounter63
+ The L2 performance monitor counter63 register.
+ 0x31F8
+
+
+
+
+ riscv_clint0_0
+ From riscv,clint0,control peripheral generator
+ 0x2000000
+
+ 0
+ 0x10000
+ registers
+
+
+
+ msip_0
+ MSIP Register for hart 0
+ 0x0
+
+
+ msip_1
+ MSIP Register for hart 1
+ 0x4
+
+
+ msip_2
+ MSIP Register for hart 2
+ 0x8
+
+
+ msip_3
+ MSIP Register for hart 3
+ 0xC
+
+
+ mtimecmp_0
+ MTIMECMP Register for hart 0
+ 0x4000
+ 64
+
+
+ mtimecmp_1
+ MTIMECMP Register for hart 1
+ 0x4008
+ 64
+
+
+ mtimecmp_2
+ MTIMECMP Register for hart 2
+ 0x4010
+ 64
+
+
+ mtimecmp_3
+ MTIMECMP Register for hart 3
+ 0x4018
+ 64
+
+
+ mtime
+ MTIME Register
+ 0xBFF8
+ 64
+
+
+
+
+ riscv_plic0_0
+ From riscv,plic0,control peripheral generator
+ 0xC000000
+
+ 0
+ 0x4000000
+ registers
+
+
+
+ priority_1
+ PRIORITY Register for interrupt id 1
+ 0x4
+
+
+ priority_2
+ PRIORITY Register for interrupt id 2
+ 0x8
+
+
+ priority_3
+ PRIORITY Register for interrupt id 3
+ 0xC
+
+
+ priority_4
+ PRIORITY Register for interrupt id 4
+ 0x10
+
+
+ priority_5
+ PRIORITY Register for interrupt id 5
+ 0x14
+
+
+ priority_6
+ PRIORITY Register for interrupt id 6
+ 0x18
+
+
+ priority_7
+ PRIORITY Register for interrupt id 7
+ 0x1C
+
+
+ priority_8
+ PRIORITY Register for interrupt id 8
+ 0x20
+
+
+ priority_9
+ PRIORITY Register for interrupt id 9
+ 0x24
+
+
+ priority_10
+ PRIORITY Register for interrupt id 10
+ 0x28
+
+
+ priority_11
+ PRIORITY Register for interrupt id 11
+ 0x2C
+
+
+ priority_12
+ PRIORITY Register for interrupt id 12
+ 0x30
+
+
+ priority_13
+ PRIORITY Register for interrupt id 13
+ 0x34
+
+
+ priority_14
+ PRIORITY Register for interrupt id 14
+ 0x38
+
+
+ priority_15
+ PRIORITY Register for interrupt id 15
+ 0x3C
+
+
+ priority_16
+ PRIORITY Register for interrupt id 16
+ 0x40
+
+
+ priority_17
+ PRIORITY Register for interrupt id 17
+ 0x44
+
+
+ priority_18
+ PRIORITY Register for interrupt id 18
+ 0x48
+
+
+ priority_19
+ PRIORITY Register for interrupt id 19
+ 0x4C
+
+
+ priority_20
+ PRIORITY Register for interrupt id 20
+ 0x50
+
+
+ priority_21
+ PRIORITY Register for interrupt id 21
+ 0x54
+
+
+ priority_22
+ PRIORITY Register for interrupt id 22
+ 0x58
+
+
+ priority_23
+ PRIORITY Register for interrupt id 23
+ 0x5C
+
+
+ priority_24
+ PRIORITY Register for interrupt id 24
+ 0x60
+
+
+ priority_25
+ PRIORITY Register for interrupt id 25
+ 0x64
+
+
+ priority_26
+ PRIORITY Register for interrupt id 26
+ 0x68
+
+
+ priority_27
+ PRIORITY Register for interrupt id 27
+ 0x6C
+
+
+ priority_28
+ PRIORITY Register for interrupt id 28
+ 0x70
+
+
+ priority_29
+ PRIORITY Register for interrupt id 29
+ 0x74
+
+
+ priority_30
+ PRIORITY Register for interrupt id 30
+ 0x78
+
+
+ priority_31
+ PRIORITY Register for interrupt id 31
+ 0x7C
+
+
+ priority_32
+ PRIORITY Register for interrupt id 32
+ 0x80
+
+
+ priority_33
+ PRIORITY Register for interrupt id 33
+ 0x84
+
+
+ priority_34
+ PRIORITY Register for interrupt id 34
+ 0x88
+
+
+ priority_35
+ PRIORITY Register for interrupt id 35
+ 0x8C
+
+
+ priority_36
+ PRIORITY Register for interrupt id 36
+ 0x90
+
+
+ priority_37
+ PRIORITY Register for interrupt id 37
+ 0x94
+
+
+ priority_38
+ PRIORITY Register for interrupt id 38
+ 0x98
+
+
+ priority_39
+ PRIORITY Register for interrupt id 39
+ 0x9C
+
+
+ priority_40
+ PRIORITY Register for interrupt id 40
+ 0xA0
+
+
+ priority_41
+ PRIORITY Register for interrupt id 41
+ 0xA4
+
+
+ priority_42
+ PRIORITY Register for interrupt id 42
+ 0xA8
+
+
+ priority_43
+ PRIORITY Register for interrupt id 43
+ 0xAC
+
+
+ priority_44
+ PRIORITY Register for interrupt id 44
+ 0xB0
+
+
+ priority_45
+ PRIORITY Register for interrupt id 45
+ 0xB4
+
+
+ priority_46
+ PRIORITY Register for interrupt id 46
+ 0xB8
+
+
+ priority_47
+ PRIORITY Register for interrupt id 47
+ 0xBC
+
+
+ priority_48
+ PRIORITY Register for interrupt id 48
+ 0xC0
+
+
+ priority_49
+ PRIORITY Register for interrupt id 49
+ 0xC4
+
+
+ priority_50
+ PRIORITY Register for interrupt id 50
+ 0xC8
+
+
+ priority_51
+ PRIORITY Register for interrupt id 51
+ 0xCC
+
+
+ priority_52
+ PRIORITY Register for interrupt id 52
+ 0xD0
+
+
+ priority_53
+ PRIORITY Register for interrupt id 53
+ 0xD4
+
+
+ priority_54
+ PRIORITY Register for interrupt id 54
+ 0xD8
+
+
+ priority_55
+ PRIORITY Register for interrupt id 55
+ 0xDC
+
+
+ priority_56
+ PRIORITY Register for interrupt id 56
+ 0xE0
+
+
+ priority_57
+ PRIORITY Register for interrupt id 57
+ 0xE4
+
+
+ priority_58
+ PRIORITY Register for interrupt id 58
+ 0xE8
+
+
+ priority_59
+ PRIORITY Register for interrupt id 59
+ 0xEC
+
+
+ priority_60
+ PRIORITY Register for interrupt id 60
+ 0xF0
+
+
+ priority_61
+ PRIORITY Register for interrupt id 61
+ 0xF4
+
+
+ priority_62
+ PRIORITY Register for interrupt id 62
+ 0xF8
+
+
+ priority_63
+ PRIORITY Register for interrupt id 63
+ 0xFC
+
+
+ priority_64
+ PRIORITY Register for interrupt id 64
+ 0x100
+
+
+ priority_65
+ PRIORITY Register for interrupt id 65
+ 0x104
+
+
+ priority_66
+ PRIORITY Register for interrupt id 66
+ 0x108
+
+
+ priority_67
+ PRIORITY Register for interrupt id 67
+ 0x10C
+
+
+ priority_68
+ PRIORITY Register for interrupt id 68
+ 0x110
+
+
+ priority_69
+ PRIORITY Register for interrupt id 69
+ 0x114
+
+
+ priority_70
+ PRIORITY Register for interrupt id 70
+ 0x118
+
+
+ priority_71
+ PRIORITY Register for interrupt id 71
+ 0x11C
+
+
+ priority_72
+ PRIORITY Register for interrupt id 72
+ 0x120
+
+
+ priority_73
+ PRIORITY Register for interrupt id 73
+ 0x124
+
+
+ priority_74
+ PRIORITY Register for interrupt id 74
+ 0x128
+
+
+ priority_75
+ PRIORITY Register for interrupt id 75
+ 0x12C
+
+
+ priority_76
+ PRIORITY Register for interrupt id 76
+ 0x130
+
+
+ priority_77
+ PRIORITY Register for interrupt id 77
+ 0x134
+
+
+ priority_78
+ PRIORITY Register for interrupt id 78
+ 0x138
+
+
+ priority_79
+ PRIORITY Register for interrupt id 79
+ 0x13C
+
+
+ priority_80
+ PRIORITY Register for interrupt id 80
+ 0x140
+
+
+ priority_81
+ PRIORITY Register for interrupt id 81
+ 0x144
+
+
+ priority_82
+ PRIORITY Register for interrupt id 82
+ 0x148
+
+
+ priority_83
+ PRIORITY Register for interrupt id 83
+ 0x14C
+
+
+ priority_84
+ PRIORITY Register for interrupt id 84
+ 0x150
+
+
+ priority_85
+ PRIORITY Register for interrupt id 85
+ 0x154
+
+
+ priority_86
+ PRIORITY Register for interrupt id 86
+ 0x158
+
+
+ priority_87
+ PRIORITY Register for interrupt id 87
+ 0x15C
+
+
+ priority_88
+ PRIORITY Register for interrupt id 88
+ 0x160
+
+
+ priority_89
+ PRIORITY Register for interrupt id 89
+ 0x164
+
+
+ priority_90
+ PRIORITY Register for interrupt id 90
+ 0x168
+
+
+ priority_91
+ PRIORITY Register for interrupt id 91
+ 0x16C
+
+
+ priority_92
+ PRIORITY Register for interrupt id 92
+ 0x170
+
+
+ priority_93
+ PRIORITY Register for interrupt id 93
+ 0x174
+
+
+ priority_94
+ PRIORITY Register for interrupt id 94
+ 0x178
+
+
+ priority_95
+ PRIORITY Register for interrupt id 95
+ 0x17C
+
+
+ priority_96
+ PRIORITY Register for interrupt id 96
+ 0x180
+
+
+ priority_97
+ PRIORITY Register for interrupt id 97
+ 0x184
+
+
+ priority_98
+ PRIORITY Register for interrupt id 98
+ 0x188
+
+
+ priority_99
+ PRIORITY Register for interrupt id 99
+ 0x18C
+
+
+ priority_100
+ PRIORITY Register for interrupt id 100
+ 0x190
+
+
+ priority_101
+ PRIORITY Register for interrupt id 101
+ 0x194
+
+
+ priority_102
+ PRIORITY Register for interrupt id 102
+ 0x198
+
+
+ priority_103
+ PRIORITY Register for interrupt id 103
+ 0x19C
+
+
+ priority_104
+ PRIORITY Register for interrupt id 104
+ 0x1A0
+
+
+ priority_105
+ PRIORITY Register for interrupt id 105
+ 0x1A4
+
+
+ priority_106
+ PRIORITY Register for interrupt id 106
+ 0x1A8
+
+
+ priority_107
+ PRIORITY Register for interrupt id 107
+ 0x1AC
+
+
+ priority_108
+ PRIORITY Register for interrupt id 108
+ 0x1B0
+
+
+ priority_109
+ PRIORITY Register for interrupt id 109
+ 0x1B4
+
+
+ priority_110
+ PRIORITY Register for interrupt id 110
+ 0x1B8
+
+
+ priority_111
+ PRIORITY Register for interrupt id 111
+ 0x1BC
+
+
+ priority_112
+ PRIORITY Register for interrupt id 112
+ 0x1C0
+
+
+ priority_113
+ PRIORITY Register for interrupt id 113
+ 0x1C4
+
+
+ priority_114
+ PRIORITY Register for interrupt id 114
+ 0x1C8
+
+
+ priority_115
+ PRIORITY Register for interrupt id 115
+ 0x1CC
+
+
+ priority_116
+ PRIORITY Register for interrupt id 116
+ 0x1D0
+
+
+ priority_117
+ PRIORITY Register for interrupt id 117
+ 0x1D4
+
+
+ priority_118
+ PRIORITY Register for interrupt id 118
+ 0x1D8
+
+
+ priority_119
+ PRIORITY Register for interrupt id 119
+ 0x1DC
+
+
+ priority_120
+ PRIORITY Register for interrupt id 120
+ 0x1E0
+
+
+ priority_121
+ PRIORITY Register for interrupt id 121
+ 0x1E4
+
+
+ priority_122
+ PRIORITY Register for interrupt id 122
+ 0x1E8
+
+
+ priority_123
+ PRIORITY Register for interrupt id 123
+ 0x1EC
+
+
+ priority_124
+ PRIORITY Register for interrupt id 124
+ 0x1F0
+
+
+ priority_125
+ PRIORITY Register for interrupt id 125
+ 0x1F4
+
+
+ priority_126
+ PRIORITY Register for interrupt id 126
+ 0x1F8
+
+
+ priority_127
+ PRIORITY Register for interrupt id 127
+ 0x1FC
+
+
+ priority_128
+ PRIORITY Register for interrupt id 128
+ 0x200
+
+
+ priority_129
+ PRIORITY Register for interrupt id 129
+ 0x204
+
+
+ priority_130
+ PRIORITY Register for interrupt id 130
+ 0x208
+
+
+ priority_131
+ PRIORITY Register for interrupt id 131
+ 0x20C
+
+
+ priority_132
+ PRIORITY Register for interrupt id 132
+ 0x210
+
+
+ priority_133
+ PRIORITY Register for interrupt id 133
+ 0x214
+
+
+ priority_134
+ PRIORITY Register for interrupt id 134
+ 0x218
+
+
+ priority_135
+ PRIORITY Register for interrupt id 135
+ 0x21C
+
+
+ priority_136
+ PRIORITY Register for interrupt id 136
+ 0x220
+
+
+ priority_137
+ PRIORITY Register for interrupt id 137
+ 0x224
+
+
+ pending_0
+ PENDING Register for interrupt ids 31 to 0
+ 0x1000
+
+
+ pending_1
+ PENDING Register for interrupt ids 63 to 32
+ 0x1004
+
+
+ pending_2
+ PENDING Register for interrupt ids 95 to 64
+ 0x1008
+
+
+ pending_3
+ PENDING Register for interrupt ids 127 to 96
+ 0x100C
+
+
+ pending_4
+ PENDING Register for interrupt ids 137 to 128
+ 0x1010
+
+
+ enable_0_0
+ ENABLE Register for interrupt ids 31 to 0 for hart 0
+ 0x2000
+
+
+ enable_1_0
+ ENABLE Register for interrupt ids 63 to 32 for hart 0
+ 0x2004
+
+
+ enable_2_0
+ ENABLE Register for interrupt ids 95 to 64 for hart 0
+ 0x2008
+
+
+ enable_3_0
+ ENABLE Register for interrupt ids 127 to 96 for hart 0
+ 0x200C
+
+
+ enable_4_0
+ ENABLE Register for interrupt ids 137 to 128 for hart 0
+ 0x2010
+
+
+ enable_0_1
+ ENABLE Register for interrupt ids 31 to 0 for hart 1
+ 0x2080
+
+
+ enable_1_1
+ ENABLE Register for interrupt ids 63 to 32 for hart 1
+ 0x2084
+
+
+ enable_2_1
+ ENABLE Register for interrupt ids 95 to 64 for hart 1
+ 0x2088
+
+
+ enable_3_1
+ ENABLE Register for interrupt ids 127 to 96 for hart 1
+ 0x208C
+
+
+ enable_4_1
+ ENABLE Register for interrupt ids 137 to 128 for hart 1
+ 0x2090
+
+
+ enable_0_2
+ ENABLE Register for interrupt ids 31 to 0 for hart 2
+ 0x2100
+
+
+ enable_1_2
+ ENABLE Register for interrupt ids 63 to 32 for hart 2
+ 0x2104
+
+
+ enable_2_2
+ ENABLE Register for interrupt ids 95 to 64 for hart 2
+ 0x2108
+
+
+ enable_3_2
+ ENABLE Register for interrupt ids 127 to 96 for hart 2
+ 0x210C
+
+
+ enable_4_2
+ ENABLE Register for interrupt ids 137 to 128 for hart 2
+ 0x2110
+
+
+ enable_0_3
+ ENABLE Register for interrupt ids 31 to 0 for hart 3
+ 0x2180
+
+
+ enable_1_3
+ ENABLE Register for interrupt ids 63 to 32 for hart 3
+ 0x2184
+
+
+ enable_2_3
+ ENABLE Register for interrupt ids 95 to 64 for hart 3
+ 0x2188
+
+
+ enable_3_3
+ ENABLE Register for interrupt ids 127 to 96 for hart 3
+ 0x218C
+
+
+ enable_4_3
+ ENABLE Register for interrupt ids 137 to 128 for hart 3
+ 0x2190
+
+
+ threshold_0
+ PRIORITY THRESHOLD Register for hart 0
+ 0x200000
+
+
+ claimplete_0
+ CLAIM and COMPLETE Register for hart 0
+ 0x200004
+
+
+ threshold_1
+ PRIORITY THRESHOLD Register for hart 1
+ 0x201000
+
+
+ claimplete_1
+ CLAIM and COMPLETE Register for hart 1
+ 0x201004
+
+
+ threshold_2
+ PRIORITY THRESHOLD Register for hart 2
+ 0x202000
+
+
+ claimplete_2
+ CLAIM and COMPLETE Register for hart 2
+ 0x202004
+
+
+ threshold_3
+ PRIORITY THRESHOLD Register for hart 3
+ 0x203000
+
+
+ claimplete_3
+ CLAIM and COMPLETE Register for hart 3
+ 0x203004
+
+
+
+
+ sifive_test0_0
+ From sifive,test0,control peripheral generator
+ 0x4000
+
+ 0
+ 0x1000
+ registers
+
+
+
+ finisher
+ Test finisher register
+ 0x0
+
+
+ status
+ Test status
+ [15:0]
+ read-write
+
+
+ code
+ Finisher code
+ [31:16]
+ read-write
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/bsp/sifive-nb2/metal-inline.h b/bsp/sifive-nb2/metal-inline.h
new file mode 100644
index 000000000..0faccb7ec
--- /dev/null
+++ b/bsp/sifive-nb2/metal-inline.h
@@ -0,0 +1,361 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+/* ----------------------------------- */
+/* ----------------------------------- */
+
+#ifndef ASSEMBLY
+
+#ifndef METAL_INLINE_H
+#define METAL_INLINE_H
+
+#include
+
+
+/* --------------------- fixed_clock ------------ */
+extern __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock);
+
+
+/* --------------------- fixed_factor_clock ------------ */
+
+
+/* --------------------- sifive_clint0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller);
+extern __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx);
+
+
+/* --------------------- cpu ------------ */
+extern __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu);
+extern __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu);
+extern __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu);
+extern __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu);
+
+
+/* --------------------- sifive_plic0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller);
+extern __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx);
+extern __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid);
+
+
+/* --------------------- sifive_buserror0 ------------ */
+extern __inline__ uintptr_t __metal_driver_sifive_buserror0_control_base(const struct metal_buserror *beu);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_buserror0_interrupt_parent(const struct metal_buserror *beu);
+extern __inline__ int __metal_driver_sifive_buserror0_interrupt_id(const struct metal_buserror *beu);
+
+
+/* --------------------- sifive_clic0 ------------ */
+
+
+/* --------------------- sifive_local_external_interrupts0 ------------ */
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx);
+
+
+/* --------------------- sifive_global_external_interrupts0 ------------ */
+extern __inline__ int __metal_driver_sifive_global_external_interrupts0_init_done( );
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_global_external_interrupts0_interrupt_parent(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_global_external_interrupts0_num_interrupts(struct metal_interrupt *controller);
+extern __inline__ int __metal_driver_sifive_global_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx);
+
+
+/* --------------------- sifive_gpio0 ------------ */
+
+
+/* --------------------- sifive_gpio_button ------------ */
+
+
+/* --------------------- sifive_gpio_led ------------ */
+
+
+/* --------------------- sifive_gpio_switch ------------ */
+
+
+/* --------------------- sifive_i2c0 ------------ */
+
+
+/* --------------------- sifive_pwm0 ------------ */
+
+
+/* --------------------- sifive_rtc0 ------------ */
+
+
+/* --------------------- sifive_spi0 ------------ */
+
+
+/* --------------------- sifive_test0 ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_test0_base(const struct __metal_shutdown *sd);
+extern __inline__ unsigned long __metal_driver_sifive_test0_size(const struct __metal_shutdown *sd);
+
+
+/* --------------------- sifive_trace ------------ */
+extern __inline__ unsigned long __metal_driver_sifive_trace_base(const struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_trace_size(const struct metal_uart *uart);
+
+/* --------------------- sifive_nb2emmc ------------ */
+extern __inline__ unsigned long long __metal_driver_sifive_nb2emmc_base(struct metal_emmc *emmc);
+extern __inline__ unsigned long long __metal_driver_sifive_nb2emmc_size(struct metal_emmc *emmc);
+extern __inline__ int __metal_driver_sifive_nb2emmc_num_interrupts(struct metal_emmc *emmc);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_nb2emmc_interrupt_parent(struct metal_emmc *emmc);
+extern __inline__ int __metal_driver_sifive_nb2emmc_interrupt_lines(struct metal_emmc *emmc, int idx);
+
+
+/* --------------------- sifive_nb2qspi0 ------------ */
+extern __inline__ unsigned long long __metal_driver_sifive_nb2qspi0_control_base(struct metal_qspi *qspi);
+extern __inline__ unsigned long long __metal_driver_sifive_nb2qspi0_control_size(struct metal_qspi *qspi);
+extern __inline__ struct __metal_driver_sifive_nb2gpio0 * __metal_driver_sifive_nb2qspi0_pinmux(struct metal_qspi *qspi);
+extern __inline__ unsigned long __metal_driver_sifive_nb2qspi0_pinmux_output_selector(struct metal_qspi *qspi);
+extern __inline__ unsigned long __metal_driver_sifive_nb2qspi0_pinmux_source_selector(struct metal_qspi *qspi);
+
+
+/* --------------------- sifive_nb2uart0 ------------ */
+extern __inline__ unsigned long long __metal_driver_sifive_nb2uart0_control_base(struct metal_uart *uart);
+extern __inline__ unsigned long long __metal_driver_sifive_nb2uart0_control_size(struct metal_uart *uart);
+extern __inline__ int __metal_driver_sifive_nb2uart0_num_interrupts(struct metal_uart *uart);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_nb2uart0_interrupt_parent(struct metal_uart *uart);
+extern __inline__ int __metal_driver_sifive_nb2uart0_interrupt_line(struct metal_uart *uart);
+extern __inline__ struct metal_clock * __metal_driver_sifive_nb2uart0_clock(struct metal_uart *uart);
+extern __inline__ struct __metal_driver_sifive_nb2gpio0 * __metal_driver_sifive_nb2uart0_pinmux(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_nb2uart0_pinmux_output_selector(struct metal_uart *uart);
+extern __inline__ unsigned long __metal_driver_sifive_nb2uart0_pinmux_source_selector(struct metal_uart *uart);
+
+
+/* --------------------- sifive_nb2wdt ------------ */
+extern __inline__ unsigned long long __metal_driver_sifive_nb2wdt_control_base(const struct metal_watchdog *const watchdog);
+extern __inline__ unsigned long long __metal_driver_sifive_nb2wdt_control_size(const struct metal_watchdog *const watchdog);
+extern __inline__ struct metal_interrupt * __metal_driver_sifive_nb2wdt_interrupt_parent(const struct metal_watchdog *const watchdog);
+extern __inline__ int __metal_driver_sifive_nb2wdt_interrupt_line(const struct metal_watchdog *const watchdog);
+extern __inline__ struct metal_clock * __metal_driver_sifive_nb2wdt_clock(const struct metal_watchdog *const watchdog);
+
+
+/* --------------------- sifive_fe310_g000_hfrosc ------------ */
+
+
+/* --------------------- sifive_fe310_g000_hfxosc ------------ */
+
+
+/* --------------------- sifive_fe310_g000_lfrosc ------------ */
+
+
+/* --------------------- sifive_fe310_g000_pll ------------ */
+
+
+/* --------------------- fe310_g000_prci ------------ */
+
+
+/* From subsystem_pbus_clock */
+struct __metal_driver_fixed_clock __metal_dt_subsystem_pbus_clock = {
+ .clock.vtable = &__metal_driver_vtable_fixed_clock.clock,
+};
+
+struct metal_memory __metal_dt_mem_testram_100000000 = {
+ ._base_address = 4294967296UL,
+ ._size = 536870911UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+struct metal_memory __metal_dt_mem_testram_c00000000 = {
+ ._base_address = 51539607552UL,
+ ._size = 536870911UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+struct metal_memory __metal_dt_mem_memory_800000000 = {
+ ._base_address = 34359738368UL,
+ ._size = 8589934592UL,
+ ._attrs = {
+ .R = 1,
+ .W = 1,
+ .X = 1,
+ .C = 1,
+ .A = 1},
+};
+
+/* From clint@2000000 */
+struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000 = {
+ .controller.vtable = &__metal_driver_vtable_riscv_clint0.clint_vtable,
+ .init_done = 0,
+};
+
+/* From cpu@0 */
+struct __metal_driver_cpu __metal_dt_cpu_0 = {
+ .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+ .hpm_count = 0,
+};
+
+/* From cpu@1 */
+struct __metal_driver_cpu __metal_dt_cpu_1 = {
+ .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+ .hpm_count = 0,
+};
+
+/* From cpu@2 */
+struct __metal_driver_cpu __metal_dt_cpu_2 = {
+ .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+ .hpm_count = 0,
+};
+
+/* From cpu@3 */
+struct __metal_driver_cpu __metal_dt_cpu_3 = {
+ .cpu.vtable = &__metal_driver_vtable_cpu.cpu_vtable,
+ .hpm_count = 0,
+};
+
+/* From interrupt_controller */
+struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller = {
+ .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable,
+ .init_done = 0,
+};
+
+/* From interrupt_controller */
+struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_1_interrupt_controller = {
+ .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable,
+ .init_done = 0,
+};
+
+/* From interrupt_controller */
+struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_2_interrupt_controller = {
+ .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable,
+ .init_done = 0,
+};
+
+/* From interrupt_controller */
+struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_3_interrupt_controller = {
+ .controller.vtable = &__metal_driver_vtable_riscv_cpu_intc.controller_vtable,
+ .init_done = 0,
+};
+
+/* From interrupt_controller@c000000 */
+struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000 = {
+ .controller.vtable = &__metal_driver_vtable_riscv_plic0.plic_vtable,
+ .init_done = 0,
+};
+
+struct metal_pmp __metal_dt_pmp;
+
+/* From bus_error_unit@1700000 */
+struct metal_buserror __metal_dt_bus_error_unit_1700000 = {
+};
+
+/* From bus_error_unit@1701000 */
+struct metal_buserror __metal_dt_bus_error_unit_1701000 = {
+};
+
+/* From bus_error_unit@1702000 */
+struct metal_buserror __metal_dt_bus_error_unit_1702000 = {
+};
+
+/* From bus_error_unit@1703000 */
+struct metal_buserror __metal_dt_bus_error_unit_1703000 = {
+};
+
+/* From local_external_interrupts_0 */
+struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0 = {
+ .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
+ .init_done = 0,
+};
+
+/* From local_external_interrupts_1 */
+struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_1 = {
+ .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
+ .init_done = 0,
+};
+
+/* From local_external_interrupts_2 */
+struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_2 = {
+ .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
+ .init_done = 0,
+};
+
+/* From local_external_interrupts_3 */
+struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_3 = {
+ .irc.vtable = &__metal_driver_vtable_sifive_local_external_interrupts0.local0_vtable,
+ .init_done = 0,
+};
+
+/* From global_external_interrupts */
+struct __metal_driver_sifive_global_external_interrupts0 __metal_dt_global_external_interrupts = {
+ .irc.vtable = &__metal_driver_vtable_sifive_global_external_interrupts0.global0_vtable,
+ .init_done = 0,
+};
+
+/* From teststatus@4000 */
+struct __metal_driver_sifive_test0 __metal_dt_teststatus_4000 = {
+ .shutdown.vtable = &__metal_driver_vtable_sifive_test0.shutdown,
+};
+
+/* From trace_encoder_0@10000000 */
+struct __metal_driver_sifive_trace __metal_dt_trace_encoder_0_10000000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_trace.uart,
+};
+
+/* From trace_encoder_1@10001000 */
+struct __metal_driver_sifive_trace __metal_dt_trace_encoder_1_10001000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_trace.uart,
+};
+
+/* From trace_encoder_2@10002000 */
+struct __metal_driver_sifive_trace __metal_dt_trace_encoder_2_10002000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_trace.uart,
+};
+
+/* From trace_encoder_3@10003000 */
+struct __metal_driver_sifive_trace __metal_dt_trace_encoder_3_10003000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_trace.uart,
+};
+
+/* From trace_funnel@10008000 */
+struct __metal_driver_sifive_trace __metal_dt_trace_funnel_10008000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_trace.uart,
+};
+
+/* From nb2emmc@301007000 */
+struct __metal_driver_sifive_nb2emmc __metal_dt_nb2emmc_301007000 = {
+ .emmc.vtable = &__metal_driver_vtable_sifive_nb2emmc.emmc,
+};
+
+/* From flash */
+struct __metal_driver_sifive_flash __metal_dt_flash = {
+ .flash.vtable = &__metal_driver_vtable_sifive_flash.flash,
+};
+
+/* From nb2qspi0@261010000 */
+struct __metal_driver_sifive_nb2qspi0 __metal_dt_nb2qspi0_261010000 = {
+ .qspi.vtable = &__metal_driver_vtable_sifive_nb2qspi0.qspi,
+};
+
+/* From nb2uart0@302011000 */
+struct __metal_driver_sifive_nb2uart0 __metal_dt_nb2uart0_302011000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_nb2uart0.uart,
+};
+
+/* From nb2uart0@302012000 */
+struct __metal_driver_sifive_nb2uart0 __metal_dt_nb2uart0_302012000 = {
+ .uart.vtable = &__metal_driver_vtable_sifive_nb2uart0.uart,
+};
+
+/* From nb2wdt@302058000 */
+struct __metal_driver_sifive_nb2wdt __metal_dt_nb2wdt_302058000 = {
+ .watchdog.vtable = &__metal_driver_vtable_sifive_nb2wdt.watchdog,
+};
+
+
+#endif /* METAL_INLINE_H*/
+#endif /* ! ASSEMBLY */
diff --git a/bsp/sifive-nb2/metal-platform.h b/bsp/sifive-nb2/metal-platform.h
new file mode 100644
index 000000000..6a91d8aeb
--- /dev/null
+++ b/bsp/sifive-nb2/metal-platform.h
@@ -0,0 +1,395 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+/* ----------------------------------- */
+/* ----------------------------------- */
+
+#ifndef METAL_PLATFORM_H
+#define METAL_PLATFORM_H
+
+/* From subsystem_pbus_clock */
+#define METAL_FIXED_CLOCK__CLOCK_FREQUENCY 5000000UL
+
+#define METAL_FIXED_CLOCK
+
+/* From clint@2000000 */
+#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432ULL
+#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432ULL
+#define METAL_RISCV_CLINT0_2000000_SIZE 65536ULL
+#define METAL_RISCV_CLINT0_0_SIZE 65536ULL
+
+#define METAL_RISCV_CLINT0
+#define METAL_RISCV_CLINT0_MSIP_BASE 0UL
+#define METAL_RISCV_CLINT0_MTIMECMP_BASE 16384UL
+#define METAL_RISCV_CLINT0_MTIME 49144UL
+
+/* From interrupt_controller@c000000 */
+#define METAL_RISCV_PLIC0_C000000_BASE_ADDRESS 201326592ULL
+#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592ULL
+#define METAL_RISCV_PLIC0_C000000_SIZE 67108864ULL
+#define METAL_RISCV_PLIC0_0_SIZE 67108864ULL
+#define METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY 7UL
+#define METAL_RISCV_PLIC0_0_RISCV_MAX_PRIORITY 7UL
+#define METAL_RISCV_PLIC0_C000000_RISCV_NDEV 138UL
+#define METAL_RISCV_PLIC0_0_RISCV_NDEV 138UL
+
+#define METAL_RISCV_PLIC0
+#define METAL_RISCV_PLIC0_PRIORITY_BASE 0UL
+#define METAL_RISCV_PLIC0_PENDING_BASE 4096UL
+#define METAL_RISCV_PLIC0_ENABLE_BASE 8192UL
+#define METAL_RISCV_PLIC0_ENABLE_PER_HART 128UL
+#define METAL_RISCV_PLIC0_CONTEXT_BASE 2097152UL
+#define METAL_RISCV_PLIC0_CONTEXT_PER_HART 4096UL
+#define METAL_RISCV_PLIC0_CONTEXT_THRESHOLD 0UL
+#define METAL_RISCV_PLIC0_CONTEXT_CLAIM 4UL
+
+/* From bus_error_unit@1700000 */
+#define METAL_SIFIVE_BUSERROR0_1700000_BASE_ADDRESS 24117248ULL
+#define METAL_SIFIVE_BUSERROR0_0_BASE_ADDRESS 24117248ULL
+#define METAL_SIFIVE_BUSERROR0_1700000_SIZE 4096ULL
+#define METAL_SIFIVE_BUSERROR0_0_SIZE 4096ULL
+
+/* From bus_error_unit@1701000 */
+#define METAL_SIFIVE_BUSERROR0_1701000_BASE_ADDRESS 24121344ULL
+#define METAL_SIFIVE_BUSERROR0_1_BASE_ADDRESS 24121344ULL
+#define METAL_SIFIVE_BUSERROR0_1701000_SIZE 4096ULL
+#define METAL_SIFIVE_BUSERROR0_1_SIZE 4096ULL
+
+/* From bus_error_unit@1702000 */
+#define METAL_SIFIVE_BUSERROR0_1702000_BASE_ADDRESS 24125440ULL
+#define METAL_SIFIVE_BUSERROR0_2_BASE_ADDRESS 24125440ULL
+#define METAL_SIFIVE_BUSERROR0_1702000_SIZE 4096ULL
+#define METAL_SIFIVE_BUSERROR0_2_SIZE 4096ULL
+
+/* From bus_error_unit@1703000 */
+#define METAL_SIFIVE_BUSERROR0_1703000_BASE_ADDRESS 24129536ULL
+#define METAL_SIFIVE_BUSERROR0_3_BASE_ADDRESS 24129536ULL
+#define METAL_SIFIVE_BUSERROR0_1703000_SIZE 4096ULL
+#define METAL_SIFIVE_BUSERROR0_3_SIZE 4096ULL
+
+#define METAL_SIFIVE_BUSERROR0
+#define METAL_SIFIVE_BUSERROR0_CAUSE 0UL
+#define METAL_SIFIVE_BUSERROR0_VALUE 8UL
+#define METAL_SIFIVE_BUSERROR0_ENABLE 16UL
+#define METAL_SIFIVE_BUSERROR0_PLATFORM_INTERRUPT 24UL
+#define METAL_SIFIVE_BUSERROR0_ACCRUED 32UL
+#define METAL_SIFIVE_BUSERROR0_LOCAL_INTERRUPT 40UL
+
+/* From cache_controller@2010000 */
+#define METAL_SIFIVE_CCACHE0_2010000_BASE_ADDRESS 33619968ULL
+#define METAL_SIFIVE_CCACHE0_0_BASE_ADDRESS 33619968ULL
+#define METAL_SIFIVE_CCACHE0_2010000_SIZE 16384ULL
+#define METAL_SIFIVE_CCACHE0_0_SIZE 16384ULL
+
+#define METAL_SIFIVE_CCACHE0
+#define METAL_SIFIVE_CCACHE0_CONFIG 0UL
+#define METAL_SIFIVE_CCACHE0_WAYENABLE 8UL
+#define METAL_SIFIVE_CCACHE0_ECCINJECTERROR 64UL
+#define METAL_SIFIVE_CCACHE0_DIRECCFIXLOW 256UL
+#define METAL_SIFIVE_CCACHE0_DIRECCFIXHIGH 260UL
+#define METAL_SIFIVE_CCACHE0_DIRECCFIXCOUNT 264UL
+#define METAL_SIFIVE_CCACHE0_DIRECCFAILLOW 288UL
+#define METAL_SIFIVE_CCACHE0_DIRECCFAILHIGH 292UL
+#define METAL_SIFIVE_CCACHE0_DIRECCFAILCOUNT 296UL
+#define METAL_SIFIVE_CCACHE0_DATECCFIXLOW 320UL
+#define METAL_SIFIVE_CCACHE0_DATECCFIXHIGH 324UL
+#define METAL_SIFIVE_CCACHE0_DATECCFIXCOUNT 328UL
+#define METAL_SIFIVE_CCACHE0_DATECCFAILLOW 352UL
+#define METAL_SIFIVE_CCACHE0_DATECCFAILHIGH 356UL
+#define METAL_SIFIVE_CCACHE0_DATECCFAILCOUNT 360UL
+#define METAL_SIFIVE_CCACHE0_FLUSH64 512UL
+#define METAL_SIFIVE_CCACHE0_FLUSH32 576UL
+#define METAL_SIFIVE_CCACHE0_WAYMASK0 2048UL
+#define METAL_SIFIVE_CCACHE0_PMEVENTSELECT0 8192UL
+#define METAL_SIFIVE_CCACHE0_PMCLIENTFILTER 10240UL
+#define METAL_SIFIVE_CCACHE0_PMEVENTCOUNTER0 12288UL
+
+/* From error_device@3000 */
+#define METAL_SIFIVE_ERROR0_3000_BASE_ADDRESS 12288ULL
+#define METAL_SIFIVE_ERROR0_0_BASE_ADDRESS 12288ULL
+#define METAL_SIFIVE_ERROR0_3000_SIZE 4096ULL
+#define METAL_SIFIVE_ERROR0_0_SIZE 4096ULL
+
+#define METAL_SIFIVE_ERROR0
+
+/* From global_external_interrupts */
+
+#define METAL_SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0
+
+/* From local_external_interrupts_0 */
+
+/* From local_external_interrupts_1 */
+
+/* From local_external_interrupts_2 */
+
+/* From local_external_interrupts_3 */
+
+#define METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0
+
+/* From teststatus@4000 */
+#define METAL_SIFIVE_TEST0_4000_BASE_ADDRESS 16384ULL
+#define METAL_SIFIVE_TEST0_0_BASE_ADDRESS 16384ULL
+#define METAL_SIFIVE_TEST0_4000_SIZE 4096ULL
+#define METAL_SIFIVE_TEST0_0_SIZE 4096ULL
+
+#define METAL_SIFIVE_TEST0
+#define METAL_SIFIVE_TEST0_FINISHER_OFFSET 0UL
+
+/* From trace_encoder_0@10000000 */
+#define METAL_SIFIVE_TRACE_10000000_BASE_ADDRESS 268435456ULL
+#define METAL_SIFIVE_TRACE_0_BASE_ADDRESS 268435456ULL
+#define METAL_SIFIVE_TRACE_10000000_SIZE 4096ULL
+#define METAL_SIFIVE_TRACE_0_SIZE 4096ULL
+
+/* From trace_encoder_1@10001000 */
+#define METAL_SIFIVE_TRACE_10001000_BASE_ADDRESS 268439552ULL
+#define METAL_SIFIVE_TRACE_1_BASE_ADDRESS 268439552ULL
+#define METAL_SIFIVE_TRACE_10001000_SIZE 4096ULL
+#define METAL_SIFIVE_TRACE_1_SIZE 4096ULL
+
+/* From trace_encoder_2@10002000 */
+#define METAL_SIFIVE_TRACE_10002000_BASE_ADDRESS 268443648ULL
+#define METAL_SIFIVE_TRACE_2_BASE_ADDRESS 268443648ULL
+#define METAL_SIFIVE_TRACE_10002000_SIZE 4096ULL
+#define METAL_SIFIVE_TRACE_2_SIZE 4096ULL
+
+/* From trace_encoder_3@10003000 */
+#define METAL_SIFIVE_TRACE_10003000_BASE_ADDRESS 268447744ULL
+#define METAL_SIFIVE_TRACE_3_BASE_ADDRESS 268447744ULL
+#define METAL_SIFIVE_TRACE_10003000_SIZE 4096ULL
+#define METAL_SIFIVE_TRACE_3_SIZE 4096ULL
+
+/* From trace_funnel@10008000 */
+#define METAL_SIFIVE_TRACE_10008000_BASE_ADDRESS 268468224ULL
+#define METAL_SIFIVE_TRACE_4_BASE_ADDRESS 268468224ULL
+#define METAL_SIFIVE_TRACE_10008000_SIZE 4096ULL
+#define METAL_SIFIVE_TRACE_4_SIZE 4096ULL
+
+#define METAL_SIFIVE_TRACE
+#define METAL_SIFIVE_TRACE_TECONTROL 0UL
+#define METAL_SIFIVE_TRACE_TEIMPL 4UL
+#define METAL_SIFIVE_TRACE_TESINKBASE 16UL
+#define METAL_SIFIVE_TRACE_TESINKBASEHIGH 20UL
+#define METAL_SIFIVE_TRACE_TESINKBASELIMIT 24UL
+#define METAL_SIFIVE_TRACE_TESINKSINKWP 28UL
+#define METAL_SIFIVE_TRACE_TESINKSINKRP 32UL
+#define METAL_SIFIVE_TRACE_TESINKSINKDATA 36UL
+#define METAL_SIFIVE_TRACE_TSCONTROL 64UL
+#define METAL_SIFIVE_TRACE_TSLOWER 68UL
+#define METAL_SIFIVE_TRACE_TSUPPER 72UL
+#define METAL_SIFIVE_TRACE_XTICONTROL 80UL
+#define METAL_SIFIVE_TRACE_XTOCONTROL 84UL
+#define METAL_SIFIVE_TRACE_WPCONTROL 88UL
+#define METAL_SIFIVE_TRACE_ITCTRACEENABLE 96UL
+#define METAL_SIFIVE_TRACE_ITCTRIGENABLE 100UL
+#define METAL_SIFIVE_TRACE_ITCSTIMULUS 128UL
+#define METAL_SIFIVE_TRACE_ATBSINK 3584UL
+#define METAL_SIFIVE_TRACE_PBISINK 3840UL
+
+/* From hca@20000000 */
+#define METAL_SIFIVE_HCA_VERSION 1283UL
+
+#define METAL_SIFIVE_HCA_20000000_BASE_ADDRESS 536870912ULL
+#define METAL_SIFIVE_HCA_0_BASE_ADDRESS 536870912ULL
+#define METAL_SIFIVE_HCA_20000000_SIZE 4096ULL
+#define METAL_SIFIVE_HCA_0_SIZE 4096ULL
+
+#define METAL_SIFIVE_HCA_CR 0UL
+#define METAL_SIFIVE_HCA_AES_CR 16UL
+#define METAL_SIFIVE_HCA_AES_ALEN 32UL
+#define METAL_SIFIVE_HCA_AES_PDLEN 40UL
+#define METAL_SIFIVE_HCA_AES_KEY 48UL
+#define METAL_SIFIVE_HCA_AES_INITV 80UL
+#define METAL_SIFIVE_HCA_SHA_CR 96UL
+#define METAL_SIFIVE_HCA_FIFO_IN 112UL
+#define METAL_SIFIVE_HCA_AES_OUT 128UL
+#define METAL_SIFIVE_HCA_AES_AUTH 144UL
+#define METAL_SIFIVE_HCA_HASH 160UL
+#define METAL_SIFIVE_HCA_TRNG_CR 224UL
+#define METAL_SIFIVE_HCA_TRNG_SR 228UL
+#define METAL_SIFIVE_HCA_TRNG_DATA 232UL
+#define METAL_SIFIVE_HCA_TRNG_TRIM 236UL
+#define METAL_SIFIVE_HCA_DMA_CR 272UL
+#define METAL_SIFIVE_HCA_DMA_LEN 276UL
+#define METAL_SIFIVE_HCA_DMA_SRC 280UL
+#define METAL_SIFIVE_HCA_DMA_DEST 284UL
+#define METAL_SIFIVE_HCA_HCA_REV 512UL
+#define METAL_SIFIVE_HCA_AES_REV 516UL
+#define METAL_SIFIVE_HCA_SHA_REV 520UL
+#define METAL_SIFIVE_HCA_TRNG_REV 524UL
+
+/* From nb2emmc@301007000 */
+#define METAL_SIFIVE_NB2EMMC_301007000_BASE_ADDRESS 12901707776ULL
+#define METAL_SIFIVE_NB2EMMC_0_BASE_ADDRESS 12901707776ULL
+#define METAL_SIFIVE_NB2EMMC_301007000_SIZE 4096ULL
+#define METAL_SIFIVE_NB2EMMC_0_SIZE 4096ULL
+
+#define METAL_SIFIVE_NB2EMMC
+#define METAL_SIFIVE_NB2EMMC_HRS00 0UL
+#define METAL_SIFIVE_NB2EMMC_HRS01 4UL
+#define METAL_SIFIVE_NB2EMMC_HRS02 8UL
+#define METAL_SIFIVE_NB2EMMC_HRS03 12UL
+#define METAL_SIFIVE_NB2EMMC_HRS04 16UL
+#define METAL_SIFIVE_NB2EMMC_HRS05 20UL
+#define METAL_SIFIVE_NB2EMMC_HRS06 24UL
+#define METAL_SIFIVE_NB2EMMC_HRS07 28UL
+#define METAL_SIFIVE_NB2EMMC_HRS30 120UL
+#define METAL_SIFIVE_NB2EMMC_HRS31 124UL
+#define METAL_SIFIVE_NB2EMMC_HRS32 128UL
+#define METAL_SIFIVE_NB2EMMC_HRS33 132UL
+#define METAL_SIFIVE_NB2EMMC_HRS34 136UL
+#define METAL_SIFIVE_NB2EMMC_HRS35 140UL
+#define METAL_SIFIVE_NB2EMMC_HRS36 144UL
+#define METAL_SIFIVE_NB2EMMC_HRS37 148UL
+#define METAL_SIFIVE_NB2EMMC_HRS38 152UL
+#define METAL_SIFIVE_NB2EMMC_CRS63 252UL
+#define METAL_SIFIVE_NB2EMMC_SRS00 512UL
+#define METAL_SIFIVE_NB2EMMC_SRS01 516UL
+#define METAL_SIFIVE_NB2EMMC_SRS02 520UL
+#define METAL_SIFIVE_NB2EMMC_SRS03 524UL
+#define METAL_SIFIVE_NB2EMMC_SRS04 528UL
+#define METAL_SIFIVE_NB2EMMC_SRS05 532UL
+#define METAL_SIFIVE_NB2EMMC_SRS06 536UL
+#define METAL_SIFIVE_NB2EMMC_SRS07 540UL
+#define METAL_SIFIVE_NB2EMMC_SRS08 544UL
+#define METAL_SIFIVE_NB2EMMC_SRS09 548UL
+#define METAL_SIFIVE_NB2EMMC_SRS10 552UL
+#define METAL_SIFIVE_NB2EMMC_SRS11 556UL
+#define METAL_SIFIVE_NB2EMMC_SRS12 560UL
+#define METAL_SIFIVE_NB2EMMC_SRS13 564UL
+#define METAL_SIFIVE_NB2EMMC_SRS14 568UL
+#define METAL_SIFIVE_NB2EMMC_SRS15 572UL
+#define METAL_SIFIVE_NB2EMMC_SRS16 576UL
+#define METAL_SIFIVE_NB2EMMC_SRS17 580UL
+#define METAL_SIFIVE_NB2EMMC_SRS18 584UL
+#define METAL_SIFIVE_NB2EMMC_SRS19 588UL
+#define METAL_SIFIVE_NB2EMMC_SRS20 592UL
+#define METAL_SIFIVE_NB2EMMC_SRS21 596UL
+#define METAL_SIFIVE_NB2EMMC_SRS22 600UL
+#define METAL_SIFIVE_NB2EMMC_SRS23 604UL
+#define METAL_SIFIVE_NB2EMMC_SRS24 608UL
+#define METAL_SIFIVE_NB2EMMC_SRS25 612UL
+#define METAL_SIFIVE_NB2EMMC_SRS26 616UL
+#define METAL_SIFIVE_NB2EMMC_SRS27 620UL
+#define METAL_SIFIVE_NB2EMMC_SRS28 624UL
+#define METAL_SIFIVE_NB2EMMC_SRS29 628UL
+#define METAL_SIFIVE_NB2EMMC_CQRS00 1024UL
+#define METAL_SIFIVE_NB2EMMC_CQRS01 1028UL
+#define METAL_SIFIVE_NB2EMMC_CQRS02 1032UL
+#define METAL_SIFIVE_NB2EMMC_CORS03 1036UL
+#define METAL_SIFIVE_NB2EMMC_CQRS04 1040UL
+#define METAL_SIFIVE_NB2EMMC_CQRS05 1044UL
+#define METAL_SIFIVE_NB2EMMC_CQRS06 1048UL
+#define METAL_SIFIVE_NB2EMMC_CQRS07 1052UL
+#define METAL_SIFIVE_NB2EMMC_CQRS08 1056UL
+#define METAL_SIFIVE_NB2EMMC_CQRS09 1060UL
+#define METAL_SIFIVE_NB2EMMC_CQRS10 1064UL
+#define METAL_SIFIVE_NB2EMMC_CQRS11 1068UL
+#define METAL_SIFIVE_NB2EMMC_CQRS12 1072UL
+#define METAL_SIFIVE_NB2EMMC_CQRS13 1076UL
+#define METAL_SIFIVE_NB2EMMC_CQRS14 1080UL
+#define METAL_SIFIVE_NB2EMMC_CQRS16 1088UL
+#define METAL_SIFIVE_NB2EMMC_CQRS17 1092UL
+#define METAL_SIFIVE_NB2EMMC_CQRS18 1096UL
+#define METAL_SIFIVE_NB2EMMC_CQRS19 1100UL
+#define METAL_SIFIVE_NB2EMMC_CQRS20 1104UL
+#define METAL_SIFIVE_NB2EMMC_CQRS21 1108UL
+#define METAL_SIFIVE_NB2EMMC_CQRS22 1112UL
+#define METAL_SIFIVE_NB2EMMC_CQRS23 1116UL
+
+/* From nb2qspi0@261010000 */
+#define METAL_SIFIVE_NB2QSPI0_261010000_BASE_ADDRESS 10217390080ULL
+#define METAL_SIFIVE_NB2QSPI0_0_BASE_ADDRESS 10217390080ULL
+#define METAL_SIFIVE_NB2QSPI0_261010000_SIZE 4096ULL
+#define METAL_SIFIVE_NB2QSPI0_0_SIZE 4096ULL
+
+#define METAL_SIFIVE_NB2QSPI0
+#define METAL_SIFIVE_NB2QSPI0_COMMAND_REG 0UL
+#define METAL_SIFIVE_NB2QSPI0_ADDRESS_REG 4UL
+#define METAL_SIFIVE_NB2QSPI0_DUMMY_DLP_REG 8UL
+#define METAL_SIFIVE_NB2QSPI0_MODE_REG 12UL
+#define METAL_SIFIVE_NB2QSPI0_CMD_CFG_REG 16UL
+#define METAL_SIFIVE_NB2QSPI0_TX_DATA_REG 20UL
+#define METAL_SIFIVE_NB2QSPI0_RX_DATA_REG 24UL
+#define METAL_SIFIVE_NB2QSPI0_START_CMD_REG 28UL
+#define METAL_SIFIVE_NB2QSPI0_CUSTOM_CMD_REG 32UL
+#define METAL_SIFIVE_NB2QSPI0_INTR_STAT_REG 36UL
+#define METAL_SIFIVE_NB2QSPI0_INTR_MASK_CLR_REG 40UL
+#define METAL_SIFIVE_NB2QSPI0_BAUD_RATE_REG 44UL
+#define METAL_SIFIVE_NB2QSPI0_BURST_CTRL_REG 48UL
+#define METAL_SIFIVE_NB2QSPI0_SYSTEM_STATUS_REG 52UL
+
+/* From nb2uart0@302011000 */
+#define METAL_SIFIVE_NB2UART0_302011000_BASE_ADDRESS 12918525952ULL
+#define METAL_SIFIVE_NB2UART0_0_BASE_ADDRESS 12918525952ULL
+#define METAL_SIFIVE_NB2UART0_302011000_SIZE 4096ULL
+#define METAL_SIFIVE_NB2UART0_0_SIZE 4096ULL
+
+/* From nb2uart0@302012000 */
+#define METAL_SIFIVE_NB2UART0_302012000_BASE_ADDRESS 12918530048ULL
+#define METAL_SIFIVE_NB2UART0_1_BASE_ADDRESS 12918530048ULL
+#define METAL_SIFIVE_NB2UART0_302012000_SIZE 4096ULL
+#define METAL_SIFIVE_NB2UART0_1_SIZE 4096ULL
+
+#define METAL_SIFIVE_NB2UART0
+#define METAL_SIFIVE_NB2UART0_RBR 0UL
+#define METAL_SIFIVE_NB2UART0_DLL 0UL
+#define METAL_SIFIVE_NB2UART0_THR 0UL
+#define METAL_SIFIVE_NB2UART0_DLH 4UL
+#define METAL_SIFIVE_NB2UART0_IER 4UL
+#define METAL_SIFIVE_NB2UART0_FCR 8UL
+#define METAL_SIFIVE_NB2UART0_IIR 8UL
+#define METAL_SIFIVE_NB2UART0_LCR 12UL
+#define METAL_SIFIVE_NB2UART0_MCR 16UL
+#define METAL_SIFIVE_NB2UART0_LSR 20UL
+#define METAL_SIFIVE_NB2UART0_MSR 24UL
+#define METAL_SIFIVE_NB2UART0_SCR 28UL
+#define METAL_SIFIVE_NB2UART0_LPDLL 32UL
+#define METAL_SIFIVE_NB2UART0_LPDLH 36UL
+#define METAL_SIFIVE_NB2UART0_FAR 112UL
+#define METAL_SIFIVE_NB2UART0_TFR 116UL
+#define METAL_SIFIVE_NB2UART0_RFW 120UL
+#define METAL_SIFIVE_NB2UART0_USR 124UL
+#define METAL_SIFIVE_NB2UART0_TFL 128UL
+#define METAL_SIFIVE_NB2UART0_RFL 132UL
+#define METAL_SIFIVE_NB2UART0_SRR 136UL
+#define METAL_SIFIVE_NB2UART0_SRTS 140UL
+#define METAL_SIFIVE_NB2UART0_SBCR 144UL
+#define METAL_SIFIVE_NB2UART0_SDMAM 148UL
+#define METAL_SIFIVE_NB2UART0_SFE 152UL
+#define METAL_SIFIVE_NB2UART0_SRT 156UL
+#define METAL_SIFIVE_NB2UART0_STET 160UL
+#define METAL_SIFIVE_NB2UART0_HTX 164UL
+#define METAL_SIFIVE_NB2UART0_DMASA 168UL
+#define METAL_SIFIVE_NB2UART0_TCR 172UL
+#define METAL_SIFIVE_NB2UART0_DE_EN 176UL
+#define METAL_SIFIVE_NB2UART0_RE_EN 180UL
+#define METAL_SIFIVE_NB2UART0_DET 184UL
+#define METAL_SIFIVE_NB2UART0_TAT 188UL
+#define METAL_SIFIVE_NB2UART0_DLF 192UL
+#define METAL_SIFIVE_NB2UART0_RAR 196UL
+#define METAL_SIFIVE_NB2UART0_TAR 200UL
+#define METAL_SIFIVE_NB2UART0_LCR_EXT 204UL
+#define METAL_SIFIVE_NB2UART0_UART_PROT_LEVEL 208UL
+#define METAL_SIFIVE_NB2UART0_REG_TIMEOUT_RST 212UL
+#define METAL_SIFIVE_NB2UART0_CPR 244UL
+#define METAL_SIFIVE_NB2UART0_UCV 248UL
+#define METAL_SIFIVE_NB2UART0_CTR 252UL
+
+/* From nb2wdt@302058000 */
+#define METAL_SIFIVE_NB2WDT_302058000_BASE_ADDRESS 12918816768ULL
+#define METAL_SIFIVE_NB2WDT_0_BASE_ADDRESS 12918816768ULL
+#define METAL_SIFIVE_NB2WDT_302058000_SIZE 4096ULL
+#define METAL_SIFIVE_NB2WDT_0_SIZE 4096ULL
+
+#define METAL_SIFIVE_NB2WDT
+#define METAL_SIFIVE_NB2WDT_WDT_ENABLE 1UL
+#define METAL_SIFIVE_NB2WDT_WDT_DISABLE 0UL
+#define METAL_SIFIVE_NB2WDT_WDT_RESTART 118UL
+#define METAL_SIFIVE_NB2WDT_WDT_CR 0UL
+#define METAL_SIFIVE_NB2WDT_WDT_TORR 4UL
+#define METAL_SIFIVE_NB2WDT_WDT_CCVR 8UL
+#define METAL_SIFIVE_NB2WDT_WDT_CRR 12UL
+#define METAL_SIFIVE_NB2WDT_WDT_STAT 16UL
+#define METAL_SIFIVE_NB2WDT_WDT_EOI 20UL
+
+#endif /* METAL_PLATFORM_H*/
diff --git a/bsp/sifive-nb2/metal.default.lds b/bsp/sifive-nb2/metal.default.lds
new file mode 100644
index 000000000..4bd4f131e
--- /dev/null
+++ b/bsp/sifive-nb2/metal.default.lds
@@ -0,0 +1,308 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* Default Linker Script
+ *
+ * This is the default linker script for all Freedom Metal applications.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ lim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x1e0000
+ ram (airwx) : ORIGIN = 0x800000000, LENGTH = 0x200000000
+ rom (irx!wa) : ORIGIN = 0x100000000, LENGTH = 0x1fffffff
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 1);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ /* The memory_ecc_scrub bit is used by _entry code to enable/disable
+ * memories scrubbing to zero */
+ PROVIDE(__metal_eccscrub_bit = 1);
+
+ /* The RAM memories map for ECC scrubbing */
+ /* Default zero-scrub to at most 64KB, for limiting RTL simulation run time. */
+ /* User is recommended to enable the full size for manual RTL simulation run! */
+ PROVIDE( metal_lim_0_memory_start = 0x8000000 );
+ PROVIDE( metal_lim_0_memory_end = 0x8000000 + 0x10000 );
+ /* Default zero-scrub to at most 64KB, for limiting RTL simulation run time. */
+ /* User is recommended to enable the full size for manual RTL simulation run! */
+ PROVIDE( metal_memory_0_memory_start = 0x800000000 );
+ PROVIDE( metal_memory_0_memory_end = 0x800000000 + 0x10000 );
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >rom :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >rom :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >rom :rom
+
+
+
+ .ctors : {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >rom :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >rom : rom
+
+ .rodata : {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >rom :rom
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >ram AT>rom :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >lim AT>rom :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >rom :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>rom :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>rom :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ . += __stack_size; /* Hart 1 */
+ . += __stack_size; /* Hart 2 */
+ . += __stack_size; /* Hart 3 */
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/bsp/sifive-nb2/metal.freertos.lds b/bsp/sifive-nb2/metal.freertos.lds
new file mode 100644
index 000000000..5bdc426fd
--- /dev/null
+++ b/bsp/sifive-nb2/metal.freertos.lds
@@ -0,0 +1,334 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* Privileged mode Linker Script
+ *
+ * This linker script is based on metal.default.lds. It introduce specific
+ * section to isolate (acessible only from machine mode) and others that can be
+ * used in every execution mode. This linker script it tailored for FreeRTOS
+ * applications.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ lim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x1e0000
+ ram (airwx) : ORIGIN = 0x800000000, LENGTH = 0x200000000
+ rom (irx!wa) : ORIGIN = 0x100000000, LENGTH = 0x1fffffff
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 1);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ /* The memory_ecc_scrub bit is used by _entry code to enable/disable
+ * memories scrubbing to zero */
+ PROVIDE(__metal_eccscrub_bit = 1);
+
+ /* The RAM memories map for ECC scrubbing */
+ /* Default zero-scrub to at most 64KB, for limiting RTL simulation run time. */
+ /* User is recommended to enable the full size for manual RTL simulation run! */
+ PROVIDE( metal_lim_0_memory_start = 0x8000000 );
+ PROVIDE( metal_lim_0_memory_end = 0x8000000 + 0x10000 );
+ /* Default zero-scrub to at most 64KB, for limiting RTL simulation run time. */
+ /* User is recommended to enable the full size for manual RTL simulation run! */
+ PROVIDE( metal_memory_0_memory_start = 0x800000000 );
+ PROVIDE( metal_memory_0_memory_end = 0x800000000 + 0x10000 );
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >rom :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >rom :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >rom :rom
+
+ .privileged_functions : ALIGN (32) {
+ __privileged_functions_start__ = .;
+ KEEP(*(privileged_functions))
+ . = ALIGN(32);
+ __privileged_functions_end__ = .;
+ } >rom
+
+
+ .ctors : {
+ . = ALIGN(32);
+ __unprivileged_section_start__ = .;
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >rom :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >rom : rom
+
+ .rodata : {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >rom :rom
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >ram AT>rom :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >lim AT>rom :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ *(freertos_system_calls)
+ . = ALIGN(32);
+ __unprivileged_section_end__ = .;
+ } >rom :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ . = ALIGN(32);
+ __unprivileged_data_section_start__ = .;
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>rom :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>rom :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(32);
+ __unprivileged_data_section_end__ = .;
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+ .privileged_data (NOLOAD) : ALIGN(32) {
+ __privileged_data_start__ = .;
+ *(privileged_data)
+ /* Non kernel data is kept out of the first _Privileged_Data_Region_Size
+ bytes of SRAM. */
+ . = ALIGN(32);
+ __privileged_data_end__ = .;
+ } >ram
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ . += __stack_size; /* Hart 1 */
+ . += __stack_size; /* Hart 2 */
+ . += __stack_size; /* Hart 3 */
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/bsp/sifive-nb2/metal.h b/bsp/sifive-nb2/metal.h
new file mode 100644
index 000000000..075a8d069
--- /dev/null
+++ b/bsp/sifive-nb2/metal.h
@@ -0,0 +1,1818 @@
+/* Copyright 2019 SiFive, Inc */
+/* SPDX-License-Identifier: Apache-2.0 */
+/* ----------------------------------- */
+/* ----------------------------------- */
+
+#ifndef ASSEMBLY
+
+#include
+
+#ifdef __METAL_MACHINE_MACROS
+
+#ifndef MACROS_IF_METAL_H
+#define MACROS_IF_METAL_H
+
+#define __METAL_CLINT_NUM_PARENTS 8
+
+#ifndef __METAL_CLINT_NUM_PARENTS
+#define __METAL_CLINT_NUM_PARENTS 0
+#endif
+#define __METAL_PLIC_SUBINTERRUPTS 138
+
+#define __METAL_PLIC_NUM_PARENTS 8
+
+#ifndef __METAL_PLIC_SUBINTERRUPTS
+#define __METAL_PLIC_SUBINTERRUPTS 0
+#endif
+#ifndef __METAL_PLIC_NUM_PARENTS
+#define __METAL_PLIC_NUM_PARENTS 0
+#endif
+#ifndef __METAL_CLIC_SUBINTERRUPTS
+#define __METAL_CLIC_SUBINTERRUPTS 0
+#endif
+
+#endif /* MACROS_IF_METAL_H*/
+
+#else /* ! __METAL_MACHINE_MACROS */
+
+#ifndef MACROS_ELSE_METAL_H
+#define MACROS_ELSE_METAL_H
+
+#define __METAL_CLINT_2000000_INTERRUPTS 8
+
+#define METAL_MAX_CLINT_INTERRUPTS 8
+
+#define __METAL_CLINT_NUM_PARENTS 8
+
+#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 8
+
+#define __METAL_PLIC_SUBINTERRUPTS 138
+
+#define METAL_MAX_PLIC_INTERRUPTS 8
+
+#define __METAL_PLIC_NUM_PARENTS 8
+
+#define METAL_SIFIVE_CCACHE0_INTERRUPTS { 130, 131, 132, 133, }
+
+#define METAL_SIFIVE_CCACHE0_INTERRUPT_PARENT &__metal_dt_interrupt_controller_c000000.controller
+
+#define METAL_CACHE_DRIVER_PREFIX sifive_ccache0
+
+#define METAL_SIFIVE_CCACHE0_PERFMON_COUNTERS 0
+
+#define __METAL_DT_SIFIVE_CCACHE0_HANDLE (struct metal_cache *)NULL
+
+#define __METAL_CLIC_SUBINTERRUPTS 0
+#define METAL_MAX_CLIC_INTERRUPTS 0
+
+#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_0_INTERRUPTS 16
+
+#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_1_INTERRUPTS 16
+
+#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_2_INTERRUPTS 16
+
+#define __METAL_LOCAL_EXTERNAL_INTERRUPTS_3_INTERRUPTS 16
+
+#define METAL_MAX_LOCAL_EXT_INTERRUPTS 16
+
+#define __METAL_GLOBAL_EXTERNAL_INTERRUPTS_INTERRUPTS 127
+
+#define METAL_MAX_GLOBAL_EXT_INTERRUPTS 127
+
+#define METAL_MAX_GPIO_INTERRUPTS 0
+
+#define METAL_MAX_I2C0_INTERRUPTS 0
+
+#define METAL_MAX_PWM0_INTERRUPTS 0
+
+#define METAL_MAX_PWM0_NCMP 0
+
+#define __METAL_NB2EMMC_301007000_INTERRUPTS 2
+
+#define METAL_MAX_EMMC_INTERRUPTS 2
+
+#define METAL_EMMC_BUS_WIDTH 4
+
+#define METAL_DMA_ENABLE 0
+
+#define METAL_EMMC_MAX_FREQUENCY 26000000
+
+#define METAL_FLASH_LABEL "MX25UM512"
+
+#define METAL_JEDEC_ID_0 194
+
+#define METAL_JEDEC_ID_1 128
+
+#define METAL_JEDEC_ID_2 58
+
+#define METAL_FLASH_BAUD 100000
+
+#define METAL_FLASH_CHIP_SELECT 1
+
+#define METAL_FLASH_SPI_MAX_FREQUENCY 2000000
+
+#define METAL_FLASH_SIZE 33554432
+
+#define METAL_FLASH_ERASE_BLOCK_SIZE 65536
+
+#define METAL_FLASH_WRITE_BLOCK_SIZE 1
+
+#define METAL_QSPI_AXI_BASE_ADDR 10737418240
+
+#define METAL_QSPI_AXI_SIZE 67108864
+
+#define __METAL_NB2UART0_302011000_INTERRUPTS 1
+
+#define __METAL_NB2UART0_302012000_INTERRUPTS 1
+
+#define METAL_MAX_UART_INTERRUPTS 1
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* From subsystem_pbus_clock */
+extern struct __metal_driver_fixed_clock __metal_dt_subsystem_pbus_clock;
+
+extern struct metal_memory __metal_dt_mem_testram_100000000;
+
+extern struct metal_memory __metal_dt_mem_testram_c00000000;
+
+extern struct metal_memory __metal_dt_mem_memory_800000000;
+
+/* From clint@2000000 */
+extern struct __metal_driver_riscv_clint0 __metal_dt_clint_2000000;
+
+/* From cpu@0 */
+extern struct __metal_driver_cpu __metal_dt_cpu_0;
+
+/* From cpu@1 */
+extern struct __metal_driver_cpu __metal_dt_cpu_1;
+
+/* From cpu@2 */
+extern struct __metal_driver_cpu __metal_dt_cpu_2;
+
+/* From cpu@3 */
+extern struct __metal_driver_cpu __metal_dt_cpu_3;
+
+extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_interrupt_controller;
+
+extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_1_interrupt_controller;
+
+extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_2_interrupt_controller;
+
+extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_3_interrupt_controller;
+
+/* From interrupt_controller@c000000 */
+extern struct __metal_driver_riscv_plic0 __metal_dt_interrupt_controller_c000000;
+
+extern struct metal_pmp __metal_dt_pmp;
+
+/* From bus_error_unit@1700000 */
+extern struct metal_buserror __metal_dt_bus_error_unit_1700000;
+
+/* From bus_error_unit@1701000 */
+extern struct metal_buserror __metal_dt_bus_error_unit_1701000;
+
+/* From bus_error_unit@1702000 */
+extern struct metal_buserror __metal_dt_bus_error_unit_1702000;
+
+/* From bus_error_unit@1703000 */
+extern struct metal_buserror __metal_dt_bus_error_unit_1703000;
+
+/* From local_external_interrupts_0 */
+extern struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_0;
+
+/* From local_external_interrupts_1 */
+extern struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_1;
+
+/* From local_external_interrupts_2 */
+extern struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_2;
+
+/* From local_external_interrupts_3 */
+extern struct __metal_driver_sifive_local_external_interrupts0 __metal_dt_local_external_interrupts_3;
+
+/* From global_external_interrupts */
+extern struct __metal_driver_sifive_global_external_interrupts0 __metal_dt_global_external_interrupts;
+
+/* From teststatus@4000 */
+extern struct __metal_driver_sifive_test0 __metal_dt_teststatus_4000;
+
+/* From trace_encoder_0@10000000 */
+extern struct __metal_driver_sifive_trace __metal_dt_trace_encoder_0_10000000;
+
+/* From trace_encoder_1@10001000 */
+extern struct __metal_driver_sifive_trace __metal_dt_trace_encoder_1_10001000;
+
+/* From trace_encoder_2@10002000 */
+extern struct __metal_driver_sifive_trace __metal_dt_trace_encoder_2_10002000;
+
+/* From trace_encoder_3@10003000 */
+extern struct __metal_driver_sifive_trace __metal_dt_trace_encoder_3_10003000;
+
+/* From trace_funnel@10008000 */
+extern struct __metal_driver_sifive_trace __metal_dt_trace_funnel_10008000;
+
+/* From nb2emmc@301007000 */
+extern struct __metal_driver_sifive_nb2emmc __metal_dt_nb2emmc_301007000;
+
+/* From flash */
+extern struct __metal_driver_sifive_flash __metal_dt_flash;
+
+/* From nb2qspi0@261010000 */
+extern struct __metal_driver_sifive_nb2qspi0 __metal_dt_nb2qspi0_261010000;
+
+/* From nb2uart0@302011000 */
+extern struct __metal_driver_sifive_nb2uart0 __metal_dt_nb2uart0_302011000;
+
+/* From nb2uart0@302012000 */
+extern struct __metal_driver_sifive_nb2uart0 __metal_dt_nb2uart0_302012000;
+
+/* From nb2wdt@302058000 */
+extern struct __metal_driver_sifive_nb2wdt __metal_dt_nb2wdt_302058000;
+
+
+
+/* --------------------- fixed_clock ------------ */
+static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock)
+{
+ if ((uintptr_t)clock == (uintptr_t)&__metal_dt_subsystem_pbus_clock) {
+ return METAL_FIXED_CLOCK__CLOCK_FREQUENCY;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- fixed_factor_clock ------------ */
+
+
+/* --------------------- sifive_clint0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_clint0_control_base(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
+ return METAL_RISCV_CLINT0_2000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_clint0_control_size(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
+ return METAL_RISCV_CLINT0_2000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_clint0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_clint_2000000) {
+ return METAL_MAX_CLINT_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_clint0_interrupt_parents(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if (idx == 1) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if (idx == 2) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_1_interrupt_controller.controller;
+ }
+ else if (idx == 3) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_1_interrupt_controller.controller;
+ }
+ else if (idx == 4) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_2_interrupt_controller.controller;
+ }
+ else if (idx == 5) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_2_interrupt_controller.controller;
+ }
+ else if (idx == 6) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_3_interrupt_controller.controller;
+ }
+ else if (idx == 7) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_3_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_clint0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 3;
+ }
+ else if (idx == 1) {
+ return 7;
+ }
+ else if (idx == 2) {
+ return 3;
+ }
+ else if (idx == 3) {
+ return 7;
+ }
+ else if (idx == 4) {
+ return 3;
+ }
+ else if (idx == 5) {
+ return 7;
+ }
+ else if (idx == 6) {
+ return 3;
+ }
+ else if (idx == 7) {
+ return 7;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- cpu ------------ */
+static __inline__ int __metal_driver_cpu_hartid(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return 0;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_1) {
+ return 1;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_2) {
+ return 2;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_3) {
+ return 3;
+ }
+ else {
+ return -1;
+ }
+}
+
+static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return 1000000;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_1) {
+ return 1000000;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_2) {
+ return 1000000;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_3) {
+ return 1000000;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_cpu_interrupt_controller(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return &__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_1) {
+ return &__metal_dt_cpu_1_interrupt_controller.controller;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_2) {
+ return &__metal_dt_cpu_2_interrupt_controller.controller;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_3) {
+ return &__metal_dt_cpu_3_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ int __metal_driver_cpu_num_pmp_regions(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return 4;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_1) {
+ return 4;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_2) {
+ return 4;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_3) {
+ return 4;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_buserror * __metal_driver_cpu_buserror(struct metal_cpu *cpu)
+{
+ if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) {
+ return &__metal_dt_bus_error_unit_1700000;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_1) {
+ return &__metal_dt_bus_error_unit_1701000;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_2) {
+ return &__metal_dt_bus_error_unit_1702000;
+ }
+ else if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_3) {
+ return &__metal_dt_bus_error_unit_1703000;
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+
+/* --------------------- sifive_plic0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_plic0_control_base(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_plic0_control_size(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_plic0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_RISCV_NDEV;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_plic0_max_priority(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_interrupt_controller_c000000) {
+ return METAL_RISCV_PLIC0_C000000_RISCV_MAX_PRIORITY;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_plic0_interrupt_parents(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if (idx == 1) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else if (idx == 2) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_1_interrupt_controller.controller;
+ }
+ else if (idx == 3) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_1_interrupt_controller.controller;
+ }
+ else if (idx == 4) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_2_interrupt_controller.controller;
+ }
+ else if (idx == 5) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_2_interrupt_controller.controller;
+ }
+ else if (idx == 6) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_3_interrupt_controller.controller;
+ }
+ else if (idx == 7) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_3_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 11;
+ }
+ else if (idx == 1) {
+ return 9;
+ }
+ else if (idx == 2) {
+ return 11;
+ }
+ else if (idx == 3) {
+ return 9;
+ }
+ else if (idx == 4) {
+ return 11;
+ }
+ else if (idx == 5) {
+ return 9;
+ }
+ else if (idx == 6) {
+ return 11;
+ }
+ else if (idx == 7) {
+ return 9;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid)
+{
+ if (hartid == 0) {
+ return 0;
+ }
+ else if (hartid == 1) {
+ return 2;
+ }
+ else if (hartid == 2) {
+ return 4;
+ }
+ else if (hartid == 3) {
+ return 6;
+ }
+ else {
+ return -1;
+ }
+}
+
+
+
+/* --------------------- sifive_buserror0 ------------ */
+static __inline__ uintptr_t __metal_driver_sifive_buserror0_control_base(const struct metal_buserror *buserror)
+{
+ if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1700000) {
+ return METAL_SIFIVE_BUSERROR0_1700000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1701000) {
+ return METAL_SIFIVE_BUSERROR0_1701000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1702000) {
+ return METAL_SIFIVE_BUSERROR0_1702000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1703000) {
+ return METAL_SIFIVE_BUSERROR0_1703000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_buserror0_interrupt_parent(const struct metal_buserror *buserror)
+{
+ if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1700000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1701000) {
+ return NULL;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1702000) {
+ return NULL;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1703000) {
+ return NULL;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_buserror0_interrupt_id(const struct metal_buserror *buserror)
+{
+ if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1700000) {
+ return 134;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1701000) {
+ return 135;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1702000) {
+ return 136;
+ }
+ else if ((uintptr_t)buserror == (uintptr_t)&__metal_dt_bus_error_unit_1703000) {
+ return 137;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_clic0 ------------ */
+
+
+/* --------------------- sifive_local_external_interrupts0 ------------ */
+static __inline__ struct metal_interrupt * __metal_driver_sifive_local_external_interrupts0_interrupt_parent(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
+ return (struct metal_interrupt *)&__metal_dt_cpu_0_interrupt_controller.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_local_external_interrupts0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_local_external_interrupts_0) {
+ return METAL_MAX_LOCAL_EXT_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_local_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 16;
+ }
+ else if (idx == 1) {
+ return 17;
+ }
+ else if (idx == 2) {
+ return 18;
+ }
+ else if (idx == 3) {
+ return 19;
+ }
+ else if (idx == 4) {
+ return 20;
+ }
+ else if (idx == 5) {
+ return 21;
+ }
+ else if (idx == 6) {
+ return 22;
+ }
+ else if (idx == 7) {
+ return 23;
+ }
+ else if (idx == 8) {
+ return 24;
+ }
+ else if (idx == 9) {
+ return 25;
+ }
+ else if (idx == 10) {
+ return 26;
+ }
+ else if (idx == 11) {
+ return 27;
+ }
+ else if (idx == 12) {
+ return 28;
+ }
+ else if (idx == 13) {
+ return 29;
+ }
+ else if (idx == 14) {
+ return 30;
+ }
+ else if (idx == 15) {
+ return 31;
+ }
+ else if (idx == 0) {
+ return 16;
+ }
+ else if (idx == 1) {
+ return 17;
+ }
+ else if (idx == 2) {
+ return 18;
+ }
+ else if (idx == 3) {
+ return 19;
+ }
+ else if (idx == 4) {
+ return 20;
+ }
+ else if (idx == 5) {
+ return 21;
+ }
+ else if (idx == 6) {
+ return 22;
+ }
+ else if (idx == 7) {
+ return 23;
+ }
+ else if (idx == 8) {
+ return 24;
+ }
+ else if (idx == 9) {
+ return 25;
+ }
+ else if (idx == 10) {
+ return 26;
+ }
+ else if (idx == 11) {
+ return 27;
+ }
+ else if (idx == 12) {
+ return 28;
+ }
+ else if (idx == 13) {
+ return 29;
+ }
+ else if (idx == 14) {
+ return 30;
+ }
+ else if (idx == 15) {
+ return 31;
+ }
+ else if (idx == 0) {
+ return 16;
+ }
+ else if (idx == 1) {
+ return 17;
+ }
+ else if (idx == 2) {
+ return 18;
+ }
+ else if (idx == 3) {
+ return 19;
+ }
+ else if (idx == 4) {
+ return 20;
+ }
+ else if (idx == 5) {
+ return 21;
+ }
+ else if (idx == 6) {
+ return 22;
+ }
+ else if (idx == 7) {
+ return 23;
+ }
+ else if (idx == 8) {
+ return 24;
+ }
+ else if (idx == 9) {
+ return 25;
+ }
+ else if (idx == 10) {
+ return 26;
+ }
+ else if (idx == 11) {
+ return 27;
+ }
+ else if (idx == 12) {
+ return 28;
+ }
+ else if (idx == 13) {
+ return 29;
+ }
+ else if (idx == 14) {
+ return 30;
+ }
+ else if (idx == 15) {
+ return 31;
+ }
+ else if (idx == 0) {
+ return 16;
+ }
+ else if (idx == 1) {
+ return 17;
+ }
+ else if (idx == 2) {
+ return 18;
+ }
+ else if (idx == 3) {
+ return 19;
+ }
+ else if (idx == 4) {
+ return 20;
+ }
+ else if (idx == 5) {
+ return 21;
+ }
+ else if (idx == 6) {
+ return 22;
+ }
+ else if (idx == 7) {
+ return 23;
+ }
+ else if (idx == 8) {
+ return 24;
+ }
+ else if (idx == 9) {
+ return 25;
+ }
+ else if (idx == 10) {
+ return 26;
+ }
+ else if (idx == 11) {
+ return 27;
+ }
+ else if (idx == 12) {
+ return 28;
+ }
+ else if (idx == 13) {
+ return 29;
+ }
+ else if (idx == 14) {
+ return 30;
+ }
+ else if (idx == 15) {
+ return 31;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_global_external_interrupts0 ------------ */
+static __inline__ int __metal_driver_sifive_global_external_interrupts0_init_done()
+{
+ return 0;
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_global_external_interrupts0_interrupt_parent(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_global_external_interrupts) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return NULL;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_global_external_interrupts0_num_interrupts(struct metal_interrupt *controller)
+{
+ if ((uintptr_t)controller == (uintptr_t)&__metal_dt_global_external_interrupts) {
+ return METAL_MAX_GLOBAL_EXT_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_global_external_interrupts0_interrupt_lines(struct metal_interrupt *controller, int idx)
+{
+ if (idx == 0) {
+ return 3;
+ }
+ else if (idx == 1) {
+ return 4;
+ }
+ else if (idx == 2) {
+ return 5;
+ }
+ else if (idx == 3) {
+ return 6;
+ }
+ else if (idx == 4) {
+ return 7;
+ }
+ else if (idx == 5) {
+ return 8;
+ }
+ else if (idx == 6) {
+ return 9;
+ }
+ else if (idx == 7) {
+ return 10;
+ }
+ else if (idx == 8) {
+ return 11;
+ }
+ else if (idx == 9) {
+ return 12;
+ }
+ else if (idx == 10) {
+ return 13;
+ }
+ else if (idx == 11) {
+ return 14;
+ }
+ else if (idx == 12) {
+ return 15;
+ }
+ else if (idx == 13) {
+ return 16;
+ }
+ else if (idx == 14) {
+ return 17;
+ }
+ else if (idx == 15) {
+ return 18;
+ }
+ else if (idx == 16) {
+ return 19;
+ }
+ else if (idx == 17) {
+ return 20;
+ }
+ else if (idx == 18) {
+ return 21;
+ }
+ else if (idx == 19) {
+ return 22;
+ }
+ else if (idx == 20) {
+ return 23;
+ }
+ else if (idx == 21) {
+ return 24;
+ }
+ else if (idx == 22) {
+ return 25;
+ }
+ else if (idx == 23) {
+ return 26;
+ }
+ else if (idx == 24) {
+ return 27;
+ }
+ else if (idx == 25) {
+ return 28;
+ }
+ else if (idx == 26) {
+ return 29;
+ }
+ else if (idx == 27) {
+ return 30;
+ }
+ else if (idx == 28) {
+ return 31;
+ }
+ else if (idx == 29) {
+ return 32;
+ }
+ else if (idx == 30) {
+ return 33;
+ }
+ else if (idx == 31) {
+ return 34;
+ }
+ else if (idx == 32) {
+ return 35;
+ }
+ else if (idx == 33) {
+ return 36;
+ }
+ else if (idx == 34) {
+ return 37;
+ }
+ else if (idx == 35) {
+ return 38;
+ }
+ else if (idx == 36) {
+ return 39;
+ }
+ else if (idx == 37) {
+ return 40;
+ }
+ else if (idx == 38) {
+ return 41;
+ }
+ else if (idx == 39) {
+ return 42;
+ }
+ else if (idx == 40) {
+ return 43;
+ }
+ else if (idx == 41) {
+ return 44;
+ }
+ else if (idx == 42) {
+ return 45;
+ }
+ else if (idx == 43) {
+ return 46;
+ }
+ else if (idx == 44) {
+ return 47;
+ }
+ else if (idx == 45) {
+ return 48;
+ }
+ else if (idx == 46) {
+ return 49;
+ }
+ else if (idx == 47) {
+ return 50;
+ }
+ else if (idx == 48) {
+ return 51;
+ }
+ else if (idx == 49) {
+ return 52;
+ }
+ else if (idx == 50) {
+ return 53;
+ }
+ else if (idx == 51) {
+ return 54;
+ }
+ else if (idx == 52) {
+ return 55;
+ }
+ else if (idx == 53) {
+ return 56;
+ }
+ else if (idx == 54) {
+ return 57;
+ }
+ else if (idx == 55) {
+ return 58;
+ }
+ else if (idx == 56) {
+ return 59;
+ }
+ else if (idx == 57) {
+ return 60;
+ }
+ else if (idx == 58) {
+ return 61;
+ }
+ else if (idx == 59) {
+ return 62;
+ }
+ else if (idx == 60) {
+ return 63;
+ }
+ else if (idx == 61) {
+ return 64;
+ }
+ else if (idx == 62) {
+ return 65;
+ }
+ else if (idx == 63) {
+ return 66;
+ }
+ else if (idx == 64) {
+ return 67;
+ }
+ else if (idx == 65) {
+ return 68;
+ }
+ else if (idx == 66) {
+ return 69;
+ }
+ else if (idx == 67) {
+ return 70;
+ }
+ else if (idx == 68) {
+ return 71;
+ }
+ else if (idx == 69) {
+ return 72;
+ }
+ else if (idx == 70) {
+ return 73;
+ }
+ else if (idx == 71) {
+ return 74;
+ }
+ else if (idx == 72) {
+ return 75;
+ }
+ else if (idx == 73) {
+ return 76;
+ }
+ else if (idx == 74) {
+ return 77;
+ }
+ else if (idx == 75) {
+ return 78;
+ }
+ else if (idx == 76) {
+ return 79;
+ }
+ else if (idx == 77) {
+ return 80;
+ }
+ else if (idx == 78) {
+ return 81;
+ }
+ else if (idx == 79) {
+ return 82;
+ }
+ else if (idx == 80) {
+ return 83;
+ }
+ else if (idx == 81) {
+ return 84;
+ }
+ else if (idx == 82) {
+ return 85;
+ }
+ else if (idx == 83) {
+ return 86;
+ }
+ else if (idx == 84) {
+ return 87;
+ }
+ else if (idx == 85) {
+ return 88;
+ }
+ else if (idx == 86) {
+ return 89;
+ }
+ else if (idx == 87) {
+ return 90;
+ }
+ else if (idx == 88) {
+ return 91;
+ }
+ else if (idx == 89) {
+ return 92;
+ }
+ else if (idx == 90) {
+ return 93;
+ }
+ else if (idx == 91) {
+ return 94;
+ }
+ else if (idx == 92) {
+ return 95;
+ }
+ else if (idx == 93) {
+ return 96;
+ }
+ else if (idx == 94) {
+ return 97;
+ }
+ else if (idx == 95) {
+ return 98;
+ }
+ else if (idx == 96) {
+ return 99;
+ }
+ else if (idx == 97) {
+ return 100;
+ }
+ else if (idx == 98) {
+ return 101;
+ }
+ else if (idx == 99) {
+ return 102;
+ }
+ else if (idx == 100) {
+ return 103;
+ }
+ else if (idx == 101) {
+ return 104;
+ }
+ else if (idx == 102) {
+ return 105;
+ }
+ else if (idx == 103) {
+ return 106;
+ }
+ else if (idx == 104) {
+ return 107;
+ }
+ else if (idx == 105) {
+ return 108;
+ }
+ else if (idx == 106) {
+ return 109;
+ }
+ else if (idx == 107) {
+ return 110;
+ }
+ else if (idx == 108) {
+ return 111;
+ }
+ else if (idx == 109) {
+ return 112;
+ }
+ else if (idx == 110) {
+ return 113;
+ }
+ else if (idx == 111) {
+ return 114;
+ }
+ else if (idx == 112) {
+ return 115;
+ }
+ else if (idx == 113) {
+ return 116;
+ }
+ else if (idx == 114) {
+ return 117;
+ }
+ else if (idx == 115) {
+ return 118;
+ }
+ else if (idx == 116) {
+ return 119;
+ }
+ else if (idx == 117) {
+ return 120;
+ }
+ else if (idx == 118) {
+ return 121;
+ }
+ else if (idx == 119) {
+ return 122;
+ }
+ else if (idx == 120) {
+ return 123;
+ }
+ else if (idx == 121) {
+ return 124;
+ }
+ else if (idx == 122) {
+ return 125;
+ }
+ else if (idx == 123) {
+ return 126;
+ }
+ else if (idx == 124) {
+ return 127;
+ }
+ else if (idx == 125) {
+ return 128;
+ }
+ else if (idx == 126) {
+ return 129;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_gpio0 ------------ */
+
+
+/* --------------------- sifive_gpio_button ------------ */
+
+
+/* --------------------- sifive_gpio_led ------------ */
+
+
+/* --------------------- sifive_gpio_switch ------------ */
+
+
+/* --------------------- sifive_i2c0 ------------ */
+
+
+/* --------------------- sifive_pwm0 ------------ */
+
+
+/* --------------------- sifive_rtc0 ------------ */
+
+
+
+/* --------------------- sifive_test0 ------------ */
+static __inline__ unsigned long __metal_driver_sifive_test0_base(const struct __metal_shutdown *sd)
+{
+ if ((uintptr_t)sd == (uintptr_t)&__metal_dt_teststatus_4000) {
+ return METAL_SIFIVE_TEST0_4000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_test0_size(const struct __metal_shutdown *sd)
+{
+ if ((uintptr_t)sd == (uintptr_t)&__metal_dt_teststatus_4000) {
+ return METAL_SIFIVE_TEST0_4000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_trace ------------ */
+static __inline__ unsigned long __metal_driver_sifive_trace_base(const struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_0_10000000) {
+ return METAL_SIFIVE_TRACE_10000000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_1_10001000) {
+ return METAL_SIFIVE_TRACE_10001000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_2_10002000) {
+ return METAL_SIFIVE_TRACE_10002000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_3_10003000) {
+ return METAL_SIFIVE_TRACE_10003000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_funnel_10008000) {
+ return METAL_SIFIVE_TRACE_10008000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_trace_size(const struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_0_10000000) {
+ return METAL_SIFIVE_TRACE_10000000_SIZE;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_1_10001000) {
+ return METAL_SIFIVE_TRACE_10001000_SIZE;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_2_10002000) {
+ return METAL_SIFIVE_TRACE_10002000_SIZE;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_encoder_3_10003000) {
+ return METAL_SIFIVE_TRACE_10003000_SIZE;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_trace_funnel_10008000) {
+ return METAL_SIFIVE_TRACE_10008000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+/* --------------------- sifive_nb2emmc ------------ */
+static __inline__ unsigned long long __metal_driver_sifive_nb2emmc_base(struct metal_emmc *emmc)
+{
+ if ((uintptr_t)emmc == (uintptr_t)&__metal_dt_nb2emmc_301007000) {
+ return METAL_SIFIVE_NB2EMMC_301007000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long long __metal_driver_sifive_nb2emmc_size(struct metal_emmc *emmc)
+{
+ if ((uintptr_t)emmc == (uintptr_t)&__metal_dt_nb2emmc_301007000) {
+ return METAL_SIFIVE_NB2EMMC_301007000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_nb2emmc_num_interrupts(struct metal_emmc *emmc)
+{
+ if ((uintptr_t)emmc == (uintptr_t)&__metal_dt_nb2emmc_301007000) {
+ return METAL_MAX_EMMC_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_nb2emmc_interrupt_parent(struct metal_emmc *emmc)
+{
+ if ((uintptr_t)emmc == (uintptr_t)&__metal_dt_nb2emmc_301007000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_nb2emmc_interrupt_lines(struct metal_emmc *emmc, int idx)
+{
+ if (((uintptr_t)emmc == (uintptr_t)&__metal_dt_nb2emmc_301007000) && (idx == 0)) {
+ return 45;
+ }
+ else if ((((uintptr_t)emmc == (uintptr_t)&__metal_dt_nb2emmc_301007000) && (idx == 1))) {
+ return 46;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+static __inline__ unsigned long long __metal_driver_sifive_nb2qspi0_control_base(struct metal_qspi *qspi)
+{
+ if ((uintptr_t)qspi == (uintptr_t)&__metal_dt_nb2qspi0_261010000) {
+ return METAL_SIFIVE_NB2QSPI0_261010000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long long __metal_driver_sifive_nb2qspi0_control_size(struct metal_qspi *qspi)
+{
+ if ((uintptr_t)qspi == (uintptr_t)&__metal_dt_nb2qspi0_261010000) {
+ return METAL_SIFIVE_NB2QSPI0_261010000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_nb2qspi0_clock(struct metal_qspi *qspi)
+{
+ if ((uintptr_t)qspi == (uintptr_t)&__metal_dt_nb2qspi0_261010000) {
+ return (struct metal_clock *)&__metal_dt_subsystem_pbus_clock.clock;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct __metal_driver_sifive_nb2gpio0 * __metal_driver_sifive_nb2qspi0_pinmux(struct metal_qspi *qspi)
+{
+ if ((uintptr_t)qspi == (uintptr_t)&__metal_dt_nb2qspi0_261010000) {
+ return NULL;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_nb2qspi0_pinmux_output_selector(struct metal_qspi *qspi)
+{
+ if ((uintptr_t)qspi == (uintptr_t)&__metal_dt_nb2qspi0_261010000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_nb2qspi0_pinmux_source_selector(struct metal_qspi *qspi)
+{
+ if ((uintptr_t)qspi == (uintptr_t)&__metal_dt_nb2qspi0_261010000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_nb2uart0 ------------ */
+static __inline__ unsigned long long __metal_driver_sifive_nb2uart0_control_base(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return METAL_SIFIVE_NB2UART0_302011000_BASE_ADDRESS;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return METAL_SIFIVE_NB2UART0_302012000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long long __metal_driver_sifive_nb2uart0_control_size(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return METAL_SIFIVE_NB2UART0_302011000_SIZE;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return METAL_SIFIVE_NB2UART0_302012000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_nb2uart0_num_interrupts(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return METAL_MAX_UART_INTERRUPTS;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return METAL_MAX_UART_INTERRUPTS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_nb2uart0_interrupt_parent(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return NULL;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_nb2uart0_interrupt_line(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return 64;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return 65;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_nb2uart0_clock(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return (struct metal_clock *)&__metal_dt_subsystem_pbus_clock.clock;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return (struct metal_clock *)&__metal_dt_subsystem_pbus_clock.clock;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct __metal_driver_sifive_nb2gpio0 * __metal_driver_sifive_nb2uart0_pinmux(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return NULL;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return NULL;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_nb2uart0_pinmux_output_selector(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return 0;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long __metal_driver_sifive_nb2uart0_pinmux_source_selector(struct metal_uart *uart)
+{
+ if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302011000) {
+ return 0;
+ }
+ else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_nb2uart0_302012000) {
+ return 0;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_nb2wdt ------------ */
+static __inline__ unsigned long long __metal_driver_sifive_nb2wdt_control_base(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_nb2wdt_302058000) {
+ return METAL_SIFIVE_NB2WDT_302058000_BASE_ADDRESS;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ unsigned long long __metal_driver_sifive_nb2wdt_control_size(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_nb2wdt_302058000) {
+ return METAL_SIFIVE_NB2WDT_302058000_SIZE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_interrupt * __metal_driver_sifive_nb2wdt_interrupt_parent(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_nb2wdt_302058000) {
+ return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ int __metal_driver_sifive_nb2wdt_interrupt_line(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_nb2wdt_302058000) {
+ return 4;
+ }
+ else {
+ return 0;
+ }
+}
+
+static __inline__ struct metal_clock * __metal_driver_sifive_nb2wdt_clock(const struct metal_watchdog *const watchdog)
+{
+ if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_nb2wdt_302058000) {
+ return (struct metal_clock *)&__metal_dt_subsystem_pbus_clock.clock;
+ }
+ else {
+ return 0;
+ }
+}
+
+
+
+/* --------------------- sifive_fe310_g000_hfrosc ------------ */
+
+
+/* --------------------- sifive_fe310_g000_hfxosc ------------ */
+
+
+/* --------------------- sifive_fe310_g000_lfrosc ------------ */
+
+
+/* --------------------- sifive_fe310_g000_pll ------------ */
+
+
+/* --------------------- sifive_fe310_g000_prci ------------ */
+
+
+#define __METAL_DT_MAX_MEMORIES 3
+
+__asm__ (".weak __metal_memory_table");
+struct metal_memory *__metal_memory_table[] = {
+ &__metal_dt_mem_testram_100000000,
+ &__metal_dt_mem_testram_c00000000,
+ &__metal_dt_mem_memory_800000000};
+
+/* From nb2uart0@302011000 */
+#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_nb2uart0_302011000.uart)
+
+#define __METAL_DT_NB2UART0_302011000_HANDLE (&__metal_dt_nb2uart0_302011000.uart)
+
+#define __METAL_DT_STDOUT_UART_BAUD 9600
+
+/* From clint@2000000 */
+#define __METAL_DT_RISCV_CLINT0_HANDLE (&__metal_dt_clint_2000000.controller)
+
+#define __METAL_DT_CLINT_2000000_HANDLE (&__metal_dt_clint_2000000.controller)
+
+#define __METAL_DT_MAX_HARTS 4
+
+#define __METAL_CPU_0_ICACHE_HANDLE 1
+
+#define __METAL_CPU_0_DCACHE_HANDLE 1
+
+#define __METAL_CPU_1_ICACHE_HANDLE 1
+
+#define __METAL_CPU_1_DCACHE_HANDLE 1
+
+#define __METAL_CPU_2_ICACHE_HANDLE 1
+
+#define __METAL_CPU_2_DCACHE_HANDLE 1
+
+#define __METAL_CPU_3_ICACHE_HANDLE 1
+
+#define __METAL_CPU_3_DCACHE_HANDLE 1
+
+__asm__ (".weak __metal_cpu_table");
+struct __metal_driver_cpu *__metal_cpu_table[] = {
+ &__metal_dt_cpu_0,
+ &__metal_dt_cpu_1,
+ &__metal_dt_cpu_2,
+ &__metal_dt_cpu_3};
+
+/* From interrupt_controller@c000000 */
+#define __METAL_DT_RISCV_PLIC0_HANDLE (&__metal_dt_interrupt_controller_c000000.controller)
+
+#define __METAL_DT_INTERRUPT_CONTROLLER_C000000_HANDLE (&__metal_dt_interrupt_controller_c000000.controller)
+
+#define __METAL_DT_PMP_HANDLE (&__metal_dt_pmp)
+
+/* From global_external_interrupts */
+#define __METAL_DT_SIFIVE_GLOBAL_EXINTR0_HANDLE (&__metal_dt_global_external_interrupts.irc)
+
+#define __METAL_DT_GLOBAL_EXTERNAL_INTERRUPTS_HANDLE (&__metal_dt_global_external_interrupts.irc)
+
+#define __MEE_DT_MAX_GPIOS 0
+
+__asm__ (".weak __metal_gpio_table");
+struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = {
+ NULL };
+#define __METAL_DT_MAX_BUTTONS 0
+
+__asm__ (".weak __metal_button_table");
+struct __metal_driver_sifive_gpio_button *__metal_button_table[] = {
+ NULL };
+#define __METAL_DT_MAX_LEDS 0
+
+__asm__ (".weak __metal_led_table");
+struct __metal_driver_sifive_gpio_led *__metal_led_table[] = {
+ NULL };
+#define __METAL_DT_MAX_SWITCHES 0
+
+__asm__ (".weak __metal_switch_table");
+struct __metal_driver_sifive_gpio_switch *__metal_switch_table[] = {
+ NULL };
+#define __METAL_DT_MAX_I2CS 0
+
+__asm__ (".weak __metal_i2c_table");
+struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = {
+ NULL };
+#define __METAL_DT_MAX_PWMS 0
+
+__asm__ (".weak __metal_pwm_table");
+struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = {
+ NULL };
+#define __METAL_DT_MAX_RTCS 0
+
+__asm__ (".weak __metal_rtc_table");
+struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = {
+ NULL };
+#define __METAL_DT_MAX_SPIS 0
+
+__asm__ (".weak __metal_spi_table");
+struct __metal_driver_sifive_spi0 *__metal_spi_table[] = {
+ NULL };
+/* From teststatus@4000 */
+#define __METAL_DT_SHUTDOWN_HANDLE (&__metal_dt_teststatus_4000.shutdown)
+
+#define __METAL_DT_TESTSTATUS_4000_HANDLE (&__metal_dt_teststatus_4000.shutdown)
+
+#define __METAL_DT_MAX_EMMC 1
+
+__asm__ (".weak __metal_emmc_table");
+struct __metal_driver_sifive_nb2emmc *__metal_emmc_table[] = {
+ &__metal_dt_nb2emmc_301007000};
+
+#define __METAL_DT_MAX_FLASH 1
+
+__asm__ (".weak __metal_flash_table");
+struct __metal_driver_sifive_flash *__metal_flash_table[] = {
+ &__metal_dt_flash};
+
+#define __METAL_DT_MAX_QSPIS 1
+
+__asm__ (".weak __metal_qspi_table");
+struct __metal_driver_sifive_nb2qspi0 *__metal_qspi_table[] = {
+ &__metal_dt_nb2qspi0_261010000};
+
+#define __METAL_DT_MAX_UARTS 2
+
+__asm__ (".weak __metal_uart_table");
+struct __metal_driver_sifive_nb2uart0 *__metal_uart_table[] = {
+ &__metal_dt_nb2uart0_302011000,
+ &__metal_dt_nb2uart0_302012000};
+
+#define __METAL_DT_MAX_WDOGS 1
+
+__asm__ (".weak __metal_wdog_table");
+struct __metal_driver_sifive_nb2wdt *__metal_wdog_table[] = {
+ &__metal_dt_nb2wdt_302058000};
+
+#endif /* MACROS_ELSE_METAL_H*/
+
+#endif /* ! __METAL_MACHINE_MACROS */
+
+#endif /* ! ASSEMBLY */
diff --git a/bsp/sifive-nb2/metal.ramrodata.lds b/bsp/sifive-nb2/metal.ramrodata.lds
new file mode 100644
index 000000000..7cfb000db
--- /dev/null
+++ b/bsp/sifive-nb2/metal.ramrodata.lds
@@ -0,0 +1,313 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* RAM Read-Only Data Linker Script
+ *
+ * This linker script places application code and read-only data into writable
+ * memories in an attempt to improve performance, since writable memories
+ * are generally lower-latency. This linker script may cause your application
+ * to overflow RAM, since it dramatically increases the quantity of data vying
+ * for space there.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ lim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x1e0000
+ ram (airwx) : ORIGIN = 0x800000000, LENGTH = 0x200000000
+ rom (irx!wa) : ORIGIN = 0x100000000, LENGTH = 0x1fffffff
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 1);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ /* The memory_ecc_scrub bit is used by _entry code to enable/disable
+ * memories scrubbing to zero */
+ PROVIDE(__metal_eccscrub_bit = 1);
+
+ /* The RAM memories map for ECC scrubbing */
+ /* Default zero-scrub to at most 64KB, for limiting RTL simulation run time. */
+ /* User is recommended to enable the full size for manual RTL simulation run! */
+ PROVIDE( metal_lim_0_memory_start = 0x8000000 );
+ PROVIDE( metal_lim_0_memory_end = 0x8000000 + 0x10000 );
+ /* Default zero-scrub to at most 64KB, for limiting RTL simulation run time. */
+ /* User is recommended to enable the full size for manual RTL simulation run! */
+ PROVIDE( metal_memory_0_memory_start = 0x800000000 );
+ PROVIDE( metal_memory_0_memory_end = 0x800000000 + 0x10000 );
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >rom :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >rom :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >rom :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >rom :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >rom :rom
+
+
+
+ .ctors : {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >rom :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >rom : rom
+
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >ram AT>rom :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >lim AT>rom :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >rom :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ /* Read-only data is placed in RAM to improve performance, since
+ * read-only memory generally has higher latency than RAM */
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ . = ALIGN(8);
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ } >ram AT>rom :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>rom :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ . += __stack_size; /* Hart 1 */
+ . += __stack_size; /* Hart 2 */
+ . += __stack_size; /* Hart 3 */
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/bsp/sifive-nb2/metal.scratchpad.lds b/bsp/sifive-nb2/metal.scratchpad.lds
new file mode 100644
index 000000000..9d7bdc0a5
--- /dev/null
+++ b/bsp/sifive-nb2/metal.scratchpad.lds
@@ -0,0 +1,297 @@
+/* Copyright (c) 2020 SiFive Inc. */
+/* SPDX-License-Identifier: Apache-2.0 */
+OUTPUT_ARCH("riscv")
+
+/* Scratchpad Linker Script
+ *
+ * This linker script is for executing in "scratchpad" mode, where all
+ * application code and data is placed in writable memory.
+ */
+
+ENTRY(_enter)
+
+MEMORY
+{
+ lim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x1e0000
+ ram (airwx) : ORIGIN = 0x800000000, LENGTH = 0x200000000
+ rom (irx!wa) : ORIGIN = 0x100000000, LENGTH = 0x1fffffff
+}
+
+PHDRS
+{
+ rom PT_LOAD;
+ ram_init PT_LOAD;
+ tls PT_TLS;
+ ram PT_LOAD;
+ itim_init PT_LOAD;
+ text PT_LOAD;
+ lim_init PT_LOAD;
+}
+
+SECTIONS
+{
+ /* Each hart is allocated its own stack of size __stack_size. This value
+ * can be overriden at build-time by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__stack_size=0xf00
+ *
+ * where 0xf00 can be replaced with a multiple of 16 of your choice.
+ *
+ * __stack_size is PROVIDE-ed as a symbol so that initialization code
+ * initializes the stack pointers for each hart at the right offset from
+ * the _sp symbol.
+ */
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 0x400;
+ PROVIDE(__stack_size = __stack_size);
+
+ /* The size of the heap can be overriden at build-time by adding the
+ * following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_size=0xf00
+ *
+ * where 0xf00 can be replaced with the value of your choice.
+ *
+ * Altertatively, the heap can be grown to fill the entire remaining region
+ * of RAM by adding the following to CFLAGS:
+ *
+ * -Xlinker --defsym=__heap_max=1
+ *
+ * Note that depending on the memory layout, the bitness (32/64bit) of the
+ * target, and the code model in use, this might cause a relocation error.
+ */
+ __heap_size = DEFINED(__heap_size) ? __heap_size : 0x800;
+
+ /* The boot hart sets which hart runs the pre-main initialization routines,
+ * including copying .data into RAM, zeroing the BSS region, running
+ * constructors, etc. After initialization, the boot hart is also the only
+ * hart which runs application code unless the application overrides the
+ * secondary_main() function to start execution on secondary harts.
+ */
+ PROVIDE(__metal_boot_hart = 0);
+
+ /* The chicken bit is used by pre-main initialization to enable/disable
+ * certain core features */
+ PROVIDE(__metal_chicken_bit = 1);
+
+ PROVIDE(__metal_eccscrub_bit = 0);
+
+ /* ROM SECTION
+ *
+ * The following sections contain data which lives in read-only memory, if
+ * such memory is present in the design, for the entire duration of program
+ * execution.
+ */
+
+ .init : {
+ /* The _enter symbol is placed in the .text.metal.init.enter section
+ * and must be placed at the beginning of the program */
+ KEEP (*(.text.metal.init.enter))
+ KEEP (*(.text.metal.init.*))
+ KEEP (*(SORT_NONE(.init)))
+ KEEP (*(.text.libgloss.start))
+ } >ram :rom
+
+ .fini : {
+ KEEP (*(SORT_NONE(.fini)))
+ } >ram :rom
+
+ .preinit_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } >ram :rom
+
+ .init_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+ KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ PROVIDE_HIDDEN ( metal_constructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.init_array.*)));
+ KEEP (*(.metal.init_array));
+ PROVIDE_HIDDEN ( metal_constructors_end = .);
+ } >ram :rom
+
+ .fini_array : ALIGN(8) {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+ KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ PROVIDE_HIDDEN ( metal_destructors_start = .);
+ KEEP (*(SORT_BY_INIT_PRIORITY(.metal.fini_array.*)));
+ KEEP (*(.metal.fini_array));
+ PROVIDE_HIDDEN ( metal_destructors_end = .);
+ } >ram :rom
+
+
+
+ .ctors : {
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ KEEP (*(.metal.ctors .metal.ctors.*))
+ } >ram :rom
+
+ .dtors : {
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ KEEP (*(.metal.dtors .metal.dtors.*))
+ } >ram : rom
+
+ .rodata : {
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+ . = ALIGN(8);
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+ } >ram :rom
+
+ /* ITIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into an instruction tightly-integrated memory (ITIM), if one
+ * is present in the design, during pre-main program initialization.
+ *
+ * Generally, the data copied into the ITIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .itim : ALIGN(8) {
+ *(.itim .itim.*)
+ } >ram AT>ram :itim_init
+
+ PROVIDE( metal_segment_itim_source_start = LOADADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_start = ADDR(.itim) );
+ PROVIDE( metal_segment_itim_target_end = ADDR(.itim) + SIZEOF(.itim) );
+
+ /* LIM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a loosely integrated memory (LIM), which is shared with L2
+ * cache, during pre-main program initialization.
+ *
+ * Generally, the data copied into the LIM should be performance-critical
+ * functions which benefit from low instruction-fetch latency.
+ */
+
+ .lim : ALIGN(8) {
+ *(.lim .lim.*)
+ } >lim AT>ram :lim_init
+
+ PROVIDE( metal_segment_lim_source_start = LOADADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_start = ADDR(.lim) );
+ PROVIDE( metal_segment_lim_target_end = ADDR(.lim) + SIZEOF(.lim) );
+
+ /* TEXT SECTION
+ *
+ * The following section contains the code of the program, excluding
+ * everything that's been allocated into the ITIM/LIM already
+ */
+
+ .text : {
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.*)
+ *(.gnu.linkonce.t.*)
+ } >ram :text
+
+ /* RAM SECTION
+ *
+ * The following sections contain data which is copied from read-only
+ * memory into a read-write-capable memory such as data tightly-integrated
+ * memory (DTIM) or another main memory, as well as the BSS, stack, and
+ * heap.
+ *
+ * You might notice that .data, .tdata, .tbss, .tbss_space, and .bss all
+ * have an apparently unnecessary ALIGN at their top. This is because
+ * the implementation of _start in Freedom Metal libgloss depends on the
+ * ADDR and LOADADDR being 8-byte aligned.
+ */
+
+ .data : ALIGN(8) {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ . = ALIGN(8);
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ } >ram AT>ram :ram_init
+
+ .tdata : ALIGN(8) {
+ PROVIDE( __tls_base = . );
+ *(.tdata .tdata.* .gnu.linkonce.td.*)
+ } >ram AT>ram :tls :ram_init
+
+ PROVIDE( __tdata_source = LOADADDR(.tdata) );
+ PROVIDE( __tdata_size = SIZEOF(.tdata) );
+
+ PROVIDE( metal_segment_data_source_start = LOADADDR(.data) );
+ PROVIDE( metal_segment_data_target_start = ADDR(.data) );
+ PROVIDE( metal_segment_data_target_end = ADDR(.tdata) + SIZEOF(.tdata) );
+
+ .tbss : ALIGN(8) {
+ *(.tbss .tbss.* .gnu.linkonce.tb.*)
+ *(.tcommon .tcommon.*)
+ PROVIDE( __tls_end = . );
+ } >ram AT>ram :tls :ram
+ PROVIDE( __tbss_size = SIZEOF(.tbss) );
+ PROVIDE( __tls_size = __tls_end - __tls_base );
+
+ .tbss_space : ALIGN(8) {
+ . = . + __tbss_size;
+ } >ram :ram
+
+ .bss (NOLOAD): ALIGN(8) {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ } >ram :ram
+
+ PROVIDE( metal_segment_bss_source_start = LOADADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_start = ADDR(.tbss) );
+ PROVIDE( metal_segment_bss_target_end = ADDR(.bss) + SIZEOF(.bss) );
+
+
+
+ .stack (NOLOAD) : ALIGN(16) {
+ PROVIDE(metal_segment_stack_begin = .);
+ . += __stack_size; /* Hart 0 */
+ PROVIDE( _sp = . );
+ . += __stack_size; /* Hart 1 */
+ . += __stack_size; /* Hart 2 */
+ . += __stack_size; /* Hart 3 */
+ PROVIDE(metal_segment_stack_end = .);
+ } >ram :ram
+
+ .heap (NOLOAD) : ALIGN(8) {
+ PROVIDE( __end = . );
+ PROVIDE( __heap_start = . );
+ PROVIDE( metal_segment_heap_target_start = . );
+ /* If __heap_max is defined, grow the heap to use the rest of RAM,
+ * otherwise set the heap size to __heap_size */
+ . = DEFINED(__heap_max) ? MIN( LENGTH(ram) - ( . - ORIGIN(ram)) , 0x10000000) : __heap_size;
+ PROVIDE( metal_segment_heap_target_end = . );
+ PROVIDE( _heap_end = . );
+ PROVIDE( __heap_end = . );
+ } >ram :ram
+
+ /* C++ exception handling information is
+ * not useful with our current runtime environment,
+ * and it consumes flash space. Discard it until
+ * we have something that can use it
+ */
+ /DISCARD/ : {
+ *(.eh_frame .eh_frame.*)
+ }
+}
\ No newline at end of file
diff --git a/bsp/sifive-nb2/settings.mk b/bsp/sifive-nb2/settings.mk
new file mode 100644
index 000000000..02bb37f90
--- /dev/null
+++ b/bsp/sifive-nb2/settings.mk
@@ -0,0 +1,15 @@
+# Copyright (C) 2020 SiFive Inc
+# SPDX-License-Identifier: Apache-2.0
+
+RISCV_ARCH = rv64imafdc
+RISCV_ABI = lp64d
+RISCV_CMODEL = medany
+RISCV_SERIES = sifive-7-series
+
+TARGET_TAGS = board openocd
+TARGET_DHRY_ITERS = 20000000
+TARGET_CORE_ITERS = 5000
+TARGET_FREERTOS_WAIT_MS = 1000
+TARGET_INTR_WAIT_CYCLE = 0
+
+COREIP_MEM_WIDTH = 128
\ No newline at end of file
diff --git a/freedom-devicetree-tools b/freedom-devicetree-tools
index 99215f3bb..0a1297d94 160000
--- a/freedom-devicetree-tools
+++ b/freedom-devicetree-tools
@@ -1 +1 @@
-Subproject commit 99215f3bb636999699c681f1008bae813def4c72
+Subproject commit 0a1297d94448f9d17033d0e356b15604949aa976
diff --git a/freedom-metal b/freedom-metal
index 54b0cbcf2..98055d788 160000
--- a/freedom-metal
+++ b/freedom-metal
@@ -1 +1 @@
-Subproject commit 54b0cbcf2bf129efe7ff04afbf89210a6dd29358
+Subproject commit 98055d7885fe407d3322b6e2a25b7cf6848d2a87
diff --git a/scripts/devicetree-overlay-generator b/scripts/devicetree-overlay-generator
index 934c69d37..a2fe8020e 160000
--- a/scripts/devicetree-overlay-generator
+++ b/scripts/devicetree-overlay-generator
@@ -1 +1 @@
-Subproject commit 934c69d374e1ef3f5c9661535f4d8a5a65f776cb
+Subproject commit a2fe8020ee978eb5ca88d40cf71a815ccb2b8397
diff --git a/scripts/esdk-settings-generator b/scripts/esdk-settings-generator
index 795d65bc6..c1d40501f 160000
--- a/scripts/esdk-settings-generator
+++ b/scripts/esdk-settings-generator
@@ -1 +1 @@
-Subproject commit 795d65bc6c033c6d97222f2683f2112631558aa2
+Subproject commit c1d40501f26b4fa8b7bf7098c7801c026cb3fc1f
diff --git a/software/example-emmc b/software/example-emmc
new file mode 160000
index 000000000..e210fb687
--- /dev/null
+++ b/software/example-emmc
@@ -0,0 +1 @@
+Subproject commit e210fb687ce7568bf3c73b48938d3e0a076c4f78
diff --git a/software/example-flash b/software/example-flash
new file mode 160000
index 000000000..812ba152d
--- /dev/null
+++ b/software/example-flash
@@ -0,0 +1 @@
+Subproject commit 812ba152d931e2ea5a07c6717cc74e30eb27994c
diff --git a/wit-manifest.json b/wit-manifest.json
index 39cf26122..e1095ae10 100644
--- a/wit-manifest.json
+++ b/wit-manifest.json
@@ -1,11 +1,11 @@
[
{
- "commit": "99215f3bb636999699c681f1008bae813def4c72",
+ "commit": "0a1297d94448f9d17033d0e356b15604949aa976",
"name": "freedom-devicetree-tools",
"source": "git@github.com:sifive/freedom-devicetree-tools.git"
},
{
- "commit": "54b0cbcf2bf129efe7ff04afbf89210a6dd29358",
+ "commit": "98055d7885fe407d3322b6e2a25b7cf6848d2a87",
"name": "freedom-metal",
"source": "git@github.com:sifive/freedom-metal.git"
},
@@ -15,7 +15,7 @@
"source": "git@github.com:sifive/elf2hex.git"
},
{
- "commit": "934c69d374e1ef3f5c9661535f4d8a5a65f776cb",
+ "commit": "a2fe8020ee978eb5ca88d40cf71a815ccb2b8397",
"name": "devicetree-overlay-generator",
"source": "git@github.com:sifive/devicetree-overlay-generator.git"
},
@@ -35,7 +35,7 @@
"source": "git@github.com:sifive/openocdcfg-generator.git"
},
{
- "commit": "795d65bc6c033c6d97222f2683f2112631558aa2",
+ "commit": "c1d40501f26b4fa8b7bf7098c7801c026cb3fc1f",
"name": "esdk-settings-generator",
"source": "git@github.com:sifive/esdk-settings-generator.git"
},
@@ -268,5 +268,15 @@
"commit": "cd04f06675b3ba464ffabd72e5800b9ba1313104",
"name": "example-lim",
"source": "git@github.com:sifive/example-lim.git"
+ },
+ {
+ "commit": "e210fb687ce7568bf3c73b48938d3e0a076c4f78",
+ "name": "example-emmc",
+ "source": "git@github.com:sifive/example-emmc.git"
+ },
+ {
+ "commit": "812ba152d931e2ea5a07c6717cc74e30eb27994c",
+ "name": "example-flash",
+ "source":"git@github.com:sifive/example-flash.git"
}
]