lapic: continuous LVT registers as an array
Pointer arithmetic is currently used to calculate the address of a specific Local Vector Table (LVT) register (except LVT_CMCI) in lapic, since the registers are continuously placed with fixed padding in between. However each of these registers are declared as a single uint32_t in struct lapic, resulting pointer arithmetic on a non-array pointer which violates MISRA C requirements. This patch refactors struct lapic by converting the LVT registers fields (again except LVT_CMCI) to an array named lvt. The LVT indices are reordered to reflect the order of the LVT registers on hardware, and reused to index this lvt array. The code before and after the changes is semantically equivalent. Signed-off-by: Junjie Mao <junjie.mao@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
parent
9a604ed00e
commit
2266e133fb
|
@ -227,28 +227,28 @@ vlapic_id_write_handler(struct vlapic *vlapic)
|
|||
static inline bool
|
||||
vlapic_lvtt_oneshot(struct vlapic *vlapic)
|
||||
{
|
||||
return ((vlapic->apic_page->lvt_timer & APIC_LVTT_TM)
|
||||
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM)
|
||||
== APIC_LVTT_TM_ONE_SHOT);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
vlapic_lvtt_period(struct vlapic *vlapic)
|
||||
{
|
||||
return ((vlapic->apic_page->lvt_timer & APIC_LVTT_TM)
|
||||
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM)
|
||||
== APIC_LVTT_TM_PERIODIC);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
vlapic_lvtt_tsc_deadline(struct vlapic *vlapic)
|
||||
{
|
||||
return ((vlapic->apic_page->lvt_timer & APIC_LVTT_TM)
|
||||
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM)
|
||||
== APIC_LVTT_TM_TSCDLT);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
vlapic_lvtt_masked(struct vlapic *vlapic)
|
||||
{
|
||||
return !!(vlapic->apic_page->lvt_timer & APIC_LVTT_M);
|
||||
return !!(vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_M);
|
||||
}
|
||||
|
||||
static void vlapic_create_timer(struct vlapic *vlapic)
|
||||
|
@ -416,28 +416,6 @@ vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static inline uint32_t *
|
||||
vlapic_get_lvtptr(struct vlapic *vlapic, uint32_t offset)
|
||||
{
|
||||
struct lapic *lapic = vlapic->apic_page;
|
||||
int i;
|
||||
|
||||
switch (offset) {
|
||||
case APIC_OFFSET_CMCI_LVT:
|
||||
return &lapic->lvt_cmci;
|
||||
case APIC_OFFSET_TIMER_LVT:
|
||||
case APIC_OFFSET_THERM_LVT:
|
||||
case APIC_OFFSET_PERF_LVT:
|
||||
case APIC_OFFSET_LINT0_LVT:
|
||||
case APIC_OFFSET_LINT1_LVT:
|
||||
case APIC_OFFSET_ERROR_LVT:
|
||||
i = (offset - APIC_OFFSET_TIMER_LVT) >> 2;
|
||||
return (&lapic->lvt_timer) + i;
|
||||
default:
|
||||
panic("vlapic_get_lvt: invalid LVT\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
lvt_off_to_idx(uint32_t offset)
|
||||
{
|
||||
|
@ -476,6 +454,28 @@ lvt_off_to_idx(uint32_t offset)
|
|||
return index;
|
||||
}
|
||||
|
||||
static inline uint32_t *
|
||||
vlapic_get_lvtptr(struct vlapic *vlapic, uint32_t offset)
|
||||
{
|
||||
struct lapic *lapic = vlapic->apic_page;
|
||||
int i;
|
||||
|
||||
switch (offset) {
|
||||
case APIC_OFFSET_CMCI_LVT:
|
||||
return &lapic->lvt_cmci;
|
||||
case APIC_OFFSET_TIMER_LVT:
|
||||
case APIC_OFFSET_THERM_LVT:
|
||||
case APIC_OFFSET_PERF_LVT:
|
||||
case APIC_OFFSET_LINT0_LVT:
|
||||
case APIC_OFFSET_LINT1_LVT:
|
||||
case APIC_OFFSET_ERROR_LVT:
|
||||
i = lvt_off_to_idx(offset);
|
||||
return &(lapic->lvt[i].val);
|
||||
default:
|
||||
panic("vlapic_get_lvt: invalid LVT\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
vlapic_get_lvt(struct vlapic *vlapic, uint32_t offset)
|
||||
{
|
||||
|
@ -557,22 +557,22 @@ vlapic_mask_lvts(struct vlapic *vlapic)
|
|||
lapic->lvt_cmci |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_CMCI_LVT);
|
||||
|
||||
lapic->lvt_timer |= APIC_LVT_M;
|
||||
lapic->lvt[APIC_LVT_TIMER].val |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_TIMER_LVT);
|
||||
|
||||
lapic->lvt_thermal |= APIC_LVT_M;
|
||||
lapic->lvt[APIC_LVT_THERMAL].val |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_THERM_LVT);
|
||||
|
||||
lapic->lvt_pcint |= APIC_LVT_M;
|
||||
lapic->lvt[APIC_LVT_PMC].val |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_PERF_LVT);
|
||||
|
||||
lapic->lvt_lint0 |= APIC_LVT_M;
|
||||
lapic->lvt[APIC_LVT_LINT0].val |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_LINT0_LVT);
|
||||
|
||||
lapic->lvt_lint1 |= APIC_LVT_M;
|
||||
lapic->lvt[APIC_LVT_LINT1].val |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_LINT1_LVT);
|
||||
|
||||
lapic->lvt_error |= APIC_LVT_M;
|
||||
lapic->lvt[APIC_LVT_ERROR].val |= APIC_LVT_M;
|
||||
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_ERROR_LVT);
|
||||
}
|
||||
|
||||
|
@ -1500,10 +1500,10 @@ void vlapic_restore(struct vlapic *vlapic, struct lapic_regs *regs)
|
|||
lapic->tmr[i].val = regs->tmr[i];
|
||||
lapic->svr = regs->svr;
|
||||
vlapic_svr_write_handler(vlapic);
|
||||
lapic->lvt_timer = regs->lvtt;
|
||||
lapic->lvt_lint0 = regs->lvt0;
|
||||
lapic->lvt_lint1 = regs->lvt1;
|
||||
lapic->lvt_error = regs->lvterr;
|
||||
lapic->lvt[APIC_LVT_TIMER].val = regs->lvtt;
|
||||
lapic->lvt[APIC_LVT_LINT0].val = regs->lvt0;
|
||||
lapic->lvt[APIC_LVT_LINT1].val = regs->lvt1;
|
||||
lapic->lvt[APIC_LVT_ERROR].val = regs->lvterr;
|
||||
lapic->icr_timer = regs->ticr;
|
||||
lapic->ccr_timer = regs->tccr;
|
||||
lapic->dcr_timer = regs->tdcr;
|
||||
|
@ -1788,7 +1788,7 @@ static int vlapic_timer_expired(void *data)
|
|||
|
||||
/* inject vcpu timer interrupt if not masked */
|
||||
if (!vlapic_lvtt_masked(vlapic))
|
||||
vlapic_intr_edge(vcpu, lapic->lvt_timer & APIC_LVTT_VECTOR);
|
||||
vlapic_intr_edge(vcpu, lapic->lvt[APIC_LVT_TIMER].val & APIC_LVTT_VECTOR);
|
||||
|
||||
if (!vlapic_lvtt_period(vlapic))
|
||||
vlapic->vlapic_timer.timer.fire_tsc = 0;
|
||||
|
|
|
@ -158,12 +158,7 @@ struct lapic {
|
|||
uint32_t lvt_cmci; PAD3;
|
||||
uint32_t icr_lo; PAD3;
|
||||
uint32_t icr_hi; PAD3;
|
||||
uint32_t lvt_timer; PAD3;
|
||||
uint32_t lvt_thermal; PAD3;
|
||||
uint32_t lvt_pcint; PAD3;
|
||||
uint32_t lvt_lint0; PAD3;
|
||||
uint32_t lvt_lint1; PAD3;
|
||||
uint32_t lvt_error; PAD3;
|
||||
struct lapic_reg lvt[6];
|
||||
uint32_t icr_timer; PAD3;
|
||||
uint32_t ccr_timer; PAD3;
|
||||
/* reserved */ PAD4;
|
||||
|
@ -421,12 +416,12 @@ struct ioapic {
|
|||
#define APIC_EXTF_IER_CAP 0x00000001
|
||||
|
||||
/* LVT table indices */
|
||||
#define APIC_LVT_LINT0 0
|
||||
#define APIC_LVT_LINT1 1
|
||||
#define APIC_LVT_TIMER 2
|
||||
#define APIC_LVT_ERROR 3
|
||||
#define APIC_LVT_PMC 4
|
||||
#define APIC_LVT_THERMAL 5
|
||||
#define APIC_LVT_TIMER 0
|
||||
#define APIC_LVT_THERMAL 1
|
||||
#define APIC_LVT_PMC 2
|
||||
#define APIC_LVT_LINT0 3
|
||||
#define APIC_LVT_LINT1 4
|
||||
#define APIC_LVT_ERROR 5
|
||||
#define APIC_LVT_CMCI 6
|
||||
#define APIC_LVT_MAX APIC_LVT_CMCI
|
||||
|
||||
|
|
Loading…
Reference in New Issue