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

* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf:
  pseries: Cleanup duplications of ics_valid_irq() code
  pseries: Clean up inconsistent variable name in xics.c
  target-ppc: Extend FPU state for newer POWER CPUs
  target-ppc: Rework storage of VPA registration state
  Revert "PPC: pseries: Remove hack for PIO window"
This commit is contained in:
Aurelien Jarno 2012-11-01 16:42:49 +01:00
commit 46a3f23413
6 changed files with 79 additions and 26 deletions

View File

@ -439,6 +439,43 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level); qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level);
} }
static uint64_t spapr_io_read(void *opaque, hwaddr addr,
unsigned size)
{
switch (size) {
case 1:
return cpu_inb(addr);
case 2:
return cpu_inw(addr);
case 4:
return cpu_inl(addr);
}
assert(0);
}
static void spapr_io_write(void *opaque, hwaddr addr,
uint64_t data, unsigned size)
{
switch (size) {
case 1:
cpu_outb(addr, data);
return;
case 2:
cpu_outw(addr, data);
return;
case 4:
cpu_outl(addr, data);
return;
}
assert(0);
}
static const MemoryRegionOps spapr_io_ops = {
.endianness = DEVICE_LITTLE_ENDIAN,
.read = spapr_io_read,
.write = spapr_io_write
};
/* /*
* MSI/MSIX memory region implementation. * MSI/MSIX memory region implementation.
* The handler handles both MSI and MSIX. * The handler handles both MSI and MSIX.
@ -508,9 +545,14 @@ static int spapr_phb_init(SysBusDevice *s)
* old_portion are updated */ * old_portion are updated */
sprintf(namebuf, "%s.io", sphb->dtbusname); sprintf(namebuf, "%s.io", sphb->dtbusname);
memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE); memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE);
/* FIXME: fix to support multiple PHBs */
memory_region_add_subregion(get_system_io(), 0, &sphb->iospace);
sprintf(namebuf, "%s.io-alias", sphb->dtbusname);
memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb,
namebuf, SPAPR_PCI_IO_WIN_SIZE);
memory_region_add_subregion(get_system_memory(), sphb->io_win_addr, memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
&sphb->iospace); &sphb->iowindow);
/* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors, /* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
* we need to allocate some memory to catch those writes coming * we need to allocate some memory to catch those writes coming

View File

@ -44,7 +44,7 @@ typedef struct sPAPRPHBState {
MemoryRegion memspace, iospace; MemoryRegion memspace, iospace;
hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size; hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
hwaddr msi_win_addr; hwaddr msi_win_addr;
MemoryRegion memwindow, msiwindow; MemoryRegion memwindow, iowindow, msiwindow;
uint32_t dma_liobn; uint32_t dma_liobn;
uint64_t dma_window_start; uint64_t dma_window_start;

View File

@ -108,13 +108,13 @@ static void icp_set_cppr(struct icp_state *icp, int server, uint8_t cppr)
} }
} }
static void icp_set_mfrr(struct icp_state *icp, int nr, uint8_t mfrr) static void icp_set_mfrr(struct icp_state *icp, int server, uint8_t mfrr)
{ {
struct icp_server_state *ss = icp->ss + nr; struct icp_server_state *ss = icp->ss + server;
ss->mfrr = mfrr; ss->mfrr = mfrr;
if (mfrr < CPPR(ss)) { if (mfrr < CPPR(ss)) {
icp_check_ipi(icp, nr); icp_check_ipi(icp, server);
} }
} }
@ -326,8 +326,7 @@ static void ics_eoi(struct ics_state *ics, int nr)
qemu_irq xics_get_qirq(struct icp_state *icp, int irq) qemu_irq xics_get_qirq(struct icp_state *icp, int irq)
{ {
if ((irq < icp->ics->offset) if (!ics_valid_irq(icp->ics, irq)) {
|| (irq >= (icp->ics->offset + icp->ics->nr_irqs))) {
return NULL; return NULL;
} }
@ -336,8 +335,7 @@ qemu_irq xics_get_qirq(struct icp_state *icp, int irq)
void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi) void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi)
{ {
assert((irq >= icp->ics->offset) assert(ics_valid_irq(icp->ics, irq));
&& (irq < (icp->ics->offset + icp->ics->nr_irqs)));
icp->ics->irqs[irq - icp->ics->offset].lsi = lsi; icp->ics->irqs[irq - icp->ics->offset].lsi = lsi;
} }

View File

@ -963,7 +963,7 @@ struct CPUPPCState {
/* floating point registers */ /* floating point registers */
float64 fpr[32]; float64 fpr[32];
/* floating point status and control register */ /* floating point status and control register */
uint32_t fpscr; target_ulong fpscr;
/* Next instruction pointer */ /* Next instruction pointer */
target_ulong nip; target_ulong nip;
@ -1014,6 +1014,8 @@ struct CPUPPCState {
/* Altivec registers */ /* Altivec registers */
ppc_avr_t avr[32]; ppc_avr_t avr[32];
uint32_t vscr; uint32_t vscr;
/* VSX registers */
uint64_t vsr[32];
/* SPE registers */ /* SPE registers */
uint64_t spe_acc; uint64_t spe_acc;
uint32_t spe_fscr; uint32_t spe_fscr;
@ -1045,9 +1047,9 @@ struct CPUPPCState {
#endif #endif
#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) #if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY)
hwaddr vpa_addr; uint64_t vpa_addr;
hwaddr slb_shadow_addr, slb_shadow_size; uint64_t slb_shadow_addr, slb_shadow_size;
hwaddr dtl_addr, dtl_size; uint64_t dtl_addr, dtl_size;
#endif /* TARGET_PPC64 */ #endif /* TARGET_PPC64 */
int error_code; int error_code;

View File

@ -6,6 +6,7 @@ void cpu_save(QEMUFile *f, void *opaque)
{ {
CPUPPCState *env = (CPUPPCState *)opaque; CPUPPCState *env = (CPUPPCState *)opaque;
unsigned int i, j; unsigned int i, j;
uint32_t fpscr;
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
qemu_put_betls(f, &env->gpr[i]); qemu_put_betls(f, &env->gpr[i]);
@ -30,7 +31,8 @@ void cpu_save(QEMUFile *f, void *opaque)
u.d = env->fpr[i]; u.d = env->fpr[i];
qemu_put_be64(f, u.l); qemu_put_be64(f, u.l);
} }
qemu_put_be32s(f, &env->fpscr); fpscr = env->fpscr;
qemu_put_be32s(f, &fpscr);
qemu_put_sbe32s(f, &env->access_type); qemu_put_sbe32s(f, &env->access_type);
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
qemu_put_betls(f, &env->asr); qemu_put_betls(f, &env->asr);
@ -90,6 +92,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
CPUPPCState *env = (CPUPPCState *)opaque; CPUPPCState *env = (CPUPPCState *)opaque;
unsigned int i, j; unsigned int i, j;
target_ulong sdr1; target_ulong sdr1;
uint32_t fpscr;
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++)
qemu_get_betls(f, &env->gpr[i]); qemu_get_betls(f, &env->gpr[i]);
@ -114,7 +117,8 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
u.l = qemu_get_be64(f); u.l = qemu_get_be64(f);
env->fpr[i] = u.d; env->fpr[i] = u.d;
} }
qemu_get_be32s(f, &env->fpscr); qemu_get_be32s(f, &fpscr);
env->fpscr = fpscr;
qemu_get_sbe32s(f, &env->access_type); qemu_get_sbe32s(f, &env->access_type);
#if defined(TARGET_PPC64) #if defined(TARGET_PPC64)
qemu_get_betls(f, &env->asr); qemu_get_betls(f, &env->asr);

