qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf

* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf: (31 commits)
PPC: linux-user: Calculate context pointer explicitly
target-ppc: Error out for -cpu host on unknown PVR
target-ppc: Slim conversion of model definitions to QOM subclasses
PPC: Bring EPR support closer to reality
PPC: KVM: set has-idle in guest device tree
kvm: Update kernel headers
openpic: fix CTPR and de-assertion of interrupts
openpic: move IACK to its own function
openpic: IRQ_check: search the queue a word at a time
openpic: fix sense and priority bits
openpic: add some bounds checking for IRQ numbers
openpic: use standard bitmap operations
Revert "openpic: Accelerate pending irq search"
openpic: always call IRQ_check from IRQ_get_next
openpic/fsl: critical interrupts ignore mask before v4.1
openpic: make ctpr signed
openpic: rework critical interrupt support
openpic: make register names correspond better with hw docs
ppc/booke: fix crit/mcheck/debug exceptions
openpic: lower interrupt when reading the MSI register
...

+1226 -651
+636 -388
hw/openpic.c
··· 39 39 #include "openpic.h" 40 40 #include "sysbus.h" 41 41 #include "pci/msi.h" 42 + #include "qemu/bitops.h" 42 43 43 44 //#define DEBUG_OPENPIC 44 45 45 46 #ifdef DEBUG_OPENPIC 46 - #define DPRINTF(fmt, ...) do { printf(fmt , ## __VA_ARGS__); } while (0) 47 + static const int debug_openpic = 1; 47 48 #else 48 - #define DPRINTF(fmt, ...) do { } while (0) 49 + static const int debug_openpic = 0; 49 50 #endif 50 51 52 + #define DPRINTF(fmt, ...) do { \ 53 + if (debug_openpic) { \ 54 + printf(fmt , ## __VA_ARGS__); \ 55 + } \ 56 + } while (0) 57 + 51 58 #define MAX_CPU 15 52 59 #define MAX_SRC 256 53 60 #define MAX_TMR 4 54 - #define VECTOR_BITS 8 55 61 #define MAX_IPI 4 56 62 #define MAX_MSI 8 57 63 #define MAX_IRQ (MAX_SRC + MAX_IPI + MAX_TMR) 58 64 #define VID 0x03 /* MPIC version ID */ 59 65 60 66 /* OpenPIC capability flags */ 61 - #define OPENPIC_FLAG_IDE_CRIT (1 << 0) 67 + #define OPENPIC_FLAG_IDR_CRIT (1 << 0) 62 68 63 69 /* OpenPIC address map */ 64 70 #define OPENPIC_GLB_REG_START 0x0 ··· 115 121 #define FSL_BRR1_IPMJ (0x00 << 8) /* 8 bit IP major number */ 116 122 #define FSL_BRR1_IPMN 0x00 /* 8 bit IP minor number */ 117 123 118 - #define FREP_NIRQ_SHIFT 16 119 - #define FREP_NCPU_SHIFT 8 120 - #define FREP_VID_SHIFT 0 124 + #define FRR_NIRQ_SHIFT 16 125 + #define FRR_NCPU_SHIFT 8 126 + #define FRR_VID_SHIFT 0 121 127 122 128 #define VID_REVISION_1_2 2 123 129 #define VID_REVISION_1_3 3 124 130 125 - #define VENI_GENERIC 0x00000000 /* Generic Vendor ID */ 131 + #define VIR_GENERIC 0x00000000 /* Generic Vendor ID */ 132 + 133 + #define GCR_RESET 0x80000000 134 + #define GCR_MODE_PASS 0x00000000 135 + #define GCR_MODE_MIXED 0x20000000 136 + #define GCR_MODE_PROXY 0x60000000 137 + 138 + #define TBCR_CI 0x80000000 /* count inhibit */ 139 + #define TCCR_TOG 0x80000000 /* toggles when decrement to zero */ 126 140 127 141 #define IDR_EP_SHIFT 31 128 142 #define IDR_EP_MASK (1 << IDR_EP_SHIFT) ··· 137 151 #define MSIIR_IBS_SHIFT 24 138 152 #define MSIIR_IBS_MASK (0x1f << MSIIR_IBS_SHIFT) 139 153 140 - #define BF_WIDTH(_bits_) \ 141 - (((_bits_) + (sizeof(uint32_t) * 8) - 1) / (sizeof(uint32_t) * 8)) 142 - 143 - static inline void set_bit(uint32_t *field, int bit) 144 - { 145 - field[bit >> 5] |= 1 << (bit & 0x1F); 146 - } 147 - 148 - static inline void reset_bit(uint32_t *field, int bit) 149 - { 150 - field[bit >> 5] &= ~(1 << (bit & 0x1F)); 151 - } 152 - 153 - static inline int test_bit(uint32_t *field, int bit) 154 - { 155 - return (field[bit >> 5] & 1 << (bit & 0x1F)) != 0; 156 - } 157 - 158 154 static int get_current_cpu(void) 159 155 { 160 - return cpu_single_env->cpu_index; 156 + if (!cpu_single_env) { 157 + return -1; 158 + } 159 + 160 + return cpu_single_env->cpu_index; 161 161 } 162 162 163 163 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, ··· 165 165 static void openpic_cpu_write_internal(void *opaque, hwaddr addr, 166 166 uint32_t val, int idx); 167 167 168 - typedef struct IRQ_queue_t { 169 - uint32_t queue[BF_WIDTH(MAX_IRQ)]; 168 + typedef enum IRQType { 169 + IRQ_TYPE_NORMAL = 0, 170 + IRQ_TYPE_FSLINT, /* FSL internal interrupt -- level only */ 171 + IRQ_TYPE_FSLSPECIAL, /* FSL timer/IPI interrupt, edge, no polarity */ 172 + } IRQType; 173 + 174 + typedef struct IRQQueue { 175 + /* Round up to the nearest 64 IRQs so that the queue length 176 + * won't change when moving between 32 and 64 bit hosts. 177 + */ 178 + unsigned long queue[BITS_TO_LONGS((MAX_IRQ + 63) & ~63)]; 170 179 int next; 171 180 int priority; 172 - int pending; /* nr of pending bits in queue */ 173 - } IRQ_queue_t; 181 + } IRQQueue; 174 182 175 - typedef struct IRQ_src_t { 176 - uint32_t ipvp; /* IRQ vector/priority register */ 177 - uint32_t ide; /* IRQ destination register */ 183 + typedef struct IRQSource { 184 + uint32_t ivpr; /* IRQ vector/priority register */ 185 + uint32_t idr; /* IRQ destination register */ 186 + uint32_t destmask; /* bitmap of CPU destinations */ 178 187 int last_cpu; 188 + int output; /* IRQ level, e.g. OPENPIC_OUTPUT_INT */ 179 189 int pending; /* TRUE if IRQ is pending */ 180 - } IRQ_src_t; 190 + IRQType type; 191 + bool level:1; /* level-triggered */ 192 + bool nomask:1; /* critical interrupts ignore mask on some FSL MPICs */ 193 + } IRQSource; 181 194 182 - #define IPVP_MASK_SHIFT 31 183 - #define IPVP_MASK_MASK (1 << IPVP_MASK_SHIFT) 184 - #define IPVP_ACTIVITY_SHIFT 30 185 - #define IPVP_ACTIVITY_MASK (1 << IPVP_ACTIVITY_SHIFT) 186 - #define IPVP_MODE_SHIFT 29 187 - #define IPVP_MODE_MASK (1 << IPVP_MODE_SHIFT) 188 - #define IPVP_POLARITY_SHIFT 23 189 - #define IPVP_POLARITY_MASK (1 << IPVP_POLARITY_SHIFT) 190 - #define IPVP_SENSE_SHIFT 22 191 - #define IPVP_SENSE_MASK (1 << IPVP_SENSE_SHIFT) 195 + #define IVPR_MASK_SHIFT 31 196 + #define IVPR_MASK_MASK (1 << IVPR_MASK_SHIFT) 197 + #define IVPR_ACTIVITY_SHIFT 30 198 + #define IVPR_ACTIVITY_MASK (1 << IVPR_ACTIVITY_SHIFT) 199 + #define IVPR_MODE_SHIFT 29 200 + #define IVPR_MODE_MASK (1 << IVPR_MODE_SHIFT) 201 + #define IVPR_POLARITY_SHIFT 23 202 + #define IVPR_POLARITY_MASK (1 << IVPR_POLARITY_SHIFT) 203 + #define IVPR_SENSE_SHIFT 22 204 + #define IVPR_SENSE_MASK (1 << IVPR_SENSE_SHIFT) 192 205 193 - #define IPVP_PRIORITY_MASK (0x1F << 16) 194 - #define IPVP_PRIORITY(_ipvpr_) ((int)(((_ipvpr_) & IPVP_PRIORITY_MASK) >> 16)) 195 - #define IPVP_VECTOR_MASK ((1 << VECTOR_BITS) - 1) 196 - #define IPVP_VECTOR(_ipvpr_) ((_ipvpr_) & IPVP_VECTOR_MASK) 206 + #define IVPR_PRIORITY_MASK (0xF << 16) 207 + #define IVPR_PRIORITY(_ivprr_) ((int)(((_ivprr_) & IVPR_PRIORITY_MASK) >> 16)) 208 + #define IVPR_VECTOR(opp, _ivprr_) ((_ivprr_) & (opp)->vector_mask) 197 209 198 - typedef struct IRQ_dst_t { 199 - uint32_t pctp; /* CPU current task priority */ 200 - uint32_t pcsr; /* CPU sensitivity register */ 201 - IRQ_queue_t raised; 202 - IRQ_queue_t servicing; 210 + /* IDR[EP/CI] are only for FSL MPIC prior to v4.0 */ 211 + #define IDR_EP 0x80000000 /* external pin */ 212 + #define IDR_CI 0x40000000 /* critical interrupt */ 213 + 214 + typedef struct IRQDest { 215 + int32_t ctpr; /* CPU current task priority */ 216 + IRQQueue raised; 217 + IRQQueue servicing; 203 218 qemu_irq *irqs; 204 - } IRQ_dst_t; 219 + 220 + /* Count of IRQ sources asserting on non-INT outputs */ 221 + uint32_t outputs_active[OPENPIC_OUTPUT_NB]; 222 + } IRQDest; 205 223 206 224 typedef struct OpenPICState { 207 225 SysBusDevice busdev; ··· 212 230 uint32_t flags; 213 231 uint32_t nb_irqs; 214 232 uint32_t vid; 215 - uint32_t veni; /* Vendor identification register */ 216 - uint32_t spve_mask; 217 - uint32_t tifr_reset; 218 - uint32_t ipvp_reset; 219 - uint32_t ide_reset; 233 + uint32_t vir; /* Vendor identification register */ 234 + uint32_t vector_mask; 235 + uint32_t tfrr_reset; 236 + uint32_t ivpr_reset; 237 + uint32_t idr_reset; 220 238 uint32_t brr1; 239 + uint32_t mpic_mode_mask; 221 240 222 241 /* Sub-regions */ 223 242 MemoryRegion sub_io_mem[5]; 224 243 225 244 /* Global registers */ 226 - uint32_t frep; /* Feature reporting register */ 227 - uint32_t glbc; /* Global configuration register */ 228 - uint32_t pint; /* Processor initialization register */ 245 + uint32_t frr; /* Feature reporting register */ 246 + uint32_t gcr; /* Global configuration register */ 247 + uint32_t pir; /* Processor initialization register */ 229 248 uint32_t spve; /* Spurious vector register */ 230 - uint32_t tifr; /* Timer frequency reporting register */ 249 + uint32_t tfrr; /* Timer frequency reporting register */ 231 250 /* Source registers */ 232 - IRQ_src_t src[MAX_IRQ]; 251 + IRQSource src[MAX_IRQ]; 233 252 /* Local registers per output pin */ 234 - IRQ_dst_t dst[MAX_CPU]; 253 + IRQDest dst[MAX_CPU]; 235 254 uint32_t nb_cpus; 236 255 /* Timer registers */ 237 256 struct { 238 - uint32_t ticc; /* Global timer current count register */ 239 - uint32_t tibc; /* Global timer base count register */ 257 + uint32_t tccr; /* Global timer current count register */ 258 + uint32_t tbcr; /* Global timer base count register */ 240 259 } timers[MAX_TMR]; 241 260 /* Shared MSI registers */ 242 261 struct { ··· 248 267 uint32_t irq_msi; 249 268 } OpenPICState; 250 269 251 - static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src); 252 - 253 - static inline void IRQ_setbit(IRQ_queue_t *q, int n_IRQ) 270 + static inline void IRQ_setbit(IRQQueue *q, int n_IRQ) 254 271 { 255 - q->pending++; 256 - set_bit(q->queue, n_IRQ); 272 + set_bit(n_IRQ, q->queue); 257 273 } 258 274 259 - static inline void IRQ_resetbit(IRQ_queue_t *q, int n_IRQ) 275 + static inline void IRQ_resetbit(IRQQueue *q, int n_IRQ) 260 276 { 261 - q->pending--; 262 - reset_bit(q->queue, n_IRQ); 277 + clear_bit(n_IRQ, q->queue); 263 278 } 264 279 265 - static inline int IRQ_testbit(IRQ_queue_t *q, int n_IRQ) 280 + static inline int IRQ_testbit(IRQQueue *q, int n_IRQ) 266 281 { 267 - return test_bit(q->queue, n_IRQ); 282 + return test_bit(n_IRQ, q->queue); 268 283 } 269 284 270 - static void IRQ_check(OpenPICState *opp, IRQ_queue_t *q) 285 + static void IRQ_check(OpenPICState *opp, IRQQueue *q) 271 286 { 272 - int next, i; 273 - int priority; 287 + int irq = -1; 288 + int next = -1; 289 + int priority = -1; 274 290 275 - next = -1; 276 - priority = -1; 291 + for (;;) { 292 + irq = find_next_bit(q->queue, opp->max_irq, irq + 1); 293 + if (irq == opp->max_irq) { 294 + break; 295 + } 277 296 278 - if (!q->pending) { 279 - /* IRQ bitmap is empty */ 280 - goto out; 281 - } 297 + DPRINTF("IRQ_check: irq %d set ivpr_pr=%d pr=%d\n", 298 + irq, IVPR_PRIORITY(opp->src[irq].ivpr), priority); 282 299 283 - for (i = 0; i < opp->max_irq; i++) { 284 - if (IRQ_testbit(q, i)) { 285 - DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n", 286 - i, IPVP_PRIORITY(opp->src[i].ipvp), priority); 287 - if (IPVP_PRIORITY(opp->src[i].ipvp) > priority) { 288 - next = i; 289 - priority = IPVP_PRIORITY(opp->src[i].ipvp); 290 - } 300 + if (IVPR_PRIORITY(opp->src[irq].ivpr) > priority) { 301 + next = irq; 302 + priority = IVPR_PRIORITY(opp->src[irq].ivpr); 291 303 } 292 304 } 293 305 294 - out: 295 306 q->next = next; 296 307 q->priority = priority; 297 308 } 298 309 299 - static int IRQ_get_next(OpenPICState *opp, IRQ_queue_t *q) 310 + static int IRQ_get_next(OpenPICState *opp, IRQQueue *q) 300 311 { 301 - if (q->next == -1) { 302 - /* XXX: optimize */ 303 - IRQ_check(opp, q); 304 - } 312 + /* XXX: optimize */ 313 + IRQ_check(opp, q); 305 314 306 315 return q->next; 307 316 } 308 317 309 - static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ) 318 + static void IRQ_local_pipe(OpenPICState *opp, int n_CPU, int n_IRQ, 319 + bool active, bool was_active) 310 320 { 311 - IRQ_dst_t *dst; 312 - IRQ_src_t *src; 321 + IRQDest *dst; 322 + IRQSource *src; 313 323 int priority; 314 324 315 325 dst = &opp->dst[n_CPU]; 316 326 src = &opp->src[n_IRQ]; 317 - priority = IPVP_PRIORITY(src->ipvp); 318 - if (priority <= dst->pctp) { 319 - /* Too low priority */ 320 - DPRINTF("%s: IRQ %d has too low priority on CPU %d\n", 321 - __func__, n_IRQ, n_CPU); 327 + 328 + DPRINTF("%s: IRQ %d active %d was %d\n", 329 + __func__, n_IRQ, active, was_active); 330 + 331 + if (src->output != OPENPIC_OUTPUT_INT) { 332 + DPRINTF("%s: output %d irq %d active %d was %d count %d\n", 333 + __func__, src->output, n_IRQ, active, was_active, 334 + dst->outputs_active[src->output]); 335 + 336 + /* On Freescale MPIC, critical interrupts ignore priority, 337 + * IACK, EOI, etc. Before MPIC v4.1 they also ignore 338 + * masking. 339 + */ 340 + if (active) { 341 + if (!was_active && dst->outputs_active[src->output]++ == 0) { 342 + DPRINTF("%s: Raise OpenPIC output %d cpu %d irq %d\n", 343 + __func__, src->output, n_CPU, n_IRQ); 344 + qemu_irq_raise(dst->irqs[src->output]); 345 + } 346 + } else { 347 + if (was_active && --dst->outputs_active[src->output] == 0) { 348 + DPRINTF("%s: Lower OpenPIC output %d cpu %d irq %d\n", 349 + __func__, src->output, n_CPU, n_IRQ); 350 + qemu_irq_lower(dst->irqs[src->output]); 351 + } 352 + } 353 + 322 354 return; 323 355 } 324 - if (IRQ_testbit(&dst->raised, n_IRQ)) { 325 - /* Interrupt miss */ 326 - DPRINTF("%s: IRQ %d was missed on CPU %d\n", 327 - __func__, n_IRQ, n_CPU); 328 - return; 356 + 357 + priority = IVPR_PRIORITY(src->ivpr); 358 + 359 + /* Even if the interrupt doesn't have enough priority, 360 + * it is still raised, in case ctpr is lowered later. 361 + */ 362 + if (active) { 363 + IRQ_setbit(&dst->raised, n_IRQ); 364 + } else { 365 + IRQ_resetbit(&dst->raised, n_IRQ); 329 366 } 330 - src->ipvp |= IPVP_ACTIVITY_MASK; 331 - IRQ_setbit(&dst->raised, n_IRQ); 332 - if (priority < dst->raised.priority) { 333 - /* An higher priority IRQ is already raised */ 334 - DPRINTF("%s: IRQ %d is hidden by raised IRQ %d on CPU %d\n", 335 - __func__, n_IRQ, dst->raised.next, n_CPU); 336 - return; 367 + 368 + IRQ_check(opp, &dst->raised); 369 + 370 + if (active && priority <= dst->ctpr) { 371 + DPRINTF("%s: IRQ %d priority %d too low for ctpr %d on CPU %d\n", 372 + __func__, n_IRQ, priority, dst->ctpr, n_CPU); 373 + active = 0; 337 374 } 338 - IRQ_get_next(opp, &dst->raised); 339 - if (IRQ_get_next(opp, &dst->servicing) != -1 && 340 - priority <= dst->servicing.priority) { 341 - DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n", 342 - __func__, n_IRQ, dst->servicing.next, n_CPU); 343 - /* Already servicing a higher priority IRQ */ 344 - return; 375 + 376 + if (active) { 377 + if (IRQ_get_next(opp, &dst->servicing) >= 0 && 378 + priority <= dst->servicing.priority) { 379 + DPRINTF("%s: IRQ %d is hidden by servicing IRQ %d on CPU %d\n", 380 + __func__, n_IRQ, dst->servicing.next, n_CPU); 381 + } else { 382 + DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d/%d\n", 383 + __func__, n_CPU, n_IRQ, dst->raised.next); 384 + qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); 385 + } 386 + } else { 387 + IRQ_get_next(opp, &dst->servicing); 388 + if (dst->raised.priority > dst->ctpr && 389 + dst->raised.priority > dst->servicing.priority) { 390 + DPRINTF("%s: IRQ %d inactive, IRQ %d prio %d above %d/%d, CPU %d\n", 391 + __func__, n_IRQ, dst->raised.next, dst->raised.priority, 392 + dst->ctpr, dst->servicing.priority, n_CPU); 393 + /* IRQ line stays asserted */ 394 + } else { 395 + DPRINTF("%s: IRQ %d inactive, current prio %d/%d, CPU %d\n", 396 + __func__, n_IRQ, dst->ctpr, dst->servicing.priority, n_CPU); 397 + qemu_irq_lower(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); 398 + } 345 399 } 346 - DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ); 347 - openpic_irq_raise(opp, n_CPU, src); 348 400 } 349 401 350 402 /* update pic state because registers for n_IRQ have changed value */ 351 403 static void openpic_update_irq(OpenPICState *opp, int n_IRQ) 352 404 { 353 - IRQ_src_t *src; 405 + IRQSource *src; 406 + bool active, was_active; 354 407 int i; 355 408 356 409 src = &opp->src[n_IRQ]; 410 + active = src->pending; 357 411 358 - if (!src->pending) { 359 - /* no irq pending */ 360 - DPRINTF("%s: IRQ %d is not pending\n", __func__, n_IRQ); 361 - return; 362 - } 363 - if (src->ipvp & IPVP_MASK_MASK) { 412 + if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) { 364 413 /* Interrupt source is disabled */ 365 414 DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ); 366 - return; 415 + active = false; 367 416 } 368 - if (IPVP_PRIORITY(src->ipvp) == 0) { 369 - /* Priority set to zero */ 370 - DPRINTF("%s: IRQ %d has 0 priority\n", __func__, n_IRQ); 417 + 418 + was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK); 419 + 420 + /* 421 + * We don't have a similar check for already-active because 422 + * ctpr may have changed and we need to withdraw the interrupt. 423 + */ 424 + if (!active && !was_active) { 425 + DPRINTF("%s: IRQ %d is already inactive\n", __func__, n_IRQ); 371 426 return; 372 427 } 373 - if (src->ipvp & IPVP_ACTIVITY_MASK) { 374 - /* IRQ already active */ 375 - DPRINTF("%s: IRQ %d is already active\n", __func__, n_IRQ); 376 - return; 428 + 429 + if (active) { 430 + src->ivpr |= IVPR_ACTIVITY_MASK; 431 + } else { 432 + src->ivpr &= ~IVPR_ACTIVITY_MASK; 377 433 } 378 - if (src->ide == 0x00000000) { 434 + 435 + if (src->idr == 0) { 379 436 /* No target */ 380 437 DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ); 381 438 return; 382 439 } 383 440 384 - if (src->ide == (1 << src->last_cpu)) { 441 + if (src->idr == (1 << src->last_cpu)) { 385 442 /* Only one CPU is allowed to receive this IRQ */ 386 - IRQ_local_pipe(opp, src->last_cpu, n_IRQ); 387 - } else if (!(src->ipvp & IPVP_MODE_MASK)) { 443 + IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active); 444 + } else if (!(src->ivpr & IVPR_MODE_MASK)) { 388 445 /* Directed delivery mode */ 389 446 for (i = 0; i < opp->nb_cpus; i++) { 390 - if (src->ide & (1 << i)) { 391 - IRQ_local_pipe(opp, i, n_IRQ); 447 + if (src->destmask & (1 << i)) { 448 + IRQ_local_pipe(opp, i, n_IRQ, active, was_active); 392 449 } 393 450 } 394 451 } else { 395 452 /* Distributed delivery mode */ 396 453 for (i = src->last_cpu + 1; i != src->last_cpu; i++) { 397 - if (i == opp->nb_cpus) 454 + if (i == opp->nb_cpus) { 398 455 i = 0; 399 - if (src->ide & (1 << i)) { 400 - IRQ_local_pipe(opp, i, n_IRQ); 456 + } 457 + if (src->destmask & (1 << i)) { 458 + IRQ_local_pipe(opp, i, n_IRQ, active, was_active); 401 459 src->last_cpu = i; 402 460 break; 403 461 } ··· 408 466 static void openpic_set_irq(void *opaque, int n_IRQ, int level) 409 467 { 410 468 OpenPICState *opp = opaque; 411 - IRQ_src_t *src; 469 + IRQSource *src; 470 + 471 + if (n_IRQ >= MAX_IRQ) { 472 + fprintf(stderr, "%s: IRQ %d out of range\n", __func__, n_IRQ); 473 + abort(); 474 + } 412 475 413 476 src = &opp->src[n_IRQ]; 414 - DPRINTF("openpic: set irq %d = %d ipvp=%08x\n", 415 - n_IRQ, level, src->ipvp); 416 - if (src->ipvp & IPVP_SENSE_MASK) { 477 + DPRINTF("openpic: set irq %d = %d ivpr=0x%08x\n", 478 + n_IRQ, level, src->ivpr); 479 + if (src->level) { 417 480 /* level-sensitive irq */ 418 481 src->pending = level; 419 - if (!level) { 420 - src->ipvp &= ~IPVP_ACTIVITY_MASK; 421 - } 482 + openpic_update_irq(opp, n_IRQ); 422 483 } else { 423 484 /* edge-sensitive irq */ 424 - if (level) 485 + if (level) { 425 486 src->pending = 1; 487 + openpic_update_irq(opp, n_IRQ); 488 + } 489 + 490 + if (src->output != OPENPIC_OUTPUT_INT) { 491 + /* Edge-triggered interrupts shouldn't be used 492 + * with non-INT delivery, but just in case, 493 + * try to make it do something sane rather than 494 + * cause an interrupt storm. This is close to 495 + * what you'd probably see happen in real hardware. 496 + */ 497 + src->pending = 0; 498 + openpic_update_irq(opp, n_IRQ); 499 + } 426 500 } 427 - openpic_update_irq(opp, n_IRQ); 428 501 } 429 502 430 503 static void openpic_reset(DeviceState *d) ··· 432 505 OpenPICState *opp = FROM_SYSBUS(typeof (*opp), sysbus_from_qdev(d)); 433 506 int i; 434 507 435 - opp->glbc = 0x80000000; 508 + opp->gcr = GCR_RESET; 436 509 /* Initialise controller registers */ 437 - opp->frep = ((opp->nb_irqs -1) << FREP_NIRQ_SHIFT) | 438 - ((opp->nb_cpus -1) << FREP_NCPU_SHIFT) | 439 - (opp->vid << FREP_VID_SHIFT); 510 + opp->frr = ((opp->nb_irqs - 1) << FRR_NIRQ_SHIFT) | 511 + ((opp->nb_cpus - 1) << FRR_NCPU_SHIFT) | 512 + (opp->vid << FRR_VID_SHIFT); 440 513 441 - opp->pint = 0x00000000; 442 - opp->spve = -1 & opp->spve_mask; 443 - opp->tifr = opp->tifr_reset; 514 + opp->pir = 0; 515 + opp->spve = -1 & opp->vector_mask; 516 + opp->tfrr = opp->tfrr_reset; 444 517 /* Initialise IRQ sources */ 445 518 for (i = 0; i < opp->max_irq; i++) { 446 - opp->src[i].ipvp = opp->ipvp_reset; 447 - opp->src[i].ide = opp->ide_reset; 519 + opp->src[i].ivpr = opp->ivpr_reset; 520 + opp->src[i].idr = opp->idr_reset; 521 + 522 + switch (opp->src[i].type) { 523 + case IRQ_TYPE_NORMAL: 524 + opp->src[i].level = !!(opp->ivpr_reset & IVPR_SENSE_MASK); 525 + break; 526 + 527 + case IRQ_TYPE_FSLINT: 528 + opp->src[i].ivpr |= IVPR_POLARITY_MASK; 529 + break; 530 + 531 + case IRQ_TYPE_FSLSPECIAL: 532 + break; 533 + } 448 534 } 449 535 /* Initialise IRQ destinations */ 450 536 for (i = 0; i < MAX_CPU; i++) { 451 - opp->dst[i].pctp = 0x0000000F; 452 - opp->dst[i].pcsr = 0x00000000; 453 - memset(&opp->dst[i].raised, 0, sizeof(IRQ_queue_t)); 537 + opp->dst[i].ctpr = 15; 538 + memset(&opp->dst[i].raised, 0, sizeof(IRQQueue)); 454 539 opp->dst[i].raised.next = -1; 455 - memset(&opp->dst[i].servicing, 0, sizeof(IRQ_queue_t)); 540 + memset(&opp->dst[i].servicing, 0, sizeof(IRQQueue)); 456 541 opp->dst[i].servicing.next = -1; 457 542 } 458 543 /* Initialise timers */ 459 544 for (i = 0; i < MAX_TMR; i++) { 460 - opp->timers[i].ticc = 0x00000000; 461 - opp->timers[i].tibc = 0x80000000; 545 + opp->timers[i].tccr = 0; 546 + opp->timers[i].tbcr = TBCR_CI; 462 547 } 463 548 /* Go out of RESET state */ 464 - opp->glbc = 0x00000000; 549 + opp->gcr = 0; 465 550 } 466 551 467 - static inline uint32_t read_IRQreg_ide(OpenPICState *opp, int n_IRQ) 552 + static inline uint32_t read_IRQreg_idr(OpenPICState *opp, int n_IRQ) 468 553 { 469 - return opp->src[n_IRQ].ide; 554 + return opp->src[n_IRQ].idr; 470 555 } 471 556 472 - static inline uint32_t read_IRQreg_ipvp(OpenPICState *opp, int n_IRQ) 557 + static inline uint32_t read_IRQreg_ivpr(OpenPICState *opp, int n_IRQ) 473 558 { 474 - return opp->src[n_IRQ].ipvp; 559 + return opp->src[n_IRQ].ivpr; 475 560 } 476 561 477 - static inline void write_IRQreg_ide(OpenPICState *opp, int n_IRQ, uint32_t val) 562 + static inline void write_IRQreg_idr(OpenPICState *opp, int n_IRQ, uint32_t val) 478 563 { 479 - uint32_t tmp; 564 + IRQSource *src = &opp->src[n_IRQ]; 565 + uint32_t normal_mask = (1UL << opp->nb_cpus) - 1; 566 + uint32_t crit_mask = 0; 567 + uint32_t mask = normal_mask; 568 + int crit_shift = IDR_EP_SHIFT - opp->nb_cpus; 569 + int i; 480 570 481 - tmp = val & 0xC0000000; 482 - tmp |= val & ((1ULL << MAX_CPU) - 1); 483 - opp->src[n_IRQ].ide = tmp; 484 - DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide); 571 + if (opp->flags & OPENPIC_FLAG_IDR_CRIT) { 572 + crit_mask = mask << crit_shift; 573 + mask |= crit_mask | IDR_EP; 574 + } 575 + 576 + src->idr = val & mask; 577 + DPRINTF("Set IDR %d to 0x%08x\n", n_IRQ, src->idr); 578 + 579 + if (opp->flags & OPENPIC_FLAG_IDR_CRIT) { 580 + if (src->idr & crit_mask) { 581 + if (src->idr & normal_mask) { 582 + DPRINTF("%s: IRQ configured for multiple output types, using " 583 + "critical\n", __func__); 584 + } 585 + 586 + src->output = OPENPIC_OUTPUT_CINT; 587 + src->nomask = true; 588 + src->destmask = 0; 589 + 590 + for (i = 0; i < opp->nb_cpus; i++) { 591 + int n_ci = IDR_CI0_SHIFT - i; 592 + 593 + if (src->idr & (1UL << n_ci)) { 594 + src->destmask |= 1UL << i; 595 + } 596 + } 597 + } else { 598 + src->output = OPENPIC_OUTPUT_INT; 599 + src->nomask = false; 600 + src->destmask = src->idr & normal_mask; 601 + } 602 + } else { 603 + src->destmask = src->idr; 604 + } 485 605 } 486 606 487 - static inline void write_IRQreg_ipvp(OpenPICState *opp, int n_IRQ, uint32_t val) 607 + static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val) 488 608 { 489 - /* NOTE: not fully accurate for special IRQs, but simple and sufficient */ 609 + uint32_t mask; 610 + 611 + /* NOTE when implementing newer FSL MPIC models: starting with v4.0, 612 + * the polarity bit is read-only on internal interrupts. 613 + */ 614 + mask = IVPR_MASK_MASK | IVPR_PRIORITY_MASK | IVPR_SENSE_MASK | 615 + IVPR_POLARITY_MASK | opp->vector_mask; 616 + 490 617 /* ACTIVITY bit is read-only */ 491 - opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp & 0x40000000) 492 - | (val & 0x800F00FF); 618 + opp->src[n_IRQ].ivpr = 619 + (opp->src[n_IRQ].ivpr & IVPR_ACTIVITY_MASK) | (val & mask); 620 + 621 + /* For FSL internal interrupts, The sense bit is reserved and zero, 622 + * and the interrupt is always level-triggered. Timers and IPIs 623 + * have no sense or polarity bits, and are edge-triggered. 624 + */ 625 + switch (opp->src[n_IRQ].type) { 626 + case IRQ_TYPE_NORMAL: 627 + opp->src[n_IRQ].level = !!(opp->src[n_IRQ].ivpr & IVPR_SENSE_MASK); 628 + break; 629 + 630 + case IRQ_TYPE_FSLINT: 631 + opp->src[n_IRQ].ivpr &= ~IVPR_SENSE_MASK; 632 + break; 633 + 634 + case IRQ_TYPE_FSLSPECIAL: 635 + opp->src[n_IRQ].ivpr &= ~(IVPR_POLARITY_MASK | IVPR_SENSE_MASK); 636 + break; 637 + } 638 + 493 639 openpic_update_irq(opp, n_IRQ); 494 - DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ, val, 495 - opp->src[n_IRQ].ipvp); 640 + DPRINTF("Set IVPR %d to 0x%08x -> 0x%08x\n", n_IRQ, val, 641 + opp->src[n_IRQ].ivpr); 496 642 } 497 643 498 644 static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val, 499 645 unsigned len) 500 646 { 501 647 OpenPICState *opp = opaque; 502 - IRQ_dst_t *dst; 648 + IRQDest *dst; 503 649 int idx; 504 650 505 - DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val); 506 - if (addr & 0xF) 651 + DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n", 652 + __func__, addr, val); 653 + if (addr & 0xF) { 507 654 return; 655 + } 508 656 switch (addr) { 509 657 case 0x00: /* Block Revision Register1 (BRR1) is Readonly */ 510 658 break; ··· 518 666 case 0xB0: 519 667 openpic_cpu_write_internal(opp, addr, val, get_current_cpu()); 520 668 break; 521 - case 0x1000: /* FREP */ 669 + case 0x1000: /* FRR */ 522 670 break; 523 - case 0x1020: /* GLBC */ 524 - if (val & 0x80000000) { 671 + case 0x1020: /* GCR */ 672 + if (val & GCR_RESET) { 525 673 openpic_reset(&opp->busdev.qdev); 674 + } else if (opp->mpic_mode_mask) { 675 + CPUArchState *env; 676 + int mpic_proxy = 0; 677 + 678 + opp->gcr &= ~opp->mpic_mode_mask; 679 + opp->gcr |= val & opp->mpic_mode_mask; 680 + 681 + /* Set external proxy mode */ 682 + if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) { 683 + mpic_proxy = 1; 684 + } 685 + for (env = first_cpu; env != NULL; env = env->next_cpu) { 686 + env->mpic_proxy = mpic_proxy; 687 + } 526 688 } 527 689 break; 528 - case 0x1080: /* VENI */ 690 + case 0x1080: /* VIR */ 529 691 break; 530 - case 0x1090: /* PINT */ 692 + case 0x1090: /* PIR */ 531 693 for (idx = 0; idx < opp->nb_cpus; idx++) { 532 - if ((val & (1 << idx)) && !(opp->pint & (1 << idx))) { 694 + if ((val & (1 << idx)) && !(opp->pir & (1 << idx))) { 533 695 DPRINTF("Raise OpenPIC RESET output for CPU %d\n", idx); 534 696 dst = &opp->dst[idx]; 535 697 qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_RESET]); 536 - } else if (!(val & (1 << idx)) && (opp->pint & (1 << idx))) { 698 + } else if (!(val & (1 << idx)) && (opp->pir & (1 << idx))) { 537 699 DPRINTF("Lower OpenPIC RESET output for CPU %d\n", idx); 538 700 dst = &opp->dst[idx]; 539 701 qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_RESET]); 540 702 } 541 703 } 542 - opp->pint = val; 704 + opp->pir = val; 543 705 break; 544 - case 0x10A0: /* IPI_IPVP */ 706 + case 0x10A0: /* IPI_IVPR */ 545 707 case 0x10B0: 546 708 case 0x10C0: 547 709 case 0x10D0: 548 710 { 549 711 int idx; 550 712 idx = (addr - 0x10A0) >> 4; 551 - write_IRQreg_ipvp(opp, opp->irq_ipi0 + idx, val); 713 + write_IRQreg_ivpr(opp, opp->irq_ipi0 + idx, val); 552 714 } 553 715 break; 554 716 case 0x10E0: /* SPVE */ 555 - opp->spve = val & opp->spve_mask; 717 + opp->spve = val & opp->vector_mask; 556 718 break; 557 719 default: 558 720 break; ··· 564 726 OpenPICState *opp = opaque; 565 727 uint32_t retval; 566 728 567 - DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr); 729 + DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr); 568 730 retval = 0xFFFFFFFF; 569 - if (addr & 0xF) 731 + if (addr & 0xF) { 570 732 return retval; 733 + } 571 734 switch (addr) { 572 - case 0x1000: /* FREP */ 573 - retval = opp->frep; 735 + case 0x1000: /* FRR */ 736 + retval = opp->frr; 574 737 break; 575 - case 0x1020: /* GLBC */ 576 - retval = opp->glbc; 738 + case 0x1020: /* GCR */ 739 + retval = opp->gcr; 577 740 break; 578 - case 0x1080: /* VENI */ 579 - retval = opp->veni; 741 + case 0x1080: /* VIR */ 742 + retval = opp->vir; 580 743 break; 581 - case 0x1090: /* PINT */ 744 + case 0x1090: /* PIR */ 582 745 retval = 0x00000000; 583 746 break; 584 747 case 0x00: /* Block Revision Register1 (BRR1) */ 748 + retval = opp->brr1; 749 + break; 585 750 case 0x40: 586 751 case 0x50: 587 752 case 0x60: ··· 592 757 case 0xB0: 593 758 retval = openpic_cpu_read_internal(opp, addr, get_current_cpu()); 594 759 break; 595 - case 0x10A0: /* IPI_IPVP */ 760 + case 0x10A0: /* IPI_IVPR */ 596 761 case 0x10B0: 597 762 case 0x10C0: 598 763 case 0x10D0: 599 764 { 600 765 int idx; 601 766 idx = (addr - 0x10A0) >> 4; 602 - retval = read_IRQreg_ipvp(opp, opp->irq_ipi0 + idx); 767 + retval = read_IRQreg_ivpr(opp, opp->irq_ipi0 + idx); 603 768 } 604 769 break; 605 770 case 0x10E0: /* SPVE */ ··· 608 773 default: 609 774 break; 610 775 } 611 - DPRINTF("%s: => %08x\n", __func__, retval); 776 + DPRINTF("%s: => 0x%08x\n", __func__, retval); 612 777 613 778 return retval; 614 779 } ··· 619 784 OpenPICState *opp = opaque; 620 785 int idx; 621 786 622 - DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 623 - if (addr & 0xF) 787 + DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n", 788 + __func__, addr, val); 789 + if (addr & 0xF) { 624 790 return; 791 + } 625 792 idx = (addr >> 6) & 0x3; 626 793 addr = addr & 0x30; 627 794 628 795 if (addr == 0x0) { 629 - /* TIFR (TFRR) */ 630 - opp->tifr = val; 796 + /* TFRR */ 797 + opp->tfrr = val; 631 798 return; 632 799 } 633 800 switch (addr & 0x30) { 634 - case 0x00: /* TICC (GTCCR) */ 801 + case 0x00: /* TCCR */ 635 802 break; 636 - case 0x10: /* TIBC (GTBCR) */ 637 - if ((opp->timers[idx].ticc & 0x80000000) != 0 && 638 - (val & 0x80000000) == 0 && 639 - (opp->timers[idx].tibc & 0x80000000) != 0) 640 - opp->timers[idx].ticc &= ~0x80000000; 641 - opp->timers[idx].tibc = val; 803 + case 0x10: /* TBCR */ 804 + if ((opp->timers[idx].tccr & TCCR_TOG) != 0 && 805 + (val & TBCR_CI) == 0 && 806 + (opp->timers[idx].tbcr & TBCR_CI) != 0) { 807 + opp->timers[idx].tccr &= ~TCCR_TOG; 808 + } 809 + opp->timers[idx].tbcr = val; 642 810 break; 643 - case 0x20: /* TIVP (GTIVPR) */ 644 - write_IRQreg_ipvp(opp, opp->irq_tim0 + idx, val); 811 + case 0x20: /* TVPR */ 812 + write_IRQreg_ivpr(opp, opp->irq_tim0 + idx, val); 645 813 break; 646 - case 0x30: /* TIDE (GTIDR) */ 647 - write_IRQreg_ide(opp, opp->irq_tim0 + idx, val); 814 + case 0x30: /* TDR */ 815 + write_IRQreg_idr(opp, opp->irq_tim0 + idx, val); 648 816 break; 649 817 } 650 818 } ··· 655 823 uint32_t retval = -1; 656 824 int idx; 657 825 658 - DPRINTF("%s: addr %08x\n", __func__, addr); 826 + DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr); 659 827 if (addr & 0xF) { 660 828 goto out; 661 829 } 662 830 idx = (addr >> 6) & 0x3; 663 831 if (addr == 0x0) { 664 - /* TIFR (TFRR) */ 665 - retval = opp->tifr; 832 + /* TFRR */ 833 + retval = opp->tfrr; 666 834 goto out; 667 835 } 668 836 switch (addr & 0x30) { 669 - case 0x00: /* TICC (GTCCR) */ 670 - retval = opp->timers[idx].ticc; 837 + case 0x00: /* TCCR */ 838 + retval = opp->timers[idx].tccr; 671 839 break; 672 - case 0x10: /* TIBC (GTBCR) */ 673 - retval = opp->timers[idx].tibc; 840 + case 0x10: /* TBCR */ 841 + retval = opp->timers[idx].tbcr; 674 842 break; 675 - case 0x20: /* TIPV (TIPV) */ 676 - retval = read_IRQreg_ipvp(opp, opp->irq_tim0 + idx); 843 + case 0x20: /* TIPV */ 844 + retval = read_IRQreg_ivpr(opp, opp->irq_tim0 + idx); 677 845 break; 678 846 case 0x30: /* TIDE (TIDR) */ 679 - retval = read_IRQreg_ide(opp, opp->irq_tim0 + idx); 847 + retval = read_IRQreg_idr(opp, opp->irq_tim0 + idx); 680 848 break; 681 849 } 682 850 683 851 out: 684 - DPRINTF("%s: => %08x\n", __func__, retval); 852 + DPRINTF("%s: => 0x%08x\n", __func__, retval); 685 853 686 854 return retval; 687 855 } ··· 692 860 OpenPICState *opp = opaque; 693 861 int idx; 694 862 695 - DPRINTF("%s: addr %08x <= %08x\n", __func__, addr, val); 696 - if (addr & 0xF) 863 + DPRINTF("%s: addr %#" HWADDR_PRIx " <= %08" PRIx64 "\n", 864 + __func__, addr, val); 865 + if (addr & 0xF) { 697 866 return; 867 + } 698 868 addr = addr & 0xFFF0; 699 869 idx = addr >> 5; 700 870 if (addr & 0x10) { 701 871 /* EXDE / IFEDE / IEEDE */ 702 - write_IRQreg_ide(opp, idx, val); 872 + write_IRQreg_idr(opp, idx, val); 703 873 } else { 704 874 /* EXVP / IFEVP / IEEVP */ 705 - write_IRQreg_ipvp(opp, idx, val); 875 + write_IRQreg_ivpr(opp, idx, val); 706 876 } 707 877 } 708 878 ··· 712 882 uint32_t retval; 713 883 int idx; 714 884 715 - DPRINTF("%s: addr %08x\n", __func__, addr); 885 + DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr); 716 886 retval = 0xFFFFFFFF; 717 - if (addr & 0xF) 887 + if (addr & 0xF) { 718 888 return retval; 889 + } 719 890 addr = addr & 0xFFF0; 720 891 idx = addr >> 5; 721 892 if (addr & 0x10) { 722 893 /* EXDE / IFEDE / IEEDE */ 723 - retval = read_IRQreg_ide(opp, idx); 894 + retval = read_IRQreg_idr(opp, idx); 724 895 } else { 725 896 /* EXVP / IFEVP / IEEVP */ 726 - retval = read_IRQreg_ipvp(opp, idx); 897 + retval = read_IRQreg_ivpr(opp, idx); 727 898 } 728 - DPRINTF("%s: => %08x\n", __func__, retval); 899 + DPRINTF("%s: => 0x%08x\n", __func__, retval); 729 900 730 901 return retval; 731 902 } ··· 737 908 int idx = opp->irq_msi; 738 909 int srs, ibs; 739 910 740 - DPRINTF("%s: addr " TARGET_FMT_plx " <= %08x\n", __func__, addr, val); 911 + DPRINTF("%s: addr %#" HWADDR_PRIx " <= 0x%08" PRIx64 "\n", 912 + __func__, addr, val); 741 913 if (addr & 0xF) { 742 914 return; 743 915 } ··· 762 934 uint64_t r = 0; 763 935 int i, srs; 764 936 765 - DPRINTF("%s: addr " TARGET_FMT_plx "\n", __func__, addr); 937 + DPRINTF("%s: addr %#" HWADDR_PRIx "\n", __func__, addr); 766 938 if (addr & 0xF) { 767 939 return -1; 768 940 } ··· 781 953 r = opp->msi[srs].msir; 782 954 /* Clear on read */ 783 955 opp->msi[srs].msir = 0; 956 + openpic_set_irq(opp, opp->irq_msi + srs, 0); 784 957 break; 785 958 case 0x120: /* MSISR */ 786 959 for (i = 0; i < MAX_MSI; i++) { ··· 796 969 uint32_t val, int idx) 797 970 { 798 971 OpenPICState *opp = opaque; 799 - IRQ_src_t *src; 800 - IRQ_dst_t *dst; 972 + IRQSource *src; 973 + IRQDest *dst; 801 974 int s_IRQ, n_IRQ; 802 975 803 - DPRINTF("%s: cpu %d addr " TARGET_FMT_plx " <= %08x\n", __func__, idx, 976 + DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx " <= 0x%08x\n", __func__, idx, 804 977 addr, val); 805 - if (addr & 0xF) 978 + 979 + if (idx < 0) { 806 980 return; 981 + } 982 + 983 + if (addr & 0xF) { 984 + return; 985 + } 807 986 dst = &opp->dst[idx]; 808 987 addr &= 0xFF0; 809 988 switch (addr) { ··· 813 992 case 0x70: 814 993 idx = (addr - 0x40) >> 4; 815 994 /* we use IDE as mask which CPUs to deliver the IPI to still. */ 816 - write_IRQreg_ide(opp, opp->irq_ipi0 + idx, 817 - opp->src[opp->irq_ipi0 + idx].ide | val); 995 + write_IRQreg_idr(opp, opp->irq_ipi0 + idx, 996 + opp->src[opp->irq_ipi0 + idx].idr | val); 818 997 openpic_set_irq(opp, opp->irq_ipi0 + idx, 1); 819 998 openpic_set_irq(opp, opp->irq_ipi0 + idx, 0); 820 999 break; 821 - case 0x80: /* PCTP */ 822 - dst->pctp = val & 0x0000000F; 1000 + case 0x80: /* CTPR */ 1001 + dst->ctpr = val & 0x0000000F; 1002 + 1003 + DPRINTF("%s: set CPU %d ctpr to %d, raised %d servicing %d\n", 1004 + __func__, idx, dst->ctpr, dst->raised.priority, 1005 + dst->servicing.priority); 1006 + 1007 + if (dst->raised.priority <= dst->ctpr) { 1008 + DPRINTF("%s: Lower OpenPIC INT output cpu %d due to ctpr\n", 1009 + __func__, idx); 1010 + qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); 1011 + } else if (dst->raised.priority > dst->servicing.priority) { 1012 + DPRINTF("%s: Raise OpenPIC INT output cpu %d irq %d\n", 1013 + __func__, idx, dst->raised.next); 1014 + qemu_irq_raise(dst->irqs[OPENPIC_OUTPUT_INT]); 1015 + } 1016 + 823 1017 break; 824 1018 case 0x90: /* WHOAMI */ 825 1019 /* Read-only register */ 826 1020 break; 827 - case 0xA0: /* PIAC */ 1021 + case 0xA0: /* IACK */ 828 1022 /* Read-only register */ 829 1023 break; 830 - case 0xB0: /* PEOI */ 831 - DPRINTF("PEOI\n"); 1024 + case 0xB0: /* EOI */ 1025 + DPRINTF("EOI\n"); 832 1026 s_IRQ = IRQ_get_next(opp, &dst->servicing); 1027 + 1028 + if (s_IRQ < 0) { 1029 + DPRINTF("%s: EOI with no interrupt in service\n", __func__); 1030 + break; 1031 + } 1032 + 833 1033 IRQ_resetbit(&dst->servicing, s_IRQ); 834 - dst->servicing.next = -1; 835 1034 /* Set up next servicing IRQ */ 836 1035 s_IRQ = IRQ_get_next(opp, &dst->servicing); 837 1036 /* Check queued interrupts. */ ··· 839 1038 src = &opp->src[n_IRQ]; 840 1039 if (n_IRQ != -1 && 841 1040 (s_IRQ == -1 || 842 - IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) { 1041 + IVPR_PRIORITY(src->ivpr) > dst->servicing.priority)) { 843 1042 DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", 844 1043 idx, n_IRQ); 845 - openpic_irq_raise(opp, idx, src); 1044 + qemu_irq_raise(opp->dst[idx].irqs[OPENPIC_OUTPUT_INT]); 846 1045 } 847 1046 break; 848 1047 default: ··· 856 1055 openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12); 857 1056 } 858 1057 1058 + 1059 + static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) 1060 + { 1061 + IRQSource *src; 1062 + int retval, irq; 1063 + 1064 + DPRINTF("Lower OpenPIC INT output\n"); 1065 + qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); 1066 + 1067 + irq = IRQ_get_next(opp, &dst->raised); 1068 + DPRINTF("IACK: irq=%d\n", irq); 1069 + 1070 + if (irq == -1) { 1071 + /* No more interrupt pending */ 1072 + return opp->spve; 1073 + } 1074 + 1075 + src = &opp->src[irq]; 1076 + if (!(src->ivpr & IVPR_ACTIVITY_MASK) || 1077 + !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) { 1078 + fprintf(stderr, "%s: bad raised IRQ %d ctpr %d ivpr 0x%08x\n", 1079 + __func__, irq, dst->ctpr, src->ivpr); 1080 + openpic_update_irq(opp, irq); 1081 + retval = opp->spve; 1082 + } else { 1083 + /* IRQ enter servicing state */ 1084 + IRQ_setbit(&dst->servicing, irq); 1085 + retval = IVPR_VECTOR(opp, src->ivpr); 1086 + } 1087 + 1088 + if (!src->level) { 1089 + /* edge-sensitive IRQ */ 1090 + src->ivpr &= ~IVPR_ACTIVITY_MASK; 1091 + src->pending = 0; 1092 + IRQ_resetbit(&dst->raised, irq); 1093 + } 1094 + 1095 + if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + MAX_IPI))) { 1096 + src->idr &= ~(1 << cpu); 1097 + if (src->idr && !src->level) { 1098 + /* trigger on CPUs that didn't know about it yet */ 1099 + openpic_set_irq(opp, irq, 1); 1100 + openpic_set_irq(opp, irq, 0); 1101 + /* if all CPUs knew about it, set active bit again */ 1102 + src->ivpr |= IVPR_ACTIVITY_MASK; 1103 + } 1104 + } 1105 + 1106 + return retval; 1107 + } 1108 + 859 1109 static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, 860 1110 int idx) 861 1111 { 862 1112 OpenPICState *opp = opaque; 863 - IRQ_src_t *src; 864 - IRQ_dst_t *dst; 1113 + IRQDest *dst; 865 1114 uint32_t retval; 866 - int n_IRQ; 867 1115 868 - DPRINTF("%s: cpu %d addr " TARGET_FMT_plx "\n", __func__, idx, addr); 1116 + DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr); 869 1117 retval = 0xFFFFFFFF; 870 - if (addr & 0xF) 1118 + 1119 + if (idx < 0) { 871 1120 return retval; 1121 + } 1122 + 1123 + if (addr & 0xF) { 1124 + return retval; 1125 + } 872 1126 dst = &opp->dst[idx]; 873 1127 addr &= 0xFF0; 874 1128 switch (addr) { 875 - case 0x00: /* Block Revision Register1 (BRR1) */ 876 - retval = opp->brr1; 877 - break; 878 - case 0x80: /* PCTP */ 879 - retval = dst->pctp; 1129 + case 0x80: /* CTPR */ 1130 + retval = dst->ctpr; 880 1131 break; 881 1132 case 0x90: /* WHOAMI */ 882 1133 retval = idx; 883 1134 break; 884 - case 0xA0: /* PIAC */ 885 - DPRINTF("Lower OpenPIC INT output\n"); 886 - qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); 887 - n_IRQ = IRQ_get_next(opp, &dst->raised); 888 - DPRINTF("PIAC: irq=%d\n", n_IRQ); 889 - if (n_IRQ == -1) { 890 - /* No more interrupt pending */ 891 - retval = IPVP_VECTOR(opp->spve); 892 - } else { 893 - src = &opp->src[n_IRQ]; 894 - if (!(src->ipvp & IPVP_ACTIVITY_MASK) || 895 - !(IPVP_PRIORITY(src->ipvp) > dst->pctp)) { 896 - /* - Spurious level-sensitive IRQ 897 - * - Priorities has been changed 898 - * and the pending IRQ isn't allowed anymore 899 - */ 900 - src->ipvp &= ~IPVP_ACTIVITY_MASK; 901 - retval = IPVP_VECTOR(opp->spve); 902 - } else { 903 - /* IRQ enter servicing state */ 904 - IRQ_setbit(&dst->servicing, n_IRQ); 905 - retval = IPVP_VECTOR(src->ipvp); 906 - } 907 - IRQ_resetbit(&dst->raised, n_IRQ); 908 - dst->raised.next = -1; 909 - if (!(src->ipvp & IPVP_SENSE_MASK)) { 910 - /* edge-sensitive IRQ */ 911 - src->ipvp &= ~IPVP_ACTIVITY_MASK; 912 - src->pending = 0; 913 - } 914 - 915 - if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) { 916 - src->ide &= ~(1 << idx); 917 - if (src->ide && !(src->ipvp & IPVP_SENSE_MASK)) { 918 - /* trigger on CPUs that didn't know about it yet */ 919 - openpic_set_irq(opp, n_IRQ, 1); 920 - openpic_set_irq(opp, n_IRQ, 0); 921 - /* if all CPUs knew about it, set active bit again */ 922 - src->ipvp |= IPVP_ACTIVITY_MASK; 923 - } 924 - } 925 - } 1135 + case 0xA0: /* IACK */ 1136 + retval = openpic_iack(opp, dst, idx); 926 1137 break; 927 - case 0xB0: /* PEOI */ 1138 + case 0xB0: /* EOI */ 928 1139 retval = 0; 929 1140 break; 930 1141 default: 931 1142 break; 932 1143 } 933 - DPRINTF("%s: => %08x\n", __func__, retval); 1144 + DPRINTF("%s: => 0x%08x\n", __func__, retval); 934 1145 935 1146 return retval; 936 1147 } ··· 1040 1251 }, 1041 1252 }; 1042 1253 1043 - static void openpic_save_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) 1254 + static void openpic_save_IRQ_queue(QEMUFile* f, IRQQueue *q) 1044 1255 { 1045 1256 unsigned int i; 1046 1257 1047 - for (i = 0; i < BF_WIDTH(MAX_IRQ); i++) 1048 - qemu_put_be32s(f, &q->queue[i]); 1258 + for (i = 0; i < ARRAY_SIZE(q->queue); i++) { 1259 + /* Always put the lower half of a 64-bit long first, in case we 1260 + * restore on a 32-bit host. The least significant bits correspond 1261 + * to lower IRQ numbers in the bitmap. 1262 + */ 1263 + qemu_put_be32(f, (uint32_t)q->queue[i]); 1264 + #if LONG_MAX > 0x7FFFFFFF 1265 + qemu_put_be32(f, (uint32_t)(q->queue[i] >> 32)); 1266 + #endif 1267 + } 1049 1268 1050 1269 qemu_put_sbe32s(f, &q->next); 1051 1270 qemu_put_sbe32s(f, &q->priority); ··· 1056 1275 OpenPICState *opp = (OpenPICState *)opaque; 1057 1276 unsigned int i; 1058 1277 1059 - qemu_put_be32s(f, &opp->glbc); 1060 - qemu_put_be32s(f, &opp->veni); 1061 - qemu_put_be32s(f, &opp->pint); 1278 + qemu_put_be32s(f, &opp->gcr); 1279 + qemu_put_be32s(f, &opp->vir); 1280 + qemu_put_be32s(f, &opp->pir); 1062 1281 qemu_put_be32s(f, &opp->spve); 1063 - qemu_put_be32s(f, &opp->tifr); 1064 - 1065 - for (i = 0; i < opp->max_irq; i++) { 1066 - qemu_put_be32s(f, &opp->src[i].ipvp); 1067 - qemu_put_be32s(f, &opp->src[i].ide); 1068 - qemu_put_sbe32s(f, &opp->src[i].last_cpu); 1069 - qemu_put_sbe32s(f, &opp->src[i].pending); 1070 - } 1282 + qemu_put_be32s(f, &opp->tfrr); 1071 1283 1072 1284 qemu_put_be32s(f, &opp->nb_cpus); 1073 1285 1074 1286 for (i = 0; i < opp->nb_cpus; i++) { 1075 - qemu_put_be32s(f, &opp->dst[i].pctp); 1076 - qemu_put_be32s(f, &opp->dst[i].pcsr); 1287 + qemu_put_sbe32s(f, &opp->dst[i].ctpr); 1077 1288 openpic_save_IRQ_queue(f, &opp->dst[i].raised); 1078 1289 openpic_save_IRQ_queue(f, &opp->dst[i].servicing); 1290 + qemu_put_buffer(f, (uint8_t *)&opp->dst[i].outputs_active, 1291 + sizeof(opp->dst[i].outputs_active)); 1079 1292 } 1080 1293 1081 1294 for (i = 0; i < MAX_TMR; i++) { 1082 - qemu_put_be32s(f, &opp->timers[i].ticc); 1083 - qemu_put_be32s(f, &opp->timers[i].tibc); 1295 + qemu_put_be32s(f, &opp->timers[i].tccr); 1296 + qemu_put_be32s(f, &opp->timers[i].tbcr); 1297 + } 1298 + 1299 + for (i = 0; i < opp->max_irq; i++) { 1300 + qemu_put_be32s(f, &opp->src[i].ivpr); 1301 + qemu_put_be32s(f, &opp->src[i].idr); 1302 + qemu_put_sbe32s(f, &opp->src[i].last_cpu); 1303 + qemu_put_sbe32s(f, &opp->src[i].pending); 1084 1304 } 1085 1305 } 1086 1306 1087 - static void openpic_load_IRQ_queue(QEMUFile* f, IRQ_queue_t *q) 1307 + static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q) 1088 1308 { 1089 1309 unsigned int i; 1090 1310 1091 - for (i = 0; i < BF_WIDTH(MAX_IRQ); i++) 1092 - qemu_get_be32s(f, &q->queue[i]); 1311 + for (i = 0; i < ARRAY_SIZE(q->queue); i++) { 1312 + unsigned long val; 1313 + 1314 + val = qemu_get_be32(f); 1315 + #if LONG_MAX > 0x7FFFFFFF 1316 + val <<= 32; 1317 + val |= qemu_get_be32(f); 1318 + #endif 1319 + 1320 + q->queue[i] = val; 1321 + } 1093 1322 1094 1323 qemu_get_sbe32s(f, &q->next); 1095 1324 qemu_get_sbe32s(f, &q->priority); ··· 1100 1329 OpenPICState *opp = (OpenPICState *)opaque; 1101 1330 unsigned int i; 1102 1331 1103 - if (version_id != 1) 1332 + if (version_id != 1) { 1104 1333 return -EINVAL; 1334 + } 1105 1335 1106 - qemu_get_be32s(f, &opp->glbc); 1107 - qemu_get_be32s(f, &opp->veni); 1108 - qemu_get_be32s(f, &opp->pint); 1336 + qemu_get_be32s(f, &opp->gcr); 1337 + qemu_get_be32s(f, &opp->vir); 1338 + qemu_get_be32s(f, &opp->pir); 1109 1339 qemu_get_be32s(f, &opp->spve); 1110 - qemu_get_be32s(f, &opp->tifr); 1111 - 1112 - for (i = 0; i < opp->max_irq; i++) { 1113 - qemu_get_be32s(f, &opp->src[i].ipvp); 1114 - qemu_get_be32s(f, &opp->src[i].ide); 1115 - qemu_get_sbe32s(f, &opp->src[i].last_cpu); 1116 - qemu_get_sbe32s(f, &opp->src[i].pending); 1117 - } 1340 + qemu_get_be32s(f, &opp->tfrr); 1118 1341 1119 1342 qemu_get_be32s(f, &opp->nb_cpus); 1120 1343 1121 1344 for (i = 0; i < opp->nb_cpus; i++) { 1122 - qemu_get_be32s(f, &opp->dst[i].pctp); 1123 - qemu_get_be32s(f, &opp->dst[i].pcsr); 1345 + qemu_get_sbe32s(f, &opp->dst[i].ctpr); 1124 1346 openpic_load_IRQ_queue(f, &opp->dst[i].raised); 1125 1347 openpic_load_IRQ_queue(f, &opp->dst[i].servicing); 1348 + qemu_get_buffer(f, (uint8_t *)&opp->dst[i].outputs_active, 1349 + sizeof(opp->dst[i].outputs_active)); 1126 1350 } 1127 1351 1128 1352 for (i = 0; i < MAX_TMR; i++) { 1129 - qemu_get_be32s(f, &opp->timers[i].ticc); 1130 - qemu_get_be32s(f, &opp->timers[i].tibc); 1353 + qemu_get_be32s(f, &opp->timers[i].tccr); 1354 + qemu_get_be32s(f, &opp->timers[i].tbcr); 1131 1355 } 1132 1356 1133 - return 0; 1134 - } 1357 + for (i = 0; i < opp->max_irq; i++) { 1358 + uint32_t val; 1135 1359 1136 - static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src) 1137 - { 1138 - int n_ci = IDR_CI0_SHIFT - n_CPU; 1360 + val = qemu_get_be32(f); 1361 + write_IRQreg_idr(opp, i, val); 1362 + val = qemu_get_be32(f); 1363 + write_IRQreg_ivpr(opp, i, val); 1139 1364 1140 - if ((opp->flags & OPENPIC_FLAG_IDE_CRIT) && (src->ide & (1 << n_ci))) { 1141 - qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]); 1142 - } else { 1143 - qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); 1365 + qemu_get_be32s(f, &opp->src[i].ivpr); 1366 + qemu_get_be32s(f, &opp->src[i].idr); 1367 + qemu_get_sbe32s(f, &opp->src[i].last_cpu); 1368 + qemu_get_sbe32s(f, &opp->src[i].pending); 1144 1369 } 1370 + 1371 + return 0; 1145 1372 } 1146 1373 1147 - struct memreg { 1374 + typedef struct MemReg { 1148 1375 const char *name; 1149 1376 MemoryRegionOps const *ops; 1150 1377 bool map; 1151 1378 hwaddr start_addr; 1152 1379 ram_addr_t size; 1153 - }; 1380 + } MemReg; 1154 1381 1155 1382 static int openpic_init(SysBusDevice *dev) 1156 1383 { 1157 1384 OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev); 1158 1385 int i, j; 1159 - struct memreg list_le[] = { 1386 + MemReg list_le[] = { 1160 1387 {"glb", &openpic_glb_ops_le, true, 1161 1388 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE}, 1162 1389 {"tmr", &openpic_tmr_ops_le, true, ··· 1168 1395 {"cpu", &openpic_cpu_ops_le, true, 1169 1396 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, 1170 1397 }; 1171 - struct memreg list_be[] = { 1398 + MemReg list_be[] = { 1172 1399 {"glb", &openpic_glb_ops_be, true, 1173 1400 OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE}, 1174 1401 {"tmr", &openpic_tmr_ops_be, true, ··· 1180 1407 {"cpu", &openpic_cpu_ops_be, true, 1181 1408 OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE}, 1182 1409 }; 1183 - struct memreg *list; 1410 + MemReg *list; 1184 1411 1185 1412 switch (opp->model) { 1186 1413 case OPENPIC_MODEL_FSL_MPIC_20: 1187 1414 default: 1188 - opp->flags |= OPENPIC_FLAG_IDE_CRIT; 1415 + opp->flags |= OPENPIC_FLAG_IDR_CRIT; 1189 1416 opp->nb_irqs = 80; 1190 1417 opp->vid = VID_REVISION_1_2; 1191 - opp->veni = VENI_GENERIC; 1192 - opp->spve_mask = 0xFFFF; 1193 - opp->tifr_reset = 0x00000000; 1194 - opp->ipvp_reset = 0x80000000; 1195 - opp->ide_reset = 0x00000001; 1418 + opp->vir = VIR_GENERIC; 1419 + opp->vector_mask = 0xFFFF; 1420 + opp->tfrr_reset = 0; 1421 + opp->ivpr_reset = IVPR_MASK_MASK; 1422 + opp->idr_reset = 1 << 0; 1196 1423 opp->max_irq = FSL_MPIC_20_MAX_IRQ; 1197 1424 opp->irq_ipi0 = FSL_MPIC_20_IPI_IRQ; 1198 1425 opp->irq_tim0 = FSL_MPIC_20_TMR_IRQ; 1199 1426 opp->irq_msi = FSL_MPIC_20_MSI_IRQ; 1200 1427 opp->brr1 = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN; 1428 + /* XXX really only available as of MPIC 4.0 */ 1429 + opp->mpic_mode_mask = GCR_MODE_PROXY; 1430 + 1201 1431 msi_supported = true; 1202 1432 list = list_be; 1433 + 1434 + for (i = 0; i < FSL_MPIC_20_MAX_EXT; i++) { 1435 + opp->src[i].level = false; 1436 + } 1437 + 1438 + /* Internal interrupts, including message and MSI */ 1439 + for (i = 16; i < MAX_SRC; i++) { 1440 + opp->src[i].type = IRQ_TYPE_FSLINT; 1441 + opp->src[i].level = true; 1442 + } 1443 + 1444 + /* timers and IPIs */ 1445 + for (i = MAX_SRC; i < MAX_IRQ; i++) { 1446 + opp->src[i].type = IRQ_TYPE_FSLSPECIAL; 1447 + opp->src[i].level = false; 1448 + } 1449 + 1203 1450 break; 1451 + 1204 1452 case OPENPIC_MODEL_RAVEN: 1205 1453 opp->nb_irqs = RAVEN_MAX_EXT; 1206 1454 opp->vid = VID_REVISION_1_3; 1207 - opp->veni = VENI_GENERIC; 1208 - opp->spve_mask = 0xFF; 1209 - opp->tifr_reset = 0x003F7A00; 1210 - opp->ipvp_reset = 0xA0000000; 1211 - opp->ide_reset = 0x00000000; 1455 + opp->vir = VIR_GENERIC; 1456 + opp->vector_mask = 0xFF; 1457 + opp->tfrr_reset = 4160000; 1458 + opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK; 1459 + opp->idr_reset = 0; 1212 1460 opp->max_irq = RAVEN_MAX_IRQ; 1213 1461 opp->irq_ipi0 = RAVEN_IPI_IRQ; 1214 1462 opp->irq_tim0 = RAVEN_TMR_IRQ;
+6 -2
hw/ppc/e500.c
··· 225 225 kvmppc_get_hypercall(env, hypercall, sizeof(hypercall)); 226 226 qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions", 227 227 hypercall, sizeof(hypercall)); 228 + /* if KVM supports the idle hcall, set property indicating this */ 229 + if (kvmppc_get_hasidle(env)) { 230 + qemu_devtree_setprop(fdt, "/hypervisor", "has-idle", NULL, 0); 231 + } 228 232 } 229 233 230 234 /* Create CPU nodes */ ··· 493 497 irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; 494 498 irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; 495 499 env->spr[SPR_BOOKE_PIR] = env->cpu_index = i; 496 - env->mpic_cpu_base = MPC8544_CCSRBAR_BASE + 497 - MPC8544_MPIC_REGS_OFFSET + 0x20000; 500 + env->mpic_iack = MPC8544_CCSRBAR_BASE + 501 + MPC8544_MPIC_REGS_OFFSET + 0x200A0; 498 502 499 503 ppc_booke_timers_init(cpu, 400000000, PPC_TIMER_E500); 500 504
+13
hw/ppc_booke.c
··· 237 237 238 238 } 239 239 240 + static void ppc_booke_timer_reset_handle(void *opaque) 241 + { 242 + PowerPCCPU *cpu = opaque; 243 + CPUPPCState *env = &cpu->env; 244 + 245 + env->spr[SPR_BOOKE_TSR] = 0; 246 + env->spr[SPR_BOOKE_TCR] = 0; 247 + 248 + booke_update_irq(cpu); 249 + } 250 + 240 251 void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags) 241 252 { 242 253 ppc_tb_t *tb_env; ··· 257 268 qemu_new_timer_ns(vm_clock, &booke_fit_cb, cpu); 258 269 booke_timer->wdt_timer = 259 270 qemu_new_timer_ns(vm_clock, &booke_wdt_cb, cpu); 271 + 272 + qemu_register_reset(ppc_booke_timer_reset_handle, cpu); 260 273 }
+98
linux-headers/asm-powerpc/epapr_hcalls.h
··· 1 + /* 2 + * ePAPR hcall interface 3 + * 4 + * Copyright 2008-2011 Freescale Semiconductor, Inc. 5 + * 6 + * Author: Timur Tabi <timur@freescale.com> 7 + * 8 + * This file is provided under a dual BSD/GPL license. When using or 9 + * redistributing this file, you may do so under either license. 10 + * 11 + * Redistribution and use in source and binary forms, with or without 12 + * modification, are permitted provided that the following conditions are met: 13 + * * Redistributions of source code must retain the above copyright 14 + * notice, this list of conditions and the following disclaimer. 15 + * * Redistributions in binary form must reproduce the above copyright 16 + * notice, this list of conditions and the following disclaimer in the 17 + * documentation and/or other materials provided with the distribution. 18 + * * Neither the name of Freescale Semiconductor nor the 19 + * names of its contributors may be used to endorse or promote products 20 + * derived from this software without specific prior written permission. 21 + * 22 + * 23 + * ALTERNATIVELY, this software may be distributed under the terms of the 24 + * GNU General Public License ("GPL") as published by the Free Software 25 + * Foundation, either version 2 of that License or (at your option) any 26 + * later version. 27 + * 28 + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 29 + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 30 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 31 + * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 32 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 33 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 34 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 35 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 + */ 39 + 40 + #ifndef _ASM_POWERPC_EPAPR_HCALLS_H 41 + #define _ASM_POWERPC_EPAPR_HCALLS_H 42 + 43 + #define EV_BYTE_CHANNEL_SEND 1 44 + #define EV_BYTE_CHANNEL_RECEIVE 2 45 + #define EV_BYTE_CHANNEL_POLL 3 46 + #define EV_INT_SET_CONFIG 4 47 + #define EV_INT_GET_CONFIG 5 48 + #define EV_INT_SET_MASK 6 49 + #define EV_INT_GET_MASK 7 50 + #define EV_INT_IACK 9 51 + #define EV_INT_EOI 10 52 + #define EV_INT_SEND_IPI 11 53 + #define EV_INT_SET_TASK_PRIORITY 12 54 + #define EV_INT_GET_TASK_PRIORITY 13 55 + #define EV_DOORBELL_SEND 14 56 + #define EV_MSGSND 15 57 + #define EV_IDLE 16 58 + 59 + /* vendor ID: epapr */ 60 + #define EV_LOCAL_VENDOR_ID 0 /* for private use */ 61 + #define EV_EPAPR_VENDOR_ID 1 62 + #define EV_FSL_VENDOR_ID 2 /* Freescale Semiconductor */ 63 + #define EV_IBM_VENDOR_ID 3 /* IBM */ 64 + #define EV_GHS_VENDOR_ID 4 /* Green Hills Software */ 65 + #define EV_ENEA_VENDOR_ID 5 /* Enea */ 66 + #define EV_WR_VENDOR_ID 6 /* Wind River Systems */ 67 + #define EV_AMCC_VENDOR_ID 7 /* Applied Micro Circuits */ 68 + #define EV_KVM_VENDOR_ID 42 /* KVM */ 69 + 70 + /* The max number of bytes that a byte channel can send or receive per call */ 71 + #define EV_BYTE_CHANNEL_MAX_BYTES 16 72 + 73 + 74 + #define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num)) 75 + #define EV_HCALL_TOKEN(hcall_num) _EV_HCALL_TOKEN(EV_EPAPR_VENDOR_ID, hcall_num) 76 + 77 + /* epapr return codes */ 78 + #define EV_SUCCESS 0 79 + #define EV_EPERM 1 /* Operation not permitted */ 80 + #define EV_ENOENT 2 /* Entry Not Found */ 81 + #define EV_EIO 3 /* I/O error occured */ 82 + #define EV_EAGAIN 4 /* The operation had insufficient 83 + * resources to complete and should be 84 + * retried 85 + */ 86 + #define EV_ENOMEM 5 /* There was insufficient memory to 87 + * complete the operation */ 88 + #define EV_EFAULT 6 /* Bad guest address */ 89 + #define EV_ENODEV 7 /* No such device */ 90 + #define EV_EINVAL 8 /* An argument supplied to the hcall 91 + was out of range or invalid */ 92 + #define EV_INTERNAL 9 /* An internal error occured */ 93 + #define EV_CONFIG 10 /* A configuration error was detected */ 94 + #define EV_INVALID_STATE 11 /* The object is in an invalid state */ 95 + #define EV_UNIMPLEMENTED 12 /* Unimplemented hypercall */ 96 + #define EV_BUFFER_OVERFLOW 13 /* Caller-supplied buffer too small */ 97 + 98 + #endif /* _ASM_POWERPC_EPAPR_HCALLS_H */
+86
linux-headers/asm-powerpc/kvm.h
··· 221 221 222 222 __u32 dbsr; /* KVM_SREGS_E_UPDATE_DBSR */ 223 223 __u32 dbcr[3]; 224 + /* 225 + * iac/dac registers are 64bit wide, while this API 226 + * interface provides only lower 32 bits on 64 bit 227 + * processors. ONE_REG interface is added for 64bit 228 + * iac/dac registers. 229 + */ 224 230 __u32 iac[4]; 225 231 __u32 dac[2]; 226 232 __u32 dvc[2]; ··· 325 331 __u32 reserved[8]; 326 332 }; 327 333 334 + /* For KVM_PPC_GET_HTAB_FD */ 335 + struct kvm_get_htab_fd { 336 + __u64 flags; 337 + __u64 start_index; 338 + __u64 reserved[2]; 339 + }; 340 + 341 + /* Values for kvm_get_htab_fd.flags */ 342 + #define KVM_GET_HTAB_BOLTED_ONLY ((__u64)0x1) 343 + #define KVM_GET_HTAB_WRITE ((__u64)0x2) 344 + 345 + /* 346 + * Data read on the file descriptor is formatted as a series of 347 + * records, each consisting of a header followed by a series of 348 + * `n_valid' HPTEs (16 bytes each), which are all valid. Following 349 + * those valid HPTEs there are `n_invalid' invalid HPTEs, which 350 + * are not represented explicitly in the stream. The same format 351 + * is used for writing. 352 + */ 353 + struct kvm_get_htab_header { 354 + __u32 index; 355 + __u16 n_valid; 356 + __u16 n_invalid; 357 + }; 358 + 328 359 #define KVM_REG_PPC_HIOR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x1) 360 + #define KVM_REG_PPC_IAC1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x2) 361 + #define KVM_REG_PPC_IAC2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3) 362 + #define KVM_REG_PPC_IAC3 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x4) 363 + #define KVM_REG_PPC_IAC4 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x5) 364 + #define KVM_REG_PPC_DAC1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x6) 365 + #define KVM_REG_PPC_DAC2 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x7) 366 + #define KVM_REG_PPC_DABR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x8) 367 + #define KVM_REG_PPC_DSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x9) 368 + #define KVM_REG_PPC_PURR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xa) 369 + #define KVM_REG_PPC_SPURR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb) 370 + #define KVM_REG_PPC_DAR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xc) 371 + #define KVM_REG_PPC_DSISR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xd) 372 + #define KVM_REG_PPC_AMR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xe) 373 + #define KVM_REG_PPC_UAMOR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xf) 374 + 375 + #define KVM_REG_PPC_MMCR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x10) 376 + #define KVM_REG_PPC_MMCR1 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x11) 377 + #define KVM_REG_PPC_MMCRA (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x12) 378 + 379 + #define KVM_REG_PPC_PMC1 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x18) 380 + #define KVM_REG_PPC_PMC2 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x19) 381 + #define KVM_REG_PPC_PMC3 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1a) 382 + #define KVM_REG_PPC_PMC4 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1b) 383 + #define KVM_REG_PPC_PMC5 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1c) 384 + #define KVM_REG_PPC_PMC6 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1d) 385 + #define KVM_REG_PPC_PMC7 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1e) 386 + #define KVM_REG_PPC_PMC8 (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x1f) 387 + 388 + /* 32 floating-point registers */ 389 + #define KVM_REG_PPC_FPR0 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x20) 390 + #define KVM_REG_PPC_FPR(n) (KVM_REG_PPC_FPR0 + (n)) 391 + #define KVM_REG_PPC_FPR31 (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x3f) 392 + 393 + /* 32 VMX/Altivec vector registers */ 394 + #define KVM_REG_PPC_VR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x40) 395 + #define KVM_REG_PPC_VR(n) (KVM_REG_PPC_VR0 + (n)) 396 + #define KVM_REG_PPC_VR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x5f) 397 + 398 + /* 32 double-width FP registers for VSX */ 399 + /* High-order halves overlap with FP regs */ 400 + #define KVM_REG_PPC_VSR0 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x60) 401 + #define KVM_REG_PPC_VSR(n) (KVM_REG_PPC_VSR0 + (n)) 402 + #define KVM_REG_PPC_VSR31 (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x7f) 403 + 404 + /* FP and vector status/control registers */ 405 + #define KVM_REG_PPC_FPSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x80) 406 + #define KVM_REG_PPC_VSCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x81) 407 + 408 + /* Virtual processor areas */ 409 + /* For SLB & DTL, address in high (first) half, length in low half */ 410 + #define KVM_REG_PPC_VPA_ADDR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0x82) 411 + #define KVM_REG_PPC_VPA_SLB (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x83) 412 + #define KVM_REG_PPC_VPA_DTL (KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84) 413 + 414 + #define KVM_REG_PPC_EPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85) 329 415 330 416 #endif /* __LINUX_KVM_POWERPC_H */
+7 -6
linux-headers/asm-powerpc/kvm_para.h
··· 17 17 * Authors: Hollis Blanchard <hollisb@us.ibm.com> 18 18 */ 19 19 20 - #ifndef _UAPI__POWERPC_KVM_PARA_H__ 21 - #define _UAPI__POWERPC_KVM_PARA_H__ 20 + #ifndef __POWERPC_KVM_PARA_H__ 21 + #define __POWERPC_KVM_PARA_H__ 22 22 23 23 #include <linux/types.h> 24 24 ··· 75 75 }; 76 76 77 77 #define KVM_SC_MAGIC_R0 0x4b564d21 /* "KVM!" */ 78 - #define HC_VENDOR_KVM (42 << 16) 79 - #define HC_EV_SUCCESS 0 80 - #define HC_EV_UNIMPLEMENTED 12 78 + 79 + #define KVM_HCALL_TOKEN(num) _EV_HCALL_TOKEN(EV_KVM_VENDOR_ID, num) 80 + 81 + #include <asm/epapr_hcalls.h> 81 82 82 83 #define KVM_FEATURE_MAGIC_PAGE 1 83 84 ··· 87 88 #define KVM_MAGIC_FEAT_MAS0_TO_SPRG7 (1 << 1) 88 89 89 90 90 - #endif /* _UAPI__POWERPC_KVM_PARA_H__ */ 91 + #endif /* __POWERPC_KVM_PARA_H__ */
+16 -5
linux-headers/linux/kvm.h
··· 167 167 #define KVM_EXIT_OSI 18 168 168 #define KVM_EXIT_PAPR_HCALL 19 169 169 #define KVM_EXIT_S390_UCONTROL 20 170 + #define KVM_EXIT_WATCHDOG 21 170 171 171 172 /* For KVM_EXIT_INTERNAL_ERROR */ 172 - #define KVM_INTERNAL_ERROR_EMULATION 1 173 - #define KVM_INTERNAL_ERROR_SIMUL_EX 2 173 + /* Emulate instruction failed. */ 174 + #define KVM_INTERNAL_ERROR_EMULATION 1 175 + /* Encounter unexpected simultaneous exceptions. */ 176 + #define KVM_INTERNAL_ERROR_SIMUL_EX 2 177 + /* Encounter unexpected vm-exit due to delivery event. */ 178 + #define KVM_INTERNAL_ERROR_DELIVERY_EV 3 174 179 175 180 /* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */ 176 181 struct kvm_run { ··· 476 481 __u32 pad; 477 482 struct kvm_ppc_one_seg_page_size sps[KVM_PPC_PAGE_SIZES_MAX_SZ]; 478 483 }; 484 + 485 + #define KVM_PPC_PVINFO_FLAGS_EV_IDLE (1<<0) 479 486 480 487 #define KVMIO 0xAE 481 488 ··· 626 633 #define KVM_CAP_READONLY_MEM 81 627 634 #endif 628 635 #define KVM_CAP_IRQFD_RESAMPLE 82 636 + #define KVM_CAP_PPC_BOOKE_WATCHDOG 83 637 + #define KVM_CAP_PPC_HTAB_FD 84 629 638 630 639 #ifdef KVM_CAP_IRQ_ROUTING 631 640 ··· 848 857 #define KVM_PPC_GET_SMMU_INFO _IOR(KVMIO, 0xa6, struct kvm_ppc_smmu_info) 849 858 /* Available with KVM_CAP_PPC_ALLOC_HTAB */ 850 859 #define KVM_PPC_ALLOCATE_HTAB _IOWR(KVMIO, 0xa7, __u32) 860 + #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) 861 + /* Available with KVM_CAP_RMA */ 862 + #define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) 863 + /* Available with KVM_CAP_PPC_HTAB_FD */ 864 + #define KVM_PPC_GET_HTAB_FD _IOW(KVMIO, 0xaa, struct kvm_get_htab_fd) 851 865 852 866 /* 853 867 * ioctls for vcpu fds ··· 911 925 /* Available with KVM_CAP_XCRS */ 912 926 #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) 913 927 #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) 914 - #define KVM_CREATE_SPAPR_TCE _IOW(KVMIO, 0xa8, struct kvm_create_spapr_tce) 915 - /* Available with KVM_CAP_RMA */ 916 - #define KVM_ALLOCATE_RMA _IOR(KVMIO, 0xa9, struct kvm_allocate_rma) 917 928 /* Available with KVM_CAP_SW_TLB */ 918 929 #define KVM_DIRTY_TLB _IOW(KVMIO, 0xaa, struct kvm_dirty_tlb) 919 930 /* Available with KVM_CAP_ONE_REG */
+3 -3
linux-headers/linux/kvm_para.h
··· 1 - #ifndef _UAPI__LINUX_KVM_PARA_H 2 - #define _UAPI__LINUX_KVM_PARA_H 1 + #ifndef __LINUX_KVM_PARA_H 2 + #define __LINUX_KVM_PARA_H 3 3 4 4 /* 5 5 * This header file provides a method for making a hypercall to the host ··· 25 25 */ 26 26 #include <asm/kvm_para.h> 27 27 28 - #endif /* _UAPI__LINUX_KVM_PARA_H */ 28 + #endif /* __LINUX_KVM_PARA_H */
+3 -3
linux-headers/linux/vfio.h
··· 8 8 * it under the terms of the GNU General Public License version 2 as 9 9 * published by the Free Software Foundation. 10 10 */ 11 - #ifndef _UAPIVFIO_H 12 - #define _UAPIVFIO_H 11 + #ifndef VFIO_H 12 + #define VFIO_H 13 13 14 14 #include <linux/types.h> 15 15 #include <linux/ioctl.h> ··· 365 365 366 366 #define VFIO_IOMMU_UNMAP_DMA _IO(VFIO_TYPE, VFIO_BASE + 14) 367 367 368 - #endif /* _UAPIVFIO_H */ 368 + #endif /* VFIO_H */
+3 -3
linux-headers/linux/virtio_config.h
··· 1 - #ifndef _UAPI_LINUX_VIRTIO_CONFIG_H 2 - #define _UAPI_LINUX_VIRTIO_CONFIG_H 1 + #ifndef _LINUX_VIRTIO_CONFIG_H 2 + #define _LINUX_VIRTIO_CONFIG_H 3 3 /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so 4 4 * anyone can use the definitions to implement compatible drivers/servers. 5 5 * ··· 51 51 * suppressed them? */ 52 52 #define VIRTIO_F_NOTIFY_ON_EMPTY 24 53 53 54 - #endif /* _UAPI_LINUX_VIRTIO_CONFIG_H */ 54 + #endif /* _LINUX_VIRTIO_CONFIG_H */
+3 -3
linux-headers/linux/virtio_ring.h
··· 1 - #ifndef _UAPI_LINUX_VIRTIO_RING_H 2 - #define _UAPI_LINUX_VIRTIO_RING_H 1 + #ifndef _LINUX_VIRTIO_RING_H 2 + #define _LINUX_VIRTIO_RING_H 3 3 /* An interface for efficient virtio implementation, currently for use by KVM 4 4 * and lguest, but hopefully others soon. Do NOT change this since it will 5 5 * break existing servers and clients. ··· 160 160 return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old); 161 161 } 162 162 163 - #endif /* _UAPI_LINUX_VIRTIO_RING_H */ 163 + #endif /* _LINUX_VIRTIO_RING_H */
+3 -3
linux-user/signal.c
··· 4578 4578 4579 4579 signal = current_exec_domain_sig(sig); 4580 4580 4581 - err |= __put_user(h2g(ka->_sa_handler), &sc->handler); 4581 + err |= __put_user(ka->_sa_handler, &sc->handler); 4582 4582 err |= __put_user(set->sig[0], &sc->oldmask); 4583 4583 #if defined(TARGET_PPC64) 4584 4584 err |= __put_user(set->sig[0] >> 32, &sc->_unused[3]); ··· 4600 4600 4601 4601 /* Create a stack frame for the caller of the handler. */ 4602 4602 newsp = frame_addr - SIGNAL_FRAMESIZE; 4603 - err |= __put_user(env->gpr[1], (target_ulong *)(uintptr_t) newsp); 4603 + err |= put_user(env->gpr[1], newsp, target_ulong); 4604 4604 4605 4605 if (err) 4606 4606 goto sigsegv; ··· 4608 4608 /* Set up registers for signal handler. */ 4609 4609 env->gpr[1] = newsp; 4610 4610 env->gpr[3] = signal; 4611 - env->gpr[4] = (target_ulong) h2g(sc); 4611 + env->gpr[4] = frame_addr + offsetof(struct target_sigframe, sctx); 4612 4612 env->nip = (target_ulong) ka->_sa_handler; 4613 4613 /* Signal handlers are entered in big-endian mode. */ 4614 4614 env->msr &= ~MSR_LE;
+3
scripts/update-linux-headers.sh
··· 54 54 if [ $arch = x86 ]; then 55 55 cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86" 56 56 fi 57 + if [ $arch = powerpc ]; then 58 + cp "$tmpdir/include/asm/epapr_hcalls.h" "$output/linux-headers/asm-powerpc/" 59 + fi 57 60 done 58 61 59 62 rm -rf "$output/linux-headers/linux"
+1 -3
target-ppc/Makefile.objs
··· 1 - obj-y += translate.o helper.o 1 + obj-y += translate.o 2 2 obj-$(CONFIG_SOFTMMU) += machine.o 3 3 obj-$(CONFIG_KVM) += kvm.o kvm_ppc.o 4 - obj-y += helper.o 5 4 obj-y += excp_helper.o 6 5 obj-y += fpu_helper.o 7 6 obj-y += int_helper.o ··· 9 8 obj-y += timebase_helper.o 10 9 obj-y += misc_helper.o 11 10 obj-y += mem_helper.o 12 - obj-y += mpic_helper.o
+5
target-ppc/cpu-qom.h
··· 50 50 /*< public >*/ 51 51 52 52 void (*parent_reset)(CPUState *cpu); 53 + 54 + /* TODO inline fields here */ 55 + ppc_def_t *info; 53 56 } PowerPCCPUClass; 54 57 55 58 /** ··· 72 75 } 73 76 74 77 #define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e)) 78 + 79 + PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr); 75 80 76 81 77 82 #endif
+3 -5
target-ppc/cpu.h
··· 1067 1067 target_ulong ivor_mask; 1068 1068 target_ulong ivpr_mask; 1069 1069 target_ulong hreset_vector; 1070 - hwaddr mpic_cpu_base; 1070 + hwaddr mpic_iack; 1071 + /* true when the external proxy facility mode is enabled */ 1072 + bool mpic_proxy; 1071 1073 #endif 1072 1074 1073 1075 /* Those resources are used only during code translation */ ··· 1155 1157 void ppc_store_msr (CPUPPCState *env, target_ulong value); 1156 1158 1157 1159 void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf); 1158 - 1159 - const ppc_def_t *ppc_find_by_pvr(uint32_t pvr); 1160 - const ppc_def_t *cpu_ppc_find_by_name (const char *name); 1161 - int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def); 1162 1160 1163 1161 /* Time-base and decrementer management */ 1164 1162 #ifndef NO_CPU_IO_DEFS
+26 -9
target-ppc/excp_helper.c
··· 84 84 " => %08x (%02x)\n", env->nip, excp, env->error_code); 85 85 86 86 /* new srr1 value excluding must-be-zero bits */ 87 - msr = env->msr & ~0x783f0000ULL; 87 + if (excp_model == POWERPC_EXCP_BOOKE) { 88 + msr = env->msr; 89 + } else { 90 + msr = env->msr & ~0x783f0000ULL; 91 + } 88 92 89 93 /* new interrupt handler msr */ 90 94 new_msr = env->msr & ((target_ulong)1 << MSR_ME); ··· 145 149 srr1 = SPR_40x_SRR3; 146 150 break; 147 151 case POWERPC_EXCP_BOOKE: 152 + /* FIXME: choose one or the other based on CPU type */ 148 153 srr0 = SPR_BOOKE_MCSRR0; 149 154 srr1 = SPR_BOOKE_MCSRR1; 150 155 asrr0 = SPR_BOOKE_CSRR0; ··· 172 177 case POWERPC_EXCP_EXTERNAL: /* External input */ 173 178 if (lpes0 == 1) { 174 179 new_msr |= (target_ulong)MSR_HVB; 180 + } 181 + if (env->mpic_proxy) { 182 + /* IACK the IRQ on delivery */ 183 + env->spr[SPR_BOOKE_EPR] = ldl_phys(env->mpic_iack); 175 184 } 176 185 goto store_next; 177 186 case POWERPC_EXCP_ALIGN: /* Alignment exception */ ··· 275 284 case POWERPC_EXCP_DEBUG: /* Debug interrupt */ 276 285 switch (excp_model) { 277 286 case POWERPC_EXCP_BOOKE: 287 + /* FIXME: choose one or the other based on CPU type */ 278 288 srr0 = SPR_BOOKE_DSRR0; 279 289 srr1 = SPR_BOOKE_DSRR1; 280 290 asrr0 = SPR_BOOKE_CSRR0; ··· 836 846 837 847 void helper_rfi(CPUPPCState *env) 838 848 { 839 - do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1], 840 - ~((target_ulong)0x783F0000), 1); 849 + if (env->excp_model == POWERPC_EXCP_BOOKE) { 850 + do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1], 851 + ~((target_ulong)0), 0); 852 + } else { 853 + do_rfi(env, env->spr[SPR_SRR0], env->spr[SPR_SRR1], 854 + ~((target_ulong)0x783F0000), 1); 855 + } 841 856 } 842 857 843 858 #if defined(TARGET_PPC64) ··· 864 879 865 880 void helper_rfci(CPUPPCState *env) 866 881 { 867 - do_rfi(env, env->spr[SPR_BOOKE_CSRR0], SPR_BOOKE_CSRR1, 868 - ~((target_ulong)0x3FFF0000), 0); 882 + do_rfi(env, env->spr[SPR_BOOKE_CSRR0], env->spr[SPR_BOOKE_CSRR1], 883 + ~((target_ulong)0), 0); 869 884 } 870 885 871 886 void helper_rfdi(CPUPPCState *env) 872 887 { 873 - do_rfi(env, env->spr[SPR_BOOKE_DSRR0], SPR_BOOKE_DSRR1, 874 - ~((target_ulong)0x3FFF0000), 0); 888 + /* FIXME: choose CSRR1 or DSRR1 based on cpu type */ 889 + do_rfi(env, env->spr[SPR_BOOKE_DSRR0], env->spr[SPR_BOOKE_DSRR1], 890 + ~((target_ulong)0), 0); 875 891 } 876 892 877 893 void helper_rfmci(CPUPPCState *env) 878 894 { 879 - do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], SPR_BOOKE_MCSRR1, 880 - ~((target_ulong)0x3FFF0000), 0); 895 + /* FIXME: choose CSRR1 or MCSRR1 based on cpu type */ 896 + do_rfi(env, env->spr[SPR_BOOKE_MCSRR0], env->spr[SPR_BOOKE_MCSRR1], 897 + ~((target_ulong)0), 0); 881 898 } 882 899 #endif 883 900
-50
target-ppc/helper.c
··· 1 - /* 2 - * PowerPC emulation helpers for QEMU. 3 - * 4 - * Copyright (c) 2003-2007 Jocelyn Mayer 5 - * 6 - * This library is free software; you can redistribute it and/or 7 - * modify it under the terms of the GNU Lesser General Public 8 - * License as published by the Free Software Foundation; either 9 - * version 2 of the License, or (at your option) any later version. 10 - * 11 - * This library is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 - * Lesser General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU Lesser General Public 17 - * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #include "cpu.h" 21 - #include "helper_regs.h" 22 - #include "sysemu/kvm.h" 23 - #include "kvm_ppc.h" 24 - #include "sysemu/cpus.h" 25 - 26 - PowerPCCPU *cpu_ppc_init(const char *cpu_model) 27 - { 28 - PowerPCCPU *cpu; 29 - CPUPPCState *env; 30 - const ppc_def_t *def; 31 - 32 - def = cpu_ppc_find_by_name(cpu_model); 33 - if (!def) { 34 - return NULL; 35 - } 36 - 37 - cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU)); 38 - env = &cpu->env; 39 - 40 - if (tcg_enabled()) { 41 - ppc_translate_init(); 42 - } 43 - 44 - env->cpu_model_str = cpu_model; 45 - cpu_ppc_register_internal(env, def); 46 - 47 - qemu_init_vcpu(env); 48 - 49 - return cpu; 50 - }
-1
target-ppc/helper.h
··· 405 405 DEF_HELPER_2(store_40x_sler, void, env, tl) 406 406 DEF_HELPER_2(store_booke_tcr, void, env, tl) 407 407 DEF_HELPER_2(store_booke_tsr, void, env, tl) 408 - DEF_HELPER_1(load_epr, tl, env) 409 408 DEF_HELPER_3(store_ibatl, void, env, i32, tl) 410 409 DEF_HELPER_3(store_ibatu, void, env, i32, tl) 411 410 DEF_HELPER_3(store_dbatl, void, env, i32, tl)
+64 -13
target-ppc/kvm.c
··· 989 989 return kvmppc_read_int_cpu_dt("ibm,dfp"); 990 990 } 991 991 992 + static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo) 993 + { 994 + PowerPCCPU *cpu = ppc_env_get_cpu(env); 995 + CPUState *cs = CPU(cpu); 996 + 997 + if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) && 998 + !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) { 999 + return 0; 1000 + } 1001 + 1002 + return 1; 1003 + } 1004 + 1005 + int kvmppc_get_hasidle(CPUPPCState *env) 1006 + { 1007 + struct kvm_ppc_pvinfo pvinfo; 1008 + 1009 + if (!kvmppc_get_pvinfo(env, &pvinfo) && 1010 + (pvinfo.flags & KVM_PPC_PVINFO_FLAGS_EV_IDLE)) { 1011 + return 1; 1012 + } 1013 + 1014 + return 0; 1015 + } 1016 + 992 1017 int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len) 993 1018 { 994 - PowerPCCPU *cpu = ppc_env_get_cpu(env); 995 - CPUState *cs = CPU(cpu); 996 1019 uint32_t *hc = (uint32_t*)buf; 997 - 998 1020 struct kvm_ppc_pvinfo pvinfo; 999 1021 1000 - if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) && 1001 - !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) { 1022 + if (!kvmppc_get_pvinfo(env, &pvinfo)) { 1002 1023 memcpy(buf, pvinfo.hcall, buf_len); 1003 - 1004 1024 return 0; 1005 1025 } 1006 1026 ··· 1210 1230 } 1211 1231 } 1212 1232 1213 - const ppc_def_t *kvmppc_host_cpu_def(void) 1233 + static void kvmppc_host_cpu_initfn(Object *obj) 1234 + { 1235 + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(obj); 1236 + 1237 + assert(kvm_enabled()); 1238 + 1239 + if (pcc->info->pvr != mfpvr()) { 1240 + fprintf(stderr, "Your host CPU is unsupported.\n" 1241 + "Please choose a supported model instead, see -cpu ?.\n"); 1242 + exit(1); 1243 + } 1244 + } 1245 + 1246 + static void kvmppc_host_cpu_class_init(ObjectClass *oc, void *data) 1214 1247 { 1248 + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); 1215 1249 uint32_t host_pvr = mfpvr(); 1216 - const ppc_def_t *base_spec; 1250 + PowerPCCPUClass *pvr_pcc; 1217 1251 ppc_def_t *spec; 1218 1252 uint32_t vmx = kvmppc_get_vmx(); 1219 1253 uint32_t dfp = kvmppc_get_dfp(); 1220 1254 1221 - base_spec = ppc_find_by_pvr(host_pvr); 1255 + spec = g_malloc0(sizeof(*spec)); 1222 1256 1223 - spec = g_malloc0(sizeof(*spec)); 1224 - memcpy(spec, base_spec, sizeof(*spec)); 1257 + pvr_pcc = ppc_cpu_class_by_pvr(host_pvr); 1258 + if (pvr_pcc != NULL) { 1259 + memcpy(spec, pvr_pcc->info, sizeof(*spec)); 1260 + } 1261 + pcc->info = spec; 1262 + /* Override the display name for -cpu ? and QMP */ 1263 + pcc->info->name = "host"; 1225 1264 1226 1265 /* Now fix up the spec with information we can query from the host */ 1227 1266 ··· 1234 1273 /* Only override when we know what the host supports */ 1235 1274 alter_insns(&spec->insns_flags2, PPC2_DFP, dfp); 1236 1275 } 1237 - 1238 - return spec; 1239 1276 } 1240 1277 1241 1278 int kvmppc_fixup_cpu(CPUPPCState *env) ··· 1265 1302 { 1266 1303 return 1; 1267 1304 } 1305 + 1306 + static const TypeInfo kvm_host_cpu_type_info = { 1307 + .name = TYPE_HOST_POWERPC_CPU, 1308 + .parent = TYPE_POWERPC_CPU, 1309 + .instance_init = kvmppc_host_cpu_initfn, 1310 + .class_init = kvmppc_host_cpu_class_init, 1311 + }; 1312 + 1313 + static void kvm_ppc_register_types(void) 1314 + { 1315 + type_register_static(&kvm_host_cpu_type_info); 1316 + } 1317 + 1318 + type_init(kvm_ppc_register_types)
+8 -6
target-ppc/kvm_ppc.h
··· 11 11 12 12 #include "exec/memory.h" 13 13 14 + #define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU 15 + 14 16 void kvmppc_init(void); 15 17 16 18 #ifdef CONFIG_KVM ··· 19 21 uint64_t kvmppc_get_clockfreq(void); 20 22 uint32_t kvmppc_get_vmx(void); 21 23 uint32_t kvmppc_get_dfp(void); 24 + int kvmppc_get_hasidle(CPUPPCState *env); 22 25 int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len); 23 26 int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level); 24 27 void kvmppc_set_papr(PowerPCCPU *cpu); ··· 30 33 int kvmppc_reset_htab(int shift_hint); 31 34 uint64_t kvmppc_rma_size(uint64_t current_size, unsigned int hash_shift); 32 35 #endif /* !CONFIG_USER_ONLY */ 33 - const ppc_def_t *kvmppc_host_cpu_def(void); 34 36 int kvmppc_fixup_cpu(CPUPPCState *env); 35 37 36 38 #else ··· 51 53 } 52 54 53 55 static inline uint32_t kvmppc_get_dfp(void) 56 + { 57 + return 0; 58 + } 59 + 60 + static inline int kvmppc_get_hasidle(CPUPPCState *env) 54 61 { 55 62 return 0; 56 63 } ··· 114 121 } 115 122 116 123 #endif /* !CONFIG_USER_ONLY */ 117 - 118 - static inline const ppc_def_t *kvmppc_host_cpu_def(void) 119 - { 120 - return NULL; 121 - } 122 124 123 125 static inline int kvmppc_fixup_cpu(CPUPPCState *env) 124 126 {
-35
target-ppc/mpic_helper.c
··· 1 - /* 2 - * PowerPC emulation helpers for QEMU. 3 - * 4 - * Copyright (c) 2003-2007 Jocelyn Mayer 5 - * 6 - * This library is free software; you can redistribute it and/or 7 - * modify it under the terms of the GNU Lesser General Public 8 - * License as published by the Free Software Foundation; either 9 - * version 2 of the License, or (at your option) any later version. 10 - * 11 - * This library is distributed in the hope that it will be useful, 12 - * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 - * Lesser General Public License for more details. 15 - * 16 - * You should have received a copy of the GNU Lesser General Public 17 - * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - #include "cpu.h" 20 - #include "helper.h" 21 - 22 - /*****************************************************************************/ 23 - /* SPR accesses */ 24 - 25 - #if !defined(CONFIG_USER_ONLY) 26 - /* 27 - * This is an ugly helper for EPR, which is basically the same as accessing 28 - * the IACK (PIAC) register on the MPIC. Because we model the MPIC as a device 29 - * that can only talk to the CPU through MMIO, let's access it that way! 30 - */ 31 - target_ulong helper_load_epr(CPUPPCState *env) 32 - { 33 - return ldl_phys(env->mpic_cpu_base + 0xA0); 34 - } 35 - #endif
+239 -113
target-ppc/translate_init.c
··· 4493 4493 tcg_temp_free(mas7); 4494 4494 } 4495 4495 4496 - static void spr_load_epr(void *opaque, int gprn, int sprn) 4497 - { 4498 - gen_helper_load_epr(cpu_gpr[gprn], cpu_env); 4499 - } 4500 - 4501 4496 #endif 4502 4497 4503 4498 enum fsl_e500_version { ··· 4656 4651 0x00000000); 4657 4652 spr_register(env, SPR_BOOKE_EPR, "EPR", 4658 4653 SPR_NOACCESS, SPR_NOACCESS, 4659 - &spr_load_epr, SPR_NOACCESS, 4654 + &spr_read_generic, SPR_NOACCESS, 4660 4655 0x00000000); 4661 4656 /* XXX better abstract into Emb.xxx features */ 4662 4657 if (version == fsl_e5500) { ··· 9797 9792 } 9798 9793 9799 9794 /*****************************************************************************/ 9800 - static int create_ppc_opcodes (CPUPPCState *env, const ppc_def_t *def) 9795 + static void create_ppc_opcodes(PowerPCCPU *cpu, Error **errp) 9801 9796 { 9797 + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 9798 + CPUPPCState *env = &cpu->env; 9799 + const ppc_def_t *def = pcc->info; 9802 9800 opcode_t *opc; 9803 9801 9804 9802 fill_new_table(env->opcodes, 0x40); ··· 9806 9804 if (((opc->handler.type & def->insns_flags) != 0) || 9807 9805 ((opc->handler.type2 & def->insns_flags2) != 0)) { 9808 9806 if (register_insn(env->opcodes, opc) < 0) { 9809 - printf("*** ERROR initializing PowerPC instruction " 9810 - "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2, 9811 - opc->opc3); 9812 - return -1; 9807 + error_setg(errp, "ERROR initializing PowerPC instruction " 9808 + "0x%02x 0x%02x 0x%02x\n", opc->opc1, opc->opc2, 9809 + opc->opc3); 9810 + return; 9813 9811 } 9814 9812 } 9815 9813 } 9816 9814 fix_opcode_tables(env->opcodes); 9817 9815 fflush(stdout); 9818 9816 fflush(stderr); 9819 - 9820 - return 0; 9821 9817 } 9822 9818 9823 9819 #if defined(PPC_DUMP_CPU) ··· 10031 10027 return 0; 10032 10028 } 10033 10029 10034 - int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) 10030 + static void ppc_cpu_realize(Object *obj, Error **errp) 10035 10031 { 10036 - env->msr_mask = def->msr_mask; 10037 - env->mmu_model = def->mmu_model; 10038 - env->excp_model = def->excp_model; 10039 - env->bus_model = def->bus_model; 10040 - env->insns_flags = def->insns_flags; 10041 - env->insns_flags2 = def->insns_flags2; 10042 - env->flags = def->flags; 10043 - env->bfd_mach = def->bfd_mach; 10044 - env->check_pow = def->check_pow; 10045 - 10046 - #if defined(TARGET_PPC64) 10047 - if (def->sps) 10048 - env->sps = *def->sps; 10049 - else if (env->mmu_model & POWERPC_MMU_64) { 10050 - /* Use default sets of page sizes */ 10051 - static const struct ppc_segment_page_sizes defsps = { 10052 - .sps = { 10053 - { .page_shift = 12, /* 4K */ 10054 - .slb_enc = 0, 10055 - .enc = { { .page_shift = 12, .pte_enc = 0 } } 10056 - }, 10057 - { .page_shift = 24, /* 16M */ 10058 - .slb_enc = 0x100, 10059 - .enc = { { .page_shift = 24, .pte_enc = 0 } } 10060 - }, 10061 - }, 10062 - }; 10063 - env->sps = defsps; 10064 - } 10065 - #endif /* defined(TARGET_PPC64) */ 10032 + PowerPCCPU *cpu = POWERPC_CPU(obj); 10033 + CPUPPCState *env = &cpu->env; 10034 + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 10035 + ppc_def_t *def = pcc->info; 10036 + Error *local_err = NULL; 10066 10037 10067 10038 if (kvm_enabled()) { 10068 10039 if (kvmppc_fixup_cpu(env) != 0) { 10069 - fprintf(stderr, "Unable to virtualize selected CPU with KVM\n"); 10070 - exit(1); 10040 + error_setg(errp, "Unable to virtualize selected CPU with KVM"); 10041 + return; 10071 10042 } 10072 10043 } else { 10073 10044 if (ppc_fixup_cpu(env) != 0) { 10074 - fprintf(stderr, "Unable to emulate selected CPU with TCG\n"); 10075 - exit(1); 10045 + error_setg(errp, "Unable to emulate selected CPU with TCG"); 10046 + return; 10076 10047 } 10077 10048 } 10078 10049 10079 - if (create_ppc_opcodes(env, def) < 0) 10080 - return -1; 10050 + create_ppc_opcodes(cpu, &local_err); 10051 + if (local_err != NULL) { 10052 + error_propagate(errp, local_err); 10053 + return; 10054 + } 10081 10055 init_ppc_proc(env, def); 10082 10056 10083 10057 if (def->insns_flags & PPC_FLOAT) { ··· 10092 10066 gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg, 10093 10067 34, "power-spe.xml", 0); 10094 10068 } 10069 + 10070 + qemu_init_vcpu(env); 10095 10071 10096 10072 #if defined(PPC_DUMP_CPU) 10097 10073 { ··· 10254 10230 dump_ppc_sprs(env); 10255 10231 fflush(stdout); 10256 10232 #endif 10233 + } 10257 10234 10258 - return 0; 10235 + static gint ppc_cpu_compare_class_pvr(gconstpointer a, gconstpointer b) 10236 + { 10237 + ObjectClass *oc = (ObjectClass *)a; 10238 + uint32_t pvr = *(uint32_t *)b; 10239 + PowerPCCPUClass *pcc = (PowerPCCPUClass *)a; 10240 + 10241 + /* -cpu host does a PVR lookup during construction */ 10242 + if (unlikely(strcmp(object_class_get_name(oc), 10243 + TYPE_HOST_POWERPC_CPU) == 0)) { 10244 + return -1; 10245 + } 10246 + 10247 + return pcc->info->pvr == pvr ? 0 : -1; 10259 10248 } 10260 10249 10261 - static bool ppc_cpu_usable(const ppc_def_t *def) 10250 + PowerPCCPUClass *ppc_cpu_class_by_pvr(uint32_t pvr) 10262 10251 { 10263 - #if defined(TARGET_PPCEMB) 10264 - /* When using the ppcemb target, we only support 440 style cores */ 10265 - if (def->mmu_model != POWERPC_MMU_BOOKE) { 10266 - return false; 10252 + GSList *list, *item; 10253 + PowerPCCPUClass *pcc = NULL; 10254 + 10255 + list = object_class_get_list(TYPE_POWERPC_CPU, false); 10256 + item = g_slist_find_custom(list, &pvr, ppc_cpu_compare_class_pvr); 10257 + if (item != NULL) { 10258 + pcc = POWERPC_CPU_CLASS(item->data); 10267 10259 } 10268 - #endif 10260 + g_slist_free(list); 10269 10261 10270 - return true; 10262 + return pcc; 10271 10263 } 10272 10264 10273 - const ppc_def_t *ppc_find_by_pvr(uint32_t pvr) 10265 + static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b) 10274 10266 { 10275 - int i; 10267 + ObjectClass *oc = (ObjectClass *)a; 10268 + const char *name = b; 10276 10269 10277 - for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) { 10278 - if (!ppc_cpu_usable(&ppc_defs[i])) { 10279 - continue; 10280 - } 10281 - 10282 - /* If we have an exact match, we're done */ 10283 - if (pvr == ppc_defs[i].pvr) { 10284 - return &ppc_defs[i]; 10285 - } 10270 + if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 && 10271 + strcmp(object_class_get_name(oc) + strlen(name), 10272 + "-" TYPE_POWERPC_CPU) == 0) { 10273 + return 0; 10286 10274 } 10287 - 10288 - return NULL; 10275 + return -1; 10289 10276 } 10290 10277 10291 10278 #include <ctype.h> 10292 10279 10293 - const ppc_def_t *cpu_ppc_find_by_name (const char *name) 10280 + static ObjectClass *ppc_cpu_class_by_name(const char *name) 10294 10281 { 10295 - const ppc_def_t *ret; 10282 + GSList *list, *item; 10283 + ObjectClass *ret = NULL; 10296 10284 const char *p; 10297 - int i, max, len; 10285 + int i, len; 10298 10286 10299 - if (kvm_enabled() && (strcasecmp(name, "host") == 0)) { 10300 - return kvmppc_host_cpu_def(); 10287 + if (strcasecmp(name, "host") == 0) { 10288 + if (kvm_enabled()) { 10289 + ret = object_class_by_name(TYPE_HOST_POWERPC_CPU); 10290 + } 10291 + return ret; 10301 10292 } 10302 10293 10303 10294 /* Check if the given name is a PVR */ ··· 10312 10303 if (!qemu_isxdigit(*p++)) 10313 10304 break; 10314 10305 } 10315 - if (i == 8) 10316 - return ppc_find_by_pvr(strtoul(name, NULL, 16)); 10317 - } 10318 - ret = NULL; 10319 - max = ARRAY_SIZE(ppc_defs); 10320 - for (i = 0; i < max; i++) { 10321 - if (!ppc_cpu_usable(&ppc_defs[i])) { 10322 - continue; 10306 + if (i == 8) { 10307 + ret = OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16))); 10308 + return ret; 10323 10309 } 10310 + } 10324 10311 10325 - if (strcasecmp(name, ppc_defs[i].name) == 0) { 10326 - ret = &ppc_defs[i]; 10327 - break; 10328 - } 10312 + list = object_class_get_list(TYPE_POWERPC_CPU, false); 10313 + item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name); 10314 + if (item != NULL) { 10315 + ret = OBJECT_CLASS(item->data); 10329 10316 } 10317 + g_slist_free(list); 10330 10318 10331 10319 return ret; 10332 10320 } 10333 10321 10334 - void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf) 10322 + PowerPCCPU *cpu_ppc_init(const char *cpu_model) 10323 + { 10324 + PowerPCCPU *cpu; 10325 + CPUPPCState *env; 10326 + ObjectClass *oc; 10327 + Error *err = NULL; 10328 + 10329 + oc = ppc_cpu_class_by_name(cpu_model); 10330 + if (oc == NULL) { 10331 + return NULL; 10332 + } 10333 + 10334 + cpu = POWERPC_CPU(object_new(object_class_get_name(oc))); 10335 + env = &cpu->env; 10336 + 10337 + if (tcg_enabled()) { 10338 + ppc_translate_init(); 10339 + } 10340 + 10341 + env->cpu_model_str = cpu_model; 10342 + 10343 + ppc_cpu_realize(OBJECT(cpu), &err); 10344 + if (err != NULL) { 10345 + fprintf(stderr, "%s\n", error_get_pretty(err)); 10346 + error_free(err); 10347 + object_delete(OBJECT(cpu)); 10348 + return NULL; 10349 + } 10350 + 10351 + return cpu; 10352 + } 10353 + 10354 + /* Sort by PVR, ordering special case "host" last. */ 10355 + static gint ppc_cpu_list_compare(gconstpointer a, gconstpointer b) 10335 10356 { 10336 - int i, max; 10357 + ObjectClass *oc_a = (ObjectClass *)a; 10358 + ObjectClass *oc_b = (ObjectClass *)b; 10359 + PowerPCCPUClass *pcc_a = POWERPC_CPU_CLASS(oc_a); 10360 + PowerPCCPUClass *pcc_b = POWERPC_CPU_CLASS(oc_b); 10361 + const char *name_a = object_class_get_name(oc_a); 10362 + const char *name_b = object_class_get_name(oc_b); 10337 10363 10338 - max = ARRAY_SIZE(ppc_defs); 10339 - for (i = 0; i < max; i++) { 10340 - if (!ppc_cpu_usable(&ppc_defs[i])) { 10341 - continue; 10364 + if (strcmp(name_a, TYPE_HOST_POWERPC_CPU) == 0) { 10365 + return 1; 10366 + } else if (strcmp(name_b, TYPE_HOST_POWERPC_CPU) == 0) { 10367 + return -1; 10368 + } else { 10369 + /* Avoid an integer overflow during subtraction */ 10370 + if (pcc_a->info->pvr < pcc_b->info->pvr) { 10371 + return -1; 10372 + } else if (pcc_a->info->pvr > pcc_b->info->pvr) { 10373 + return 1; 10374 + } else { 10375 + return 0; 10342 10376 } 10343 - 10344 - (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n", 10345 - ppc_defs[i].name, ppc_defs[i].pvr); 10346 10377 } 10378 + } 10379 + 10380 + static void ppc_cpu_list_entry(gpointer data, gpointer user_data) 10381 + { 10382 + ObjectClass *oc = data; 10383 + CPUListState *s = user_data; 10384 + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); 10385 + 10386 + (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n", 10387 + pcc->info->name, pcc->info->pvr); 10388 + } 10389 + 10390 + void ppc_cpu_list(FILE *f, fprintf_function cpu_fprintf) 10391 + { 10392 + CPUListState s = { 10393 + .file = f, 10394 + .cpu_fprintf = cpu_fprintf, 10395 + }; 10396 + GSList *list; 10397 + 10398 + list = object_class_get_list(TYPE_POWERPC_CPU, false); 10399 + list = g_slist_sort(list, ppc_cpu_list_compare); 10400 + g_slist_foreach(list, ppc_cpu_list_entry, &s); 10401 + g_slist_free(list); 10402 + } 10403 + 10404 + static void ppc_cpu_defs_entry(gpointer data, gpointer user_data) 10405 + { 10406 + ObjectClass *oc = data; 10407 + CpuDefinitionInfoList **first = user_data; 10408 + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); 10409 + CpuDefinitionInfoList *entry; 10410 + CpuDefinitionInfo *info; 10411 + 10412 + info = g_malloc0(sizeof(*info)); 10413 + info->name = g_strdup(pcc->info->name); 10414 + 10415 + entry = g_malloc0(sizeof(*entry)); 10416 + entry->value = info; 10417 + entry->next = *first; 10418 + *first = entry; 10347 10419 } 10348 10420 10349 10421 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp) 10350 10422 { 10351 10423 CpuDefinitionInfoList *cpu_list = NULL; 10352 - int i; 10424 + GSList *list; 10353 10425 10354 - for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) { 10355 - CpuDefinitionInfoList *entry; 10356 - CpuDefinitionInfo *info; 10426 + list = object_class_get_list(TYPE_POWERPC_CPU, false); 10427 + g_slist_foreach(list, ppc_cpu_defs_entry, &cpu_list); 10428 + g_slist_free(list); 10357 10429 10358 - if (!ppc_cpu_usable(&ppc_defs[i])) { 10359 - continue; 10360 - } 10430 + return cpu_list; 10431 + } 10361 10432 10362 - info = g_malloc0(sizeof(*info)); 10363 - info->name = g_strdup(ppc_defs[i].name); 10433 + static void ppc_cpu_def_class_init(ObjectClass *oc, void *data) 10434 + { 10435 + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); 10436 + ppc_def_t *info = data; 10364 10437 10365 - entry = g_malloc0(sizeof(*entry)); 10366 - entry->value = info; 10367 - entry->next = cpu_list; 10368 - cpu_list = entry; 10369 - } 10438 + pcc->info = info; 10439 + } 10440 + 10441 + static void ppc_cpu_register_model(const ppc_def_t *def) 10442 + { 10443 + TypeInfo type_info = { 10444 + .parent = TYPE_POWERPC_CPU, 10445 + .class_init = ppc_cpu_def_class_init, 10446 + .class_data = (void *)def, 10447 + }; 10370 10448 10371 - return cpu_list; 10449 + type_info.name = g_strdup_printf("%s-" TYPE_POWERPC_CPU, def->name), 10450 + type_register(&type_info); 10451 + g_free((gpointer)type_info.name); 10372 10452 } 10373 10453 10374 10454 /* CPUClass::reset() */ ··· 10439 10519 static void ppc_cpu_initfn(Object *obj) 10440 10520 { 10441 10521 PowerPCCPU *cpu = POWERPC_CPU(obj); 10522 + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); 10442 10523 CPUPPCState *env = &cpu->env; 10524 + ppc_def_t *def = pcc->info; 10443 10525 10444 10526 cpu_exec_init(env); 10527 + 10528 + env->msr_mask = def->msr_mask; 10529 + env->mmu_model = def->mmu_model; 10530 + env->excp_model = def->excp_model; 10531 + env->bus_model = def->bus_model; 10532 + env->insns_flags = def->insns_flags; 10533 + env->insns_flags2 = def->insns_flags2; 10534 + env->flags = def->flags; 10535 + env->bfd_mach = def->bfd_mach; 10536 + env->check_pow = def->check_pow; 10537 + 10538 + #if defined(TARGET_PPC64) 10539 + if (def->sps) { 10540 + env->sps = *def->sps; 10541 + } else if (env->mmu_model & POWERPC_MMU_64) { 10542 + /* Use default sets of page sizes */ 10543 + static const struct ppc_segment_page_sizes defsps = { 10544 + .sps = { 10545 + { .page_shift = 12, /* 4K */ 10546 + .slb_enc = 0, 10547 + .enc = { { .page_shift = 12, .pte_enc = 0 } } 10548 + }, 10549 + { .page_shift = 24, /* 16M */ 10550 + .slb_enc = 0x100, 10551 + .enc = { { .page_shift = 24, .pte_enc = 0 } } 10552 + }, 10553 + }, 10554 + }; 10555 + env->sps = defsps; 10556 + } 10557 + #endif /* defined(TARGET_PPC64) */ 10445 10558 } 10446 10559 10447 10560 static void ppc_cpu_class_init(ObjectClass *oc, void *data) ··· 10458 10571 .parent = TYPE_CPU, 10459 10572 .instance_size = sizeof(PowerPCCPU), 10460 10573 .instance_init = ppc_cpu_initfn, 10461 - .abstract = false, 10574 + .abstract = true, 10462 10575 .class_size = sizeof(PowerPCCPUClass), 10463 10576 .class_init = ppc_cpu_class_init, 10464 10577 }; 10465 10578 10466 10579 static void ppc_cpu_register_types(void) 10467 10580 { 10581 + int i; 10582 + 10468 10583 type_register_static(&ppc_cpu_type_info); 10584 + 10585 + for (i = 0; i < ARRAY_SIZE(ppc_defs); i++) { 10586 + const ppc_def_t *def = &ppc_defs[i]; 10587 + #if defined(TARGET_PPCEMB) 10588 + /* When using the ppcemb target, we only support 440 style cores */ 10589 + if (def->mmu_model != POWERPC_MMU_BOOKE) { 10590 + continue; 10591 + } 10592 + #endif 10593 + ppc_cpu_register_model(def); 10594 + } 10469 10595 } 10470 10596 10471 10597 type_init(ppc_cpu_register_types)