(&self, cpu_id: u32, boot_ip: u64, fdt_start: u64)
| 2747 | /// |
| 2748 | #[cfg(target_arch = "aarch64")] |
| 2749 | fn setup_regs(&self, cpu_id: u32, boot_ip: u64, fdt_start: u64) -> cpu::Result<()> { |
| 2750 | // Get the register index of the PSTATE (Processor State) register. |
| 2751 | let pstate = offset_of!(kvm_regs, regs.pstate); |
| 2752 | self.fd |
| 2753 | .set_one_reg( |
| 2754 | arm64_core_reg_id!(KVM_REG_SIZE_U64, pstate), |
| 2755 | ®s::PSTATE_FAULT_BITS_64.to_le_bytes(), |
| 2756 | ) |
| 2757 | .map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?; |
| 2758 | |
| 2759 | // Other vCPUs are powered off initially awaiting PSCI wakeup. |
| 2760 | if cpu_id == 0 { |
| 2761 | // Setting the PC (Processor Counter) to the current program address (kernel address). |
| 2762 | let pc = offset_of!(kvm_regs, regs.pc); |
| 2763 | self.fd |
| 2764 | .set_one_reg( |
| 2765 | arm64_core_reg_id!(KVM_REG_SIZE_U64, pc), |
| 2766 | &boot_ip.to_le_bytes(), |
| 2767 | ) |
| 2768 | .map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?; |
| 2769 | |
| 2770 | // Last mandatory thing to set -> the address pointing to the FDT (also called DTB). |
| 2771 | // "The device tree blob (dtb) must be placed on an 8-byte boundary and must |
| 2772 | // not exceed 2 megabytes in size." -> https://www.kernel.org/doc/Documentation/arm64/booting.txt. |
| 2773 | // We are choosing to place it the end of DRAM. See `get_fdt_addr`. |
| 2774 | let regs0 = offset_of!(kvm_regs, regs.regs); |
| 2775 | self.fd |
| 2776 | .set_one_reg( |
| 2777 | arm64_core_reg_id!(KVM_REG_SIZE_U64, regs0), |
| 2778 | &fdt_start.to_le_bytes(), |
| 2779 | ) |
| 2780 | .map_err(|e| cpu::HypervisorCpuError::SetAarchCoreRegister(e.into()))?; |
| 2781 | } |
| 2782 | Ok(()) |
| 2783 | } |
| 2784 | |
| 2785 | #[cfg(target_arch = "riscv64")] |
| 2786 | /// |
no outgoing calls