View File

@ -68,7 +68,7 @@ static TCGv cpu_cfar;
#endif #endif
static TCGv cpu_xer; static TCGv cpu_xer;
static TCGv cpu_reserve; static TCGv cpu_reserve;
static TCGv_i32 cpu_fpscr; static TCGv cpu_fpscr;
static TCGv_i32 cpu_access_type; static TCGv_i32 cpu_access_type;
#include "gen-icount.h" #include "gen-icount.h"
@ -163,8 +163,8 @@ void ppc_translate_init(void)
offsetof(CPUPPCState, reserve_addr), offsetof(CPUPPCState, reserve_addr),
"reserve_addr"); "reserve_addr");
cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0, cpu_fpscr = tcg_global_mem_new(TCG_AREG0,
offsetof(CPUPPCState, fpscr), "fpscr"); offsetof(CPUPPCState, fpscr), "fpscr");
cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0, cpu_access_type = tcg_global_mem_new_i32(TCG_AREG0,
offsetof(CPUPPCState, access_type), "access_type"); offsetof(CPUPPCState, access_type), "access_type");
@ -2302,6 +2302,7 @@ GEN_FLOAT_B(neg, 0x08, 0x01, 0, PPC_FLOAT);
/* mcrfs */ /* mcrfs */
static void gen_mcrfs(DisasContext *ctx) static void gen_mcrfs(DisasContext *ctx)
{ {
TCGv tmp = tcg_temp_new();
int bfa; int bfa;
if (unlikely(!ctx->fpu_enabled)) { if (unlikely(!ctx->fpu_enabled)) {
@ -2309,9 +2310,11 @@ static void gen_mcrfs(DisasContext *ctx)
return; return;
} }
bfa = 4 * (7 - crfS(ctx->opcode)); bfa = 4 * (7 - crfS(ctx->opcode));
tcg_gen_shri_i32(cpu_crf[crfD(ctx->opcode)], cpu_fpscr, bfa); tcg_gen_shri_tl(tmp, cpu_fpscr, bfa);
tcg_gen_trunc_tl_i32(cpu_crf[crfD(ctx->opcode)], tmp);
tcg_temp_free(tmp);
tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf); tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], 0xf);
tcg_gen_andi_i32(cpu_fpscr, cpu_fpscr, ~(0xF << bfa)); tcg_gen_andi_tl(cpu_fpscr, cpu_fpscr, ~(0xF << bfa));
} }
/* mffs */ /* mffs */
@ -2322,7 +2325,7 @@ static void gen_mffs(DisasContext *ctx)
return; return;
} }
gen_reset_fpstatus(); gen_reset_fpstatus();
tcg_gen_extu_i32_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr); tcg_gen_extu_tl_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpscr);
gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0); gen_compute_fprf(cpu_fpr[rD(ctx->opcode)], 0, Rc(ctx->opcode) != 0);
} }
@ -2346,7 +2349,8 @@ static void gen_mtfsb0(DisasContext *ctx)
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
if (unlikely(Rc(ctx->opcode) != 0)) { if (unlikely(Rc(ctx->opcode) != 0)) {
tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
} }
} }
@ -2371,7 +2375,8 @@ static void gen_mtfsb1(DisasContext *ctx)
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
} }
if (unlikely(Rc(ctx->opcode) != 0)) { if (unlikely(Rc(ctx->opcode) != 0)) {
tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
} }
/* We can raise a differed exception */ /* We can raise a differed exception */
gen_helper_float_check_status(cpu_env); gen_helper_float_check_status(cpu_env);
@ -2397,7 +2402,8 @@ static void gen_mtfsf(DisasContext *ctx)
gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0); gen_helper_store_fpscr(cpu_env, cpu_fpr[rB(ctx->opcode)], t0);
tcg_temp_free_i32(t0); tcg_temp_free_i32(t0);
if (unlikely(Rc(ctx->opcode) != 0)) { if (unlikely(Rc(ctx->opcode) != 0)) {
tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
} }
/* We can raise a differed exception */ /* We can raise a differed exception */
gen_helper_float_check_status(cpu_env); gen_helper_float_check_status(cpu_env);
@ -2425,7 +2431,8 @@ static void gen_mtfsfi(DisasContext *ctx)
tcg_temp_free_i64(t0); tcg_temp_free_i64(t0);
tcg_temp_free_i32(t1); tcg_temp_free_i32(t1);
if (unlikely(Rc(ctx->opcode) != 0)) { if (unlikely(Rc(ctx->opcode) != 0)) {
tcg_gen_shri_i32(cpu_crf[1], cpu_fpscr, FPSCR_OX); tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_fpscr);
tcg_gen_shri_i32(cpu_crf[1], cpu_crf[1], FPSCR_OX);
} }
/* We can raise a differed exception */ /* We can raise a differed exception */
gen_helper_float_check_status(cpu_env); gen_helper_float_check_status(cpu_env);
@ -9463,7 +9470,7 @@ void cpu_dump_state (CPUPPCState *env, FILE *f, fprintf_function cpu_fprintf,
if ((i & (RFPL - 1)) == (RFPL - 1)) if ((i & (RFPL - 1)) == (RFPL - 1))
cpu_fprintf(f, "\n"); cpu_fprintf(f, "\n");
} }
cpu_fprintf(f, "FPSCR %08x\n", env->fpscr); cpu_fprintf(f, "FPSCR " TARGET_FMT_lx "\n", env->fpscr);
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
cpu_fprintf(f, " SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx cpu_fprintf(f, " SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx
" PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n", " PVR " TARGET_FMT_lx " VRSAVE " TARGET_FMT_lx "\n",