[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.
This commit is contained in:
Travis Geiselbrecht
2022-08-06 17:28:12 -07:00
parent fb373eb4de
commit c3ea652c1f
4 changed files with 26 additions and 30 deletions

View File

@@ -8,6 +8,7 @@
#include "platform_p.h"
#include <assert.h>
#include <inttypes.h>
#include <lk/err.h>
#include <lk/debug.h>
#include <lk/reg.h>
@@ -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);

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}