aboutsummaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authorVladimir Chtchetkine <vchtchetkine@google.com>2011-09-29 15:54:52 -0700
committerVladimir Chtchetkine <vchtchetkine@google.com>2011-09-29 15:59:16 -0700
commitd0b482eb3e8cb699a2090bc773364d3a7d369a25 (patch)
tree1cf7d757ec81b83c463d489b087f3436940b9e92 /hw
parent6e93697bf74fe127356e98bceabf67597c0e1084 (diff)
downloadexternal_qemu-d0b482eb3e8cb699a2090bc773364d3a7d369a25.zip
external_qemu-d0b482eb3e8cb699a2090bc773364d3a7d369a25.tar.gz
external_qemu-d0b482eb3e8cb699a2090bc773364d3a7d369a25.tar.bz2
Fix IRQ allocation for goldfish devices.
There were two issues fixed here: 1. IRQ allocation (for a device) has never been checked on going out of bounds. 2. In x86 platform some IRQs were reserved (for kbd, mouse, and exception), but IRQ allocation for goldfish devices didn't check for those reserved IRQs being assigned to a device. Change-Id: I9d48485d973bcc8fd8a3dd1b78fbfa6a05aeea22
Diffstat (limited to 'hw')
-rw-r--r--hw/goldfish_device.c13
-rw-r--r--hw/goldfish_device.h14
-rw-r--r--hw/goldfish_interrupt.c2
-rw-r--r--hw/i8259.c3
-rw-r--r--hw/pc.c4
5 files changed, 32 insertions, 4 deletions
diff --git a/hw/goldfish_device.c b/hw/goldfish_device.c
index e98161a..e3dbfcb 100644
--- a/hw/goldfish_device.c
+++ b/hw/goldfish_device.c
@@ -12,6 +12,7 @@
#include "qemu_file.h"
#include "arm_pic.h"
#include "goldfish_device.h"
+#include "android/utils/debug.h"
#ifdef TARGET_I386
#include "kvm.h"
#endif
@@ -59,6 +60,18 @@ int goldfish_add_device_no_io(struct goldfish_device *dev)
if(dev->irq == 0 && dev->irq_count > 0) {
dev->irq = goldfish_free_irq;
goldfish_free_irq += dev->irq_count;
+#ifdef TARGET_I386
+ /* Make sure that we pass by the reserved IRQs. */
+ while (goldfish_free_irq == GFD_KBD_IRQ ||
+ goldfish_free_irq == GFD_MOUSE_IRQ ||
+ goldfish_free_irq == GFD_ERR_IRQ) {
+ goldfish_free_irq++;
+ }
+#endif
+ if (goldfish_free_irq >= GFD_MAX_IRQ) {
+ derror("Goldfish device has exceeded available IRQ number.");
+ exit(1);
+ }
}
//printf("goldfish_add_device: %s, base %x %x, irq %d %d\n",
// dev->name, dev->base, dev->size, dev->irq, dev->irq_count);
diff --git a/hw/goldfish_device.h b/hw/goldfish_device.h
index 19f4b32..a9e3f83 100644
--- a/hw/goldfish_device.h
+++ b/hw/goldfish_device.h
@@ -55,4 +55,18 @@ void trace_dev_init();
void events_dev_init(uint32_t base, qemu_irq irq);
void nand_dev_init(uint32_t base);
+#ifdef TARGET_I386
+/* Maximum IRQ number available for a device on x86. */
+#define GFD_MAX_IRQ 16
+/* IRQ reserved for keyboard. */
+#define GFD_KBD_IRQ 1
+/* IRQ reserved for mouse. */
+#define GFD_MOUSE_IRQ 12
+/* IRQ reserved for error (raising an exception in TB code). */
+#define GFD_ERR_IRQ 13
+#else
+/* Maximum IRQ number available for a device on ARM. */
+#define GFD_MAX_IRQ 32
#endif
+
+#endif /* GOLDFISH_DEVICE_H */
diff --git a/hw/goldfish_interrupt.c b/hw/goldfish_interrupt.c
index c620664..f4c5a89 100644
--- a/hw/goldfish_interrupt.c
+++ b/hw/goldfish_interrupt.c
@@ -166,7 +166,7 @@ qemu_irq* goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq
qemu_irq* qi;
s = qemu_mallocz(sizeof(*s));
- qi = qemu_allocate_irqs(goldfish_int_set_irq, s, 32);
+ qi = qemu_allocate_irqs(goldfish_int_set_irq, s, GFD_MAX_IRQ);
s->dev.name = "goldfish_interrupt_controller";
s->dev.id = -1;
s->dev.base = base;
diff --git a/hw/i8259.c b/hw/i8259.c
index 091ba7a..0049e73 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -25,6 +25,7 @@
#include "pc.h"
#include "isa.h"
#include "monitor.h"
+#include "goldfish_device.h"
/* debug PIC */
//#define DEBUG_PIC
@@ -559,7 +560,7 @@ qemu_irq *i8259_init(qemu_irq parent_irq)
s->pics[0].pics_state = s;
s->pics[1].pics_state = s;
isa_pic = s;
- return qemu_allocate_irqs(i8259_set_irq, s, 16);
+ return qemu_allocate_irqs(i8259_set_irq, s, GFD_MAX_IRQ);
}
void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
diff --git a/hw/pc.c b/hw/pc.c
index 7a83b4c..f44c44e 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1033,7 +1033,7 @@ static void pc_init1(ram_addr_t ram_size,
cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
i8259 = i8259_init(cpu_irq[0]);
- ferr_irq = i8259[13];
+ ferr_irq = i8259[GFD_ERR_IRQ];
#define IRQ_PDEV_BUS 4
goldfish_device_init(i8259, 0xff010000, 0x7f0000, 5, 5);
@@ -1177,7 +1177,7 @@ static void pc_init1(ram_addr_t ram_size,
}
#endif
- i8042_init(i8259[1], i8259[12], 0x60);
+ i8042_init(i8259[GFD_KBD_IRQ], i8259[GFD_MOUSE_IRQ], 0x60);
DMA_init(0);
goldfish_fb_init(0);