diff options
Diffstat (limited to 'hw/intc')
| -rw-r--r-- | hw/intc/openpic.c | 99 | ||||
| -rw-r--r-- | hw/intc/openpic_kvm.c | 15 |
2 files changed, 60 insertions, 54 deletions
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c index 08e0e19c59..028529e13d 100644 --- a/hw/intc/openpic.c +++ b/hw/intc/openpic.c @@ -192,6 +192,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, int idx); static void openpic_cpu_write_internal(void *opaque, hwaddr addr, uint32_t val, int idx); +static void openpic_reset(DeviceState *d); typedef enum IRQType { IRQ_TYPE_NORMAL = 0, @@ -529,55 +530,6 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level) } } -static void openpic_reset(DeviceState *d) -{ - OpenPICState *opp = OPENPIC(d); - int i; - - opp->gcr = GCR_RESET; - /* Initialise controller registers */ - opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) | - ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) | - (opp->vid << FRR_VID_SHIFT); - - opp->pir = 0; - opp->spve = -1 & opp->vector_mask; - opp->tfrr = opp->tfrr_reset; - /* Initialise IRQ sources */ - for (i = 0; i < opp->max_irq; i++) { - opp->src[i].ivpr = opp->ivpr_reset; - opp->src[i].idr = opp->idr_reset; - - switch (opp->src[i].type) { - case IRQ_TYPE_NORMAL: - opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK); - break; - - case IRQ_TYPE_FSLINT: - opp->src[i].ivpr |= IVPR_POLARITY_MASK; - break; - - case IRQ_TYPE_FSLSPECIAL: - break; - } - } - /* Initialise IRQ destinations */ - for (i = 0; i < MAX_CPU; i++) { - opp->dst[i].ctpr = 15; - memset(&opp->dst[i].raised, 0, sizeof(IRQQueue)); - opp->dst[i].raised.next = -1; - memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue)); - opp->dst[i].servicing.next = -1; - } - /* Initialise timers */ - for (i = 0; i < OPENPIC_MAX_TMR; i++) { - opp->timers[i].tccr = 0; - opp->timers[i].tbcr = TBCR_CI; - } - /* Go out of RESET state */ - opp->gcr = 0; -} - static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ) { return opp->src[n_IRQ].idr; @@ -1461,6 +1413,55 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id) return 0; } +static void openpic_reset(DeviceState *d) +{ + OpenPICState *opp = OPENPIC(d); + int i; + + opp->gcr = GCR_RESET; + /* Initialise controller registers */ + opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) | + ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) | + (opp->vid << FRR_VID_SHIFT); + + opp->pir = 0; + opp->spve = -1 & opp->vector_mask; + opp->tfrr = opp->tfrr_reset; + /* Initialise IRQ sources */ + for (i = 0; i < opp->max_irq; i++) { + opp->src[i].ivpr = opp->ivpr_reset; + switch (opp->src[i].type) { + case IRQ_TYPE_NORMAL: + opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK); + break; + + case IRQ_TYPE_FSLINT: + opp->src[i].ivpr |= IVPR_POLARITY_MASK; + break; + + case IRQ_TYPE_FSLSPECIAL: + break; + } + + write_IRQreg_idr(opp, i, opp->idr_reset); + } + /* Initialise IRQ destinations */ + for (i = 0; i < MAX_CPU; i++) { + opp->dst[i].ctpr = 15; + memset(&opp->dst[i].raised, 0, sizeof(IRQQueue)); + opp->dst[i].raised.next = -1; + memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue)); + opp->dst[i].servicing.next = -1; + } + /* Initialise timers */ + for (i = 0; i < OPENPIC_MAX_TMR; i++) { + opp->timers[i].tccr = 0; + opp->timers[i].tbcr = TBCR_CI; + } + /* Go out of RESET state */ + opp->gcr = 0; +} + typedef struct MemReg { const char *name; MemoryRegionOps const *ops; diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c index 585ab4ff20..e3bce043a3 100644 --- a/hw/intc/openpic_kvm.c +++ b/hw/intc/openpic_kvm.c @@ -31,6 +31,8 @@ #include "sysemu/kvm.h" #include "qemu/log.h" +#define GCR_RESET 0x80000000 + #define KVM_OPENPIC(obj) \ OBJECT_CHECK(KVMOpenPICState, (obj), TYPE_KVM_OPENPIC) @@ -50,11 +52,6 @@ static void kvm_openpic_set_irq(void *opaque, int n_IRQ, int level) kvm_set_irq(kvm_state, n_IRQ, level); } -static void kvm_openpic_reset(DeviceState *d) -{ - qemu_log_mask(LOG_UNIMP, "%s: unimplemented\n", __func__); -} - static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { @@ -74,6 +71,14 @@ static void kvm_openpic_write(void *opaque, hwaddr addr, uint64_t val, } } +static void kvm_openpic_reset(DeviceState *d) +{ + KVMOpenPICState *opp = KVM_OPENPIC(d); + + /* Trigger the GCR.RESET bit to reset the PIC */ + kvm_openpic_write(opp, 0x1020, GCR_RESET, sizeof(uint32_t)); +} + static uint64_t kvm_openpic_read(void *opaque, hwaddr addr, unsigned size) { KVMOpenPICState *opp = opaque; |