Commit 75f0585f authored by Blue Swirl's avatar Blue Swirl
Browse files

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

* 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf:
  PPC: KVM: Add support for EPR with KVM
  openpic: export e500 epr enable into a ppc.c function
  Update Linux kernel headers
  PPC: e500: Change in-memory order of load blobs
  PPC: Provide zero SVR for -cpu e500mc and e5500
  PPC: E500: Calculate loading blob offsets properly
  openpic: set mixed mode as supported
  openpic: unify gcr mode mask updates
  openpic: move gcr write into a function
parents 67c4f2d0 5b95b8b9
Loading
Loading
Loading
Loading
+23 −17
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include "sysbus.h"
#include "pci/msi.h"
#include "qemu/bitops.h"
#include "ppc.h"

//#define DEBUG_OPENPIC

@@ -644,6 +645,26 @@ static inline void write_IRQreg_ivpr(OpenPICState *opp, int n_IRQ, uint32_t val)
            opp->src[n_IRQ].ivpr);
}

static void openpic_gcr_write(OpenPICState *opp, uint64_t val)
{
    bool mpic_proxy = false;

    if (val & GCR_RESET) {
        openpic_reset(&opp->busdev.qdev);
        return;
    }

    opp->gcr &= ~opp->mpic_mode_mask;
    opp->gcr |= val & opp->mpic_mode_mask;

    /* Set external proxy mode */
    if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
        mpic_proxy = true;
    }

    ppce500_set_mpic_proxy(mpic_proxy);
}

static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
                              unsigned len)
{
@@ -672,23 +693,7 @@ static void openpic_gbl_write(void *opaque, hwaddr addr, uint64_t val,
    case 0x1000: /* FRR */
        break;
    case 0x1020: /* GCR */
        if (val & GCR_RESET) {
            openpic_reset(&opp->busdev.qdev);
        } else if (opp->mpic_mode_mask) {
            CPUArchState *env;
            int mpic_proxy = 0;

            opp->gcr &= ~opp->mpic_mode_mask;
            opp->gcr |= val & opp->mpic_mode_mask;

            /* Set external proxy mode */
            if ((val & opp->mpic_mode_mask) == GCR_MODE_PROXY) {
                mpic_proxy = 1;
            }
            for (env = first_cpu; env != NULL; env = env->next_cpu) {
                env->mpic_proxy = mpic_proxy;
            }
        }
        openpic_gcr_write(opp, val);
        break;
    case 0x1080: /* VIR */
        break;
@@ -1464,6 +1469,7 @@ static int openpic_init(SysBusDevice *dev)
        opp->irq_ipi0 = RAVEN_IPI_IRQ;
        opp->irq_tim0 = RAVEN_TMR_IRQ;
        opp->brr1 = -1;
        opp->mpic_mode_mask = GCR_MODE_MIXED;
        list = list_le;
        /* Don't map MSI region */
        list[2].map = false;
+17 −0
Original line number Diff line number Diff line
@@ -428,6 +428,23 @@ void ppce500_irq_init(CPUPPCState *env)
    env->irq_inputs = (void **)qemu_allocate_irqs(&ppce500_set_irq,
                                                  cpu, PPCE500_INPUT_NB);
}

/* Enable or Disable the E500 EPR capability */
void ppce500_set_mpic_proxy(bool enabled)
{
    CPUPPCState *env;

    for (env = first_cpu; env != NULL; env = env->next_cpu) {
        PowerPCCPU *cpu = ppc_env_get_cpu(env);
        CPUState *cs = CPU(cpu);

        env->mpic_proxy = enabled;
        if (kvm_enabled()) {
            kvmppc_set_mpic_proxy(POWERPC_CPU(cs), enabled);
        }
    }
}

/*****************************************************************************/
/* PowerPC time base and decrementer emulation */

+2 −0
Original line number Diff line number Diff line
@@ -73,6 +73,8 @@ void ppc6xx_irq_init (CPUPPCState *env);
void ppc970_irq_init (CPUPPCState *env);
void ppcPOWER7_irq_init (CPUPPCState *env);

void ppce500_set_mpic_proxy(bool enabled);

/* PPC machines for OpenBIOS */
enum {
    ARCH_PREP = 0,
+13 −4
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#define UIMAGE_LOAD_BASE           0
#define DTC_LOAD_PAD               0x1800000
#define DTC_PAD_MASK               0xFFFFF
#define DTB_MAX_SIZE               (8 * 1024 * 1024)
#define INITRD_LOAD_PAD            0x2000000
#define INITRD_PAD_MASK            0xFFFFFF

@@ -464,6 +465,7 @@ void ppce500_init(PPCE500Params *params)
    target_ulong dt_base = 0;
    target_ulong initrd_base = 0;
    target_long initrd_size = 0;
    target_ulong cur_base = 0;
    int i = 0, j, k;
    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};
    qemu_irq **irqs, *mpic;
@@ -626,12 +628,17 @@ void ppce500_init(PPCE500Params *params)
                    params->kernel_filename);
            exit(1);
        }

        cur_base = loadaddr + kernel_size;

        /* Reserve space for dtb */
        dt_base = (cur_base + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
        cur_base += DTB_MAX_SIZE;
    }

    /* Load initrd. */
    if (params->initrd_filename) {
        initrd_base = (loadaddr + kernel_size + INITRD_LOAD_PAD) &
            ~INITRD_PAD_MASK;
        initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
        initrd_size = load_image_targphys(params->initrd_filename, initrd_base,
                                          ram_size - initrd_base);

@@ -640,6 +647,8 @@ void ppce500_init(PPCE500Params *params)
                    params->initrd_filename);
            exit(1);
        }

        cur_base = initrd_base + initrd_size;
    }

    /* If we're loading a kernel directly, we must load the device tree too. */
@@ -647,13 +656,13 @@ void ppce500_init(PPCE500Params *params)
        struct boot_info *boot_info;
        int dt_size;

        dt_base = (loadaddr + kernel_size + DTC_LOAD_PAD) & ~DTC_PAD_MASK;
        dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base,
                                           initrd_size);
        if (dt_size < 0) {
            fprintf(stderr, "couldn't load device tree\n");
            exit(1);
        }
        assert(dt_size < DTB_MAX_SIZE);

        boot_info = env->load_info;
        boot_info->entry = entry;
+5 −1
Original line number Diff line number Diff line
@@ -114,7 +114,10 @@ struct kvm_regs {
/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
#define KVM_SREGS_E_SPE			(1 << 9)

/* External Proxy (EXP) -- EPR */
/*
 * DEPRECATED! USE ONE_REG FOR THIS ONE!
 * External Proxy (EXP) -- EPR
 */
#define KVM_SREGS_EXP			(1 << 10)

/* External PID (E.PD) -- EPSC/EPLC */
@@ -412,5 +415,6 @@ struct kvm_get_htab_header {
#define KVM_REG_PPC_VPA_DTL	(KVM_REG_PPC | KVM_REG_SIZE_U128 | 0x84)

#define KVM_REG_PPC_EPCR	(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x85)
#define KVM_REG_PPC_EPR		(KVM_REG_PPC | KVM_REG_SIZE_U32 | 0x86)

#endif /* __LINUX_KVM_POWERPC_H */
Loading