summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure1
-rw-r--r--hw/i386/kvmvapic.c6
-rw-r--r--hw/net/spapr_llan.c2
-rw-r--r--hw/ppc/e500.c31
-rw-r--r--hw/ppc/spapr_iommu.c14
-rw-r--r--hw/s390x/ipl.c38
-rw-r--r--pc-bios/README4
-rw-r--r--pc-bios/s390-ccw.imgbin9432 -> 9432 bytes
-rw-r--r--pc-bios/s390-ccw/main.c24
-rw-r--r--pc-bios/s390-ccw/start.S2
-rw-r--r--pc-bios/slof.binbin880832 -> 909720 bytes
m---------roms/SLOF0
-rw-r--r--target-ppc/cpu.h3
-rw-r--r--target-ppc/mmu_helper.c4
-rw-r--r--target-ppc/translate.c32
-rw-r--r--target-ppc/translate_init.c4
16 files changed, 120 insertions, 45 deletions
diff --git a/configure b/configure
index a9ff4ad882..9439f1c727 100755
--- a/configure
+++ b/configure
@@ -4518,6 +4518,7 @@ for bios_file in \
$source_path/pc-bios/*.aml \
$source_path/pc-bios/*.rom \
$source_path/pc-bios/*.dtb \
+ $source_path/pc-bios/*.img \
$source_path/pc-bios/openbios-* \
$source_path/pc-bios/palcode-*
do
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 5b558aa180..655483bd1d 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -687,8 +687,14 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
}
}
+static uint64_t vapic_read(void *opaque, hwaddr addr, unsigned size)
+{
+ return 0xffffffff;
+}
+
static const MemoryRegionOps vapic_ops = {
.write = vapic_write,
+ .read = vapic_read,
.endianness = DEVICE_NATIVE_ENDIAN,
};
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index 3150add3c1..03a09f2047 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -336,6 +336,8 @@ static target_ulong h_register_logical_lan(PowerPCCPU *cpu,
spapr_vio_dma_set(sdev, VLAN_BD_ADDR(rec_queue), 0, VLAN_BD_LEN(rec_queue));
dev->isopen = 1;
+ qemu_flush_queued_packets(qemu_get_queue(dev->nic));
+
return H_SUCCESS;
}
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index c1bdb6be98..c9ae51211e 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -37,6 +37,7 @@
#include "qemu/host-utils.h"
#include "hw/pci-host/ppce500.h"
+#define EPAPR_MAGIC (0x45504150)
#define BINARY_DEVICE_TREE_FILE "mpc8544ds.dtb"
#define UIMAGE_LOAD_BASE 0
#define DTC_LOAD_PAD 0x1800000
@@ -393,11 +394,10 @@ static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
return 63 - clz64(size >> 10);
}
-static void mmubooke_create_initial_mapping(CPUPPCState *env)
+static int booke206_initial_map_tsize(CPUPPCState *env)
{
struct boot_info *bi = env->load_info;
- ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
- hwaddr size, dt_end;
+ hwaddr dt_end;
int ps;
/* Our initial TLB entry needs to cover everything from 0 to
@@ -408,6 +408,24 @@ static void mmubooke_create_initial_mapping(CPUPPCState *env)
/* e500v2 can only do even TLB size bits */
ps++;
}
+ return ps;
+}
+
+static uint64_t mmubooke_initial_mapsize(CPUPPCState *env)
+{
+ int tsize;
+
+ tsize = booke206_initial_map_tsize(env);
+ return (1ULL << 10 << tsize);
+}
+
+static void mmubooke_create_initial_mapping(CPUPPCState *env)
+{
+ ppcmas_tlb_t *tlb = booke206_get_tlbm(env, 1, 0, 0);
+ hwaddr size;
+ int ps;
+
+ ps = booke206_initial_map_tsize(env);
size = (ps << MAS1_TSIZE_SHIFT);
tlb->mas1 = MAS1_VALID | size;
tlb->mas2 = 0;
@@ -444,6 +462,12 @@ static void ppce500_cpu_reset(void *opaque)
cs->halted = 0;
env->gpr[1] = (16<<20) - 8;
env->gpr[3] = bi->dt_base;
+ env->gpr[4] = 0;
+ env->gpr[5] = 0;
+ env->gpr[6] = EPAPR_MAGIC;
+ env->gpr[7] = mmubooke_initial_mapsize(env);
+ env->gpr[8] = 0;
+ env->gpr[9] = 0;
env->nip = bi->entry;
mmubooke_create_initial_mapping(env);
}
@@ -523,6 +547,7 @@ void ppce500_init(PPCE500Params *params)
/* Fixup Memory size on a alignment boundary */
ram_size &= ~(RAM_SIZES_ALIGN - 1);
+ params->ram_size = ram_size;
/* Register Memory */
memory_region_init_ram(ram, "mpc8544ds.ram", ram_size);
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index d2782cfb39..e1fe94115f 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -55,6 +55,12 @@ static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn)
{
sPAPRTCETable *tcet;
+ if (liobn & 0xFFFFFFFF00000000ULL) {
+ hcall_dprintf("Request for out-of-bounds LIOBN 0x" TARGET_FMT_lx "\n",
+ liobn);
+ return NULL;
+ }
+
QLIST_FOREACH(tcet, &spapr_tce_tables, list) {
if (tcet->liobn == liobn) {
return tcet;
@@ -199,7 +205,7 @@ static target_ulong put_tce_emu(sPAPRTCETable *tcet, target_ulong ioba,
sPAPRTCE *tcep;
if (ioba >= tcet->window_size) {
- hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x"
+ hcall_dprintf("spapr_vio_put_tce on out-of-bounds IOBA 0x"
TARGET_FMT_lx "\n", ioba);
return H_PARAMETER;
}
@@ -218,12 +224,6 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
target_ulong tce = args[2];
sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
- if (liobn & 0xFFFFFFFF00000000ULL) {
- hcall_dprintf("spapr_vio_put_tce on out-of-boundsw LIOBN "
- TARGET_FMT_lx "\n", liobn);
- return H_PARAMETER;
- }
-
ioba &= ~(SPAPR_TCE_PAGE_SIZE - 1);
if (tcet) {
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index ace5ff50d1..0aeb003c9d 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -16,6 +16,8 @@
#include "elf.h"
#include "hw/loader.h"
#include "hw/sysbus.h"
+#include "hw/s390x/virtio-ccw.h"
+#include "hw/s390x/css.h"
#define KERN_IMAGE_START 0x010000UL
#define KERN_PARM_AREA 0x010480UL
@@ -57,16 +59,6 @@ typedef struct S390IPLState {
} S390IPLState;
-static void s390_ipl_cpu(uint64_t pswaddr)
-{
- S390CPU *cpu = S390_CPU(qemu_get_cpu(0));
- CPUS390XState *env = &cpu->env;
-
- env->psw.addr = pswaddr;
- env->psw.mask = IPL_PSW_MASK;
- s390_add_running_cpu(cpu);
-}
-
static int s390_ipl_init(SysBusDevice *dev)
{
S390IPLState *ipl = S390_IPL(dev);
@@ -82,6 +74,10 @@ static int s390_ipl_init(SysBusDevice *dev)
}
bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+ if (bios_filename == NULL) {
+ hw_error("could not find stage1 bootloader\n");
+ }
+
bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL,
NULL, 1, ELF_MACHINE, 0);
if (bios_size == -1UL) {
@@ -151,8 +147,28 @@ static Property s390_ipl_properties[] = {
static void s390_ipl_reset(DeviceState *dev)
{
S390IPLState *ipl = S390_IPL(dev);
+ S390CPU *cpu = S390_CPU(qemu_get_cpu(0));
+ CPUS390XState *env = &cpu->env;
- s390_ipl_cpu(ipl->start_addr);
+ env->psw.addr = ipl->start_addr;
+ env->psw.mask = IPL_PSW_MASK;
+
+ if (!ipl->kernel) {
+ /* booting firmware, tell what device to boot from */
+ DeviceState *dev_st = get_boot_device(0);
+ VirtioCcwDevice *ccw_dev = (VirtioCcwDevice *) object_dynamic_cast(
+ OBJECT(&(dev_st->parent_obj)), "virtio-blk-ccw");
+
+ if (ccw_dev) {
+ env->regs[7] = ccw_dev->sch->cssid << 24 |
+ ccw_dev->sch->ssid << 16 |
+ ccw_dev->sch->devno;
+ } else {
+ env->regs[7] = -1;
+ }
+ }
+
+ s390_add_running_cpu(cpu);
}
static void s390_ipl_class_init(ObjectClass *klass, void *data)
diff --git a/pc-bios/README b/pc-bios/README
index 7b4dfed6cf..030d92a049 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -16,8 +16,8 @@
- SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
implementation for certain IBM POWER hardware. The sources are at
- https://github.com/dgibson/SLOF, and the image currently in qemu is
- built from git tag qemu-slof-20121018.
+ https://github.com/aik/SLOF, and the image currently in qemu is
+ built from git tag qemu-slof-20130430.
- sgabios (the Serial Graphics Adapter option ROM) provides a means for
legacy x86 software to communicate with an attached serial console as
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index 149cf70140..1b2a11e728 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index fd40fa582a..1665c57225 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -12,6 +12,7 @@
struct subchannel_id blk_schid;
char stack[PAGE_SIZE * 8] __attribute__((__aligned__(PAGE_SIZE)));
+uint64_t boot_value;
void virtio_panic(const char *string)
{
@@ -20,15 +21,22 @@ void virtio_panic(const char *string)
while (1) { }
}
-static void virtio_setup(void)
+static void virtio_setup(uint64_t dev_info)
{
struct schib schib;
int i;
int r;
bool found = false;
-
+ bool check_devno = false;
+ uint16_t dev_no = -1;
blk_schid.one = 1;
+ if (dev_info != -1) {
+ check_devno = true;
+ dev_no = dev_info & 0xffff;
+ debug_print_int("device no. ", dev_no);
+ }
+
for (i = 0; i < 0x10000; i++) {
blk_schid.sch_no = i;
r = stsch_err(blk_schid, &schib);
@@ -36,9 +44,11 @@ static void virtio_setup(void)
break;
}
if (schib.pmcw.dnv) {
- if (virtio_is_blk(blk_schid)) {
- found = true;
- break;
+ if (!check_devno || (schib.pmcw.dev == dev_no)) {
+ if (virtio_is_blk(blk_schid)) {
+ found = true;
+ break;
+ }
}
}
}
@@ -53,7 +63,9 @@ static void virtio_setup(void)
int main(void)
{
sclp_setup();
- virtio_setup();
+ debug_print_int("boot reg[7] ", boot_value);
+ virtio_setup(boot_value);
+
if (zipl_load() < 0)
sclp_print("Failed to load OS from hard disk\n");
disabled_wait();
diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
index 09deee7fc0..5d5df0d616 100644
--- a/pc-bios/s390-ccw/start.S
+++ b/pc-bios/s390-ccw/start.S
@@ -14,6 +14,8 @@
_start:
larl %r15, stack + 0x8000 /* Set up stack */
+larl %r6, boot_value
+stg %r7, 0(%r6) /* save the boot_value before any function calls */
j main /* And call C */
/*
diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin
index 3410f4fff4..092e58a46e 100644
--- a/pc-bios/slof.bin
+++ b/pc-bios/slof.bin
Binary files differ
diff --git a/roms/SLOF b/roms/SLOF
-Subproject 0ad10f26c94a86a0c9c3970e53f9a9f6a744055
+Subproject 8cfdfc43f4c4c8c8dfa4b7cf16f7c19c84eee81
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 7cacb56bc5..aa1d013c31 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -119,6 +119,9 @@ enum powerpc_mmu_t {
/* Architecture 2.06 variant */
POWERPC_MMU_2_06 = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
| POWERPC_MMU_AMR | 0x00000003,
+ /* Architecture 2.06 "degraded" (no 1T segments) */
+ POWERPC_MMU_2_06a = POWERPC_MMU_64 | POWERPC_MMU_AMR
+ | 0x00000003,
/* Architecture 2.06 "degraded" (no 1T segments or AMR) */
POWERPC_MMU_2_06d = POWERPC_MMU_64 | 0x00000003,
#endif /* defined(TARGET_PPC64) */
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index acf01331f1..68d5415e54 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -1188,6 +1188,7 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env)
#if defined(TARGET_PPC64)
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
dump_slb(f, cpu_fprintf, env);
break;
@@ -1324,6 +1325,7 @@ hwaddr cpu_get_phys_page_debug(CPUPPCState *env, target_ulong addr)
#if defined(TARGET_PPC64)
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
return ppc_hash64_get_phys_page_debug(env, addr);
#endif
@@ -1815,6 +1817,7 @@ void ppc_tlb_invalidate_all(CPUPPCState *env)
#if defined(TARGET_PPC64)
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
#endif /* defined(TARGET_PPC64) */
tlb_flush(env, 1);
@@ -1884,6 +1887,7 @@ void ppc_tlb_invalidate_one(CPUPPCState *env, target_ulong addr)
#if defined(TARGET_PPC64)
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
+ case POWERPC_MMU_2_06a:
case POWERPC_MMU_2_06d:
/* tlbie invalidate TLBs for all segments */
/* XXX: given the fact that there are too many segments to invalidate,
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 1a84653983..0886f4d699 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -4005,19 +4005,19 @@ static inline void gen_op_mfspr(DisasContext *ctx)
* allowing userland application to read the PVR
*/
if (sprn != SPR_PVR) {
- qemu_log("Trying to read privileged spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to read privileged spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
+ qemu_log("Trying to read privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to read privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
}
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
- qemu_log("Trying to read invalid spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to read invalid spr %d %03x at " TARGET_FMT_lx "\n",
- sprn, sprn, ctx->nip);
+ qemu_log("Trying to read invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to read invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
@@ -4150,18 +4150,18 @@ static void gen_mtspr(DisasContext *ctx)
(*write_cb)(ctx, sprn, rS(ctx->opcode));
} else {
/* Privilege exception */
- qemu_log("Trying to write privileged spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to write privileged spr %d %03x at " TARGET_FMT_lx
- "\n", sprn, sprn, ctx->nip);
+ qemu_log("Trying to write privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to write privileged spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
}
} else {
/* Not defined */
- qemu_log("Trying to write invalid spr %d %03x at "
- TARGET_FMT_lx "\n", sprn, sprn, ctx->nip);
- printf("Trying to write invalid spr %d %03x at " TARGET_FMT_lx "\n",
- sprn, sprn, ctx->nip);
+ qemu_log("Trying to write invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
+ printf("Trying to write invalid spr %d (0x%03x) at "
+ TARGET_FMT_lx "\n", sprn, sprn, ctx->nip - 4);
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR);
}
}
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 6feb62abcd..021a31e209 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7010,6 +7010,10 @@ static void init_proc_POWER7 (CPUPPCState *env)
&spr_read_generic, &spr_write_generic,
&spr_read_generic, &spr_write_generic,
0x00000000);
+ spr_register(env, SPR_PPR, "PPR",
+ &spr_read_generic, &spr_write_generic,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
#if !defined(CONFIG_USER_ONLY)
env->slb_nr = 32;
#endif