diff --git a/bsp/sparkfun-redv/README.md b/bsp/sparkfun-redv/README.md new file mode 100644 index 00000000..52cc3132 --- /dev/null +++ b/bsp/sparkfun-redv/README.md @@ -0,0 +1,13 @@ +Sparkfun RED-V is a low-cost, Arduino-compatible development board featuring the Freedom E310. It’s one of the best ways to start prototyping and developing your RISC‑V applications. + +This target is ideal for getting familiar with the RISC-V ISA instruction set and the freedom-metal libraries. It supports: + +- 1 hart with RV32IMAC core +- 4 hardware breakpoints +- Physical Memory Protection with 8 regions +- 16 local interrupts signal that can be connected to off core complex devices +- Up to 127 PLIC interrupt signals that can be connected to off core complex devices, with 7 priority levels +- GPIO memory with 16 interrupt lines +- SPI memory with 1 interrupt line +- Serial port with 1 interrupt line +- 1 blue LED diff --git a/bsp/sparkfun-redv/core.dts b/bsp/sparkfun-redv/core.dts new file mode 100644 index 00000000..26819954 --- /dev/null +++ b/bsp/sparkfun-redv/core.dts @@ -0,0 +1,250 @@ +/dts-v1/; +/ { + #address-cells = <1>; + #size-cells = <1>; + compatible = "sparkfun,redv"; + model = "sparkfun,rev"; + cpus { + #address-cells = <1>; + #size-cells = <0>; + compatible = "sifive,fe310-g000"; + L6: cpu@0 { + clocks = <&hfclk>; + compatible = "sifive,rocket0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + next-level-cache = <&spi0>; + reg = <0>; + riscv,isa = "rv32imac"; + riscv,pmpregions = <8>; + sifive,itim = <&itim>; + sifive,dtim = <&dtim>; + status = "okay"; + timebase-frequency = <16000000>; + hardware-exec-breakpoint-count = <4>; + hlic: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + soc { + #address-cells = <1>; + #size-cells = <1>; + #clock-cells = <1>; + compatible = "sifive,hifive1"; + ranges; + hfxoscin: clock@0 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <16000000>; + }; + hfxoscout: clock@1 { + compatible = "sifive,fe310-g000,hfxosc"; + clocks = <&hfxoscin>; + reg = <&prci 0x4>; + reg-names = "config"; + }; + hfroscin: clock@2 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <72000000>; + }; + hfroscout: clock@3 { + compatible = "sifive,fe310-g000,hfrosc"; + clocks = <&hfroscin>; + reg = <&prci 0x0>; + reg-names = "config"; + }; + hfclk: clock@4 { + compatible = "sifive,fe310-g000,pll"; + clocks = <&hfxoscout &hfroscout>; + clock-names = "pllref", "pllsel0"; + reg = <&prci 0x8 &prci 0xc>; + reg-names = "config", "divider"; + clock-frequency = <16000000>; + }; + lfrosc: clock@5 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + psdlfaltclk: clock@6 { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + }; + lfclk: clock@7 { + compatible = "sifive,fe310-g000,lfrosc"; + clocks = <&lfrosc &psdlfaltclk>; + clock-names = "lfrosc", "psdlfaltclk"; + reg = <&aon 0x70 &aon 0x7C>; + reg-names = "config", "mux"; + }; + debug-controller@0 { + compatible = "sifive,debug-011", "riscv,debug-011"; + interrupts-extended = <&hlic 65535>; + reg = <0x0 0x1000>; + reg-names = "control"; + }; + /* Missing: Error device */ + maskrom@1000 { + reg = <0x1000 0x2000>; + reg-names = "mem"; + }; + otp@20000 { + reg = <0x20000 0x2000 0x10010000 0x1000>; + reg-names = "mem", "control"; + }; + clint: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&hlic 3 &hlic 7>; + reg = <0x2000000 0x10000>; + reg-names = "control"; + }; + itim: itim@8000000 { + compatible = "sifive,itim0"; + reg = <0x8000000 0x2000>; + reg-names = "mem"; + }; + plic: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "riscv,plic0"; + interrupt-controller; + interrupts-extended = <&hlic 11>; + reg = <0xc000000 0x4000000>; + reg-names = "control"; + riscv,max-priority = <7>; + riscv,ndev = <52>; + }; + aon: aon@10000000 { + compatible = "sifive,aon0"; + reg = <0x10000000 0x8000>; + reg-names = "mem"; + interrupt-parent = <&plic>; + interrupts = <1 2>; + clocks = <&lfclk>; + }; + prci: prci@10008000 { + compatible = "sifive,fe310-g000,prci"; + reg = <0x10008000 0x8000>; + reg-names = "mem"; + }; + gpio0: gpio@10012000 { + compatible = "sifive,gpio0"; + interrupt-parent = <&plic>; + interrupts = <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 + 27 28 29>; + reg = <0x10012000 0x1000>; + reg-names = "control"; + }; + led@0 { + compatible = "sifive,gpio-leds"; + label = "LD0"; + gpios = <&gpio0 5>; + linux,default-trigger = "none"; + }; + uart0: serial@10013000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <3>; + reg = <0x10013000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x30000>; + }; + spi0: spi@10014000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <5>; + reg = <0x10014000 0x1000 0x20000000 0x7A120>; + reg-names = "control", "mem"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x0>; + #address-cells = <1>; + #size-cells = <1>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x20000000 0x424000>; + }; + }; + pwm0: pwm@10015000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <8>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <40 41 42 43>; + reg = <0x10015000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0F 0x0F>; + }; + i2c0: i2c@10016000 { + compatible = "sifive,i2c0"; + interrupt-parent = <&plic>; + interrupts = <52>; + reg = <0x10016000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x3000>; + }; + uart1: serial@10023000 { + compatible = "sifive,uart0"; + interrupt-parent = <&plic>; + interrupts = <4>; + reg = <0x10023000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x840000>; + }; + spi1: spi@10024000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <6>; + reg = <0x10024000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0x0003C>; + }; + pwm1: pwm@10025000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <16>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <44 45 46 47>; + reg = <0x10025000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x780000 0x780000>; + }; + spi2: spi@10034000 { + compatible = "sifive,spi0"; + interrupt-parent = <&plic>; + interrupts = <7>; + reg = <0x10034000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x0 0xFC000000>; + }; + pwm2: pwm@10035000 { + compatible = "sifive,pwm0"; + sifive,comparator-widthbits = <16>; + sifive,ncomparators = <4>; + interrupt-parent = <&plic>; + interrupts = <48 49 50 51>; + reg = <0x10035000 0x1000>; + reg-names = "control"; + clocks = <&hfclk>; + pinmux = <&gpio0 0x3C00 0x3C00>; + }; + dtim: dtim@80000000 { + compatible = "sifive,dtim0"; + reg = <0x80000000 0x4000>; + reg-names = "mem"; + }; + }; +}; diff --git a/bsp/sparkfun-redv/design.dts b/bsp/sparkfun-redv/design.dts new file mode 100644 index 00000000..098c25c4 --- /dev/null +++ b/bsp/sparkfun-redv/design.dts @@ -0,0 +1,10 @@ +/include/ "core.dts" +/ { + chosen { + metal,entry = <&spi0 1 65536>; + metal,boothart = <&L6>; + stdout-path = "/soc/serial@10013000:115200"; + metal,itim = <&itim 0 0>; + metal,ram = <&dtim 0 0>; + }; +}; diff --git a/bsp/sparkfun-redv/design.reglist b/bsp/sparkfun-redv/design.reglist new file mode 100644 index 00000000..921dd83a --- /dev/null +++ b/bsp/sparkfun-redv/design.reglist @@ -0,0 +1,54 @@ +zero +ra +sp +gp +tp +t0 +t1 +t2 +fp +s1 +a0 +a1 +a2 +a3 +a4 +a5 +a6 +a7 +s2 +s3 +s4 +s5 +s6 +s7 +s8 +s9 +s10 +s11 +t3 +t4 +t5 +t6 +pc +mstatus +misa +mie +mtvec +mscratch +mepc +mcause +mtval +mip +mvendorid +marchid +mimpid +mhartid +tselect +tdata1 +tdata2 +tdata3 +dcsr +dpc +dscratch +priv diff --git a/bsp/sparkfun-redv/design.svd b/bsp/sparkfun-redv/design.svd new file mode 100644 index 00000000..3ad2768b --- /dev/null +++ b/bsp/sparkfun-redv/design.svd @@ -0,0 +1,3169 @@ +<?xml version="1.0" encoding="utf-8"?> +<device schemaVersion="1.3" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="CMSIS-SVD.xsd"> + <name>sifive_hifive1_revb</name> + <version>0.1</version> + <description>From sifive,hifive1-revb,model device generator</description> + <addressUnitBits>8</addressUnitBits> + <width>32</width> + <size>32</size> + <access>read-write</access> + <peripherals> + <peripheral> + <name>riscv_clint0_0</name> + <description>From riscv,clint0,control peripheral generator</description> + <baseAddress>0x2000000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x10000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>msip_0</name> + <description>MSIP Register for hart 0</description> + <addressOffset>0x0</addressOffset> + </register> + <register> + <name>mtimecmp_0</name> + <description>MTIMECMP Register for hart 0</description> + <addressOffset>0x4000</addressOffset> + <size>64</size> + </register> + <register> + <name>mtime</name> + <description>MTIME Register</description> + <addressOffset>0xBFF8</addressOffset> + <size>64</size> + </register> + </registers> + </peripheral> + <peripheral> + <name>riscv_plic0_0</name> + <description>From riscv,plic0,control peripheral generator</description> + <baseAddress>0xC000000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x4000000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>priority_1</name> + <description>PRIORITY Register for interrupt id 1</description> + <addressOffset>0x4</addressOffset> + </register> + <register> + <name>priority_2</name> + <description>PRIORITY Register for interrupt id 2</description> + <addressOffset>0x8</addressOffset> + </register> + <register> + <name>priority_3</name> + <description>PRIORITY Register for interrupt id 3</description> + <addressOffset>0xC</addressOffset> + </register> + <register> + <name>priority_4</name> + <description>PRIORITY Register for interrupt id 4</description> + <addressOffset>0x10</addressOffset> + </register> + <register> + <name>priority_5</name> + <description>PRIORITY Register for interrupt id 5</description> + <addressOffset>0x14</addressOffset> + </register> + <register> + <name>priority_6</name> + <description>PRIORITY Register for interrupt id 6</description> + <addressOffset>0x18</addressOffset> + </register> + <register> + <name>priority_7</name> + <description>PRIORITY Register for interrupt id 7</description> + <addressOffset>0x1C</addressOffset> + </register> + <register> + <name>priority_8</name> + <description>PRIORITY Register for interrupt id 8</description> + <addressOffset>0x20</addressOffset> + </register> + <register> + <name>priority_9</name> + <description>PRIORITY Register for interrupt id 9</description> + <addressOffset>0x24</addressOffset> + </register> + <register> + <name>priority_10</name> + <description>PRIORITY Register for interrupt id 10</description> + <addressOffset>0x28</addressOffset> + </register> + <register> + <name>priority_11</name> + <description>PRIORITY Register for interrupt id 11</description> + <addressOffset>0x2C</addressOffset> + </register> + <register> + <name>priority_12</name> + <description>PRIORITY Register for interrupt id 12</description> + <addressOffset>0x30</addressOffset> + </register> + <register> + <name>priority_13</name> + <description>PRIORITY Register for interrupt id 13</description> + <addressOffset>0x34</addressOffset> + </register> + <register> + <name>priority_14</name> + <description>PRIORITY Register for interrupt id 14</description> + <addressOffset>0x38</addressOffset> + </register> + <register> + <name>priority_15</name> + <description>PRIORITY Register for interrupt id 15</description> + <addressOffset>0x3C</addressOffset> + </register> + <register> + <name>priority_16</name> + <description>PRIORITY Register for interrupt id 16</description> + <addressOffset>0x40</addressOffset> + </register> + <register> + <name>priority_17</name> + <description>PRIORITY Register for interrupt id 17</description> + <addressOffset>0x44</addressOffset> + </register> + <register> + <name>priority_18</name> + <description>PRIORITY Register for interrupt id 18</description> + <addressOffset>0x48</addressOffset> + </register> + <register> + <name>priority_19</name> + <description>PRIORITY Register for interrupt id 19</description> + <addressOffset>0x4C</addressOffset> + </register> + <register> + <name>priority_20</name> + <description>PRIORITY Register for interrupt id 20</description> + <addressOffset>0x50</addressOffset> + </register> + <register> + <name>priority_21</name> + <description>PRIORITY Register for interrupt id 21</description> + <addressOffset>0x54</addressOffset> + </register> + <register> + <name>priority_22</name> + <description>PRIORITY Register for interrupt id 22</description> + <addressOffset>0x58</addressOffset> + </register> + <register> + <name>priority_23</name> + <description>PRIORITY Register for interrupt id 23</description> + <addressOffset>0x5C</addressOffset> + </register> + <register> + <name>priority_24</name> + <description>PRIORITY Register for interrupt id 24</description> + <addressOffset>0x60</addressOffset> + </register> + <register> + <name>priority_25</name> + <description>PRIORITY Register for interrupt id 25</description> + <addressOffset>0x64</addressOffset> + </register> + <register> + <name>priority_26</name> + <description>PRIORITY Register for interrupt id 26</description> + <addressOffset>0x68</addressOffset> + </register> + <register> + <name>priority_27</name> + <description>PRIORITY Register for interrupt id 27</description> + <addressOffset>0x6C</addressOffset> + </register> + <register> + <name>priority_28</name> + <description>PRIORITY Register for interrupt id 28</description> + <addressOffset>0x70</addressOffset> + </register> + <register> + <name>priority_29</name> + <description>PRIORITY Register for interrupt id 29</description> + <addressOffset>0x74</addressOffset> + </register> + <register> + <name>priority_30</name> + <description>PRIORITY Register for interrupt id 30</description> + <addressOffset>0x78</addressOffset> + </register> + <register> + <name>priority_31</name> + <description>PRIORITY Register for interrupt id 31</description> + <addressOffset>0x7C</addressOffset> + </register> + <register> + <name>priority_32</name> + <description>PRIORITY Register for interrupt id 32</description> + <addressOffset>0x80</addressOffset> + </register> + <register> + <name>priority_33</name> + <description>PRIORITY Register for interrupt id 33</description> + <addressOffset>0x84</addressOffset> + </register> + <register> + <name>priority_34</name> + <description>PRIORITY Register for interrupt id 34</description> + <addressOffset>0x88</addressOffset> + </register> + <register> + <name>priority_35</name> + <description>PRIORITY Register for interrupt id 35</description> + <addressOffset>0x8C</addressOffset> + </register> + <register> + <name>priority_36</name> + <description>PRIORITY Register for interrupt id 36</description> + <addressOffset>0x90</addressOffset> + </register> + <register> + <name>priority_37</name> + <description>PRIORITY Register for interrupt id 37</description> + <addressOffset>0x94</addressOffset> + </register> + <register> + <name>priority_38</name> + <description>PRIORITY Register for interrupt id 38</description> + <addressOffset>0x98</addressOffset> + </register> + <register> + <name>priority_39</name> + <description>PRIORITY Register for interrupt id 39</description> + <addressOffset>0x9C</addressOffset> + </register> + <register> + <name>priority_40</name> + <description>PRIORITY Register for interrupt id 40</description> + <addressOffset>0xA0</addressOffset> + </register> + <register> + <name>priority_41</name> + <description>PRIORITY Register for interrupt id 41</description> + <addressOffset>0xA4</addressOffset> + </register> + <register> + <name>priority_42</name> + <description>PRIORITY Register for interrupt id 42</description> + <addressOffset>0xA8</addressOffset> + </register> + <register> + <name>priority_43</name> + <description>PRIORITY Register for interrupt id 43</description> + <addressOffset>0xAC</addressOffset> + </register> + <register> + <name>priority_44</name> + <description>PRIORITY Register for interrupt id 44</description> + <addressOffset>0xB0</addressOffset> + </register> + <register> + <name>priority_45</name> + <description>PRIORITY Register for interrupt id 45</description> + <addressOffset>0xB4</addressOffset> + </register> + <register> + <name>priority_46</name> + <description>PRIORITY Register for interrupt id 46</description> + <addressOffset>0xB8</addressOffset> + </register> + <register> + <name>priority_47</name> + <description>PRIORITY Register for interrupt id 47</description> + <addressOffset>0xBC</addressOffset> + </register> + <register> + <name>priority_48</name> + <description>PRIORITY Register for interrupt id 48</description> + <addressOffset>0xC0</addressOffset> + </register> + <register> + <name>priority_49</name> + <description>PRIORITY Register for interrupt id 49</description> + <addressOffset>0xC4</addressOffset> + </register> + <register> + <name>priority_50</name> + <description>PRIORITY Register for interrupt id 50</description> + <addressOffset>0xC8</addressOffset> + </register> + <register> + <name>priority_51</name> + <description>PRIORITY Register for interrupt id 51</description> + <addressOffset>0xCC</addressOffset> + </register> + <register> + <name>priority_52</name> + <description>PRIORITY Register for interrupt id 52</description> + <addressOffset>0xD0</addressOffset> + </register> + <register> + <name>pending_0</name> + <description>PENDING Register for interrupt ids 31 to 0</description> + <addressOffset>0x1000</addressOffset> + </register> + <register> + <name>pending_1</name> + <description>PENDING Register for interrupt ids 52 to 32</description> + <addressOffset>0x1004</addressOffset> + </register> + <register> + <name>enable_0_0</name> + <description>ENABLE Register for interrupt ids 31 to 0 for hart 0</description> + <addressOffset>0x2000</addressOffset> + </register> + <register> + <name>enable_1_0</name> + <description>ENABLE Register for interrupt ids 52 to 32 for hart 0</description> + <addressOffset>0x2004</addressOffset> + </register> + <register> + <name>threshold_0</name> + <description>PRIORITY THRESHOLD Register for hart 0</description> + <addressOffset>0x200000</addressOffset> + </register> + <register> + <name>claimplete_0</name> + <description>CLAIM and COMPLETE Register for hart 0</description> + <addressOffset>0x200004</addressOffset> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_aon0_0</name> + <description>From sifive,aon0,mem peripheral generator</description> + <baseAddress>0x10000000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x8000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>backup_0</name> + <description>Backup Register 0</description> + <addressOffset>0x80</addressOffset> + </register> + <register> + <name>backup_1</name> + <description>Backup Register 1</description> + <addressOffset>0x84</addressOffset> + </register> + <register> + <name>backup_2</name> + <description>Backup Register 2</description> + <addressOffset>0x88</addressOffset> + </register> + <register> + <name>backup_3</name> + <description>Backup Register 3</description> + <addressOffset>0x8C</addressOffset> + </register> + <register> + <name>backup_4</name> + <description>Backup Register 4</description> + <addressOffset>0x90</addressOffset> + </register> + <register> + <name>backup_5</name> + <description>Backup Register 5</description> + <addressOffset>0x94</addressOffset> + </register> + <register> + <name>backup_6</name> + <description>Backup Register 6</description> + <addressOffset>0x98</addressOffset> + </register> + <register> + <name>backup_7</name> + <description>Backup Register 7</description> + <addressOffset>0x9C</addressOffset> + </register> + <register> + <name>backup_8</name> + <description>Backup Register 8</description> + <addressOffset>0xA0</addressOffset> + </register> + <register> + <name>backup_9</name> + <description>Backup Register 9</description> + <addressOffset>0xA4</addressOffset> + </register> + <register> + <name>backup_10</name> + <description>Backup Register 10</description> + <addressOffset>0xA8</addressOffset> + </register> + <register> + <name>backup_11</name> + <description>Backup Register 11</description> + <addressOffset>0xAC</addressOffset> + </register> + <register> + <name>backup_12</name> + <description>Backup Register 12</description> + <addressOffset>0xB0</addressOffset> + </register> + <register> + <name>backup_13</name> + <description>Backup Register 13</description> + <addressOffset>0xB4</addressOffset> + </register> + <register> + <name>backup_14</name> + <description>Backup Register 14</description> + <addressOffset>0xB8</addressOffset> + </register> + <register> + <name>backup_15</name> + <description>Backup Register 15</description> + <addressOffset>0xBC</addressOffset> + </register> + <register> + <name>wdogcfg</name> + <description>wdog Configuration</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>wdogscale</name> + <description>Counter scale value.</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogrsten</name> + <description>Controls whether the comparator output can set the wdogrst bit and hence cause a full reset.</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogzerocmp</name> + <description>Reset counter to zero after match.</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogenalways</name> + <description>Enable Always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogcoreawake</name> + <description>Increment the watchdog counter if the processor is not asleep</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wdogip0</name> + <description>Interrupt 0 Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>wdogcount</name> + <description>Counter Register</description> + <addressOffset>0x8</addressOffset> + </register> + <register> + <name>wdogs</name> + <description>Scaled value of Counter</description> + <addressOffset>0x10</addressOffset> + </register> + <register> + <name>wdogfeed</name> + <description>Feed register</description> + <addressOffset>0x18</addressOffset> + </register> + <register> + <name>wdogkey</name> + <description>Key Register</description> + <addressOffset>0x1C</addressOffset> + </register> + <register> + <name>wdogcmp0</name> + <description>Comparator 0</description> + <addressOffset>0x20</addressOffset> + </register> + <register> + <name>rtccfg</name> + <description>rtc Configuration</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>rtcscale</name> + <description>Counter scale value.</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rtcenalways</name> + <description>Enable Always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rtcip0</name> + <description>Interrupt 0 Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rtccountlo</name> + <description>Low bits of Counter</description> + <addressOffset>0x48</addressOffset> + </register> + <register> + <name>rtccounthi</name> + <description>High bits of Counter</description> + <addressOffset>0x4C</addressOffset> + </register> + <register> + <name>rtcs</name> + <description>Scaled value of Counter</description> + <addressOffset>0x50</addressOffset> + </register> + <register> + <name>rtccmp0</name> + <description>Comparator 0</description> + <addressOffset>0x60</addressOffset> + </register> + <register> + <name>pmuwakeupi0</name> + <description>Wakeup program instruction 0</description> + <addressOffset>0x100</addressOffset> + </register> + <register> + <name>pmuwakeupi1</name> + <description>Wakeup program instruction 1</description> + <addressOffset>0x104</addressOffset> + </register> + <register> + <name>pmuwakeupi2</name> + <description>Wakeup program instruction 2</description> + <addressOffset>0x108</addressOffset> + </register> + <register> + <name>pmuwakeupi3</name> + <description>Wakeup program instruction 3</description> + <addressOffset>0x10C</addressOffset> + </register> + <register> + <name>pmuwakeupi4</name> + <description>Wakeup program instruction 4</description> + <addressOffset>0x110</addressOffset> + </register> + <register> + <name>pmuwakeupi5</name> + <description>Wakeup program instruction 5</description> + <addressOffset>0x114</addressOffset> + </register> + <register> + <name>pmuwakeupi6</name> + <description>Wakeup program instruction 6</description> + <addressOffset>0x118</addressOffset> + </register> + <register> + <name>pmuwakeupi7</name> + <description>Wakeup program instruction 7</description> + <addressOffset>0x11C</addressOffset> + </register> + <register> + <name>pmusleepi0</name> + <description>Sleep program instruction 0</description> + <addressOffset>0x120</addressOffset> + </register> + <register> + <name>pmusleepi1</name> + <description>Sleep program instruction 1</description> + <addressOffset>0x124</addressOffset> + </register> + <register> + <name>pmusleepi2</name> + <description>Sleep program instruction 2</description> + <addressOffset>0x128</addressOffset> + </register> + <register> + <name>pmusleepi3</name> + <description>Sleep program instruction 3</description> + <addressOffset>0x12C</addressOffset> + </register> + <register> + <name>pmusleepi4</name> + <description>Sleep program instruction 4</description> + <addressOffset>0x130</addressOffset> + </register> + <register> + <name>pmusleepi5</name> + <description>Sleep program instruction 5</description> + <addressOffset>0x134</addressOffset> + </register> + <register> + <name>pmusleepi6</name> + <description>Sleep program instruction 6</description> + <addressOffset>0x138</addressOffset> + </register> + <register> + <name>pmusleepi7</name> + <description>Sleep program instruction 7</description> + <addressOffset>0x13C</addressOffset> + </register> + <register> + <name>pmuie</name> + <description>PMU Interrupt Enables</description> + <addressOffset>0x140</addressOffset> + </register> + <register> + <name>pmucause</name> + <description>PMU Wakeup Cause</description> + <addressOffset>0x144</addressOffset> + </register> + <register> + <name>pmusleep</name> + <description>Initiate PMU Sleep Sequence</description> + <addressOffset>0x148</addressOffset> + </register> + <register> + <name>pmukey</name> + <description>PMU Key. Reads as 1 when PMU is unlocked</description> + <addressOffset>0x14C</addressOffset> + </register> + <register> + <name>aoncfg</name> + <description>AON Block Configuration Information</description> + <addressOffset>0x300</addressOffset> + <fields> + <field> + <name>has_bandgap</name> + <description>Bandgap feature is present</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_bod</name> + <description>Brownout detector feature is present</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_lfrosc</name> + <description>Low Frequency Ring Oscillator feature is present</description> + <bitRange>[2:2]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_lfrcosc</name> + <description>Low Frequency RC Oscillator feature is present</description> + <bitRange>[3:3]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_lfxosc</name> + <description>Low Frequency Crystal Oscillator feature is present</description> + <bitRange>[4:4]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_por</name> + <description>Power-On-Reset feature is present</description> + <bitRange>[5:5]</bitRange> + <access>read-only</access> + </field> + <field> + <name>has_ldo</name> + <description>Low Dropout Regulator feature is present</description> + <bitRange>[6:6]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>lfrosccfg</name> + <description>Ring Oscillator Configuration and Status</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>lfroscdiv</name> + <description>Ring Oscillator Divider Register</description> + <bitRange>[5:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>lfrosctrim</name> + <description>Ring Oscillator Trim Register</description> + <bitRange>[20:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>lfroscen</name> + <description>Ring Oscillator Enable</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>lfroscrdy</name> + <description>Ring Oscillator Ready</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>lfclkmux</name> + <description>Low-Frequency Clock Mux Control and Status</description> + <addressOffset>0x7C</addressOffset> + <fields> + <field> + <name>lfextclk_sel</name> + <description>Low Frequency Clock Source Selector</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + <enumeratedValues> + <enumeratedValue> + <name>internal</name> + <description>Use internal LF clock source</description> + <value>0</value> + </enumeratedValue> + <enumeratedValue> + <name>external</name> + <description>Use external LF clock source</description> + <value>1</value> + </enumeratedValue> + </enumeratedValues> + </field> + <field> + <name>lfextclk_mux_status</name> + <description>Setting of the aon_lfclksel pin</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + <enumeratedValues> + <enumeratedValue> + <name>external</name> + <description>Use external LF clock source</description> + <value>0</value> + </enumeratedValue> + <enumeratedValue> + <name>sw</name> + <description>Use clock source selected by lfextclk_sel</description> + <value>1</value> + </enumeratedValue> + </enumeratedValues> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_fe310_g000_prci_0</name> + <description>From sifive,fe310-g000,prci,mem peripheral generator</description> + <baseAddress>0x10008000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x8000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>hfrosccfg</name> + <description>Ring Oscillator Configuration and Status</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>hfroscdiv</name> + <description>Ring Oscillator Divider Register</description> + <bitRange>[5:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfrosctrim</name> + <description>Ring Oscillator Trim Register</description> + <bitRange>[20:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfroscen</name> + <description>Ring Oscillator Enable</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfroscrdy</name> + <description>Ring Oscillator Ready</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>hfxosccfg</name> + <description>Crystal Oscillator Configuration and Status</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>hfxoscen</name> + <description>Crystal Oscillator Enable</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>hfxoscrdy</name> + <description>Crystal Oscillator Ready</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>pllcfg</name> + <description>PLL Configuration and Status</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pllr</name> + <description>PLL R Value</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllf</name> + <description>PLL F Value</description> + <bitRange>[9:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllq</name> + <description>PLL Q Value</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllsel</name> + <description>PLL Select</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllrefsel</name> + <description>PLL Reference Select</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pllbypass</name> + <description>PLL Bypass</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>plllock</name> + <description>PLL Lock</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>plloutdiv</name> + <description>PLL Final Divide Configuration</description> + <addressOffset>0xC</addressOffset> + <fields> + <field> + <name>plloutdiv</name> + <description>PLL Final Divider Value</description> + <bitRange>[5:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>plloutdivby1</name> + <description>PLL Final Divide By 1</description> + <bitRange>[13:8]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>procmoncfg</name> + <description>Process Monitor Configuration and Status</description> + <addressOffset>0xF0</addressOffset> + <fields> + <field> + <name>procmon_div_sel</name> + <description>Proccess Monitor Divider</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>procmon_delay_sel</name> + <description>Process Monitor Delay Selector</description> + <bitRange>[12:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>procmon_en</name> + <description>Process Monitor Enable</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>procomon_sel</name> + <description>Process Monitor Select</description> + <bitRange>[25:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_gpio0_0</name> + <description>From sifive,gpio0,control peripheral generator</description> + <baseAddress>0x10012000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>input_val</name> + <description>Pin value</description> + <addressOffset>0x0</addressOffset> + </register> + <register> + <name>input_en</name> + <description>Pin input enable</description> + <addressOffset>0x4</addressOffset> + </register> + <register> + <name>output_en</name> + <description>Pin output enable</description> + <addressOffset>0x8</addressOffset> + </register> + <register> + <name>output_val</name> + <description>Output value</description> + <addressOffset>0xC</addressOffset> + </register> + <register> + <name>pue</name> + <description>Internal pull-up enable</description> + <addressOffset>0x10</addressOffset> + </register> + <register> + <name>ds</name> + <description>Pin drive strength</description> + <addressOffset>0x14</addressOffset> + </register> + <register> + <name>rise_ie</name> + <description>Rise interrupt enable</description> + <addressOffset>0x18</addressOffset> + </register> + <register> + <name>rise_ip</name> + <description>Rise interrupt pending</description> + <addressOffset>0x1C</addressOffset> + </register> + <register> + <name>fall_ie</name> + <description>Fall interrupt enable</description> + <addressOffset>0x20</addressOffset> + </register> + <register> + <name>fall_ip</name> + <description>Fall interrupt pending</description> + <addressOffset>0x24</addressOffset> + </register> + <register> + <name>high_ie</name> + <description>High interrupt enable</description> + <addressOffset>0x28</addressOffset> + </register> + <register> + <name>high_ip</name> + <description>High interrupt pending</description> + <addressOffset>0x2C</addressOffset> + </register> + <register> + <name>low_ie</name> + <description>Low interrupt enable</description> + <addressOffset>0x30</addressOffset> + </register> + <register> + <name>low_ip</name> + <description>Low interrupt pending</description> + <addressOffset>0x34</addressOffset> + </register> + <register> + <name>iof_en</name> + <description>I/O function enable</description> + <addressOffset>0x38</addressOffset> + </register> + <register> + <name>iof_sel</name> + <description>I/O function select</description> + <addressOffset>0x3C</addressOffset> + </register> + <register> + <name>out_xor</name> + <description>Output XOR (invert)</description> + <addressOffset>0x40</addressOffset> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_uart0_0</name> + <description>From sifive,uart0,control peripheral generator</description> + <baseAddress>0x10013000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>txdata</name> + <description>Transmit data register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>Transmit FIFO full</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Receive data register</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>Receive FIFO empty</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>txctrl</name> + <description>Transmit control register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>txen</name> + <description>Transmit enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>nstop</name> + <description>Number of stop bits</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>txcnt</name> + <description>Transmit watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxctrl</name> + <description>Receive control register</description> + <addressOffset>0xC</addressOffset> + <fields> + <field> + <name>rxen</name> + <description>Receive enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxcnt</name> + <description>Receive watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>UART interrupt enable</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>UART interrupt pending</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>div</name> + <description>Baud rate divisor</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>div</name> + <description>Baud rate divisor.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_spi0_0</name> + <description>From sifive,spi0,control peripheral generator</description> + <baseAddress>0x10014000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>sckdiv</name> + <description>Serial clock divisor</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>div</name> + <description>Divisor for serial clock.</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sckmode</name> + <description>Serial clock mode</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>pha</name> + <description>Serial clock phase</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pol</name> + <description>Serial clock polarity</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csid</name> + <description>Chip select ID</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>csid</name> + <description>Chip select ID.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csdef</name> + <description>Chip select default</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>csdef</name> + <description>Chip select default value. Reset to all-1s.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csmode</name> + <description>Chip select mode</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>mode</name> + <description>Chip select mode</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay0</name> + <description>Delay control 0</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>cssck</name> + <description>CS to SCK Delay</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>sckcs</name> + <description>SCK to CS Delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay1</name> + <description>Delay control 1</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>intercs</name> + <description>Minimum CS inactive time</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>interxfr</name> + <description>Maximum interframe delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>extradel</name> + <description>SPI extra sampling delay to increase the SPI frequency</description> + <addressOffset>0x38</addressOffset> + <fields> + <field> + <name>coarse</name> + <description>Coarse grain sample delay (multiples of system clocks)</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>fine</name> + <description>Fine grain sample delay (multiples of process-specific buffer delay)</description> + <bitRange>[16:12]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sampledel</name> + <description>Number of delay stages from slave to the SPI controller</description> + <addressOffset>0x3C</addressOffset> + <fields> + <field> + <name>sd</name> + <description>Number of delay stages from slave to SPI controller</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fmt</name> + <description>Frame format</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>proto</name> + <description>SPI protocol</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>endian</name> + <description>SPI endianness</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>dir</name> + <description>SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>len</name> + <description>Number of bits per frame</description> + <bitRange>[19:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txdata</name> + <description>Tx FIFO Data</description> + <addressOffset>0x48</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>FIFO full flag</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Rx FIFO data</description> + <addressOffset>0x4C</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>FIFO empty flag</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txmark</name> + <description>Tx FIFO watermark</description> + <addressOffset>0x50</addressOffset> + <fields> + <field> + <name>txmark</name> + <description>Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxmark</name> + <description>Rx FIFO watermark</description> + <addressOffset>0x54</addressOffset> + <fields> + <field> + <name>rxmark</name> + <description>Receive watermark</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fctrl</name> + <description>SPI flash interface control</description> + <addressOffset>0x60</addressOffset> + <fields> + <field> + <name>en</name> + <description>SPI Flash Mode Select</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ffmt</name> + <description>SPI flash instruction format</description> + <addressOffset>0x64</addressOffset> + <fields> + <field> + <name>cmd_en</name> + <description>Enable sending of command</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_len</name> + <description>Number of address bytes (0 to 4)</description> + <bitRange>[3:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_cnt</name> + <description>Number of dummy cycles</description> + <bitRange>[7:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_proto</name> + <description>Protocol for transmitting command</description> + <bitRange>[9:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_proto</name> + <description>Protocol for transmitting address and padding</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>data_proto</name> + <description>Protocol for receiving data bytes</description> + <bitRange>[13:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_code</name> + <description>Value of command byte</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_code</name> + <description>First 8 bits to transmit during dummy cycles</description> + <bitRange>[31:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>SPI interrupt enable</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>SPI interrupt pending</description> + <addressOffset>0x74</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_pwm0_0</name> + <description>From sifive,pwm0,control peripheral generator</description> + <baseAddress>0x10015000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>pwmcfg</name> + <description>PWM configuration register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>pwmscale</name> + <description>PWM Counter scale</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmsticky</name> + <description>PWM Sticky - disallow clearing pwmcmpXip bits</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmzerocmp</name> + <description>PWM Zero - counter resets to zero after match</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmdeglitch</name> + <description>PWM Deglitch - latch pwmcmpXip within same cycle</description> + <bitRange>[10:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenalways</name> + <description>PWM enable always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenoneshot</name> + <description>PWM enable one shot - run one cycle</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0center</name> + <description>PWM0 Compare Center</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1center</name> + <description>PWM1 Compare Center</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2center</name> + <description>PWM2 Compare Center</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3center</name> + <description>PWM3 Compare Center</description> + <bitRange>[19:19]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0invert</name> + <description>PWM0 Invert</description> + <bitRange>[20:20]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1invert</name> + <description>PWM1 Invert</description> + <bitRange>[21:21]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2invert</name> + <description>PWM2 Invert</description> + <bitRange>[22:22]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3invert</name> + <description>PWM3 Invert</description> + <bitRange>[23:23]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0gang</name> + <description>PWM0/PWM1 Compare Gang</description> + <bitRange>[24:24]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1gang</name> + <description>PWM1/PWM2 Compare Gang</description> + <bitRange>[25:25]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2gang</name> + <description>PWM2/PWM3 Compare Gang</description> + <bitRange>[26:26]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3gang</name> + <description>PWM3/PWM0 Compare Gang</description> + <bitRange>[27:27]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0ip</name> + <description>PWM0 Interrupt Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1ip</name> + <description>PWM1 Interrupt Pending</description> + <bitRange>[29:29]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2ip</name> + <description>PWM2 Interrupt Pending</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3ip</name> + <description>PWM3 Interrupt Pending</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcount</name> + <description>PWM count register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pwmcount</name> + <description>PWM count register.</description> + <bitRange>[30:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwms</name> + <description>Scaled PWM count register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>pwms</name> + <description>Scaled PWM count register.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp0</name> + <description>PWM 0 compare register</description> + <addressOffset>0x20</addressOffset> + <fields> + <field> + <name>pwmcmp0</name> + <description>PWM 0 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp1</name> + <description>PWM 1 compare register</description> + <addressOffset>0x24</addressOffset> + <fields> + <field> + <name>pwmcmp1</name> + <description>PWM 1 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp2</name> + <description>PWM 2 compare register</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>pwmcmp2</name> + <description>PWM 2 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp3</name> + <description>PWM 3 compare register</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>pwmcmp3</name> + <description>PWM 3 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_i2c0_0</name> + <description>From sifive,i2c0,control peripheral generator</description> + <baseAddress>0x10016000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>prescale_low</name> + <description>Clock Prescale register lo-byte</description> + <addressOffset>0x0</addressOffset> + </register> + <register> + <name>prescale_high</name> + <description>Clock Prescale register hi-byte</description> + <addressOffset>0x4</addressOffset> + </register> + <register> + <name>control</name> + <description>Control register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>en</name> + <description>I2C core enable bit</description> + <bitRange>[6:6]</bitRange> + <access>read-write</access> + </field> + <field> + <name>ien</name> + <description>I2C core interrupt enable bit</description> + <bitRange>[7:7]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>transmit__receive</name> + <description>Transmit and receive data byte register</description> + <addressOffset>0xC</addressOffset> + </register> + <register> + <name>command__status</name> + <description>Command write and status read register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>wr_iack__rd_if</name> + <description>Clear interrupt and Interrupt pending</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_res__rd_tip</name> + <description>Reserved and Transfer in progress</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_res__rd_res</name> + <description>Reserved and Reserved</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_ack__rd_res</name> + <description>Send ACK/NACK and Reserved</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_txd__rd_res</name> + <description>Transmit data and Reserved</description> + <bitRange>[4:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_rxd__rd_al</name> + <description>Receive data and Arbitration lost</description> + <bitRange>[5:5]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_sto__rd_busy</name> + <description>Generate stop and I2C bus busy</description> + <bitRange>[6:6]</bitRange> + <access>read-write</access> + </field> + <field> + <name>wr_sta__rd_rxack</name> + <description>Generate start and Got ACK/NACK</description> + <bitRange>[7:7]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_uart0_1</name> + <description>From sifive,uart0,control peripheral generator</description> + <baseAddress>0x10023000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>txdata</name> + <description>Transmit data register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>Transmit FIFO full</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Receive data register</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>Receive FIFO empty</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>txctrl</name> + <description>Transmit control register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>txen</name> + <description>Transmit enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>nstop</name> + <description>Number of stop bits</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>txcnt</name> + <description>Transmit watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxctrl</name> + <description>Receive control register</description> + <addressOffset>0xC</addressOffset> + <fields> + <field> + <name>rxen</name> + <description>Receive enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxcnt</name> + <description>Receive watermark level</description> + <bitRange>[18:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>UART interrupt enable</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>UART interrupt pending</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark interrupt pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark interrupt pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>div</name> + <description>Baud rate divisor</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>div</name> + <description>Baud rate divisor.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_spi0_1</name> + <description>From sifive,spi0,control peripheral generator</description> + <baseAddress>0x10024000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>sckdiv</name> + <description>Serial clock divisor</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>div</name> + <description>Divisor for serial clock.</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sckmode</name> + <description>Serial clock mode</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>pha</name> + <description>Serial clock phase</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pol</name> + <description>Serial clock polarity</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csid</name> + <description>Chip select ID</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>csid</name> + <description>Chip select ID.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csdef</name> + <description>Chip select default</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>csdef</name> + <description>Chip select default value. Reset to all-1s.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csmode</name> + <description>Chip select mode</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>mode</name> + <description>Chip select mode</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay0</name> + <description>Delay control 0</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>cssck</name> + <description>CS to SCK Delay</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>sckcs</name> + <description>SCK to CS Delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay1</name> + <description>Delay control 1</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>intercs</name> + <description>Minimum CS inactive time</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>interxfr</name> + <description>Maximum interframe delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>extradel</name> + <description>SPI extra sampling delay to increase the SPI frequency</description> + <addressOffset>0x38</addressOffset> + <fields> + <field> + <name>coarse</name> + <description>Coarse grain sample delay (multiples of system clocks)</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>fine</name> + <description>Fine grain sample delay (multiples of process-specific buffer delay)</description> + <bitRange>[16:12]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sampledel</name> + <description>Number of delay stages from slave to the SPI controller</description> + <addressOffset>0x3C</addressOffset> + <fields> + <field> + <name>sd</name> + <description>Number of delay stages from slave to SPI controller</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fmt</name> + <description>Frame format</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>proto</name> + <description>SPI protocol</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>endian</name> + <description>SPI endianness</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>dir</name> + <description>SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>len</name> + <description>Number of bits per frame</description> + <bitRange>[19:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txdata</name> + <description>Tx FIFO Data</description> + <addressOffset>0x48</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>FIFO full flag</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Rx FIFO data</description> + <addressOffset>0x4C</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>FIFO empty flag</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txmark</name> + <description>Tx FIFO watermark</description> + <addressOffset>0x50</addressOffset> + <fields> + <field> + <name>txmark</name> + <description>Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxmark</name> + <description>Rx FIFO watermark</description> + <addressOffset>0x54</addressOffset> + <fields> + <field> + <name>rxmark</name> + <description>Receive watermark</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fctrl</name> + <description>SPI flash interface control</description> + <addressOffset>0x60</addressOffset> + <fields> + <field> + <name>en</name> + <description>SPI Flash Mode Select</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ffmt</name> + <description>SPI flash instruction format</description> + <addressOffset>0x64</addressOffset> + <fields> + <field> + <name>cmd_en</name> + <description>Enable sending of command</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_len</name> + <description>Number of address bytes (0 to 4)</description> + <bitRange>[3:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_cnt</name> + <description>Number of dummy cycles</description> + <bitRange>[7:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_proto</name> + <description>Protocol for transmitting command</description> + <bitRange>[9:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_proto</name> + <description>Protocol for transmitting address and padding</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>data_proto</name> + <description>Protocol for receiving data bytes</description> + <bitRange>[13:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_code</name> + <description>Value of command byte</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_code</name> + <description>First 8 bits to transmit during dummy cycles</description> + <bitRange>[31:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>SPI interrupt enable</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>SPI interrupt pending</description> + <addressOffset>0x74</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_pwm0_1</name> + <description>From sifive,pwm0,control peripheral generator</description> + <baseAddress>0x10025000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>pwmcfg</name> + <description>PWM configuration register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>pwmscale</name> + <description>PWM Counter scale</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmsticky</name> + <description>PWM Sticky - disallow clearing pwmcmpXip bits</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmzerocmp</name> + <description>PWM Zero - counter resets to zero after match</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmdeglitch</name> + <description>PWM Deglitch - latch pwmcmpXip within same cycle</description> + <bitRange>[10:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenalways</name> + <description>PWM enable always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenoneshot</name> + <description>PWM enable one shot - run one cycle</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0center</name> + <description>PWM0 Compare Center</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1center</name> + <description>PWM1 Compare Center</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2center</name> + <description>PWM2 Compare Center</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3center</name> + <description>PWM3 Compare Center</description> + <bitRange>[19:19]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0invert</name> + <description>PWM0 Invert</description> + <bitRange>[20:20]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1invert</name> + <description>PWM1 Invert</description> + <bitRange>[21:21]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2invert</name> + <description>PWM2 Invert</description> + <bitRange>[22:22]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3invert</name> + <description>PWM3 Invert</description> + <bitRange>[23:23]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0gang</name> + <description>PWM0/PWM1 Compare Gang</description> + <bitRange>[24:24]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1gang</name> + <description>PWM1/PWM2 Compare Gang</description> + <bitRange>[25:25]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2gang</name> + <description>PWM2/PWM3 Compare Gang</description> + <bitRange>[26:26]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3gang</name> + <description>PWM3/PWM0 Compare Gang</description> + <bitRange>[27:27]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0ip</name> + <description>PWM0 Interrupt Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1ip</name> + <description>PWM1 Interrupt Pending</description> + <bitRange>[29:29]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2ip</name> + <description>PWM2 Interrupt Pending</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3ip</name> + <description>PWM3 Interrupt Pending</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcount</name> + <description>PWM count register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pwmcount</name> + <description>PWM count register.</description> + <bitRange>[30:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwms</name> + <description>Scaled PWM count register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>pwms</name> + <description>Scaled PWM count register.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp0</name> + <description>PWM 0 compare register</description> + <addressOffset>0x20</addressOffset> + <fields> + <field> + <name>pwmcmp0</name> + <description>PWM 0 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp1</name> + <description>PWM 1 compare register</description> + <addressOffset>0x24</addressOffset> + <fields> + <field> + <name>pwmcmp1</name> + <description>PWM 1 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp2</name> + <description>PWM 2 compare register</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>pwmcmp2</name> + <description>PWM 2 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp3</name> + <description>PWM 3 compare register</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>pwmcmp3</name> + <description>PWM 3 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_spi0_2</name> + <description>From sifive,spi0,control peripheral generator</description> + <baseAddress>0x10034000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>sckdiv</name> + <description>Serial clock divisor</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>div</name> + <description>Divisor for serial clock.</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sckmode</name> + <description>Serial clock mode</description> + <addressOffset>0x4</addressOffset> + <fields> + <field> + <name>pha</name> + <description>Serial clock phase</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pol</name> + <description>Serial clock polarity</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csid</name> + <description>Chip select ID</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>csid</name> + <description>Chip select ID.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csdef</name> + <description>Chip select default</description> + <addressOffset>0x14</addressOffset> + <fields> + <field> + <name>csdef</name> + <description>Chip select default value. Reset to all-1s.</description> + <bitRange>[31:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>csmode</name> + <description>Chip select mode</description> + <addressOffset>0x18</addressOffset> + <fields> + <field> + <name>mode</name> + <description>Chip select mode</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay0</name> + <description>Delay control 0</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>cssck</name> + <description>CS to SCK Delay</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>sckcs</name> + <description>SCK to CS Delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>delay1</name> + <description>Delay control 1</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>intercs</name> + <description>Minimum CS inactive time</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>interxfr</name> + <description>Maximum interframe delay</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>extradel</name> + <description>SPI extra sampling delay to increase the SPI frequency</description> + <addressOffset>0x38</addressOffset> + <fields> + <field> + <name>coarse</name> + <description>Coarse grain sample delay (multiples of system clocks)</description> + <bitRange>[11:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>fine</name> + <description>Fine grain sample delay (multiples of process-specific buffer delay)</description> + <bitRange>[16:12]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>sampledel</name> + <description>Number of delay stages from slave to the SPI controller</description> + <addressOffset>0x3C</addressOffset> + <fields> + <field> + <name>sd</name> + <description>Number of delay stages from slave to SPI controller</description> + <bitRange>[4:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fmt</name> + <description>Frame format</description> + <addressOffset>0x40</addressOffset> + <fields> + <field> + <name>proto</name> + <description>SPI protocol</description> + <bitRange>[1:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>endian</name> + <description>SPI endianness</description> + <bitRange>[2:2]</bitRange> + <access>read-write</access> + </field> + <field> + <name>dir</name> + <description>SPI I/O direction. This is reset to 1 for flash-enabled SPI controllers, 0 otherwise.</description> + <bitRange>[3:3]</bitRange> + <access>read-write</access> + </field> + <field> + <name>len</name> + <description>Number of bits per frame</description> + <bitRange>[19:16]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txdata</name> + <description>Tx FIFO Data</description> + <addressOffset>0x48</addressOffset> + <fields> + <field> + <name>data</name> + <description>Transmit data</description> + <bitRange>[7:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>full</name> + <description>FIFO full flag</description> + <bitRange>[31:31]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + <register> + <name>rxdata</name> + <description>Rx FIFO data</description> + <addressOffset>0x4C</addressOffset> + <fields> + <field> + <name>data</name> + <description>Received data</description> + <bitRange>[7:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>empty</name> + <description>FIFO empty flag</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>txmark</name> + <description>Tx FIFO watermark</description> + <addressOffset>0x50</addressOffset> + <fields> + <field> + <name>txmark</name> + <description>Transmit watermark. The reset value is 1 for flash-enabled controllers, 0 otherwise.</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>rxmark</name> + <description>Rx FIFO watermark</description> + <addressOffset>0x54</addressOffset> + <fields> + <field> + <name>rxmark</name> + <description>Receive watermark</description> + <bitRange>[2:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>fctrl</name> + <description>SPI flash interface control</description> + <addressOffset>0x60</addressOffset> + <fields> + <field> + <name>en</name> + <description>SPI Flash Mode Select</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ffmt</name> + <description>SPI flash instruction format</description> + <addressOffset>0x64</addressOffset> + <fields> + <field> + <name>cmd_en</name> + <description>Enable sending of command</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_len</name> + <description>Number of address bytes (0 to 4)</description> + <bitRange>[3:1]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_cnt</name> + <description>Number of dummy cycles</description> + <bitRange>[7:4]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_proto</name> + <description>Protocol for transmitting command</description> + <bitRange>[9:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>addr_proto</name> + <description>Protocol for transmitting address and padding</description> + <bitRange>[11:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>data_proto</name> + <description>Protocol for receiving data bytes</description> + <bitRange>[13:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>cmd_code</name> + <description>Value of command byte</description> + <bitRange>[23:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pad_code</name> + <description>First 8 bits to transmit during dummy cycles</description> + <bitRange>[31:24]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ie</name> + <description>SPI interrupt enable</description> + <addressOffset>0x70</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark enable</description> + <bitRange>[0:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark enable</description> + <bitRange>[1:1]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>ip</name> + <description>SPI interrupt pending</description> + <addressOffset>0x74</addressOffset> + <fields> + <field> + <name>txwm</name> + <description>Transmit watermark pending</description> + <bitRange>[0:0]</bitRange> + <access>read-only</access> + </field> + <field> + <name>rxwm</name> + <description>Receive watermark pending</description> + <bitRange>[1:1]</bitRange> + <access>read-only</access> + </field> + </fields> + </register> + </registers> + </peripheral> + <peripheral> + <name>sifive_pwm0_2</name> + <description>From sifive,pwm0,control peripheral generator</description> + <baseAddress>0x10035000</baseAddress> + <addressBlock> + <offset>0</offset> + <size>0x1000</size> + <usage>registers</usage> + </addressBlock> + <registers> + <register> + <name>pwmcfg</name> + <description>PWM configuration register</description> + <addressOffset>0x0</addressOffset> + <fields> + <field> + <name>pwmscale</name> + <description>PWM Counter scale</description> + <bitRange>[3:0]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmsticky</name> + <description>PWM Sticky - disallow clearing pwmcmpXip bits</description> + <bitRange>[8:8]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmzerocmp</name> + <description>PWM Zero - counter resets to zero after match</description> + <bitRange>[9:9]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmdeglitch</name> + <description>PWM Deglitch - latch pwmcmpXip within same cycle</description> + <bitRange>[10:10]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenalways</name> + <description>PWM enable always - run continuously</description> + <bitRange>[12:12]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmenoneshot</name> + <description>PWM enable one shot - run one cycle</description> + <bitRange>[13:13]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0center</name> + <description>PWM0 Compare Center</description> + <bitRange>[16:16]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1center</name> + <description>PWM1 Compare Center</description> + <bitRange>[17:17]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2center</name> + <description>PWM2 Compare Center</description> + <bitRange>[18:18]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3center</name> + <description>PWM3 Compare Center</description> + <bitRange>[19:19]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0invert</name> + <description>PWM0 Invert</description> + <bitRange>[20:20]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1invert</name> + <description>PWM1 Invert</description> + <bitRange>[21:21]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2invert</name> + <description>PWM2 Invert</description> + <bitRange>[22:22]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3invert</name> + <description>PWM3 Invert</description> + <bitRange>[23:23]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0gang</name> + <description>PWM0/PWM1 Compare Gang</description> + <bitRange>[24:24]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1gang</name> + <description>PWM1/PWM2 Compare Gang</description> + <bitRange>[25:25]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2gang</name> + <description>PWM2/PWM3 Compare Gang</description> + <bitRange>[26:26]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3gang</name> + <description>PWM3/PWM0 Compare Gang</description> + <bitRange>[27:27]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp0ip</name> + <description>PWM0 Interrupt Pending</description> + <bitRange>[28:28]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp1ip</name> + <description>PWM1 Interrupt Pending</description> + <bitRange>[29:29]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp2ip</name> + <description>PWM2 Interrupt Pending</description> + <bitRange>[30:30]</bitRange> + <access>read-write</access> + </field> + <field> + <name>pwmcmp3ip</name> + <description>PWM3 Interrupt Pending</description> + <bitRange>[31:31]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcount</name> + <description>PWM count register</description> + <addressOffset>0x8</addressOffset> + <fields> + <field> + <name>pwmcount</name> + <description>PWM count register.</description> + <bitRange>[30:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwms</name> + <description>Scaled PWM count register</description> + <addressOffset>0x10</addressOffset> + <fields> + <field> + <name>pwms</name> + <description>Scaled PWM count register.</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp0</name> + <description>PWM 0 compare register</description> + <addressOffset>0x20</addressOffset> + <fields> + <field> + <name>pwmcmp0</name> + <description>PWM 0 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp1</name> + <description>PWM 1 compare register</description> + <addressOffset>0x24</addressOffset> + <fields> + <field> + <name>pwmcmp1</name> + <description>PWM 1 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp2</name> + <description>PWM 2 compare register</description> + <addressOffset>0x28</addressOffset> + <fields> + <field> + <name>pwmcmp2</name> + <description>PWM 2 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + <register> + <name>pwmcmp3</name> + <description>PWM 3 compare register</description> + <addressOffset>0x2C</addressOffset> + <fields> + <field> + <name>pwmcmp3</name> + <description>PWM 3 Compare Value</description> + <bitRange>[15:0]</bitRange> + <access>read-write</access> + </field> + </fields> + </register> + </registers> + </peripheral> + </peripherals> +</device> \ No newline at end of file diff --git a/bsp/sparkfun-redv/metal-inline.h b/bsp/sparkfun-redv/metal-inline.h new file mode 100644 index 00000000..7933a9c4 --- /dev/null +++ b/bsp/sparkfun-redv/metal-inline.h @@ -0,0 +1,374 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef ASSEMBLY + +#ifndef METAL_INLINE_H +#define METAL_INLINE_H + +#include <metal/machine.h> + + +/* --------------------- 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 ------------ */ + + +/* --------------------- sifive_clic0 ------------ */ + + +/* --------------------- sifive_local_external_interrupts0 ------------ */ + + +/* --------------------- sifive_global_external_interrupts0 ------------ */ + + +/* --------------------- sifive_gpio0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio); +extern __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio); +extern __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio); +extern __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx); + + +/* --------------------- sifive_gpio_button ------------ */ + + +/* --------------------- sifive_gpio_led ------------ */ +extern __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led); +extern __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led); +extern __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led); + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- sifive_i2c0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c); +extern __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c); +extern __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c); +extern __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c); + + +/* --------------------- sifive_pwm0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx); +extern __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm); +extern __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm); +extern __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm); + + +/* --------------------- sifive_rtc0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc); +extern __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc); +extern __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc); +extern __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc); + + +/* --------------------- sifive_spi0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi); +extern __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi); + + +/* --------------------- sifive_test0 ------------ */ + + +/* --------------------- sifive_trace ------------ */ + +/* --------------------- sifive_uart0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart); +extern __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart); +extern __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart); +extern __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart); +extern __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart); +extern __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart); + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog); +extern __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog); +extern __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog); +extern __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog); + + +/* --------------------- sifive_fe310_g000_hfrosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock); +extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock); + + +/* --------------------- sifive_fe310_g000_hfxosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock); + + +/* --------------------- sifive_fe310_g000_lfrosc ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock); +extern __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock); + + +/* --------------------- sifive_fe310_g000_pll ------------ */ +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock); +extern __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( ); +extern __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock); +extern __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ); + + +/* --------------------- fe310_g000_prci ------------ */ +extern __inline__ long __metal_driver_sifive_fe310_g000_prci_base( ); +extern __inline__ long __metal_driver_sifive_fe310_g000_prci_size( ); +extern __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ); + + +/* From clock@0 */ +struct __metal_driver_fixed_clock __metal_dt_clock_0 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@2 */ +struct __metal_driver_fixed_clock __metal_dt_clock_2 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@5 */ +struct __metal_driver_fixed_clock __metal_dt_clock_5 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +/* From clock@6 */ +struct __metal_driver_fixed_clock __metal_dt_clock_6 = { + .clock.vtable = &__metal_driver_vtable_fixed_clock.clock, +}; + +struct metal_memory __metal_dt_mem_dtim_80000000 = { + ._base_address = 2147483648UL, + ._size = 16384UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_itim_8000000 = { + ._base_address = 134217728UL, + ._size = 8192UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10014000 = { + ._base_address = 536870912UL, + ._size = 500000UL, + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10024000 = { + ._attrs = { + .R = 1, + .W = 1, + .X = 1, + .C = 1, + .A = 1}, +}; + +struct metal_memory __metal_dt_mem_spi_10034000 = { + ._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 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@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 gpio@10012000 */ +struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000 = { + .gpio.vtable = &__metal_driver_vtable_sifive_gpio0.gpio, +}; + +/* From led@0 */ +struct __metal_driver_sifive_gpio_led __metal_dt_led_0 = { + .led.vtable = &__metal_driver_vtable_sifive_led.led_vtable, +}; + +/* From i2c@10016000 */ +struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000 = { + .i2c.vtable = &__metal_driver_vtable_sifive_i2c0.i2c, +}; + +/* From pwm@10015000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10025000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From pwm@10035000 */ +struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000 = { + .pwm.vtable = &__metal_driver_vtable_sifive_pwm0.pwm, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000 = { + .rtc.vtable = &__metal_driver_vtable_sifive_rtc0.rtc, +}; + +/* From spi@10014000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10024000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From spi@10034000 */ +struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000 = { + .spi.vtable = &__metal_driver_vtable_sifive_spi0.spi, +}; + +/* From serial@10013000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000 = { + .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, +}; + +/* From serial@10023000 */ +struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000 = { + .uart.vtable = &__metal_driver_vtable_sifive_uart0.uart, +}; + +/* From aon@10000000 */ +struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000 = { + .watchdog.vtable = &__metal_driver_vtable_sifive_wdog0.watchdog, +}; + +/* From clock@3 */ +struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfrosc.clock, +}; + +/* From clock@1 */ +struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_hfxosc.clock, +}; + +/* From clock@7 */ +struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_lfrosc.clock, +}; + +/* From clock@4 */ +struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4 = { + .clock.vtable = &__metal_driver_vtable_sifive_fe310_g000_pll.clock, +}; + +/* From prci@10008000 */ +struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000 = { + .vtable = &__metal_driver_vtable_sifive_fe310_g000_prci, +}; + + +#endif /* METAL_INLINE_H*/ +#endif /* ! ASSEMBLY */ diff --git a/bsp/sparkfun-redv/metal-platform.h b/bsp/sparkfun-redv/metal-platform.h new file mode 100644 index 00000000..6ac62600 --- /dev/null +++ b/bsp/sparkfun-redv/metal-platform.h @@ -0,0 +1,298 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef METAL_PLATFORM_H +#define METAL_PLATFORM_H + +/* From clock@0 */ +#define METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY 16000000UL + +/* From clock@2 */ +#define METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY 72000000UL + +/* From clock@5 */ +#define METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY 32768UL + +/* From clock@6 */ +#define METAL_FIXED_CLOCK_6_CLOCK_FREQUENCY 32768UL + +#define METAL_FIXED_CLOCK + +/* From clint@2000000 */ +#define METAL_RISCV_CLINT0_2000000_BASE_ADDRESS 33554432UL +#define METAL_RISCV_CLINT0_0_BASE_ADDRESS 33554432UL +#define METAL_RISCV_CLINT0_2000000_SIZE 65536UL +#define METAL_RISCV_CLINT0_0_SIZE 65536UL + +#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 201326592UL +#define METAL_RISCV_PLIC0_0_BASE_ADDRESS 201326592UL +#define METAL_RISCV_PLIC0_C000000_SIZE 67108864UL +#define METAL_RISCV_PLIC0_0_SIZE 67108864UL +#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 53UL +#define METAL_RISCV_PLIC0_0_RISCV_NDEV 53UL + +#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 aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_AON0 +#define METAL_SIFIVE_AON0_WDOGCFG 0UL +#define METAL_SIFIVE_AON0_WDOGCOUNT 8UL +#define METAL_SIFIVE_AON0_WDOGS 16UL +#define METAL_SIFIVE_AON0_WDOGFEED 24UL +#define METAL_SIFIVE_AON0_WDOGKEY 28UL +#define METAL_SIFIVE_AON0_WDOGCMP 32UL +#define METAL_SIFIVE_AON0_RTCCFG 64UL +#define METAL_SIFIVE_AON0_RTCLO 72UL +#define METAL_SIFIVE_AON0_RTCHI 72UL +#define METAL_SIFIVE_AON0_RTCS 80UL +#define METAL_SIFIVE_AON0_RTCCMP 96UL +#define METAL_SIFIVE_AON0_LFROSCCFG 112UL +#define METAL_SIFIVE_AON0_BACKUP0 128UL +#define METAL_SIFIVE_AON0_BACKUP1 132UL +#define METAL_SIFIVE_AON0_BACKUP2 136UL +#define METAL_SIFIVE_AON0_BACKUP3 140UL +#define METAL_SIFIVE_AON0_BACKUP4 144UL +#define METAL_SIFIVE_AON0_BACKUP5 148UL +#define METAL_SIFIVE_AON0_BACKUP6 152UL +#define METAL_SIFIVE_AON0_BACKUP7 152UL +#define METAL_SIFIVE_AON0_BACKUP8 160UL +#define METAL_SIFIVE_AON0_BACKUP9 164UL +#define METAL_SIFIVE_AON0_BACKUP10 168UL +#define METAL_SIFIVE_AON0_BACKUP11 172UL +#define METAL_SIFIVE_AON0_BACKUP12 176UL +#define METAL_SIFIVE_AON0_BACKUP13 180UL +#define METAL_SIFIVE_AON0_BACKUP14 184UL +#define METAL_SIFIVE_AON0_BACKUP15 188UL +#define METAL_SIFIVE_AON0_BACKUP16 192UL +#define METAL_SIFIVE_AON0_BACKUP17 196UL +#define METAL_SIFIVE_AON0_BACKUP18 200UL +#define METAL_SIFIVE_AON0_BACKUP19 204UL +#define METAL_SIFIVE_AON0_BACKUP20 208UL +#define METAL_SIFIVE_AON0_BACKUP21 212UL +#define METAL_SIFIVE_AON0_BACKUP22 216UL +#define METAL_SIFIVE_AON0_BACKUP23 220UL +#define METAL_SIFIVE_AON0_BACKUP24 224UL +#define METAL_SIFIVE_AON0_BACKUP25 228UL +#define METAL_SIFIVE_AON0_BACKUP26 232UL +#define METAL_SIFIVE_AON0_BACKUP27 236UL +#define METAL_SIFIVE_AON0_BACKUP28 240UL +#define METAL_SIFIVE_AON0_BACKUP29 244UL +#define METAL_SIFIVE_AON0_BACKUP30 248UL +#define METAL_SIFIVE_AON0_BACKUP31 252UL +#define METAL_SIFIVE_AON0_PMU_WAKEUP_BASE 256UL +#define METAL_SIFIVE_AON0_PWM_SLEEP_BASE 288UL +#define METAL_SIFIVE_AON0_PMUIE 320UL +#define METAL_SIFIVE_AON0_PMUCAUSE 324UL +#define METAL_SIFIVE_AON0_PMUSLEEP 328UL +#define METAL_SIFIVE_AON0_PMUKEY 332UL + +/* From clock@3 */ + +#define METAL_SIFIVE_FE310_G000_HFROSC + +/* From clock@1 */ + +#define METAL_SIFIVE_FE310_G000_HFXOSC + +/* From clock@7 */ + +#define METAL_SIFIVE_FE310_G000_LFROSC + +/* From prci@10008000 */ +#define METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS 268468224UL +#define METAL_SIFIVE_FE310_G000_PRCI_0_BASE_ADDRESS 268468224UL +#define METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE 32768UL +#define METAL_SIFIVE_FE310_G000_PRCI_0_SIZE 32768UL + +#define METAL_SIFIVE_FE310_G000_PRCI +#define METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG 0UL +#define METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG 4UL +#define METAL_SIFIVE_FE310_G000_PRCI_PLLCFG 8UL +#define METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV 12UL + +/* From clock@4 */ +#define METAL_SIFIVE_FE310_G000_PLL_4_CLOCK_FREQUENCY 16000000UL + +#define METAL_SIFIVE_FE310_G000_PLL + +/* From gpio@10012000 */ +#define METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS 268509184UL +#define METAL_SIFIVE_GPIO0_0_BASE_ADDRESS 268509184UL +#define METAL_SIFIVE_GPIO0_10012000_SIZE 4096UL +#define METAL_SIFIVE_GPIO0_0_SIZE 4096UL + +#define METAL_SIFIVE_GPIO0 +#define METAL_SIFIVE_GPIO0_VALUE 0UL +#define METAL_SIFIVE_GPIO0_INPUT_EN 4UL +#define METAL_SIFIVE_GPIO0_OUTPUT_EN 8UL +#define METAL_SIFIVE_GPIO0_PORT 12UL +#define METAL_SIFIVE_GPIO0_PUE 16UL +#define METAL_SIFIVE_GPIO0_DS 20UL +#define METAL_SIFIVE_GPIO0_RISE_IE 24UL +#define METAL_SIFIVE_GPIO0_RISE_IP 28UL +#define METAL_SIFIVE_GPIO0_FALL_IE 32UL +#define METAL_SIFIVE_GPIO0_FALL_IP 36UL +#define METAL_SIFIVE_GPIO0_HIGH_IE 40UL +#define METAL_SIFIVE_GPIO0_HIGH_IP 44UL +#define METAL_SIFIVE_GPIO0_LOW_IE 48UL +#define METAL_SIFIVE_GPIO0_LOW_IP 52UL +#define METAL_SIFIVE_GPIO0_IOF_EN 56UL +#define METAL_SIFIVE_GPIO0_IOF_SEL 60UL +#define METAL_SIFIVE_GPIO0_OUT_XOR 64UL + +/* From led@0 */ + +#define METAL_SIFIVE_GPIO_LEDS + +/* From i2c@10016000 */ +#define METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_0_BASE_ADDRESS 268525568UL +#define METAL_SIFIVE_I2C0_10016000_SIZE 4096UL +#define METAL_SIFIVE_I2C0_0_SIZE 4096UL + +#define METAL_SIFIVE_I2C0 +#define METAL_SIFIVE_I2C0_PRESCALE_LOW 0UL +#define METAL_SIFIVE_I2C0_PRESCALE_HIGH 4UL +#define METAL_SIFIVE_I2C0_CONTROL 8UL +#define METAL_SIFIVE_I2C0_TRANSMIT 12UL +#define METAL_SIFIVE_I2C0_RECEIVE 12UL +#define METAL_SIFIVE_I2C0_COMMAND 16UL +#define METAL_SIFIVE_I2C0_STATUS 16UL + +/* From pwm@10015000 */ +#define METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS 268521472UL +#define METAL_SIFIVE_PWM0_0_BASE_ADDRESS 268521472UL +#define METAL_SIFIVE_PWM0_10015000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_0_SIZE 4096UL + +/* From pwm@10025000 */ +#define METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_1_BASE_ADDRESS 268587008UL +#define METAL_SIFIVE_PWM0_10025000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_1_SIZE 4096UL + +/* From pwm@10035000 */ +#define METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_2_BASE_ADDRESS 268652544UL +#define METAL_SIFIVE_PWM0_10035000_SIZE 4096UL +#define METAL_SIFIVE_PWM0_2_SIZE 4096UL + +#define METAL_SIFIVE_PWM0 +#define METAL_SIFIVE_PWM0_PWMCFG 0UL +#define METAL_SIFIVE_PWM0_PWMCOUNT 8UL +#define METAL_SIFIVE_PWM0_PWMS 16UL +#define METAL_SIFIVE_PWM0_PWMCMP0 32UL +#define METAL_SIFIVE_PWM0_PWMCMP1 36UL +#define METAL_SIFIVE_PWM0_PWMCMP2 40UL +#define METAL_SIFIVE_PWM0_PWMCMP3 44UL + +/* From aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_RTC0 +#define METAL_SIFIVE_RTC0_RTCCFG 64UL +#define METAL_SIFIVE_RTC0_RTCCOUNTLO 72UL +#define METAL_SIFIVE_RTC0_RTCCOUNTHI 76UL +#define METAL_SIFIVE_RTC0_RTCS 80UL +#define METAL_SIFIVE_RTC0_RTCCMP0 96UL + +/* From spi@10014000 */ +#define METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS 268517376UL +#define METAL_SIFIVE_SPI0_0_BASE_ADDRESS 268517376UL +#define METAL_SIFIVE_SPI0_10014000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_0_SIZE 4096UL + +/* From spi@10024000 */ +#define METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_1_BASE_ADDRESS 268582912UL +#define METAL_SIFIVE_SPI0_10024000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_1_SIZE 4096UL + +/* From spi@10034000 */ +#define METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_2_BASE_ADDRESS 268648448UL +#define METAL_SIFIVE_SPI0_10034000_SIZE 4096UL +#define METAL_SIFIVE_SPI0_2_SIZE 4096UL + +#define METAL_SIFIVE_SPI0 +#define METAL_SIFIVE_SPI0_SCKDIV 0UL +#define METAL_SIFIVE_SPI0_SCKMODE 4UL +#define METAL_SIFIVE_SPI0_CSID 16UL +#define METAL_SIFIVE_SPI0_CSDEF 20UL +#define METAL_SIFIVE_SPI0_CSMODE 24UL +#define METAL_SIFIVE_SPI0_DELAY0 40UL +#define METAL_SIFIVE_SPI0_DELAY1 44UL +#define METAL_SIFIVE_SPI0_FMT 64UL +#define METAL_SIFIVE_SPI0_TXDATA 72UL +#define METAL_SIFIVE_SPI0_RXDATA 76UL +#define METAL_SIFIVE_SPI0_TXMARK 80UL +#define METAL_SIFIVE_SPI0_RXMARK 84UL +#define METAL_SIFIVE_SPI0_FCTRL 96UL +#define METAL_SIFIVE_SPI0_FFMT 100UL +#define METAL_SIFIVE_SPI0_IE 112UL +#define METAL_SIFIVE_SPI0_IP 116UL + +/* From serial@10013000 */ +#define METAL_SIFIVE_UART0_10013000_BASE_ADDRESS 268513280UL +#define METAL_SIFIVE_UART0_0_BASE_ADDRESS 268513280UL +#define METAL_SIFIVE_UART0_10013000_SIZE 4096UL +#define METAL_SIFIVE_UART0_0_SIZE 4096UL + +/* From serial@10023000 */ +#define METAL_SIFIVE_UART0_10023000_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_1_BASE_ADDRESS 268578816UL +#define METAL_SIFIVE_UART0_10023000_SIZE 4096UL +#define METAL_SIFIVE_UART0_1_SIZE 4096UL + +#define METAL_SIFIVE_UART0 +#define METAL_SIFIVE_UART0_TXDATA 0UL +#define METAL_SIFIVE_UART0_RXDATA 4UL +#define METAL_SIFIVE_UART0_TXCTRL 8UL +#define METAL_SIFIVE_UART0_RXCTRL 12UL +#define METAL_SIFIVE_UART0_IE 16UL +#define METAL_SIFIVE_UART0_IP 20UL +#define METAL_SIFIVE_UART0_DIV 24UL + +/* From aon@10000000 */ +#define METAL_SIFIVE_AON0_10000000_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_0_BASE_ADDRESS 268435456UL +#define METAL_SIFIVE_AON0_10000000_SIZE 32768UL +#define METAL_SIFIVE_AON0_0_SIZE 32768UL + +#define METAL_SIFIVE_WDOG0 +#define METAL_SIFIVE_WDOG0_MAGIC_KEY 5370206UL +#define METAL_SIFIVE_WDOG0_MAGIC_FOOD 218755085UL +#define METAL_SIFIVE_WDOG0_WDOGCFG 0UL +#define METAL_SIFIVE_WDOG0_WDOGCOUNT 8UL +#define METAL_SIFIVE_WDOG0_WDOGS 16UL +#define METAL_SIFIVE_WDOG0_WDOGFEED 24UL +#define METAL_SIFIVE_WDOG0_WDOGKEY 28UL +#define METAL_SIFIVE_WDOG0_WDOGCMP 32UL + +#endif /* METAL_PLATFORM_H*/ diff --git a/bsp/sparkfun-redv/metal.default.lds b/bsp/sparkfun-redv/metal.default.lds new file mode 100644 index 00000000..094dcb61 --- /dev/null +++ b/bsp/sparkfun-redv/metal.default.lds @@ -0,0 +1,301 @@ +/* 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 +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +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); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* 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.*) + } >itim 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.*) + } >ram 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 = . ); + 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/sparkfun-redv/metal.freertos.lds b/bsp/sparkfun-redv/metal.freertos.lds new file mode 100644 index 00000000..4798504e --- /dev/null +++ b/bsp/sparkfun-redv/metal.freertos.lds @@ -0,0 +1,327 @@ +/* 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 +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +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); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* 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.*) + } >itim 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.*) + } >ram 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 = . ); + 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/sparkfun-redv/metal.h b/bsp/sparkfun-redv/metal.h new file mode 100644 index 00000000..b00885c3 --- /dev/null +++ b/bsp/sparkfun-redv/metal.h @@ -0,0 +1,1468 @@ +/* Copyright 2019 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ +/* ----------------------------------- */ +/* ----------------------------------- */ + +#ifndef ASSEMBLY + +#include <metal/machine/platform.h> + +#ifdef __METAL_MACHINE_MACROS + +#ifndef MACROS_IF_METAL_H +#define MACROS_IF_METAL_H + +#define __METAL_CLINT_NUM_PARENTS 2 + +#ifndef __METAL_CLINT_NUM_PARENTS +#define __METAL_CLINT_NUM_PARENTS 0 +#endif +#define __METAL_PLIC_SUBINTERRUPTS 53 + +#define __METAL_PLIC_NUM_PARENTS 1 + +#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 2 + +#define METAL_MAX_CLINT_INTERRUPTS 2 + +#define __METAL_CLINT_NUM_PARENTS 2 + +#define __METAL_INTERRUPT_CONTROLLER_C000000_INTERRUPTS 1 + +#define __METAL_PLIC_SUBINTERRUPTS 53 + +#define METAL_MAX_PLIC_INTERRUPTS 1 + +#define __METAL_PLIC_NUM_PARENTS 1 + +#define __METAL_CLIC_SUBINTERRUPTS 0 +#define METAL_MAX_CLIC_INTERRUPTS 0 + +#define METAL_MAX_LOCAL_EXT_INTERRUPTS 0 + +#define METAL_MAX_GLOBAL_EXT_INTERRUPTS 0 + +#define __METAL_GPIO_10012000_INTERRUPTS 32 + +#define METAL_MAX_GPIO_INTERRUPTS 32 + +#define __METAL_I2C_10016000_INTERRUPTS 1 + +#define METAL_MAX_I2C0_INTERRUPTS 1 + +#define __METAL_PWM_10015000_INTERRUPTS 4 + +#define __METAL_PWM_10025000_INTERRUPTS 4 + +#define __METAL_PWM_10035000_INTERRUPTS 4 + +#define METAL_MAX_PWM0_INTERRUPTS 4 + +#define METAL_MAX_PWM0_NCMP 4 + +#define __METAL_SERIAL_10013000_INTERRUPTS 1 + +#define __METAL_SERIAL_10023000_INTERRUPTS 1 + +#define METAL_MAX_UART_INTERRUPTS 1 + +#define METAL_MAX_SIMUART_INTERRUPTS 0 + + +#include <metal/drivers/fixed-clock.h> +#include <metal/memory.h> +#include <metal/drivers/riscv_clint0.h> +#include <metal/drivers/riscv_cpu.h> +#include <metal/drivers/riscv_plic0.h> +#include <metal/pmp.h> +#include <metal/drivers/sifive_gpio0.h> +#include <metal/drivers/sifive_gpio-leds.h> +#include <metal/drivers/sifive_i2c0.h> +#include <metal/drivers/sifive_pwm0.h> +#include <metal/drivers/sifive_rtc0.h> +#include <metal/drivers/sifive_spi0.h> +#include <metal/drivers/sifive_uart0.h> +#include <metal/drivers/sifive_wdog0.h> +#include <metal/drivers/sifive_fe310-g000_hfrosc.h> +#include <metal/drivers/sifive_fe310-g000_hfxosc.h> +#include <metal/drivers/sifive_fe310-g000_lfrosc.h> +#include <metal/drivers/sifive_fe310-g000_pll.h> +#include <metal/drivers/sifive_fe310-g000_prci.h> + +/* From clock@0 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_0; + +/* From clock@2 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_2; + +/* From clock@5 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_5; + +/* From clock@6 */ +extern struct __metal_driver_fixed_clock __metal_dt_clock_6; + +extern struct metal_memory __metal_dt_mem_dtim_80000000; + +extern struct metal_memory __metal_dt_mem_itim_8000000; + +extern struct metal_memory __metal_dt_mem_spi_10014000; + +extern struct metal_memory __metal_dt_mem_spi_10024000; + +extern struct metal_memory __metal_dt_mem_spi_10034000; + +/* 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; + +extern struct __metal_driver_riscv_cpu_intc __metal_dt_cpu_0_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 gpio@10012000 */ +extern struct __metal_driver_sifive_gpio0 __metal_dt_gpio_10012000; + +/* From led@0 */ +extern struct __metal_driver_sifive_gpio_led __metal_dt_led_0; + +/* From i2c@10016000 */ +extern struct __metal_driver_sifive_i2c0 __metal_dt_i2c_10016000; + +/* From pwm@10015000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10015000; + +/* From pwm@10025000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10025000; + +/* From pwm@10035000 */ +extern struct __metal_driver_sifive_pwm0 __metal_dt_pwm_10035000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_rtc0 __metal_dt_rtc_10000000; + +/* From spi@10014000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10014000; + +/* From spi@10024000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10024000; + +/* From spi@10034000 */ +extern struct __metal_driver_sifive_spi0 __metal_dt_spi_10034000; + +/* From serial@10013000 */ +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10013000; + +/* From serial@10023000 */ +extern struct __metal_driver_sifive_uart0 __metal_dt_serial_10023000; + +/* From aon@10000000 */ +extern struct __metal_driver_sifive_wdog0 __metal_dt_aon_10000000; + +/* From clock@3 */ +extern struct __metal_driver_sifive_fe310_g000_hfrosc __metal_dt_clock_3; + +/* From clock@1 */ +extern struct __metal_driver_sifive_fe310_g000_hfxosc __metal_dt_clock_1; + +/* From clock@7 */ +extern struct __metal_driver_sifive_fe310_g000_lfrosc __metal_dt_clock_7; + +/* From clock@4 */ +extern struct __metal_driver_sifive_fe310_g000_pll __metal_dt_clock_4; + +/* From prci@10008000 */ +extern struct __metal_driver_sifive_fe310_g000_prci __metal_dt_prci_10008000; + + + +/* --------------------- fixed_clock ------------ */ +static __inline__ unsigned long __metal_driver_fixed_clock_rate(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_0) { + return METAL_FIXED_CLOCK_0_CLOCK_FREQUENCY; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_2) { + return METAL_FIXED_CLOCK_2_CLOCK_FREQUENCY; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_5) { + return METAL_FIXED_CLOCK_5_CLOCK_FREQUENCY; + } + else if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_6) { + return METAL_FIXED_CLOCK_6_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 { + 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 { + 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 { + return -1; + } +} + +static __inline__ int __metal_driver_cpu_timebase(struct metal_cpu *cpu) +{ + if ((uintptr_t)cpu == (uintptr_t)&__metal_dt_cpu_0) { + return 16000000; + } + 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 { + 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 8; + } + 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 NULL; + } + 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 { + return NULL; + } +} + +static __inline__ int __metal_driver_sifive_plic0_interrupt_lines(struct metal_interrupt *controller, int idx) +{ + if (idx == 0) { + return 11; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_plic0_context_ids(int hartid) +{ + if (hartid == 0) { + return 0; + } + else { + return -1; + } +} + + + +/* --------------------- sifive_buserror0 ------------ */ + + +/* --------------------- sifive_clic0 ------------ */ + + +/* --------------------- sifive_local_external_interrupts0 ------------ */ + + +/* --------------------- sifive_global_external_interrupts0 ------------ */ + + +/* --------------------- sifive_gpio0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_gpio0_base(struct metal_gpio *gpio) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_gpio0_size(struct metal_gpio *gpio) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_SIFIVE_GPIO0_10012000_SIZE; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_gpio0_num_interrupts(struct metal_gpio *gpio) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return METAL_MAX_GPIO_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_gpio0_interrupt_parent(struct metal_gpio *gpio) +{ + if ((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_gpio0_interrupt_lines(struct metal_gpio *gpio, int idx) +{ + if (((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 0)) { + return 8; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 1))) { + return 9; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 2))) { + return 10; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 3))) { + return 11; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 4))) { + return 12; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 5))) { + return 13; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 6))) { + return 14; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 7))) { + return 15; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 8))) { + return 16; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 9))) { + return 17; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 10))) { + return 18; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 11))) { + return 19; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 12))) { + return 20; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 13))) { + return 21; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 14))) { + return 22; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 15))) { + return 23; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 16))) { + return 24; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 17))) { + return 25; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 18))) { + return 26; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 19))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 20))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 21))) { + return 29; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 22))) { + return 30; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 23))) { + return 31; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 24))) { + return 32; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 25))) { + return 33; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 26))) { + return 34; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 27))) { + return 35; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 28))) { + return 36; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 29))) { + return 27; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 30))) { + return 28; + } + else if ((((uintptr_t)gpio == (uintptr_t)&__metal_dt_gpio_10012000) && (idx == 31))) { + return 29; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_gpio_button ------------ */ + + +/* --------------------- sifive_gpio_led ------------ */ +static __inline__ struct metal_gpio * __metal_driver_sifive_gpio_led_gpio(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return (struct metal_gpio *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ int __metal_driver_sifive_gpio_led_pin(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return 5; + } + else { + return 0; + } +} + +static __inline__ char * __metal_driver_sifive_gpio_led_label(struct metal_led *led) +{ + if ((uintptr_t)led == (uintptr_t)&__metal_dt_led_0) { + return "LD0"; + } + else { + return ""; + } +} + + + +/* --------------------- sifive_gpio_switch ------------ */ + + +/* --------------------- sifive_i2c0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_base(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_control_size(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return METAL_SIFIVE_I2C0_10016000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_i2c0_clock(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_i2c0_pinmux(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_output_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_i2c0_pinmux_source_selector(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 12288; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_i2c0_num_interrupts(struct metal_i2c *i2c) +{ + return METAL_MAX_I2C0_INTERRUPTS; +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_i2c0_interrupt_parent(struct metal_i2c *i2c) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_i2c0_interrupt_line(struct metal_i2c *i2c) +{ + if ((uintptr_t)i2c == (uintptr_t)&__metal_dt_i2c_10016000) { + return 52; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_pwm0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_base(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_BASE_ADDRESS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_BASE_ADDRESS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_control_size(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return METAL_SIFIVE_PWM0_10015000_SIZE; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return METAL_SIFIVE_PWM0_10025000_SIZE; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return METAL_SIFIVE_PWM0_10035000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_pwm0_clock(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return NULL; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_pwm0_pinmux(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return NULL; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_output_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_pwm0_pinmux_source_selector(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 15; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 7864320; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 15360; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_num_interrupts(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return __METAL_PWM_10015000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return __METAL_PWM_10025000_INTERRUPTS; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return __METAL_PWM_10035000_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_pwm0_interrupt_parent(struct metal_pwm *pwm) +{ + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; +} + +static __inline__ int __metal_driver_sifive_pwm0_interrupt_lines(struct metal_pwm *pwm, int idx) +{ + if (((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 0)) { + return 40; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 1))) { + return 41; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 2))) { + return 42; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) && (idx == 3))) { + return 43; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 0))) { + return 44; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 1))) { + return 45; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 2))) { + return 46; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) && (idx == 3))) { + return 47; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 0))) { + return 48; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 1))) { + return 49; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 2))) { + return 50; + } + else if ((((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) && (idx == 3))) { + return 51; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_compare_width(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 8; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 16; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 16; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_pwm0_comparator_count(struct metal_pwm *pwm) +{ + if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10015000) { + return 4; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10025000) { + return 4; + } + else if ((uintptr_t)pwm == (uintptr_t)&__metal_dt_pwm_10035000) { + return 4; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_rtc0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_base(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_rtc0_control_size(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_rtc0_interrupt_parent(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_rtc0_interrupt_line(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return 2; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_rtc0_clock(const struct metal_rtc *const rtc) +{ + if ((uintptr_t)rtc == (uintptr_t)&__metal_dt_rtc_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } +} + + +static __inline__ unsigned long __metal_driver_sifive_spi0_control_base(struct metal_spi *spi) +{ + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return METAL_SIFIVE_SPI0_10014000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_BASE_ADDRESS; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_spi0_control_size(struct metal_spi *spi) +{ + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return METAL_SIFIVE_SPI0_10014000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return METAL_SIFIVE_SPI0_10024000_SIZE; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return METAL_SIFIVE_SPI0_10034000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_spi0_clock(struct metal_spi *spi) +{ + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_spi0_pinmux(struct metal_spi *spi) +{ + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_output_selector(struct metal_spi *spi) +{ + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_spi0_pinmux_source_selector(struct metal_spi *spi) +{ + if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10014000) { + return 0; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10024000) { + return 60; + } + else if ((uintptr_t)spi == (uintptr_t)&__metal_dt_spi_10034000) { + return 4227858432; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_test0 ------------ */ + + +/* --------------------- sifive_trace ------------ */ + +/* --------------------- sifive_uart0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_uart0_control_base(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return METAL_SIFIVE_UART0_10013000_BASE_ADDRESS; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_uart0_control_size(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return METAL_SIFIVE_UART0_10013000_SIZE; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_SIFIVE_UART0_10023000_SIZE; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_uart0_num_interrupts(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return METAL_MAX_UART_INTERRUPTS; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return METAL_MAX_UART_INTERRUPTS; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_uart0_interrupt_parent(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_uart0_interrupt_line(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 3; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 4; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_uart0_clock(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct metal_clock *)&__metal_dt_clock_4.clock; + } + else { + return 0; + } +} + +static __inline__ struct __metal_driver_sifive_gpio0 * __metal_driver_sifive_uart0_pinmux(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return (struct __metal_driver_sifive_gpio0 *)&__metal_dt_gpio_10012000; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_output_selector(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 0; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 0; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_uart0_pinmux_source_selector(struct metal_uart *uart) +{ + if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10013000) { + return 196608; + } + else if ((uintptr_t)uart == (uintptr_t)&__metal_dt_serial_10023000) { + return 8650752; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_simuart0 ------------ */ + + +/* --------------------- sifive_wdog0 ------------ */ +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_base(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_BASE_ADDRESS; + } + else { + return 0; + } +} + +static __inline__ unsigned long __metal_driver_sifive_wdog0_control_size(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return METAL_SIFIVE_AON0_10000000_SIZE; + } + else { + return 0; + } +} + +static __inline__ struct metal_interrupt * __metal_driver_sifive_wdog0_interrupt_parent(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_interrupt *)&__metal_dt_interrupt_controller_c000000.controller; + } + else { + return 0; + } +} + +static __inline__ int __metal_driver_sifive_wdog0_interrupt_line(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return 1; + } + else { + return 0; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_wdog0_clock(const struct metal_watchdog *const watchdog) +{ + if ((uintptr_t)watchdog == (uintptr_t)&__metal_dt_aon_10000000) { + return (struct metal_clock *)&__metal_dt_clock_7.clock; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_fe310_g000_hfrosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfrosc_ref(const struct metal_clock *clock) +{ + return (struct metal_clock *)&__metal_dt_clock_2.clock; +} + +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_base(const struct metal_clock *clock) +{ + return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; +} + +static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfrosc_config_vtable(struct metal_clock *clock) +{ + return &__metal_driver_vtable_sifive_fe310_g000_prci; +} + +static __inline__ long __metal_driver_sifive_fe310_g000_hfrosc_config_offset(const struct metal_clock *clock) +{ + return METAL_SIFIVE_FE310_G000_PRCI_HFROSCCFG; +} + + + +/* --------------------- sifive_fe310_g000_hfxosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_hfxosc_ref(const struct metal_clock *clock) +{ + return (struct metal_clock *)&__metal_dt_clock_0.clock; +} + +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_hfxosc_config_base(const struct metal_clock *clock) +{ + return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; +} + +static __inline__ long __metal_driver_sifive_fe310_g000_hfxosc_config_offset(const struct metal_clock *clock) +{ + return METAL_SIFIVE_FE310_G000_PRCI_HFXOSCCFG; +} + + + +/* --------------------- sifive_fe310_g000_lfrosc ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_lfrosc(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_5.clock; + } + else { + return NULL; + } +} + +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_lfrosc_psdlfaltclk(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return (struct metal_clock *)&__metal_dt_clock_6.clock; + } + else { + return NULL; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_config_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 112; + } + else { + return 0; + } +} + +static __inline__ unsigned long int __metal_driver_sifive_fe310_g000_lfrosc_mux_reg(const struct metal_clock *clock) +{ + if ((uintptr_t)clock == (uintptr_t)&__metal_dt_clock_7) { + return 124; + } + else { + return 0; + } +} + + + +/* --------------------- sifive_fe310_g000_pll ------------ */ +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllsel0(const struct metal_clock *clock) +{ + return (struct metal_clock *)&__metal_dt_clock_3.clock; +} + +static __inline__ struct metal_clock * __metal_driver_sifive_fe310_g000_pll_pllref(const struct metal_clock *clock) +{ + return (struct metal_clock *)&__metal_dt_clock_1.clock; +} + +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_divider_base(const struct metal_clock *clock) +{ + return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; +} + +static __inline__ long __metal_driver_sifive_fe310_g000_pll_divider_offset(const struct metal_clock *clock) +{ + return METAL_SIFIVE_FE310_G000_PRCI_PLLOUTDIV; +} + +static __inline__ struct __metal_driver_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_pll_config_base( ) +{ + return (struct __metal_driver_sifive_fe310_g000_prci *)&__metal_dt_prci_10008000; +} + +static __inline__ long __metal_driver_sifive_fe310_g000_pll_config_offset( ) +{ + return METAL_SIFIVE_FE310_G000_PRCI_PLLCFG; +} + +static __inline__ long __metal_driver_sifive_fe310_g000_pll_init_rate( ) +{ + return 16000000; +} + + + +/* --------------------- sifive_fe310_g000_prci ------------ */ +static __inline__ long __metal_driver_sifive_fe310_g000_prci_base( ) +{ + return METAL_SIFIVE_FE310_G000_PRCI_10008000_BASE_ADDRESS; +} + +static __inline__ long __metal_driver_sifive_fe310_g000_prci_size( ) +{ + return METAL_SIFIVE_FE310_G000_PRCI_10008000_SIZE; +} + +static __inline__ const struct __metal_driver_vtable_sifive_fe310_g000_prci * __metal_driver_sifive_fe310_g000_prci_vtable( ) +{ + return &__metal_driver_vtable_sifive_fe310_g000_prci; +} + + + +#define __METAL_DT_MAX_MEMORIES 3 + +__asm__ (".weak __metal_memory_table"); +struct metal_memory *__metal_memory_table[] = { + &__metal_dt_mem_dtim_80000000, + &__metal_dt_mem_itim_8000000, + &__metal_dt_mem_spi_10014000}; + +/* From serial@10013000 */ +#define __METAL_DT_STDOUT_UART_HANDLE (&__metal_dt_serial_10013000.uart) + +#define __METAL_DT_SERIAL_10013000_HANDLE (&__metal_dt_serial_10013000.uart) + +#define __METAL_DT_STDOUT_UART_BAUD 115200 + +/* 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 1 + +#define __METAL_CPU_0_ICACHE_HANDLE 1 + +__asm__ (".weak __metal_cpu_table"); +struct __metal_driver_cpu *__metal_cpu_table[] = { + &__metal_dt_cpu_0}; + +/* 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) + +#define __MEE_DT_MAX_GPIOS 1 + +__asm__ (".weak __metal_gpio_table"); +struct __metal_driver_sifive_gpio0 *__metal_gpio_table[] = { + &__metal_dt_gpio_10012000}; + +#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 1 + +__asm__ (".weak __metal_led_table"); +struct __metal_driver_sifive_gpio_led *__metal_led_table[] = { + &__metal_dt_led_0}; + +#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 1 + +__asm__ (".weak __metal_i2c_table"); +struct __metal_driver_sifive_i2c0 *__metal_i2c_table[] = { + &__metal_dt_i2c_10016000}; + +#define __METAL_DT_MAX_PWMS 3 + +__asm__ (".weak __metal_pwm_table"); +struct __metal_driver_sifive_pwm0 *__metal_pwm_table[] = { + &__metal_dt_pwm_10015000, + &__metal_dt_pwm_10025000, + &__metal_dt_pwm_10035000}; + +#define __METAL_DT_MAX_RTCS 1 + +__asm__ (".weak __metal_rtc_table"); +struct __metal_driver_sifive_rtc0 *__metal_rtc_table[] = { + &__metal_dt_rtc_10000000}; + +#define __METAL_DT_MAX_SPIS 3 + +__asm__ (".weak __metal_spi_table"); +struct __metal_driver_sifive_spi0 *__metal_spi_table[] = { + &__metal_dt_spi_10014000, + &__metal_dt_spi_10024000, + &__metal_dt_spi_10034000}; + +#define __METAL_DT_MAX_UARTS 2 + +__asm__ (".weak __metal_uart_table"); +struct __metal_driver_sifive_uart0 *__metal_uart_table[] = { + &__metal_dt_serial_10013000, + &__metal_dt_serial_10023000}; + +#define __METAL_DT_MAX_SIMUARTS 0 + +__asm__ (".weak __metal_simuart_table"); +struct __metal_driver_sifive_simuart0 *__metal_simuart_table[] = { + NULL }; +#define __METAL_DT_MAX_WDOGS 1 + +__asm__ (".weak __metal_wdog_table"); +struct __metal_driver_sifive_wdog0 *__metal_wdog_table[] = { + &__metal_dt_aon_10000000}; + +/* From clock@4 */ +#define __METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE (&__metal_dt_clock_4) + +#define __METAL_DT_CLOCK_4_HANDLE (&__metal_dt_clock_4) + +#endif /* MACROS_ELSE_METAL_H*/ + +#endif /* ! __METAL_MACHINE_MACROS */ + +#endif /* ! ASSEMBLY */ diff --git a/bsp/sparkfun-redv/metal.ramrodata.lds b/bsp/sparkfun-redv/metal.ramrodata.lds new file mode 100644 index 00000000..6803873c --- /dev/null +++ b/bsp/sparkfun-redv/metal.ramrodata.lds @@ -0,0 +1,306 @@ +/* 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 +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +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); + + /* The memory_ecc_scrub bit is used by _entry code to enable/disable + * memories scrubbing to zero */ + PROVIDE(__metal_eccscrub_bit = 0); + + /* The RAM memories map for ECC scrubbing */ + PROVIDE( metal_dtim_0_memory_start = 0x80000000 ); + PROVIDE( metal_dtim_0_memory_end = 0x80000000 + 0x4000 ); + PROVIDE( metal_itim_0_memory_start = 0x8000000 ); + PROVIDE( metal_itim_0_memory_end = 0x8000000 + 0x2000 ); + + /* 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.*) + } >itim 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.*) + } >ram 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 = . ); + 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/sparkfun-redv/metal.scratchpad.lds b/bsp/sparkfun-redv/metal.scratchpad.lds new file mode 100644 index 00000000..35672691 --- /dev/null +++ b/bsp/sparkfun-redv/metal.scratchpad.lds @@ -0,0 +1,294 @@ +/* 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 +{ + itim (airwx) : ORIGIN = 0x8000000, LENGTH = 0x2000 + ram (arw!xi) : ORIGIN = 0x80000000, LENGTH = 0x4000 + rom (irx!wa) : ORIGIN = 0x20010000, LENGTH = 0x6a120 +} + +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.*) + } >itim 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.*) + } >ram 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 = . ); + 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/sparkfun-redv/settings.mk b/bsp/sparkfun-redv/settings.mk new file mode 100644 index 00000000..a8ddd99f --- /dev/null +++ b/bsp/sparkfun-redv/settings.mk @@ -0,0 +1,13 @@ +# Copyright (C) 2020 SiFive Inc +# SPDX-License-Identifier: Apache-2.0 + +RISCV_ARCH = rv32imac +RISCV_ABI = ilp32 +RISCV_CMODEL = medlow +RISCV_SERIES = sifive-3-series + +TARGET_TAGS = board jlink +TARGET_DHRY_ITERS = 20000000 +TARGET_CORE_ITERS = 5000 +TARGET_FREERTOS_WAIT_MS = 1000 +TARGET_INTR_WAIT_CYCLE = 0 \ No newline at end of file