66#include <arch/vgic.h>
77#include <arch/vgicv3.h>
88
9+ #include <arch/gicv3.h>
10+
911#include <bit.h>
1012#include <spinlock.h>
1113#include <cpu.h>
@@ -318,10 +320,75 @@ static bool vgic_icc_sre_handler(struct emul_access* acc)
318320 return true;
319321}
320322
323+ void vgic_cpu_reset (struct vcpu * vcpu )
324+ {
325+ for (irqid_t i = 0 ; i < GIC_CPU_PRIV ; i ++ ) {
326+ vcpu -> arch .vgic_priv .interrupts [i ].owner = NULL ;
327+ vcpu -> arch .vgic_priv .interrupts [i ].lock = SPINLOCK_INITVAL ;
328+ vcpu -> arch .vgic_priv .interrupts [i ].state = INV ;
329+ vcpu -> arch .vgic_priv .interrupts [i ].prio = GIC_LOWEST_PRIO ;
330+ vcpu -> arch .vgic_priv .interrupts [i ].cfg = 0 ;
331+ vcpu -> arch .vgic_priv .interrupts [i ].route = GICD_IROUTER_INV ;
332+ vcpu -> arch .vgic_priv .interrupts [i ].phys .redist = vcpu -> phys_id ;
333+ vcpu -> arch .vgic_priv .interrupts [i ].in_lr = false;
334+ vcpu -> arch .vgic_priv .interrupts [i ].enabled = false;
335+
336+ if (vcpu -> arch .vgic_priv .interrupts [i ].hw ) {
337+ gic_set_enable (i , false);
338+ gic_set_prio (i , GIC_LOWEST_PRIO );
339+ gic_set_act (i , false);
340+ gic_set_pend (i , false);
341+ // gicd_set_route(i, GICD_IROUTER_INV);
342+ }
343+ }
344+
345+ for (irqid_t i = 0 ; i < GIC_MAX_SGIS ; i ++ ) {
346+ vcpu -> arch .vgic_priv .interrupts [i ].cfg = 0x2 ;
347+ }
348+
349+ for (size_t i = 0 ; i < gich_num_lrs (); i ++ ) {
350+ gich_write_lr (i , 0 );
351+ }
352+
353+ // gich_set_hcr(0);
354+ gich_set_vmcr (0 );
355+ // TODO: reset gich apr registers
356+
357+ list_init (& vcpu -> arch .vgic_spilled );
358+ }
359+
360+ void vgic_reset (struct vm * vm )
361+ {
362+ for (irqid_t i = 0 ; i < vm -> arch .vgicd .int_num ; i ++ ) {
363+ vm -> arch .vgicd .interrupts [i ].owner = NULL ;
364+ vm -> arch .vgicd .interrupts [i ].lock = SPINLOCK_INITVAL ;
365+ vm -> arch .vgicd .interrupts [i ].state = INV ;
366+ vm -> arch .vgicd .interrupts [i ].prio = GIC_LOWEST_PRIO ;
367+ vm -> arch .vgicd .interrupts [i ].cfg = 0 ;
368+ vm -> arch .vgicd .interrupts [i ].route = GICD_IROUTER_INV ;
369+ vm -> arch .vgicd .interrupts [i ].phys .route = GICD_IROUTER_INV ;
370+ vm -> arch .vgicd .interrupts [i ].in_lr = false;
371+ vm -> arch .vgicd .interrupts [i ].enabled = false;
372+
373+ if (vm -> arch .vgicd .interrupts [i ].hw ) {
374+ irqid_t id = i + GIC_CPU_PRIV ;
375+ gic_set_enable (id , false);
376+ gic_set_prio (id , GIC_LOWEST_PRIO );
377+ gic_set_act (id , false);
378+ gic_set_pend (id , false);
379+ gicd_set_route (id , GICD_IROUTER_INV );
380+ }
381+ }
382+
383+ vm -> arch .vgicd .CTLR = 0 ;
384+
385+ list_init (& vm -> arch .vgic_spilled );
386+ vm -> arch .vgic_spilled_lock = SPINLOCK_INITVAL ;
387+ }
388+
321389void vgic_init (struct vm * vm , const struct vgic_dscrp * vgic_dscrp )
322390{
323391 vm -> arch .vgicr_addr = vgic_dscrp -> gicr_addr ;
324- vm -> arch .vgicd .CTLR = 0 ;
325392 size_t vtyper_itln = vgic_get_itln (vgic_dscrp );
326393 vm -> arch .vgicd .int_num = 32 * (vtyper_itln + 1 );
327394 vm -> arch .vgicd .TYPER = ((vtyper_itln << GICD_TYPER_ITLN_OFF ) & GICD_TYPER_ITLN_MSK ) |
@@ -336,17 +403,8 @@ void vgic_init(struct vm* vm, const struct vgic_dscrp* vgic_dscrp)
336403 }
337404
338405 for (irqid_t i = 0 ; i < vm -> arch .vgicd .int_num ; i ++ ) {
339- vm -> arch .vgicd .interrupts [i ].owner = NULL ;
340- vm -> arch .vgicd .interrupts [i ].lock = SPINLOCK_INITVAL ;
341406 vm -> arch .vgicd .interrupts [i ].id = i + GIC_CPU_PRIV ;
342- vm -> arch .vgicd .interrupts [i ].state = INV ;
343- vm -> arch .vgicd .interrupts [i ].prio = GIC_LOWEST_PRIO ;
344- vm -> arch .vgicd .interrupts [i ].cfg = 0 ;
345- vm -> arch .vgicd .interrupts [i ].route = GICD_IROUTER_INV ;
346- vm -> arch .vgicd .interrupts [i ].phys .route = GICD_IROUTER_INV ;
347407 vm -> arch .vgicd .interrupts [i ].hw = false;
348- vm -> arch .vgicd .interrupts [i ].in_lr = false;
349- vm -> arch .vgicd .interrupts [i ].enabled = false;
350408 }
351409
352410 vm -> arch .vgicd_emul = (struct emul_mem ){ .va_base = vgic_dscrp -> gicd_addr ,
@@ -377,29 +435,14 @@ void vgic_init(struct vm* vm, const struct vgic_dscrp* vgic_dscrp)
377435 .handler = vgic_icc_sre_handler };
378436 vm_emul_add_reg (vm , & vm -> arch .icc_sre_emul );
379437
380- list_init (& vm -> arch .vgic_spilled );
381- vm -> arch .vgic_spilled_lock = SPINLOCK_INITVAL ;
438+ vgic_reset (vm );
382439}
383440
384441void vgic_cpu_init (struct vcpu * vcpu )
385442{
386443 for (irqid_t i = 0 ; i < GIC_CPU_PRIV ; i ++ ) {
387- vcpu -> arch .vgic_priv .interrupts [i ].owner = NULL ;
388- vcpu -> arch .vgic_priv .interrupts [i ].lock = SPINLOCK_INITVAL ;
389444 vcpu -> arch .vgic_priv .interrupts [i ].id = i ;
390- vcpu -> arch .vgic_priv .interrupts [i ].state = INV ;
391- vcpu -> arch .vgic_priv .interrupts [i ].prio = GIC_LOWEST_PRIO ;
392- vcpu -> arch .vgic_priv .interrupts [i ].cfg = 0 ;
393- vcpu -> arch .vgic_priv .interrupts [i ].route = GICD_IROUTER_INV ;
394- vcpu -> arch .vgic_priv .interrupts [i ].phys .redist = vcpu -> phys_id ;
395- vcpu -> arch .vgic_priv .interrupts [i ].hw = false;
396- vcpu -> arch .vgic_priv .interrupts [i ].in_lr = false;
397- vcpu -> arch .vgic_priv .interrupts [i ].enabled = false;
398445 }
399446
400- for (irqid_t i = 0 ; i < GIC_MAX_SGIS ; i ++ ) {
401- vcpu -> arch .vgic_priv .interrupts [i ].cfg = 0x2 ;
402- }
403-
404- list_init (& vcpu -> arch .vgic_spilled );
447+ vgic_cpu_reset (vcpu );
405448}
0 commit comments