ppc patch queue 2013-01-07
Hi Blue / Aurelien,
This is my current patch queue for ppc. Please pull.
Alex
The following changes since commit 8e4a424b305e29dc0e454f52df3b35577f342975:
Blue Swirl (1):
Revert "virtio-pci: replace byte swap hack"
are available in the git repository at:
git://repo.or.cz/qemu/agraf.git ppc-for-upstream
Alexander Graf (3):
openpic: fix coding style issues
kvm: Update kernel headers
PPC: Bring EPR support closer to reality
Andreas Färber (2):
target-ppc: Slim conversion of model definitions to QOM subclasses
target-ppc: Error out for -cpu host on unknown PVR
Bharat Bhushan (2):
powerpc: linux header sync script includes epapr_hcalls.h
PPC: Reset qemu timers when guest reset
Samuel Seay (2):
PPC: fix segfault in signal handling code
PPC: linux-user: Calculate context pointer explicitly
Scott Wood (21):
openpic: symbolicize some magic numbers
openpic: remove pcsr (CPU sensitivity register)
openpic: support large vectors on FSL mpic
openpic: BRR1 is not a CPU-specific register.
openpic: s/opp->nb_irqs -1/opp->nb_cpus - 1/
openpic: don't crash on a register access without a CPU context
openpic: fix debug prints
openpic: lower interrupt when reading the MSI register ppc/booke: fix crit/mcheck/debug exceptions
openpic: make register names correspond better with hw docs
openpic: rework critical interrupt support
openpic: make ctpr signed
openpic/fsl: critical interrupts ignore mask before v4.1
openpic: always call IRQ_check from IRQ_get_next Revert "openpic: Accelerate pending irq search"
openpic: use standard bitmap operations
openpic: add some bounds checking for IRQ numbers
openpic: fix sense and priority bits
openpic: IRQ_check: search the queue a word at a time
openpic: move IACK to its own function
openpic: fix CTPR and de-assertion of interrupts
Stuart Yoder (1):
PPC: KVM: set has-idle in guest device tree
hw/openpic.c | 1032 ++++++++++++++++++----------- hw/ppc/e500.c | 8 +- hw/ppc_booke.c | 13 + linux-headers/asm-powerpc/epapr_hcalls.h | 98 +++ linux-headers/asm-powerpc/kvm.h | 86 +++ linux-headers/asm-powerpc/kvm_para.h | 13 +- linux-headers/linux/kvm.h | 21 +- linux-headers/linux/kvm_para.h | 6 +- linux-headers/linux/vfio.h | 6 +- linux-headers/linux/virtio_config.h | 6 +- linux-headers/linux/virtio_ring.h | 6 +- linux-user/signal.c | 6 +- scripts/update-linux-headers.sh | 3 + target-ppc/Makefile.objs | 4 +- target-ppc/cpu-qom.h | 5 + target-ppc/cpu.h | 8 +- target-ppc/excp_helper.c | 35 +- target-ppc/helper.c | 50 -- target-ppc/helper.h | 1 - target-ppc/kvm.c | 77 ++- target-ppc/kvm_ppc.h | 9 +- target-ppc/mpic_helper.c | 35 - target-ppc/translate_init.c | 352 +++++++---- 23 files changed, 1225 insertions(+), 655 deletions(-) create mode 100644 linux-headers/asm-powerpc/epapr_hcalls.h delete mode 100644 target-ppc/helper.c delete mode 100644 target-ppc/mpic_helper.c
PATCH 1/31 openpic: symbolicize some magic numbers
From: Scott Wood <[email protected]>
Deefine symbolic names for some register bits, and use some that have already been defined.
Also convert some register values from hex to decimal when it improves readability.
IPVP_PRIORITY_MASK is corrected from (0x1F << 16) to (0xF << 16), in conjunction with making wider use of the symbolic name. I looked at Freescale and IBM MPIC docs and at the base OpenPIC spec, and all three had priority as 4 bits rather than 5. Plus, the magic nubmer that is being replaced with symbolic values treated the field as 4 bits wide.
--- hw/openpic.c | 54 ++++++++++++++++++++++++++++++++---------------------- 1 files changed, 32 insertions(+), 22 deletions(-)
hw/openpic.c +32 -22
@@ -124,6 +124,11 @@#define VENI_GENERIC 0x00000000/* Generic Vendor ID */ +#define GLBC_RESET 0x80000000 + +#define TIBC_CI 0x80000000/* count inhibit */ +#define TICC_TOG 0x80000000/* toggles when decrement to zero */ +#define IDR_EP_SHIFT 31#define IDR_EP_MASK (1 << IDR_EP_SHIFT)#define IDR_CI0_SHIFT 30
@@ -190,11 +195,15 @@ typedef struct IRQ_src_t {#define IPVP_SENSE_SHIFT 22#define IPVP_SENSE_MASK (1 << IPVP_SENSE_SHIFT) -#define IPVP_PRIORITY_MASK (0x1F << 16) +#define IPVP_PRIORITY_MASK (0xF << 16)#define IPVP_PRIORITY (_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16))#define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1)#define IPVP_VECTOR (_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK) +/* IDE[EP/CI] are only for FSL MPIC prior to v4.0 */ +#define IDE_EP 0x80000000/* external pin */ +#define IDE_CI 0x40000000/* critical interrupt */ + typedef struct IRQ_dst_t { uint32_t pctp; /* CPU current task priority */ uint32_t pcsr; /* CPU sensitivity register */
@@ -375,7 +384,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)DPRINTF ("%s: IRQ %d is already active\n" , __func__, n_IRQ);return ; } -if (src->ide ==0x00000000 ) { +if (src->ide ==0 ) {/* No target */ DPRINTF ("%s: IRQ %d has no target\n" , __func__, n_IRQ);return ;
@@ -432,13 +441,13 @@ static void openpic_reset(DeviceState *d)OpenPICState *opp =FROM_SYSBUS (typeof (*opp),sysbus_from_qdev (d));int i; - opp->glbc =0x80000000 ; + opp->glbc =GLBC_RESET ;/* Initialise controller registers */ opp->frep = ((opp->nb_irqs -1 ) <<FREP_NIRQ_SHIFT ) | ((opp->nb_cpus -1 ) <<FREP_NCPU_SHIFT ) | (opp->vid <<FREP_VID_SHIFT ); - opp->pint =0x00000000 ; + opp->pint =0 ; opp->spve =-1 & opp->spve_mask; opp->tifr = opp->tifr_reset;/* Initialise IRQ sources */
@@ -448,7 +457,7 @@ static void openpic_reset(DeviceState *d) }/* Initialise IRQ destinations */ for (i =0 ; i <MAX_CPU ; i++) { - opp->dst[i].pctp =0x0000000F ; + opp->dst[i].pctp =15 ; opp->dst[i].pcsr =0x00000000 ;memset (&opp->dst[i].raised,0 ,sizeof (IRQ_queue_t)); opp->dst[i].raised.next =-1 ;
@@ -457,11 +466,11 @@ static void openpic_reset(DeviceState *d) }/* Initialise timers */ for (i =0 ; i <MAX_TMR ; i++) { - opp->timers[i].ticc =0x00000000 ; - opp->timers[i].tibc =0x80000000 ; + opp->timers[i].ticc =0 ; + opp->timers[i].tibc =TIBC_CI ; }/* Go out of RESET state */ - opp->glbc =0x00000000 ; + opp->glbc =0 ; }static inline uint32_t read_IRQreg_ide (OpenPICState *opp,int n_IRQ)
@@ -478,7 +487,7 @@ static inline void write_IRQreg_ide(OpenPICState *opp, int n_IRQ, uint32_t val) {uint32_t tmp; - tmp = val &0xC0000000 ; + tmp = val & (IDE_EP |IDE_CI ); tmp |= val & ((1ULL <<MAX_CPU ) -1 ); opp->src[n_IRQ].ide = tmp;DPRINTF ("Set IDE %d to 0x%08x\n" , n_IRQ, opp->src[n_IRQ].ide);
@@ -488,8 +497,8 @@ static inline void write_IRQreg_ipvp(OpenPICState *opp, int n_IRQ, uint32_t val) {/* NOTE: not fully accurate for special IRQs, but simple and sufficient */ /* ACTIVITY bit is read-only */ - opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp &0x40000000 ) - | (val &0x800F00FF ); + opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp &IPVP_ACTIVITY_MASK ) | + (val & (IPVP_MASK_MASK |IPVP_PRIORITY_MASK |IPVP_VECTOR_MASK ));openpic_update_irq (opp, n_IRQ);DPRINTF ("Set IPVP %d to 0x%08x -> 0x%08x\n" , n_IRQ, val, opp->src[n_IRQ].ipvp);
@@ -521,7 +530,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,case 0x1000 :/* FREP */ break ;case 0x1020 :/* GLBC */ -if (val &0x80000000 ) { +if (val &GLBC_RESET ) {openpic_reset (&opp->busdev.qdev); }break ;
@@ -634,10 +643,11 @@ static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,case 0x00 :/* TICC (GTCCR) */ break ;case 0x10 :/* TIBC (GTBCR) */ -if ((opp->timers[idx].ticc &0x80000000 ) !=0 && - (val &0x80000000 ) ==0 && - (opp->timers[idx].tibc &0x80000000 ) !=0 ) - opp->timers[idx].ticc &= ~0x80000000 ; +if ((opp->timers[idx].ticc &TICC_TOG ) !=0 && + (val &TIBC_CI ) ==0 && + (opp->timers[idx].tibc &TIBC_CI ) !=0 ) { + opp->timers[idx].ticc &= ~TICC_TOG ; + } opp->timers[idx].tibc = val;break ;case 0x20 :/* TIVP (GTIVPR) */
@@ -1190,9 +1200,9 @@ static int openpic_init(SysBusDevice *dev) opp->vid =VID_REVISION_1_2 ; opp->veni =VENI_GENERIC ; opp->spve_mask =0xFFFF ; - opp->tifr_reset =0x00000000 ; - opp->ipvp_reset =0x80000000 ; - opp->ide_reset =0x00000001 ; + opp->tifr_reset =0 ; + opp->ipvp_reset =IPVP_MASK_MASK ; + opp->ide_reset =1 <<0 ; opp->max_irq =FSL_MPIC_20_MAX_IRQ ; opp->irq_ipi0 =FSL_MPIC_20_IPI_IRQ ; opp->irq_tim0 =FSL_MPIC_20_TMR_IRQ ;
@@ -1206,9 +1216,9 @@ static int openpic_init(SysBusDevice *dev) opp->vid =VID_REVISION_1_3 ; opp->veni =VENI_GENERIC ; opp->spve_mask =0xFF ; - opp->tifr_reset =0x003F7A00 ; - opp->ipvp_reset =0xA0000000 ; - opp->ide_reset =0x00000000 ; + opp->tifr_reset =4160000 ; + opp->ipvp_reset =IPVP_MASK_MASK |IPVP_MODE_MASK ; + opp->ide_reset =0 ; opp->max_irq =RAVEN_MAX_IRQ ; opp->irq_ipi0 =RAVEN_IPI_IRQ ; opp->irq_tim0 =RAVEN_TMR_IRQ ;
Signature · 1 line
1.6.0.2
PATCH 2/31 openpic: remove pcsr (CPU sensitivity register)
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
I could not find this register in any spec (FSL, IBM, or OpenPIC) and the code doesn't do anything with it but initialize, save, or restore it.
--- hw/openpic.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-)
hw/openpic.c +0 -4
@@ -206,7 +206,6 @@ typedef struct IRQ_src_t { typedef struct IRQ_dst_t { uint32_t pctp; /* CPU current task priority */ - uint32_t pcsr; /* CPU sensitivity register */ IRQ_queue_t raised; IRQ_queue_t servicing; qemu_irq *irqs;
@@ -458,7 +457,6 @@ static void openpic_reset(DeviceState *d)/* Initialise IRQ destinations */ for (i =0 ; i <MAX_CPU ; i++) { opp->dst[i].pctp =15 ; - opp->dst[i].pcsr =0x00000000 ;memset (&opp->dst[i].raised,0 ,sizeof (IRQ_queue_t)); opp->dst[i].raised.next =-1 ;memset (&opp->dst[i].servicing,0 ,sizeof (IRQ_queue_t));
@@ -1083,7 +1081,6 @@ static void openpic_save(QEMUFile* f, void *opaque)for (i =0 ; i < opp->nb_cpus; i++) {qemu_put_be32s (f, &opp->dst[i].pctp); -qemu_put_be32s (f, &opp->dst[i].pcsr);openpic_save_IRQ_queue (f, &opp->dst[i].raised);openpic_save_IRQ_queue (f, &opp->dst[i].servicing); }
@@ -1130,7 +1127,6 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)for (i =0 ; i < opp->nb_cpus; i++) {qemu_get_be32s (f, &opp->dst[i].pctp); -qemu_get_be32s (f, &opp->dst[i].pcsr);openpic_load_IRQ_queue (f, &opp->dst[i].raised);openpic_load_IRQ_queue (f, &opp->dst[i].servicing); }
Signature · 1 line
1.6.0.2
PATCH 3/31 openpic: support large vectors on FSL mpic
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Previously only the spurious vector was sized appropriately to the openpic model.
Also, instances of "IPVP_VECTOR(opp->spve)" were replace with just "opp->spve", as opp->spve is already just a vector and not an IVPR.
--- hw/openpic.c | 22 ++++++++++------------ 1 files changed, 10 insertions(+), 12 deletions(-)
hw/openpic.c +10 -12
@@ -51,7 +51,6 @@#define MAX_CPU 15#define MAX_SRC 256#define MAX_TMR 4 -#define VECTOR_BITS 8#define MAX_IPI 4#define MAX_MSI 8#define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR)
@@ -197,8 +196,7 @@ typedef struct IRQ_src_t {#define IPVP_PRIORITY_MASK (0xF << 16)#define IPVP_PRIORITY (_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16)) -#define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1) -#define IPVP_VECTOR (_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK) +#define IPVP_VECTOR (opp, _ipvpr_) ((_ipvpr_) & (opp)->vector_mask)/* IDE[EP/CI] are only for FSL MPIC prior to v4.0 */ #define IDE_EP 0x80000000/* external pin */
@@ -221,7 +219,7 @@ typedef struct OpenPICState {uint32_t nb_irqs;uint32_t vid;uint32_t veni;/* Vendor identification register */ -uint32_t spve_mask; +uint32_t vector_mask;uint32_t tifr_reset;uint32_t ipvp_reset;uint32_t ide_reset;
@@ -447,7 +445,7 @@ static void openpic_reset(DeviceState *d) (opp->vid <<FREP_VID_SHIFT ); opp->pint =0 ; - opp->spve =-1 & opp->spve_mask; + opp->spve =-1 & opp->vector_mask; opp->tifr = opp->tifr_reset;/* Initialise IRQ sources */ for (i =0 ; i < opp->max_irq; i++) {
@@ -496,7 +494,7 @@ static inline void write_IRQreg_ipvp(OpenPICState *opp, int n_IRQ, uint32_t val)/* NOTE: not fully accurate for special IRQs, but simple and sufficient */ /* ACTIVITY bit is read-only */ opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp &IPVP_ACTIVITY_MASK ) | - (val & (IPVP_MASK_MASK |IPVP_PRIORITY_MASK |IPVP_VECTOR_MASK )); + (val & (IPVP_MASK_MASK |IPVP_PRIORITY_MASK | opp->vector_mask));openpic_update_irq (opp, n_IRQ);DPRINTF ("Set IPVP %d to 0x%08x -> 0x%08x\n" , n_IRQ, val, opp->src[n_IRQ].ipvp);
@@ -559,7 +557,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val, }break ;case 0x10E0 :/* SPVE */ - opp->spve = val & opp->spve_mask; + opp->spve = val & opp->vector_mask;break ;default :break ;
@@ -896,7 +894,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,DPRINTF ("PIAC: irq=%d\n" , n_IRQ);if (n_IRQ ==-1 ) {/* No more interrupt pending */ - retval =IPVP_VECTOR (opp->spve); + retval = opp->spve; }else { src = &opp->src[n_IRQ]; if (!(src->ipvp & IPVP_ACTIVITY_MASK) ||
@@ -906,11 +904,11 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,* and the pending IRQ isn't allowed anymore */ src->ipvp &= ~IPVP_ACTIVITY_MASK ; - retval =IPVP_VECTOR (opp->spve); + retval = opp->spve; }else {/* IRQ enter servicing state */ IRQ_setbit (&dst->servicing, n_IRQ); - retval =IPVP_VECTOR (src->ipvp); + retval =IPVP_VECTOR (opp, src->ipvp); }IRQ_resetbit (&dst->raised, n_IRQ); dst->raised.next =-1 ;
@@ -1195,7 +1193,7 @@ static int openpic_init(SysBusDevice *dev) opp->nb_irqs =80 ; opp->vid =VID_REVISION_1_2 ; opp->veni =VENI_GENERIC ; - opp->spve_mask =0xFFFF ; + opp->vector_mask =0xFFFF ; opp->tifr_reset =0 ; opp->ipvp_reset =IPVP_MASK_MASK ; opp->ide_reset =1 <<0 ;
@@ -1211,7 +1209,7 @@ static int openpic_init(SysBusDevice *dev) opp->nb_irqs =RAVEN_MAX_EXT ; opp->vid =VID_REVISION_1_3 ; opp->veni =VENI_GENERIC ; - opp->spve_mask =0xFF ; + opp->vector_mask =0xFF ; opp->tifr_reset =4160000 ; opp->ipvp_reset =IPVP_MASK_MASK |IPVP_MODE_MASK ; opp->ide_reset =0 ;
Signature · 1 line
1.6.0.2
PATCH 4/31 openpic: BRR1 is not a CPU-specific register.
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
It's in the address range that normally contains a magic redirection to the CPU-specific region of the curretn CPU, but it isn't actually a per-CPU register. On real hardware BRR1 shows up only at 0x40000, not at 0x60000 or other non-magic per-CPU areas. Plus, this makes it possible to read the register on the QEMU command line with "xp".
--- hw/openpic.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-)
hw/openpic.c +2 -3
@@ -587,6 +587,8 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len) retval =0x00000000 ;break ;case 0x00 :/* Block Revision Register1 (BRR1) */ + retval = opp->brr1; +break ;case 0x40 :case 0x50 :case 0x60 :
@@ -878,9 +880,6 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, dst = &opp->dst[idx]; addr &=0xFF0 ;switch (addr) { -case 0x00 :/* Block Revision Register1 (BRR1) */ - retval = opp->brr1; -break ;case 0x80 :/* PCTP */ retval = dst->pctp;break ;
Signature · 1 line
1.6.0.2
PATCH 5/31 openpic: s/opp->nb_irqs -1/opp->nb_cpus - 1/
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
"opp->nb_irqs-1" would have been a minor coding style error, but putting in one space but not the other makes it look confusingly like a numeric literal "-1".
--- hw/openpic.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
hw/openpic.c +2 -2
@@ -440,8 +440,8 @@ static void openpic_reset(DeviceState *d) opp->glbc =GLBC_RESET ;/* Initialise controller registers */ - opp->frep = ((opp->nb_irqs -1 ) <<FREP_NIRQ_SHIFT ) | - ((opp->nb_cpus -1 ) <<FREP_NCPU_SHIFT ) | + opp->frep = ((opp->nb_irqs -1 ) <<FREP_NIRQ_SHIFT ) | + ((opp->nb_cpus -1 ) <<FREP_NCPU_SHIFT ) | (opp->vid <<FREP_VID_SHIFT ); opp->pint =0 ;
Signature · 1 line
1.6.0.2
PATCH 6/31 openpic: don't crash on a register access without a CPU context
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
If we access a register via the QEMU memory inspection commands (e.g. "xp") rather than from guest code, we won't have a CPU context. Gracefully fail to access the register in that case, rather than crashing.
--- hw/openpic.c | 16 +++++++++++++++- 1 files changed, 15 insertions(+), 1 deletions(-)
hw/openpic.c +15 -1
@@ -161,7 +161,11 @@ static inline int test_bit(uint32_t *field, int bit)static int get_current_cpu (void ) { -return cpu_single_env->cpu_index; +if (!cpu_single_env) { +return -1 ; + } + +return cpu_single_env->cpu_index; } static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,
@@ -810,6 +814,11 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,DPRINTF ("%s: cpu %d addr " TARGET_FMT_plx" <= %08x\n" , __func__, idx, addr, val); + +if (idx <0 ) { +return ; + } +if (addr &0xF )return ; dst = &opp->dst[idx];
@@ -875,6 +884,11 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,DPRINTF ("%s: cpu %d addr " TARGET_FMT_plx"\n" , __func__, idx, addr); retval =0xFFFFFFFF ; + +if (idx <0 ) { +return retval; + } +if (addr &0xF )return retval; dst = &opp->dst[idx];
Signature · 1 line
1.6.0.2
PATCH 7/31 powerpc: linux header sync script includes epapr_hcalls.h
In reply to Alexander GrafFrom: Bharat Bhushan <[email protected]>
epapr_hcalls.h is now referenced by kvm_para.h. so this is needed for QEMU to get compiled on powerpc.
--- scripts/update-linux-headers.sh | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
scripts/update-linux-headers.sh +3 -0
@@ -54,6 +54,9 @@ for arch in $ARCHLIST; do if [ $arch = x86 ]; then cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86" fi + if [ $arch = powerpc ]; then + cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc/" + fi done rm -rf "$output/linux-headers/linux"
Signature · 1 line
1.6.0.2
PATCH 8/31 openpic: fix coding style issues
In reply to Alexander GrafThis patch fixes the following coding style violations:
- structs have to be typedef and be CamelCase
- if()s are always surrounded by curly braces
--- hw/openpic.c | 100 ++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 55 insertions(+), 45 deletions(-)
hw/openpic.c +55 -45
@@ -173,19 +173,19 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,static void openpic_cpu_write_internal (void *opaque,hwaddr addr,uint32_t val,int idx); -typedef struct IRQ_queue_t { +typedef struct IRQQueue {uint32_t queue[BF_WIDTH (MAX_IRQ )];int next;int priority;int pending;/* nr of pending bits in queue */ -}IRQ_queue_t ; +}IRQQueue ; -typedef struct IRQ_src_t { +typedef struct IRQSource {uint32_t ipvp;/* IRQ vector/priority register */ uint32_t ide;/* IRQ destination register */ int last_cpu;int pending;/* TRUE if IRQ is pending */ -}IRQ_src_t ; +}IRQSource ;#define IPVP_MASK_SHIFT 31#define IPVP_MASK_MASK (1 << IPVP_MASK_SHIFT)
@@ -206,12 +206,12 @@ typedef struct IRQ_src_t {#define IDE_EP 0x80000000/* external pin */ #define IDE_CI 0x40000000/* critical interrupt */ -typedef struct IRQ_dst_t { +typedef struct IRQDest {uint32_t pctp;/* CPU current task priority */ -IRQ_queue_t raised; -IRQ_queue_t servicing; +IRQQueue raised; +IRQQueue servicing;qemu_irq *irqs; -}IRQ_dst_t ; +}IRQDest ; typedef struct OpenPICState { SysBusDevice busdev;
@@ -239,9 +239,9 @@ typedef struct OpenPICState {uint32_t spve;/* Spurious vector register */ uint32_t tifr;/* Timer frequency reporting register */ /* Source registers */ -IRQ_src_t src[MAX_IRQ ]; +IRQSource src[MAX_IRQ ];/* Local registers per output pin */ -IRQ_dst_t dst[MAX_CPU ]; +IRQDest dst[MAX_CPU ];uint32_t nb_cpus;/* Timer registers */ struct {
@@ -258,26 +258,26 @@ typedef struct OpenPICState {uint32_t irq_msi; } OpenPICState; -static void openpic_irq_raise (OpenPICState *opp,int n_CPU,IRQ_src_t *src); +static void openpic_irq_raise (OpenPICState *opp,int n_CPU,IRQSource *src); -static inline void IRQ_setbit (IRQ_queue_t *q,int n_IRQ) +static inline void IRQ_setbit (IRQQueue *q,int n_IRQ) { q->pending++;set_bit (q->queue, n_IRQ); } -static inline void IRQ_resetbit (IRQ_queue_t *q,int n_IRQ) +static inline void IRQ_resetbit (IRQQueue *q,int n_IRQ) { q->pending--;reset_bit (q->queue, n_IRQ); } -static inline int IRQ_testbit (IRQ_queue_t *q,int n_IRQ) +static inline int IRQ_testbit (IRQQueue *q,int n_IRQ) {return test_bit (q->queue, n_IRQ); } -static void IRQ_check (OpenPICState *opp,IRQ_queue_t *q) +static void IRQ_check (OpenPICState *opp,IRQQueue *q) {int next, i;int priority;
@@ -306,7 +306,7 @@ out: q->priority = priority; } -static int IRQ_get_next (OpenPICState *opp,IRQ_queue_t *q) +static int IRQ_get_next (OpenPICState *opp,IRQQueue *q) {if (q->next ==-1 ) {/* XXX: optimize */
@@ -318,8 +318,8 @@ static int IRQ_get_next(OpenPICState *opp, IRQ_queue_t *q)static void IRQ_local_pipe (OpenPICState *opp,int n_CPU,int n_IRQ) { -IRQ_dst_t *dst; -IRQ_src_t *src; +IRQDest *dst; +IRQSource *src;int priority; dst = &opp->dst[n_CPU];
@@ -360,7 +360,7 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ)/* update pic state because registers for n_IRQ have changed value */ static void openpic_update_irq (OpenPICState *opp,int n_IRQ) { -IRQ_src_t *src; +IRQSource *src;int i; src = &opp->src[n_IRQ];
@@ -404,8 +404,9 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ) }else {/* Distributed delivery mode */ for (i = src->last_cpu +1 ; i != src->last_cpu; i++) { -if (i == opp->nb_cpus) +if (i == opp->nb_cpus) { i =0 ; + }if (src->ide & (1 << i)) {IRQ_local_pipe (opp, i, n_IRQ); src->last_cpu = i;
@@ -418,7 +419,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)static void openpic_set_irq (void *opaque,int n_IRQ,int level) {OpenPICState *opp = opaque; -IRQ_src_t *src; +IRQSource *src; src = &opp->src[n_IRQ]; DPRINTF("openpic: set irq %d = %d ipvp=%08x\n",
@@ -431,8 +432,9 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level) } }else {/* edge-sensitive irq */ -if (level) +if (level) { src->pending =1 ; + } }openpic_update_irq (opp, n_IRQ); }
@@ -459,9 +461,9 @@ static void openpic_reset(DeviceState *d)/* Initialise IRQ destinations */ for (i =0 ; i <MAX_CPU ; i++) { opp->dst[i].pctp =15 ; -memset (&opp->dst[i].raised,0 ,sizeof (IRQ_queue_t)); +memset (&opp->dst[i].raised,0 ,sizeof (IRQQueue)); opp->dst[i].raised.next =-1 ; -memset (&opp->dst[i].servicing,0 ,sizeof (IRQ_queue_t)); +memset (&opp->dst[i].servicing,0 ,sizeof (IRQQueue)); opp->dst[i].servicing.next =-1 ; }/* Initialise timers */
@@ -508,12 +510,13 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val, unsigned len) {OpenPICState *opp = opaque; -IRQ_dst_t *dst; +IRQDest *dst;int idx;DPRINTF ("%s: addr " TARGET_FMT_plx" <= %08x\n" , __func__, addr, val); -if (addr &0xF ) +if (addr &0xF ) {return ; + }switch (addr) {case 0x00 :/* Block Revision Register1 (BRR1) is Readonly */ break ;
@@ -575,8 +578,9 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)DPRINTF ("%s: addr " TARGET_FMT_plx"\n" , __func__, addr); retval =0xFFFFFFFF ; -if (addr &0xF ) +if (addr &0xF ) {return retval; + }switch (addr) {case 0x1000 :/* FREP */ retval = opp->frep;
@@ -631,8 +635,9 @@ static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,int idx;DPRINTF ("%s: addr %08x <= %08x\n" , __func__, addr, val); -if (addr &0xF ) +if (addr &0xF ) {return ; + } idx = (addr >>6 ) &0x3 ; addr = addr &0x30 ;
@@ -705,8 +710,9 @@ static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,int idx;DPRINTF ("%s: addr %08x <= %08x\n" , __func__, addr, val); -if (addr &0xF ) +if (addr &0xF ) {return ; + } addr = addr &0xFFF0 ; idx = addr >>5 ;if (addr &0x10 ) {
@@ -726,8 +732,9 @@ static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)DPRINTF ("%s: addr %08x\n" , __func__, addr); retval =0xFFFFFFFF ; -if (addr &0xF ) +if (addr &0xF ) {return retval; + } addr = addr &0xFFF0 ; idx = addr >>5 ;if (addr &0x10 ) {
@@ -808,8 +815,8 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, uint32_t val, int idx) {OpenPICState *opp = opaque; -IRQ_src_t *src; -IRQ_dst_t *dst; +IRQSource *src; +IRQDest *dst;int s_IRQ, n_IRQ; DPRINTF("%s: cpu %d addr " TARGET_FMT_plx " <= %08x\n", __func__, idx,
@@ -819,8 +826,9 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,return ; } -if (addr &0xF ) +if (addr &0xF ) {return ; + } dst = &opp->dst[idx]; addr &=0xFF0 ;switch (addr) {
@@ -877,8 +885,8 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, int idx) {OpenPICState *opp = opaque; -IRQ_src_t *src; -IRQ_dst_t *dst; +IRQSource *src; +IRQDest *dst;uint32_t retval;int n_IRQ;
@@ -889,8 +897,9 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,return retval; } -if (addr &0xF ) +if (addr &0xF ) {return retval; + } dst = &opp->dst[idx]; addr &=0xFF0 ;switch (addr) {
@@ -1059,7 +1068,7 @@ static const MemoryRegionOps openpic_msi_ops_be = { }, }; -static void openpic_save_IRQ_queue (QEMUFile * f,IRQ_queue_t *q) +static void openpic_save_IRQ_queue (QEMUFile * f,IRQQueue *q) {unsigned int i;
@@ -1102,7 +1111,7 @@ static void openpic_save(QEMUFile* f, void *opaque) } } -static void openpic_load_IRQ_queue (QEMUFile * f,IRQ_queue_t *q) +static void openpic_load_IRQ_queue (QEMUFile * f,IRQQueue *q) {unsigned int i;
@@ -1118,8 +1127,9 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)OpenPICState *opp = (OpenPICState *)opaque;unsigned int i; -if (version_id !=1 ) +if (version_id !=1 ) {return -EINVAL ; + }qemu_get_be32s (f, &opp->glbc);qemu_get_be32s (f, &opp->veni);
@@ -1150,7 +1160,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)return 0 ; } -static void openpic_irq_raise (OpenPICState *opp,int n_CPU,IRQ_src_t *src) +static void openpic_irq_raise (OpenPICState *opp,int n_CPU,IRQSource *src) {int n_ci =IDR_CI0_SHIFT - n_CPU;
@@ -1161,19 +1171,19 @@ static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src) } } -struct memreg { +typedef struct MemReg {const char *name;MemoryRegionOps const *ops;bool map;hwaddr start_addr;ram_addr_t size; -}; +}MemReg ;static int openpic_init (SysBusDevice *dev) {OpenPICState *opp =FROM_SYSBUS (typeof (*opp), dev);int i, j; -struct memreg list_le[] = { +MemReg list_le[] = { {"glb" , &openpic_glb_ops_le, true,OPENPIC_GLB_REG_START ,OPENPIC_GLB_REG_SIZE }, {"tmr" , &openpic_tmr_ops_le, true,
@@ -1185,7 +1195,7 @@ static int openpic_init(SysBusDevice *dev) {"cpu", &openpic_cpu_ops_le, true, OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, }; - struct memreg list_be[] = { + MemReg list_be[] = { {"glb", &openpic_glb_ops_be, true, OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE}, {"tmr", &openpic_tmr_ops_be, true,
@@ -1197,7 +1207,7 @@ static int openpic_init(SysBusDevice *dev) {"cpu" , &openpic_cpu_ops_be, true, OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, }; -struct memreg *list; +MemReg *list;switch (opp->model) {case OPENPIC_MODEL_FSL_MPIC_20 :
Signature · 1 line
1.6.0.2
PATCH 9/31 PPC: Reset qemu timers when guest reset
In reply to Alexander GrafFrom: Bharat Bhushan <[email protected]>
This patch install the timer reset handler. This will be called when the guest is reset.
--- hw/ppc_booke.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
hw/ppc_booke.c +13 -0
@@ -237,6 +237,17 @@ void store_booke_tcr(CPUPPCState *env, target_ulong val) } +static void ppc_booke_timer_reset_handle (void *opaque) +{ +PowerPCCPU *cpu = opaque; +CPUPPCState *env = &cpu->env; + + env->spr[SPR_BOOKE_TSR ] =0 ; + env->spr[SPR_BOOKE_TCR ] =0 ; + +booke_update_irq (cpu); +} +void ppc_booke_timers_init (PowerPCCPU *cpu,uint32_t freq,uint32_t flags) {ppc_tb_t *tb_env;
@@ -257,4 +268,6 @@ void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)qemu_new_timer_ns (vm_clock, &booke_fit_cb, cpu); booke_timer->wdt_timer =qemu_new_timer_ns (vm_clock, &booke_wdt_cb, cpu); + +qemu_register_reset (ppc_booke_timer_reset_handle, cpu); }
Signature · 1 line
1.6.0.2
PATCH 10/31 PPC: fix segfault in signal handling code
In reply to Alexander GrafFrom: Samuel Seay <[email protected]>
Removed h2g() macro around the ka->_sa_handler due to the _sa_handler being a guest memory address.
Changed the __put_user to put_user as it was attempting to put a value at the stack address but the new address is a guest memory address, __put_user is for host memory addresses.
--- linux-user/signal.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
linux-user/signal.c +2 -2
@@ -4584,7 +4584,7 @@ static void setup_frame(int sig, struct target_sigaction *ka, signal =current_exec_domain_sig (sig); - err |=__put_user (h2g (ka->_sa_handler), &sc->handler); + err |=__put_user (ka->_sa_handler, &sc->handler); err |=__put_user (set->sig[0 ], &sc->oldmask);#if defined(TARGET_PPC64 ) err |=__put_user (set->sig[0 ] >>32 , &sc->_unused[3 ]);
@@ -4606,7 +4606,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,/* Create a stack frame for the caller of the handler. */ newsp = frame_addr -SIGNAL_FRAMESIZE ; - err |=__put_user (env->gpr[1 ], (target_ulong *)(uintptr_t ) newsp); + err |=put_user (env->gpr[1 ], newsp, target_ulong);if (err) goto sigsegv;
Signature · 1 line
1.6.0.2
PATCH 11/31 openpic: fix debug prints
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Fix various format errors when debug prints are enabled. Also cause error checking to happen even when debug prints are not enabled, and consistently use 0x for hex output.
--- hw/openpic.c | 44 +++++++++++++++++++++++++++----------------- 1 files changed, 27 insertions(+), 17 deletions(-)
hw/openpic.c +27 -17
@@ -43,11 +43,17 @@//#define DEBUG_OPENPIC #ifdef DEBUG_OPENPIC -#define DPRINTF (fmt, ...) do { printf(fmt , ## __VA_ARGS__); } while (0) +static const int debug_openpic =1 ;#else -#define DPRINTF (fmt, ...) do { } while (0) +static const int debug_openpic =0 ;#endif +#define DPRINTF (fmt, ...) do { \ + if (debug_openpic) { \ + printf(fmt , ## __VA_ARGS__); \ + } \ + } while (0) +#define MAX_CPU 15#define MAX_SRC 256#define MAX_TMR 4
@@ -422,7 +428,7 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)IRQSource *src; src = &opp->src[n_IRQ]; -DPRINTF ("openpic: set irq %d = %d ipvp=%08x\n" , +DPRINTF ("openpic: set irq %d = %d ipvp=0x%08x\n" , n_IRQ, level, src->ipvp);if (src->ipvp &IPVP_SENSE_MASK ) {/* level-sensitive irq */
@@ -513,7 +519,8 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,IRQDest *dst;int idx; -DPRINTF ("%s: addr " TARGET_FMT_plx" <= %08x\n" , __func__, addr, val); +DPRINTF ("%s: addr %#" HWADDR_PRIx" <= %08" PRIx64"\n" , + __func__, addr, val);if (addr &0xF ) {return ; }
@@ -576,7 +583,7 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)OpenPICState *opp = opaque;uint32_t retval; -DPRINTF ("%s: addr " TARGET_FMT_plx"\n" , __func__, addr); +DPRINTF ("%s: addr %#" HWADDR_PRIx"\n" , __func__, addr); retval =0xFFFFFFFF ;if (addr &0xF ) {return retval;
@@ -623,7 +630,7 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)default :break ; } -DPRINTF ("%s: => %08x\n" , __func__, retval); +DPRINTF ("%s: => 0x%08x\n" , __func__, retval);return retval; }
@@ -634,7 +641,8 @@ static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val,OpenPICState *opp = opaque;int idx; -DPRINTF ("%s: addr %08x <= %08x\n" , __func__, addr, val); +DPRINTF ("%s: addr %#" HWADDR_PRIx" <= %08" PRIx64"\n" , + __func__, addr, val);if (addr &0xF ) {return ; }
@@ -672,7 +680,7 @@ static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len)uint32_t retval =-1 ;int idx; -DPRINTF ("%s: addr %08x\n" , __func__, addr); +DPRINTF ("%s: addr %#" HWADDR_PRIx"\n" , __func__, addr);if (addr &0xF ) { goto out; }
@@ -698,7 +706,7 @@ static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len) } out: -DPRINTF ("%s: => %08x\n" , __func__, retval); +DPRINTF ("%s: => 0x%08x\n" , __func__, retval);return retval; }
@@ -709,7 +717,8 @@ static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val,OpenPICState *opp = opaque;int idx; -DPRINTF ("%s: addr %08x <= %08x\n" , __func__, addr, val); +DPRINTF ("%s: addr %#" HWADDR_PRIx" <= %08" PRIx64"\n" , + __func__, addr, val);if (addr &0xF ) {return ; }
@@ -730,7 +739,7 @@ static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)uint32_t retval;int idx; -DPRINTF ("%s: addr %08x\n" , __func__, addr); +DPRINTF ("%s: addr %#" HWADDR_PRIx"\n" , __func__, addr); retval =0xFFFFFFFF ;if (addr &0xF ) {return retval;
@@ -744,7 +753,7 @@ static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len)/* EXVP / IFEVP / IEEVP */ retval =read_IRQreg_ipvp (opp, idx); } -DPRINTF ("%s: => %08x\n" , __func__, retval); +DPRINTF ("%s: => 0x%08x\n" , __func__, retval);return retval; }
@@ -756,7 +765,8 @@ static void openpic_msi_write(void *opaque, hwaddr addr, uint64_t val,int idx = opp->irq_msi;int srs, ibs; -DPRINTF ("%s: addr " TARGET_FMT_plx" <= %08x\n" , __func__, addr, val); +DPRINTF ("%s: addr %#" HWADDR_PRIx" <= 0x%08" PRIx64"\n" , + __func__, addr, val);if (addr &0xF ) {return ; }
@@ -781,7 +791,7 @@ static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size)uint64_t r =0 ;int i, srs; -DPRINTF ("%s: addr " TARGET_FMT_plx"\n" , __func__, addr); +DPRINTF ("%s: addr %#" HWADDR_PRIx"\n" , __func__, addr);if (addr &0xF ) {return -1 ; }
@@ -819,7 +829,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,IRQDest *dst;int s_IRQ, n_IRQ; -DPRINTF ("%s: cpu %d addr " TARGET_FMT_plx" <= %08x\n" , __func__, idx, +DPRINTF ("%s: cpu %d addr %#" HWADDR_PRIx" <= 0x%08x\n" , __func__, idx, addr, val);if (idx <0 ) {
@@ -890,7 +900,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,uint32_t retval;int n_IRQ; -DPRINTF ("%s: cpu %d addr " TARGET_FMT_plx"\n" , __func__, idx, addr); +DPRINTF ("%s: cpu %d addr %#" HWADDR_PRIx"\n" , __func__, idx, addr); retval =0xFFFFFFFF ;if (idx <0 ) {
@@ -958,7 +968,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,default :break ; } -DPRINTF ("%s: => %08x\n" , __func__, retval); +DPRINTF ("%s: => 0x%08x\n" , __func__, retval);return retval; }
Signature · 1 line
1.6.0.2
PATCH 12/31 openpic: lower interrupt when reading the MSI register
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
This will stop things from breaking once it's properly treated as a level-triggered interrupt. Note that it's the MPIC's MSI cascade interrupts that are level-triggered; the individual MSIs are edge-triggered.
--- hw/openpic.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
hw/openpic.c +1 -0
@@ -810,6 +810,7 @@ static uint64_t openpic_msi_read(void *opaque, hwaddr addr, unsigned size) r = opp->msi[srs].msir;/* Clear on read */ opp->msi[srs].msir =0 ; +openpic_set_irq (opp, opp->irq_msi + srs,0 );break ;case 0x120 :/* MSISR */ for (i =0 ; i <MAX_MSI ; i++) {
Signature · 1 line
1.6.0.2
PATCH 13/31 ppc/booke: fix crit/mcheck/debug exceptions
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Book E does not play games with certain bits of xSRR1 being MSR save bits and others being error status. xSRR1 is the old MSR, period. This was causing things like MSR[CE] to be lost, even in the saved version, as soon as you take an exception.
rfci/rfdi/rfmci are fixed to pass the actual xSRR1 register contents, rather than the register number.
Put FIXME comments on the hack that is "asrr0/1". The whole point of separate exception levels is so that you can, for example, take a machine check or debug interrupt without corrupting critical-level operations. The right xSRR0/1 set needs to be chosen based on CPU type flags.
--- target-ppc/excp_helper.c | 31 ++++++++++++++++++++++--------- 1 files changed, 22 insertions(+), 9 deletions(-)
target-ppc/excp_helper.c +22 -9
@@ -84,7 +84,11 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) " => %08x (%02x)\n", env->nip, excp, env->error_code);/* new srr1 value excluding must-be-zero bits */ - msr = env->msr & ~0x783f0000ULL ; +if (excp_model ==POWERPC_EXCP_BOOKE ) { + msr = env->msr; + }else { + msr = env->msr & ~0x783f0000ULL ; + }/* new interrupt handler msr */ new_msr = env->msr & ((target_ulong )1 <<MSR_ME );
@@ -145,6 +149,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp) srr1 = SPR_40x_SRR3;break ;case POWERPC_EXCP_BOOKE : +/* FIXME: choose one or the other based on CPU type */ srr0 =SPR_BOOKE_MCSRR0 ; srr1 =SPR_BOOKE_MCSRR1 ; asrr0 =SPR_BOOKE_CSRR0 ;
@@ -275,6 +280,7 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)case POWERPC_EXCP_DEBUG :/* Debug interrupt */ switch (excp_model) {case POWERPC_EXCP_BOOKE : +/* FIXME: choose one or the other based on CPU type */ srr0 =SPR_BOOKE_DSRR0 ; srr1 =SPR_BOOKE_DSRR1 ; asrr0 =SPR_BOOKE_CSRR0 ;
@@ -836,8 +842,13 @@ static inline void do_rfi(CPUPPCState *env, target_ulong nip, target_ulong msr,void helper_rfi (CPUPPCState *env) { -do_rfi (env, env->spr[SPR_SRR0 ], env->spr[SPR_SRR1 ], - ~((target_ulong )0x783F0000 ),1 ); +if (env->excp_model ==POWERPC_EXCP_BOOKE ) { +do_rfi (env, env->spr[SPR_SRR0 ], env->spr[SPR_SRR1 ], + ~((target_ulong )0 ),0 ); + }else { +do_rfi (env, env->spr[SPR_SRR0 ], env->spr[SPR_SRR1 ], + ~((target_ulong )0x783F0000 ),1 ); + } }#if defined(TARGET_PPC64 )
@@ -864,20 +875,22 @@ void helper_40x_rfci(CPUPPCState *env)void helper_rfci (CPUPPCState *env) { -do_rfi (env, env->spr[SPR_BOOKE_CSRR0 ],SPR_BOOKE_CSRR1 , - ~((target_ulong )0x3FFF0000 ),0 ); +do_rfi (env, env->spr[SPR_BOOKE_CSRR0 ], env->spr[SPR_BOOKE_CSRR1 ], + ~((target_ulong )0 ),0 ); }void helper_rfdi (CPUPPCState *env) { -do_rfi (env, env->spr[SPR_BOOKE_DSRR0 ],SPR_BOOKE_DSRR1 , - ~((target_ulong )0x3FFF0000 ),0 ); +/* FIXME: choose CSRR1 or DSRR1 based on cpu type */ +do_rfi (env, env->spr[SPR_BOOKE_DSRR0 ], env->spr[SPR_BOOKE_DSRR1 ], + ~((target_ulong )0 ),0 ); }void helper_rfmci (CPUPPCState *env) { -do_rfi (env, env->spr[SPR_BOOKE_MCSRR0 ],SPR_BOOKE_MCSRR1 , - ~((target_ulong )0x3FFF0000 ),0 ); +/* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ +do_rfi (env, env->spr[SPR_BOOKE_MCSRR0 ], env->spr[SPR_BOOKE_MCSRR1 ], + ~((target_ulong )0 ),0 ); }#endif
Signature · 1 line
1.6.0.2
PATCH 14/31 openpic: make register names correspond better with hw docs
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
The base openpic specification doesn't provide abbreviated register names, so it's somewhat understandable that the QEMU code made up its own, except that most of the names that QEMU used didn't correspond to the terminology used by any implementation I could find.
In some cases, like PCTP, the phrase "processor current task priority" could be found in the openpic spec when describing the concept, but the register itself was labelled "current task priority register" and every implementation seems to use either CTPR or the full phrase.
In other cases, individual implementations disagree on what to call the register. The implementations I have documentation for are Freescale, Raven (MCP750), and IBM. The Raven docs tend to not use abbreviations at all. The IBM MPIC isn't implemented in QEMU. Thus, where there's disagreement I chose to use the Freescale abbreviations.
--- hw/openpic.c | 356 +++++++++++++++++++++++++++++----------------------------- 1 files changed, 178 insertions(+), 178 deletions(-)
hw/openpic.c +178 -178
@@ -63,7 +63,7 @@ static const int debug_openpic = 0;#define VID 0x03/* MPIC version ID */ /* OpenPIC capability flags */ -#define OPENPIC_FLAG_IDE_CRIT (1 << 0) +#define OPENPIC_FLAG_IDR_CRIT (1 << 0)/* OpenPIC address map */ #define OPENPIC_GLB_REG_START 0x0
@@ -120,19 +120,19 @@ static const int debug_openpic = 0;#define FSL_BRR1_IPMJ (0x00 << 8)/* 8 bit IP major number */ #define FSL_BRR1_IPMN 0x00/* 8 bit IP minor number */ -#define FREP_NIRQ_SHIFT 16 -#define FREP_NCPU_SHIFT 8 -#define FREP_VID_SHIFT 0 +#define FRR_NIRQ_SHIFT 16 +#define FRR_NCPU_SHIFT 8 +#define FRR_VID_SHIFT 0#define VID_REVISION_1_2 2#define VID_REVISION_1_3 3 -#define VENI_GENERIC 0x00000000/* Generic Vendor ID */ +#define VIR_GENERIC 0x00000000/* Generic Vendor ID */ -#define GLBC_RESET 0x80000000 +#define GCR_RESET 0x80000000 -#define TIBC_CI 0x80000000/* count inhibit */ -#define TICC_TOG 0x80000000/* toggles when decrement to zero */ +#define TBCR_CI 0x80000000/* count inhibit */ +#define TCCR_TOG 0x80000000/* toggles when decrement to zero */ #define IDR_EP_SHIFT 31#define IDR_EP_MASK (1 << IDR_EP_SHIFT)
@@ -187,33 +187,33 @@ typedef struct IRQQueue { } IRQQueue;typedef struct IRQSource { -uint32_t ipvp;/* IRQ vector/priority register */ -uint32_t ide;/* IRQ destination register */ +uint32_t ivpr;/* IRQ vector/priority register */ +uint32_t idr;/* IRQ destination register */ int last_cpu;int pending;/* TRUE if IRQ is pending */ }IRQSource ; -#define IPVP_MASK_SHIFT 31 -#define IPVP_MASK_MASK (1 << IPVP_MASK_SHIFT) -#define IPVP_ACTIVITY_SHIFT 30 -#define IPVP_ACTIVITY_MASK (1 << IPVP_ACTIVITY_SHIFT) -#define IPVP_MODE_SHIFT 29 -#define IPVP_MODE_MASK (1 << IPVP_MODE_SHIFT) -#define IPVP_POLARITY_SHIFT 23 -#define IPVP_POLARITY_MASK (1 << IPVP_POLARITY_SHIFT) -#define IPVP_SENSE_SHIFT 22 -#define IPVP_SENSE_MASK (1 << IPVP_SENSE_SHIFT) - -#define IPVP_PRIORITY_MASK (0xF << 16) -#define IPVP_PRIORITY (_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16)) -#define IPVP_VECTOR (opp, _ipvpr_) ((_ipvpr_) & (opp)->vector_mask) - -/* IDE[EP/CI] are only for FSL MPIC prior to v4.0 */ -#define IDE_EP 0x80000000/* external pin */ -#define IDE_CI 0x40000000/* critical interrupt */ +#define IVPR_MASK_SHIFT 31 +#define IVPR_MASK_MASK (1 << IVPR_MASK_SHIFT) +#define IVPR_ACTIVITY_SHIFT 30 +#define IVPR_ACTIVITY_MASK (1 << IVPR_ACTIVITY_SHIFT) +#define IVPR_MODE_SHIFT 29 +#define IVPR_MODE_MASK (1 << IVPR_MODE_SHIFT) +#define IVPR_POLARITY_SHIFT 23 +#define IVPR_POLARITY_MASK (1 << IVPR_POLARITY_SHIFT) +#define IVPR_SENSE_SHIFT 22 +#define IVPR_SENSE_MASK (1 << IVPR_SENSE_SHIFT) + +#define IVPR_PRIORITY_MASK (0xF << 16) +#define IVPR_PRIORITY (_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16)) +#define IVPR_VECTOR (opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask) + +/* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */ +#define IDR_EP 0x80000000/* external pin */ +#define IDR_CI 0x40000000/* critical interrupt */ typedef struct IRQDest { - uint32_t pctp; /* CPU current task priority */ + uint32_t ctpr; /* CPU current task priority */ IRQQueue raised; IRQQueue servicing; qemu_irq *irqs;
@@ -228,22 +228,22 @@ typedef struct OpenPICState {uint32_t flags;uint32_t nb_irqs;uint32_t vid; -uint32_t veni;/* Vendor identification register */ +uint32_t vir;/* Vendor identification register */ uint32_t vector_mask; -uint32_t tifr_reset; -uint32_t ipvp_reset; -uint32_t ide_reset; +uint32_t tfrr_reset; +uint32_t ivpr_reset; +uint32_t idr_reset;uint32_t brr1;/* Sub-regions */ MemoryRegion sub_io_mem[5 ];/* Global registers */ -uint32_t frep;/* Feature reporting register */ -uint32_t glbc;/* Global configuration register */ -uint32_t pint;/* Processor initialization register */ +uint32_t frr;/* Feature reporting register */ +uint32_t gcr;/* Global configuration register */ +uint32_t pir;/* Processor initialization register */ uint32_t spve;/* Spurious vector register */ -uint32_t tifr;/* Timer frequency reporting register */ +uint32_t tfrr;/* Timer frequency reporting register */ /* Source registers */ IRQSource src[MAX_IRQ ];/* Local registers per output pin */
@@ -251,8 +251,8 @@ typedef struct OpenPICState {uint32_t nb_cpus;/* Timer registers */ struct { -uint32_t ticc;/* Global timer current count register */ -uint32_t tibc;/* Global timer base count register */ +uint32_t tccr;/* Global timer current count register */ +uint32_t tbcr;/* Global timer base count register */ } timers[MAX_TMR ];/* Shared MSI registers */ struct {
@@ -298,11 +298,11 @@ static void IRQ_check(OpenPICState *opp, IRQQueue *q)for (i =0 ; i < opp->max_irq; i++) {if (IRQ_testbit (q, i)) { -DPRINTF ("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n" , - i,IPVP_PRIORITY (opp->src[i].ipvp), priority); -if (IPVP_PRIORITY (opp->src[i].ipvp) > priority) { +DPRINTF ("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n" , + i,IVPR_PRIORITY (opp->src[i].ivpr), priority); +if (IVPR_PRIORITY (opp->src[i].ivpr) > priority) { next = i; - priority =IPVP_PRIORITY (opp->src[i].ipvp); + priority =IVPR_PRIORITY (opp->src[i].ivpr); } } }
@@ -330,8 +330,8 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ) dst = &opp->dst[n_CPU]; src = &opp->src[n_IRQ]; - priority =IPVP_PRIORITY (src->ipvp); -if (priority <= dst->pctp) { + priority =IVPR_PRIORITY (src->ivpr); +if (priority <= dst->ctpr) {/* Too low priority */ DPRINTF ("%s: IRQ %d has too low priority on CPU %d\n" , __func__, n_IRQ, n_CPU);
@@ -343,7 +343,7 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ) __func__, n_IRQ, n_CPU);return ; } - src->ipvp |=IPVP_ACTIVITY_MASK ; + src->ivpr |=IVPR_ACTIVITY_MASK ;IRQ_setbit (&dst->raised, n_IRQ);if (priority < dst->raised.priority) {/* An higher priority IRQ is already raised */
@@ -376,34 +376,34 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)DPRINTF ("%s: IRQ %d is not pending\n" , __func__, n_IRQ);return ; } -if (src->ipvp &IPVP_MASK_MASK ) { +if (src->ivpr &IVPR_MASK_MASK ) {/* Interrupt source is disabled */ DPRINTF ("%s: IRQ %d is disabled\n" , __func__, n_IRQ);return ; } -if (IPVP_PRIORITY (src->ipvp) ==0 ) { +if (IVPR_PRIORITY (src->ivpr) ==0 ) {/* Priority set to zero */ DPRINTF ("%s: IRQ %d has 0 priority\n" , __func__, n_IRQ);return ; } -if (src->ipvp &IPVP_ACTIVITY_MASK ) { +if (src->ivpr &IVPR_ACTIVITY_MASK ) {/* IRQ already active */ DPRINTF ("%s: IRQ %d is already active\n" , __func__, n_IRQ);return ; } -if (src->ide ==0 ) { +if (src->idr ==0 ) {/* No target */ DPRINTF ("%s: IRQ %d has no target\n" , __func__, n_IRQ);return ; } -if (src->ide == (1 << src->last_cpu)) { +if (src->idr == (1 << src->last_cpu)) {/* Only one CPU is allowed to receive this IRQ */ IRQ_local_pipe (opp, src->last_cpu, n_IRQ); - }else if (!(src->ipvp &IPVP_MODE_MASK )) { + }else if (!(src->ivpr &IVPR_MODE_MASK )) {/* Directed delivery mode */ for (i =0 ; i < opp->nb_cpus; i++) { -if (src->ide & (1 << i)) { +if (src->idr & (1 << i)) {IRQ_local_pipe (opp, i, n_IRQ); } }
@@ -413,7 +413,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)if (i == opp->nb_cpus) { i =0 ; } -if (src->ide & (1 << i)) { +if (src->idr & (1 << i)) {IRQ_local_pipe (opp, i, n_IRQ); src->last_cpu = i;break ;
@@ -428,13 +428,13 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)IRQSource *src; src = &opp->src[n_IRQ]; -DPRINTF ("openpic: set irq %d = %d ipvp=0x%08x\n" , - n_IRQ, level, src->ipvp); -if (src->ipvp &IPVP_SENSE_MASK ) { +DPRINTF ("openpic: set irq %d = %d ivpr=0x%08x\n" , + n_IRQ, level, src->ivpr); +if (src->ivpr &IVPR_SENSE_MASK ) {/* level-sensitive irq */ src->pending = level;if (!level) { - src->ipvp &= ~IPVP_ACTIVITY_MASK ; + src->ivpr &= ~IVPR_ACTIVITY_MASK ; } }else {/* edge-sensitive irq */
@@ -450,23 +450,23 @@ static void openpic_reset(DeviceState *d)OpenPICState *opp =FROM_SYSBUS (typeof (*opp),sysbus_from_qdev (d));int i; - opp->glbc =GLBC_RESET ; + opp->gcr =GCR_RESET ;/* Initialise controller registers */ - opp->frep = ((opp->nb_irqs -1 ) <<FREP_NIRQ_SHIFT ) | - ((opp->nb_cpus -1 ) <<FREP_NCPU_SHIFT ) | - (opp->vid <<FREP_VID_SHIFT ); + opp->frr = ((opp->nb_irqs -1 ) <<FRR_NIRQ_SHIFT ) | + ((opp->nb_cpus -1 ) <<FRR_NCPU_SHIFT ) | + (opp->vid <<FRR_VID_SHIFT ); - opp->pint =0 ; + opp->pir =0 ; opp->spve =-1 & opp->vector_mask; - opp->tifr = opp->tifr_reset; + opp->tfrr = opp->tfrr_reset;/* Initialise IRQ sources */ for (i =0 ; i < opp->max_irq; i++) { - opp->src[i].ipvp = opp->ipvp_reset; - opp->src[i].ide = opp->ide_reset; + opp->src[i].ivpr = opp->ivpr_reset; + opp->src[i].idr = opp->idr_reset; }/* Initialise IRQ destinations */ for (i =0 ; i <MAX_CPU ; i++) { - opp->dst[i].pctp =15 ; + 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));
@@ -474,42 +474,42 @@ static void openpic_reset(DeviceState *d) }/* Initialise timers */ for (i =0 ; i <MAX_TMR ; i++) { - opp->timers[i].ticc =0 ; - opp->timers[i].tibc =TIBC_CI ; + opp->timers[i].tccr =0 ; + opp->timers[i].tbcr =TBCR_CI ; }/* Go out of RESET state */ - opp->glbc =0 ; + opp->gcr =0 ; } -static inline uint32_t read_IRQreg_ide (OpenPICState *opp,int n_IRQ) +static inline uint32_t read_IRQreg_idr (OpenPICState *opp,int n_IRQ) { -return opp->src[n_IRQ].ide; +return opp->src[n_IRQ].idr; } -static inline uint32_t read_IRQreg_ipvp (OpenPICState *opp,int n_IRQ) +static inline uint32_t read_IRQreg_ivpr (OpenPICState *opp,int n_IRQ) { -return opp->src[n_IRQ].ipvp; +return opp->src[n_IRQ].ivpr; } -static inline void write_IRQreg_ide (OpenPICState *opp,int n_IRQ,uint32_t val) +static inline void write_IRQreg_idr (OpenPICState *opp,int n_IRQ,uint32_t val) {uint32_t tmp; - tmp = val & (IDE_EP |IDE_CI ); + tmp = val & (IDR_EP |IDR_CI ); tmp |= val & ((1ULL <<MAX_CPU ) -1 ); - opp->src[n_IRQ].ide = tmp; -DPRINTF ("Set IDE %d to 0x%08x\n" , n_IRQ, opp->src[n_IRQ].ide); + opp->src[n_IRQ].idr = tmp; +DPRINTF ("Set IDR %d to 0x%08x\n" , n_IRQ, opp->src[n_IRQ].idr); } -static inline void write_IRQreg_ipvp (OpenPICState *opp,int n_IRQ,uint32_t val) +static inline void write_IRQreg_ivpr (OpenPICState *opp,int n_IRQ,uint32_t val) {/* NOTE: not fully accurate for special IRQs, but simple and sufficient */ /* ACTIVITY bit is read-only */ - opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp &IPVP_ACTIVITY_MASK ) | - (val & (IPVP_MASK_MASK |IPVP_PRIORITY_MASK | opp->vector_mask)); + opp->src[n_IRQ].ivpr = (opp->src[n_IRQ].ivpr &IVPR_ACTIVITY_MASK ) | + (val & (IVPR_MASK_MASK |IVPR_PRIORITY_MASK | opp->vector_mask));openpic_update_irq (opp, n_IRQ); -DPRINTF ("Set IPVP %d to 0x%08x -> 0x%08x\n" , n_IRQ, val, - opp->src[n_IRQ].ipvp); +DPRINTF ("Set IVPR %d to 0x%08x -> 0x%08x\n" , n_IRQ, val, + opp->src[n_IRQ].ivpr); } static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
@@ -537,37 +537,37 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,case 0xB0 :openpic_cpu_write_internal (opp, addr, val,get_current_cpu ());break ; -case 0x1000 :/* FREP */ +case 0x1000 :/* FRR */ break ; -case 0x1020 :/* GLBC */ -if (val &GLBC_RESET ) { +case 0x1020 :/* GCR */ +if (val &GCR_RESET ) {openpic_reset (&opp->busdev.qdev); }break ; -case 0x1080 :/* VENI */ +case 0x1080 :/* VIR */ break ; -case 0x1090 :/* PINT */ +case 0x1090 :/* PIR */ for (idx =0 ; idx < opp->nb_cpus; idx++) { -if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) { +if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) {DPRINTF ("Raise OpenPIC RESET output for CPU %d\n" , idx); dst = &opp->dst[idx];qemu_irq_raise (dst->irqs[OPENPIC_OUTPUT_RESET ]); - }else if (!(val & (1 << idx)) && (opp->pint & (1 << idx))) { + }else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) {DPRINTF ("Lower OpenPIC RESET output for CPU %d\n" , idx); dst = &opp->dst[idx];qemu_irq_lower (dst->irqs[OPENPIC_OUTPUT_RESET ]); } } - opp->pint = val; + opp->pir = val;break ; -case 0x10A0 :/* IPI_IPVP */ +case 0x10A0 :/* IPI_IVPR */ case 0x10B0 :case 0x10C0 :case 0x10D0 : {int idx; idx = (addr -0x10A0 ) >>4 ; -write_IRQreg_ipvp (opp, opp->irq_ipi0 + idx, val); +write_IRQreg_ivpr (opp, opp->irq_ipi0 + idx, val); }break ;case 0x10E0 :/* SPVE */
@@ -589,16 +589,16 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)return retval; }switch (addr) { -case 0x1000 :/* FREP */ - retval = opp->frep; +case 0x1000 :/* FRR */ + retval = opp->frr;break ; -case 0x1020 :/* GLBC */ - retval = opp->glbc; +case 0x1020 :/* GCR */ + retval = opp->gcr;break ; -case 0x1080 :/* VENI */ - retval = opp->veni; +case 0x1080 :/* VIR */ + retval = opp->vir;break ; -case 0x1090 :/* PINT */ +case 0x1090 :/* PIR */ retval =0x00000000 ;break ;case 0x00 :/* Block Revision Register1 (BRR1) */
@@ -614,14 +614,14 @@ static uint64_t openpic_gbl_read(void *opaque, hwaddr addr, unsigned len)case 0xB0 : retval =openpic_cpu_read_internal (opp, addr,get_current_cpu ());break ; -case 0x10A0 :/* IPI_IPVP */ +case 0x10A0 :/* IPI_IVPR */ case 0x10B0 :case 0x10C0 :case 0x10D0 : {int idx; idx = (addr -0x10A0 ) >>4 ; - retval =read_IRQreg_ipvp (opp, opp->irq_ipi0 + idx); + retval =read_IRQreg_ivpr (opp, opp->irq_ipi0 + idx); }break ;case 0x10E0 :/* SPVE */
@@ -650,26 +650,26 @@ static void openpic_tmr_write(void *opaque, hwaddr addr, uint64_t val, addr = addr &0x30 ;if (addr ==0x0 ) { -/* TIFR (TFRR) */ - opp->tifr = val; +/* TFRR */ + opp->tfrr = val;return ; }switch (addr &0x30 ) { -case 0x00 :/* TICC (GTCCR) */ +case 0x00 :/* TCCR */ break ; -case 0x10 :/* TIBC (GTBCR) */ -if ((opp->timers[idx].ticc &TICC_TOG ) !=0 && - (val &TIBC_CI ) ==0 && - (opp->timers[idx].tibc &TIBC_CI ) !=0 ) { - opp->timers[idx].ticc &= ~TICC_TOG ; +case 0x10 :/* TBCR */ +if ((opp->timers[idx].tccr &TCCR_TOG ) !=0 && + (val &TBCR_CI ) ==0 && + (opp->timers[idx].tbcr &TBCR_CI ) !=0 ) { + opp->timers[idx].tccr &= ~TCCR_TOG ; } - opp->timers[idx].tibc = val; + opp->timers[idx].tbcr = val;break ; -case 0x20 :/* TIVP (GTIVPR) */ -write_IRQreg_ipvp (opp, opp->irq_tim0 + idx, val); +case 0x20 :/* TVPR */ +write_IRQreg_ivpr (opp, opp->irq_tim0 + idx, val);break ; -case 0x30 :/* TIDE (GTIDR) */ -write_IRQreg_ide (opp, opp->irq_tim0 + idx, val); +case 0x30 :/* TDR */ +write_IRQreg_idr (opp, opp->irq_tim0 + idx, val);break ; } }
@@ -686,22 +686,22 @@ static uint64_t openpic_tmr_read(void *opaque, hwaddr addr, unsigned len) } idx = (addr >>6 ) &0x3 ;if (addr ==0x0 ) { -/* TIFR (TFRR) */ - retval = opp->tifr; +/* TFRR */ + retval = opp->tfrr; goto out; }switch (addr &0x30 ) { -case 0x00 :/* TICC (GTCCR) */ - retval = opp->timers[idx].ticc; +case 0x00 :/* TCCR */ + retval = opp->timers[idx].tccr;break ; -case 0x10 :/* TIBC (GTBCR) */ - retval = opp->timers[idx].tibc; +case 0x10 :/* TBCR */ + retval = opp->timers[idx].tbcr;break ; -case 0x20 :/* TIPV (TIPV) */ - retval =read_IRQreg_ipvp (opp, opp->irq_tim0 + idx); +case 0x20 :/* TIPV */ + retval =read_IRQreg_ivpr (opp, opp->irq_tim0 + idx);break ;case 0x30 :/* TIDE (TIDR) */ - retval =read_IRQreg_ide (opp, opp->irq_tim0 + idx); + retval =read_IRQreg_idr (opp, opp->irq_tim0 + idx);break ; }
@@ -726,10 +726,10 @@ static void openpic_src_write(void *opaque, hwaddr addr, uint64_t val, idx = addr >>5 ;if (addr &0x10 ) {/* EXDE / IFEDE / IEEDE */ -write_IRQreg_ide (opp, idx, val); +write_IRQreg_idr (opp, idx, val); }else {/* EXVP / IFEVP / IEEVP */ -write_IRQreg_ipvp (opp, idx, val); +write_IRQreg_ivpr (opp, idx, val); } }
@@ -748,10 +748,10 @@ static uint64_t openpic_src_read(void *opaque, uint64_t addr, unsigned len) idx = addr >>5 ;if (addr &0x10 ) {/* EXDE / IFEDE / IEEDE */ - retval =read_IRQreg_ide (opp, idx); + retval =read_IRQreg_idr (opp, idx); }else {/* EXVP / IFEVP / IEEVP */ - retval =read_IRQreg_ipvp (opp, idx); + retval =read_IRQreg_ivpr (opp, idx); }DPRINTF ("%s: => 0x%08x\n" , __func__, retval);
@@ -849,22 +849,22 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,case 0x70 : idx = (addr -0x40 ) >>4 ;/* we use IDE as mask which CPUs to deliver the IPI to still. */ -write_IRQreg_ide (opp, opp->irq_ipi0 + idx, - opp->src[opp->irq_ipi0 + idx].ide | val); +write_IRQreg_idr (opp, opp->irq_ipi0 + idx, + opp->src[opp->irq_ipi0 + idx].idr | val);openpic_set_irq (opp, opp->irq_ipi0 + idx,1 );openpic_set_irq (opp, opp->irq_ipi0 + idx,0 );break ; -case 0x80 :/* PCTP */ - dst->pctp = val &0x0000000F ; +case 0x80 :/* CTPR */ + dst->ctpr = val &0x0000000F ;break ;case 0x90 :/* WHOAMI */ /* Read-only register */ break ; -case 0xA0 :/* PIAC */ +case 0xA0 :/* IACK */ /* Read-only register */ break ; -case 0xB0 :/* PEOI */ -DPRINTF ("PEOI\n" ); +case 0xB0 :/* EOI */ +DPRINTF ("EOI\n" ); s_IRQ =IRQ_get_next (opp, &dst->servicing);IRQ_resetbit (&dst->servicing, s_IRQ); dst->servicing.next =-1 ;
@@ -875,7 +875,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, src = &opp->src[n_IRQ];if (n_IRQ !=-1 && (s_IRQ ==-1 || -IPVP_PRIORITY (src->ipvp) > dst->servicing.priority)) { +IVPR_PRIORITY (src->ivpr) > dst->servicing.priority)) {DPRINTF ("Raise OpenPIC INT output cpu %d irq %d\n" , idx, n_IRQ);openpic_irq_raise (opp, idx, src);
@@ -914,56 +914,56 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, dst = &opp->dst[idx]; addr &=0xFF0 ;switch (addr) { -case 0x80 :/* PCTP */ - retval = dst->pctp; +case 0x80 :/* CTPR */ + retval = dst->ctpr;break ;case 0x90 :/* WHOAMI */ retval = idx;break ; -case 0xA0 :/* PIAC */ +case 0xA0 :/* IACK */ DPRINTF ("Lower OpenPIC INT output\n" );qemu_irq_lower (dst->irqs[OPENPIC_OUTPUT_INT ]); n_IRQ =IRQ_get_next (opp, &dst->raised); -DPRINTF ("PIAC: irq=%d\n" , n_IRQ); +DPRINTF ("IACK: irq=%d\n" , n_IRQ);if (n_IRQ ==-1 ) {/* No more interrupt pending */ retval = opp->spve; }else { src = &opp->src[n_IRQ]; -if (!(src->ipvp &IPVP_ACTIVITY_MASK ) || - !(IPVP_PRIORITY (src->ipvp) > dst->pctp)) { +if (!(src->ivpr &IVPR_ACTIVITY_MASK ) || + !(IVPR_PRIORITY (src->ivpr) > dst->ctpr)) {/* - Spurious level-sensitive IRQ * - Priorities has been changed * and the pending IRQ isn't allowed anymore */ - src->ipvp &= ~IPVP_ACTIVITY_MASK ; + src->ivpr &= ~IVPR_ACTIVITY_MASK ; retval = opp->spve; }else {/* IRQ enter servicing state */ IRQ_setbit (&dst->servicing, n_IRQ); - retval =IPVP_VECTOR (opp, src->ipvp); + retval =IVPR_VECTOR (opp, src->ivpr); }IRQ_resetbit (&dst->raised, n_IRQ); dst->raised.next =-1 ; -if (!(src->ipvp &IPVP_SENSE_MASK )) { +if (!(src->ivpr &IVPR_SENSE_MASK )) {/* edge-sensitive IRQ */ - src->ipvp &= ~IPVP_ACTIVITY_MASK ; + src->ivpr &= ~IVPR_ACTIVITY_MASK ; src->pending =0 ; }if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 +MAX_IPI ))) { - src->ide &= ~(1 << idx); -if (src->ide && !(src->ipvp &IPVP_SENSE_MASK )) { + src->idr &= ~(1 << idx); +if (src->idr && !(src->ivpr &IVPR_SENSE_MASK )) {/* trigger on CPUs that didn't know about it yet */ openpic_set_irq (opp, n_IRQ,1 );openpic_set_irq (opp, n_IRQ,0 );/* if all CPUs knew about it, set active bit again */ - src->ipvp |=IPVP_ACTIVITY_MASK ; + src->ivpr |=IVPR_ACTIVITY_MASK ; } } }break ; -case 0xB0 :/* PEOI */ +case 0xB0 :/* EOI */ retval =0 ;break ;default :
@@ -1095,15 +1095,15 @@ static void openpic_save(QEMUFile* f, void *opaque)OpenPICState *opp = (OpenPICState *)opaque;unsigned int i; -qemu_put_be32s (f, &opp->glbc); -qemu_put_be32s (f, &opp->veni); -qemu_put_be32s (f, &opp->pint); +qemu_put_be32s (f, &opp->gcr); +qemu_put_be32s (f, &opp->vir); +qemu_put_be32s (f, &opp->pir);qemu_put_be32s (f, &opp->spve); -qemu_put_be32s (f, &opp->tifr); +qemu_put_be32s (f, &opp->tfrr);for (i =0 ; i < opp->max_irq; i++) { -qemu_put_be32s (f, &opp->src[i].ipvp); -qemu_put_be32s (f, &opp->src[i].ide); +qemu_put_be32s (f, &opp->src[i].ivpr); +qemu_put_be32s (f, &opp->src[i].idr);qemu_put_sbe32s (f, &opp->src[i].last_cpu);qemu_put_sbe32s (f, &opp->src[i].pending); }
@@ -1111,14 +1111,14 @@ static void openpic_save(QEMUFile* f, void *opaque)qemu_put_be32s (f, &opp->nb_cpus);for (i =0 ; i < opp->nb_cpus; i++) { -qemu_put_be32s (f, &opp->dst[i].pctp); +qemu_put_be32s (f, &opp->dst[i].ctpr);openpic_save_IRQ_queue (f, &opp->dst[i].raised);openpic_save_IRQ_queue (f, &opp->dst[i].servicing); }for (i =0 ; i <MAX_TMR ; i++) { -qemu_put_be32s (f, &opp->timers[i].ticc); -qemu_put_be32s (f, &opp->timers[i].tibc); +qemu_put_be32s (f, &opp->timers[i].tccr); +qemu_put_be32s (f, &opp->timers[i].tbcr); } }
@@ -1142,15 +1142,15 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)return -EINVAL ; } -qemu_get_be32s (f, &opp->glbc); -qemu_get_be32s (f, &opp->veni); -qemu_get_be32s (f, &opp->pint); +qemu_get_be32s (f, &opp->gcr); +qemu_get_be32s (f, &opp->vir); +qemu_get_be32s (f, &opp->pir);qemu_get_be32s (f, &opp->spve); -qemu_get_be32s (f, &opp->tifr); +qemu_get_be32s (f, &opp->tfrr);for (i =0 ; i < opp->max_irq; i++) { -qemu_get_be32s (f, &opp->src[i].ipvp); -qemu_get_be32s (f, &opp->src[i].ide); +qemu_get_be32s (f, &opp->src[i].ivpr); +qemu_get_be32s (f, &opp->src[i].idr);qemu_get_sbe32s (f, &opp->src[i].last_cpu);qemu_get_sbe32s (f, &opp->src[i].pending); }
@@ -1158,14 +1158,14 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)qemu_get_be32s (f, &opp->nb_cpus);for (i =0 ; i < opp->nb_cpus; i++) { -qemu_get_be32s (f, &opp->dst[i].pctp); +qemu_get_be32s (f, &opp->dst[i].ctpr);openpic_load_IRQ_queue (f, &opp->dst[i].raised);openpic_load_IRQ_queue (f, &opp->dst[i].servicing); }for (i =0 ; i <MAX_TMR ; i++) { -qemu_get_be32s (f, &opp->timers[i].ticc); -qemu_get_be32s (f, &opp->timers[i].tibc); +qemu_get_be32s (f, &opp->timers[i].tccr); +qemu_get_be32s (f, &opp->timers[i].tbcr); }return 0 ;
@@ -1175,7 +1175,7 @@ static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQSource *src) {int n_ci =IDR_CI0_SHIFT - n_CPU; -if ((opp->flags &OPENPIC_FLAG_IDE_CRIT ) && (src->ide & (1 << n_ci))) { +if ((opp->flags &OPENPIC_FLAG_IDR_CRIT ) && (src->idr & (1 << n_ci))) {qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT ]); }else {qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT ]);
@@ -1223,14 +1223,14 @@ static int openpic_init(SysBusDevice *dev)switch (opp->model) {case OPENPIC_MODEL_FSL_MPIC_20 :default : - opp->flags |=OPENPIC_FLAG_IDE_CRIT ; + opp->flags |=OPENPIC_FLAG_IDR_CRIT ; opp->nb_irqs =80 ; opp->vid =VID_REVISION_1_2 ; - opp->veni =VENI_GENERIC ; + opp->vir =VIR_GENERIC ; opp->vector_mask =0xFFFF ; - opp->tifr_reset =0 ; - opp->ipvp_reset =IPVP_MASK_MASK ; - opp->ide_reset =1 <<0 ; + opp->tfrr_reset =0 ; + opp->ivpr_reset =IVPR_MASK_MASK ; + opp->idr_reset =1 <<0 ; opp->max_irq =FSL_MPIC_20_MAX_IRQ ; opp->irq_ipi0 =FSL_MPIC_20_IPI_IRQ ; opp->irq_tim0 =FSL_MPIC_20_TMR_IRQ ;
@@ -1242,11 +1242,11 @@ static int openpic_init(SysBusDevice *dev)case OPENPIC_MODEL_RAVEN : opp->nb_irqs =RAVEN_MAX_EXT ; opp->vid =VID_REVISION_1_3 ; - opp->veni =VENI_GENERIC ; + opp->vir =VIR_GENERIC ; opp->vector_mask =0xFF ; - opp->tifr_reset =4160000 ; - opp->ipvp_reset =IPVP_MASK_MASK |IPVP_MODE_MASK ; - opp->ide_reset =0 ; + opp->tfrr_reset =4160000 ; + opp->ivpr_reset =IVPR_MASK_MASK |IVPR_MODE_MASK ; + opp->idr_reset =0 ; opp->max_irq =RAVEN_MAX_IRQ ; opp->irq_ipi0 =RAVEN_IPI_IRQ ; opp->irq_tim0 =RAVEN_TMR_IRQ ;
Signature · 1 line
1.6.0.2
PATCH 15/31 openpic: rework critical interrupt support
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Critical interrupts on FSL MPIC are not supposed to pay attention to priority, IACK, EOI, etc. On the currently modeled version it's not supposed to pay attention to the mask bit either.
Also reorganize to make it easier to implement newer FSL MPIC models, which encode interrupt level information differently and support mcheck as well as crit, and to reduce problems for later patches in this set.
Still missing is the ability to lower the CINT signal to the core, as IACK/EOI is not used. This will come with general IRQ-source-driven lowering in the next patch.
New state is added which is not serialized, but instead is recomputed in openpic_load() by calling the appropriate write_IRQreg function. This should have the side effect of causing the IRQ outputs to be raised appropriately on load, which was missing.
The serialization format is altered by swapping ivpr and idr (we'd like IDR to be restored before we run the IVPR logic), and moving interrupts to the end (so that other state has been restored by the time we run the IDR/IVPR logic. Serialization for this driver is not yet in a state where backwards compatibility is reasonable (assuming it works at all), and the current serialization format was not built for extensibility.
--- hw/openpic.c | 110 ++++++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 76 insertions(+), 34 deletions(-)
hw/openpic.c +76 -34
@@ -189,7 +189,9 @@ typedef struct IRQQueue {typedef struct IRQSource {uint32_t ivpr;/* IRQ vector/priority register */ uint32_t idr;/* IRQ destination register */ +uint32_t destmask;/* bitmap of CPU destinations */ int last_cpu; +int output;/* IRQ level, e.g. OPENPIC_OUTPUT_INT */ int pending;/* TRUE if IRQ is pending */ }IRQSource ;
@@ -264,8 +266,6 @@ typedef struct OpenPICState {uint32_t irq_msi; } OpenPICState; -static void openpic_irq_raise (OpenPICState *opp,int n_CPU,IRQSource *src); -static inline void IRQ_setbit (IRQQueue *q,int n_IRQ) { q->pending++;
@@ -330,6 +330,19 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ) dst = &opp->dst[n_CPU]; src = &opp->src[n_IRQ]; + +if (src->output !=OPENPIC_OUTPUT_INT ) { +/* On Freescale MPIC, critical interrupts ignore priority, +* IACK, EOI, etc. Before MPIC v4.1 they also ignore +* masking. +*/ + src->ivpr |=IVPR_ACTIVITY_MASK ; +DPRINTF ("%s: Raise OpenPIC output %d cpu %d irq %d\n" , + __func__, src->output, n_CPU, n_IRQ); +qemu_irq_raise (opp->dst[n_CPU].irqs[src->output]); +return ; + } + priority =IVPR_PRIORITY (src->ivpr);if (priority <= dst->ctpr) {/* Too low priority */
@@ -360,7 +373,7 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ)return ; }DPRINTF ("Raise OpenPIC INT output cpu %d irq %d\n" , n_CPU, n_IRQ); -openpic_irq_raise (opp, n_CPU, src); +qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT ]); }/* update pic state because registers for n_IRQ have changed value */
@@ -403,7 +416,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ) }else if (!(src->ivpr &IVPR_MODE_MASK )) {/* Directed delivery mode */ for (i =0 ; i < opp->nb_cpus; i++) { -if (src->idr & (1 << i)) { +if (src->destmask & (1 << i)) {IRQ_local_pipe (opp, i, n_IRQ); } }
@@ -413,7 +426,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)if (i == opp->nb_cpus) { i =0 ; } -if (src->idr & (1 << i)) { +if (src->destmask & (1 << i)) {IRQ_local_pipe (opp, i, n_IRQ); src->last_cpu = i;break ;
@@ -493,12 +506,45 @@ static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ)static inline void write_IRQreg_idr (OpenPICState *opp,int n_IRQ,uint32_t val) { -uint32_t tmp; +IRQSource *src = &opp->src[n_IRQ]; +uint32_t normal_mask = (1UL << opp->nb_cpus) -1 ; +uint32_t crit_mask =0 ; +uint32_t mask = normal_mask; +int crit_shift =IDR_EP_SHIFT - opp->nb_cpus; +int i; + +if (opp->flags &OPENPIC_FLAG_IDR_CRIT ) { + crit_mask = mask << crit_shift; + mask |= crit_mask |IDR_EP ; + } + + src->idr = val & mask; +DPRINTF ("Set IDR %d to 0x%08x\n" , n_IRQ, src->idr); + +if (opp->flags &OPENPIC_FLAG_IDR_CRIT ) { +if (src->idr & crit_mask) { +if (src->idr & normal_mask) { +DPRINTF ("%s: IRQ configured for multiple output types, using " +"critical\n" , __func__); + } + + src->output =OPENPIC_OUTPUT_CINT ; + src->destmask =0 ; + +for (i =0 ; i < opp->nb_cpus; i++) { +int n_ci =IDR_CI0_SHIFT - i; - tmp = val & (IDR_EP |IDR_CI ); - tmp |= val & ((1ULL <<MAX_CPU ) -1 ); - opp->src[n_IRQ].idr = tmp; -DPRINTF ("Set IDR %d to 0x%08x\n" , n_IRQ, opp->src[n_IRQ].idr); +if (src->idr & (1UL << n_ci)) { + src->destmask |=1UL << i; + } + } + }else { + src->output =OPENPIC_OUTPUT_INT ; + src->destmask = src->idr & normal_mask; + } + }else { + src->destmask = src->idr; + } }static inline void write_IRQreg_ivpr (OpenPICState *opp,int n_IRQ,uint32_t val)
@@ -878,7 +924,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) {DPRINTF ("Raise OpenPIC INT output cpu %d irq %d\n" , idx, n_IRQ); -openpic_irq_raise (opp, idx, src); +qemu_irq_raise (opp->dst[idx].irqs[OPENPIC_OUTPUT_INT ]); }break ;default :
@@ -1101,13 +1147,6 @@ static void openpic_save(QEMUFile* f, void *opaque)qemu_put_be32s (f, &opp->spve);qemu_put_be32s (f, &opp->tfrr); -for (i =0 ; i < opp->max_irq; i++) { -qemu_put_be32s (f, &opp->src[i].ivpr); -qemu_put_be32s (f, &opp->src[i].idr); -qemu_put_sbe32s (f, &opp->src[i].last_cpu); -qemu_put_sbe32s (f, &opp->src[i].pending); - } -qemu_put_be32s (f, &opp->nb_cpus);for (i =0 ; i < opp->nb_cpus; i++) {
@@ -1120,6 +1159,13 @@ static void openpic_save(QEMUFile* f, void *opaque)qemu_put_be32s (f, &opp->timers[i].tccr);qemu_put_be32s (f, &opp->timers[i].tbcr); } + +for (i =0 ; i < opp->max_irq; i++) { +qemu_put_be32s (f, &opp->src[i].ivpr); +qemu_put_be32s (f, &opp->src[i].idr); +qemu_put_sbe32s (f, &opp->src[i].last_cpu); +qemu_put_sbe32s (f, &opp->src[i].pending); + } }static void openpic_load_IRQ_queue (QEMUFile * f,IRQQueue *q)
@@ -1148,13 +1194,6 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)qemu_get_be32s (f, &opp->spve);qemu_get_be32s (f, &opp->tfrr); -for (i =0 ; i < opp->max_irq; i++) { -qemu_get_be32s (f, &opp->src[i].ivpr); -qemu_get_be32s (f, &opp->src[i].idr); -qemu_get_sbe32s (f, &opp->src[i].last_cpu); -qemu_get_sbe32s (f, &opp->src[i].pending); - } -qemu_get_be32s (f, &opp->nb_cpus);for (i =0 ; i < opp->nb_cpus; i++) {
@@ -1168,18 +1207,21 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)qemu_get_be32s (f, &opp->timers[i].tbcr); } -return 0 ; -} +for (i =0 ; i < opp->max_irq; i++) { +uint32_t val; -static void openpic_irq_raise (OpenPICState *opp,int n_CPU,IRQSource *src) -{ -int n_ci =IDR_CI0_SHIFT - n_CPU; + val =qemu_get_be32 (f); +write_IRQreg_idr (opp, i, val); + val =qemu_get_be32 (f); +write_IRQreg_ivpr (opp, i, val); -if ((opp->flags &OPENPIC_FLAG_IDR_CRIT ) && (src->idr & (1 << n_ci))) { -qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT ]); - }else { -qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT ]); +qemu_get_be32s (f, &opp->src[i].ivpr); +qemu_get_be32s (f, &opp->src[i].idr); +qemu_get_sbe32s (f, &opp->src[i].last_cpu); +qemu_get_sbe32s (f, &opp->src[i].pending); } + +return 0 ; } typedef struct MemReg {
Signature · 1 line
1.6.0.2
PATCH 16/31 openpic: make ctpr signed
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Other priorities are signed, so avoid comparisons between signed and unsigned.
--- hw/openpic.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
hw/openpic.c +3 -3
@@ -215,7 +215,7 @@ typedef struct IRQSource {#define IDR_CI 0x40000000/* critical interrupt */ typedef struct IRQDest { - uint32_t ctpr; /* CPU current task priority */ + int32_t ctpr; /* CPU current task priority */ IRQQueue raised; IRQQueue servicing; qemu_irq *irqs;
@@ -1150,7 +1150,7 @@ static void openpic_save(QEMUFile* f, void *opaque)qemu_put_be32s (f, &opp->nb_cpus);for (i =0 ; i < opp->nb_cpus; i++) { -qemu_put_be32s (f, &opp->dst[i].ctpr); +qemu_put_sbe32s (f, &opp->dst[i].ctpr);openpic_save_IRQ_queue (f, &opp->dst[i].raised);openpic_save_IRQ_queue (f, &opp->dst[i].servicing); }
@@ -1197,7 +1197,7 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)qemu_get_be32s (f, &opp->nb_cpus);for (i =0 ; i < opp->nb_cpus; i++) { -qemu_get_be32s (f, &opp->dst[i].ctpr); +qemu_get_sbe32s (f, &opp->dst[i].ctpr);openpic_load_IRQ_queue (f, &opp->dst[i].raised);openpic_load_IRQ_queue (f, &opp->dst[i].servicing); }
Signature · 1 line
1.6.0.2
PATCH 17/31 openpic/fsl: critical interrupts ignore mask before v4.1
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
--- hw/openpic.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
hw/openpic.c +4 -1
@@ -193,6 +193,7 @@ typedef struct IRQSource {int last_cpu;int output;/* IRQ level, e.g. OPENPIC_OUTPUT_INT */ int pending;/* TRUE if IRQ is pending */ + bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ } IRQSource;#define IVPR_MASK_SHIFT 31
@@ -389,7 +390,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)DPRINTF ("%s: IRQ %d is not pending\n" , __func__, n_IRQ);return ; } -if (src->ivpr &IVPR_MASK_MASK ) { +if ((src->ivpr &IVPR_MASK_MASK ) && !src->nomask) {/* Interrupt source is disabled */ DPRINTF ("%s: IRQ %d is disabled\n" , __func__, n_IRQ);return ;
@@ -529,6 +530,7 @@ static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val) } src->output =OPENPIC_OUTPUT_CINT ; + src->nomask = true; src->destmask =0 ;for (i =0 ; i < opp->nb_cpus; i++) {
@@ -540,6 +542,7 @@ static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val) } }else { src->output =OPENPIC_OUTPUT_INT ; + src->nomask = false; src->destmask = src->idr & normal_mask; } }else {
Signature · 1 line
1.6.0.2
PATCH 18/31 openpic: always call IRQ_check from IRQ_get_next
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Previously the code relied on the queue's "next" field getting set to -1 sometime between an update to the bitmap, and the next call to IRQ_get_next. Sometimes this happened after the update. Sometimes it happened before the check. Sometimes it didn't happen at all.
--- hw/openpic.c | 10 +++------- 1 files changed, 3 insertions(+), 7 deletions(-)
hw/openpic.c +3 -7
@@ -315,10 +315,8 @@ out:static int IRQ_get_next (OpenPICState *opp,IRQQueue *q) { -if (q->next ==-1 ) { -/* XXX: optimize */ -IRQ_check (opp, q); - } +/* XXX: optimize */ +IRQ_check (opp, q);return q->next; }
@@ -365,7 +363,7 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ) __func__, n_IRQ, dst->raised.next, n_CPU);return ; } -IRQ_get_next (opp, &dst->raised); +IRQ_check (opp, &dst->raised);if (IRQ_get_next (opp, &dst->servicing) !=-1 && priority <= dst->servicing.priority) { DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n",
@@ -916,7 +914,6 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,DPRINTF ("EOI\n" ); s_IRQ =IRQ_get_next (opp, &dst->servicing);IRQ_resetbit (&dst->servicing, s_IRQ); - dst->servicing.next =-1 ;/* Set up next servicing IRQ */ s_IRQ =IRQ_get_next (opp, &dst->servicing);/* Check queued interrupts. */
@@ -993,7 +990,6 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, retval =IVPR_VECTOR (opp, src->ivpr); }IRQ_resetbit (&dst->raised, n_IRQ); - dst->raised.next =-1 ;if (!(src->ivpr &IVPR_SENSE_MASK )) {/* edge-sensitive IRQ */ src->ivpr &= ~IVPR_ACTIVITY_MASK ;
Signature · 1 line
1.6.0.2
PATCH 19/31 Revert "openpic: Accelerate pending irq search"
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
This reverts commit a9bd83f4c65de0058659ede009fa1a241f379edd.
This counting approach is not robust against setting a bit that was already set, or clearing a bit that was already clear. Perhaps that is considered a bug, but besides the lack of any documentation for that restriction, it's a pretty unpleasant way for the problem to manifest itself.
It could be made more robust by testing the current value of the bit before changing the count, but a later patch speeds up IRQ_check in all cases, not just when there's nothing pending. Hopefully that should be adequate to address performance concerns.
--- hw/openpic.c | 11 ----------- 1 files changed, 0 insertions(+), 11 deletions(-)
hw/openpic.c +0 -11
@@ -183,7 +183,6 @@ typedef struct IRQQueue {uint32_t queue[BF_WIDTH (MAX_IRQ )];int next;int priority; -int pending;/* nr of pending bits in queue */ } IRQQueue; typedef struct IRQSource {
@@ -269,13 +268,11 @@ typedef struct OpenPICState {static inline void IRQ_setbit (IRQQueue *q,int n_IRQ) { - q->pending++;set_bit (q->queue, n_IRQ); }static inline void IRQ_resetbit (IRQQueue *q,int n_IRQ) { - q->pending--;reset_bit (q->queue, n_IRQ); }
@@ -291,12 +288,6 @@ static void IRQ_check(OpenPICState *opp, IRQQueue *q) next =-1 ; priority =-1 ; - -if (!q->pending) { -/* IRQ bitmap is empty */ - goto out; - } -for (i =0 ; i < opp->max_irq; i++) {if (IRQ_testbit (q, i)) { DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n",
@@ -307,8 +298,6 @@ static void IRQ_check(OpenPICState *opp, IRQQueue *q) } } } - -out: q->next = next; q->priority = priority; }
Signature · 1 line
1.6.0.2
PATCH 20/31 openpic: use standard bitmap operations
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Besides the private implementation being redundant, namespace collisions prevented the use of other things in bitops.h.
Serialization does get a bit more awkward, unfortunately, since the standard bitmap operations are "unsigned long" rather than "uint32_t", though in exchange we will get faster queue lookups on 64-bit hosts once we search a word at a time.
--- hw/openpic.c | 55 +++++++++++++++++++++++++++++-------------------------- 1 files changed, 29 insertions(+), 26 deletions(-)
hw/openpic.c +29 -26
@@ -39,6 +39,7 @@#include "openpic.h" #include "sysbus.h" #include "pci/msi.h" +#include "qemu/bitops.h" //#define DEBUG_OPENPIC
@@ -147,24 +148,6 @@ static const int debug_openpic = 0;#define MSIIR_IBS_SHIFT 24#define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT) -#define BF_WIDTH (_bits_) \ -(((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8)) - -static inline void set_bit (uint32_t *field,int bit) -{ - field[bit >>5 ] |=1 << (bit &0x1F ); -} - -static inline void reset_bit (uint32_t *field,int bit) -{ - field[bit >>5 ] &= ~(1 << (bit &0x1F )); -} - -static inline int test_bit (uint32_t *field,int bit) -{ -return (field[bit >>5 ] &1 << (bit &0x1F )) !=0 ; -} -static int get_current_cpu (void ) {if (!cpu_single_env) {
@@ -180,7 +163,10 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, uint32_t val, int idx);typedef struct IRQQueue { -uint32_t queue[BF_WIDTH (MAX_IRQ )]; +/* Round up to the nearest 64 IRQs so that the queue length +* won't change when moving between 32 and 64 bit hosts. +*/ +unsigned long queue[BITS_TO_LONGS ((MAX_IRQ +63 ) & ~63 )];int next;int priority; }IRQQueue ;
@@ -268,17 +254,17 @@ typedef struct OpenPICState {static inline void IRQ_setbit (IRQQueue *q,int n_IRQ) { -set_bit (q->queue, n_IRQ); +set_bit (n_IRQ, q->queue); }static inline void IRQ_resetbit (IRQQueue *q,int n_IRQ) { -reset_bit (q->queue, n_IRQ); +clear_bit (n_IRQ, q->queue); }static inline int IRQ_testbit (IRQQueue *q,int n_IRQ) { -return test_bit (q->queue, n_IRQ); +return test_bit (n_IRQ, q->queue); }static void IRQ_check (OpenPICState *opp,IRQQueue *q)
@@ -1117,8 +1103,16 @@ static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q) {unsigned int i; -for (i =0 ; i <BF_WIDTH (MAX_IRQ ); i++) -qemu_put_be32s (f, &q->queue[i]); +for (i =0 ; i <ARRAY_SIZE (q->queue); i++) { +/* Always put the lower half of a 64-bit long first, in case we +* restore on a 32-bit host. The least significant bits correspond +* to lower IRQ numbers in the bitmap. +*/ +qemu_put_be32 (f, (uint32_t )q->queue[i]); +#if LONG_MAX >0x7FFFFFFF +qemu_put_be32 (f, (uint32_t )(q->queue[i] >>32 )); +#endif + }qemu_put_sbe32s (f, &q->next);qemu_put_sbe32s (f, &q->priority);
@@ -1160,8 +1154,17 @@ static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q) {unsigned int i; -for (i =0 ; i <BF_WIDTH (MAX_IRQ ); i++) -qemu_get_be32s (f, &q->queue[i]); +for (i =0 ; i <ARRAY_SIZE (q->queue); i++) { +unsigned long val; + + val =qemu_get_be32 (f); +#if LONG_MAX >0x7FFFFFFF + val <<=32 ; + val |=qemu_get_be32 (f); +#endif + + q->queue[i] = val; + }qemu_get_sbe32s (f, &q->next);qemu_get_sbe32s (f, &q->priority);
Signature · 1 line
1.6.0.2
PATCH 21/31 openpic: add some bounds checking for IRQ numbers
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
The two checks with abort() guard against potential QEMU-internal problems, but the EOI check stops the guest from causing updates to queue position -1 and other havoc if it writes EOI with no interrupt in service.
--- hw/openpic.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
hw/openpic.c +11 -0
@@ -414,6 +414,11 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)OpenPICState *opp = opaque;IRQSource *src; +if (n_IRQ >=MAX_IRQ ) { +fprintf (stderr,"%s: IRQ %d out of range\n" , __func__, n_IRQ); +abort (); + } + src = &opp->src[n_IRQ];DPRINTF ("openpic: set irq %d = %d ivpr=0x%08x\n" , n_IRQ, level, src->ivpr);
@@ -888,6 +893,12 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,case 0xB0 :/* EOI */ DPRINTF ("EOI\n" ); s_IRQ =IRQ_get_next (opp, &dst->servicing); + +if (s_IRQ <0 ) { +DPRINTF ("%s: EOI with no interrupt in service\n" , __func__); +break ; + } +IRQ_resetbit (&dst->servicing, s_IRQ);/* Set up next servicing IRQ */ s_IRQ =IRQ_get_next (opp, &dst->servicing);
Signature · 1 line
1.6.0.2
PATCH 22/31 openpic: fix sense and priority bits
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Previously, the sense and priority bits were masked off when writing to IVPR, and all interrupts were treated as edge-triggered (despite the existence of code for handling level-triggered interrupts).
Polarity is implemented only as storage. We don't simulate the bad effects that you'd get on real hardware if you set this incorrectly, but at least the guest sees the right thing when it reads back the register.
Sense now controls level/edge on FSL external interrupts (and all interrupts on non-FSL MPIC). FSL internal interrupts do not have a sense bit (reads as zero), but are level. FSL timers and IPIs do not have sense or polarity bits (read as zero), and are edge-triggered. To accommodate FSL internal interrupts, QEMU's internal notion of whether an interrupt is level-triggered is separated from the IVPR bit.
--- hw/openpic.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 71 insertions(+), 6 deletions(-)
hw/openpic.c +71 -6
@@ -162,6 +162,12 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,static void openpic_cpu_write_internal (void *opaque,hwaddr addr,uint32_t val,int idx); +typedef enum IRQType { +IRQ_TYPE_NORMAL =0 , +IRQ_TYPE_FSLINT ,/* FSL internal interrupt -- level only */ +IRQ_TYPE_FSLSPECIAL ,/* FSL timer/IPI interrupt, edge, no polarity */ +}IRQType ; + typedef struct IRQQueue { /* Round up to the nearest 64 IRQs so that the queue length * won't change when moving between 32 and 64 bit hosts.
@@ -178,6 +184,8 @@ typedef struct IRQSource {int last_cpu;int output;/* IRQ level, e.g. OPENPIC_OUTPUT_INT */ int pending;/* TRUE if IRQ is pending */ +IRQType type; + bool level:1; /* level-triggered */ bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ } IRQSource;
@@ -422,7 +430,7 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level) src = &opp->src[n_IRQ];DPRINTF ("openpic: set irq %d = %d ivpr=0x%08x\n" , n_IRQ, level, src->ivpr); -if (src->ivpr &IVPR_SENSE_MASK ) { +if (src->level) {/* level-sensitive irq */ src->pending = level;if (!level) {
@@ -455,6 +463,19 @@ static void openpic_reset(DeviceState *d)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++) {
@@ -530,10 +551,36 @@ static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val)static inline void write_IRQreg_ivpr (OpenPICState *opp,int n_IRQ,uint32_t val) { -/* NOTE: not fully accurate for special IRQs, but simple and sufficient */ +uint32_t mask; + +/* NOTE when implementing newer FSL MPIC models: starting with v4.0, +* the polarity bit is read-only on internal interrupts. +*/ + mask =IVPR_MASK_MASK |IVPR_PRIORITY_MASK |IVPR_SENSE_MASK | +IVPR_POLARITY_MASK | opp->vector_mask; +/* ACTIVITY bit is read-only */ - opp->src[n_IRQ].ivpr = (opp->src[n_IRQ].ivpr &IVPR_ACTIVITY_MASK ) | - (val & (IVPR_MASK_MASK |IVPR_PRIORITY_MASK | opp->vector_mask)); + opp->src[n_IRQ].ivpr = + (opp->src[n_IRQ].ivpr &IVPR_ACTIVITY_MASK ) | (val & mask); + +/* For FSL internal interrupts, The sense bit is reserved and zero, +* and the interrupt is always level-triggered. Timers and IPIs +* have no sense or polarity bits, and are edge-triggered. +*/ +switch (opp->src[n_IRQ].type) { +case IRQ_TYPE_NORMAL : + opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr &IVPR_SENSE_MASK ); +break ; + +case IRQ_TYPE_FSLINT : + opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK ; +break ; + +case IRQ_TYPE_FSLSPECIAL : + opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK |IVPR_SENSE_MASK ); +break ; + } +openpic_update_irq (opp, n_IRQ);DPRINTF ("Set IVPR %d to 0x%08x -> 0x%08x\n" , n_IRQ, val, opp->src[n_IRQ].ivpr);
@@ -976,7 +1023,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, retval =IVPR_VECTOR (opp, src->ivpr); }IRQ_resetbit (&dst->raised, n_IRQ); -if (!(src->ivpr &IVPR_SENSE_MASK )) { +if (!src->level) {/* edge-sensitive IRQ */ src->ivpr &= ~IVPR_ACTIVITY_MASK ; src->pending =0 ;
@@ -984,7 +1031,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr,if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 +MAX_IPI ))) { src->idr &= ~(1 << idx); -if (src->idr && !(src->ivpr &IVPR_SENSE_MASK )) { +if (src->idr && !src->level) {/* trigger on CPUs that didn't know about it yet */ openpic_set_irq (opp, n_IRQ,1 );openpic_set_irq (opp, n_IRQ,0 );
@@ -1282,7 +1329,25 @@ static int openpic_init(SysBusDevice *dev) opp->brr1 =FSL_BRR1_IPID |FSL_BRR1_IPMJ |FSL_BRR1_IPMN ; msi_supported = true; list = list_be; + +for (i =0 ; i <FSL_MPIC_20_MAX_EXT ; i++) { + opp->src[i].level = false; + } + +/* Internal interrupts, including message and MSI */ +for (i =16 ; i <MAX_SRC ; i++) { + opp->src[i].type =IRQ_TYPE_FSLINT ; + opp->src[i].level = true; + } + +/* timers and IPIs */ +for (i =MAX_SRC ; i <MAX_IRQ ; i++) { + opp->src[i].type =IRQ_TYPE_FSLSPECIAL ; + opp->src[i].level = false; + } +break ; +case OPENPIC_MODEL_RAVEN : opp->nb_irqs =RAVEN_MAX_EXT ; opp->vid =VID_REVISION_1_3 ;
Signature · 1 line
1.6.0.2
PATCH 23/31 openpic: IRQ_check: search the queue a word at a time
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Search the queue more efficiently by first looking for a non-zero word, and then using the common bit-searching function to find the bit within the word. It would be even nicer if bitops_ffsl() could be hooked up to the compiler intrinsic so that bit-searching instructions could be used, but that's another matter.
--- hw/openpic.c | 28 ++++++++++++++++------------ 1 files changed, 16 insertions(+), 12 deletions(-)
hw/openpic.c +16 -12
@@ -277,21 +277,25 @@ static inline int IRQ_testbit(IRQQueue *q, int n_IRQ)static void IRQ_check (OpenPICState *opp,IRQQueue *q) { -int next, i; -int priority; +int irq =-1 ; +int next =-1 ; +int priority =-1 ; - next =-1 ; - priority =-1 ; -for (i =0 ; i < opp->max_irq; i++) { -if (IRQ_testbit (q, i)) { -DPRINTF ("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n" , - i,IVPR_PRIORITY (opp->src[i].ivpr), priority); -if (IVPR_PRIORITY (opp->src[i].ivpr) > priority) { - next = i; - priority =IVPR_PRIORITY (opp->src[i].ivpr); - } +for (;;) { + irq =find_next_bit (q->queue, opp->max_irq, irq +1 ); +if (irq == opp->max_irq) { +break ; + } + +DPRINTF ("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n" , + irq,IVPR_PRIORITY (opp->src[irq].ivpr), priority); + +if (IVPR_PRIORITY (opp->src[irq].ivpr) > priority) { + next = irq; + priority =IVPR_PRIORITY (opp->src[irq].ivpr); } } + q->next = next; q->priority = priority; }
Signature · 1 line
1.6.0.2
PATCH 24/31 openpic: move IACK to its own function
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Besides making the code cleaner, we will need a separate way to access IACK in order to implement EPR (external proxy) interrupt delivery.
--- hw/openpic.c | 95 ++++++++++++++++++++++++++++++++------------------------- 1 files changed, 53 insertions(+), 42 deletions(-)
hw/openpic.c +53 -42
@@ -975,14 +975,64 @@ static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val,openpic_cpu_write_internal (opaque, addr, val, (addr &0x1f000 ) >>12 ); } + +static uint32_t openpic_iack (OpenPICState *opp,IRQDest *dst,int cpu) +{ +IRQSource *src; +int retval, irq; + +DPRINTF ("Lower OpenPIC INT output\n" ); +qemu_irq_lower (dst->irqs[OPENPIC_OUTPUT_INT ]); + + irq =IRQ_get_next (opp, &dst->raised); +DPRINTF ("IACK: irq=%d\n" , irq); + +if (irq ==-1 ) { +/* No more interrupt pending */ +return opp->spve; + } + + src = &opp->src[irq]; +if (!(src->ivpr &IVPR_ACTIVITY_MASK ) || + !(IVPR_PRIORITY (src->ivpr) > dst->ctpr)) { +/* - Spurious level-sensitive IRQ +* - Priorities has been changed +* and the pending IRQ isn't allowed anymore +*/ + src->ivpr &= ~IVPR_ACTIVITY_MASK ; + retval = opp->spve; + }else { +/* IRQ enter servicing state */ +IRQ_setbit (&dst->servicing, irq); + retval =IVPR_VECTOR (opp, src->ivpr); + } +IRQ_resetbit (&dst->raised, irq); +if (!src->level) { +/* edge-sensitive IRQ */ + src->ivpr &= ~IVPR_ACTIVITY_MASK ; + src->pending =0 ; + } + +if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 +MAX_IPI ))) { + src->idr &= ~(1 << cpu); +if (src->idr && !src->level) { +/* trigger on CPUs that didn't know about it yet */ +openpic_set_irq (opp, irq,1 ); +openpic_set_irq (opp, irq,0 ); +/* if all CPUs knew about it, set active bit again */ + src->ivpr |=IVPR_ACTIVITY_MASK ; + } + } + +return retval; +} +static uint32_t openpic_cpu_read_internal (void *opaque,hwaddr addr,int idx) {OpenPICState *opp = opaque; -IRQSource *src;IRQDest *dst;uint32_t retval; -int n_IRQ;DPRINTF ("%s: cpu %d addr %#" HWADDR_PRIx"\n" , __func__, idx, addr); retval =0xFFFFFFFF ;
@@ -1004,46 +1054,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, retval = idx;break ;case 0xA0 :/* IACK */ -DPRINTF ("Lower OpenPIC INT output\n" ); -qemu_irq_lower (dst->irqs[OPENPIC_OUTPUT_INT ]); - n_IRQ =IRQ_get_next (opp, &dst->raised); -DPRINTF ("IACK: irq=%d\n" , n_IRQ); -if (n_IRQ ==-1 ) { -/* No more interrupt pending */ - retval = opp->spve; - }else { - src = &opp->src[n_IRQ]; -if (!(src->ivpr &IVPR_ACTIVITY_MASK ) || - !(IVPR_PRIORITY (src->ivpr) > dst->ctpr)) { -/* - Spurious level-sensitive IRQ -* - Priorities has been changed -* and the pending IRQ isn't allowed anymore -*/ - src->ivpr &= ~IVPR_ACTIVITY_MASK ; - retval = opp->spve; - }else { -/* IRQ enter servicing state */ -IRQ_setbit (&dst->servicing, n_IRQ); - retval =IVPR_VECTOR (opp, src->ivpr); - } -IRQ_resetbit (&dst->raised, n_IRQ); -if (!src->level) { -/* edge-sensitive IRQ */ - src->ivpr &= ~IVPR_ACTIVITY_MASK ; - src->pending =0 ; - } - -if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 +MAX_IPI ))) { - src->idr &= ~(1 << idx); -if (src->idr && !src->level) { -/* trigger on CPUs that didn't know about it yet */ -openpic_set_irq (opp, n_IRQ,1 ); -openpic_set_irq (opp, n_IRQ,0 ); -/* if all CPUs knew about it, set active bit again */ - src->ivpr |=IVPR_ACTIVITY_MASK ; - } - } - } + retval =openpic_iack (opp, dst, idx);break ;case 0xB0 :/* EOI */ retval =0 ;
Signature · 1 line
1.6.0.2
PATCH 25/31 openpic: fix CTPR and de-assertion of interrupts
In reply to Alexander GrafFrom: Scott Wood <[email protected]>
Properly implement level-triggered interrupts by withdrawing an interrupt from the raised queue if the interrupt source de-asserts. Also withdraw from the raised queue if the interrupt becomes masked.
When CTPR is written, check whether we need to raise or lower the interrupt output.
--- hw/openpic.c | 181 +++++++++++++++++++++++++++++++++++++++------------------- 1 files changed, 123 insertions(+), 58 deletions(-)
hw/openpic.c +123 -58
@@ -213,6 +213,9 @@ typedef struct IRQDest {IRQQueue raised;IRQQueue servicing;qemu_irq *irqs; + +/* Count of IRQ sources asserting on non-INT outputs */ +uint32_t outputs_active[OPENPIC_OUTPUT_NB ]; } IRQDest; typedef struct OpenPICState {
@@ -308,7 +311,8 @@ static int IRQ_get_next(OpenPICState *opp, IRQQueue *q)return q->next; } -static void IRQ_local_pipe (OpenPICState *opp,int n_CPU,int n_IRQ) +static void IRQ_local_pipe (OpenPICState *opp,int n_CPU,int n_IRQ, +bool active,bool was_active) {IRQDest *dst;IRQSource *src;
@@ -317,79 +321,113 @@ static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ) dst = &opp->dst[n_CPU]; src = &opp->src[n_IRQ]; +DPRINTF ("%s: IRQ %d active %d was %d\n" , + __func__, n_IRQ, active, was_active); +if (src->output !=OPENPIC_OUTPUT_INT ) { +DPRINTF ("%s: output %d irq %d active %d was %d count %d\n" , + __func__, src->output, n_IRQ, active, was_active, + dst->outputs_active[src->output]); +/* On Freescale MPIC, critical interrupts ignore priority, * IACK, EOI, etc. Before MPIC v4.1 they also ignore * masking. */ - src->ivpr |=IVPR_ACTIVITY_MASK ; -DPRINTF ("%s: Raise OpenPIC output %d cpu %d irq %d\n" , - __func__, src->output, n_CPU, n_IRQ); -qemu_irq_raise (opp->dst[n_CPU].irqs[src->output]); +if (active) { +if (!was_active && dst->outputs_active[src->output]++ ==0 ) { +DPRINTF ("%s: Raise OpenPIC output %d cpu %d irq %d\n" , + __func__, src->output, n_CPU, n_IRQ); +qemu_irq_raise (dst->irqs[src->output]); + } + }else { +if (was_active && --dst->outputs_active[src->output] ==0 ) { +DPRINTF ("%s: Lower OpenPIC output %d cpu %d irq %d\n" , + __func__, src->output, n_CPU, n_IRQ); +qemu_irq_lower (dst->irqs[src->output]); + } + } +return ; } priority =IVPR_PRIORITY (src->ivpr); -if (priority <= dst->ctpr) { -/* Too low priority */ -DPRINTF ("%s: IRQ %d has too low priority on CPU %d\n" , - __func__, n_IRQ, n_CPU); -return ; - } -if (IRQ_testbit (&dst->raised, n_IRQ)) { -/* Interrupt miss */ -DPRINTF ("%s: IRQ %d was missed on CPU %d\n" , - __func__, n_IRQ, n_CPU); -return ; - } - src->ivpr |=IVPR_ACTIVITY_MASK ; -IRQ_setbit (&dst->raised, n_IRQ); -if (priority < dst->raised.priority) { -/* An higher priority IRQ is already raised */ -DPRINTF ("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n" , - __func__, n_IRQ, dst->raised.next, n_CPU); -return ; + +/* Even if the interrupt doesn't have enough priority, +* it is still raised, in case ctpr is lowered later. +*/ +if (active) { +IRQ_setbit (&dst->raised, n_IRQ); + }else { +IRQ_resetbit (&dst->raised, n_IRQ); } +IRQ_check (opp, &dst->raised); -if (IRQ_get_next (opp, &dst->servicing) !=-1 && - priority <= dst->servicing.priority) { -DPRINTF ("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n" , - __func__, n_IRQ, dst->servicing.next, n_CPU); -/* Already servicing a higher priority IRQ */ -return ; + +if (active && priority <= dst->ctpr) { +DPRINTF ("%s: IRQ %d priority %d too low for ctpr %d on CPU %d\n" , + __func__, n_IRQ, priority, dst->ctpr, n_CPU); + active =0 ; + } + +if (active) { +if (IRQ_get_next (opp, &dst->servicing) >=0 && + priority <= dst->servicing.priority) { +DPRINTF ("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n" , + __func__, n_IRQ, dst->servicing.next, n_CPU); + }else { +DPRINTF ("%s: Raise OpenPIC INT output cpu %d irq %d/%d\n" , + __func__, n_CPU, n_IRQ, dst->raised.next); +qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT ]); + } + }else { +IRQ_get_next (opp, &dst->servicing); +if (dst->raised.priority > dst->ctpr && + dst->raised.priority > dst->servicing.priority) { +DPRINTF ("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d\n" , + __func__, n_IRQ, dst->raised.next, dst->raised.priority, + dst->ctpr, dst->servicing.priority, n_CPU); +/* IRQ line stays asserted */ + }else { +DPRINTF ("%s: IRQ %d inactive, current prio %d/%d, CPU %d\n" , + __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU); +qemu_irq_lower (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT ]); + } } -DPRINTF ("Raise OpenPIC INT output cpu %d irq %d\n" , n_CPU, n_IRQ); -qemu_irq_raise (opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT ]); }/* update pic state because registers for n_IRQ have changed value */ static void openpic_update_irq (OpenPICState *opp,int n_IRQ) {IRQSource *src; +bool active, was_active;int i; src = &opp->src[n_IRQ]; + active = src->pending; -if (!src->pending) { -/* no irq pending */ -DPRINTF ("%s: IRQ %d is not pending\n" , __func__, n_IRQ); -return ; - }if ((src->ivpr &IVPR_MASK_MASK ) && !src->nomask) {/* Interrupt source is disabled */ DPRINTF ("%s: IRQ %d is disabled\n" , __func__, n_IRQ); -return ; + active = false; } -if (IVPR_PRIORITY (src->ivpr) ==0 ) { -/* Priority set to zero */ -DPRINTF ("%s: IRQ %d has 0 priority\n" , __func__, n_IRQ); + + was_active = !!(src->ivpr &IVPR_ACTIVITY_MASK ); + +/* +* We don't have a similar check for already-active because +* ctpr may have changed and we need to withdraw the interrupt. +*/ +if (!active && !was_active) { +DPRINTF ("%s: IRQ %d is already inactive\n" , __func__, n_IRQ);return ; } -if (src->ivpr &IVPR_ACTIVITY_MASK ) { -/* IRQ already active */ -DPRINTF ("%s: IRQ %d is already active\n" , __func__, n_IRQ); -return ; + +if (active) { + src->ivpr |=IVPR_ACTIVITY_MASK ; + }else { + src->ivpr &= ~IVPR_ACTIVITY_MASK ; } +if (src->idr ==0 ) {/* No target */ DPRINTF ("%s: IRQ %d has no target\n" , __func__, n_IRQ);
@@ -398,12 +436,12 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ)if (src->idr == (1 << src->last_cpu)) {/* Only one CPU is allowed to receive this IRQ */ -IRQ_local_pipe (opp, src->last_cpu, n_IRQ); +IRQ_local_pipe (opp, src->last_cpu, n_IRQ, active, was_active); }else if (!(src->ivpr &IVPR_MODE_MASK )) {/* Directed delivery mode */ for (i =0 ; i < opp->nb_cpus; i++) {if (src->destmask & (1 << i)) { -IRQ_local_pipe (opp, i, n_IRQ); +IRQ_local_pipe (opp, i, n_IRQ, active, was_active); } } }else {
@@ -413,7 +451,7 @@ static void openpic_update_irq(OpenPICState *opp, int n_IRQ) i =0 ; }if (src->destmask & (1 << i)) { -IRQ_local_pipe (opp, i, n_IRQ); +IRQ_local_pipe (opp, i, n_IRQ, active, was_active); src->last_cpu = i;break ; }
@@ -437,16 +475,25 @@ static void openpic_set_irq(void *opaque, int n_IRQ, int level)if (src->level) {/* level-sensitive irq */ src->pending = level; -if (!level) { - src->ivpr &= ~IVPR_ACTIVITY_MASK ; - } +openpic_update_irq (opp, n_IRQ); }else {/* edge-sensitive irq */ if (level) { src->pending =1 ; +openpic_update_irq (opp, n_IRQ); + } + +if (src->output !=OPENPIC_OUTPUT_INT ) { +/* Edge-triggered interrupts shouldn't be used +* with non-INT delivery, but just in case, +* try to make it do something sane rather than +* cause an interrupt storm. This is close to +* what you'd probably see happen in real hardware. +*/ + src->pending =0 ; +openpic_update_irq (opp, n_IRQ); } } -openpic_update_irq (opp, n_IRQ); }static void openpic_reset (DeviceState *d)
@@ -934,6 +981,21 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr,break ;case 0x80 :/* CTPR */ dst->ctpr = val &0x0000000F ; + +DPRINTF ("%s: set CPU %d ctpr to %d, raised %d servicing %d\n" , + __func__, idx, dst->ctpr, dst->raised.priority, + dst->servicing.priority); + +if (dst->raised.priority <= dst->ctpr) { +DPRINTF ("%s: Lower OpenPIC INT output cpu %d due to ctpr\n" , + __func__, idx); +qemu_irq_lower (dst->irqs[OPENPIC_OUTPUT_INT ]); + }else if (dst->raised.priority > dst->servicing.priority) { +DPRINTF ("%s: Raise OpenPIC INT output cpu %d irq %d\n" , + __func__, idx, dst->raised.next); +qemu_irq_raise (dst->irqs[OPENPIC_OUTPUT_INT ]); + } +break ;case 0x90 :/* WHOAMI */ /* Read-only register */
@@ -995,22 +1057,21 @@ static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) src = &opp->src[irq];if (!(src->ivpr &IVPR_ACTIVITY_MASK ) || !(IVPR_PRIORITY (src->ivpr) > dst->ctpr)) { -/* - Spurious level-sensitive IRQ -* - Priorities has been changed -* and the pending IRQ isn't allowed anymore -*/ - src->ivpr &= ~IVPR_ACTIVITY_MASK ; +fprintf (stderr,"%s: bad raised IRQ %d ctpr %d ivpr 0x%08x\n" , + __func__, irq, dst->ctpr, src->ivpr); +openpic_update_irq (opp, irq); retval = opp->spve; }else {/* IRQ enter servicing state */ IRQ_setbit (&dst->servicing, irq); retval =IVPR_VECTOR (opp, src->ivpr); } -IRQ_resetbit (&dst->raised, irq); +if (!src->level) {/* edge-sensitive IRQ */ src->ivpr &= ~IVPR_ACTIVITY_MASK ; src->pending =0 ; +IRQ_resetbit (&dst->raised, irq); }if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 +MAX_IPI ))) {
@@ -1208,6 +1269,8 @@ static void openpic_save(QEMUFile* f, void *opaque)qemu_put_sbe32s (f, &opp->dst[i].ctpr);openpic_save_IRQ_queue (f, &opp->dst[i].raised);openpic_save_IRQ_queue (f, &opp->dst[i].servicing); +qemu_put_buffer (f, (uint8_t *)&opp->dst[i].outputs_active, +sizeof (opp->dst[i].outputs_active)); }for (i =0 ; i <MAX_TMR ; i++) {
@@ -1264,6 +1327,8 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)qemu_get_sbe32s (f, &opp->dst[i].ctpr);openpic_load_IRQ_queue (f, &opp->dst[i].raised);openpic_load_IRQ_queue (f, &opp->dst[i].servicing); +qemu_get_buffer (f, (uint8_t *)&opp->dst[i].outputs_active, +sizeof (opp->dst[i].outputs_active)); }for (i =0 ; i <MAX_TMR ; i++) {
Signature · 1 line
1.6.0.2
PATCH 26/31 kvm: Update kernel headers
In reply to Alexander GrafCorresponding kvm.git hash: 18eb54cf4a
--- linux-headers/asm-powerpc/epapr_hcalls.h | 98 ++++++++++++++++++++++++++++++ linux-headers/asm-powerpc/kvm.h | 86 ++++++++++++++++++++++++++ linux-headers/asm-powerpc/kvm_para.h | 13 ++-- linux-headers/linux/kvm.h | 21 +++++-- linux-headers/linux/kvm_para.h | 6 +- linux-headers/linux/vfio.h | 6 +- linux-headers/linux/virtio_config.h | 6 +- linux-headers/linux/virtio_ring.h | 6 +- 8 files changed, 219 insertions(+), 23 deletions(-) create mode 100644 linux-headers/asm-powerpc/epapr_hcalls.h
linux-headers/asm-powerpc/epapr_hcalls.h new file +98 -0
@@ -0,0 +1,98 @@ +/* +* ePAPR hcall interface +* +* Copyright 2008-2011 Freescale Semiconductor, Inc. +* +* Author: Timur Tabi <[email protected]> +* +* This file is provided under a dual BSD/GPL license. When using or +* redistributing this file, you may do so under either license. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of Freescale Semiconductor nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* +* ALTERNATIVELY, this software may be distributed under the terms of the +* GNU General Public License ("GPL") as published by the Free Software +* Foundation, either version 2 of that License or (at your option) any +* later version. +* +* THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _ASM_POWERPC_EPAPR_HCALLS_H +#define _ASM_POWERPC_EPAPR_HCALLS_H + +#define EV_BYTE_CHANNEL_SEND 1 +#define EV_BYTE_CHANNEL_RECEIVE 2 +#define EV_BYTE_CHANNEL_POLL 3 +#define EV_INT_SET_CONFIG 4 +#define EV_INT_GET_CONFIG 5 +#define EV_INT_SET_MASK 6 +#define EV_INT_GET_MASK 7 +#define EV_INT_IACK 9 +#define EV_INT_EOI 10 +#define EV_INT_SEND_IPI 11 +#define EV_INT_SET_TASK_PRIORITY 12 +#define EV_INT_GET_TASK_PRIORITY 13 +#define EV_DOORBELL_SEND 14 +#define EV_MSGSND 15 +#define EV_IDLE 16 + +/* vendor ID: epapr */ +#define EV_LOCAL_VENDOR_ID 0/* for private use */ +#define EV_EPAPR_VENDOR_ID 1 +#define EV_FSL_VENDOR_ID 2/* Freescale Semiconductor */ +#define EV_IBM_VENDOR_ID 3/* IBM */ +#define EV_GHS_VENDOR_ID 4/* Green Hills Software */ +#define EV_ENEA_VENDOR_ID 5/* Enea */ +#define EV_WR_VENDOR_ID 6/* Wind River Systems */ +#define EV_AMCC_VENDOR_ID 7/* Applied Micro Circuits */ +#define EV_KVM_VENDOR_ID 42/* KVM */ + +/* The max number of bytes that a byte channel can send or receive per call */ +#define EV_BYTE_CHANNEL_MAX_BYTES 16 + + +#define _EV_HCALL_TOKEN (id, num) (((id) << 16) | (num)) +#define EV_HCALL_TOKEN (hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num) + +/* epapr return codes */ +#define EV_SUCCESS 0 +#define EV_EPERM 1/* Operation not permitted */ +#define EV_ENOENT 2/* Entry Not Found */ +#define EV_EIO 3/* I/O error occured */ +#define EV_EAGAIN 4/* The operation had insufficient +* resources to complete and should be +* retried +*/ +#define EV_ENOMEM 5/* There was insufficient memory to +* complete the operation */ +#define EV_EFAULT 6/* Bad guest address */ +#define EV_ENODEV 7/* No such device */ +#define EV_EINVAL 8/* An argument supplied to the hcall +was out of range or invalid */ +#define EV_INTERNAL 9/* An internal error occured */ +#define EV_CONFIG 10/* A configuration error was detected */ +#define EV_INVALID_STATE 11/* The object is in an invalid state */ +#define EV_UNIMPLEMENTED 12/* Unimplemented hypercall */ +#define EV_BUFFER_OVERFLOW 13/* Caller-supplied buffer too small */ + +#endif /* _ASM_POWERPC_EPAPR_HCALLS_H */
linux-headers/asm-powerpc/kvm.h +86 -0
98 lines not on this page · raw message
linux-headers/asm-powerpc/kvm_para.h +7 -6
@@ -17,8 +17,8 @@* Authors: Hollis Blanchard <[email protected]> */ -#ifndef _UAPI__POWERPC_KVM_PARA_H__ -#define _UAPI__POWERPC_KVM_PARA_H__ +#ifndef __POWERPC_KVM_PARA_H__ +#define __POWERPC_KVM_PARA_H__#include <linux/types.h>
@@ -75,9 +75,10 @@ struct kvm_vcpu_arch_shared { };#define KVM_SC_MAGIC_R0 0x4b564d21/* "KVM!" */ -#define HC_VENDOR_KVM (42 << 16) -#define HC_EV_SUCCESS 0 -#define HC_EV_UNIMPLEMENTED 12 + +#define KVM_HCALL_TOKEN (num) _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num) + +#include <asm/epapr_hcalls.h> #define KVM_FEATURE_MAGIC_PAGE 1
@@ -87,4 +88,4 @@ struct kvm_vcpu_arch_shared {#define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1) -#endif /* _UAPI__POWERPC_KVM_PARA_H__ */ +#endif /* __POWERPC_KVM_PARA_H__ */
linux-headers/linux/kvm.h +16 -5
@@ -167,10 +167,15 @@ struct kvm_pit_config {#define KVM_EXIT_OSI 18#define KVM_EXIT_PAPR_HCALL 19#define KVM_EXIT_S390_UCONTROL 20 +#define KVM_EXIT_WATCHDOG 21/* For KVM_EXIT_INTERNAL_ERROR */ -#define KVM_INTERNAL_ERROR_EMULATION 1 -#define KVM_INTERNAL_ERROR_SIMUL_EX 2 +/* Emulate instruction failed. */ +#define KVM_INTERNAL_ERROR_EMULATION 1 +/* Encounter unexpected simultaneous exceptions. */ +#define KVM_INTERNAL_ERROR_SIMUL_EX 2 +/* Encounter unexpected vm-exit due to delivery event. */ +#define KVM_INTERNAL_ERROR_DELIVERY_EV 3/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ struct kvm_run {
@@ -477,6 +482,8 @@ struct kvm_ppc_smmu_info {struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ ]; }; +#define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) +#define KVMIO 0xAE/* machine type bits, to be used as argument to KVM_CREATE_VM */
@@ -626,6 +633,8 @@ struct kvm_ppc_smmu_info {#define KVM_CAP_READONLY_MEM 81#endif #define KVM_CAP_IRQFD_RESAMPLE 82 +#define KVM_CAP_PPC_BOOKE_WATCHDOG 83 +#define KVM_CAP_PPC_HTAB_FD 84#ifdef KVM_CAP_IRQ_ROUTING
@@ -848,6 +857,11 @@ struct kvm_s390_ucas_mapping {#define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info)/* Available with KVM_CAP_PPC_ALLOC_HTAB */ #define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32) +#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) +/* Available with KVM_CAP_RMA */ +#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) +/* Available with KVM_CAP_PPC_HTAB_FD */ +#define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd)/* * ioctls for vcpu fds
@@ -911,9 +925,6 @@ struct kvm_s390_ucas_mapping {/* Available with KVM_CAP_XCRS */ #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs)#define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) -#define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) -/* Available with KVM_CAP_RMA */ -#define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma)/* Available with KVM_CAP_SW_TLB */ #define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb)/* Available with KVM_CAP_ONE_REG */
linux-headers/linux/kvm_para.h +3 -3
@@ -1,5 +1,5 @@ -#ifndef _UAPI__LINUX_KVM_PARA_H -#define _UAPI__LINUX_KVM_PARA_H +#ifndef __LINUX_KVM_PARA_H +#define __LINUX_KVM_PARA_H/* * This header file provides a method for making a hypercall to the host
@@ -25,4 +25,4 @@*/ #include <asm/kvm_para.h> -#endif /* _UAPI__LINUX_KVM_PARA_H */ +#endif /* __LINUX_KVM_PARA_H */
linux-headers/linux/vfio.h +3 -3
@@ -8,8 +8,8 @@* it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#ifndef _UAPIVFIO_H -#define _UAPIVFIO_H +#ifndef VFIO_H +#define VFIO_H #include <linux/types.h> #include <linux/ioctl.h>
@@ -365,4 +365,4 @@ struct vfio_iommu_type1_dma_unmap {#define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14) -#endif /* _UAPIVFIO_H */ +#endif /* VFIO_H */
linux-headers/linux/virtio_config.h +3 -3
@@ -1,5 +1,5 @@ -#ifndef _UAPI_LINUX_VIRTIO_CONFIG_H -#define _UAPI_LINUX_VIRTIO_CONFIG_H +#ifndef _LINUX_VIRTIO_CONFIG_H +#define _LINUX_VIRTIO_CONFIG_H/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so * anyone can use the definitions to implement compatible drivers/servers. *
@@ -51,4 +51,4 @@* suppressed them? */ #define VIRTIO_F_NOTIFY_ON_EMPTY 24 -#endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */ +#endif /* _LINUX_VIRTIO_CONFIG_H */
linux-headers/linux/virtio_ring.h +3 -3
@@ -1,5 +1,5 @@ -#ifndef _UAPI_LINUX_VIRTIO_RING_H -#define _UAPI_LINUX_VIRTIO_RING_H +#ifndef _LINUX_VIRTIO_RING_H +#define _LINUX_VIRTIO_RING_H/* An interface for efficient virtio implementation, currently for use by KVM * and lguest, but hopefully others soon. Do NOT change this since it will * break existing servers and clients.
@@ -160,4 +160,4 @@ static __inline__ int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old); } -#endif /* _UAPI_LINUX_VIRTIO_RING_H */ +#endif /* _LINUX_VIRTIO_RING_H */
Signature · 1 line
1.6.0.2
PATCH 27/31 PPC: KVM: set has-idle in guest device tree
In reply to Alexander GrafFrom: Stuart Yoder <[email protected]>
On e500mc, the platform doesn't provide a way for the CPU to go idle.
To still not uselessly burn CPU time, expose an idle hypercall to the guest if kvm supports it.
--- hw/ppc/e500.c | 4 ++++ target-ppc/kvm.c | 32 ++++++++++++++++++++++++++------ target-ppc/kvm_ppc.h | 1 + 3 files changed, 31 insertions(+), 6 deletions(-)
hw/ppc/e500.c +4 -0
@@ -225,6 +225,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,kvmppc_get_hypercall (env, hypercall,sizeof (hypercall));qemu_devtree_setprop (fdt,"/hypervisor" ,"hcall-instructions" , hypercall,sizeof (hypercall)); +/* if KVM supports the idle hcall, set property indicating this */ +if (kvmppc_get_hasidle (env)) { +qemu_devtree_setprop (fdt,"/hypervisor" ,"has-idle" ,NULL ,0 ); + } }/* Create CPU nodes */
target-ppc/kvm.c +26 -6
@@ -989,18 +989,38 @@ uint32_t kvmppc_get_dfp(void)return kvmppc_read_int_cpu_dt ("ibm,dfp" ); } +static int kvmppc_get_pvinfo (CPUPPCState *env,struct kvm_ppc_pvinfo *pvinfo) + { +PowerPCCPU *cpu =ppc_env_get_cpu (env); +CPUState *cs =CPU (cpu); + +if (kvm_check_extension (cs->kvm_state,KVM_CAP_PPC_GET_PVINFO ) && + !kvm_vm_ioctl (cs->kvm_state,KVM_PPC_GET_PVINFO , pvinfo)) { +return 0 ; + } + +return 1 ; +} + +int kvmppc_get_hasidle (CPUPPCState *env) +{ +struct kvm_ppc_pvinfo pvinfo; + +if (!kvmppc_get_pvinfo (env, &pvinfo) && + (pvinfo.flags &KVM_PPC_PVINFO_FLAGS_EV_IDLE )) { +return 1 ; + } + +return 0 ; +} +int kvmppc_get_hypercall (CPUPPCState *env,uint8_t *buf,int buf_len) { -PowerPCCPU *cpu =ppc_env_get_cpu (env); -CPUState *cs =CPU (cpu);uint32_t *hc = (uint32_t *)buf; -struct kvm_ppc_pvinfo pvinfo; -if (kvm_check_extension (cs->kvm_state,KVM_CAP_PPC_GET_PVINFO ) && - !kvm_vm_ioctl (cs->kvm_state,KVM_PPC_GET_PVINFO , &pvinfo)) { +if (!kvmppc_get_pvinfo (env, &pvinfo)) {memcpy (buf, pvinfo.hcall, buf_len); -return 0 ; }
target-ppc/kvm_ppc.h +1 -0
@@ -19,6 +19,7 @@ uint32_t kvmppc_get_tbfreq(void);uint64_t kvmppc_get_clockfreq (void );uint32_t kvmppc_get_vmx (void );uint32_t kvmppc_get_dfp (void ); +int kvmppc_get_hasidle (CPUPPCState *env);int kvmppc_get_hypercall (CPUPPCState *env,uint8_t *buf,int buf_len);int kvmppc_set_interrupt (PowerPCCPU *cpu,int irq,int level);void kvmppc_set_papr (PowerPCCPU *cpu);
Signature · 1 line
1.6.0.2
PATCH 28/31 PPC: Bring EPR support closer to reality
In reply to Alexander GrafWe already used to support the external proxy facility of FSL MPICs, but only implemented it halfway correctly.
This patch adds support for
* dynamic enablement of the EPR facility
* interrupt acknowledgement only when the interrupt is delivered
This way the implementation now is closer to real hardware.
--- hw/openpic.c | 21 +++++++++++++++++++++ hw/ppc/e500.c | 4 ++-- target-ppc/Makefile.objs | 1 - target-ppc/cpu.h | 4 +++- target-ppc/excp_helper.c | 4 ++++ target-ppc/helper.h | 1 - target-ppc/mpic_helper.c | 35 ----------------------------------- target-ppc/translate_init.c | 7 +------ 8 files changed, 31 insertions(+), 46 deletions(-) delete mode 100644 target-ppc/mpic_helper.c
hw/openpic.c +21 -0
@@ -131,6 +131,9 @@ static const int debug_openpic = 0;#define VIR_GENERIC 0x00000000/* Generic Vendor ID */ #define GCR_RESET 0x80000000 +#define GCR_MODE_PASS 0x00000000 +#define GCR_MODE_MIXED 0x20000000 +#define GCR_MODE_PROXY 0x60000000#define TBCR_CI 0x80000000/* count inhibit */ #define TCCR_TOG 0x80000000/* toggles when decrement to zero */
@@ -233,6 +236,7 @@ typedef struct OpenPICState {uint32_t ivpr_reset;uint32_t idr_reset;uint32_t brr1; +uint32_t mpic_mode_mask;/* Sub-regions */ MemoryRegion sub_io_mem[5 ];
@@ -667,6 +671,20 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,case 0x1020 :/* GCR */ if (val &GCR_RESET ) {openpic_reset (&opp->busdev.qdev); + }else if (opp->mpic_mode_mask) { +CPUArchState *env; +int mpic_proxy =0 ; + + opp->gcr &= ~opp->mpic_mode_mask; + opp->gcr |= val & opp->mpic_mode_mask; + +/* Set external proxy mode */ +if ((val & opp->mpic_mode_mask) ==GCR_MODE_PROXY ) { + mpic_proxy =1 ; + } +for (env = first_cpu; env !=NULL ; env = env->next_cpu) { + env->mpic_proxy = mpic_proxy; + } }break ;case 0x1080 :/* VIR */
@@ -1407,6 +1425,9 @@ static int openpic_init(SysBusDevice *dev) opp->irq_tim0 =FSL_MPIC_20_TMR_IRQ ; opp->irq_msi =FSL_MPIC_20_MSI_IRQ ; opp->brr1 =FSL_BRR1_IPID |FSL_BRR1_IPMJ |FSL_BRR1_IPMN ; +/* XXX really only available as of MPIC 4.0 */ + opp->mpic_mode_mask =GCR_MODE_PROXY ; + msi_supported = true; list = list_be;
hw/ppc/e500.c +2 -2
@@ -497,8 +497,8 @@ void ppce500_init(PPCE500Params *params) irqs[i][OPENPIC_OUTPUT_INT ] = input[PPCE500_INPUT_INT ]; irqs[i][OPENPIC_OUTPUT_CINT ] = input[PPCE500_INPUT_CINT ]; env->spr[SPR_BOOKE_PIR ] = env->cpu_index = i; - env->mpic_cpu_base =MPC8544_CCSRBAR_BASE + -MPC8544_MPIC_REGS_OFFSET +0x20000 ; + env->mpic_iack =MPC8544_CCSRBAR_BASE + +MPC8544_MPIC_REGS_OFFSET +0x200A0 ;ppc_booke_timers_init (cpu,400000000 ,PPC_TIMER_E500 );
target-ppc/Makefile.objs +0 -1
@@ -9,4 +9,3 @@ obj-y += mmu_helper.o obj-y += timebase_helper.o obj-y += misc_helper.o obj-y += mem_helper.o -obj-y += mpic_helper.o
target-ppc/cpu.h +3 -1
@@ -1067,7 +1067,9 @@ struct CPUPPCState {target_ulong ivor_mask;target_ulong ivpr_mask;target_ulong hreset_vector; -hwaddr mpic_cpu_base; +hwaddr mpic_iack; +/* true when the external proxy facility mode is enabled */ +bool mpic_proxy;#endif /* Those resources are used only during code translation */
target-ppc/excp_helper.c +4 -0
@@ -178,6 +178,10 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)if (lpes0 ==1 ) { new_msr |= (target_ulong )MSR_HVB ; } +if (env->mpic_proxy) { +/* IACK the IRQ on delivery */ + env->spr[SPR_BOOKE_EPR ] =ldl_phys (env->mpic_iack); + } goto store_next;case POWERPC_EXCP_ALIGN :/* Alignment exception */ if (lpes1 ==0 ) {
target-ppc/helper.h +0 -1
@@ -405,7 +405,6 @@ DEF_HELPER_2(store_40x_dbcr0, void, env, tl) DEF_HELPER_2(store_40x_sler, void, env, tl) DEF_HELPER_2(store_booke_tcr, void, env, tl) DEF_HELPER_2(store_booke_tsr, void, env, tl) -DEF_HELPER_1(load_epr, tl, env) DEF_HELPER_3(store_ibatl, void, env, i32, tl) DEF_HELPER_3(store_ibatu, void, env, i32, tl)DEF_HELPER_3 (store_dbatl, void, env, i32, tl)
target-ppc/mpic_helper.c deleted +0 -35
@@ -1,35 +0,0 @@ -/* -* PowerPC emulation helpers for QEMU. -* -* Copyright (c) 2003-2007 Jocelyn Mayer -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2 of the License, or (at your option) any later version. -* -* This library 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, see <http://www.gnu.org/licenses/>. -*/ -#include "cpu.h" -#include "helper.h" - -/*****************************************************************************/ -/* SPR accesses */ - -#if !defined(CONFIG_USER_ONLY ) -/* -* This is an ugly helper for EPR, which is basically the same as accessing -* the IACK (PIAC) register on the MPIC. Because we model the MPIC as a device -* that can only talk to the CPU through MMIO, let's access it that way! -*/ -target_ulong helper_load_epr (CPUPPCState *env) -{ -return ldl_phys (env->mpic_cpu_base +0xA0 ); -} -#endif
target-ppc/translate_init.c +1 -6
@@ -4493,11 +4493,6 @@ static void spr_read_mas73(void *opaque, int gprn, int sprn)tcg_temp_free (mas7); } -static void spr_load_epr (void *opaque,int gprn,int sprn) -{ -gen_helper_load_epr (cpu_gpr[gprn], cpu_env); -} -#endif enum fsl_e500_version {
@@ -4656,7 +4651,7 @@ static void init_proc_e500 (CPUPPCState *env, int version) 0x00000000);spr_register (env,SPR_BOOKE_EPR ,"EPR" ,SPR_NOACCESS ,SPR_NOACCESS , - &spr_load_epr,SPR_NOACCESS , + &spr_read_generic,SPR_NOACCESS ,0x00000000 );/* XXX better abstract into Emb.xxx features */ if (version == fsl_e5500) {
Signature · 1 line
1.6.0.2
PATCH 29/31 target-ppc: Slim conversion of model definitions to QOM subclasses
In reply to Alexander GrafFrom: Andreas Färber <[email protected]>
Since the model list is highly macrofied, keep ppc_def_t for now and save a pointer to it in PowerPCCPUClass. This results in a flat list of subclasses including aliases, to be refined later.
Move cpu_ppc_init() to translate_init.c and drop helper.c. Long-term the idea is to turn translate_init.c into a standalone cpu.c.
Inline cpu_ppc_usable() into type registration.
Split cpu_ppc_register() in two by code movement into the initfn and by turning the remaining part into a realizefn.
Move qemu_init_vcpu() call into the new realizefn and adapt create_ppc_opcodes() to return an Error.
Change ppc_find_by_pvr() -> ppc_cpu_class_by_pvr(). Change ppc_find_by_name() -> ppc_cpu_class_by_name().
Turn -cpu host into its own subclass. This requires to move the kvm_enabled() check in ppc_cpu_class_by_name() to avoid the class being found via the normal name lookup in the !kvm_enabled() case. Turn kvmppc_host_cpu_def() into the class_init and add an initfn that asserts KVM is in fact enabled.
Implement -cpu ? and the QMP equivalent in terms of subclasses. This newly exposes -cpu host to the user, ordered last for -cpu ?.
--- target-ppc/Makefile.objs | 3 +- target-ppc/cpu-qom.h | 5 + target-ppc/cpu.h | 4 - target-ppc/helper.c | 50 ------ target-ppc/kvm.c | 37 ++++- target-ppc/kvm_ppc.h | 8 +- target-ppc/translate_init.c | 345 +++++++++++++++++++++++++++++------------- 7 files changed, 276 insertions(+), 176 deletions(-) delete mode 100644 target-ppc/helper.c
target-ppc/Makefile.objs +1 -2
@@ -1,7 +1,6 @@ -obj-y += translate.o helper.o +obj-y += translate.o obj-$(CONFIG_SOFTMMU) += machine.o obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o -obj-y += helper.o obj-y += excp_helper.o obj-y += fpu_helper.o obj-y += int_helper.o
target-ppc/cpu-qom.h +5 -0
@@ -50,6 +50,9 @@ typedef struct PowerPCCPUClass {/*< public >*/ void (*parent_reset)(CPUState *cpu); + +/* TODO inline fields here */ +ppc_def_t *info; } PowerPCCPUClass;/**
@@ -73,5 +76,7 @@ static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)#define ENV_GET_CPU (e) CPU(ppc_env_get_cpu(e)) +PowerPCCPUClass *ppc_cpu_class_by_pvr (uint32_t pvr); +#endif
target-ppc/cpu.h +0 -4
@@ -1158,10 +1158,6 @@ void ppc_store_msr (CPUPPCState *env, target_ulong value);void ppc_cpu_list (FILE *f,fprintf_function cpu_fprintf); -const ppc_def_t *ppc_find_by_pvr (uint32_t pvr); -const ppc_def_t *cpu_ppc_find_by_name (const char *name); -int cpu_ppc_register_internal (CPUPPCState *env,const ppc_def_t *def); -/* Time-base and decrementer management */ #ifndef NO_CPU_IO_DEFS uint64_t cpu_ppc_load_tbl (CPUPPCState *env);
target-ppc/helper.c deleted +0 -50
50 lines not on this page · raw message
target-ppc/kvm.c +30 -7
@@ -1230,18 +1230,29 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on) } } -const ppc_def_t *kvmppc_host_cpu_def (void ) +static void kvmppc_host_cpu_initfn (Object *obj) { +assert (kvm_enabled ()); +} + +static void kvmppc_host_cpu_class_init (ObjectClass *oc,void *data) +{ +PowerPCCPUClass *pcc =POWERPC_CPU_CLASS (oc);uint32_t host_pvr =mfpvr (); -const ppc_def_t *base_spec; +PowerPCCPUClass *pvr_pcc;ppc_def_t *spec;uint32_t vmx =kvmppc_get_vmx ();uint32_t dfp =kvmppc_get_dfp (); - base_spec =ppc_find_by_pvr (host_pvr); - spec =g_malloc0 (sizeof (*spec)); -memcpy (spec, base_spec,sizeof (*spec)); + + pvr_pcc =ppc_cpu_class_by_pvr (host_pvr); +if (pvr_pcc !=NULL ) { +memcpy (spec, pvr_pcc->info,sizeof (*spec)); + } + pcc->info = spec; +/* Override the display name for -cpu ? and QMP */ + pcc->info->name ="host" ;/* Now fix up the spec with information we can query from the host */
@@ -1254,8 +1265,6 @@ const ppc_def_t *kvmppc_host_cpu_def(void)/* Only override when we know what the host supports */ alter_insns (&spec->insns_flags2,PPC2_DFP , dfp); } - -return spec; }int kvmppc_fixup_cpu (CPUPPCState *env)
@@ -1285,3 +1294,17 @@ int kvm_arch_on_sigbus(int code, void *addr) {return 1 ; } + +static const TypeInfo kvm_host_cpu_type_info = { + .name =TYPE_HOST_POWERPC_CPU , + .parent =TYPE_POWERPC_CPU , + .instance_init = kvmppc_host_cpu_initfn, + .class_init = kvmppc_host_cpu_class_init, +}; + +static void kvm_ppc_register_types (void ) +{ +type_register_static (&kvm_host_cpu_type_info); +} + +type_init (kvm_ppc_register_types)
target-ppc/kvm_ppc.h +2 -6
@@ -11,6 +11,8 @@#include "exec/memory.h" +#define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU +void kvmppc_init (void );#ifdef CONFIG_KVM
@@ -31,7 +33,6 @@ int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);int kvmppc_reset_htab (int shift_hint);uint64_t kvmppc_rma_size (uint64_t current_size,unsigned int hash_shift);#endif /* !CONFIG_USER_ONLY */ -const ppc_def_t *kvmppc_host_cpu_def (void );int kvmppc_fixup_cpu (CPUPPCState *env);#else
@@ -116,11 +117,6 @@ static inline int kvmppc_update_sdr1(CPUPPCState *env)#endif /* !CONFIG_USER_ONLY */ -static inline const ppc_def_t *kvmppc_host_cpu_def (void ) -{ -return NULL ; -} -static inline int kvmppc_fixup_cpu (CPUPPCState *env) {return -1 ;
target-ppc/translate_init.c +238 -107
459 lines not on this page · raw message
Signature · 1 line
1.6.0.2
PATCH 30/31 target-ppc: Error out for -cpu host on unknown PVR
In reply to Alexander GrafFrom: Andreas Färber <[email protected]>
Previously we silently exited, with subclasses we got an opcode warning. Instead, explicitly tell the user what's wrong.
An indication for this is -cpu ? showing "host" with an all-zero PVR.
--- target-ppc/kvm.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-)
target-ppc/kvm.c +8 -0
@@ -1232,7 +1232,15 @@ static void alter_insns(uint64_t *word, uint64_t flags, bool on)static void kvmppc_host_cpu_initfn (Object *obj) { +PowerPCCPUClass *pcc =POWERPC_CPU_GET_CLASS (obj); +assert (kvm_enabled ()); + +if (pcc->info->pvr !=mfpvr ()) { +fprintf (stderr,"Your host CPU is unsupported.\n" +"Please choose a supported model instead, see -cpu ?.\n" ); +exit (1 ); + } }static void kvmppc_host_cpu_class_init (ObjectClass *oc,void *data)
Signature · 1 line
1.6.0.2
PATCH 31/31 PPC: linux-user: Calculate context pointer explicitly
In reply to Alexander GrafFrom: Samuel Seay <[email protected]>
Peter Maydell recommended the change to be more proper. The result was tested and shows coming up with the same proper value.
--- linux-user/signal.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
linux-user/signal.c +1 -1
@@ -4614,7 +4614,7 @@ static void setup_frame(int sig, struct target_sigaction *ka,/* Set up registers for signal handler. */ env->gpr[1 ] = newsp; env->gpr[3 ] = signal; - env->gpr[4 ] = (target_ulong )h2g (sc); + env->gpr[4 ] = frame_addr + offsetof(struct target_sigframe , sctx); env->nip = (target_ulong ) ka->_sa_handler;/* Signal handlers are entered in big-endian mode. */ env->msr &= ~MSR_LE ;
Signature · 1 line
1.6.0.2
Am 07.01.2013 16:38, schrieb Alexander Graf:
Quoted 3 lines
Hi Blue / Aurelien,
This is my current patch queue for ppc. Please pull.
Breaks on x86_64:
CC ppc-softmmu/hw/ppc/e500.o/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c: In function ‘ppce500_load_device_tree’:/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: implicit declaration of function ‘kvmppc_get_hasidle’ [-Werror=implicit-function-declaration] /home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: nested extern declaration of ‘kvmppc_get_hasidle’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[1]: *** [hw/ppc/e500.o] Fehler 1
make: *** [subdir-ppc-softmmu] Fehler 2
Lacking a static inline version of kvmppc_get_hasidle() in kvm_ppc.h.
Andreas
Signature · 2 lines
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Quoted 19 lines · Andreas Färber
Am 07.01.2013 16:38, schrieb Alexander Graf:
Quoted 3 lines
Hi Blue / Aurelien,
This is my current patch queue for ppc. Please pull.
Breaks on
x86_64:CC
ppc-softmmu/hw/ppc/e500.o/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c: In function ‘ppce500_load_device_tree’:/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: implicit declaration of function ‘kvmppc_get_hasidle’ [-Werror=implicit-function-declaration]/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: nested extern declaration of ‘kvmppc_get_hasidle’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[1]: *** [hw/ppc/e500.o] Fehler 1
make: *** [subdir-ppc-softmmu] Fehler 2
Quoted 1 line
Lacking a static inline version of
kvmppc_get_hasidle()inkvm_ppc.h.
Sigh. I wonder why our buildbots didn't fetch this one.
Fixed it up manually in both ppc-next and ppc-for-upstream, so the pull request is still valid.
Alex
Quoted 22 lines · Alexander Graf
Quoted 19 lines · Andreas Färber
Am 07.01.2013 16:38, schrieb Alexander Graf:
Quoted 3 lines
Hi Blue / Aurelien,
This is my current patch queue for ppc. Please pull.
Breaks on
x86_64:CC
ppc-softmmu/hw/ppc/e500.o/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c: In function ‘ppce500_load_device_tree’:/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: implicit declaration of function ‘kvmppc_get_hasidle’ [-Werror=implicit-function-declaration]/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: nested extern declaration of ‘kvmppc_get_hasidle’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[1]: *** [hw/ppc/e500.o] Fehler 1
make: *** [subdir-ppc-softmmu] Fehler 2
Quoted 5 lines
Quoted 1 line
Lacking a static inline version of
kvmppc_get_hasidle()inkvm_ppc.h.Sigh. I wonder why our buildbots didn't fetch this one.
Fixed it up manually in both ppc-next and ppc-for-upstream, so the pull request is still valid.
e500.o is only built when CONFIG_FDT is defined.
agraf: "zypper search libfdt" on qemu-ppc.opensuse.org turns up no packages. Any ideas where to get the packages from?
Stefan
Am 08.01.2013 um 09:54 schrieb Stefan Hajnoczi <[email protected]>:
Quoted 25 lines · Alexander Graf
Quoted 24 lines · Andreas Färber
Quoted 21 lines
Am 07.01.2013 16:38, schrieb Alexander Graf:
Quoted 3 lines
Hi Blue / Aurelien,
This is my current patch queue for ppc. Please pull.
Breaks on
x86_64:CC
ppc-softmmu/hw/ppc/e500.o/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c: In function ‘ppce500_load_device_tree’:/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: implicit declaration of function ‘kvmppc_get_hasidle’ [-Werror=implicit-function-declaration]/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: nested extern declaration of ‘kvmppc_get_hasidle’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[1]: *** [hw/ppc/e500.o] Fehler 1
make: *** [subdir-ppc-softmmu] Fehler 2Lacking a static inline version of
kvmppc_get_hasidle()inkvm_ppc.h.
Quoted 8 lines
Quoted 3 lines
Sigh. I wonder why our buildbots didn't fetch this one.
Fixed it up manually in both ppc-next and ppc-for-upstream, so the pull request is still valid.
e500.o is only built when
CONFIG_FDTis defined.agraf: "zypper search libfdt" on qemu-ppc.opensuse.org turns up no packages. Any ideas where to get the packages from?
I can install them on the ppc box, but the important build case would be against x86, no?
Alex
Quoted 2 lines
Stefan
Quoted 2 lines · Stefan Hajnoczi
agraf: "zypper search libfdt" on qemu-ppc.opensuse.org turns up no packages. Any ideas where to get the packages from?
Fedora 17 ships them. Either grab the packages from there, or the rpm info points to
URL : http://git.jdl.com/gitweb/?p=dtc.git;a=summary
as the upstream source.
r~
Quoted 22 lines · Alexander Graf
Quoted 19 lines · Andreas Färber
Am 07.01.2013 16:38, schrieb Alexander Graf:
Quoted 3 lines
Hi Blue / Aurelien,
This is my current patch queue for ppc. Please pull.
Breaks on
x86_64:CC
ppc-softmmu/hw/ppc/e500.o/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c: In function ‘ppce500_load_device_tree’:/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: implicit declaration of function ‘kvmppc_get_hasidle’ [-Werror=implicit-function-declaration]/home/andreas/QEMU/qemu-ppc/hw/ppc/e500.c:229:9: error: nested extern declaration of ‘kvmppc_get_hasidle’ [-Werror=nested-externs]
cc1: all warnings being treated as errors
make[1]: *** [hw/ppc/e500.o] Fehler 1
make: *** [subdir-ppc-softmmu] Fehler 2
Quoted 5 lines
Quoted 1 line
Lacking a static inline version of
kvmppc_get_hasidle()inkvm_ppc.h.Sigh. I wonder why our buildbots didn't fetch this one.
Fixed it up manually in both ppc-next and ppc-for-upstream, so the pull request is still valid.
Thanks, pulled.
Quoted 4 lines
Alex