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" } ]