diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2013-01-19 09:56:41 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2013-01-19 09:56:41 +0000 |
commit | 75f0585f1718c575716021d11bfeb695129f785d (patch) | |
tree | bb1a9ea23af027b8c37ae4b1147f801d32c71ce1 /hw | |
parent | 67c4f2d0e11de8ee534b17edafbcbcdcca4b0e9b (diff) | |
parent | 5b95b8b9c1b0cd30a31dbeffdaec35134248b6e9 (diff) | |
download | qemu-75f0585f1718c575716021d11bfeb695129f785d.tar.gz qemu-75f0585f1718c575716021d11bfeb695129f785d.tar.bz2 qemu-75f0585f1718c575716021d11bfeb695129f785d.zip |
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
Diffstat (limited to 'hw')
-rw-r--r-- | hw/openpic.c | 40 | ||||
-rw-r--r-- | hw/ppc.c | 17 | ||||
-rw-r--r-- | hw/ppc.h | 2 | ||||
-rw-r--r-- | hw/ppc/e500.c | 17 |
4 files changed, 55 insertions, 21 deletions
diff --git a/hw/openpic.c b/hw/openpic.c index f6cc07bd6e..cc8ec35b5d 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -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; @@ -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 */ @@ -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, diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 7b3e2e6723..c36821a99f 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -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 @@ -463,7 +464,8 @@ void ppce500_init(PPCE500Params *params) target_long kernel_size=0; target_ulong dt_base = 0; target_ulong initrd_base = 0; - target_long initrd_size=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; |