arm/tk1: addresses/interrupts for hyp mode

This commit is contained in:
Yanyan Shen 2016-05-04 16:53:27 +10:00
parent c13eeffddc
commit fa9b6e4312
3 changed files with 29 additions and 5 deletions

View file

@ -211,13 +211,19 @@ enum IRQConstants {
maxIRQ = 192
} platform_interrupt_t;
#define INTERRUPT_S_PGPT INTERRUPT_PPI_13
#define INTERRUPT_NS_PGPT INTERRUPT_PPI_14
#define INTERRUPT_VGPT INTERRUPT_PPI_11
#define INTERRUPT_HGPT INTERRUPT_PPI_10
#define INTERRUPT_VGIC_MAINTENANCE INTERRUPT_PPI_9
#define INTERRUPT_S_PGPT INTERRUPT_PPI_13
#define INTERRUPT_NS_PGPT INTERRUPT_PPI_14
#define INTERRUPT_VGPT INTERRUPT_PPI_11
#define INTERRUPT_HGPT INTERRUPT_PPI_10
/* the kernel runs in secure supervisor mode by default */
#ifdef ARM_HYP
#define KERNEL_TIMER_IRQ INTERRUPT_HGPT
#else
#define KERNEL_TIMER_IRQ INTERRUPT_S_PGPT
#endif
enum irqNumbers {
irqInvalid = 255

View file

@ -26,6 +26,10 @@
#define GIC_DISTRIBUTOR_PADDR GICD_PADDR
#define GIC_CONTROLLER0_PADDR GICI_PADDR
/* HYP mode kernel devices */
#define GIC_VCPUCTRL_PPTR 0xfff06000
#define GIC_PL400_VCPUCTRL_PPTR GIC_VCPUCTRL_PPTR
#define GIC_VCPUCTRL_PADDR (VGICI_REQ_PADDR)
/*
* many of the device regions are not 4K page aligned, so some regions may contain more than
* one devices. it is the user's responsibilty to figure out how to use these regions

View file

@ -84,6 +84,12 @@
#define VGIC_IRQ_ACTIVE (0x2U << 28)
#define VGIC_IRQ_MASK (0x3U << 28)
#define VIRQ_GROUP_MASK (1)
#define VIRQ_GROUP_SHIFT (30)
#define VIRQ_PRIORITY_MASK (0x1f)
#define VIRQ_PRIORITY_SHIFT (23)
#define VIRQ_IRQ_MASK (0x3ff)
struct gich_vcpu_ctrl_map {
uint32_t hcr; /* 0x000 RW 0x00000000 Hypervisor Control Register */
uint32_t vtr; /* 0x004 RO IMPLEMENTATION DEFINED VGIC Type Register */
@ -354,10 +360,18 @@ decodeVCPUReadReg(cap_t cap, unsigned int length, word_t* buffer)
return invokeVCPUReadReg(VCPU_PTR(cap_vcpu_cap_get_capVCPUPtr(cap)), field);
}
static uint32_t makeVIRQ(int group, int priority, int irq)
{
uint32_t virq = ((group & VIRQ_GROUP_MASK) << VIRQ_GROUP_SHIFT);
virq |= ((priority & VIRQ_PRIORITY_MASK) << VIRQ_PRIORITY_SHIFT);
virq |= (irq & VIRQ_IRQ_MASK);
return virq;
}
exception_t
invokeVCPUInjectIRQ(vcpu_t* vcpu, int index, int group, int priority, int irq)
{
vcpu->vgic.lr[index] = (group << 30) | (priority << 23) | (irq << 0);
vcpu->vgic.lr[index] = makeVIRQ(group, priority, irq);
vcpu->vgic.lr[index] |= VGIC_IRQ_PENDING | VGIC_LR_EOIIRQEN;
setThreadState(ksCurThread, ThreadState_Restart);