diff --git a/.gitignore b/.gitignore index 1fcf1c950d3e2697d08967be40e7eea7f2384642..60d48244ab195f4966c9b96a22df9591bb8e3674 100644 --- a/.gitignore +++ b/.gitignore @@ -66,4 +66,4 @@ todo *.sh # ignore Image -# zvm_config/qemu_platform/hub/* +zvm_config/qemu_platform/hub/* diff --git a/arch/arm64/core/isr_wrapper.S b/arch/arm64/core/isr_wrapper.S index b2fba94a3f5e73cf041b6c34962a599e9f7a493d..3ab41dcc550ba7dd816ce7ff95fadc215fdecb04 100644 --- a/arch/arm64/core/isr_wrapper.S +++ b/arch/arm64/core/isr_wrapper.S @@ -70,12 +70,6 @@ oob: stp x0, xzr, [sp, #-16]! -#ifdef CONFIG_ZVM - bl z_vm_switch_handle_pre -#endif - - ldp x0, x1, [sp] - /* Retrieve the interrupt service routine */ ldr x1, =_sw_isr_table add x1, x1, x0, lsl #4 /* table is 16-byte wide */ @@ -90,7 +84,7 @@ oob: msr daifset, #(DAIFSET_IRQ_BIT) /* Signal end-of-interrupt */ - ldp x0, xzr, [sp], #16 + ldp x0, xzr, [sp] spurious_continue: #if !defined(CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER) @@ -99,6 +93,16 @@ spurious_continue: bl z_soc_irq_eoi #endif /* !CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */ + ldp x0, xzr, [sp] +#ifdef CONFIG_ZVM + /* switch handle preprocess */ + bl zvm_switch_handle_pre + mov x1, x0 + ldp x0, xzr, [sp], #16 + /* passthrough device may need deactive */ + bl arm_gic_eoi_deactive +#endif + #ifdef CONFIG_TRACING bl sys_trace_isr_exit #endif diff --git a/arch/arm64/core/reset.c b/arch/arm64/core/reset.c index ad779e303ecd68ff9d1199f898abfd0e64ba2b3b..bfa7d750f0b32d6edc42fb419fcd26bcaceb3a96 100644 --- a/arch/arm64/core/reset.c +++ b/arch/arm64/core/reset.c @@ -220,6 +220,11 @@ void z_arm64_el2_vhe_init(void) "99: \n" ); } + /* enable EOI mode, for passthrough device. */ + reg = read_sysreg(ICC_CTLR_EL1); + reg |= 0x02; + write_sysreg(reg, ICC_CTLR_EL1); + #endif /* Get identification information for the PE from midr_el1, diff --git a/arch/arm64/core/virtualization/CMakeLists.txt b/arch/arm64/core/virtualization/CMakeLists.txt index 368611f9d8312a2348357091c438701cb04e21d2..ab2ee04cebd190735d66aabc72cb861164069272 100644 --- a/arch/arm64/core/virtualization/CMakeLists.txt +++ b/arch/arm64/core/virtualization/CMakeLists.txt @@ -7,12 +7,12 @@ zephyr_library() zephyr_library_sources( hyp_entry.S hyp_vector.S - arm.c + cpu.c mm.c vtimer.c trap_handler.c switch.c - sysreg.c + cpu_irq.c ) diff --git a/arch/arm64/core/virtualization/arm.c b/arch/arm64/core/virtualization/cpu.c similarity index 59% rename from arch/arm64/core/virtualization/arm.c rename to arch/arm64/core/virtualization/cpu.c index 8918bd1ac876cc6088fe934c1057189572819ecd..d06dc4f16be9968eae146ce6e77b7ca6e2f3b5cc 100644 --- a/arch/arm64/core/virtualization/arm.c +++ b/arch/arm64/core/virtualization/cpu.c @@ -15,18 +15,155 @@ #include #include #include - #include -#include -#include -#include -#include +#include #include -#include #include LOG_MODULE_DECLARE(ZVM_MODULE_NAME); +/** + * @brief vcpu_sysreg_loads_vhe - Load guest system registers to the physical CPU. + */ +static void vcpu_sysreg_load(struct vcpu *vcpu) +{ + struct zvm_vcpu_context *g_context = &vcpu->arch->ctxt; + + write_csselr_el1(g_context->sys_regs[VCPU_CSSELR_EL1]); + write_vmpidr_el2(g_context->sys_regs[VCPU_MPIDR_EL1]); + write_sctlr_el12(g_context->sys_regs[VCPU_SCTLR_EL1]); + write_tcr_el12(g_context->sys_regs[VCPU_TCR_EL1]); + write_cpacr_el12(g_context->sys_regs[VCPU_CPACR_EL1]); + write_ttbr0_el12(g_context->sys_regs[VCPU_TTBR0_EL1]); + write_ttbr1_el12(g_context->sys_regs[VCPU_TTBR1_EL1]); + write_esr_el12(g_context->sys_regs[VCPU_ESR_EL1]); + write_afsr0_el12(g_context->sys_regs[VCPU_AFSR0_EL1]); + write_afsr1_el12(g_context->sys_regs[VCPU_AFSR1_EL1]); + write_far_el12(g_context->sys_regs[VCPU_FAR_EL1]); + write_mair_el12(g_context->sys_regs[VCPU_MAIR_EL1]); + write_vbar_el12(g_context->sys_regs[VCPU_VBAR_EL1]); + write_contextidr_el12(g_context->sys_regs[VCPU_CONTEXTIDR_EL1]); + write_amair_el12(g_context->sys_regs[VCPU_AMAIR_EL1]); + write_cntkctl_el12(g_context->sys_regs[VCPU_CNTKCTL_EL1]); + write_par_el1(g_context->sys_regs[VCPU_PAR_EL1]); + write_tpidr_el1(g_context->sys_regs[VCPU_TPIDR_EL1]); + write_sp_el1(g_context->sys_regs[VCPU_SP_EL1]); + write_elr_el12(g_context->sys_regs[VCPU_ELR_EL1]); + write_spsr_el12(g_context->sys_regs[VCPU_SPSR_EL1]); + + vcpu->arch->vcpu_sys_register_loaded = true; + write_hstr_el2(BIT(15)); + vcpu->arch->host_mdcr_el2 = read_mdcr_el2(); + write_mdcr_el2(vcpu->arch->guest_mdcr_el2); +} + +/** + * @brief store system register to vcpu struct for keeping the VM state. + */ +static void vcpu_sysreg_save(struct vcpu *vcpu) +{ + struct zvm_vcpu_context *g_context = &vcpu->arch->ctxt; + + g_context->sys_regs[VCPU_MPIDR_EL1] = read_vmpidr_el2(); + g_context->sys_regs[VCPU_CSSELR_EL1] = read_csselr_el1(); + g_context->sys_regs[VCPU_ACTLR_EL1] = read_actlr_el1(); + + g_context->sys_regs[VCPU_SCTLR_EL1] = read_sctlr_el12(); + g_context->sys_regs[VCPU_CPACR_EL1] = read_cpacr_el12(); + g_context->sys_regs[VCPU_TTBR0_EL1] = read_ttbr0_el12(); + g_context->sys_regs[VCPU_TTBR1_EL1] = read_ttbr1_el12(); + g_context->sys_regs[VCPU_ESR_EL1] = read_esr_el12(); + g_context->sys_regs[VCPU_TCR_EL1] = read_tcr_el12(); + g_context->sys_regs[VCPU_AFSR0_EL1] = read_afsr0_el12(); + g_context->sys_regs[VCPU_AFSR1_EL1] = read_afsr1_el12(); + g_context->sys_regs[VCPU_FAR_EL1] = read_far_el12(); + g_context->sys_regs[VCPU_MAIR_EL1] = read_mair_el12(); + g_context->sys_regs[VCPU_VBAR_EL1] = read_vbar_el12(); + g_context->sys_regs[VCPU_CONTEXTIDR_EL1] = read_contextidr_el12(); + g_context->sys_regs[VCPU_AMAIR_EL1] = read_amair_el12(); + g_context->sys_regs[VCPU_CNTKCTL_EL1] = read_cntkctl_el12(); + + g_context->sys_regs[VCPU_PAR_EL1] = read_par_el1(); + g_context->sys_regs[VCPU_TPIDR_EL1] = read_tpidr_el1(); + g_context->regs.esf_handle_regs.elr = read_elr_el12(); + g_context->regs.esf_handle_regs.spsr = read_spsr_el12(); + vcpu->arch->vcpu_sys_register_loaded = false; +} + +/** + * @brief Load guest system register. +*/ +void switch_to_guest_sysreg(struct vcpu *vcpu) +{ + uint32_t reg_val; + struct zvm_vcpu_context *gcontext = &vcpu->arch->ctxt; + struct zvm_vcpu_context *hcontext = &vcpu->arch->host_ctxt; + + /* save host context */ + hcontext->running_vcpu = vcpu; + hcontext->sys_regs[VCPU_SPSR_EL1] = read_spsr_el1(); + hcontext->sys_regs[VCPU_MDSCR_EL1] = read_mdscr_el1(); + + /* load stage-2 pgd for vm */ + write_vtcr_el2(vcpu->vm->arch->vtcr_el2); + write_vttbr_el2(vcpu->vm->arch->vttbr); + isb(); + + /* enable hyperviosr trap */ + write_hcr_el2(vcpu->arch->hcr_el2); + reg_val = read_cpacr_el1(); + reg_val |= CPACR_EL1_TTA; + reg_val &= ~CPACR_EL1_ZEN; + reg_val |= CPTR_EL2_TAM; + reg_val |= CPACR_EL1_FPEN_NOTRAP; + write_cpacr_el1(reg_val); + write_vbar_el2((uint64_t)_hyp_vector_table); + + hcontext->sys_regs[VCPU_TPIDRRO_EL0] = read_tpidrro_el0(); + write_tpidrro_el0(gcontext->sys_regs[VCPU_TPIDRRO_EL0]); + + write_elr_el2(gcontext->regs.pc); + write_spsr_el2(gcontext->regs.pstate); + + reg_val = ((struct gicv3_vcpuif_ctxt *)vcpu->arch->virq_data)->icc_ctlr_el1; + reg_val &= ~(0x02); + write_sysreg(reg_val, ICC_CTLR_EL1); + +} + +void switch_to_host_sysreg(struct vcpu *vcpu) +{ + uint32_t reg_val; + struct zvm_vcpu_context *gcontext = &vcpu->arch->ctxt; + struct zvm_vcpu_context *hcontext = &vcpu->arch->host_ctxt; + + gcontext->sys_regs[VCPU_TPIDRRO_EL0] = read_tpidrro_el0(); + write_tpidrro_el0(hcontext->sys_regs[VCPU_TPIDRRO_EL0]); + + gcontext->regs.pc = read_elr_el2(); + gcontext->regs.pstate = read_spsr_el2(); + + reg_val = ((struct gicv3_vcpuif_ctxt *)vcpu->arch->virq_data)->icc_ctlr_el1; + reg_val |= (0x02); + write_sysreg(reg_val, ICC_CTLR_EL1); + + /* disable hyperviosr trap */ + if (vcpu->arch->hcr_el2 & HCR_VSE_BIT) { + vcpu->arch->hcr_el2 = read_hcr_el2(); + } + write_hcr_el2(HCR_VHE_FLAGS); + write_vbar_el2((uint64_t)_vector_table); + + /* save vm's stage-2 pgd */ + vcpu->vm->arch->vtcr_el2 = read_vtcr_el2(); + vcpu->vm->arch->vttbr = read_vttbr_el2(); + isb(); + + /* load host context */ + write_mdscr_el1(hcontext->sys_regs[VCPU_MDSCR_EL1]); + write_spsr_el1(hcontext->sys_regs[VCPU_SPSR_EL1]); +} + static void hyp_memory_map(void) { /*TODO: support split mode.*/ @@ -211,13 +348,8 @@ void arch_vcpu_context_load(struct vcpu *vcpu) vcpu_vtimer_load(vcpu); vcpu_vgic_load(vcpu); -#ifdef CONFIG_SCHED_CPU_MASK_PIN_ONLY vcpu->arch->hcr_el2 &= ~HCR_TWE_BIT; vcpu->arch->hcr_el2 &= ~HCR_TWI_BIT; -#else - vcpu->arch->hcr_el2 |= HCR_TWE_BIT; - vcpu->arch->hcr_el2 |= HCR_TWI_BIT; -#endif } int arch_vcpu_init(struct vcpu *vcpu) diff --git a/arch/arm64/core/virtualization/cpu_irq.c b/arch/arm64/core/virtualization/cpu_irq.c new file mode 100644 index 0000000000000000000000000000000000000000..508269334edcf0972ac9f4e27077bbc87b0bdfae --- /dev/null +++ b/arch/arm64/core/virtualization/cpu_irq.c @@ -0,0 +1,48 @@ +/* + * Copyright 2022-2023 HNU-ESNL + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include + +LOG_MODULE_DECLARE(ZVM_MODULE_NAME); + +#ifdef CONFIG_GIC_V3 +#define VM_GIC_NAME vm_gic_v3 +#elif CONFIG_GIC_V2 +#define VM_GIC_NAME vm_gic_v2 +#endif + +bool arch_irq_ispending(struct vcpu *vcpu) +{ + uint32_t *mem_addr_base = NULL; + uint32_t pend_addrend; + struct vm *vm; + struct virt_dev *vdev; + struct _dnode *d_node, *ds_node; + + vm = vcpu->vm; + SYS_DLIST_FOR_EACH_NODE_SAFE(&vm->vdev_list, d_node, ds_node){ + vdev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); + if (!strcmp(vdev->name, TOSTRING(VM_GIC_NAME))) { + mem_addr_base = arm_gic_get_distbase(vdev); + break; + } + } + + if(mem_addr_base == NULL){ + ZVM_LOG_ERR("Can not find gic controller! \n"); + return false; + } + mem_addr_base += VGICD_ISPENDRn; + pend_addrend = (uint64_t)mem_addr_base+(VGICD_ICPENDRn-VGICD_ISPENDRn); + for(; (uint64_t)mem_addr_base < pend_addrend; mem_addr_base++){ + if(vgic_irq_test_bit(vcpu, 0, mem_addr_base, 32, 0)){ + return true; + } + } + return false; +} \ No newline at end of file diff --git a/arch/arm64/core/virtualization/switch.c b/arch/arm64/core/virtualization/switch.c index c98df13753fb3ea5fb966722e4d87d37188d7de7..f6d3284fbfc6ad2121403b828665f00a54eb0c69 100644 --- a/arch/arm64/core/virtualization/switch.c +++ b/arch/arm64/core/virtualization/switch.c @@ -9,15 +9,10 @@ #include #include #include - -#include -#include +#include #include -#include -#include -#include #include - +#include #include #include #include @@ -169,22 +164,22 @@ int arch_vcpu_run(struct vcpu *vcpu) return ret; } -void z_vm_switch_handle_pre(uint32_t irq) +bool zvm_switch_handle_pre(uint32_t irq) { - bool *bit_addr; struct k_thread *thread; struct vcpu *vcpu; if( (vcpu = _current_vcpu) == NULL){ - return; + return false; } - bit_addr = vcpu->vm->vm_irq_block.irq_bitmap; /* If it is a vcpu thread, judge whether the signal is send to it */ - if(!bit_addr[irq]){ - return; + if(!vcpu->vm->vm_irq_block.irq_bitmap[irq]){ + return false; } thread = vcpu->work->vcpu_thread; thread->base.thread_state |= _THREAD_VCPU_NO_SWITCH; + + return true; } diff --git a/arch/arm64/core/virtualization/sysreg.c b/arch/arm64/core/virtualization/sysreg.c deleted file mode 100644 index 30b7078ca60f9f8aaf8f6c3bce953893ba4c75ab..0000000000000000000000000000000000000000 --- a/arch/arm64/core/virtualization/sysreg.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2021-2022 HNU-ESNL - * Copyright 2023 openEuler SIG-Zephyr - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -void vcpu_sysreg_load(struct vcpu *vcpu) -{ - struct zvm_vcpu_context *g_context = &vcpu->arch->ctxt; - - write_csselr_el1(g_context->sys_regs[VCPU_CSSELR_EL1]); - write_vmpidr_el2(g_context->sys_regs[VCPU_MPIDR_EL1]); - write_sctlr_el12(g_context->sys_regs[VCPU_SCTLR_EL1]); - write_tcr_el12(g_context->sys_regs[VCPU_TCR_EL1]); - write_cpacr_el12(g_context->sys_regs[VCPU_CPACR_EL1]); - write_ttbr0_el12(g_context->sys_regs[VCPU_TTBR0_EL1]); - write_ttbr1_el12(g_context->sys_regs[VCPU_TTBR1_EL1]); - write_esr_el12(g_context->sys_regs[VCPU_ESR_EL1]); - write_afsr0_el12(g_context->sys_regs[VCPU_AFSR0_EL1]); - write_afsr1_el12(g_context->sys_regs[VCPU_AFSR1_EL1]); - write_far_el12(g_context->sys_regs[VCPU_FAR_EL1]); - write_mair_el12(g_context->sys_regs[VCPU_MAIR_EL1]); - write_vbar_el12(g_context->sys_regs[VCPU_VBAR_EL1]); - write_contextidr_el12(g_context->sys_regs[VCPU_CONTEXTIDR_EL1]); - write_amair_el12(g_context->sys_regs[VCPU_AMAIR_EL1]); - write_cntkctl_el12(g_context->sys_regs[VCPU_CNTKCTL_EL1]); - write_par_el1(g_context->sys_regs[VCPU_PAR_EL1]); - write_tpidr_el1(g_context->sys_regs[VCPU_TPIDR_EL1]); - write_sp_el1(g_context->sys_regs[VCPU_SP_EL1]); - write_elr_el12(g_context->sys_regs[VCPU_ELR_EL1]); - write_spsr_el12(g_context->sys_regs[VCPU_SPSR_EL1]); - - vcpu->arch->vcpu_sys_register_loaded = true; - write_hstr_el2(BIT(15)); - vcpu->arch->host_mdcr_el2 = read_mdcr_el2(); - write_mdcr_el2(vcpu->arch->guest_mdcr_el2); -} - -void vcpu_sysreg_save(struct vcpu *vcpu) -{ - struct zvm_vcpu_context *g_context = &vcpu->arch->ctxt; - - g_context->sys_regs[VCPU_MPIDR_EL1] = read_vmpidr_el2(); - g_context->sys_regs[VCPU_CSSELR_EL1] = read_csselr_el1(); - g_context->sys_regs[VCPU_ACTLR_EL1] = read_actlr_el1(); - - g_context->sys_regs[VCPU_SCTLR_EL1] = read_sctlr_el12(); - g_context->sys_regs[VCPU_CPACR_EL1] = read_cpacr_el12(); - g_context->sys_regs[VCPU_TTBR0_EL1] = read_ttbr0_el12(); - g_context->sys_regs[VCPU_TTBR1_EL1] = read_ttbr1_el12(); - g_context->sys_regs[VCPU_ESR_EL1] = read_esr_el12(); - g_context->sys_regs[VCPU_TCR_EL1] = read_tcr_el12(); - g_context->sys_regs[VCPU_AFSR0_EL1] = read_afsr0_el12(); - g_context->sys_regs[VCPU_AFSR1_EL1] = read_afsr1_el12(); - g_context->sys_regs[VCPU_FAR_EL1] = read_far_el12(); - g_context->sys_regs[VCPU_MAIR_EL1] = read_mair_el12(); - g_context->sys_regs[VCPU_VBAR_EL1] = read_vbar_el12(); - g_context->sys_regs[VCPU_CONTEXTIDR_EL1] = read_contextidr_el12(); - g_context->sys_regs[VCPU_AMAIR_EL1] = read_amair_el12(); - g_context->sys_regs[VCPU_CNTKCTL_EL1] = read_cntkctl_el12(); - - g_context->sys_regs[VCPU_PAR_EL1] = read_par_el1(); - g_context->sys_regs[VCPU_TPIDR_EL1] = read_tpidr_el1(); - g_context->regs.esf_handle_regs.elr = read_elr_el12(); - g_context->regs.esf_handle_regs.spsr = read_spsr_el12(); - vcpu->arch->vcpu_sys_register_loaded = false; -} - - -void switch_to_guest_sysreg(struct vcpu *vcpu) -{ - uint32_t reg_val; - struct zvm_vcpu_context *gcontext = &vcpu->arch->ctxt; - struct zvm_vcpu_context *hcontext = &vcpu->arch->host_ctxt; - - /* save host context */ - hcontext->running_vcpu = vcpu; - hcontext->sys_regs[VCPU_SPSR_EL1] = read_spsr_el1(); - hcontext->sys_regs[VCPU_MDSCR_EL1] = read_mdscr_el1(); - - /* load stage-2 pgd for vm */ - write_vtcr_el2(vcpu->vm->arch->vtcr_el2); - write_vttbr_el2(vcpu->vm->arch->vttbr); - isb(); - - /* enable hyperviosr trap */ - write_hcr_el2(vcpu->arch->hcr_el2); - reg_val = read_cpacr_el1(); - reg_val |= CPACR_EL1_TTA; - reg_val &= ~CPACR_EL1_ZEN; - reg_val |= CPTR_EL2_TAM; - reg_val |= CPACR_EL1_FPEN_NOTRAP; - write_cpacr_el1(reg_val); - write_vbar_el2((uint64_t)_hyp_vector_table); - - hcontext->sys_regs[VCPU_TPIDRRO_EL0] = read_tpidrro_el0(); - write_tpidrro_el0(gcontext->sys_regs[VCPU_TPIDRRO_EL0]); - - write_elr_el2(gcontext->regs.pc); - write_spsr_el2(gcontext->regs.pstate); - - reg_val = ((struct gicv3_vcpuif_ctxt *)vcpu->arch->virq_data)->icc_ctlr_el1; - reg_val &= ~(0x02); - write_sysreg(reg_val, ICC_CTLR_EL1); - -} - -void switch_to_host_sysreg(struct vcpu *vcpu) -{ - uint32_t reg_val; - struct zvm_vcpu_context *gcontext = &vcpu->arch->ctxt; - struct zvm_vcpu_context *hcontext = &vcpu->arch->host_ctxt; - - gcontext->sys_regs[VCPU_TPIDRRO_EL0] = read_tpidrro_el0(); - write_tpidrro_el0(hcontext->sys_regs[VCPU_TPIDRRO_EL0]); - - gcontext->regs.pc = read_elr_el2(); - gcontext->regs.pstate = read_spsr_el2(); - - reg_val = ((struct gicv3_vcpuif_ctxt *)vcpu->arch->virq_data)->icc_ctlr_el1; - reg_val |= (0x02); - write_sysreg(reg_val, ICC_CTLR_EL1); - - /* disable hyperviosr trap */ - if (vcpu->arch->hcr_el2 & HCR_VSE_BIT) { - vcpu->arch->hcr_el2 = read_hcr_el2(); - } - write_hcr_el2(HCR_VHE_FLAGS); - write_vbar_el2((uint64_t)_vector_table); - - /* save vm's stage-2 pgd */ - vcpu->vm->arch->vtcr_el2 = read_vtcr_el2(); - vcpu->vm->arch->vttbr = read_vttbr_el2(); - isb(); - - /* load host context */ - write_mdscr_el1(hcontext->sys_regs[VCPU_MDSCR_EL1]); - write_spsr_el1(hcontext->sys_regs[VCPU_SPSR_EL1]); -} diff --git a/arch/arm64/core/virtualization/trap_handler.c b/arch/arm64/core/virtualization/trap_handler.c index 825c19235a1917416410506cbd7db17d9276321f..6f3ca20149fabca0ed6ad9cca9f01b5a991b7698 100644 --- a/arch/arm64/core/virtualization/trap_handler.c +++ b/arch/arm64/core/virtualization/trap_handler.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -39,6 +38,7 @@ static int handle_ftrans_desc(int iss_dfsc, uint64_t pa_addr, { int ret = 0; struct vcpu *vcpu = _current_vcpu; + uint64_t esr_elx = vcpu->arch->fault.esr_el2; #ifdef CONFIG_VM_DYNAMIC_MEMORY /* TODO: Add dynamic memory allocate. */ @@ -58,7 +58,7 @@ static int handle_ftrans_desc(int iss_dfsc, uint64_t pa_addr, */ }else{ vm_mem_domain_partitions_add(vcpu->vm->vmem_domain); - vcpu->arch->ctxt.regs.pc -= AARCH64_INST_ADJUST; + vcpu->arch->ctxt.regs.pc -= (GET_ESR_IL(esr_elx)) ? 4 : 2; } #endif return ret; @@ -122,16 +122,28 @@ static int cpu_unknwn_sync(arch_commom_regs_t *arch_ctxt, uint64_t esr_elx) static int cpu_wfi_wfe_sync(arch_commom_regs_t *arch_ctxt, uint64_t esr_elx) { - int ret; + uint32_t condition, esr_iss; struct vcpu *vcpu = _current_vcpu; - /* judge whether the vcpu has pending or active irq */ - ret = vcpu_irq_exit(vcpu); - if(ret){ - return 0; /* There are some irq need to process */ + esr_iss = GET_ESR_ISS(esr_elx); + if(esr_iss & BIT(ESR_ISS_CV_SHIFT)){ + condition = GET_ESR_ISS_COND(esr_elx); + if((condition & 0x1) && (condition != 0xf)){ + return -ESRCH; + } + }else{ + /* TODO: support aarch32 VM.*/ + return -ESRCH; + } + /* WFE */ + if(esr_iss & 0x01){ + if(vcpu->vcpu_state == _VCPU_STATE_RUNNING){ + vm_vcpu_ready(vcpu); + } + }else{ /* WFI */ + vcpu_wait_for_irq(vcpu); } - /* TODO: support wfi and wfe for system.*/ return 0; } @@ -190,15 +202,13 @@ static int cpu_system_msr_mrs_sync(arch_commom_regs_t *arch_ctxt, uint64_t esr_e reg_name = this_esr & ESR_SYSINS_REGS_MASK; switch (reg_name) { /* supporte sgi related register here */ + case ESR_SYSINSREG_SGI0R_EL1: case ESR_SYSINSREG_SGI1R_EL1: case ESR_SYSINSREG_ASGI1R_EL1: - case ESR_SYSINSREG_SGI0R_EL1: if (!esr_sysreg->dire) { vgicv3_raise_sgi(vcpu, *reg_value); } break; - /* supporte timer related register here, - Other registe is treated as invailed. Add other reg later */ case ESR_SYSINSREG_CNTPCT_EL0: /* The process for VM's timer, emulate timer register access */ case ESR_SYSINSREG_CNTP_TVAL_EL0: @@ -300,7 +310,6 @@ static int cpu_misaligned_sp_sync(arch_commom_regs_t *arch_ctxt, uint64_t esr_el int arch_vm_trap_sync(struct vcpu *vcpu) { int err = 0; - uint32_t fix_esr_elx; uint64_t esr_elx; arch_commom_regs_t *arch_ctxt; @@ -374,8 +383,7 @@ int arch_vm_trap_sync(struct vcpu *vcpu) default: goto handler_failed; } - fix_esr_elx = AARCH64_INST_ADJUST; - vcpu->arch->ctxt.regs.pc += fix_esr_elx; + vcpu->arch->ctxt.regs.pc += (GET_ESR_IL(esr_elx)) ? 4 : 2; return err; handler_failed: diff --git a/arch/arm64/core/virtualization/vtimer.c b/arch/arm64/core/virtualization/vtimer.c index ed11689d38c5b7583aa2389c5e1c487767329b8a..0bae496e655646e67ab6dc534b1280ee0d86ca90 100644 --- a/arch/arm64/core/virtualization/vtimer.c +++ b/arch/arm64/core/virtualization/vtimer.c @@ -9,7 +9,6 @@ #include #include #include - #include #include #include @@ -247,9 +246,10 @@ void simulate_timer_cntp_ctl(struct vcpu *vcpu, int read, uint64_t *value) */ int arch_vcpu_timer_init(struct vcpu *vcpu) { - bool *bit_addr; + bool *bit_map; struct virt_timer_context *ctxt; struct vcpu_arch *arch = vcpu->arch; + struct virt_irq_desc *irq_desc; arch->vtimer_context = (struct virt_timer_context *)k_malloc(sizeof(struct virt_timer_context)); if(!arch->vtimer_context) { @@ -281,9 +281,14 @@ int arch_vcpu_timer_init(struct vcpu *vcpu) init_virt_timer_timeout(&ctxt->vtimer_timeout, virt_vtimer_expiry); init_virt_timer_timeout(&ctxt->ptimer_timeout, virt_ptimer_expiry); - bit_addr = vcpu->vm->vm_irq_block.irq_bitmap; - bit_addr[ctxt->virt_virq] = true; - bit_addr[ctxt->virt_pirq] = true; + /*El1 physical and virtual timer. */ + bit_map = vcpu->vm->vm_irq_block.irq_bitmap; + bit_map[ctxt->virt_virq] = true; + bit_map[ctxt->virt_pirq] = true; + + /*Make VM directly access virt timer register.*/ + irq_desc = vgic_get_virt_irq_desc(vcpu, ctxt->virt_virq); + irq_desc->virq_flags |= VIRQ_HW_FLAG; return 0; } diff --git a/auto_zvm.sh b/auto_zvm.sh index 89098d70fcc7356118e1d7942afa802f425fd0c7..3c12b5b71b3623ea676b4e4af6f750aa7a0b382f 100755 --- a/auto_zvm.sh +++ b/auto_zvm.sh @@ -44,7 +44,7 @@ elif [ "$OPS" = "$ops_debug" ]; then -net none -pidfile qemu.pid -chardev stdio,id=con,mux=on \ -serial chardev:con -mon chardev=con,mode=readline -serial pty -serial pty -smp cpus=4 \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/zephyr.bin,addr=0xf2000000,force-raw=on \ - -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image_oee,addr=0xf3000000,force-raw=on \ + -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/Image,addr=0xf3000000,force-raw=on \ -device loader,file=$(pwd)/zvm_config/qemu_platform/hub/linux-qemu-virtio.dtb,addr=0xf2a00000 \ -kernel $(pwd)/build/zephyr/zvm_host.elf @@ -72,5 +72,4 @@ elif [ "$OPS" = "$ops_debug" ]; then else echo "Error arguments for this auto.sh! \n Please input command like: ./z_auto.sh build qemu. " fi - -fi \ No newline at end of file +fi diff --git a/boards/arm64/fvp_cortex_a55x4_a75x2_smp/fvp_cortex_a55x4_a75x2_smp_defconfig b/boards/arm64/fvp_cortex_a55x4_a75x2_smp/fvp_cortex_a55x4_a75x2_smp_defconfig index b93b8616851f3b36dd6c099e11c371c9291f8712..145123d435ea1a834048dc980ee13d0f9f9c899b 100644 --- a/boards/arm64/fvp_cortex_a55x4_a75x2_smp/fvp_cortex_a55x4_a75x2_smp_defconfig +++ b/boards/arm64/fvp_cortex_a55x4_a75x2_smp/fvp_cortex_a55x4_a75x2_smp_defconfig @@ -36,6 +36,7 @@ CONFIG_ZVM_MAX_XLAT_TABLES=128 #enable CONFIG_SMP=y +CONFIG_MP_NUM_CPUS=4 CONFIG_CACHE_MANAGEMENT=y CONFIG_PM_CPU_OPS=y diff --git a/boards/arm64/roc_rk3568_pc/Kconfig.board b/boards/arm64/roc_rk3568_pc/Kconfig.board index 97844de31fd4475e2be6923cbebd2e540a1a006d..ddc9cf7707d390b27da2b1e2566298cc3f98cd0b 100644 --- a/boards/arm64/roc_rk3568_pc/Kconfig.board +++ b/boards/arm64/roc_rk3568_pc/Kconfig.board @@ -6,3 +6,12 @@ config BOARD_ROC_RK3568_PC bool "Rockchip ROC-RK3568-PC" depends on SOC_SERIES_RK3568 select ARM64 + +#ifdef BOARD_ROC_RK3568_PC + +config RK3568_CLOCK_CONTROL_INIT_PRIORITY + int "Clock control init priority" + help + Clock control driver device initialization priority for rk3568. + +#endif \ No newline at end of file diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig index 6d1d36ca6aa8f2fd46c185310c2eee698d5bae84..b97af81f8bdfd18d6a26bb23b3b1911f1626d5d7 100644 --- a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_defconfig @@ -6,6 +6,7 @@ CONFIG_SOC_SERIES_RK3568=y CONFIG_SOC_RK3568=y CONFIG_BOARD_ROC_RK3568_PC=y +CONFIG_RK3568_CLOCK_CONTROL_INIT_PRIORITY=40 # Serial Drivers CONFIG_SERIAL=y diff --git a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig index 0f99d24cf0f7220f092fbc84b59fc49ac0c4c27d..abe9f8f0b2d5f148cd439ac3fa0bc902df37fbf6 100644 --- a/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig +++ b/boards/arm64/roc_rk3568_pc/roc_rk3568_pc_smp_defconfig @@ -4,6 +4,7 @@ CONFIG_SOC_SERIES_RK3568=y CONFIG_SOC_RK3568=y CONFIG_BOARD_ROC_RK3568_PC=y +CONFIG_RK3568_CLOCK_CONTROL_INIT_PRIORITY=40 # SMP support CONFIG_SMP=y diff --git a/drivers/clock_control/clock_control_rk3568_cru.c b/drivers/clock_control/clock_control_rk3568_cru.c index 3a6e1b322e59a6c280c95867bfbd54489f420acd..a9e54b8fdcc67e055e1f16c506e399154995bd71 100644 --- a/drivers/clock_control/clock_control_rk3568_cru.c +++ b/drivers/clock_control/clock_control_rk3568_cru.c @@ -4,7 +4,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -//need edit not for vm system first. #include #include @@ -13,9 +12,17 @@ #include #include +#define DEV_CFG(dev) \ + ((const struct rk3568_clk_syscon * const)(dev)->config) + +/** + * @breif: init clock syscon(cru) for rk3568 soc. +*/ static int rk3568_cru_clk_init(const struct device *dev) { - dev->state->init_res = VM_DEVICE_INIT_RES; + int ret; + ret = z_info_sys_clkcon(dev->name, DEV_CFG(dev)->reg_base, DEV_CFG(dev)->reg_size, NULL); + return 0; } @@ -31,30 +38,20 @@ static int rk3568_cru_clk_off(const struct device *dev, return 0; } -static const struct clock_control_driver_api rk3568_cru_driver_api = { +static const struct clock_control_driver_api rk3568_cru_api = { .on = rk3568_cru_clk_on, .off = rk3568_cru_clk_off, }; -static int vm_cru_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) -{ - return 0; -} - -static const struct virt_device_api virt_cru_api = { - .init_fn = vm_cru_init, - .device_driver_api = &rk3568_cru_driver_api, -}; - -static struct virt_device_config virt_cru_cfg = { +static struct rk3568_clk_syscon rk3568_cru_cfg = { .reg_base = DT_REG_ADDR(DT_NODELABEL(cru)), .reg_size = DT_REG_SIZE(DT_NODELABEL(cru)), - .hirq_num = VM_DEVICE_INVALID_VIRQ, + .priv_data = NULL, }; DEVICE_DT_DEFINE(DT_NODELABEL(cru), &rk3568_cru_clk_init, NULL, - NULL, &virt_cru_cfg, - PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, - &virt_cru_api); + NULL, &rk3568_cru_cfg, + PRE_KERNEL_1, CONFIG_RK3568_CLOCK_CONTROL_INIT_PRIORITY, + &rk3568_cru_api); diff --git a/drivers/clock_control/clock_control_rk3568_pmucru.c b/drivers/clock_control/clock_control_rk3568_pmucru.c index 68c5e9d8bf2558df1497172ae4fc08d6230ff22d..3648f0529402dee496d641100220614a0f7e0342 100644 --- a/drivers/clock_control/clock_control_rk3568_pmucru.c +++ b/drivers/clock_control/clock_control_rk3568_pmucru.c @@ -4,20 +4,26 @@ * * SPDX-License-Identifier: Apache-2.0 */ -//need edit not for vm system first. #include #include #include #include #include - #include +#define DEV_CFG(dev) \ + ((const struct rk3568_clk_syscon * const)(dev)->config) + +/** + * @breif: init clock syscon(pmucru) for rk3568 soc. +*/ static int rk3568_pmucru_clk_init(const struct device *dev) { - dev->state->init_res = VM_DEVICE_INIT_RES; - return 0; + int ret; + ret = z_info_sys_clkcon(dev->name, DEV_CFG(dev)->reg_base, DEV_CFG(dev)->reg_size, NULL); + + return ret; } static int rk3568_pmucru_clk_on(const struct device *dev, @@ -32,30 +38,20 @@ static int rk3568_pmucru_clk_off(const struct device *dev, return 0; } -static const struct clock_control_driver_api rk3568_pmucru_driver_api = { +static const struct clock_control_driver_api rk3568_pmucru_api = { .on = rk3568_pmucru_clk_on, .off = rk3568_pmucru_clk_off, }; -static int vm_pmucru_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) -{ - return 0; -} - -static const struct virt_device_api virt_pmucru_api = { - .init_fn = vm_pmucru_init, - .device_driver_api = &rk3568_pmucru_driver_api, -}; - -static struct virt_device_config virt_pmucru_cfg = { +static struct rk3568_clk_syscon rk3568_pmucru_cfg = { .reg_base = DT_REG_ADDR(DT_NODELABEL(pmucru)), .reg_size = DT_REG_SIZE(DT_NODELABEL(pmucru)), - .hirq_num = VM_DEVICE_INVALID_VIRQ, + .priv_data = NULL, }; DEVICE_DT_DEFINE(DT_NODELABEL(pmucru), &rk3568_pmucru_clk_init, NULL, - NULL, &virt_pmucru_cfg, - PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, - &virt_pmucru_api); + NULL, &rk3568_pmucru_cfg, + PRE_KERNEL_1, CONFIG_RK3568_CLOCK_CONTROL_INIT_PRIORITY, + &rk3568_pmucru_api); diff --git a/drivers/interrupt_controller/intc_gicv3.c b/drivers/interrupt_controller/intc_gicv3.c index 05b44d061a02fe11bfa86062354114acc7e8c80f..0e81766e4604dc7a6ac41f9c82509e2b2e2b5cc8 100644 --- a/drivers/interrupt_controller/intc_gicv3.c +++ b/drivers/interrupt_controller/intc_gicv3.c @@ -257,6 +257,20 @@ void arm_gic_eoi(unsigned int intid) } +void arm_gic_eoi_deactive(unsigned int intid, bool no_deactive) +{ + /** + * For VM passthrough device's intid, write dir to this intid + * may be cause unpredictable action. And When ICC_CTLR_EL1.eoimode + * is set to '1', host os's intid must use deactive operation. + */ + __DSB(); + if(!no_deactive){ + write_sysreg(intid, ICC_DIR_EL1); + } + isb(); +} + void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff, uint16_t target_list) { diff --git a/drivers/syscon/rk3568_syscon.c b/drivers/syscon/rk3568_syscon.c index c58aace728cf8fb3f2ff68fe7e84257c42a246d5..8dcbd8e2d86f6aae462ed19c4a774fb17f1fd95b 100644 --- a/drivers/syscon/rk3568_syscon.c +++ b/drivers/syscon/rk3568_syscon.c @@ -15,7 +15,7 @@ #define DT_DRV_COMPAT syscon void rk3568_syscon_generic_init(const struct device *dev) -{ +{ /*Set flag as the idle device which can bind to vm */ dev->state->init_res = VM_DEVICE_INIT_RES; } diff --git a/include/arch/arm64/cpu.h b/include/arch/arm64/cpu.h index 1057958ce38546cd43d21e76e435fcaa75abbae8..6b2a5b7a50fb052520b730c8186f7a9e5d14930c 100644 --- a/include/arch/arm64/cpu.h +++ b/include/arch/arm64/cpu.h @@ -36,6 +36,10 @@ /* Additional SPSR bits */ #define SPSR_IL_BIT BIT(20) +#define SPSR_VF_BIT BIT(28) +#define SPSR_CF_BIT BIT(29) +#define SPSR_ZF_BIT BIT(30) +#define SPSR_NF_BIT BIT(31) #define SCTLR_EL3_RES1 (BIT(29) | BIT(28) | BIT(23) | \ @@ -103,15 +107,20 @@ #define GET_EL(_mode) (((_mode) >> MODE_EL_SHIFT) & MODE_EL_MASK) #define ESR_EC_SHIFT (26) -#define ESR_EC_MASK BIT_MASK(6) +#define ESR_EC_MASK BIT_MASK(6) #define ESR_ISS_SHIFT (0) #define ESR_ISS_MASK BIT_MASK(25) +#define ESR_ISS_COND_SHIFT (15) +#define ESR_ISS_COND_MASK BIT_MASK(4) +#define ESR_ISS_CV_SHIFT (24) +#define ESR_ISS_CV_MASK BIT_MASK(1) #define ESR_IL_SHIFT (25) -#define ESR_IL_MASK BIT_MASK(1) +#define ESR_IL_MASK BIT_MASK(1) #define GET_ESR_EC(esr) (((esr) >> ESR_EC_SHIFT) & ESR_EC_MASK) #define GET_ESR_IL(esr) (((esr) >> ESR_IL_SHIFT) & ESR_IL_MASK) #define GET_ESR_ISS(esr) (((esr) >> ESR_ISS_SHIFT) & ESR_ISS_MASK) +#define GET_ESR_ISS_COND(esr) (((esr) >> ESR_ISS_COND_SHIFT) & ESR_ISS_COND_MASK) #define CNTV_CTL_ENABLE_BIT BIT(0) #define CNTV_CTL_IMASK_BIT BIT(1) diff --git a/include/drivers/interrupt_controller/gic.h b/include/drivers/interrupt_controller/gic.h index 51c7dd77672ef4bb7489da5a0c278c4f6f37c17d..522d19fca89ed4c0328ff29b4b5104b7e648c943 100644 --- a/include/drivers/interrupt_controller/gic.h +++ b/include/drivers/interrupt_controller/gic.h @@ -325,6 +325,14 @@ unsigned int arm_gic_get_active(void); */ void arm_gic_eoi(unsigned int irq); +/** + * @brief Deactive interrupt after eoi + * + * @param intid interrupt ID + * @param no_deactive no need deactive flag + */ +void arm_gic_eoi_deactive(unsigned int intid, bool no_deactive); + #ifdef CONFIG_SMP /** * @brief Initialize GIC of secondary cores diff --git a/include/dt-bindings/clock/rk3568_clock.h b/include/dt-bindings/clock/rk3568_clock.h index aecfdd4ce0841b276f03515dbdc446703ca92f00..155db4d9fd66416276ad61af78ad55f7d4da840d 100644 --- a/include/dt-bindings/clock/rk3568_clock.h +++ b/include/dt-bindings/clock/rk3568_clock.h @@ -1,932 +1,145 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: BSD-3-Clause */ /* - * Copyright (c) 2020 Rockchip Electronics Co. Ltd. - * Author: Elaine Zhang + * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd. */ -#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H -#define _DT_BINDINGS_CLK_ROCKCHIP_RK3568_H - -/* pmucru-clocks indices */ - -/* pmucru plls */ -#define PLL_PPLL 1 -#define PLL_HPLL 2 - -/* pmucru clocks */ -#define XIN_OSC0_DIV 4 -#define CLK_RTC_32K 5 -#define CLK_PMU 6 -#define CLK_I2C0 7 -#define CLK_RTC32K_FRAC 8 -#define CLK_UART0_DIV 9 -#define CLK_UART0_FRAC 10 -#define SCLK_UART0 11 -#define DBCLK_GPIO0 12 -#define CLK_PWM0 13 -#define CLK_CAPTURE_PWM0_NDFT 14 -#define CLK_PMUPVTM 15 -#define CLK_CORE_PMUPVTM 16 -#define CLK_REF24M 17 -#define XIN_OSC0_USBPHY0_G 18 -#define CLK_USBPHY0_REF 19 -#define XIN_OSC0_USBPHY1_G 20 -#define CLK_USBPHY1_REF 21 -#define XIN_OSC0_MIPIDSIPHY0_G 22 -#define CLK_MIPIDSIPHY0_REF 23 -#define XIN_OSC0_MIPIDSIPHY1_G 24 -#define CLK_MIPIDSIPHY1_REF 25 -#define CLK_WIFI_DIV 26 -#define CLK_WIFI_OSC0 27 -#define CLK_WIFI 28 -#define CLK_PCIEPHY0_DIV 29 -#define CLK_PCIEPHY0_OSC0 30 -#define CLK_PCIEPHY0_REF 31 -#define CLK_PCIEPHY1_DIV 32 -#define CLK_PCIEPHY1_OSC0 33 -#define CLK_PCIEPHY1_REF 34 -#define CLK_PCIEPHY2_DIV 35 -#define CLK_PCIEPHY2_OSC0 36 -#define CLK_PCIEPHY2_REF 37 -#define CLK_PCIE30PHY_REF_M 38 -#define CLK_PCIE30PHY_REF_N 39 -#define CLK_HDMI_REF 40 -#define XIN_OSC0_EDPPHY_G 41 -#define PCLK_PDPMU 42 -#define PCLK_PMU 43 -#define PCLK_UART0 44 -#define PCLK_I2C0 45 -#define PCLK_GPIO0 46 -#define PCLK_PMUPVTM 47 -#define PCLK_PWM0 48 -#define CLK_PDPMU 49 -#define SCLK_32K_IOE 50 - -#define CLKPMU_NR_CLKS (SCLK_32K_IOE + 1) - -/* cru-clocks indices */ - -/* cru plls */ -#define PLL_APLL 1 -#define PLL_DPLL 2 -#define PLL_CPLL 3 -#define PLL_GPLL 4 -#define PLL_VPLL 5 -#define PLL_NPLL 6 - -/* cru clocks */ -#define CPLL_333M 9 -#define ARMCLK 10 -#define USB480M 11 -#define ACLK_CORE_NIU2BUS 18 -#define CLK_CORE_PVTM 19 -#define CLK_CORE_PVTM_CORE 20 -#define CLK_CORE_PVTPLL 21 -#define CLK_GPU_SRC 22 -#define CLK_GPU_PRE_NDFT 23 -#define CLK_GPU_PRE_MUX 24 -#define ACLK_GPU_PRE 25 -#define PCLK_GPU_PRE 26 -#define CLK_GPU 27 -#define CLK_GPU_NP5 28 -#define PCLK_GPU_PVTM 29 -#define CLK_GPU_PVTM 30 -#define CLK_GPU_PVTM_CORE 31 -#define CLK_GPU_PVTPLL 32 -#define CLK_NPU_SRC 33 -#define CLK_NPU_PRE_NDFT 34 -#define CLK_NPU 35 -#define CLK_NPU_NP5 36 -#define HCLK_NPU_PRE 37 -#define PCLK_NPU_PRE 38 -#define ACLK_NPU_PRE 39 -#define ACLK_NPU 40 -#define HCLK_NPU 41 -#define PCLK_NPU_PVTM 42 -#define CLK_NPU_PVTM 43 -#define CLK_NPU_PVTM_CORE 44 -#define CLK_NPU_PVTPLL 45 -#define CLK_DDRPHY1X_SRC 46 -#define CLK_DDRPHY1X_HWFFC_SRC 47 -#define CLK_DDR1X 48 -#define CLK_MSCH 49 -#define CLK24_DDRMON 50 -#define ACLK_GIC_AUDIO 51 -#define HCLK_GIC_AUDIO 52 -#define HCLK_SDMMC_BUFFER 53 -#define DCLK_SDMMC_BUFFER 54 -#define ACLK_GIC600 55 -#define ACLK_SPINLOCK 56 -#define HCLK_I2S0_8CH 57 -#define HCLK_I2S1_8CH 58 -#define HCLK_I2S2_2CH 59 -#define HCLK_I2S3_2CH 60 -#define CLK_I2S0_8CH_TX_SRC 61 -#define CLK_I2S0_8CH_TX_FRAC 62 -#define MCLK_I2S0_8CH_TX 63 -#define I2S0_MCLKOUT_TX 64 -#define CLK_I2S0_8CH_RX_SRC 65 -#define CLK_I2S0_8CH_RX_FRAC 66 -#define MCLK_I2S0_8CH_RX 67 -#define I2S0_MCLKOUT_RX 68 -#define CLK_I2S1_8CH_TX_SRC 69 -#define CLK_I2S1_8CH_TX_FRAC 70 -#define MCLK_I2S1_8CH_TX 71 -#define I2S1_MCLKOUT_TX 72 -#define CLK_I2S1_8CH_RX_SRC 73 -#define CLK_I2S1_8CH_RX_FRAC 74 -#define MCLK_I2S1_8CH_RX 75 -#define I2S1_MCLKOUT_RX 76 -#define CLK_I2S2_2CH_SRC 77 -#define CLK_I2S2_2CH_FRAC 78 -#define MCLK_I2S2_2CH 79 -#define I2S2_MCLKOUT 80 -#define CLK_I2S3_2CH_TX_SRC 81 -#define CLK_I2S3_2CH_TX_FRAC 82 -#define MCLK_I2S3_2CH_TX 83 -#define I2S3_MCLKOUT_TX 84 -#define CLK_I2S3_2CH_RX_SRC 85 -#define CLK_I2S3_2CH_RX_FRAC 86 -#define MCLK_I2S3_2CH_RX 87 -#define I2S3_MCLKOUT_RX 88 -#define HCLK_PDM 89 -#define MCLK_PDM 90 -#define HCLK_VAD 91 -#define HCLK_SPDIF_8CH 92 -#define MCLK_SPDIF_8CH_SRC 93 -#define MCLK_SPDIF_8CH_FRAC 94 -#define MCLK_SPDIF_8CH 95 -#define HCLK_AUDPWM 96 -#define SCLK_AUDPWM_SRC 97 -#define SCLK_AUDPWM_FRAC 98 -#define SCLK_AUDPWM 99 -#define HCLK_ACDCDIG 100 -#define CLK_ACDCDIG_I2C 101 -#define CLK_ACDCDIG_DAC 102 -#define CLK_ACDCDIG_ADC 103 -#define ACLK_SECURE_FLASH 104 -#define HCLK_SECURE_FLASH 105 -#define ACLK_CRYPTO_NS 106 -#define HCLK_CRYPTO_NS 107 -#define CLK_CRYPTO_NS_CORE 108 -#define CLK_CRYPTO_NS_PKA 109 -#define CLK_CRYPTO_NS_RNG 110 -#define HCLK_TRNG_NS 111 -#define CLK_TRNG_NS 112 -#define PCLK_OTPC_NS 113 -#define CLK_OTPC_NS_SBPI 114 -#define CLK_OTPC_NS_USR 115 -#define HCLK_NANDC 116 -#define NCLK_NANDC 117 -#define HCLK_SFC 118 -#define HCLK_SFC_XIP 119 -#define SCLK_SFC 120 -#define ACLK_EMMC 121 -#define HCLK_EMMC 122 -#define BCLK_EMMC 123 -#define CCLK_EMMC 124 -#define TCLK_EMMC 125 -#define ACLK_PIPE 126 -#define PCLK_PIPE 127 -#define PCLK_PIPE_GRF 128 -#define ACLK_PCIE20_MST 129 -#define ACLK_PCIE20_SLV 130 -#define ACLK_PCIE20_DBI 131 -#define PCLK_PCIE20 132 -#define CLK_PCIE20_AUX_NDFT 133 -#define CLK_PCIE20_AUX_DFT 134 -#define CLK_PCIE20_PIPE_DFT 135 -#define ACLK_PCIE30X1_MST 136 -#define ACLK_PCIE30X1_SLV 137 -#define ACLK_PCIE30X1_DBI 138 -#define PCLK_PCIE30X1 139 -#define CLK_PCIE30X1_AUX_NDFT 140 -#define CLK_PCIE30X1_AUX_DFT 141 -#define CLK_PCIE30X1_PIPE_DFT 142 -#define ACLK_PCIE30X2_MST 143 -#define ACLK_PCIE30X2_SLV 144 -#define ACLK_PCIE30X2_DBI 145 -#define PCLK_PCIE30X2 146 -#define CLK_PCIE30X2_AUX_NDFT 147 -#define CLK_PCIE30X2_AUX_DFT 148 -#define CLK_PCIE30X2_PIPE_DFT 149 -#define ACLK_SATA0 150 -#define CLK_SATA0_PMALIVE 151 -#define CLK_SATA0_RXOOB 152 -#define CLK_SATA0_PIPE_NDFT 153 -#define CLK_SATA0_PIPE_DFT 154 -#define ACLK_SATA1 155 -#define CLK_SATA1_PMALIVE 156 -#define CLK_SATA1_RXOOB 157 -#define CLK_SATA1_PIPE_NDFT 158 -#define CLK_SATA1_PIPE_DFT 159 -#define ACLK_SATA2 160 -#define CLK_SATA2_PMALIVE 161 -#define CLK_SATA2_RXOOB 162 -#define CLK_SATA2_PIPE_NDFT 163 -#define CLK_SATA2_PIPE_DFT 164 -#define ACLK_USB3OTG0 165 -#define CLK_USB3OTG0_REF 166 -#define CLK_USB3OTG0_SUSPEND 167 -#define ACLK_USB3OTG1 168 -#define CLK_USB3OTG1_REF 169 -#define CLK_USB3OTG1_SUSPEND 170 -#define CLK_XPCS_EEE 171 -#define PCLK_XPCS 172 -#define ACLK_PHP 173 -#define HCLK_PHP 174 -#define PCLK_PHP 175 -#define HCLK_SDMMC0 176 -#define CLK_SDMMC0 177 -#define HCLK_SDMMC1 178 -#define CLK_SDMMC1 179 -#define ACLK_GMAC0 180 -#define PCLK_GMAC0 181 -#define CLK_MAC0_2TOP 182 -#define CLK_MAC0_OUT 183 -#define CLK_MAC0_REFOUT 184 -#define CLK_GMAC0_PTP_REF 185 -#define ACLK_USB 186 -#define HCLK_USB 187 -#define PCLK_USB 188 -#define HCLK_USB2HOST0 189 -#define HCLK_USB2HOST0_ARB 190 -#define HCLK_USB2HOST1 191 -#define HCLK_USB2HOST1_ARB 192 -#define HCLK_SDMMC2 193 -#define CLK_SDMMC2 194 -#define ACLK_GMAC1 195 -#define PCLK_GMAC1 196 -#define CLK_MAC1_2TOP 197 -#define CLK_MAC1_OUT 198 -#define CLK_MAC1_REFOUT 199 -#define CLK_GMAC1_PTP_REF 200 -#define ACLK_PERIMID 201 -#define HCLK_PERIMID 202 -#define ACLK_VI 203 -#define HCLK_VI 204 -#define PCLK_VI 205 -#define ACLK_VICAP 206 -#define HCLK_VICAP 207 -#define DCLK_VICAP 208 -#define ICLK_VICAP_G 209 -#define ACLK_ISP 210 -#define HCLK_ISP 211 -#define CLK_ISP 212 -#define PCLK_CSI2HOST1 213 -#define CLK_CIF_OUT 214 -#define CLK_CAM0_OUT 215 -#define CLK_CAM1_OUT 216 -#define ACLK_VO 217 -#define HCLK_VO 218 -#define PCLK_VO 219 -#define ACLK_VOP_PRE 220 -#define ACLK_VOP 221 -#define HCLK_VOP 222 -#define DCLK_VOP0 223 -#define DCLK_VOP1 224 -#define DCLK_VOP2 225 -#define CLK_VOP_PWM 226 -#define ACLK_HDCP 227 -#define HCLK_HDCP 228 -#define PCLK_HDCP 229 -#define PCLK_HDMI_HOST 230 -#define CLK_HDMI_SFR 231 -#define PCLK_DSITX_0 232 -#define PCLK_DSITX_1 233 -#define PCLK_EDP_CTRL 234 -#define CLK_EDP_200M 235 -#define ACLK_VPU_PRE 236 -#define HCLK_VPU_PRE 237 -#define ACLK_VPU 238 -#define HCLK_VPU 239 -#define ACLK_RGA_PRE 240 -#define HCLK_RGA_PRE 241 -#define PCLK_RGA_PRE 242 -#define ACLK_RGA 243 -#define HCLK_RGA 244 -#define CLK_RGA_CORE 245 -#define ACLK_IEP 246 -#define HCLK_IEP 247 -#define CLK_IEP_CORE 248 -#define HCLK_EBC 249 -#define DCLK_EBC 250 -#define ACLK_JDEC 251 -#define HCLK_JDEC 252 -#define ACLK_JENC 253 -#define HCLK_JENC 254 -#define PCLK_EINK 255 -#define HCLK_EINK 256 -#define ACLK_RKVENC_PRE 257 -#define HCLK_RKVENC_PRE 258 -#define ACLK_RKVENC 259 -#define HCLK_RKVENC 260 -#define CLK_RKVENC_CORE 261 -#define ACLK_RKVDEC_PRE 262 -#define HCLK_RKVDEC_PRE 263 -#define ACLK_RKVDEC 264 -#define HCLK_RKVDEC 265 -#define CLK_RKVDEC_CA 266 -#define CLK_RKVDEC_CORE 267 -#define CLK_RKVDEC_HEVC_CA 268 -#define ACLK_BUS 269 -#define PCLK_BUS 270 -#define PCLK_TSADC 271 -#define CLK_TSADC_TSEN 272 -#define CLK_TSADC 273 -#define PCLK_SARADC 274 -#define CLK_SARADC 275 -#define PCLK_SCR 276 -#define PCLK_WDT_NS 277 -#define TCLK_WDT_NS 278 -#define ACLK_DMAC0 279 -#define ACLK_DMAC1 280 -#define ACLK_MCU 281 -#define PCLK_INTMUX 282 -#define PCLK_MAILBOX 283 -#define PCLK_UART1 284 -#define CLK_UART1_SRC 285 -#define CLK_UART1_FRAC 286 -#define SCLK_UART1 287 -#define PCLK_UART2 288 -#define CLK_UART2_SRC 289 -#define CLK_UART2_FRAC 290 -#define SCLK_UART2 291 -#define PCLK_UART3 292 -#define CLK_UART3_SRC 293 -#define CLK_UART3_FRAC 294 -#define SCLK_UART3 295 -#define PCLK_UART4 296 -#define CLK_UART4_SRC 297 -#define CLK_UART4_FRAC 298 -#define SCLK_UART4 299 -#define PCLK_UART5 300 -#define CLK_UART5_SRC 301 -#define CLK_UART5_FRAC 302 -#define SCLK_UART5 303 -#define PCLK_UART6 304 -#define CLK_UART6_SRC 305 -#define CLK_UART6_FRAC 306 -#define SCLK_UART6 307 -#define PCLK_UART7 308 -#define CLK_UART7_SRC 309 -#define CLK_UART7_FRAC 310 -#define SCLK_UART7 311 -#define PCLK_UART8 312 -#define CLK_UART8_SRC 313 -#define CLK_UART8_FRAC 314 -#define SCLK_UART8 315 -#define PCLK_UART9 316 -#define CLK_UART9_SRC 317 -#define CLK_UART9_FRAC 318 -#define SCLK_UART9 319 -#define PCLK_CAN0 320 -#define CLK_CAN0 321 -#define PCLK_CAN1 322 -#define CLK_CAN1 323 -#define PCLK_CAN2 324 -#define CLK_CAN2 325 -#define CLK_I2C 326 -#define PCLK_I2C1 327 -#define CLK_I2C1 328 -#define PCLK_I2C2 329 -#define CLK_I2C2 330 -#define PCLK_I2C3 331 -#define CLK_I2C3 332 -#define PCLK_I2C4 333 -#define CLK_I2C4 334 -#define PCLK_I2C5 335 -#define CLK_I2C5 336 -#define PCLK_SPI0 337 -#define CLK_SPI0 338 -#define PCLK_SPI1 339 -#define CLK_SPI1 340 -#define PCLK_SPI2 341 -#define CLK_SPI2 342 -#define PCLK_SPI3 343 -#define CLK_SPI3 344 -#define PCLK_PWM1 345 -#define CLK_PWM1 346 -#define CLK_PWM1_CAPTURE 347 -#define PCLK_PWM2 348 -#define CLK_PWM2 349 -#define CLK_PWM2_CAPTURE 350 -#define PCLK_PWM3 351 -#define CLK_PWM3 352 -#define CLK_PWM3_CAPTURE 353 -#define DBCLK_GPIO 354 -#define PCLK_GPIO1 355 -#define DBCLK_GPIO1 356 -#define PCLK_GPIO2 357 -#define DBCLK_GPIO2 358 -#define PCLK_GPIO3 359 -#define DBCLK_GPIO3 360 -#define PCLK_GPIO4 361 -#define DBCLK_GPIO4 362 -#define OCC_SCAN_CLK_GPIO 363 -#define PCLK_TIMER 364 -#define CLK_TIMER0 365 -#define CLK_TIMER1 366 -#define CLK_TIMER2 367 -#define CLK_TIMER3 368 -#define CLK_TIMER4 369 -#define CLK_TIMER5 370 -#define ACLK_TOP_HIGH 371 -#define ACLK_TOP_LOW 372 -#define HCLK_TOP 373 -#define PCLK_TOP 374 -#define PCLK_PCIE30PHY 375 -#define CLK_OPTC_ARB 376 -#define PCLK_MIPICSIPHY 377 -#define PCLK_MIPIDSIPHY0 378 -#define PCLK_MIPIDSIPHY1 379 -#define PCLK_PIPEPHY0 380 -#define PCLK_PIPEPHY1 381 -#define PCLK_PIPEPHY2 382 -#define PCLK_CPU_BOOST 383 -#define CLK_CPU_BOOST 384 -#define PCLK_OTPPHY 385 -#define SCLK_GMAC0 386 -#define SCLK_GMAC0_RGMII_SPEED 387 -#define SCLK_GMAC0_RMII_SPEED 388 -#define SCLK_GMAC0_RX_TX 389 -#define SCLK_GMAC1 390 -#define SCLK_GMAC1_RGMII_SPEED 391 -#define SCLK_GMAC1_RMII_SPEED 392 -#define SCLK_GMAC1_RX_TX 393 -#define SCLK_SDMMC0_DRV 394 -#define SCLK_SDMMC0_SAMPLE 395 -#define SCLK_SDMMC1_DRV 396 -#define SCLK_SDMMC1_SAMPLE 397 -#define SCLK_SDMMC2_DRV 398 -#define SCLK_SDMMC2_SAMPLE 399 -#define SCLK_EMMC_DRV 400 -#define SCLK_EMMC_SAMPLE 401 -#define PCLK_EDPPHY_GRF 402 -#define CLK_HDMI_CEC 403 -#define CLK_I2S0_8CH_TX 404 -#define CLK_I2S0_8CH_RX 405 -#define CLK_I2S1_8CH_TX 406 -#define CLK_I2S1_8CH_RX 407 -#define CLK_I2S2_2CH 408 -#define CLK_I2S3_2CH_TX 409 -#define CLK_I2S3_2CH_RX 410 -#define CPLL_500M 411 -#define CPLL_250M 412 -#define CPLL_125M 413 -#define CPLL_62P5M 414 -#define CPLL_50M 415 -#define CPLL_25M 416 -#define CPLL_100M 417 -#define SCLK_DDRCLK 418 -#define I2S1_MCLKOUT 419 -#define I2S3_MCLKOUT 420 -#define I2S1_MCLK_RX_IOE 421 -#define I2S1_MCLK_TX_IOE 422 -#define I2S2_MCLK_IOE 423 -#define I2S3_MCLK_IOE 424 - -#define PCLK_CORE_PVTM 450 - -#define CLK_NR_CLKS (PCLK_CORE_PVTM + 1) - -/* pmu soft-reset indices */ -/* pmucru_softrst_con0 */ -#define SRST_P_PDPMU_NIU 0 -#define SRST_P_PMUCRU 1 -#define SRST_P_PMUGRF 2 -#define SRST_P_I2C0 3 -#define SRST_I2C0 4 -#define SRST_P_UART0 5 -#define SRST_S_UART0 6 -#define SRST_P_PWM0 7 -#define SRST_PWM0 8 -#define SRST_P_GPIO0 9 -#define SRST_GPIO0 10 -#define SRST_P_PMUPVTM 11 -#define SRST_PMUPVTM 12 - -/* soft-reset indices */ - -/* cru_softrst_con0 */ -#define SRST_NCORERESET0 0 -#define SRST_NCORERESET1 1 -#define SRST_NCORERESET2 2 -#define SRST_NCORERESET3 3 -#define SRST_NCPUPORESET0 4 -#define SRST_NCPUPORESET1 5 -#define SRST_NCPUPORESET2 6 -#define SRST_NCPUPORESET3 7 -#define SRST_NSRESET 8 -#define SRST_NSPORESET 9 -#define SRST_NATRESET 10 -#define SRST_NGICRESET 11 -#define SRST_NPRESET 12 -#define SRST_NPERIPHRESET 13 - -/* cru_softrst_con1 */ -#define SRST_A_CORE_NIU2DDR 16 -#define SRST_A_CORE_NIU2BUS 17 -#define SRST_P_DBG_NIU 18 -#define SRST_P_DBG 19 -#define SRST_P_DBG_DAPLITE 20 -#define SRST_DAP 21 -#define SRST_A_ADB400_CORE2GIC 22 -#define SRST_A_ADB400_GIC2CORE 23 -#define SRST_P_CORE_GRF 24 -#define SRST_P_CORE_PVTM 25 -#define SRST_CORE_PVTM 26 -#define SRST_CORE_PVTPLL 27 - -/* cru_softrst_con2 */ -#define SRST_GPU 32 -#define SRST_A_GPU_NIU 33 -#define SRST_P_GPU_NIU 34 -#define SRST_P_GPU_PVTM 35 -#define SRST_GPU_PVTM 36 -#define SRST_GPU_PVTPLL 37 -#define SRST_A_NPU_NIU 40 -#define SRST_H_NPU_NIU 41 -#define SRST_P_NPU_NIU 42 -#define SRST_A_NPU 43 -#define SRST_H_NPU 44 -#define SRST_P_NPU_PVTM 45 -#define SRST_NPU_PVTM 46 -#define SRST_NPU_PVTPLL 47 - -/* cru_softrst_con3 */ -#define SRST_A_MSCH 51 -#define SRST_HWFFC_CTRL 52 -#define SRST_DDR_ALWAYSON 53 -#define SRST_A_DDRSPLIT 54 -#define SRST_DDRDFI_CTL 55 -#define SRST_A_DMA2DDR 57 - -/* cru_softrst_con4 */ -#define SRST_A_PERIMID_NIU 64 -#define SRST_H_PERIMID_NIU 65 -#define SRST_A_GIC_AUDIO_NIU 66 -#define SRST_H_GIC_AUDIO_NIU 67 -#define SRST_A_GIC600 68 -#define SRST_A_GIC600_DEBUG 69 -#define SRST_A_GICADB_CORE2GIC 70 -#define SRST_A_GICADB_GIC2CORE 71 -#define SRST_A_SPINLOCK 72 -#define SRST_H_SDMMC_BUFFER 73 -#define SRST_D_SDMMC_BUFFER 74 -#define SRST_H_I2S0_8CH 75 -#define SRST_H_I2S1_8CH 76 -#define SRST_H_I2S2_2CH 77 -#define SRST_H_I2S3_2CH 78 - -/* cru_softrst_con5 */ -#define SRST_M_I2S0_8CH_TX 80 -#define SRST_M_I2S0_8CH_RX 81 -#define SRST_M_I2S1_8CH_TX 82 -#define SRST_M_I2S1_8CH_RX 83 -#define SRST_M_I2S2_2CH 84 -#define SRST_M_I2S3_2CH_TX 85 -#define SRST_M_I2S3_2CH_RX 86 -#define SRST_H_PDM 87 -#define SRST_M_PDM 88 -#define SRST_H_VAD 89 -#define SRST_H_SPDIF_8CH 90 -#define SRST_M_SPDIF_8CH 91 -#define SRST_H_AUDPWM 92 -#define SRST_S_AUDPWM 93 -#define SRST_H_ACDCDIG 94 -#define SRST_ACDCDIG 95 - -/* cru_softrst_con6 */ -#define SRST_A_SECURE_FLASH_NIU 96 -#define SRST_H_SECURE_FLASH_NIU 97 -#define SRST_A_CRYPTO_NS 103 -#define SRST_H_CRYPTO_NS 104 -#define SRST_CRYPTO_NS_CORE 105 -#define SRST_CRYPTO_NS_PKA 106 -#define SRST_CRYPTO_NS_RNG 107 -#define SRST_H_TRNG_NS 108 -#define SRST_TRNG_NS 109 - -/* cru_softrst_con7 */ -#define SRST_H_NANDC 112 -#define SRST_N_NANDC 113 -#define SRST_H_SFC 114 -#define SRST_H_SFC_XIP 115 -#define SRST_S_SFC 116 -#define SRST_A_EMMC 117 -#define SRST_H_EMMC 118 -#define SRST_B_EMMC 119 -#define SRST_C_EMMC 120 -#define SRST_T_EMMC 121 - -/* cru_softrst_con8 */ -#define SRST_A_PIPE_NIU 128 -#define SRST_P_PIPE_NIU 130 -#define SRST_P_PIPE_GRF 133 -#define SRST_A_SATA0 134 -#define SRST_SATA0_PIPE 135 -#define SRST_SATA0_PMALIVE 136 -#define SRST_SATA0_RXOOB 137 -#define SRST_A_SATA1 138 -#define SRST_SATA1_PIPE 139 -#define SRST_SATA1_PMALIVE 140 -#define SRST_SATA1_RXOOB 141 - -/* cru_softrst_con9 */ -#define SRST_A_SATA2 144 -#define SRST_SATA2_PIPE 145 -#define SRST_SATA2_PMALIVE 146 -#define SRST_SATA2_RXOOB 147 -#define SRST_USB3OTG0 148 -#define SRST_USB3OTG1 149 -#define SRST_XPCS 150 -#define SRST_XPCS_TX_DIV10 151 -#define SRST_XPCS_RX_DIV10 152 -#define SRST_XPCS_XGXS_RX 153 - -/* cru_softrst_con10 */ -#define SRST_P_PCIE20 160 -#define SRST_PCIE20_POWERUP 161 -#define SRST_MSTR_ARESET_PCIE20 162 -#define SRST_SLV_ARESET_PCIE20 163 -#define SRST_DBI_ARESET_PCIE20 164 -#define SRST_BRESET_PCIE20 165 -#define SRST_PERST_PCIE20 166 -#define SRST_CORE_RST_PCIE20 167 -#define SRST_NSTICKY_RST_PCIE20 168 -#define SRST_STICKY_RST_PCIE20 169 -#define SRST_PWR_RST_PCIE20 170 - -/* cru_softrst_con11 */ -#define SRST_P_PCIE30X1 176 -#define SRST_PCIE30X1_POWERUP 177 -#define SRST_M_ARESET_PCIE30X1 178 -#define SRST_S_ARESET_PCIE30X1 179 -#define SRST_D_ARESET_PCIE30X1 180 -#define SRST_BRESET_PCIE30X1 181 -#define SRST_PERST_PCIE30X1 182 -#define SRST_CORE_RST_PCIE30X1 183 -#define SRST_NSTC_RST_PCIE30X1 184 -#define SRST_STC_RST_PCIE30X1 185 -#define SRST_PWR_RST_PCIE30X1 186 - -/* cru_softrst_con12 */ -#define SRST_P_PCIE30X2 192 -#define SRST_PCIE30X2_POWERUP 193 -#define SRST_M_ARESET_PCIE30X2 194 -#define SRST_S_ARESET_PCIE30X2 195 -#define SRST_D_ARESET_PCIE30X2 196 -#define SRST_BRESET_PCIE30X2 197 -#define SRST_PERST_PCIE30X2 198 -#define SRST_CORE_RST_PCIE30X2 199 -#define SRST_NSTC_RST_PCIE30X2 200 -#define SRST_STC_RST_PCIE30X2 201 -#define SRST_PWR_RST_PCIE30X2 202 - -/* cru_softrst_con13 */ -#define SRST_A_PHP_NIU 208 -#define SRST_H_PHP_NIU 209 -#define SRST_P_PHP_NIU 210 -#define SRST_H_SDMMC0 211 -#define SRST_SDMMC0 212 -#define SRST_H_SDMMC1 213 -#define SRST_SDMMC1 214 -#define SRST_A_GMAC0 215 -#define SRST_GMAC0_TIMESTAMP 216 - -/* cru_softrst_con14 */ -#define SRST_A_USB_NIU 224 -#define SRST_H_USB_NIU 225 -#define SRST_P_USB_NIU 226 -#define SRST_P_USB_GRF 227 -#define SRST_H_USB2HOST0 228 -#define SRST_H_USB2HOST0_ARB 229 -#define SRST_USB2HOST0_UTMI 230 -#define SRST_H_USB2HOST1 231 -#define SRST_H_USB2HOST1_ARB 232 -#define SRST_USB2HOST1_UTMI 233 -#define SRST_H_SDMMC2 234 -#define SRST_SDMMC2 235 -#define SRST_A_GMAC1 236 -#define SRST_GMAC1_TIMESTAMP 237 - -/* cru_softrst_con15 */ -#define SRST_A_VI_NIU 240 -#define SRST_H_VI_NIU 241 -#define SRST_P_VI_NIU 242 -#define SRST_A_VICAP 247 -#define SRST_H_VICAP 248 -#define SRST_D_VICAP 249 -#define SRST_I_VICAP 250 -#define SRST_P_VICAP 251 -#define SRST_H_ISP 252 -#define SRST_ISP 253 -#define SRST_P_CSI2HOST1 255 - -/* cru_softrst_con16 */ -#define SRST_A_VO_NIU 256 -#define SRST_H_VO_NIU 257 -#define SRST_P_VO_NIU 258 -#define SRST_A_VOP_NIU 259 -#define SRST_A_VOP 260 -#define SRST_H_VOP 261 -#define SRST_VOP0 262 -#define SRST_VOP1 263 -#define SRST_VOP2 264 -#define SRST_VOP_PWM 265 -#define SRST_A_HDCP 266 -#define SRST_H_HDCP 267 -#define SRST_P_HDCP 268 -#define SRST_P_HDMI_HOST 270 -#define SRST_HDMI_HOST 271 - -/* cru_softrst_con17 */ -#define SRST_P_DSITX_0 272 -#define SRST_P_DSITX_1 273 -#define SRST_P_EDP_CTRL 274 -#define SRST_EDP_24M 275 -#define SRST_A_VPU_NIU 280 -#define SRST_H_VPU_NIU 281 -#define SRST_A_VPU 282 -#define SRST_H_VPU 283 -#define SRST_H_EINK 286 -#define SRST_P_EINK 287 - -/* cru_softrst_con18 */ -#define SRST_A_RGA_NIU 288 -#define SRST_H_RGA_NIU 289 -#define SRST_P_RGA_NIU 290 -#define SRST_A_RGA 292 -#define SRST_H_RGA 293 -#define SRST_RGA_CORE 294 -#define SRST_A_IEP 295 -#define SRST_H_IEP 296 -#define SRST_IEP_CORE 297 -#define SRST_H_EBC 298 -#define SRST_D_EBC 299 -#define SRST_A_JDEC 300 -#define SRST_H_JDEC 301 -#define SRST_A_JENC 302 -#define SRST_H_JENC 303 - -/* cru_softrst_con19 */ -#define SRST_A_VENC_NIU 304 -#define SRST_H_VENC_NIU 305 -#define SRST_A_RKVENC 307 -#define SRST_H_RKVENC 308 -#define SRST_RKVENC_CORE 309 - -/* cru_softrst_con20 */ -#define SRST_A_RKVDEC_NIU 320 -#define SRST_H_RKVDEC_NIU 321 -#define SRST_A_RKVDEC 322 -#define SRST_H_RKVDEC 323 -#define SRST_RKVDEC_CA 324 -#define SRST_RKVDEC_CORE 325 -#define SRST_RKVDEC_HEVC_CA 326 - -/* cru_softrst_con21 */ -#define SRST_A_BUS_NIU 336 -#define SRST_P_BUS_NIU 338 -#define SRST_P_CAN0 340 -#define SRST_CAN0 341 -#define SRST_P_CAN1 342 -#define SRST_CAN1 343 -#define SRST_P_CAN2 344 -#define SRST_CAN2 345 -#define SRST_P_GPIO1 346 -#define SRST_GPIO1 347 -#define SRST_P_GPIO2 348 -#define SRST_GPIO2 349 -#define SRST_P_GPIO3 350 -#define SRST_GPIO3 351 - -/* cru_softrst_con22 */ -#define SRST_P_GPIO4 352 -#define SRST_GPIO4 353 -#define SRST_P_I2C1 354 -#define SRST_I2C1 355 -#define SRST_P_I2C2 356 -#define SRST_I2C2 357 -#define SRST_P_I2C3 358 -#define SRST_I2C3 359 -#define SRST_P_I2C4 360 -#define SRST_I2C4 361 -#define SRST_P_I2C5 362 -#define SRST_I2C5 363 -#define SRST_P_OTPC_NS 364 -#define SRST_OTPC_NS_SBPI 365 -#define SRST_OTPC_NS_USR 366 - -/* cru_softrst_con23 */ -#define SRST_P_PWM1 368 -#define SRST_PWM1 369 -#define SRST_P_PWM2 370 -#define SRST_PWM2 371 -#define SRST_P_PWM3 372 -#define SRST_PWM3 373 -#define SRST_P_SPI0 374 -#define SRST_SPI0 375 -#define SRST_P_SPI1 376 -#define SRST_SPI1 377 -#define SRST_P_SPI2 378 -#define SRST_SPI2 379 -#define SRST_P_SPI3 380 -#define SRST_SPI3 381 - -/* cru_softrst_con24 */ -#define SRST_P_SARADC 384 -#define SRST_P_TSADC 385 -#define SRST_TSADC 386 -#define SRST_P_TIMER 387 -#define SRST_TIMER0 388 -#define SRST_TIMER1 389 -#define SRST_TIMER2 390 -#define SRST_TIMER3 391 -#define SRST_TIMER4 392 -#define SRST_TIMER5 393 -#define SRST_P_UART1 394 -#define SRST_S_UART1 395 - -/* cru_softrst_con25 */ -#define SRST_P_UART2 400 -#define SRST_S_UART2 401 -#define SRST_P_UART3 402 -#define SRST_S_UART3 403 -#define SRST_P_UART4 404 -#define SRST_S_UART4 405 -#define SRST_P_UART5 406 -#define SRST_S_UART5 407 -#define SRST_P_UART6 408 -#define SRST_S_UART6 409 -#define SRST_P_UART7 410 -#define SRST_S_UART7 411 -#define SRST_P_UART8 412 -#define SRST_S_UART8 413 -#define SRST_P_UART9 414 -#define SRST_S_UART9 415 - -/* cru_softrst_con26 */ -#define SRST_P_GRF 416 -#define SRST_P_GRF_VCCIO12 417 -#define SRST_P_GRF_VCCIO34 418 -#define SRST_P_GRF_VCCIO567 419 -#define SRST_P_SCR 420 -#define SRST_P_WDT_NS 421 -#define SRST_T_WDT_NS 422 -#define SRST_P_DFT2APB 423 -#define SRST_A_MCU 426 -#define SRST_P_INTMUX 427 -#define SRST_P_MAILBOX 428 - -/* cru_softrst_con27 */ -#define SRST_A_TOP_HIGH_NIU 432 -#define SRST_A_TOP_LOW_NIU 433 -#define SRST_H_TOP_NIU 434 -#define SRST_P_TOP_NIU 435 -#define SRST_P_TOP_CRU 438 -#define SRST_P_DDRPHY 439 -#define SRST_DDRPHY 440 -#define SRST_P_MIPICSIPHY 442 -#define SRST_P_MIPIDSIPHY0 443 -#define SRST_P_MIPIDSIPHY1 444 -#define SRST_P_PCIE30PHY 445 -#define SRST_PCIE30PHY 446 -#define SRST_P_PCIE30PHY_GRF 447 - -/* cru_softrst_con28 */ -#define SRST_P_APB2ASB_LEFT 448 -#define SRST_P_APB2ASB_BOTTOM 449 -#define SRST_P_ASB2APB_LEFT 450 -#define SRST_P_ASB2APB_BOTTOM 451 -#define SRST_P_PIPEPHY0 452 -#define SRST_PIPEPHY0 453 -#define SRST_P_PIPEPHY1 454 -#define SRST_PIPEPHY1 455 -#define SRST_P_PIPEPHY2 456 -#define SRST_PIPEPHY2 457 -#define SRST_P_USB2PHY0_GRF 458 -#define SRST_P_USB2PHY1_GRF 459 -#define SRST_P_CPU_BOOST 460 -#define SRST_CPU_BOOST 461 -#define SRST_P_OTPPHY 462 -#define SRST_OTPPHY 463 +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RK3568_CLOCK_H +#define ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RK3568_CLOCK_H +#ifdef __cplusplus + extern "C" { +#endif -/* cru_softrst_con29 */ -#define SRST_USB2PHY0_POR 464 -#define SRST_USB2PHY0_USB3OTG0 465 -#define SRST_USB2PHY0_USB3OTG1 466 -#define SRST_USB2PHY1_POR 467 -#define SRST_USB2PHY1_USB2HOST0 468 -#define SRST_USB2PHY1_USB2HOST1 469 -#define SRST_P_EDPPHY_GRF 470 -#define SRST_TSADCPHY 471 -#define SRST_GMAC0_DELAYLINE 472 -#define SRST_GMAC1_DELAYLINE 473 -#define SRST_OTPC_ARB 474 -#define SRST_P_PIPEPHY0_GRF 475 -#define SRST_P_PIPEPHY1_GRF 476 -#define SRST_P_PIPEPHY2_GRF 477 +#ifndef __ASSEMBLY__ +#ifndef __IO +#define __IO #endif + +/* PMUCRU Register Structure Define */ +struct PMUCRU_REG { + __IO uint32_t PPLL_CON[5]; /* Address Offset: 0x0000 */ + uint32_t RESERVED0014[11]; /* Address Offset: 0x0014 */ + __IO uint32_t HPLL_CON[5]; /* Address Offset: 0x0040 */ + uint32_t RESERVED0054[11]; /* Address Offset: 0x0054 */ + __IO uint32_t MODE_CON00; /* Address Offset: 0x0080 */ + uint32_t RESERVED0084[31]; /* Address Offset: 0x0084 */ + __IO uint32_t CRU_CLKSEL_CON[10]; /* Address Offset: 0x0100 */ + uint32_t RESERVED0128[22]; /* Address Offset: 0x0128 */ + __IO uint32_t CRU_CLKGATE_CON[3]; /* Address Offset: 0x0180 */ + uint32_t RESERVED018C[29]; /* Address Offset: 0x018C */ + __IO uint32_t CRU_SOFTRST_CON[1]; /* Address Offset: 0x0200 */ +}; + +/* CRU Register Structure Define */ +struct CRU_REG { + __IO uint32_t APLL_CON[5]; /* Address Offset: 0x0000 */ + uint32_t RESERVED0014[3]; /* Address Offset: 0x0014 */ + __IO uint32_t DPLL_CON[5]; /* Address Offset: 0x0020 */ + uint32_t RESERVED0034[3]; /* Address Offset: 0x0034 */ + __IO uint32_t GPLL_CON[5]; /* Address Offset: 0x0040 */ + uint32_t RESERVED0054[3]; /* Address Offset: 0x0054 */ + __IO uint32_t CPLL_CON[5]; /* Address Offset: 0x0060 */ + uint32_t RESERVED0074[3]; /* Address Offset: 0x0074 */ + __IO uint32_t NPLL_CON[2]; /* Address Offset: 0x0080 */ + uint32_t RESERVED0088[6]; /* Address Offset: 0x0088 */ + __IO uint32_t VPLL_CON[2]; /* Address Offset: 0x00A0 */ + uint32_t RESERVED00A8[6]; /* Address Offset: 0x00A8 */ + __IO uint32_t MODE_CON00; /* Address Offset: 0x00C0 */ + __IO uint32_t MISC_CON[3]; /* Address Offset: 0x00C4 */ + __IO uint32_t GLB_CNT_TH; /* Address Offset: 0x00D0 */ + __IO uint32_t GLB_SRST_FST; /* Address Offset: 0x00D4 */ + __IO uint32_t GLB_SRST_SND; /* Address Offset: 0x00D8 */ + __IO uint32_t GLB_RST_CON; /* Address Offset: 0x00DC */ + __IO uint32_t GLB_RST_ST; /* Address Offset: 0x00E0 */ + uint32_t RESERVED00E4[7]; /* Address Offset: 0x00E4 */ + __IO uint32_t CRU_CLKSEL_CON[85]; /* Address Offset: 0x0100 */ + uint32_t RESERVED0254[43]; /* Address Offset: 0x0254 */ + __IO uint32_t CRU_CLKGATE_CON[36]; /* Address Offset: 0x0300 */ + uint32_t RESERVED0390[28]; /* Address Offset: 0x0390 */ + __IO uint32_t CRU_SOFTRST_CON[30]; /* Address Offset: 0x0400 */ + uint32_t RESERVED0478[2]; /* Address Offset: 0x0478 */ + __IO uint32_t SSGTBL0_3; /* Address Offset: 0x0480 */ + __IO uint32_t SSGTBL4_7; /* Address Offset: 0x0484 */ + __IO uint32_t SSGTBL8_11; /* Address Offset: 0x0488 */ + __IO uint32_t SSGTBL12_15; /* Address Offset: 0x048C */ + __IO uint32_t SSGTBL16_19; /* Address Offset: 0x0490 */ + __IO uint32_t SSGTBL20_23; /* Address Offset: 0x0494 */ + __IO uint32_t SSGTBL24_27; /* Address Offset: 0x0498 */ + __IO uint32_t SSGTBL28_31; /* Address Offset: 0x049C */ + __IO uint32_t SSGTBL32_35; /* Address Offset: 0x04A0 */ + __IO uint32_t SSGTBL36_39; /* Address Offset: 0x04A4 */ + __IO uint32_t SSGTBL40_43; /* Address Offset: 0x04A8 */ + __IO uint32_t SSGTBL44_47; /* Address Offset: 0x04AC */ + __IO uint32_t SSGTBL48_51; /* Address Offset: 0x04B0 */ + __IO uint32_t SSGTBL52_55; /* Address Offset: 0x04B4 */ + __IO uint32_t SSGTBL56_59; /* Address Offset: 0x04B8 */ + __IO uint32_t SSGTBL60_63; /* Address Offset: 0x04BC */ + __IO uint32_t SSGTBL64_67; /* Address Offset: 0x04C0 */ + __IO uint32_t SSGTBL68_71; /* Address Offset: 0x04C4 */ + __IO uint32_t SSGTBL72_75; /* Address Offset: 0x04C8 */ + __IO uint32_t SSGTBL76_79; /* Address Offset: 0x04CC */ + __IO uint32_t SSGTBL80_83; /* Address Offset: 0x04D0 */ + __IO uint32_t SSGTBL84_87; /* Address Offset: 0x04D4 */ + __IO uint32_t SSGTBL88_91; /* Address Offset: 0x04D8 */ + __IO uint32_t SSGTBL92_95; /* Address Offset: 0x04DC */ + __IO uint32_t SSGTBL96_99; /* Address Offset: 0x04E0 */ + __IO uint32_t SSGTBL100_103; /* Address Offset: 0x04E4 */ + __IO uint32_t SSGTBL104_107; /* Address Offset: 0x04E8 */ + __IO uint32_t SSGTBL108_111; /* Address Offset: 0x04EC */ + __IO uint32_t SSGTBL112_115; /* Address Offset: 0x04F0 */ + __IO uint32_t SSGTBL116_119; /* Address Offset: 0x04F4 */ + __IO uint32_t SSGTBL120_123; /* Address Offset: 0x04F8 */ + __IO uint32_t SSGTBL124_127; /* Address Offset: 0x04FC */ + __IO uint32_t AUTOCS_CORE_CON0; /* Address Offset: 0x0500 */ + __IO uint32_t AUTOCS_CORE_CON1; /* Address Offset: 0x0504 */ + __IO uint32_t AUTOCS_GPU_CON0; /* Address Offset: 0x0508 */ + __IO uint32_t AUTOCS_GPU_CON1; /* Address Offset: 0x050C */ + __IO uint32_t AUTOCS_BUS_CON0; /* Address Offset: 0x0510 */ + __IO uint32_t AUTOCS_BUS_CON1; /* Address Offset: 0x0514 */ + __IO uint32_t AUTOCS_TOP_CON0; /* Address Offset: 0x0518 */ + __IO uint32_t AUTOCS_TOP_CON1; /* Address Offset: 0x051C */ + __IO uint32_t AUTOCS_RKVDEC_CON0; /* Address Offset: 0x0520 */ + __IO uint32_t AUTOCS_RKVDEC_CON1; /* Address Offset: 0x0524 */ + __IO uint32_t AUTOCS_RKVENC_CON0; /* Address Offset: 0x0528 */ + __IO uint32_t AUTOCS_RKVENC_CON1; /* Address Offset: 0x052C */ + __IO uint32_t AUTOCS_VPU_CON0; /* Address Offset: 0x0530 */ + __IO uint32_t AUTOCS_VPU_CON1; /* Address Offset: 0x0534 */ + __IO uint32_t AUTOCS_PERI_CON0; /* Address Offset: 0x0538 */ + __IO uint32_t AUTOCS_PERI_CON1; /* Address Offset: 0x053C */ + __IO uint32_t AUTOCS_GPLL_CON0; /* Address Offset: 0x0540 */ + __IO uint32_t AUTOCS_GPLL_CON1; /* Address Offset: 0x0544 */ + __IO uint32_t AUTOCS_CPLL_CON0; /* Address Offset: 0x0548 */ + __IO uint32_t AUTOCS_CPLL_CON1; /* Address Offset: 0x054C */ + uint32_t RESERVED0550[12]; /* Address Offset: 0x0550 */ + __IO uint32_t SDMMC0_CON[2]; /* Address Offset: 0x0580 */ + __IO uint32_t SDMMC1_CON[2]; /* Address Offset: 0x0588 */ + __IO uint32_t SDMMC2_CON[2]; /* Address Offset: 0x0590 */ + __IO uint32_t EMMC_CON[2]; /* Address Offset: 0x0598 */ +}; + +/* pmucru system configuration. */ +struct rk3568_clk_syscon { + uint32_t reg_base; + uint32_t reg_size; + void *priv_data; +}; + +/* Add current clock syscon info to subsys(like zvm) */ +int z_info_sys_clkcon(const char *name, uint32_t addr_base, + uint32_t addr_size, void *priv); + +int __weak z_info_sys_clkcon(const char *name, uint32_t addr_base, + uint32_t addr_size, void *priv) +{ + ARG_UNUSED(addr_base); + ARG_UNUSED(addr_size); + ARG_UNUSED(priv); + return 0; +} + +#endif /* __ASSEMBLY__ */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_CLOCK_RK3568_CLOCK_H_ */ \ No newline at end of file diff --git a/include/linker/common-rom.ld b/include/linker/common-rom.ld index afdc76434bbf395169267598353c201f50d3c605..a72b71174db42eccc1c65876a1567509d7971969 100644 --- a/include/linker/common-rom.ld +++ b/include/linker/common-rom.ld @@ -226,3 +226,10 @@ #endif /* LINKER_DEVICE_HANDLES_PASS1 */ __device_handles_end = .; } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + SECTION_DATA_PROLOGUE(virtual_device_instances_sections,,) + { + __virtual_device_instances_start = .; + KEEP(*("._virtual_device_instance.*")); + __virtual_device_instances_end = .; + } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) diff --git a/include/virtualization/arm/asm.h b/include/virtualization/arm/asm.h index 1e72c7872c423acab1a4719b3d307953d8fdaf1f..470f817a76e8b8be0544d22d71d873c7f436f10f 100644 --- a/include/virtualization/arm/asm.h +++ b/include/virtualization/arm/asm.h @@ -7,23 +7,23 @@ #ifndef ZEPHYR_INCLUDE_ZVM_ARM_ASM_H_ #define ZEPHYR_INCLUDE_ZVM_ARM_ASM_H_ -#define ARM_VM_EXCEPTION_SYNC (0x1) -#define ARM_VM_EXCEPTION_IRQ (0x2) -#define ARM_VM_EXCEPTION_SERROR (0x3) -#define ARM_VM_EXCEPTION_IRQ_IN_SYNC (0x4) +#define ARM_VM_EXCEPTION_SYNC (0x01) +#define ARM_VM_EXCEPTION_IRQ (0x02) +#define ARM_VM_EXCEPTION_SERROR (0x03) +#define ARM_VM_EXCEPTION_IRQ_IN_SYNC (0x04) -#define DFSC_FT_TRANS_L0 (0x04) -#define DFSC_FT_TRANS_L1 (0x05) -#define DFSC_FT_TRANS_L2 (0x06) -#define DFSC_FT_TRANS_L3 (0x07) -#define DFSC_FT_ACCESS_L0 (0x08) -#define DFSC_FT_ACCESS_L1 (0x09) -#define DFSC_FT_ACCESS_L2 (0x0A) -#define DFSC_FT_ACCESS_L3 (0x0B) -#define DFSC_FT_PERM_L0 (0x0C) -#define DFSC_FT_PERM_L1 (0x0D) -#define DFSC_FT_PERM_L2 (0x0E) -#define DFSC_FT_PERM_L3 (0x0F) +#define DFSC_FT_TRANS_L0 (0x04) +#define DFSC_FT_TRANS_L1 (0x05) +#define DFSC_FT_TRANS_L2 (0x06) +#define DFSC_FT_TRANS_L3 (0x07) +#define DFSC_FT_ACCESS_L0 (0x08) +#define DFSC_FT_ACCESS_L1 (0x09) +#define DFSC_FT_ACCESS_L2 (0x0A) +#define DFSC_FT_ACCESS_L3 (0x0B) +#define DFSC_FT_PERM_L0 (0x0C) +#define DFSC_FT_PERM_L1 (0x0D) +#define DFSC_FT_PERM_L2 (0x0E) +#define DFSC_FT_PERM_L3 (0x0F) #define ARM_VM_SERROR_PENDING(x) !!((x) & (1U << 31)) diff --git a/include/virtualization/arm/cpu.h b/include/virtualization/arm/cpu.h index 40ec0d43b498722f974227bd5080964b52334cba..da8786feb23e0861d8e517d95fdbfa28241a56ee 100644 --- a/include/virtualization/arm/cpu.h +++ b/include/virtualization/arm/cpu.h @@ -12,6 +12,7 @@ #include #include #include +#include #define HCR_VHE_FLAGS (HCR_RW_BIT | HCR_TGE_BIT | HCR_E2H_BIT) @@ -104,13 +105,14 @@ ((__SYSREG_##crm) << ESR_SYSINS_CRM_SHIFT) | \ ((__SYSREG_##op2) << ESR_SYSINS_OP2_SHIFT)) -#define ESR_SYSINSREG_SGI1R_EL1 ESR_SYSINS(3,0,c12,c11,5) -#define ESR_SYSINSREG_ASGI1R_EL1 ESR_SYSINS(3,1,c12,c11,6) -#define ESR_SYSINSREG_SGI0R_EL1 ESR_SYSINS(3,2,c12,c11,7) -#define ESR_SYSINSREG_CNTPCT_EL0 ESR_SYSINS(3,3,c14,c0,0) -#define ESR_SYSINSREG_CNTP_TVAL_EL0 ESR_SYSINS(3,3,c14,c2,0) -#define ESR_SYSINSREG_CNTP_CTL_EL0 ESR_SYSINS(3,3,c14,c2,1) -#define ESR_SYSINSREG_CNTP_CVAL_EL0 ESR_SYSINS(3,3,c14,c2,2) +#define ESR_SYSINSREG_SGI1R_EL1 ESR_SYSINS(3,0,c12,c11,5) +#define ESR_SYSINSREG_ASGI1R_EL1 ESR_SYSINS(3,1,c12,c11,6) +#define ESR_SYSINSREG_SGI0R_EL1 ESR_SYSINS(3,2,c12,c11,7) +#define ESR_SYSINSERG_CTLR_EL1 ESR_SYSINS(3,0,c12,c12,4) +#define ESR_SYSINSREG_CNTPCT_EL0 ESR_SYSINS(3,3,c14,c0,0) +#define ESR_SYSINSREG_CNTP_TVAL_EL0 ESR_SYSINS(3,3,c14,c2,0) +#define ESR_SYSINSREG_CNTP_CTL_EL0 ESR_SYSINS(3,3,c14,c2,1) +#define ESR_SYSINSREG_CNTP_CVAL_EL0 ESR_SYSINS(3,3,c14,c2,2) /* Emulate ASM UBFX operation*/ @@ -118,36 +120,36 @@ #define ASM_UBFX(start, width, src) ((ASM_MASK_BIT(start, width) & src)>>start) -/* below value is caculated from vcpu_sysreg on '../arm64/kvm_host.h' -for the base value with 149 */ -#define VCPU_SYS_REG_NUM (126) -#define VCPU_MPIDR_EL1 (1) -#define VCPU_CSSELR_EL1 (2) -#define VCPU_SCTLR_EL1 (3) -#define VCPU_ACTLR_EL1 (4) -#define VCPU_CPACR_EL1 (5) -#define VCPU_TTBR0_EL1 (6) -#define VCPU_TTBR1_EL1 (7) -#define VCPU_TCR_EL1 (8) -#define VCPU_ESR_EL1 (10) -#define VCPU_AFSR0_EL1 (11) -#define VCPU_AFSR1_EL1 (12) -#define VCPU_FAR_EL1 (13) -#define VCPU_MAIR_EL1 (14) -#define VCPU_VBAR_EL1 (15) -#define VCPU_CONTEXTIDR_EL1 (16) -#define VCPU_TPIDR_EL0 (17) -#define VCPU_TPIDRRO_EL0 (18) -#define VCPU_TPIDR_EL1 (19) -#define VCPU_AMAIR_EL1 (20) -#define VCPU_CNTKCTL_EL1 (21) -#define VCPU_PAR_EL1 (22) -#define VCPU_MDSCR_EL1 (23) -#define VCPU_DISR_EL1 (25) -#define VCPU_ELR_EL1 (106) -#define VCPU_SP_EL1 (107) -#define VCPU_SPSR_EL1 (108) -#define VCPU_VPIDR (125) +enum { + VCPU_MPIDR_EL1, + VCPU_CSSELR_EL1, + VCPU_SCTLR_EL1, + VCPU_ACTLR_EL1, + VCPU_CPACR_EL1, + VCPU_TTBR0_EL1, + VCPU_TTBR1_EL1, + VCPU_TCR_EL1, + VCPU_ESR_EL1, + VCPU_AFSR0_EL1, + VCPU_AFSR1_EL1, + VCPU_FAR_EL1, + VCPU_MAIR_EL1, + VCPU_VBAR_EL1, + VCPU_CONTEXTIDR_EL1, + VCPU_TPIDR_EL0, + VCPU_TPIDRRO_EL0, + VCPU_TPIDR_EL1, + VCPU_AMAIR_EL1, + VCPU_CNTKCTL_EL1, + VCPU_PAR_EL1, + VCPU_MDSCR_EL1, + VCPU_DISR_EL1, + VCPU_ELR_EL1, + VCPU_SP_EL1, + VCPU_SPSR_EL1, + VCPU_VPIDR, + VCPU_SYS_REG_NUM +}; #define DEFAULT_VCPU (0) #define DEFAULT_PCPU (1) @@ -210,17 +212,27 @@ typedef struct vcpu_arch vcpu_arch_t; extern void *_vector_table[]; extern void _hyp_vector_table(void); +void arch_vcpu_context_save(struct vcpu *vcpu); +void arch_vcpu_context_load(struct vcpu *vcpu); + /** - * @brief Check if ZVM supports ARM64. + * @brief Load guest system register. +*/ +void switch_to_guest_sysreg(struct vcpu *vcpu); + +/** + * @brief switch_to_host_sysreg aim to save guest sysreg before exit. */ -int zvm_arch_init(void *op); +void switch_to_host_sysreg(struct vcpu *vcpu); /** * @brief init vcpu arch related struct here. */ int arch_vcpu_init(struct vcpu *vcpu); -void arch_vcpu_context_save(struct vcpu *vcpu); -void arch_vcpu_context_load(struct vcpu *vcpu); +/** + * @brief Check if ZVM supports ARM64. + */ +int zvm_arch_init(void *op); #endif /*ZEPHYR_INCLUDE_ZVM_ARM_CPU_H_*/ diff --git a/include/virtualization/arm/cpu_irq.h b/include/virtualization/arm/cpu_irq.h new file mode 100644 index 0000000000000000000000000000000000000000..d157fce3f46c478f522e2ec2473bb07334996e60 --- /dev/null +++ b/include/virtualization/arm/cpu_irq.h @@ -0,0 +1,14 @@ +/* + * Copyright 2022-2023 HNU + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZVM_ARM_CPU_IRQ_H_ +#define ZEPHYR_INCLUDE_ZVM_ARM_CPU_IRQ_H_ + +#include + +bool arch_irq_ispending(struct vcpu *vcpu); + +#endif /* ZEPHYR_INCLUDE_ZVM_ARM_CPU_IRQ_H_ */ \ No newline at end of file diff --git a/include/virtualization/arm/switch.h b/include/virtualization/arm/switch.h index db0b90df4b016421366e099a6952756fc75d2955..4ef5e8878e4310b279f30f245b133b0ced68b858 100644 --- a/include/virtualization/arm/switch.h +++ b/include/virtualization/arm/switch.h @@ -26,9 +26,13 @@ void get_zvm_host_context(void); int arch_vcpu_run(struct vcpu *vcpu); /** - * @brief Avoid switch handle when current thread is a vcpu thread. + * @brief Avoid switch handle when current thread is a vcpu thread, + * and curretn irq is send to vcpu. + * @retval + * true: this irq is sent to vcpu. + * false: this irq is a normal irq. */ -void z_vm_switch_handle_pre(uint32_t irq); +bool zvm_switch_handle_pre(uint32_t irq); #endif /* ZEPHYR_INCLUDE_ZVM_ARM_SWITCH_H__ */ diff --git a/include/virtualization/arm/sysreg.h b/include/virtualization/arm/sysreg.h deleted file mode 100644 index ef51ae48c0479b3f80c0e40e3f575aff624d13a9..0000000000000000000000000000000000000000 --- a/include/virtualization/arm/sysreg.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2021-2022 HNU - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_ZVM_ARM_SYSREG_H__ -#define ZEPHYR_INCLUDE_ZVM_ARM_SYSREG_H__ - -#include -#include - -/** - * @brief vcpu_sysreg_loads_vhe - Load guest system registers to the physical CPU. - */ -void vcpu_sysreg_load(struct vcpu *vcpu); - -/** - * @brief store system register to vcpu struct for keeping the VM state. - */ -void vcpu_sysreg_save(struct vcpu *vcpu); - -/** - * @brief Load guest system register. -*/ -void switch_to_guest_sysreg(struct vcpu *vcpu); - -/** - * @brief switch_to_host_sysreg aim to save guest sysreg before exit. - */ -void switch_to_host_sysreg(struct vcpu *vcpu); - -#endif /* ZEPHYR_INCLUDE_ZVM_ARM_SYSREG_H__ */ diff --git a/include/virtualization/arm/trap_handler.h b/include/virtualization/arm/trap_handler.h index 75b29f156ef8b7e1c2634cd645bdc1b64a32577c..83daa863d3e6058f4e4a89d189621496e09f9917 100644 --- a/include/virtualization/arm/trap_handler.h +++ b/include/virtualization/arm/trap_handler.h @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 HNU + * Copyright 2021-2022 HNU-ESNL * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,8 +16,6 @@ #define VM_PPI_VIRQ_NR (16) #define VM_SPI_VIRQ_NR (256 - VM_SGI_VIRQ_NR - VM_PPI_VIRQ_NR) -#define AARCH64_INST_ADJUST (0x04) - /* HPFAR_EL2 addr mask */ #define HPFAR_EL2_MASK GENMASK(39,4) #define HPFAR_EL2_SHIFT (4) @@ -55,7 +53,7 @@ struct esr_sysreg_area { uint64_t op1 :3; /* Op1 */ uint64_t op2 :3; /* Op2 */ uint64_t op0 :2; /* Op0 */ - uint64_t res0 :3; /* reserved file */ + uint64_t res0 :3; /* reserved file */ uint64_t il :1; /* Instruction length */ uint64_t ec :6; /* Exception Class */ }; diff --git a/include/virtualization/vdev/vgic_common.h b/include/virtualization/vdev/vgic_common.h index 65675a74b8219b171be35067f0b86eaaf77b68c2..50e51b1ae4bd95ebc97a38f95436cf909dc00999 100644 --- a/include/virtualization/vdev/vgic_common.h +++ b/include/virtualization/vdev/vgic_common.h @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include struct virt_dev; @@ -19,8 +21,8 @@ struct virt_dev; #define VGIC_CONTROL_BLOCK_NAME vm_irq_control_block /* GIC version */ -#define VGIC_V2 BIT(0) -#define VGIC_V3 BIT(8) +#define VGIC_V2 BIT(0) +#define VGIC_V3 BIT(8) /* GIC dev type */ #define TYPE_GIC_GICD BIT(0) @@ -36,10 +38,14 @@ struct virt_dev; #define VGIC_RDIST_SIZE DT_REG_SIZE_BY_IDX(DT_INST(0, arm_gic), 1) /* GICD registers offset from DIST_base(n) */ -#define VGICD_CTLR 0x0000 -#define VGICD_TYPER 0x0004 -#define VGICD_IIDR 0x0008 -#define VGICD_STATUSR 0x0010 +#define VGICD_CTLR (GICD_CTLR-GIC_DIST_BASE) +#define VGICD_TYPER (GICD_TYPER-GIC_DIST_BASE) +#define VGICD_IIDR (GICD_IIDR-GIC_DIST_BASE) +#define VGICD_STATUSR (GICD_STATUSR-GIC_DIST_BASE) +#define VGICD_ISENABLERn (GICD_ISENABLERn-GIC_DIST_BASE) +#define VGICD_ICENABLERn (GICD_ICENABLERn-GIC_DIST_BASE) +#define VGICD_ISPENDRn (GICD_ISPENDRn-GIC_DIST_BASE) +#define VGICD_ICPENDRn (GICD_ICPENDRn-GIC_DIST_BASE) #define VGIC_RESERVED 0x0F30 #define VGIC_INMIRn 0x0f80 @@ -69,12 +75,18 @@ struct virt_dev; #define vgic_sysreg_read64(data, base, offset) sys_read64(data, (long unsigned int)(base+((offset)/4))) #define vgic_sysreg_write64(data, base, offset) sys_write64(data, (long unsigned int)(base+((offset)/4))) +#define DEFAULT_DISABLE_IRQVAL (0xFFFFFFFF) + /** * @brief Virtual generatic interrupt controller distributor * struct for each vm. */ struct virt_gic_gicd { - /* gicd address base and size */ + /** + * gicd address base and size which + * are used to locate vdev access from + * vm. + */ uint32_t gicd_base; uint32_t gicd_size; /* virtual gicr for emulating device for vm. */ @@ -116,13 +128,9 @@ __subsystem struct vm_irq_handler_api { vm_irq_enter_t irq_enter_to_vm; }; -void z_ready_thread(struct k_thread *thread); +uint32_t *arm_gic_get_distbase(struct virt_dev *vdev); -/** - * @brief test and set vgic bits. - */ -void vgic_irq_test_and_set_bit(struct vcpu *vcpu, uint32_t spi_nr_count, uint32_t *value, - uint32_t bit_size, bool enable); +void z_ready_thread(struct k_thread *thread); /** * @brief Just for enable menopoly irq for vcpu. @@ -149,9 +157,7 @@ int set_virq_to_vcpu(struct vcpu *vcpu, uint32_t virq_num); */ int set_virq_to_vm(struct vm *vm, uint32_t virq_num); - int virt_irq_sync_vgic(struct vcpu *vcpu); - int virt_irq_flush_vgic(struct vcpu *vcpu); /** @@ -159,11 +165,6 @@ int virt_irq_flush_vgic(struct vcpu *vcpu); */ struct virt_irq_desc *get_virt_irq_desc(struct vcpu *vcpu, uint32_t virq); -/** - * @brief Create vm's interrupt controller. - */ -int vm_intctrl_vdev_create(struct vm *vm); - /** * @brief When vcpu is loop on idel mode, we must send virq * to activate it. @@ -194,4 +195,86 @@ static ALWAYS_INLINE bool is_vm_irq_valid(struct vm *vm, uint32_t flag) return true; } +static ALWAYS_INLINE struct virt_irq_desc *vgic_get_virt_irq_desc(struct vcpu *vcpu, uint32_t virq) +{ + struct vm *vm = vcpu->vm; + + /* sgi virq num */ + if (virq < VM_LOCAL_VIRQ_NR) { + return &vcpu->virq_block.vcpu_virt_irq_desc[virq]; + } + + /* spi virq num */ + if((virq >= VM_LOCAL_VIRQ_NR) && (virq < VM_GLOBAL_VIRQ_NR)) { + return &vm->vm_irq_block.vm_virt_irq_desc[virq - VM_LOCAL_VIRQ_NR]; + } + + return NULL; +} + +static ALWAYS_INLINE int vgic_irq_enable(struct vcpu *vcpu, uint32_t virt_irq) +{ + struct virt_irq_desc *desc; + + desc = vgic_get_virt_irq_desc(vcpu, virt_irq); + if (!desc) { + return -ENOENT; + } + desc->virq_flags |= VIRQ_ENABLED_FLAG; + if (virt_irq > VM_LOCAL_VIRQ_NR) { + if (desc->virq_flags & VIRQ_HW_FLAG) { + if (desc->pirq_num > VM_LOCAL_VIRQ_NR) + irq_enable(desc->pirq_num); + else { + return -ENODEV; + } + } + } else { + if(desc->virq_flags & VIRQ_HW_FLAG) { + irq_enable(virt_irq); + } + } + return 0; +} + +static ALWAYS_INLINE int vgic_irq_disable(struct vcpu *vcpu, uint32_t virt_irq) +{ + struct virt_irq_desc *desc; + + desc = vgic_get_virt_irq_desc(vcpu, virt_irq); + if (!desc) { + return -ENOENT; + } + desc->virq_flags &= ~VIRQ_ENABLED_FLAG; + if (virt_irq > VM_LOCAL_VIRQ_NR) { + if (desc->virq_flags & VIRQ_HW_FLAG) { + if (desc->pirq_num > VM_LOCAL_VIRQ_NR) { + irq_disable(desc->pirq_num); + } else { + return -ENODEV; + } + } + } else { + if(desc->virq_flags & VIRQ_HW_FLAG) { + irq_disable(virt_irq); + } + } + return 0; +} + +static ALWAYS_INLINE bool vgic_irq_test_bit(struct vcpu *vcpu, uint32_t spi_nr_count, + uint32_t *value, uint32_t bit_size, bool enable) +{ + ARG_UNUSED(enable); + ARG_UNUSED(spi_nr_count); + int bit; + uint32_t reg_mem_addr = (uint64_t)value; + for (bit=0; bit #include #include +#include "../../../drivers/interrupt_controller/intc_gicv3_priv.h" /* SGI mode */ -#define SGI_SIG_TO_LIST (0) -#define SGI_SIG_TO_OTHERS (1) +#define SGI_SIG_TO_LIST (0) +#define SGI_SIG_TO_OTHERS (1) /* vgic macro here */ -#define VGIC_MAX_VCPU 64 -#define VGIC_UNDEFINE_ADDR 0xFFFFFFFF +#define VGIC_MAX_VCPU 64 +#define VGIC_UNDEFINE_ADDR 0xFFFFFFFF /* vgic action */ #define ACTION_CLEAR_VIRQ BIT(0) @@ -52,13 +53,13 @@ #define LIST_REG_HW_VIRQ (1) /* GICR registers offset from RDIST_base(n) */ -#define VGICR_CTLR 0x0000 -#define VGICR_IIDR 0x0004 -#define VGICR_TYPER 0x0008 -#define VGICR_STATUSR 0x0010 -#define VGICR_WAKER 0x0014 -#define VGICR_PROPBASER 0x0070 -#define VGICR_PENDBASER 0x0078 +#define VGICR_CTLR GICR_CTLR +#define VGICR_IIDR GICR_IIDR +#define VGICR_TYPER GICR_TYPER +#define VGICR_STATUSR GICR_STATUSR +#define VGICR_WAKER GICR_WAKER +#define VGICR_PROPBASER GICR_PROPBASER +#define VGICR_PENDBASER GICR_PENDBASER #define VGICR_ISENABLER0 0x0100 #define VGICR_ICENABLER0 0x0180 #define VGICR_SGI_PENDING 0x0200 @@ -137,7 +138,11 @@ struct virt_gic_gicr { uint32_t *gicr_rd_reg_base; uint32_t *gicr_sgi_reg_base; - /* vm's physical gicr address. */ + /** + * gicr address base and size which + * are used to locate vdev access from + * vm. + */ uint32_t gicr_rd_base; uint32_t gicr_sgi_base; uint32_t gicr_rd_size; @@ -224,6 +229,51 @@ int vgicv3_raise_sgi(struct vcpu *vcpu, unsigned long sgi_value); */ struct vgicv3_dev *vgicv3_dev_init(struct vm *vm); +/** + * @brief When VMs enable or disable register, zvm will test + * related bit and set it to correct value. This function is used + * for irq enable or disable flag; +*/ +static ALWAYS_INLINE void vgic_test_and_set_enable_bit(struct vcpu *vcpu, uint32_t spi_nr_count, + uint32_t *value, uint32_t bit_size, bool enable, void *vgic_priv) +{ + int bit; + uint32_t reg_mem_addr = (uint64_t)value; + struct virt_gic_gicd *gicd = NULL; + struct virt_gic_gicr *gicr = NULL; + + for (bit=0; bitgicr_sgi_reg_base, VGICR_ISENABLER0) | BIT(bit),\ + gicr->gicr_sgi_reg_base, VGICR_ISENABLER0); + }else{ + gicd = (struct virt_gic_gicd *)vgic_priv; + vgic_sysreg_write32(vgic_sysreg_read32(gicd->gicd_regs_base, VGICD_ISENABLERn) | BIT(bit),\ + gicd->gicd_regs_base, VGICD_ISENABLERn); + } + } else { + /* TODO: add a situation for disable irq interrupt later */ + if (*value != DEFAULT_DISABLE_IRQVAL) { + vgic_irq_disable(vcpu, spi_nr_count + bit); + } + if(spi_nr_count < VM_LOCAL_VIRQ_NR){ + gicr = (struct virt_gic_gicr *)vgic_priv; + vgic_sysreg_write32(vgic_sysreg_read32(gicr->gicr_sgi_reg_base, VGICR_ICENABLER0) & ~BIT(bit),\ + gicr->gicr_sgi_reg_base, VGICR_ICENABLER0); + }else{ + gicd = (struct virt_gic_gicd *)vgic_priv; + vgic_sysreg_write32(vgic_sysreg_read32(gicd->gicd_regs_base, VGICD_ICENABLERn) | ~BIT(bit),\ + gicd->gicd_regs_base, VGICD_ICENABLERn); + } + } + } + } +} + static ALWAYS_INLINE uint64_t gicv3_read_lr(uint8_t register_id) { switch (register_id) { diff --git a/include/virtualization/vdev/virt_clock_syscon.h b/include/virtualization/vdev/virt_clock_syscon.h new file mode 100644 index 0000000000000000000000000000000000000000..03805a6a71fe28c5fe5333a27b1e15d657a7e222 --- /dev/null +++ b/include/virtualization/vdev/virt_clock_syscon.h @@ -0,0 +1,35 @@ +/* + * Copyright 2023-2024 HNU-ESNL + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_VIRTUALIZATION_VDEV_VIRT_CLOCK_SYSCON_H_ +#define ZEPHYR_INCLUDE_VIRTUALIZATION_VDEV_VIRT_CLOCK_SYSCON_H_ + +#include +#include +#include +#include + + +/* The clock syscon node */ +struct virt_clk_syscon { + const char *name; + + uint32_t reg_base; + uint32_t reg_size; + void *clk_syscon; + + sys_dnode_t clk_node; +}; + +/* The clock syscon list */ +struct virt_clk_syscon_list { + struct k_spinlock vclk_lock; + + uint16_t clk_num; + sys_dlist_t clk_syscon_list; +}; + +#endif /* ZEPHYR_INCLUDE_VIRTUALIZATION_VDEV_VIRT_CLOCK_SYSCON_H_ */ diff --git a/include/virtualization/vdev/virt_device.h b/include/virtualization/vdev/virt_device.h index 59901352d20af9e61180a8a9d985800255beae57..cda0aa8b3ad99b5e0a7c140abb864b308a510d3a 100644 --- a/include/virtualization/vdev/virt_device.h +++ b/include/virtualization/vdev/virt_device.h @@ -17,10 +17,21 @@ #define VM_DEVICE_INVALID_BASE (0xFFFFFFFF) #define VM_DEVICE_INVALID_VIRQ (0xFF) +/** + * @brief DEVICE_TYPE for each vm, whcih is used to + * judge whether it is nesscary to init when vm creat. +*/ +#define VM_DEVICE_PRE_KERNEL_1 (0x01) + typedef void (*virt_device_irq_callback_user_data_set_t)(const struct device *dev, void *cb, void *user_data); +/** + * @brief Get private date for vm. +*/ struct virt_device_data { + /* virtual device types for vm, can be seen in macro 'DEVICE_TYPE'. */ + uint16_t vdevice_type; /* Get the virt device data port*/ void *device_data; #ifdef CONFIG_VIRT_DEVICE_INTERRUPT_DRIVEN @@ -58,6 +69,64 @@ struct virt_device_api { const void *device_driver_api; }; +/** + * @brief Virtual devices backend instance in zvm. +*/ +struct virtual_device_instance { + const char *name; + struct virt_device_data *data; + struct virt_device_config *cfg; + const struct virt_device_api *api; +}; + +/* The overall virtual devices instances. */ +extern const struct virtual_device_instance __virtual_device_instances_start[]; +extern const struct virtual_device_instance __virtual_device_instances_end[]; + +/** + * @brief Macro for creating a virtual device instance. + * + * @param _init_fn Init function for virtual device. + * @param _level Init level. + * @param _prio Init priority. + * @param _name Name of the virtual device instance. + * @param _data Date of the virtual device instance. + * @param _cfg Configuration of virtual device. + * @param _api Virtual device backend API. + * @param ... Optional context. + */ +#define ZVM_VIRTUAL_DEVICE_DEFINE(_init_fn, _level, _prio, _name, _data, _cfg, _api, ...) \ + Z_INIT_ENTRY_DEFINE(Z_SYS_NAME(_init_fn), _init_fn, NULL, _level, _prio); \ + static const STRUCT_SECTION_ITERABLE(virtual_device_instance, _name) = \ + { \ + .name = STRINGIFY(_name), \ + .data = &_data, \ + .cfg = &_cfg, \ + .api = &_api, \ + } + +/** + * @brief Get virtual device. + * + * @param[in] idx Pointer to the virtual device instance. + * + * @return Pointer to the virtual device instance. + */ +static inline const struct virtual_device_instance *zvm_virtual_device_get(uint32_t idx) +{ + return &__virtual_device_instances_start[idx]; +} + +/** + * @brief Get number of virtual devices. + * + * @return Number of virtual devices. +*/ +static inline int zvm_virtual_devices_count_get(void) +{ + return __virtual_device_instances_end - __virtual_device_instances_start; +} + /** * @brief Set the IRQ callback function pointer. * diff --git a/include/virtualization/vm.h b/include/virtualization/vm.h index 0c51a332b25907f0fb96605ce52ae023d1443a9a..fbd367640c3013c15252010ef59c6b745b65a6c3 100644 --- a/include/virtualization/vm.h +++ b/include/virtualization/vm.h @@ -213,7 +213,7 @@ int vm_mem_init(struct vm *vm); int vm_vcpus_create(uint16_t vcpu_num, struct vm *vm); int vm_vcpus_init(struct vm *vm); -int vm_vcpus_run(struct vm *vm); +int vm_vcpus_ready(struct vm *vm); int vm_vcpus_pause(struct vm *vm); int vm_vcpus_halt(struct vm *vm); int vm_delete(struct vm *vm); diff --git a/include/virtualization/vm_cpu.h b/include/virtualization/vm_cpu.h index bbc99bd6427dcf17fe50312aa09f10e3ec3e85b9..920479e0d66aa57923a52d07de9d8fa82c075673 100644 --- a/include/virtualization/vm_cpu.h +++ b/include/virtualization/vm_cpu.h @@ -11,6 +11,14 @@ #include #include #include +#ifdef CONFIG_ARM64 +#include +#include +#include +#include +#include +#include +#endif #ifdef CONFIG_PREEMPT_ENABLED /* positive num */ @@ -33,18 +41,19 @@ struct vcpu; struct vcpu *vm_vcpu_init(struct vm *vm, uint16_t vcpu_id, char *vcpu_name); /** - * @brief start the vcpu instance. - */ -int vm_vcpu_run(struct vcpu *vcpu); + * @brief the vcpu has below state: + * running: vcpu is running, and is allocated to physical cpu. + * ready: prepare to running. +*/ +int vm_vcpu_ready(struct vcpu *vcpu); int vm_vcpu_pause(struct vcpu *vcpu); int vm_vcpu_halt(struct vcpu *vcpu); /** * @brief vcpu run func entry. */ -int z_vcpu_run(struct vcpu *vcpu); +int vcpu_thread_entry(struct vcpu *vcpu); -int vcpu_irq_exit(struct vcpu *vcpu); int vcpu_state_switch(struct k_thread *thread, uint16_t new_state); void do_vcpu_swap(struct k_thread *new_thread, struct k_thread *old_thread); diff --git a/include/virtualization/vm_dev.h b/include/virtualization/vm_dev.h index a8868ada3933478958afcdf9c011e08f0d50b47c..2044364750f15229284e80f0ae54524f8b7e99d4 100644 --- a/include/virtualization/vm_dev.h +++ b/include/virtualization/vm_dev.h @@ -15,13 +15,15 @@ #include #include -#define VIRT_DEV_NAME_LENGTH (32) -#define VIRT_DEV_TYPE_LENGTH (32) +#define VIRT_DEV_NAME_LENGTH (32) +#define VIRT_DEV_TYPE_LENGTH (32) #define DEV_TYPE_EMULATE_ALL_DEVICE (0x01) #define DEV_TYPE_VIRTIO_DEVICE (0x02) #define DEV_TYPE_PASSTHROUGH_DEVICE (0x03) +#define TOSTRING(x) STRINGIFY(x) + struct virt_dev { /* name of virtual device */ char name[VIRT_DEV_NAME_LENGTH]; @@ -29,7 +31,7 @@ struct virt_dev { /* Is this dev pass-through device? */ bool dev_pt_flag; /* Is this dev virtio device?*/ - bool shareable; + bool shareable; uint32_t hirq; uint32_t virq; @@ -40,12 +42,14 @@ struct virt_dev { struct _dnode vdev_node; struct vm *vm; + /** * Device private data may be usefull, - * For full virtual device, it may store the emulated device private data. - * For passthrough, it store the hardware instance data. + * 1. For full virtual device, it store the emulated device's driver, + * for example: virt_device instance. + * 2. For passthrough device, it store the hardware instance data. */ - void *priv_data; + const void *priv_data; /** * Binding to full virtual device driver. diff --git a/include/virtualization/vm_irq.h b/include/virtualization/vm_irq.h index 1149ccfdef17abcc44029b1339ccc795de498d7b..c1401ee5eb512765d69f86b82cb3176152302a05 100644 --- a/include/virtualization/vm_irq.h +++ b/include/virtualization/vm_irq.h @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include /** @@ -30,7 +32,6 @@ #define VIRQ_ACTIVED_FLAG BIT(2) #define VIRQ_ENABLED_FLAG BIT(3) #define VIRQ_WAKEUP_FLAG BIT(4) -#define VIRQ_NOUSED_FLAG BIT(5) /* Hardware irq states */ #define VIRQ_STATE_INVALID (0b00) @@ -49,7 +50,6 @@ #define VM_GLOBAL_VIRQ_NR (VM_LOCAL_VIRQ_NR + VM_SPI_VIRQ_NR) struct vm; -struct vcpu; struct virt_dev; /** @@ -83,6 +83,14 @@ struct virt_irq_desc { sys_dnode_t desc_node; }; +/* vcpu wfi struct */ +struct vcpu_wfi { + bool state; + uint16_t yeild_count; + struct k_spinlock wfi_lock; + void *priv; +}; + /** * @brief vm's irq block to describe this all the device interrup * for vm. In this struct, it called `VM_LOCAL_VIRQ_NR`; @@ -96,6 +104,7 @@ struct vcpu_virt_irq_block { uint32_t virq_pending_counts; struct virt_irq_desc vcpu_virt_irq_desc[VM_LOCAL_VIRQ_NR]; + struct vcpu_wfi vwfi; struct k_spinlock spinlock; @@ -120,6 +129,9 @@ struct vm_virt_irq_block { uint32_t irq_target[VM_GLOBAL_VIRQ_NR]; uint32_t ipi_vcpu_source[CONFIG_MP_NUM_CPUS][VM_SGI_VIRQ_NR]; + /* virtual irq block. */ + struct k_spinlock vm_virq_lock; + /* desc for this vm */ struct virt_irq_desc vm_virt_irq_desc[VM_GLOBAL_VIRQ_NR-VM_LOCAL_VIRQ_NR]; @@ -127,6 +139,10 @@ struct vm_virt_irq_block { void *virt_priv_date; }; +bool vcpu_irq_exist(struct vcpu *vcpu); + +int vcpu_wait_for_irq(struct vcpu *vcpu); + /** * @brief init the irq desc when add @vm_dev. */ diff --git a/include/virtualization/zvm.h b/include/virtualization/zvm.h index b311b7c23ec3cdf5c36eb1dbf13dde586ee6f2e5..981f54a9159f3d1972045fe4bdfee72ba12b94ba 100644 --- a/include/virtualization/zvm.h +++ b/include/virtualization/zvm.h @@ -114,7 +114,7 @@ do {\ lock->locked = 0x0; \ }) #else -#define ZVM_SPINLOCK_INIT(dev) (dev = NULL) +#define ZVM_SPINLOCK_INIT(dev) #endif extern struct z_kernel _kernel; diff --git a/kernel/sched.c b/kernel/sched.c index 279551b5ac3d1d88d21523324bfd323ac2b61301..445497d6456ec01162e3484f76985af1b8a3a196 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -1006,18 +1006,13 @@ void *z_get_next_switch_handle(void *interrupted) return ret; #else #ifdef CONFIG_ZVM - if(vcpu_need_switch(new_thread, old_thread)){ - do_vcpu_swap(new_thread, old_thread); + if(vcpu_need_switch(_kernel.ready_q.cache, _current)){ + do_vcpu_swap(_kernel.ready_q.cache, _current); } #endif /* CONFIG_ZVM */ z_sched_usage_switch(_kernel.ready_q.cache); _current->switch_handle = interrupted; set_current(_kernel.ready_q.cache); -#ifdef CONFIG_ZVM - if(vcpu_need_switch(new_thread, old_thread)){ - do_vcpu_swap(new_thread, old_thread); - } -#endif /* CONFIG_ZVM */ return _current->switch_handle; #endif } diff --git a/samples/_zvm/boards/qemu_cortex_max.conf b/samples/_zvm/boards/qemu_cortex_max.conf new file mode 100644 index 0000000000000000000000000000000000000000..adac4b289f1b82d95354fc38a224aed65cb0931b --- /dev/null +++ b/samples/_zvm/boards/qemu_cortex_max.conf @@ -0,0 +1,32 @@ +# Project configuration +# Copyright 2021-2022 HNU + +#ARMV8 NO-SECURE MODE +CONFIG_ARMV8_A_NS=y + +# kernel vm size(16M virt ram start + size) +# It is the virt size of kernel, must bigger than true kernel size. +#CONFIG_KERNEL_VM_SIZE=0xb0c00000 +CONFIG_KERNEL_VM_SIZE=0x20000000 + +# uart +CONFIG_UART_PL011_PORT1=n + +# vgic device. +CONFIG_VM_VGICV3=y + +# vuart device. +CONFIG_VM_SERIAL1=y +CONFIG_VM_SERIAL2=y + +# make more table for vm's pgd +CONFIG_ZVM_ZEPHYR_MAX_XLAT_TABLES=512 +CONFIG_ZVM_LINUX_MAX_XLAT_TABLES=8192 + +# heap size of zephyr +# CONFIG_HEAP_MEM_POOL_SIZE=1610612736 + +# enable vm device below: +CONFIG_VM_VIRTIO_MMIO=y +CONFIG_VM_VIRTIO_BLOCK=y + diff --git a/samples/_zvm/boards/qemu_cortex_max.overlay b/samples/_zvm/boards/qemu_cortex_max.overlay new file mode 100644 index 0000000000000000000000000000000000000000..a03920a30fdec599b9cf5c4121dea39ce7082b7b --- /dev/null +++ b/samples/_zvm/boards/qemu_cortex_max.overlay @@ -0,0 +1,229 @@ +/* + * Copyright 2021-2022 HNU + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/{ + aliases { + vmserial1 = "/soc/uart@9001000"; + vmserial2 = "/soc/uart@9002000"; + vmplatform = "/soc/platform@c000000"; + vmfw = "/soc/fw-cfg@9020000"; + vmvirtio1 = "/soc/virtio_mmio@a000000"; + vmvirtio2 = "/soc/virtio_mmio@a000200"; + vmvirtio3 = "/soc/virtio_mmio@a000400"; + vmvirtio4 = "/soc/virtio_mmio@a000600"; + vmvirtio5 = "/soc/virtio_mmio@a000800"; + vmvirtio6 = "/soc/virtio_mmio@a000a00"; + vmvirtio7 = "/soc/virtio_mmio@a000c00"; + vmvirtio8 = "/soc/virtio_mmio@a000e00"; + vmvirtio9 = "/soc/virtio_mmio@a001000"; + vmvirtio10 = "/soc/virtio_mmio@a001200"; + vmgpioctrl = "/soc/pl061@9030000"; +// vmpcie = "/soc/pcie@10000000"; + vmrtc = "/soc/pl031@9010000"; + vmpmu = "/soc/pmu"; + vmflash = "/soc/flash@0"; + }; + + chosen { + vm,console = &uart0; + }; + + soc { + + uart1: uart@9001000 { + compatible = "arm,pl011"; + reg = <0x00 0x09001000 0x00 0x1000>; + interrupts = ; + interrupt-names = "irq_0"; + clocks = <&uartclk>; + status = "reserved"; + current-speed = <115200>; + label = "UART_1"; + }; + + uart2: uart@9002000 { + compatible = "arm,pl011"; + reg = <0x00 0x09002000 0x00 0x1000>; + interrupts = ; + interrupt-names = "irq_0"; + clocks = <&uartclk>; + status = "reserved"; + current-speed = <115200>; + label = "UART_2"; + }; + + platform@c000000 { + interrupt-parent = <0x8005>; + ranges = <0x00 0x00 0xc000000 0x2000000>; + #address-cells = <0x01>; + #size-cells = <0x01>; + compatible = "qemu,platform\0simple-bus"; + }; + + fw-cfg@9020000 { + dma-coherent; + reg = <0x00 0x9020000 0x00 0x18>; + compatible = "qemu,fw-cfg-mmio"; + }; + + virtio_mmio@a000000 { + interrupts = ; + reg = <0x00 0xa000000 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000200 { + interrupts = ; + reg = <0x00 0xa000200 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000400 { + interrupts = ; + reg = <0x00 0xa000400 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000600 { + interrupts = ; + reg = <0x00 0xa000600 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000800 { + interrupts = ; + reg = <0x00 0xa000800 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000a00 { + interrupts = ; + reg = <0x00 0xa000a00 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000c00 { + interrupts = ; + reg = <0x00 0xa000c00 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a000e00 { + interrupts = ; + reg = <0x00 0xa000e00 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a001000 { + interrupts = ; + reg = <0x00 0xa001000 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + virtio_mmio@a001200 { + interrupts = ; + reg = <0x00 0xa001200 0x00 0x1000>; + compatible = "virtio,mmio"; + device_type = "virtio"; + virtio_type = <2>; + }; + + pl061@9030000 { + phandle = <0x8007>; + clock-names = "apb_pclk"; + clocks = <0x8000>; + interrupts = ; + gpio-controller; + #gpio-cells = <0x02>; + compatible = "arm,pl061\0arm,primecell"; + reg = <0x00 0x9030000 0x00 0x1000>; + }; +/* + pcie@10000000 { + interrupt-map-mask = <0x1800 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x03 0x04 0x00 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x04 0x04 0x00 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x05 0x04 0x00 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x04 0x04 0x800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x05 0x04 0x800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x06 0x04 0x800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x05 0x04 0x1000 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x06 0x04 0x1000 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x03 0x04 0x1000 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x01 0x8005 0x00 0x00 0x00 0x06 0x04 0x1800 0x00 0x00 0x02 0x8005 0x00 0x00 0x00 0x03 0x04 0x1800 0x00 0x00 0x03 0x8005 0x00 0x00 0x00 0x04 0x04 0x1800 0x00 0x00 0x04 0x8005 0x00 0x00 0x00 0x05 0x04>; + #interrupt-cells = <0x01>; + ranges = <0x1000000 0x00 0x00 0x00 0x3eff0000 0x00 0x10000 0x2000000 0x00 0x10000000 0x00 0x10000000 0x00 0x2eff0000 0x3000000 0x80 0x00 0x80 0x00 0x80 0x00>; + reg = <0x40 0x10000000 0x00 0x10000000>; + msi-parent = <&gic_ist>; + dma-coherent; + bus-range = <0x00 0xff>; + linux,pci-domain = <0x00>; + #size-cells = <0x02>; + #address-cells = <0x03>; + device_type = "pci"; + compatible = "pci-host-ecam-generic"; + }; +*/ + pl031@9010000 { + clock-names = "apb_pclk"; + clocks = <0x8000>; + interrupts = ; + reg = <0x00 0x9010000 0x00 0x1000>; + compatible = "arm,pl031\0arm,primecell"; + }; + + pmu { + interrupts = ; + compatible = "arm,armv8-pmuv3"; + }; + + }; + + vm_zephyr_space { + #address-cells = <2>; + #size-cells = <2>; + compatible = "zephyr-vm"; + dtb_address = <0x49000000>; + dtb_size = ; + + zephyr_ddr: memory@f2000000 { + compatible = "vm-dram"; + memmap_type = "direct"; + address_type = "normal_memory"; + vm_reg_base = <0x40000000>; + vm_reg_size = ; + reg = <0x0 0xf2000000 0x0 DT_SIZE_M(1)>; + label = "VM0_MEM"; + }; + }; + + vm_linux_space { + #address-cells = <2>; + #size-cells = <2>; + compatible = "linux-vm"; + dtb_address = <0xf2a00000>; + dtb_size = ; + + linux_ddr: memory@f3000000 { + compatible = "vm-dram"; + memmap_type = "direct"; + address_type = "normal_memory"; + vm_reg_base = <0x40000000>; + vm_reg_size = ; + reg = <0x0 0xf3000000 0x0 DT_SIZE_M(240)>; + label = "VM1_MEM"; + }; + }; +}; diff --git a/samples/_zvm/boards/qemu_cortex_max_smp.overlay b/samples/_zvm/boards/qemu_cortex_max_smp.overlay index 752d0bc201cb02c39b6d1b9336720e8a42e4d1c3..b2fe94b703185c9a79ab4a36ad1a2f1e5dada11d 100644 --- a/samples/_zvm/boards/qemu_cortex_max_smp.overlay +++ b/samples/_zvm/boards/qemu_cortex_max_smp.overlay @@ -6,7 +6,6 @@ /{ aliases { - vmvgic = "/soc/vgic@8000000"; vmserial1 = "/soc/uart@9001000"; vmserial2 = "/soc/uart@9002000"; vmplatform = "/soc/platform@c000000"; @@ -33,14 +32,6 @@ }; soc { - - vgic: vgic@8000000 { - compatible = "arm,gic"; - reg = <0x00 0x8000000 0x00 0x010000>, - <0x00 0x80a0000 0x00 0xf60000>; - label = "VM_VGIC"; - }; - uart1: uart@9001000 { compatible = "arm,pl011"; reg = <0x00 0x09001000 0x00 0x1000>; diff --git a/samples/_zvm/boards/roc_rk3568_pc_smp.conf b/samples/_zvm/boards/roc_rk3568_pc_smp.conf index 4e6f1720132276598dc9eb4f461406d36e7b9442..28fc71d492ac2a831f5763bce936415cac28e2c7 100644 --- a/samples/_zvm/boards/roc_rk3568_pc_smp.conf +++ b/samples/_zvm/boards/roc_rk3568_pc_smp.conf @@ -18,6 +18,7 @@ CONFIG_VM_SERIAL2=y # fiq debugger CONFIG_VM_FIQ_DEBUGGER=y +CONFIG_VM_CLOCK_SYSTEM_CONTROLLER=y # make more table for vm's pgd CONFIG_ZVM_ZEPHYR_MAX_XLAT_TABLES=1024 diff --git a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay index 7986e1348a724cd71922a23d44e1f087f3443cc0..61ed110fbd0abae1b52732c53f4c5560ca518e91 100644 --- a/samples/_zvm/boards/roc_rk3568_pc_smp.overlay +++ b/samples/_zvm/boards/roc_rk3568_pc_smp.overlay @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 HNU + * Copyright 2021-2022 HNU-ESNL * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/samples/_zvm/prj.conf b/samples/_zvm/prj.conf index bbc839d58f3487cde205415282279a19d987a483..c56588ec8fe45b4e6b322456a6c5ef10e60c1e91 100644 --- a/samples/_zvm/prj.conf +++ b/samples/_zvm/prj.conf @@ -12,6 +12,10 @@ CONFIG_SHELL_THREAD_PRIORITY_OVERRIDE=y CONFIG_SHELL_THREAD_PRIORITY=4 CONFIG_SHELL_PROMPT_UART="zvm_host:~#" +#CPU MASK, this feature work only `CONFIG_SCHED_DUMB` is the selected +CONFIG_SCHED_CPU_MASK=y +CONFIG_SCHED_CPU_MASK_PIN_ONLY=y + # vm and vcpu configure CONFIG_MAX_VM_NUM=4 CONFIG_MAX_VCPU_PER_VM=2 @@ -20,20 +24,11 @@ CONFIG_MAX_VCPU_PER_VM=2 CONFIG_MINIMAL_LIBC_RAND=y CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=8192 -# SMP -CONFIG_SMP=y -CONFIG_MP_NUM_CPUS=4 -#CPU MASK, this feature work only `CONFIG_SCHED_DUMB` is the selected -CONFIG_SCHED_CPU_MASK=y -CONFIG_SCHED_DEADLINE=y -CONFIG_SCHED_CPU_MASK_PIN_ONLY=y - # Enable Console CONFIG_CONSOLE=y CONFIG_CONSOLE_SUBSYS=y CONFIG_CONSOLE_GETLINE=y CONFIG_UART_CONSOLE=y -CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN=n # If disable, system will always be interrupted by # periodic shell timeout. @@ -54,6 +49,7 @@ CONFIG_NUM_PREEMPT_PRIORITIES=15 # timer CONFIG_TIMING_FUNCTIONS=y +CONFIG_SCHED_DEADLINE=y CONFIG_THREAD_STACK_INFO=y CONFIG_KOBJECT_TEXT_AREA=4096 diff --git a/soc/arm64/rockchip/rk3568/mmu_regions.c b/soc/arm64/rockchip/rk3568/mmu_regions.c index 4fa7d6f4c9296f9d7b6e6bccfdb500395bb62c21..b21c8f67e82ec7e959bf91cc88ea6f0b2b1b6442 100644 --- a/soc/arm64/rockchip/rk3568/mmu_regions.c +++ b/soc/arm64/rockchip/rk3568/mmu_regions.c @@ -36,6 +36,16 @@ static const struct arm_mmu_region mmu_regions[] = { DT_REG_ADDR(DT_NODELABEL(uart9)), DT_REG_SIZE(DT_NODELABEL(uart9)), MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("PMCRU", + DT_REG_ADDR(DT_NODELABEL(pmucru)), + DT_REG_SIZE(DT_NODELABEL(pmucru)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), + + MMU_REGION_FLAT_ENTRY("CRU", + DT_REG_ADDR(DT_NODELABEL(cru)), + DT_REG_SIZE(DT_NODELABEL(cru)), + MT_DEVICE_nGnRnE | MT_P_RW_U_NA | MT_DEFAULT_SECURE_STATE), #endif }; diff --git a/subsys/virtualization/vdev/CMakeLists.txt b/subsys/virtualization/vdev/CMakeLists.txt index 5cdbeed725d702dab8ce3117d3a1a2c3f7f21b91..7800e37bb98622e60d3982545b936986969089e7 100644 --- a/subsys/virtualization/vdev/CMakeLists.txt +++ b/subsys/virtualization/vdev/CMakeLists.txt @@ -24,3 +24,8 @@ zephyr_sources_ifdef( CONFIG_VM_FIQ_DEBUGGER fiq_debugger.c ) + +zephyr_sources_ifdef( + CONFIG_VM_CLOCK_SYSTEM_CONTROLLER + virt_clock_syscon.c +) diff --git a/subsys/virtualization/vdev/Kconfig b/subsys/virtualization/vdev/Kconfig index 79dec2dc571e6834e9bf8f4bffbf5b629ec38dd7..28718a48e6ef390cf8c5f3d35add2025e395b702 100644 --- a/subsys/virtualization/vdev/Kconfig +++ b/subsys/virtualization/vdev/Kconfig @@ -86,3 +86,20 @@ config VM_FIQ_DEBUGGER_INIT_PRIORITY When fiq debugger is init, it judge the initialization priority in POST_KERNLE. endif + +config VM_CLOCK_SYSTEM_CONTROLLER + bool "VM clock system controller." + help + Some VMs may need to access clock syscon device, which is not suitable + to passthrough. ZVM must manager these clock devices and determining which + devices can be accessed. + +if VM_CLOCK_SYSTEM_CONTROLLER + +config VM_CLOCK_SYSTEM_CONTROLLER_INIT_PRIORITY + int "VM system clock controller init priority." + default 58 + help + When virt system clock is init, it judge the initialization priority in POST_KERNLE. + +endif diff --git a/subsys/virtualization/vdev/fiq_debugger.c b/subsys/virtualization/vdev/fiq_debugger.c index 4657090a65754b488e55ee6547bf0d1fbe3f2a0e..184c4e4c29b8fc5fdf84c69d507edec0583a8897 100644 --- a/subsys/virtualization/vdev/fiq_debugger.c +++ b/subsys/virtualization/vdev/fiq_debugger.c @@ -123,7 +123,7 @@ static struct virt_device_data virt_fiq_debugger_data_port = { #ifdef CONFIG_VIRT_DEVICE_INTERRUPT_DRIVEN .irq_cb = NULL, .irq_cb_data = NULL, -#endif +#endif }; static struct fiq_debugger_device_config fiq_debugger_cfg_port = { diff --git a/subsys/virtualization/vdev/serial.c b/subsys/virtualization/vdev/serial.c index e5771a1046f3d83b74a9164d0302aa486124d1a4..e714c2348a3910f75514e3583c2b21baba0028a7 100644 --- a/subsys/virtualization/vdev/serial.c +++ b/subsys/virtualization/vdev/serial.c @@ -14,8 +14,8 @@ #include #include #include -#include #include +#include #include #include @@ -105,6 +105,10 @@ void virt_serial_isr(const struct device *dev) #ifdef CONFIG_VM_SERIAL1 #ifdef CONFIG_UART_INTERRUPT_DRIVEN +/** + * @TODO: Maybe no need to enable serial port + * when vm is not start. +*/ static void serial1_irq_config_func(const struct device *dev) { IRQ_CONNECT(DT_IRQN(DT_ALIAS(vmserial1)), diff --git a/subsys/virtualization/vdev/vgic_common.c b/subsys/virtualization/vdev/vgic_common.c index de378c8460120e12865411e66f1414ebf9286d77..08e007bd9cf1454d474231279bfa69ccdb2f25ed 100644 --- a/subsys/virtualization/vdev/vgic_common.c +++ b/subsys/virtualization/vdev/vgic_common.c @@ -13,15 +13,12 @@ #include #include #include -#include #include -#include #include #include <../drivers/interrupt_controller/intc_gicv3_priv.h> #include -#include -#include #include +#include #include #include #include @@ -30,74 +27,6 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); -static struct virt_irq_desc *vgic_get_virt_irq_desc(struct vcpu *vcpu, uint32_t virq) -{ - struct vm *vm = vcpu->vm; - - /* sgi virq num */ - if (virq < VM_LOCAL_VIRQ_NR) { - return &vcpu->virq_block.vcpu_virt_irq_desc[virq]; - } - - /* spi virq num */ - if((virq >= VM_LOCAL_VIRQ_NR) && (virq < VM_GLOBAL_VIRQ_NR)) { - return &vm->vm_irq_block.vm_virt_irq_desc[virq - VM_LOCAL_VIRQ_NR]; - } - - return NULL; -} - -static int vgic_irq_enable(struct vcpu *vcpu, uint32_t virt_irq) -{ - struct virt_irq_desc *desc; - - desc = vgic_get_virt_irq_desc(vcpu, virt_irq); - if (!desc) { - return -ENOENT; - } - - desc->virq_flags |= VIRQ_ENABLED_FLAG; - if (virt_irq > VM_LOCAL_VIRQ_NR) { - if (desc->virq_flags & VIRQ_HW_FLAG) { - if (desc->pirq_num > VM_LOCAL_VIRQ_NR) - irq_enable(desc->pirq_num); - else { - ZVM_LOG_WARN("Not a spi interrupt!"); - return -ENODEV; - } - } - } else { - irq_enable(virt_irq); - } - - return 0; -} - -static int vgic_irq_disable(struct vcpu *vcpu, uint32_t virt_irq) -{ - struct virt_irq_desc *desc; - - desc = vgic_get_virt_irq_desc(vcpu, virt_irq); - if (!desc) { - return -ENOENT; - } - - desc->virq_flags &= ~VIRQ_ENABLED_FLAG; - if (virt_irq > VM_LOCAL_VIRQ_NR) { - if (desc->virq_flags & VIRQ_HW_FLAG) { - if (desc->pirq_num > VM_LOCAL_VIRQ_NR) { - irq_disable(desc->pirq_num); - } else { - ZVM_LOG_WARN("Not a spi interrupt!"); - return -ENODEV; - } - } - } else { - irq_disable(virt_irq); - } - return 0; -} - static int virt_irq_set_type(struct vcpu *vcpu, uint32_t offset, uint32_t *value) { uint8_t lowbit_value; @@ -313,12 +242,12 @@ static int vgic_gicd_mem_write(struct vcpu *vcpu, struct virt_gic_gicd *gicd, case GICD_ISENABLERn...(GICD_ICENABLERn - 1): x = (offset - GICD_ISENABLERn) / 4; y = x * 32; - vgic_irq_test_and_set_bit(vcpu, y, value, 32, 1); + vgic_test_and_set_enable_bit(vcpu, y, value, 32, 1, gicd); break; case GICD_ICENABLERn...(GICD_ISPENDRn - 1): x = (offset - GICD_ICENABLERn) / 4; y = x * 32; - vgic_irq_test_and_set_bit(vcpu, y, value, 32, 0); + vgic_test_and_set_enable_bit(vcpu, y, value, 32, 0, gicd); break; case GICD_IPRIORITYRn...(GIC_DIST_BASE + 0x07f8 - 1): t = *value; @@ -348,25 +277,6 @@ static int vgic_gicd_mem_write(struct vcpu *vcpu, struct virt_gic_gicd *gicd, return 0; } -void vgic_irq_test_and_set_bit(struct vcpu *vcpu, uint32_t spi_nr_count, uint32_t *value, - uint32_t bit_size, bool enable) -{ - int bit; - uint32_t reg_mem_addr = (uint64_t)value; - for (bit=0; bitvdev_list, d_node, ds_node) { vdev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); - - /* enable spi interrupt */ - irq = vdev->hirq; - - if (irq > CONFIG_NUM_IRQS) { - continue; + if(vdev->dev_pt_flag){ + /* enable spi interrupt */ + irq = vdev->hirq; + if (irq > CONFIG_NUM_IRQS) { + continue; + } + arm_gic_irq_enable(irq); } - arm_gic_irq_enable(irq); } } @@ -396,15 +306,14 @@ void arch_vdev_irq_disable(struct vcpu *vcpu) SYS_DLIST_FOR_EACH_NODE_SAFE(&vm->vdev_list, d_node, ds_node) { vdev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); - - /* disable spi interrupt */ - irq = vdev->hirq; - - if(irq > CONFIG_NUM_IRQS){ - continue; + if(vdev->dev_pt_flag){ + /* disable spi interrupt */ + irq = vdev->hirq; + if(irq > CONFIG_NUM_IRQS){ + continue; + } + arm_gic_irq_disable(irq); } - - arm_gic_irq_disable(irq); } } @@ -442,7 +351,7 @@ int vgic_vdev_mem_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) int i; int type = TYPE_GIC_INVAILD; struct vcpu *vcpu = _current_vcpu; - struct vgicv3_dev *vgic = (struct vgicv3_dev *)vdev->priv_data; + struct vgicv3_dev *vgic = (struct vgicv3_dev *)vdev->priv_vdev; struct virt_gic_gicd *gicd = &vgic->gicd; struct virt_gic_gicr *gicr = vgic->gicr[vcpu->vcpu_id]; @@ -499,7 +408,7 @@ int vgic_vdev_mem_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) int i; int type = TYPE_GIC_INVAILD; struct vcpu *vcpu = _current_vcpu; - struct vgicv3_dev *vgic = (struct vgicv3_dev *)vdev->priv_data; + struct vgicv3_dev *vgic = (struct vgicv3_dev *)vdev->priv_vdev; struct virt_gic_gicd *gicd = &vgic->gicd; struct virt_gic_gicr *gicr = vgic->gicr[vcpu->vcpu_id]; @@ -710,18 +619,3 @@ struct virt_irq_desc *get_virt_irq_desc(struct vcpu *vcpu, uint32_t virq) { return vgic_get_virt_irq_desc(vcpu, virq); } - -int vm_intctrl_vdev_create(struct vm *vm) -{ - int ret = 0; - const struct device *dev = DEVICE_DT_GET(DT_ALIAS(vmvgic)); - - if(((const struct virt_device_api * const)(dev->api))->init_fn){ - ((const struct virt_device_api * const)(dev->api))->init_fn(dev, vm, NULL); - }else{ - ZVM_LOG_ERR("No gic device api! \n"); - return -ENODEV; - } - - return ret; -} diff --git a/subsys/virtualization/vdev/vgic_v3.c b/subsys/virtualization/vdev/vgic_v3.c index 93c43f13dccec108d62275a947fb5685b33f3185..38627aaf853904aee171c072738a3f0fc0053fee 100644 --- a/subsys/virtualization/vdev/vgic_v3.c +++ b/subsys/virtualization/vdev/vgic_v3.c @@ -18,8 +18,8 @@ #include #include <../drivers/interrupt_controller/intc_gicv3_priv.h> #include -#include #include +#include #include #include #include @@ -28,13 +28,15 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); -#define DEV_CFG(dev) \ - ((const struct virt_device_config * const)(dev)->config) +#define VM_GIC_NAME vm_gic_v3 + #define DEV_DATA(dev) \ ((struct virt_device_data *)(dev)->data) -#define DEV_VGICV3(dev) \ - ((const struct gicv3_vdevice * const)(DEV_CFG(dev)->device_config)) +#define DEV_CFG(dev) \ + ((const struct virt_device_config * const)(dev)->config) + +static const struct virtual_device_instance *gic_virtual_device_instance; /** * @brief load list register for vcpu interface. @@ -94,8 +96,6 @@ static void vgicv3_prios_load(struct gicv3_vcpuif_ctxt *ctxt) static void vgicv3_ctrls_load(struct gicv3_vcpuif_ctxt *ctxt) { write_sysreg(ctxt->icc_sre_el1, ICC_SRE_EL1); - write_sysreg(ctxt->icc_ctlr_el1, ICC_CTLR_EL1); - write_sysreg(ctxt->ich_vmcr_el2, ICH_VMCR_EL2); write_sysreg(ctxt->ich_hcr_el2, ICH_HCR_EL2); } @@ -189,12 +189,185 @@ static void vgicv3_prios_save(struct gicv3_vcpuif_ctxt *ctxt) static void vgicv3_ctrls_save(struct gicv3_vcpuif_ctxt *ctxt) { ctxt->icc_sre_el1 = read_sysreg(ICC_SRE_EL1); - ctxt->icc_ctlr_el1 = read_sysreg(ICC_CTLR_EL1); - ctxt->ich_vmcr_el2 = read_sysreg(ICH_VMCR_EL2); ctxt->ich_hcr_el2 = read_sysreg(ICH_HCR_EL2); } +static int vdev_gicv3_init(struct vm *vm, struct vgicv3_dev *gicv3_vdev, uint32_t gicd_base, uint32_t gicd_size, + uint32_t gicr_base, uint32_t gicr_size) +{ + int i = 0; + uint32_t spi_num; + uint64_t tmp_typer = 0; + struct virt_gic_gicd *gicd = &gicv3_vdev->gicd; + struct virt_gic_gicr *gicr; + + gicd->gicd_base = gicd_base; + gicd->gicd_size = gicd_size; + gicd->gicd_regs_base = (uint32_t *)k_malloc(gicd->gicd_size); + if(!gicd->gicd_regs_base){ + return -EMMAO; + } + memset(gicd->gicd_regs_base, 0, gicd_size); + /* GICD PIDR2 */ + vgic_sysreg_write32(0x3<<4, gicd->gicd_regs_base, VGICD_PIDR2); + spi_num = ((VM_GLOBAL_VIRQ_NR + 32) >> 5) - 1; + tmp_typer = (vm->vcpu_num << 5) | (9 << 19) | spi_num; + vgic_sysreg_write32(tmp_typer, gicd->gicd_regs_base, VGICD_TYPER); + /* Init spinlock */ + ZVM_SPINLOCK_INIT(&gicd->gicd_lock); + + for (i = 0; i < VGIC_RDIST_SIZE/VGIC_RD_SGI_SIZE + 1; i++) { + gicr = (struct virt_gic_gicr *)k_malloc(sizeof(struct virt_gic_gicr)); + if(!gicr){ + return -EMMAO; + } + /* store the vcpu id for gicr */ + gicr->vcpu_id = i; + /* init redistribute size */ + gicr->gicr_rd_size = VGIC_RD_BASE_SIZE; + gicr->gicr_rd_reg_base = k_malloc(gicr->gicr_rd_size); + if(!gicr->gicr_rd_reg_base){ + ZVM_LOG_ERR("Allocat memory for gicr_rd error! \n"); + return -EMMAO; + } + memset(gicr->gicr_rd_reg_base, 0, gicr->gicr_rd_size); + /* init sgi redistribute size */ + gicr->gicr_sgi_size = VGIC_SGI_BASE_SIZE; + gicr->gicr_sgi_reg_base = k_malloc(gicr->gicr_sgi_size); + if(!gicr->gicr_sgi_reg_base){ + ZVM_LOG_ERR("Allocat memory for gicr_sgi error! \n"); + return -EMMAO; + } + memset(gicr->gicr_sgi_reg_base, 0, gicr->gicr_sgi_size); + + gicr->gicr_rd_base = gicr_base + VGIC_RD_SGI_SIZE*i; + gicr->gicr_sgi_base = gicr->gicr_rd_base + VGIC_RD_BASE_SIZE; + vgic_sysreg_write32(0x3<<4, gicr->gicr_rd_reg_base, VGICR_PIDR2); + /* Init spinlock */ + ZVM_SPINLOCK_INIT(&gicr->gicr_lock); + + if(i >= vm->vcpu_num - 1){ + /* set last gicr region flag here, means it is the last gicr region */ + vgic_sysreg_write64(GICR_TYPER_LAST_FLAG, gicr->gicr_rd_reg_base, VGICR_TYPER); + vgic_sysreg_write64(GICR_TYPER_LAST_FLAG, gicr->gicr_sgi_reg_base, VGICR_TYPER); + }else{ + vgic_sysreg_write64((uint64_t)i << 32, gicr->gicr_rd_reg_base, VGICR_TYPER); + vgic_sysreg_write64((uint64_t)i << 32, gicr->gicr_sgi_reg_base, VGICR_TYPER); + } + + gicv3_vdev->gicr[i] = gicr; + } + + ZVM_LOG_INFO("** List register num: %lld \n", VGIC_TYPER_LR_NUM); + vgicv3_lrs_init(); + + return 0; +} + +/** + * @brief init vm gic device for each vm. Including: + * 1. creating virt device for vm. + * 2. building memory map for this device. +*/ +static int vm_vgicv3_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) +{ + ARG_UNUSED(dev); + ARG_UNUSED(vdev_desc); + int ret; + uint32_t gicd_base, gicd_size, gicr_base, gicr_size; + struct virt_dev *virt_dev; + struct vgicv3_dev *vgicv3; + + gicd_base = VGIC_DIST_BASE; + gicd_size = VGIC_DIST_SIZE; + gicr_base = VGIC_RDIST_BASE; + gicr_size = VGIC_RDIST_SIZE; + /* check gic device */ + if(!gicd_base || !gicd_size || !gicr_base || !gicr_size){ + ZVM_LOG_ERR("GIC device has init error!"); + return -ENODEV; + } + + /* Init virtual device for vm. */ + virt_dev = vm_virt_dev_add(vm, gic_virtual_device_instance->name, false, false, gicd_base, + gicd_base, gicr_base+gicr_size-gicd_base, 0, 0); + if(!virt_dev){ + return -ENODEV; + } + + /* Init virtual gic device for virtual device. */ + vgicv3 = (struct vgicv3_dev *)k_malloc(sizeof(struct vgicv3_dev)); + if (!vgicv3) { + ZVM_LOG_ERR("Allocat memory for vgicv3 error \n"); + return -ENODEV; + } + ret = vdev_gicv3_init(vm, vgicv3, gicd_base, gicd_size, gicr_base, gicr_size); + if(ret){ + ZVM_LOG_ERR("Init virt gicv3 error \n"); + return -ENODEV; + } + + /* get the private data for vgicv3 */ + virt_dev->priv_data = gic_virtual_device_instance; + virt_dev->priv_vdev = vgicv3; + + return 0; +} + +/** + * @brief The init function of vgic, it provides the + * gic hardware device information to ZVM. +*/ +static int virt_gic_v3_init(const struct device *dev) +{ + ARG_UNUSED(dev); + int i; + + for (i = 0; i < zvm_virtual_devices_count_get(); i++) { + const struct virtual_device_instance *virtual_device = zvm_virtual_device_get(i); + if(strcmp(virtual_device->name, TOSTRING(VM_GIC_NAME))){ + continue; + } + DEV_DATA(virtual_device)->vdevice_type |= VM_DEVICE_PRE_KERNEL_1; + gic_virtual_device_instance = virtual_device; + break; + } + return 0; +} + +static struct virt_device_config virt_gicv3_cfg = { + .hirq_num = VM_DEVICE_INVALID_VIRQ, + .device_config = NULL, +}; + +static struct virt_device_data virt_gicv3_data_port = { + .device_data = NULL, +}; + +/** + * @brief vgic device operations api. +*/ +static const struct virt_device_api virt_gicv3_api = { + .init_fn = vm_vgicv3_init, + .virt_device_read = vgic_vdev_mem_read, + .virt_device_write = vgic_vdev_mem_write, +}; + +ZVM_VIRTUAL_DEVICE_DEFINE(virt_gic_v3_init, + POST_KERNEL, CONFIG_VM_VGICV3_INIT_PRIORITY, + VM_GIC_NAME, + virt_gicv3_data_port, + virt_gicv3_cfg, + virt_gicv3_api); + +uint32_t *arm_gic_get_distbase(struct virt_dev *vdev) +{ + struct vgicv3_dev *vgic = (struct vgicv3_dev *)vdev->priv_vdev; + struct virt_gic_gicd *gicd = &vgic->gicd; + + return gicd->gicd_regs_base; +} int gicv3_inject_virq(struct vcpu *vcpu, struct virt_irq_desc *desc) { @@ -262,22 +435,10 @@ int vgic_gicrsgi_mem_write(struct vcpu *vcpu, struct virt_gic_gicr *gicr, uint32 switch (offset) { case GICR_SGI_ISENABLER: - vgic_irq_test_and_set_bit(vcpu, 0, value, 32, 1); - for (bit = 0; bit < 32; bit++) { - if (sys_test_bit(mem_addr, bit)) { - vgic_sysreg_write32(vgic_sysreg_read32(gicr->gicr_sgi_reg_base, VGICR_ISENABLER0) | BIT(bit),\ - gicr->gicr_sgi_reg_base, VGICR_ISENABLER0); - } - } + vgic_test_and_set_enable_bit(vcpu, 0, value, 32, 1, gicr); break; case GICR_SGI_ICENABLER: - vgic_irq_test_and_set_bit(vcpu, 0, value, 32, 0); - for(bit = 0; bit < 32; bit++) { - if (sys_test_bit(mem_addr, bit)) { - vgic_sysreg_write32(vgic_sysreg_read32(gicr->gicr_sgi_reg_base, VGICR_ICENABLER0) & ~BIT(bit),\ - gicr->gicr_sgi_reg_base, VGICR_ICENABLER0); - } - } + vgic_test_and_set_enable_bit(vcpu, 0, value, 32, 0, gicr); break; case GICR_SGI_PENDING: /* clear pending state */ @@ -394,174 +555,9 @@ int vcpu_gicv3_init(struct gicv3_vcpuif_ctxt *ctxt) ctxt->icc_sre_el1 = 0x07; ctxt->icc_ctlr_el1 = read_sysreg(ICC_CTLR_EL1); - ctxt->icc_ctlr_el1 |= 0x02; ctxt->ich_vmcr_el2 = GICH_VMCR_VENG1 | GICH_VMCR_DEFAULT_MASK; ctxt->ich_hcr_el2 = GICH_HCR_EN; return 0; -} - -static int vdev_gicv3_init(struct vm *vm, struct vgicv3_dev *gicv3_vdev, uint32_t gicd_base, uint32_t gicd_size, - uint32_t gicr_base, uint32_t gicr_size) -{ - int i = 0; - uint32_t spi_num; - uint64_t tmp_typer = 0; - struct virt_gic_gicd *gicd = &gicv3_vdev->gicd; - struct virt_gic_gicr *gicr; - - gicd->gicd_base = gicd_base; - gicd->gicd_size = gicd_size; - gicd->gicd_regs_base = k_malloc(gicd->gicd_size); - if(!gicd->gicd_regs_base){ - return -EMMAO; - } - memset(gicd->gicd_regs_base, 0, gicd_size); - - /* GICD PIDR2 */ - vgic_sysreg_write32(0x3<<4, gicd->gicd_regs_base, VGICD_PIDR2); - spi_num = ((VM_GLOBAL_VIRQ_NR + 32) >> 5) - 1; - tmp_typer = (vm->vcpu_num << 5) | (9 << 19) | spi_num; - vgic_sysreg_write32(tmp_typer, gicd->gicd_regs_base, VGICD_TYPER); - /* Init spinlock */ - ZVM_SPINLOCK_INIT(&gicd->gicd_lock); - - for (i = 0; i < VGIC_RDIST_SIZE/VGIC_RD_SGI_SIZE + 1; i++) { - gicr = (struct virt_gic_gicr *)k_malloc(sizeof(struct virt_gic_gicr)); - if(!gicr){ - return -EMMAO; - } - /* store the vcpu id for gicr */ - gicr->vcpu_id = i; - /* init redistribute size */ - gicr->gicr_rd_size = VGIC_RD_BASE_SIZE; - gicr->gicr_rd_reg_base = k_malloc(gicr->gicr_rd_size); - if(!gicr->gicr_rd_reg_base){ - ZVM_LOG_ERR("Allocat memory for gicr_rd error! \n"); - return -EMMAO; - } - memset(gicr->gicr_rd_reg_base, 0, gicr->gicr_rd_size); - /* init sgi redistribute size */ - gicr->gicr_sgi_size = VGIC_SGI_BASE_SIZE; - gicr->gicr_sgi_reg_base = k_malloc(gicr->gicr_sgi_size); - if(!gicr->gicr_sgi_reg_base){ - ZVM_LOG_ERR("Allocat memory for gicr_sgi error! \n"); - return -EMMAO; - } - memset(gicr->gicr_sgi_reg_base, 0, gicr->gicr_sgi_size); - - gicr->gicr_rd_base = gicr_base + VGIC_RD_SGI_SIZE*i; - gicr->gicr_sgi_base = gicr->gicr_rd_base + VGIC_RD_BASE_SIZE; - vgic_sysreg_write32(0x3<<4, gicr->gicr_rd_reg_base, VGICR_PIDR2); - /* Init spinlock */ - ZVM_SPINLOCK_INIT(&gicr->gicr_lock); - - if(i >= vm->vcpu_num - 1){ - /* set last gicr region flag here, means it is the last gicr region */ - vgic_sysreg_write64(GICR_TYPER_LAST_FLAG, gicr->gicr_rd_reg_base, VGICR_TYPER); - vgic_sysreg_write64(GICR_TYPER_LAST_FLAG, gicr->gicr_sgi_reg_base, VGICR_TYPER); - }else{ - vgic_sysreg_write64((uint64_t)i << 32, gicr->gicr_rd_reg_base, VGICR_TYPER); - vgic_sysreg_write64((uint64_t)i << 32, gicr->gicr_sgi_reg_base, VGICR_TYPER); - } - - gicv3_vdev->gicr[i] = gicr; - } - - ZVM_LOG_INFO("** List register num: %lld \n", VGIC_TYPER_LR_NUM); - vgicv3_lrs_init(); - - return 0; -} - -/** - * @brief init vm gic device for each vm. Including: - * 1. creating virt device for vm. - * 2. building memory map for this device. -*/ -static int vm_vgicv3_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) -{ - int ret; - uint32_t gicd_base, gicd_size, gicr_base, gicr_size; - struct virt_dev *virt_dev; - struct vgicv3_dev *vgicv3; - - gicd_base = DEV_VGICV3(dev)->gicd_base; - gicd_size = DEV_VGICV3(dev)->gicd_size; - gicr_base = DEV_VGICV3(dev)->gicr_base; - gicr_size = DEV_VGICV3(dev)->gicr_size;; - /* check gic device */ - if(!gicd_base || !gicd_size || !gicr_base || !gicr_size){ - ZVM_LOG_ERR("GIC device has init error!"); - return -ENODEV; - } - - /* Init virtual device for vm. */ - virt_dev = vm_virt_dev_add(vm, dev->name, false, false, gicd_base, - gicd_base, gicr_base+gicr_size-gicd_base, 0, 0); - if(!virt_dev){ - ZVM_LOG_WARN("Init virt gic device error\n"); - return -ENODEV; - } - - /* Init virtual gic device for virtual device. */ - vgicv3 = (struct vgicv3_dev *)k_malloc(sizeof(struct vgicv3_dev)); - if (!vgicv3) { - ZVM_LOG_ERR("Allocat memory for vgicv3 error \n"); - return -ENODEV; - } - ret = vdev_gicv3_init(vm, vgicv3, gicd_base, gicd_size, gicr_base, gicr_size); - if(ret){ - ZVM_LOG_ERR("Init virt gicv3 error \n"); - return -ENODEV; - } - - /* get the private data for vgicv3 */ - virt_dev->priv_data = vgicv3; - virt_dev->priv_vdev = (void *)dev; - - return 0; -} - -/** - * @brief The init function of vgic, it provides the - * gic hardware device information to ZVM. -*/ -static int vgicv3_init(const struct device *dev) -{ - return 0; -} - -static struct gicv3_vdevice vgicv3_cfg_port = { - .gicd_base = VGIC_DIST_BASE, - .gicd_size = VGIC_DIST_SIZE, - .gicr_base = VGIC_RDIST_BASE, - .gicr_size = VGIC_RDIST_SIZE, -}; - -static struct virt_device_config virt_gicv3_cfg = { - .device_config = &vgicv3_cfg_port, -}; - -static struct virt_device_data virt_gicv3_data_port; - -/** - * @brief vgic device operations api. -*/ -static const struct virt_device_api virt_gicv3_api = { - .init_fn = vm_vgicv3_init, - .virt_device_read = vgic_vdev_mem_read, - .virt_device_write = vgic_vdev_mem_write, -}; - -/** - * @brief Define the vgic description for zvm. -*/ -DEVICE_DT_DEFINE(DT_ALIAS(vmvgic), - &vgicv3_init, - NULL, - &virt_gicv3_data_port, - &virt_gicv3_cfg, POST_KERNEL, - CONFIG_VM_VGICV3_INIT_PRIORITY, - &virt_gicv3_api); +} \ No newline at end of file diff --git a/subsys/virtualization/vdev/virt_clock_syscon.c b/subsys/virtualization/vdev/virt_clock_syscon.c new file mode 100644 index 0000000000000000000000000000000000000000..9c9896819ee1812f3ef8d0654092a629e1281ad6 --- /dev/null +++ b/subsys/virtualization/vdev/virt_clock_syscon.c @@ -0,0 +1,157 @@ +/* + * Copyright 2023-2024 HNU-ESNL + * Copyright 2023-2024 openEuler SIG-Zephyr + * + * SPDX-License-Identifier: Apache-2.0 + * + * Provide a common clock controller for each vm to + * operate system clock. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_DECLARE(ZVM_MODULE_NAME); + +#define VM_CLKCON_NAME vm_clock_syscon + +#define DEV_DATA(dev) \ + ((struct virt_device_data *)(dev)->data) + +struct virt_clk_syscon_list overall_clock_syscons; + +static const struct virtual_device_instance *clk_virtual_device_instance; + +static bool first_entry_flag = false; + +int z_info_sys_clkcon(const char *name, uint32_t addr_base, + uint32_t addr_size, void *priv) +{ + ARG_UNUSED(priv); + k_spinlock_key_t key; + struct virt_clk_syscon *clk_syscon; + + clk_syscon = (struct virt_clk_syscon *)k_malloc(sizeof(struct virt_clk_syscon)); + if (!clk_syscon) { + ZVM_LOG_ERR("Allocate memory for clk_syscon Error.\n"); + return -ENOMEM; + } + clk_syscon->reg_base = addr_base; + clk_syscon->reg_size = addr_size; + clk_syscon->name = name; + + /* Add clock syscon info to overall lists. */ + key = k_spin_lock(&overall_clock_syscons.vclk_lock); + /*dlist must be init to address to itself.*/ + if(!first_entry_flag){ + sys_dlist_init(&overall_clock_syscons.clk_syscon_list); + first_entry_flag = true; + } + sys_dlist_append(&overall_clock_syscons.clk_syscon_list, &clk_syscon->clk_node); + overall_clock_syscons.clk_num++; + k_spin_unlock(&overall_clock_syscons.vclk_lock, key); + + return 0; +} + +/** + * @brief: Get the virtual clock controller, and set a + * pre_kernel configuration for the virtual clock. +*/ +static int virt_clock_syscon_init(const struct device *dev) +{ + ARG_UNUSED(dev); + int i; + + for (i = 0; i < zvm_virtual_devices_count_get(); i++) { + const struct virtual_device_instance *virtual_device = zvm_virtual_device_get(i); + if(strcmp(virtual_device->name, TOSTRING(VM_CLKCON_NAME))){ + continue; + } + DEV_DATA(virtual_device)->vdevice_type |= VM_DEVICE_PRE_KERNEL_1; + clk_virtual_device_instance = virtual_device; + break; + } + return 0; +} + +static struct virt_device_config virt_clock_syscon_cfg = { + .hirq_num = VM_DEVICE_INVALID_VIRQ, +}; + +static struct virt_device_data virt_clock_syscon_data_port = { + .device_data = NULL, +}; + +/** + * @brief init vm clock syscon device for each vm. +*/ +static int vm_clock_syscons_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) +{ + ARG_UNUSED(dev); + struct virt_dev *vm_dev; + struct virt_clk_syscon *virt_clk_dev; + struct _dnode *d_node, *ds_node; + + /* scan the system clock list and get the clock device */ + SYS_DLIST_FOR_EACH_NODE_SAFE(&overall_clock_syscons.clk_syscon_list, d_node, ds_node){ + virt_clk_dev = CONTAINER_OF(d_node, struct virt_clk_syscon, clk_node); + vm_dev = vm_virt_dev_add(vm, virt_clk_dev->name, false, false, + virt_clk_dev->reg_base, virt_clk_dev->reg_base, + virt_clk_dev->reg_size, VM_DEVICE_INVALID_VIRQ, + VM_DEVICE_INVALID_VIRQ); + if(!vm_dev){ + return -ENODEV; + } + vm_dev->priv_data = clk_virtual_device_instance; + } + + return 0; +} + +int clk_syscon_vdev_mem_read(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + uint32_t read_value; + read_value = sys_read32(addr); + *(uint32_t *)value = read_value; + + printk("Device-%s Read:addr is %llx, value is %x\n", vdev->name, addr, read_value); + + return 0; +} + +int clk_syscon_vdev_mem_write(struct virt_dev *vdev, uint64_t addr, uint64_t *value) +{ + uint32_t be_write_value, write_value, af_write_value; + + write_value = *(uint32_t *)value; + be_write_value = sys_read32(addr); + sys_write32(write_value, addr); + af_write_value = sys_read32(addr); + + printk("Device-%s Write:addr is %llx, be_value is %x, ne_value is %x, af_value is %x\n", + vdev->name, addr, be_write_value, write_value, af_write_value); + + return 0; +} + +static const struct virt_device_api virt_clock_syscon_api = { + .init_fn = vm_clock_syscons_init, + .virt_device_read = clk_syscon_vdev_mem_read, + .virt_device_write = clk_syscon_vdev_mem_write, +}; + +/* Init after soc's clock syscon. */ +ZVM_VIRTUAL_DEVICE_DEFINE(virt_clock_syscon_init, + POST_KERNEL, CONFIG_VM_CLOCK_SYSTEM_CONTROLLER_INIT_PRIORITY, + VM_CLKCON_NAME, + virt_clock_syscon_data_port, + virt_clock_syscon_cfg, + virt_clock_syscon_api); diff --git a/subsys/virtualization/vdev/virtio.c b/subsys/virtualization/vdev/virtio.c index fdb62ea5da3640d34e520b279e751d918748aa69..dbb161446619a21e6e776cd29f6909edbf754b4e 100644 --- a/subsys/virtualization/vdev/virtio.c +++ b/subsys/virtualization/vdev/virtio.c @@ -12,7 +12,6 @@ #include #include - static sys_dlist_t virtio_devs; static sys_dlist_t virtio_emus; static struct k_spinlock virtio_lock; @@ -149,7 +148,7 @@ bool virtio_queue_should_signal(struct virtio_queue *vq) return true; } - return false; + return false; } void virtio_queue_set_avail_event(struct virtio_queue *vq) @@ -232,7 +231,7 @@ bool virtio_queue_setup(struct virtio_queue *vq, vpart = (struct vm_mem_partition *)k_malloc(sizeof(struct vm_mem_partition)); if (!vpart) { return false; - } + } if(!virtio_queue_cleanup(vq)) { return false; @@ -247,7 +246,7 @@ bool virtio_queue_setup(struct virtio_queue *vq, printk("%s: available size less than required size\n", __func__); return false; - } + } vring_init(&vq->vring, desc_count, NULL, gphys_addr, align); @@ -416,7 +415,7 @@ uint32_t virtio_buf_to_iovec_write(struct virtio_device *dev, for (i = 0; i < iov_cnt && pos < buf_len; i++) { len = ((buf_len - pos) < iov[i].len) ? (buf_len - pos) : iov[i].len; - + if (!len) { break; } @@ -427,7 +426,7 @@ uint32_t virtio_buf_to_iovec_write(struct virtio_device *dev, pos += len; } - return pos; + return pos; } void virtio_iovec_fill_zeros(struct virtio_device *dev, @@ -440,8 +439,8 @@ void virtio_iovec_fill_zeros(struct virtio_device *dev, memset(zeros, 0, sizeof(zeros)); while (i < iov_cnt) { - len = (iov[i].len < 16) ? iov[i].len : 16; - + len = (iov[i].len < 16) ? iov[i].len : 16; + if (!len) { break; } @@ -597,10 +596,10 @@ int virtio_register_device(struct virtio_device *dev) dev->emu_data = NULL; key = k_spin_lock(&virtio_lock); - + sys_dlist_append(&virtio_devs, &dev->node); rc = __virtio_find_emulator(dev); - + k_spin_unlock(&virtio_lock, key); return rc; @@ -609,7 +608,7 @@ int virtio_register_device(struct virtio_device *dev) void virtio_unregister_device(struct virtio_device *dev) { k_spinlock_key_t key; - + if (!dev) { return; } @@ -641,7 +640,7 @@ int virtio_register_emulator(struct virtio_emulator *emu) SYS_DLIST_FOR_EACH_NODE_SAFE(&virtio_emus, d_node, ds_node) { vemu = CONTAINER_OF(d_node, struct virtio_emulator, node); - + if (strcmp(vemu->name, emu->name) == 0) { found = true; break; @@ -654,7 +653,7 @@ int virtio_register_emulator(struct virtio_emulator *emu) } sys_dnode_init(&emu->node); - sys_dlist_append(&virtio_emus, &emu->node); + sys_dlist_append(&virtio_emus, &emu->node); __virtio_attach_emulator(emu); diff --git a/subsys/virtualization/vdev/virtio_mmio.c b/subsys/virtualization/vdev/virtio_mmio.c index bb206dd724302b0adf54f726108b227c55eca10c..54f32bd235c9ae7fb39dd6cbbb4d8ff284c74c89 100644 --- a/subsys/virtualization/vdev/virtio_mmio.c +++ b/subsys/virtualization/vdev/virtio_mmio.c @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -33,7 +33,7 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); static int vm_virtio_mmio_init(const struct device *dev, struct vm *vm, struct virt_dev *vdev_desc) { int ret; - + ret = ((struct virtio_mmio_driver_api *)((struct virt_device_api *)dev->api)->device_driver_api)->probe(vm, vdev_desc); if (ret) { ZVM_LOG_WARN(" Init virtio device error! \n"); @@ -45,7 +45,7 @@ static int vm_virtio_mmio_init(const struct device *dev, struct vm *vm, struct v ZVM_LOG_WARN(" Reset Init virtio device error! \n"); return -EFAULT; } - + return 0; } @@ -229,7 +229,7 @@ static int virtio_mmio_notify(struct virtio_device *dev, uint32_t vq) return -EFAULT; } - return 0; + return 0; } static struct virtio_transport mmio_tra = { @@ -253,9 +253,9 @@ int virtio_mmio_probe(struct vm *guest, struct virt_dev *edev) { name_len = strlen(guest->vm_name) < VIRTIO_DEVICE_MAX_NAME_LEN ? strlen(guest->vm_name) : VIRTIO_DEVICE_MAX_NAME_LEN; strncpy(m->dev.name, guest->vm_name, name_len); name_len = name_len + strlen(edev->name) < VIRTIO_DEVICE_MAX_NAME_LEN ? strlen(edev->name) : VIRTIO_DEVICE_MAX_NAME_LEN - name_len; - strncat(m->dev.name, edev->name, name_len); + strncat(m->dev.name, edev->name, name_len); m->dev.name[strlen(m->dev.name)] = '\0'; - + m->dev.edev = edev; m->dev.id.type = ((struct virtio_device_config *)((struct virt_device_config *)((struct device *)edev->priv_data)->config)->device_config)->virtio_type; m->dev.tra = &mmio_tra; @@ -300,7 +300,7 @@ static int virtio_mmio_remove(struct virt_dev *edev) } static int virtio_mmio_reset(struct virt_dev *edev) -{ +{ struct virtio_mmio_dev *m = edev->priv_vdev; m->config.host_features_sel = 0x0; diff --git a/subsys/virtualization/vm.c b/subsys/virtualization/vm.c index a0367d9521674df7ddf35e4a02ecccd89f0d3427..52e52cf666fcdb7bdf6127a0e885bda2b138d6b5 100644 --- a/subsys/virtualization/vm.c +++ b/subsys/virtualization/vm.c @@ -312,7 +312,7 @@ int vm_vcpus_init(struct vm *vm) return 0; } -int vm_vcpus_run(struct vm *vm) +int vm_vcpus_ready(struct vm *vm) { uint16_t i=0; struct vcpu *vcpu; @@ -329,7 +329,7 @@ int vm_vcpus_run(struct vm *vm) k_spin_unlock(&vm->spinlock, key); return -ENODEV; } - vm_vcpu_run(vcpu); + vm_vcpu_ready(vcpu); } vm->vm_status = VM_STATE_RUNNING; k_spin_unlock(&vm->spinlock, key); diff --git a/subsys/virtualization/vm_console.c b/subsys/virtualization/vm_console.c index 383e3e9617759f6b1c669f7974724eccca37ea0c..3de3c80dec203c266ce0da00aae6d4582cc20279 100644 --- a/subsys/virtualization/vm_console.c +++ b/subsys/virtualization/vm_console.c @@ -12,8 +12,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/subsys/virtualization/vm_cpu.c b/subsys/virtualization/vm_cpu.c index bf4334477687cce08aa06db2b2786008301f3dd2..35ce98b7307af73741c5689fa559c8a84d868688 100644 --- a/subsys/virtualization/vm_cpu.c +++ b/subsys/virtualization/vm_cpu.c @@ -33,7 +33,7 @@ static void init_vcpu_virt_irq_desc(struct vcpu_virt_irq_block *virq_block) desc->prio = 0; desc->vdev_trigger = 0; desc->vcpu_id = DEFAULT_VCPU; - desc->virq_flags = VIRQ_NOUSED_FLAG; + desc->virq_flags = 0; desc->virq_states = 0; desc->vm_id = DEFAULT_VM; @@ -118,9 +118,14 @@ static void vcpu_state_to_ready(struct vcpu *vcpu) uint16_t cur_state = vcpu->vcpu_state; struct k_thread *thread = vcpu->work->vcpu_thread; + vcpu->hcpu_cycles = sys_clock_cycle_get_32(); + switch (cur_state) { + case _VCPU_STATE_UNKNOWN: case _VCPU_STATE_READY: + k_thread_start(thread); + vcpu->vcpu_state = _VCPU_STATE_READY; break; case _VCPU_STATE_RUNNING: vcpu->resume_signal = true; @@ -130,7 +135,7 @@ static void vcpu_state_to_ready(struct vcpu *vcpu) k_wakeup(thread); break; default: - ZVM_LOG_WARN("Invalid cpu state here. \n"); + ZVM_LOG_WARN("Invalid cpu state! \n"); break; } @@ -264,18 +269,20 @@ int vcpu_state_switch(struct k_thread *thread, uint16_t new_state) void do_vcpu_swap(struct k_thread *new_thread, struct k_thread *old_thread) { - uint32_t cur_state; struct vcpu *vcpu; - ARG_UNUSED(cur_state); ARG_UNUSED(vcpu); + if(new_thread == old_thread){ + return; + } + #ifdef CONFIG_SMP vcpu_context_switch(new_thread, old_thread); #else if (old_thread && VCPU_THREAD(old_thread)) { save_vcpu_context(old_thread); } - else if (new_thread && VCPU_THREAD(new_thread)) { + if (new_thread && VCPU_THREAD(new_thread)) { load_vcpu_context(new_thread); } #endif /* CONFIG_SMP */ @@ -310,9 +317,9 @@ int vcpu_ipi_scheduler(uint32_t cpu_mask, uint32_t timeout) } /** - * @brief vcpu run func entry_point. + * @brief vcpu entry_point. */ -int z_vcpu_run(struct vcpu *vcpu) +int vcpu_thread_entry(struct vcpu *vcpu) { int ret = 0; ZVM_LOG_INFO("\n** Start running vcpu: %s-%d. \n", vcpu->vm->vm_name, vcpu->vcpu_id); @@ -325,26 +332,12 @@ int z_vcpu_run(struct vcpu *vcpu) return ret; } -/** - * @brief Judge whether this vcpu has irq need to handle... - */ -int vcpu_irq_exit(struct vcpu *vcpu) -{ - bool pend, active; - struct vcpu_virt_irq_block *vb = &vcpu->virq_block; - - pend = sys_dlist_is_empty(&vb->pending_irqs); - active = sys_dlist_is_empty(&vb->active_irqs); - - return !(pend && active); -} - static int created_vm_num = 0; struct vcpu *vm_vcpu_init(struct vm *vm, uint16_t vcpu_id, char *vcpu_name) { uint16_t vm_prio; - int pcpu_num; + int pcpu_num = 0; struct vcpu *vcpu; struct vcpu_work *vwork; @@ -363,6 +356,10 @@ struct vcpu *vm_vcpu_init(struct vm *vm, uint16_t vcpu_id, char *vcpu_name) /* init vcpu virt irq block. */ vcpu->virq_block.virq_pending_counts = 0; + vcpu->virq_block.vwfi.priv = NULL; + vcpu->virq_block.vwfi.state = false; + vcpu->virq_block.vwfi.yeild_count = 0; + ZVM_SPINLOCK_INIT(&vcpu->virq_block.vwfi.wfi_lock); sys_dlist_init(&vcpu->virq_block.pending_irqs); sys_dlist_init(&vcpu->virq_block.active_irqs); ZVM_SPINLOCK_INIT(&vcpu->virq_block.spinlock); @@ -391,12 +388,17 @@ struct vcpu *vm_vcpu_init(struct vm *vm, uint16_t vcpu_id, char *vcpu_name) /*TODO: In this stage, the thread is marked as a kernel thread, For system safe, we will modified it later.*/ k_tid_t tid = k_thread_create(vwork->vcpu_thread, vwork->vt_stack, - VCPU_THREAD_STACKSIZE,(void *)z_vcpu_run, vcpu, NULL, NULL, + VCPU_THREAD_STACKSIZE,(void *)vcpu_thread_entry, vcpu, NULL, NULL, vm_prio, 0, K_FOREVER); strcpy(tid->name, vcpu_name); /* SMP support*/ #ifdef CONFIG_SCHED_CPU_MASK + /** + * Due to the default 'new_thread->base.cpu_mask=1', + * BIT(0) must be cleared when enable other mask bit + * when CONFIG_SCHED_CPU_MASK_PIN_ONLY=y. + */ k_thread_cpu_mask_disable(tid, 0); if (vm->is_rtos) { @@ -414,6 +416,8 @@ struct vcpu *vm_vcpu_init(struct vm *vm, uint16_t vcpu_id, char *vcpu_name) } k_thread_cpu_mask_enable(tid, pcpu_num); vcpu->cpu = pcpu_num; +#else + vcpu->cpu = pcpu_num; #endif /* CONFIG_SCHED_CPU_MASK */ /* create a new thread and store it in work struct */ @@ -439,30 +443,9 @@ struct vcpu *vm_vcpu_init(struct vm *vm, uint16_t vcpu_id, char *vcpu_name) return vcpu; } -int vm_vcpu_run(struct vcpu *vcpu) +int vm_vcpu_ready(struct vcpu *vcpu) { - uint16_t cur_state = vcpu->vcpu_state; - struct k_thread *thread; - - /*vcpu life time cycles*/ - vcpu->hcpu_cycles = sys_clock_cycle_get_32(); - thread = vcpu->work->vcpu_thread; - - switch (cur_state) { - case _VCPU_STATE_READY: - case _VCPU_STATE_UNKNOWN: - k_thread_start(thread); - vcpu->vcpu_state = _VCPU_STATE_READY; - break; - case _VCPU_STATE_PAUSED: - vcpu_state_switch(thread, _VCPU_STATE_READY); - break; - default: - /* Handle invalid state */ - ZVM_LOG_WARN("Unknow vcpu states! \n"); - break; - } - return 0; + return vcpu_state_switch(vcpu->work->vcpu_thread, _VCPU_STATE_READY); } int vm_vcpu_pause(struct vcpu *vcpu) diff --git a/subsys/virtualization/vm_dev.c b/subsys/virtualization/vm_dev.c index c82095ab703f4bdd515a517de7ddec924367c3d5..8309f98846763a210387a06046af948586f21d90 100644 --- a/subsys/virtualization/vm_dev.c +++ b/subsys/virtualization/vm_dev.c @@ -54,7 +54,6 @@ struct virt_dev *vm_virt_dev_add(struct vm *vm, const char *dev_name, bool pt_fl vm_dev = (struct virt_dev *)k_malloc(sizeof(struct virt_dev)); if (!vm_dev) { - ZVM_LOG_ERR("Allocate memory for vm device error!\n"); return NULL; } @@ -71,17 +70,24 @@ struct virt_dev *vm_virt_dev_add(struct vm *vm, const char *dev_name, bool pt_fl ret = vm_vdev_mem_add(vm, vm_dev); if(ret){ - ZVM_LOG_ERR("Map vm device memory error!\n"); return NULL; } vm_dev->virq = dev_virq; vm_dev->hirq = dev_hirq; vm_dev->vm = vm; + + /*Init private data and vdev*/ + vm_dev->priv_data = NULL; + vm_dev->priv_vdev = NULL; + sys_dlist_append(&vm->vdev_list, &vm_dev->vdev_node); return vm_dev; } +#define DEV_DATA(dev) \ + ((struct virt_device_data *)(dev)->data) + int vdev_mmio_abort(arch_commom_regs_t *regs, int write, uint64_t addr, uint64_t *value, uint16_t size) { @@ -89,31 +95,36 @@ int vdev_mmio_abort(arch_commom_regs_t *regs, int write, uint64_t addr, struct vm *vm; struct virt_dev *vdev; struct _dnode *d_node, *ds_node; + struct virtual_device_instance *vdevice_instance; const struct device *dev; vm = get_current_vm(); SYS_DLIST_FOR_EACH_NODE_SAFE(&vm->vdev_list, d_node, ds_node){ vdev = CONTAINER_OF(d_node, struct virt_dev, vdev_node); - + vdevice_instance = (struct virtual_device_instance *)vdev->priv_data; + /*shareable device, which is used for virtio mmio. */ if (vdev->shareable) { if ((addr >= vdev->vm_vdev_vaddr) && (addr < vdev->vm_vdev_vaddr + vdev->vm_vdev_size)) { dev = (const struct device* const)vdev->priv_data; if (write) { - return ((struct virtio_mmio_driver_api *)((struct virt_device_api *)dev->api)->device_driver_api)->write(vdev, addr - vdev->vm_vdev_vaddr, 0, (uint32_t)*reg_value, size); + return ((struct virtio_mmio_driver_api *)((struct virt_device_api \ + *)dev->api)->device_driver_api)->write(vdev, addr - vdev->vm_vdev_vaddr, 0, (uint32_t)*reg_value, size); } else { - return ((struct virtio_mmio_driver_api *)((struct virt_device_api *)dev->api)->device_driver_api)->read(vdev, addr - vdev->vm_vdev_vaddr, (uint32_t *)reg_value, size); + return ((struct virtio_mmio_driver_api *)((struct virt_device_api \ + *)dev->api)->device_driver_api)->read(vdev, addr - vdev->vm_vdev_vaddr, (uint32_t *)reg_value, size); } } - } else { - if ((addr >= vdev->vm_vdev_paddr) && (addr < vdev->vm_vdev_paddr + vdev->vm_vdev_size)) { - dev = (const struct device* const)vdev->priv_vdev; - if (write) { - return ((const struct virt_device_api * \ - const)(dev->api))->virt_device_write(vdev, addr, reg_value); - }else{ - return ((const struct virt_device_api * \ - const)(dev->api))->virt_device_read(vdev, addr, reg_value); + }else if(vdevice_instance != NULL){ + if(DEV_DATA(vdevice_instance)->vdevice_type & VM_DEVICE_PRE_KERNEL_1){ + if ((addr >= vdev->vm_vdev_paddr) && (addr < vdev->vm_vdev_paddr + vdev->vm_vdev_size)) { + if (write) { + return ((const struct virt_device_api * \ + const)(vdevice_instance->api))->virt_device_write(vdev, addr, reg_value); + }else{ + return ((const struct virt_device_api * \ + const)(vdevice_instance->api))->virt_device_read(vdev, addr, reg_value); + } } } } @@ -199,31 +210,36 @@ int handle_vm_device_emulate(struct vm *vm, uint64_t pa_addr) return -ENODEV; } +#ifdef CONFIG_VM_VIRTIO_MMIO static void zvm_virtio_emu_register(void) { #ifdef CONFIG_VM_VIRTIO_BLOCK virtio_register_emulator(&virtio_blk); #endif } +#endif int vm_device_init(struct vm *vm) { - int ret; + int ret, i; sys_dlist_init(&vm->vdev_list); - - ret = vm_intctrl_vdev_create(vm); - if (ret) { - ZVM_LOG_WARN(" Init interrupt controller device error! \n"); - return -ENODEV; - } - ret = vm_console_create(vm); if (ret) { ZVM_LOG_WARN("Init vm debug console error! \n"); return -EMMAO; } + /* Assign ids to virtual devices. */ + for (i = 0; i < zvm_virtual_devices_count_get(); i++) { + const struct virtual_device_instance *virtual_device = zvm_virtual_device_get(i); + ZVM_LOG_INFO("Device name: %s. \n", virtual_device->name); + /*If the virtual device is nessenary for vm*/ + if(virtual_device->data->vdevice_type & VM_DEVICE_PRE_KERNEL_1){ + virtual_device->api->init_fn(NULL, vm, NULL); + } + } + #ifdef CONFIG_VM_VIRTIO_MMIO virtio_dev_list_init(); virtio_drv_list_init(); @@ -232,6 +248,8 @@ int vm_device_init(struct vm *vm) /* @TODO: scan the dtb and get the device's node. */ /* Board specific device init, for example fig debugger. */ switch (vm->os->type){ + case OS_TYPE_ZEPHYR: + break; case OS_TYPE_LINUX: ret = vm_init_bdspecific_device(vm); break; diff --git a/subsys/virtualization/vm_irq.c b/subsys/virtualization/vm_irq.c index 4464a3ae40f87dbab772bcc119c55f847e9bb17e..f3d7f9e53cef308dec784b84043a43981c9eb695 100644 --- a/subsys/virtualization/vm_irq.c +++ b/subsys/virtualization/vm_irq.c @@ -15,6 +15,69 @@ LOG_MODULE_DECLARE(ZVM_MODULE_NAME); +#define VWFI_YIELD_THRESHOLD 100 + +bool vcpu_irq_exist(struct vcpu *vcpu) +{ + bool pend, active; + struct vcpu_virt_irq_block *vb = &vcpu->virq_block; + + pend = sys_dlist_is_empty(&vb->pending_irqs); + active = sys_dlist_is_empty(&vb->active_irqs); + + if((!(pend && active)) || arch_irq_ispending(vcpu)){ + return true; + } + + return false; +} + +int vcpu_wait_for_irq(struct vcpu *vcpu) +{ + bool irq_exist, vcpu_will_yeild=false, vcpu_will_pause=false; + k_spinlock_key_t key; + + /* judge whether the vcpu has pending or active irq */ + irq_exist = vcpu_irq_exist(vcpu); + key = k_spin_lock(&vcpu->virq_block.vwfi.wfi_lock); + + if(irq_exist){ + vcpu->virq_block.vwfi.yeild_count=0; + goto done; + }else if(vcpu->virq_block.vwfi.yeild_count < VWFI_YIELD_THRESHOLD){ + vcpu->virq_block.vwfi.yeild_count++; + vcpu_will_yeild = true; + goto done; + } + + if(!vcpu->virq_block.vwfi.state){ + vcpu_will_pause = true; + vcpu->virq_block.vwfi.state = true; + /*start wfi timeout*/ + } + +done: + k_spin_unlock(&vcpu->virq_block.vwfi.wfi_lock, key); + + if(vcpu_will_yeild){ + /*yeild this thread*/ + } + + if(vcpu_will_pause){ + irq_exist = vcpu_irq_exist(vcpu); + if(irq_exist){ + key = k_spin_lock(&vcpu->virq_block.vwfi.wfi_lock); + vcpu->virq_block.vwfi.yeild_count=0; + vcpu->virq_block.vwfi.state=false; + /*end wfi timeout*/ + k_spin_unlock(&vcpu->virq_block.vwfi.wfi_lock, key); + } + } + + return 0; + +} + /** * @brief Init call for creating interrupt control block for vm. */ @@ -53,7 +116,7 @@ static int vm_virq_desc_init(struct vm *vm) for (i = 0; i < VM_SPI_VIRQ_NR; i++) { desc = &vm->vm_irq_block.vm_virt_irq_desc[i]; - desc->virq_flags = VIRQ_NOUSED_FLAG | VIRQ_HW_FLAG; + desc->virq_flags = 0; /* For shared irq, it shared with all cores */ desc->vcpu_id = DEFAULT_VCPU; desc->vm_id = vm->vmid; @@ -72,21 +135,23 @@ static int vm_virq_desc_init(struct vm *vm) void vm_device_irq_init(struct vm *vm, struct virt_dev *vm_dev) { - bool *bit_addr; + bool *bit_map; struct virt_irq_desc *desc; desc = get_virt_irq_desc(vm->vcpus[DEFAULT_VCPU], vm_dev->virq); if(vm_dev->dev_pt_flag){ - desc->virq_flags = VIRQ_NOUSED_FLAG | VIRQ_HW_FLAG; + desc->virq_flags |= VIRQ_HW_FLAG; }else{ ZVM_LOG_ERR("There is no supported virtual interrupt"); } desc->id = desc->virq_num; desc->pirq_num = vm_dev->hirq; desc->virq_num = vm_dev->virq; - - bit_addr = vm->vm_irq_block.irq_bitmap; - bit_addr[vm_dev->hirq] = true; + /*For passthrough device, using fast irq path. */ + if(vm_dev->dev_pt_flag){ + bit_map = vm->vm_irq_block.irq_bitmap; + bit_map[vm_dev->hirq] = true; + } } int vm_irq_block_init(struct vm *vm) diff --git a/subsys/virtualization/vm_manager.c b/subsys/virtualization/vm_manager.c index 427822570b02fe5eb171cfa0e54b487badb1c5f5..c890d6c6cdd0e505a85e79abd2e52b7db80b7506 100644 --- a/subsys/virtualization/vm_manager.c +++ b/subsys/virtualization/vm_manager.c @@ -130,7 +130,7 @@ int zvm_run_guest(size_t argc, char **argv) if (vm->vm_status & VM_STATE_NEVER_RUN) { load_os_image(vm); } - vm_vcpus_run(vm); + vm_vcpus_ready(vm); } else { ZVM_LOG_WARN("The VM has a invalid status, abort! \n"); return -ENODEV; diff --git a/subsys/virtualization/zvm.c b/subsys/virtualization/zvm.c index 8c451ad22b8bc8ad7a39bdfd55460affad51e54f..365dbfd0dae574299ad49d4d7c7098fdd52802b7 100644 --- a/subsys/virtualization/zvm.c +++ b/subsys/virtualization/zvm.c @@ -190,7 +190,7 @@ int zvm_init_idle_device(const struct device *dev, struct virt_dev *vdev, { uint16_t name_len; struct virt_dev *vm_dev = vdev; - + /*TODO:Determine whether to connect directly based on device type*/ vm_dev->dev_pt_flag = true; @@ -225,7 +225,7 @@ int zvm_init_idle_device(const struct device *dev, struct virt_dev *vdev, /** * @brief Provide physical dev info to zvm system: * 1. Find all available devices information on the board; - * 2. Build a idle dev list for the system; + * 2. Build a idle hardwar device list for the system; * 3. VM init function can get dev info from it. * @return int */