From c3ea652c1f885764041ae8ab7c23bfac36d8902a Mon Sep 17 00:00:00 2001 From: Travis Geiselbrecht Date: Sat, 6 Aug 2022 17:28:12 -0700 Subject: [PATCH] [platform][qemu-virt-m68k] fix timer interrupts The IRQ calculation for the virtio range was off by 8, which caused the virtio code to override the interrupt registration for the RTC, which caused it to stop firing. Clean up the #defines that define irq mappings to fix this issue. --- platform/qemu-virt-m68k/goldfish_rtc.c | 11 ++++++----- platform/qemu-virt-m68k/goldfish_tty.c | 10 +++++----- .../qemu-virt-m68k/include/platform/virt.h | 17 ++++++----------- platform/qemu-virt-m68k/pic.c | 18 +++++++++--------- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/platform/qemu-virt-m68k/goldfish_rtc.c b/platform/qemu-virt-m68k/goldfish_rtc.c index f3c93e47..ae6f7865 100644 --- a/platform/qemu-virt-m68k/goldfish_rtc.c +++ b/platform/qemu-virt-m68k/goldfish_rtc.c @@ -8,6 +8,7 @@ #include "platform_p.h" #include +#include #include #include #include @@ -23,7 +24,7 @@ // implementation of RTC at // https://github.com/qemu/qemu/blob/master/hw/rtc/goldfish_rtc.c -volatile unsigned int * const goldfish_rtc_base = (void *)VIRT_GF_RTC_MMIO_BASE; +volatile uint32_t * const goldfish_rtc_base = (void *)VIRT_GF_RTC_MMIO_BASE; // registers enum { @@ -42,11 +43,11 @@ static uint64_t system_boot_offset; static platform_timer_callback t_callback; static void *t_arg; -static void write_reg(int reg, uint32_t val) { +static void write_reg(unsigned int reg, uint32_t val) { goldfish_rtc_base[reg / 4] = val; } -static uint32_t read_reg(int reg) { +static uint32_t read_reg(unsigned int reg) { return goldfish_rtc_base[reg / 4]; } @@ -82,8 +83,8 @@ void goldfish_rtc_early_init(void) { // clear and stop any pending irqs on the timer platform_stop_timer(); - register_int_handler(GOLDFISH_RTC_IRQ, &rtc_irq, NULL); - unmask_interrupt(GOLDFISH_RTC_IRQ); + register_int_handler(VIRT_GF_RTC_IRQ_BASE, &rtc_irq, NULL); + unmask_interrupt(VIRT_GF_RTC_IRQ_BASE); // its okay to enable the irq since we've cleared the alarm and any pending interrupts write_reg(RTC_IRQ_ENABLED, 1); diff --git a/platform/qemu-virt-m68k/goldfish_tty.c b/platform/qemu-virt-m68k/goldfish_tty.c index 5b22eccb..14b5f403 100644 --- a/platform/qemu-virt-m68k/goldfish_tty.c +++ b/platform/qemu-virt-m68k/goldfish_tty.c @@ -19,7 +19,7 @@ // goldfish tty // from https://github.com/qemu/qemu/blob/master/hw/char/goldfish_tty.c -volatile unsigned int * const goldfish_tty_base = (void *)VIRT_GF_TTY_MMIO_BASE; +volatile uint32_t * const goldfish_tty_base = (void *)VIRT_GF_TTY_MMIO_BASE; // registers enum { @@ -47,11 +47,11 @@ static cbuf_t uart_rx_buf; static char transfer_buf[1]; // static pointer used to transfer MMIO data -static void write_reg(int reg, uint32_t val) { +static void write_reg(unsigned int reg, uint32_t val) { goldfish_tty_base[reg / 4] = val; } -static uint32_t read_reg(int reg) { +static uint32_t read_reg(unsigned int reg) { return goldfish_tty_base[reg / 4]; } @@ -83,9 +83,9 @@ void goldfish_tty_init(void) { /* finish uart init to get rx going */ cbuf_initialize_etc(&uart_rx_buf, RXBUF_SIZE, uart_rx_buf_data); - register_int_handler(GOLDFISH_TTY_IRQ, uart_irq_handler, NULL); + register_int_handler(VIRT_GF_TTY_IRQ_BASE, uart_irq_handler, NULL); - unmask_interrupt(GOLDFISH_TTY_IRQ); + unmask_interrupt(VIRT_GF_TTY_IRQ_BASE); write_reg(REG_CMD, CMD_INT_ENABLE); } diff --git a/platform/qemu-virt-m68k/include/platform/virt.h b/platform/qemu-virt-m68k/include/platform/virt.h index dd9d3c76..da343444 100644 --- a/platform/qemu-virt-m68k/include/platform/virt.h +++ b/platform/qemu-virt-m68k/include/platform/virt.h @@ -29,21 +29,16 @@ * IRQ #2 to IRQ #32 -> unused * CPU IRQ #7 -> NMI */ -#define NUM_PICS 6 -#define NUM_IRQS (NUM_PICS * 32) // PIC 1 - 6 - -#define PIC_IRQ_TO_LINEAR(pic, irq) (((pic) - 1) * 32 + ((irq) - 1)) -#define GOLDFISH_TTY_IRQ PIC_IRQ_TO_LINEAR(1, 32) // PIC 1, irq 32 -#define GOLDFISH_RTC_IRQ PIC_IRQ_TO_LINEAR(6, 1) // PIC 6, irq 1 - -#define PIC_IRQ_BASE(num) (8 + (num - 1) * 32) -#define PIC_IRQ(num, irq) (PIC_IRQ_BASE(num) + irq - 1) -//#define PIC_GPIO(pic_irq) (qdev_get_gpio_in(pic_dev[(pic_irq - 8) / 32], (pic_irq - 8) % 32)) #define VIRT_GF_PIC_MMIO_BASE 0xff000000 /* MMIO: 0xff000000 - 0xff005fff */ #define VIRT_GF_PIC_IRQ_BASE 1 /* IRQ: #1 -> #6 */ #define VIRT_GF_PIC_NB 6 +#define NUM_IRQS (VIRT_GF_PIC_NB * 32) // PIC 1 - 6 + +/* maps (pic + irq) base one to a linear number zero based */ +#define PIC_IRQ(pic, irq) (((pic) - 1) * 32 + ((irq) - 1)) + /* 2 goldfish-rtc (and timer) */ #define VIRT_GF_RTC_MMIO_BASE 0xff006000 /* MMIO: 0xff006000 - 0xff007fff */ #define VIRT_GF_RTC_IRQ_BASE PIC_IRQ(6, 1) /* PIC: #6, IRQ: #1 */ @@ -55,7 +50,7 @@ /* 1 virt-ctrl */ #define VIRT_CTRL_MMIO_BASE 0xff009000 /* MMIO: 0xff009000 - 0xff009fff */ -#define VIRT_CTRL_IRQ_BASE PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */ +#define VIRT_CTRL_IRQ_BASE PIC_IRQ(1, 1) /* PIC: #1, IRQ: #1 */ /* * virtio-mmio size is 0x200 bytes diff --git a/platform/qemu-virt-m68k/pic.c b/platform/qemu-virt-m68k/pic.c index 8612cf15..41b34aea 100644 --- a/platform/qemu-virt-m68k/pic.c +++ b/platform/qemu-virt-m68k/pic.c @@ -31,36 +31,36 @@ enum { REG_ENABLE = 0x10, }; -volatile unsigned int * const goldfish_pic_base = (void *)VIRT_GF_PIC_MMIO_BASE; +volatile uint32_t * const goldfish_pic_base = (void *)VIRT_GF_PIC_MMIO_BASE; static struct int_handlers { int_handler handler; void *arg; } handlers[NUM_IRQS]; -static void write_reg(int pic, int reg, uint32_t val) { - goldfish_pic_base[0x1000 * pic / 4 + reg / 4] = val; +static void write_reg(unsigned int pic, unsigned int reg, uint32_t val) { + goldfish_pic_base[(0x1000 * pic + reg) / 4] = val; } -static uint32_t read_reg(int pic, int reg) { - return goldfish_pic_base[0x1000 * pic / 4 + reg / 4]; +static uint32_t read_reg(unsigned int pic, unsigned int reg) { + return goldfish_pic_base[(0x1000 * pic + reg) / 4]; } -static void dump_pic(int i) { +static void dump_pic(unsigned int i) { dprintf(INFO, "PIC %d: status %u pending %#x\n", i, read_reg(i, REG_STATUS), read_reg(i, REG_IRQ_PENDING)); } static void dump_all_pics(void) { - for (int i = 0; i < NUM_PICS; i++) { + for (int i = 0; i < VIRT_GF_PIC_NB; i++) { dump_pic(i); } } -static int irq_to_pic_num(unsigned int vector) { +static unsigned int irq_to_pic_num(unsigned int vector) { return vector / 32; } -static int irq_to_pic_vec(unsigned int vector) { +static unsigned int irq_to_pic_vec(unsigned int vector) { return vector % 32; }