diff --git a/hypervisor/arch/x86/ioapic.c b/hypervisor/arch/x86/ioapic.c index 18171d4fe..9205c3894 100644 --- a/hypervisor/arch/x86/ioapic.c +++ b/hypervisor/arch/x86/ioapic.c @@ -9,13 +9,8 @@ #define IOAPIC_MAX_PIN 240U #define IOAPIC_INVALID_PIN 0xffU -struct gsi_table { - uint8_t ioapic_id; - uint8_t pin; - void *addr; -}; -static struct gsi_table gsi_table[NR_MAX_GSI]; -static uint32_t nr_gsi; +struct gsi_table gsi_table[NR_MAX_GSI]; +uint32_t nr_gsi; static spinlock_t ioapic_lock; static union ioapic_rte saved_rte[NR_IOAPICS][IOAPIC_MAX_PIN]; @@ -134,9 +129,7 @@ get_ioapic_base(uint8_t apic_id) return addr[apic_id]; } -static inline void -ioapic_get_rte_entry(void *ioapic_addr, - uint8_t pin, union ioapic_rte *rte) +void ioapic_get_rte_entry(void *ioapic_addr, uint8_t pin, union ioapic_rte *rte) { uint32_t rte_addr = ((uint32_t)pin * 2U) + 0x10U; rte->u.lo_32 = ioapic_read_reg32(ioapic_addr, rte_addr); @@ -425,67 +418,3 @@ void resume_ioapic(void) } } } - -#ifdef HV_DEBUG -static void get_rte_info(union ioapic_rte rte, bool *mask, bool *irr, - bool *phys, uint32_t *delmode, bool *level, uint32_t *vector, uint32_t *dest) -{ - *mask = ((rte.full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMSET); - *irr = ((rte.full & IOAPIC_RTE_REM_IRR) == IOAPIC_RTE_REM_IRR); - *phys = ((rte.full & IOAPIC_RTE_DESTMOD) == IOAPIC_RTE_DESTPHY); - *delmode = (uint32_t)(rte.full & IOAPIC_RTE_DELMOD); - *level = ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL); - *vector = (uint32_t)(rte.full & IOAPIC_RTE_INTVEC); - *dest = (uint32_t)(rte.full >> APIC_ID_SHIFT); -} - -int get_ioapic_info(char *str_arg, size_t str_max_len) -{ - char *str = str_arg; - uint32_t irq; - size_t len, size = str_max_len; - - len = snprintf(str, size, "\r\nIRQ\tPIN\tRTE.HI32\tRTE.LO32\tVEC\tDST\tDM\tTM\tDELM\tIRR\tMASK"); - if (len >= size) { - goto overflow; - } - size -= len; - str += len; - - for (irq = 0U; irq < nr_gsi; irq++) { - void *addr = gsi_table[irq].addr; - uint8_t pin = gsi_table[irq].pin; - union ioapic_rte rte; - - bool irr, phys, level, mask; - uint32_t delmode, vector, dest; - - ioapic_get_rte_entry(addr, pin, &rte); - - get_rte_info(rte, &mask, &irr, &phys, &delmode, &level, - &vector, &dest); - - len = snprintf(str, size, "\r\n%03d\t%03hhu\t0x%08X\t0x%08X\t", irq, pin, rte.u.hi_32, rte.u.lo_32); - if (len >= size) { - goto overflow; - } - size -= len; - str += len; - - len = snprintf(str, size, "0x%02X\t0x%02X\t%s\t%s\t%u\t%d\t%d", - vector, dest, phys ? "phys" : "logic", level ? "level" : "edge", delmode >> 8, irr, mask); - if (len >= size) { - goto overflow; - } - size -= len; - str += len; - } - - snprintf(str, size, "\r\n"); - return 0; - -overflow: - printf("buffer size could not be enough! please check!\n"); - return 0; -} -#endif /* HV_DEBUG */ diff --git a/hypervisor/debug/shell.c b/hypervisor/debug/shell.c index 088b4424a..88d6705e8 100644 --- a/hypervisor/debug/shell.c +++ b/hypervisor/debug/shell.c @@ -790,6 +790,76 @@ static int shell_show_vioapic_info(int argc, char **argv) return -EINVAL; } +static void get_rte_info(union ioapic_rte rte, bool *mask, bool *irr, + bool *phys, uint32_t *delmode, bool *level, uint32_t *vector, uint32_t *dest) +{ + *mask = ((rte.full & IOAPIC_RTE_INTMASK) == IOAPIC_RTE_INTMSET); + *irr = ((rte.full & IOAPIC_RTE_REM_IRR) == IOAPIC_RTE_REM_IRR); + *phys = ((rte.full & IOAPIC_RTE_DESTMOD) == IOAPIC_RTE_DESTPHY); + *delmode = (uint32_t)(rte.full & IOAPIC_RTE_DELMOD); + *level = ((rte.full & IOAPIC_RTE_TRGRLVL) != 0UL); + *vector = (uint32_t)(rte.full & IOAPIC_RTE_INTVEC); + *dest = (uint32_t)(rte.full >> APIC_ID_SHIFT); +} + +/** + * @brief Get information of ioapic + * + * It's for debug only. + * + * @param[in] str_max_len The max size of the string containing + * interrupt info + * @param[inout] str_arg Pointer to the output information + */ +static int get_ioapic_info(char *str_arg, size_t str_max_len) +{ + char *str = str_arg; + uint32_t irq; + size_t len, size = str_max_len; + + len = snprintf(str, size, "\r\nIRQ\tPIN\tRTE.HI32\tRTE.LO32\tVEC\tDST\tDM\tTM\tDELM\tIRR\tMASK"); + if (len >= size) { + goto overflow; + } + size -= len; + str += len; + + for (irq = 0U; irq < nr_gsi; irq++) { + void *addr = gsi_table[irq].addr; + uint8_t pin = gsi_table[irq].pin; + union ioapic_rte rte; + + bool irr, phys, level, mask; + uint32_t delmode, vector, dest; + + ioapic_get_rte_entry(addr, pin, &rte); + + get_rte_info(rte, &mask, &irr, &phys, &delmode, &level, &vector, &dest); + + len = snprintf(str, size, "\r\n%03d\t%03hhu\t0x%08X\t0x%08X\t", irq, pin, rte.u.hi_32, rte.u.lo_32); + if (len >= size) { + goto overflow; + } + size -= len; + str += len; + + len = snprintf(str, size, "0x%02X\t0x%02X\t%s\t%s\t%u\t%d\t%d", + vector, dest, phys ? "phys" : "logic", level ? "level" : "edge", delmode >> 8, irr, mask); + if (len >= size) { + goto overflow; + } + size -= len; + str += len; + } + + snprintf(str, size, "\r\n"); + return 0; + +overflow: + printf("buffer size could not be enough! please check!\n"); + return 0; +} + static int shell_show_ioapic_info(__unused int argc, __unused char **argv) { int err = 0; diff --git a/hypervisor/include/arch/x86/ioapic.h b/hypervisor/include/arch/x86/ioapic.h index 9a91c51b4..cadb5c0eb 100644 --- a/hypervisor/include/arch/x86/ioapic.h +++ b/hypervisor/include/arch/x86/ioapic.h @@ -7,6 +7,8 @@ #ifndef IOAPIC_H #define IOAPIC_H +#include + /* * IOAPIC_MAX_LINES is architecturally defined. * The usable RTEs may be a subset of the total on a per IO APIC basis. @@ -56,19 +58,16 @@ void resume_ioapic(void); void gsi_mask_irq(uint32_t irq); void gsi_unmask_irq(uint32_t irq); +void ioapic_get_rte_entry(void *ioapic_addr, uint8_t pin, union ioapic_rte *rte); + +struct gsi_table { + uint8_t ioapic_id; + uint8_t pin; + void *addr; +}; + +extern struct gsi_table gsi_table[NR_MAX_GSI]; +extern uint32_t nr_gsi; extern uint8_t pic_ioapic_pin_map[NR_LEGACY_PIN]; -#ifdef HV_DEBUG -/** - * @brief Get information of ioapic - * - * It's for debug only. - * - * @param[in] str_max_len The max size of the string containing - * interrupt info - * @param[inout] str_arg Pointer to the output information - */ -int get_ioapic_info(char *str_arg, size_t str_max_len); -#endif /* HV_DEBUG */ - #endif /* IOAPIC_H */