acrn-hypervisor/hypervisor/include/arch/x86/ioapic.h
Junjie Mao a1069a5117 HV: ioapic: unify the access pattern to RTEs
There are two different ways the current implementation adopts to access ioapic
RTEs:

    1. As two 32-bit registers (typically named ''low'' and ''high''), or

    2. As one 64-bit register (typically named ''rte'').

Two issues arise due to the mixed use of these two patterns.

    1. Additional conversions are introduced. As an example, ioapic_get_rte()
       merges two RTE fragments into a uint64_t, while some callers break it
       back to ''low'' and ''high'' again.

    2. It is tricky to choose the proper width of IOAPIC_RTE_xxx constants. SOS
       boot failure is seen when they are 32-bit due to the following code:

           /* reg is uint64_t */
           vioapic->rtbl[pin].reg &= ~IOAPIC_RTE_REM_IRR;

       while making them 64-bit leads to implicit narrowing when the RTEs are accessed
       in the low & high pattern.

This patch defines a union ''ioapic_rte'' and unifies the access pattern
to IOAPIC and vIOAPIC RTEs.

v1 -> v2:

    * Instead of two 32-bit ''low'' and ''high'', define a union that allows
      either 32-bit or 64-bit accesses to RTEs.

Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
2018-07-17 15:37:45 +08:00

43 lines
1.1 KiB
C

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IOAPIC_H
#define IOAPIC_H
/* IOAPIC_MAX_LINES is architecturally defined.
* The usable RTEs may be a subset of the total on a per IO APIC basis.
*/
#define IOAPIC_MAX_LINES 120U
#define NR_LEGACY_IRQ 16U
#define NR_LEGACY_PIN NR_LEGACY_IRQ
#define NR_MAX_GSI (CONFIG_NR_IOAPICS*IOAPIC_MAX_LINES)
#define GSI_MASK_IRQ(irq) irq_gsi_mask_unmask((irq), true)
#define GSI_UNMASK_IRQ(irq) irq_gsi_mask_unmask((irq), false)
void setup_ioapic_irq(void);
bool irq_is_gsi(uint32_t irq);
uint32_t irq_gsi_num(void);
uint8_t irq_to_pin(uint32_t irq);
uint32_t pin_to_irq(uint8_t pin);
void irq_gsi_mask_unmask(uint32_t irq, bool mask);
void ioapic_set_rte(uint32_t irq, union ioapic_rte rte);
void ioapic_get_rte(uint32_t irq, union ioapic_rte *rte);
void suspend_ioapic(void);
void resume_ioapic(void);
extern uint8_t legacy_irq_to_pin[];
extern uint8_t pic_ioapic_pin_map[];
#ifdef HV_DEBUG
int get_ioapic_info(char *str, int str_max_len);
#endif /* HV_DEBUG */
#endif /* IOAPIC_H */