Following are the auxiliary function for creating the different nodes that we append to our FDT.
(fdt: &mut FdtWriter, num_cpus: u32, isa_string: &str)
| 111 | |
| 112 | // Following are the auxiliary function for creating the different nodes that we append to our FDT. |
| 113 | fn create_cpu_nodes(fdt: &mut FdtWriter, num_cpus: u32, isa_string: &str) -> FdtWriterResult<()> { |
| 114 | // See https://elixir.bootlin.com/linux/v6.10/source/Documentation/devicetree/bindings/riscv/cpus.yaml |
| 115 | let cpus = fdt.begin_node("cpus")?; |
| 116 | // As per documentation, on RISC-V 64-bit systems value should be set to 1. |
| 117 | fdt.property_u32("#address-cells", 0x01)?; |
| 118 | fdt.property_u32("#size-cells", 0x0)?; |
| 119 | // TODO: Retrieve CPU frequency from cpu timer regs |
| 120 | let timebase_frequency: u32 = 0x989680; |
| 121 | fdt.property_u32("timebase-frequency", timebase_frequency)?; |
| 122 | |
| 123 | for cpu_index in 0..num_cpus { |
| 124 | let cpu = fdt.begin_node(&format!("cpu@{cpu_index:x}"))?; |
| 125 | fdt.property_string("device_type", "cpu")?; |
| 126 | fdt.property_string("compatible", "riscv")?; |
| 127 | fdt.property_string("mmu-type", "sv48")?; |
| 128 | fdt.property_string("riscv,isa", isa_string)?; |
| 129 | fdt.property_string("status", "okay")?; |
| 130 | fdt.property_u32("reg", cpu_index)?; |
| 131 | fdt.property_u32("phandle", CPU_BASE_PHANDLE + cpu_index)?; |
| 132 | |
| 133 | // interrupt controller node |
| 134 | let intc_node = fdt.begin_node("interrupt-controller")?; |
| 135 | fdt.property_string("compatible", "riscv,cpu-intc")?; |
| 136 | fdt.property_u32("#interrupt-cells", 1u32)?; |
| 137 | fdt.property_null("interrupt-controller")?; |
| 138 | fdt.property_u32("phandle", CPU_INTC_BASE_PHANDLE + cpu_index)?; |
| 139 | fdt.end_node(intc_node)?; |
| 140 | |
| 141 | fdt.end_node(cpu)?; |
| 142 | } |
| 143 | |
| 144 | fdt.end_node(cpus)?; |
| 145 | |
| 146 | Ok(()) |
| 147 | } |
| 148 | |
| 149 | fn create_memory_node(fdt: &mut FdtWriter, guest_mem: &GuestMemoryMmap) -> FdtWriterResult<()> { |
| 150 | // Note: memory regions from "GuestMemory" are sorted and non-zero sized. |