diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:35 -0800 |
commit | f721e3ac031f892af46f255a47d7f54a91317b30 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /hw/goldfish_interrupt.c | |
parent | bae1bc39312d5019bd9a5b8d840a529213a69a17 (diff) | |
download | external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.zip external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.gz external_qemu-f721e3ac031f892af46f255a47d7f54a91317b30.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'hw/goldfish_interrupt.c')
-rw-r--r-- | hw/goldfish_interrupt.c | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/hw/goldfish_interrupt.c b/hw/goldfish_interrupt.c deleted file mode 100644 index 2cba649..0000000 --- a/hw/goldfish_interrupt.c +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright (C) 2007-2008 The Android Open Source Project -** -** This software is licensed under the terms of the GNU General Public -** License version 2, as published by the Free Software Foundation, and -** may be copied, distributed, and modified under those terms. -** -** This program is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -** GNU General Public License for more details. -*/ -#include "qemu_file.h" -#include "arm_pic.h" -#include "goldfish_device.h" -#include "irq.h" - -enum { - INTERRUPT_STATUS = 0x00, // number of pending interrupts - INTERRUPT_NUMBER = 0x04, - INTERRUPT_DISABLE_ALL = 0x08, - INTERRUPT_DISABLE = 0x0c, - INTERRUPT_ENABLE = 0x10 -}; - -struct goldfish_int_state { - struct goldfish_device dev; - uint32_t level; - uint32_t pending_count; - uint32_t irq_enabled; - uint32_t fiq_enabled; - qemu_irq parent_irq; - qemu_irq parent_fiq; -}; - -#define GOLDFISH_INT_SAVE_VERSION 1 - -#define QFIELD_STRUCT struct goldfish_int_state -QFIELD_BEGIN(goldfish_int_fields) - QFIELD_INT32(level), - QFIELD_INT32(pending_count), - QFIELD_INT32(irq_enabled), - QFIELD_INT32(fiq_enabled), -QFIELD_END - -static void goldfish_int_save(QEMUFile* f, void* opaque) -{ - struct goldfish_int_state* s = opaque; - - qemu_put_struct(f, goldfish_int_fields, s); -} - -static int goldfish_int_load(QEMUFile* f, void* opaque, int version_id) -{ - struct goldfish_int_state* s = opaque; - - if (version_id != GOLDFISH_INT_SAVE_VERSION) - return -1; - - return qemu_get_struct(f, goldfish_int_fields, s); -} - -static void goldfish_int_update(struct goldfish_int_state *s) -{ - uint32_t flags; - - flags = (s->level & s->irq_enabled); - qemu_set_irq(s->parent_irq, flags != 0); - - flags = (s->level & s->fiq_enabled); - qemu_set_irq(s->parent_fiq, flags != 0); -} - -static void goldfish_int_set_irq(void *opaque, int irq, int level) -{ - struct goldfish_int_state *s = (struct goldfish_int_state *)opaque; - uint32_t mask = (1U << irq); - - if(level) { - if(!(s->level & mask)) { - if(s->irq_enabled & mask) - s->pending_count++; - s->level |= mask; - } - } - else { - if(s->level & mask) { - if(s->irq_enabled & mask) - s->pending_count--; - s->level &= ~mask; - } - } - goldfish_int_update(s); -} - -static uint32_t goldfish_int_read(void *opaque, target_phys_addr_t offset) -{ - struct goldfish_int_state *s = (struct goldfish_int_state *)opaque; - offset -= s->dev.base; - - switch (offset) { - case INTERRUPT_STATUS: /* IRQ_STATUS */ - return s->pending_count; - case INTERRUPT_NUMBER: { - int i; - uint32_t pending = s->level & s->irq_enabled; - for(i = 0; i < 32; i++) { - if(pending & (1U << i)) - return i; - } - return 0; - } - default: - cpu_abort (cpu_single_env, "goldfish_int_read: Bad offset %x\n", offset); - return 0; - } -} - -static void goldfish_int_write(void *opaque, target_phys_addr_t offset, uint32_t value) -{ - struct goldfish_int_state *s = (struct goldfish_int_state *)opaque; - uint32_t mask = (1U << value); - offset -= s->dev.base; - - switch (offset) { - case INTERRUPT_DISABLE_ALL: - s->pending_count = 0; - s->level = 0; - break; - - case INTERRUPT_DISABLE: - if(s->irq_enabled & mask) { - if(s->level & mask) - s->pending_count--; - s->irq_enabled &= ~mask; - } - break; - case INTERRUPT_ENABLE: - if(!(s->irq_enabled & mask)) { - s->irq_enabled |= mask; - if(s->level & mask) - s->pending_count++; - } - break; - - default: - cpu_abort (cpu_single_env, "goldfish_int_write: Bad offset %x\n", offset); - return; - } - goldfish_int_update(s); -} - -static CPUReadMemoryFunc *goldfish_int_readfn[] = { - goldfish_int_read, - goldfish_int_read, - goldfish_int_read -}; - -static CPUWriteMemoryFunc *goldfish_int_writefn[] = { - goldfish_int_write, - goldfish_int_write, - goldfish_int_write -}; - -qemu_irq* goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq parent_fiq) -{ - int ret; - struct goldfish_int_state *s; - qemu_irq* qi; - - s = qemu_mallocz(sizeof(*s)); - qi = qemu_allocate_irqs(goldfish_int_set_irq, s, 32); - s->dev.name = "goldfish_interrupt_controller"; - s->dev.id = -1; - s->dev.base = base; - s->dev.size = 0x1000; - s->parent_irq = parent_irq; - s->parent_fiq = parent_fiq; - - ret = goldfish_device_add(&s->dev, goldfish_int_readfn, goldfish_int_writefn, s); - if(ret) { - qemu_free(s); - return NULL; - } - - register_savevm( "goldfish_int", 0, GOLDFISH_INT_SAVE_VERSION, - goldfish_int_save, goldfish_int_load, s); - - return qi; -} - |