From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MswIs-0004tM-DQ for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:58 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MswIO-0004Zr-LZ for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:50 -0400 Received: from [199.232.76.173] (port=43897 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MswIN-0004ZL-Hm for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:27 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:55869) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MswIM-0005pj-5X for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:26 -0400 From: Isaku Yamahata Date: Wed, 30 Sep 2009 19:18:34 +0900 Message-Id: <1254305917-14784-59-git-send-email-yamahata@valinux.co.jp> In-Reply-To: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> References: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> Subject: [Qemu-devel] [PATCH 58/61] ioapic: make the number of pins configurable. List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, anthony@codemonkey.ws Cc: yamahata@valinux.co.jp make the number of pins configurable. Signed-off-by: Isaku Yamahata --- hw/hw.h | 20 +++++++++++++++++ hw/ioapic.c | 66 ++++++++++++++++++++++++++++++++++++++++++++-------------- hw/pc.h | 3 +- 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/hw/hw.h b/hw/hw.h index 19e9199..6f78285 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -365,6 +365,17 @@ extern const VMStateInfo vmstate_info_buffer; + type_check_array(_type,typeof_field(_state, _field),_num) \ } +#define VMSTATE_ARRAY_POINTER(_field, _state, _num, _version, _info, _type) {\ + .name = (stringify(_field)), \ + .version_id = (_version), \ + .num = (_num), \ + .info = &(_info), \ + .size = sizeof(_type), \ + .flags = VMS_ARRAY|VMS_POINTER, \ + .offset = offsetof(_state, _field) \ + + type_check_pointer(_type,typeof_field(_state, _field)) \ +} + #define VMSTATE_VARRAY(_field, _state, _field_num, _version, _info, _type) {\ .name = (stringify(_field)), \ .version_id = (_version), \ @@ -532,6 +543,15 @@ extern const VMStateDescription vmstate_pcie_device; #define VMSTATE_UINT64_ARRAY(_f, _s, _n) \ VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0) +#define VMSTATE_UINT64_ARRAY_POINTER(_f, _s, _n) \ + VMSTATE_ARRAY_POINTER(_f, _s, _n, 0, vmstate_info_uint64, uint64_t) + +#define VMSTATE_UINT64_VARRAY_V(_f, _s, _f_n, _v) \ + VMSTATE_VARRAY(_f, _s, _f_n, _v, vmstate_info_uint64, uint64_t) + +#define VMSTATE_UINT64_VARRAY(_f, _s, _f_n) \ + VMSTATE_UINT64_VARRAY_V(_f, _s, _f_n, 0) + #define VMSTATE_INT32_ARRAY_V(_f, _s, _n, _v) \ VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int32, int32_t) diff --git a/hw/ioapic.c b/hw/ioapic.c index 882ca9d..adaef41 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -32,7 +32,7 @@ # define IOAPIC_DPRINTF(format, ...) do { } while (0) #endif -#define IOAPIC_NUM_PINS 0x18 +#define IOAPIC_NUM_PINS_DEFAULT 0x18 #define IOAPIC_LVT_MASKED (1<<16) #define IOAPIC_TRIGGER_EDGE 0 @@ -48,11 +48,12 @@ #define IOAPIC_DM_EXTINT 0x7 struct IOAPICState { + int32_t num_pins; /* MRE: maximum redirection entries */ uint8_t id; uint8_t ioregsel; uint32_t irr; - uint64_t ioredtbl[IOAPIC_NUM_PINS]; + uint64_t *ioredtbl; ioapic_update_fn update_fn; void *opaque; }; @@ -75,7 +76,7 @@ static void ioapic_service(IOAPICState *s) uint8_t dest_mode; uint8_t polarity; - for (i = 0; i < IOAPIC_NUM_PINS; i++) { + for (i = 0; i < s->num_pins; i++) { mask = 1 << i; if (s->irr & mask) { entry = s->ioredtbl[i]; @@ -110,7 +111,7 @@ static void ioapic_set_irq(void *opaque, int vector, int level) if (vector == 0) vector = 2; - if (vector >= 0 && vector < IOAPIC_NUM_PINS) { + if (vector >= 0 && vector < s->num_pins) { uint32_t mask = 1 << vector; uint64_t entry = s->ioredtbl[vector]; @@ -147,14 +148,14 @@ static uint32_t ioapic_mem_readl(void *opaque, target_phys_addr_t addr) val = s->id << 24; break; case 0x01: - val = 0x11 | ((IOAPIC_NUM_PINS - 1) << 16); /* version 0x11 */ + val = 0x11 | ((s->num_pins - 1) << 16); /* version 0x11 */ break; case 0x02: val = 0; break; default: index = (s->ioregsel - 0x10) >> 1; - if (index >= 0 && index < IOAPIC_NUM_PINS) { + if (index >= 0 && index < s->num_pins) { if (s->ioregsel & 1) val = s->ioredtbl[index] >> 32; else @@ -186,7 +187,7 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va return; default: index = (s->ioregsel - 0x10) >> 1; - if (index >= 0 && index < IOAPIC_NUM_PINS) { + if (index >= 0 && index < s->num_pins) { if (s->ioregsel & 1) { s->ioredtbl[index] &= 0xffffffff; s->ioredtbl[index] |= (uint64_t)val << 32; @@ -209,7 +210,22 @@ static const VMStateDescription vmstate_ioapic = { .fields = (VMStateField []) { VMSTATE_UINT8(id, IOAPICState), VMSTATE_UINT8(ioregsel, IOAPICState), - VMSTATE_UINT64_ARRAY(ioredtbl, IOAPICState, IOAPIC_NUM_PINS), + VMSTATE_UINT64_ARRAY_POINTER(ioredtbl, IOAPICState, + IOAPIC_NUM_PINS_DEFAULT), + VMSTATE_END_OF_LIST() + } +}; + +static const VMStateDescription vmstate_ioapic_with_mre = { + .name = "ioapic", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .fields = (VMStateField []) { + VMSTATE_INT32(num_pins, IOAPICState), + VMSTATE_UINT8(id, IOAPICState), + VMSTATE_UINT8(ioregsel, IOAPICState), + VMSTATE_UINT64_VARRAY(ioredtbl, IOAPICState, num_pins), VMSTATE_END_OF_LIST() } }; @@ -221,8 +237,10 @@ static void ioapic_reset(void *opaque) ioapic_callback(s, 1); - memset(s, 0, sizeof(*s)); - for(i = 0; i < IOAPIC_NUM_PINS; i++) + s->id = 0; + s->ioregsel = 0; + s->irr = 0; + for(i = 0; i < s->num_pins; i++) s->ioredtbl[i] = 1 << 16; /* mask LVT */ } @@ -238,13 +256,18 @@ static CPUWriteMemoryFunc * const ioapic_mem_write[3] = { ioapic_mem_writel, }; -qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque) +static void ioapic_init_with_arg(uint8_t num_pins, + ioapic_update_fn update_fn, void *opaque, + IOAPICState **sp, qemu_irq **irq) { IOAPICState *s; - qemu_irq *irq; int io_memory; - s = qemu_mallocz(sizeof(IOAPICState)); + s = qemu_mallocz(sizeof(*s)); + *sp = s; + + s->ioredtbl = qemu_mallocz(sizeof(s->ioredtbl[0]) * num_pins); + s->num_pins = num_pins; s->update_fn = update_fn; s->opaque = opaque; ioapic_reset(s); @@ -253,14 +276,25 @@ qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque) ioapic_mem_write, s); cpu_register_physical_memory(0xfec00000, 0x1000, io_memory); - vmstate_register(0, &vmstate_ioapic, s); qemu_register_reset(ioapic_reset, s); - irq = qemu_allocate_irqs(ioapic_set_irq, s, IOAPIC_NUM_PINS); + *irq = qemu_allocate_irqs(ioapic_set_irq, s, num_pins); +} +qemu_irq *ioapic_init_with_mre(uint8_t num_pins, + ioapic_update_fn update_fn, void *opaque) +{ + IOAPICState *s; + qemu_irq *irq; + ioapic_init_with_arg(num_pins, update_fn, opaque, &s, &irq); + vmstate_register(0, &vmstate_ioapic_with_mre, s); return irq; } qemu_irq *ioapic_init(void) { - return ioapic_init_with_arg(NULL, NULL); + IOAPICState *s; + qemu_irq *irq; + ioapic_init_with_arg(IOAPIC_NUM_PINS_DEFAULT, NULL, NULL, &s, &irq); + vmstate_register(0, &vmstate_ioapic, s); + return irq; } diff --git a/hw/pc.h b/hw/pc.h index 44eac49..723c478 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -53,7 +53,8 @@ void apic_deliver_pic_intr(CPUState *env, int level); int apic_get_interrupt(CPUState *env); qemu_irq *ioapic_init(void); typedef void (*ioapic_update_fn)(void *opaque, int reset); -qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque); +qemu_irq *ioapic_init_with_mre(uint8_t num_pins, + ioapic_update_fn update_fn, void *opaque); void apic_reset_irq_delivered(void); int apic_get_irq_delivered(void); -- 1.6.0.2