mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20171215-v2' into staging
s390x changes for 2.12: - Lots of tcg improvements: ccw hotplug is now working and we can run a Linux kernel built for z12 under tcg - zPCI improvements to get virtio-pci working - get rid of the cssid restrictions for virtual and non-virtual channel devices - we now support 8TB+ systems - 2.12 compat machine - fixes and cleanups # gpg: Signature made Fri 15 Dec 2017 10:57:01 GMT # gpg: using RSA key 0xDECF6B93C6F02FAF # gpg: Good signature from "Cornelia Huck <conny@cornelia-huck.de>" # gpg: aka "Cornelia Huck <huckc@linux.vnet.ibm.com>" # gpg: aka "Cornelia Huck <cornelia.huck@de.ibm.com>" # gpg: aka "Cornelia Huck <cohuck@kernel.org>" # gpg: aka "Cornelia Huck <cohuck@redhat.com>" # Primary key fingerprint: C3D0 D66D C362 4FF6 A8C0 18CE DECF 6B93 C6F0 2FAF * remotes/cohuck/tags/s390x-20171215-v2: (46 commits) s390-ccw-virtio: allow for systems larger that 7.999TB s390x: change the QEMU cpu model to a stripped down z12 s390x/tcg: we already implement the Set-Program-Parameter facility s390x/tcg: implement extract-CPU-time facility s390x/tcg: Implement SIGNAL ADAPTER instruction s390x/tcg: Implement STORE CHANNEL PATH STATUS s390x/tcg: wire up SET CHANNEL MONITOR s390x/tcg: wire up SET ADDRESS LIMIT s390x/tcg: implement Interlocked-Access Facility 2 s390x/tcg: ASI/ASGI/ALSI/ALSGI are atomic with Interlocked-acccess facility 1 s390x/tcg: wire up STORE CHANNEL REPORT WORD s390x/tcg: indicate value of TODPR in STCKE s390x/tcg: implement SET CLOCK PROGRAMMABLE FIELD s390x/tcg: fix and cleanup mcck injection s390x/kvm: factor out build_channel_report_mcic() into cpu.h s390x/css: attach css bridge s390x: deprecate s390-squash-mcss machine prop s390x/css: unrestrict cssids s390x/pci: search for subregion inside the BARs s390x/pci: move the memory region write from pcistg ... # Conflicts: # include/hw/compat.h Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
+1
-1
@@ -104,7 +104,7 @@ static void emulated_ccw_3270_realize(DeviceState *ds, Error **errp)
|
||||
SubchDev *sch;
|
||||
Error *err = NULL;
|
||||
|
||||
sch = css_create_sch(cdev->devno, true, cbus->squash_mcss, errp);
|
||||
sch = css_create_sch(cdev->devno, cbus->squash_mcss, errp);
|
||||
if (!sch) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,8 @@ VirtualCssBus *virtual_css_bus_init(void)
|
||||
|
||||
/* Create bridge device */
|
||||
dev = qdev_create(NULL, TYPE_VIRTUAL_CSS_BRIDGE);
|
||||
object_property_add_child(qdev_get_machine(), TYPE_VIRTUAL_CSS_BRIDGE,
|
||||
OBJECT(dev), NULL);
|
||||
qdev_init_nofail(dev);
|
||||
|
||||
/* Create bus on bridge device */
|
||||
@@ -123,6 +125,11 @@ static Property virtual_css_bridge_properties[] = {
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
static bool prop_get_true(Object *obj, Error **errp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
|
||||
@@ -131,6 +138,12 @@ static void virtual_css_bridge_class_init(ObjectClass *klass, void *data)
|
||||
hc->unplug = ccw_device_unplug;
|
||||
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
|
||||
dc->props = virtual_css_bridge_properties;
|
||||
object_class_property_add_bool(klass, "cssid-unrestricted",
|
||||
prop_get_true, NULL, NULL);
|
||||
object_class_property_set_description(klass, "cssid-unrestricted",
|
||||
"A css device can use any cssid, regardless whether virtual"
|
||||
" or not (read only, always true)",
|
||||
NULL);
|
||||
}
|
||||
|
||||
static const TypeInfo virtual_css_bridge_info = {
|
||||
|
||||
+4
-30
@@ -1723,12 +1723,6 @@ void css_undo_stcrw(CRW *crw)
|
||||
QTAILQ_INSERT_HEAD(&channel_subsys.pending_crws, crw_cont, sibling);
|
||||
}
|
||||
|
||||
int css_do_tpi(IOIntCode *int_code, int lowcore)
|
||||
{
|
||||
/* No pending interrupts for !KVM. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
|
||||
int rfmt, void *buf)
|
||||
{
|
||||
@@ -2370,21 +2364,11 @@ const PropertyInfo css_devid_ro_propinfo = {
|
||||
.get = get_css_devid,
|
||||
};
|
||||
|
||||
SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
|
||||
Error **errp)
|
||||
SubchDev *css_create_sch(CssDevId bus_id, bool squash_mcss, Error **errp)
|
||||
{
|
||||
uint16_t schid = 0;
|
||||
SubchDev *sch;
|
||||
|
||||
if (bus_id.valid) {
|
||||
if (is_virtual != (bus_id.cssid == VIRTUAL_CSSID)) {
|
||||
error_setg(errp, "cssid %hhx not valid for %s devices",
|
||||
bus_id.cssid,
|
||||
(is_virtual ? "virtual" : "non-virtual"));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (bus_id.valid) {
|
||||
if (squash_mcss) {
|
||||
bus_id.cssid = channel_subsys.default_cssid;
|
||||
@@ -2396,19 +2380,8 @@ SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
|
||||
bus_id.devid, &schid, errp)) {
|
||||
return NULL;
|
||||
}
|
||||
} else if (squash_mcss || is_virtual) {
|
||||
bus_id.cssid = channel_subsys.default_cssid;
|
||||
|
||||
if (!css_find_free_subch_and_devno(bus_id.cssid, &bus_id.ssid,
|
||||
&bus_id.devid, &schid, errp)) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
for (bus_id.cssid = 0; bus_id.cssid < MAX_CSSID; ++bus_id.cssid) {
|
||||
if (bus_id.cssid == VIRTUAL_CSSID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (bus_id.cssid = channel_subsys.default_cssid;;) {
|
||||
if (!channel_subsys.css[bus_id.cssid]) {
|
||||
css_create_css_image(bus_id.cssid, false);
|
||||
}
|
||||
@@ -2418,7 +2391,8 @@ SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
|
||||
NULL)) {
|
||||
break;
|
||||
}
|
||||
if (bus_id.cssid == MAX_CSSID) {
|
||||
bus_id.cssid = (bus_id.cssid + 1) % MAX_CSSID;
|
||||
if (bus_id.cssid == channel_subsys.default_cssid) {
|
||||
error_setg(errp, "Virtual channel subsystem is full!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ static void s390_ccw_realize(S390CCWDevice *cdev, char *sysfsdev, Error **errp)
|
||||
goto out_err_propagate;
|
||||
}
|
||||
|
||||
sch = css_create_sch(ccw_dev->devno, false, cbus->squash_mcss, &err);
|
||||
sch = css_create_sch(ccw_dev->devno, cbus->squash_mcss, &err);
|
||||
if (!sch) {
|
||||
goto out_mdevid_free;
|
||||
}
|
||||
|
||||
@@ -284,6 +284,7 @@ struct S390PCIBusDevice {
|
||||
uint64_t fmb_addr;
|
||||
uint8_t isc;
|
||||
uint16_t noi;
|
||||
uint16_t maxstbl;
|
||||
uint8_t sum;
|
||||
S390MsixInfo msix;
|
||||
AdapterRoutes routes;
|
||||
|
||||
+200
-137
File diff suppressed because it is too large
Load Diff
@@ -162,7 +162,7 @@ typedef struct ClpRspQueryPciGrp {
|
||||
#define CLP_RSP_QPCIG_MASK_FRAME 0x2
|
||||
#define CLP_RSP_QPCIG_MASK_REFRESH 0x1
|
||||
uint8_t fr;
|
||||
uint16_t reserved2;
|
||||
uint16_t maxstbl;
|
||||
uint16_t mui;
|
||||
uint64_t reserved3;
|
||||
uint64_t dasm; /* dma address space mask */
|
||||
@@ -293,13 +293,19 @@ typedef struct ZpciFib {
|
||||
|
||||
int pci_dereg_irqs(S390PCIBusDevice *pbdev);
|
||||
void pci_dereg_ioat(S390PCIIOMMU *iommu);
|
||||
int clp_service_call(S390CPU *cpu, uint8_t r2);
|
||||
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
|
||||
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
|
||||
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2);
|
||||
int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra);
|
||||
int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
|
||||
int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
|
||||
int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra);
|
||||
int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
|
||||
uint8_t ar);
|
||||
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
|
||||
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar);
|
||||
uint8_t ar, uintptr_t ra);
|
||||
int mpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
|
||||
uintptr_t ra);
|
||||
int stpcifc_service_call(S390CPU *cpu, uint8_t r1, uint64_t fiba, uint8_t ar,
|
||||
uintptr_t ra);
|
||||
|
||||
#define ZPCI_IO_BAR_MIN 0
|
||||
#define ZPCI_IO_BAR_MAX 5
|
||||
#define ZPCI_CONFIG_BAR 15
|
||||
|
||||
#endif
|
||||
|
||||
@@ -152,14 +152,38 @@ static void virtio_ccw_register_hcalls(void)
|
||||
virtio_ccw_hcall_early_printk);
|
||||
}
|
||||
|
||||
/*
|
||||
* KVM does only support memory slots up to KVM_MEM_MAX_NR_PAGES pages
|
||||
* as the dirty bitmap must be managed by bitops that take an int as
|
||||
* position indicator. If we have a guest beyond that we will split off
|
||||
* new subregions. The split must happen on a segment boundary (1MB).
|
||||
*/
|
||||
#define KVM_MEM_MAX_NR_PAGES ((1ULL << 31) - 1)
|
||||
#define SEG_MSK (~0xfffffULL)
|
||||
#define KVM_SLOT_MAX_BYTES ((KVM_MEM_MAX_NR_PAGES * TARGET_PAGE_SIZE) & SEG_MSK)
|
||||
static void s390_memory_init(ram_addr_t mem_size)
|
||||
{
|
||||
MemoryRegion *sysmem = get_system_memory();
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
ram_addr_t chunk, offset = 0;
|
||||
unsigned int number = 0;
|
||||
gchar *name;
|
||||
|
||||
/* allocate RAM for core */
|
||||
memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
|
||||
memory_region_add_subregion(sysmem, 0, ram);
|
||||
name = g_strdup_printf("s390.ram");
|
||||
while (mem_size) {
|
||||
MemoryRegion *ram = g_new(MemoryRegion, 1);
|
||||
uint64_t size = mem_size;
|
||||
|
||||
/* KVM does not allow memslots >= 8 TB */
|
||||
chunk = MIN(size, KVM_SLOT_MAX_BYTES);
|
||||
memory_region_allocate_system_memory(ram, NULL, name, chunk);
|
||||
memory_region_add_subregion(sysmem, offset, ram);
|
||||
mem_size -= chunk;
|
||||
offset += chunk;
|
||||
g_free(name);
|
||||
name = g_strdup_printf("s390.ram.%u", ++number);
|
||||
}
|
||||
g_free(name);
|
||||
|
||||
/* Initialize storage key device */
|
||||
s390_skeys_init();
|
||||
@@ -302,13 +326,17 @@ static void ccw_init(MachineState *machine)
|
||||
/*
|
||||
* Non mcss-e enabled guests only see the devices from the default
|
||||
* css, which is determined by the value of the squash_mcss property.
|
||||
* Note: we must not squash non virtual devices to css 0xFE.
|
||||
*/
|
||||
if (css_bus->squash_mcss) {
|
||||
ret = css_create_css_image(0, true);
|
||||
} else {
|
||||
ret = css_create_css_image(VIRTUAL_CSSID, true);
|
||||
}
|
||||
if (qemu_opt_get(qemu_get_machine_opts(), "s390-squash-mcss")) {
|
||||
warn_report("The machine property 's390-squash-mcss' is deprecated"
|
||||
" (obsoleted by lifting the cssid restrictions).");
|
||||
}
|
||||
|
||||
assert(ret == 0);
|
||||
if (css_migration_enabled()) {
|
||||
css_register_vmstate();
|
||||
@@ -583,7 +611,7 @@ static inline void s390_machine_initfn(Object *obj)
|
||||
object_property_add_bool(obj, "s390-squash-mcss",
|
||||
machine_get_squash_mcss,
|
||||
machine_set_squash_mcss, NULL);
|
||||
object_property_set_description(obj, "s390-squash-mcss",
|
||||
object_property_set_description(obj, "s390-squash-mcss", "(deprecated) "
|
||||
"enable/disable squashing subchannels into the default css",
|
||||
NULL);
|
||||
object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
|
||||
@@ -639,6 +667,9 @@ bool css_migration_enabled(void)
|
||||
} \
|
||||
type_init(ccw_machine_register_##suffix)
|
||||
|
||||
#define CCW_COMPAT_2_11 \
|
||||
HW_COMPAT_2_11
|
||||
|
||||
#define CCW_COMPAT_2_10 \
|
||||
HW_COMPAT_2_10
|
||||
|
||||
@@ -716,14 +747,30 @@ bool css_migration_enabled(void)
|
||||
.value = "0",\
|
||||
},
|
||||
|
||||
static void ccw_machine_2_12_instance_options(MachineState *machine)
|
||||
{
|
||||
}
|
||||
|
||||
static void ccw_machine_2_12_class_options(MachineClass *mc)
|
||||
{
|
||||
}
|
||||
DEFINE_CCW_MACHINE(2_12, "2.12", true);
|
||||
|
||||
static void ccw_machine_2_11_instance_options(MachineState *machine)
|
||||
{
|
||||
static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 };
|
||||
ccw_machine_2_12_instance_options(machine);
|
||||
|
||||
/* before 2.12 we emulated the very first z900 */
|
||||
s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat);
|
||||
}
|
||||
|
||||
static void ccw_machine_2_11_class_options(MachineClass *mc)
|
||||
{
|
||||
ccw_machine_2_12_class_options(mc);
|
||||
SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_11);
|
||||
}
|
||||
DEFINE_CCW_MACHINE(2_11, "2.11", true);
|
||||
DEFINE_CCW_MACHINE(2_11, "2.11", false);
|
||||
|
||||
static void ccw_machine_2_10_instance_options(MachineState *machine)
|
||||
{
|
||||
|
||||
@@ -701,7 +701,7 @@ static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp)
|
||||
SubchDev *sch;
|
||||
Error *err = NULL;
|
||||
|
||||
sch = css_create_sch(ccw_dev->devno, true, cbus->squash_mcss, errp);
|
||||
sch = css_create_sch(ccw_dev->devno, cbus->squash_mcss, errp);
|
||||
if (!sch) {
|
||||
return;
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
#ifndef HW_COMPAT_H
|
||||
#define HW_COMPAT_H
|
||||
|
||||
#define HW_COMPAT_2_11
|
||||
#define HW_COMPAT_2_11 \
|
||||
/* empty */
|
||||
|
||||
#define HW_COMPAT_2_10 \
|
||||
{\
|
||||
|
||||
@@ -248,7 +248,6 @@ int css_do_tsch_get_irb(SubchDev *sch, IRB *irb, int *irb_len);
|
||||
void css_do_tsch_update_subch(SubchDev *sch);
|
||||
int css_do_stcrw(CRW *crw);
|
||||
void css_undo_stcrw(CRW *crw);
|
||||
int css_do_tpi(IOIntCode *int_code, int lowcore);
|
||||
int css_collect_chp_desc(int m, uint8_t cssid, uint8_t f_chpid, uint8_t l_chpid,
|
||||
int rfmt, void *buf);
|
||||
void css_do_schm(uint8_t mbk, int update, int dct, uint64_t mbo);
|
||||
@@ -272,12 +271,9 @@ extern const PropertyInfo css_devid_ro_propinfo;
|
||||
* default css image for it.
|
||||
* If @p bus_id is valid, and @p squash_mcss is false, verify that it is
|
||||
* not already in use, and find a free devno for it.
|
||||
* If @p bus_id is not valid, and if either @p squash_mcss or @p is_virtual
|
||||
* is true, find a free subchannel id and device number across all
|
||||
* subchannel sets from the default css image.
|
||||
* If @p bus_id is not valid, and if both @p squash_mcss and @p is_virtual
|
||||
* are false, find a non-full css image and find a free subchannel id and
|
||||
* device number across all subchannel sets from it.
|
||||
* If @p bus_id is not valid find a free subchannel id and device number
|
||||
* across all subchannel sets and all css images starting from the default
|
||||
* css image.
|
||||
*
|
||||
* If either of the former actions succeed, allocate a subchannel structure,
|
||||
* initialise it with the bus id, subchannel id and device number, register
|
||||
@@ -286,8 +282,7 @@ extern const PropertyInfo css_devid_ro_propinfo;
|
||||
* The caller becomes owner of the returned subchannel structure and
|
||||
* is responsible for unregistering and freeing it.
|
||||
*/
|
||||
SubchDev *css_create_sch(CssDevId bus_id, bool is_virtual, bool squash_mcss,
|
||||
Error **errp);
|
||||
SubchDev *css_create_sch(CssDevId bus_id, bool squash_mcss, Error **errp);
|
||||
|
||||
/** Turn on css migration */
|
||||
void css_register_vmstate(void);
|
||||
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
* into the pc-bios directory of qemu.
|
||||
*
|
||||
* Copyright (c) 2013 Alexander Graf <agraf@suse.de>
|
||||
* Copyright 2013 IBM Corp.
|
||||
* Copyright IBM Corp. 2013, 2017
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or (at
|
||||
* your option) any later version. See the COPYING file in the top-level
|
||||
@@ -13,8 +13,32 @@
|
||||
.globl _start
|
||||
_start:
|
||||
|
||||
larl %r15, stack + 0x8000 /* Set up stack */
|
||||
j main /* And call C */
|
||||
larl %r15, stack + 0x8000 /* Set up stack */
|
||||
|
||||
/* clear bss */
|
||||
larl %r2, __bss_start
|
||||
larl %r3, _end
|
||||
slgr %r3, %r2 /* get sizeof bss */
|
||||
ltgr %r3,%r3 /* bss emtpy? */
|
||||
jz done
|
||||
aghi %r3,-1
|
||||
srlg %r4,%r3,8 /* how many 256 byte chunks? */
|
||||
ltgr %r4,%r4
|
||||
lgr %r1,%r2
|
||||
jz remainder
|
||||
loop:
|
||||
xc 0(256,%r1),0(%r1)
|
||||
la %r1,256(%r1)
|
||||
brctg %r4,loop
|
||||
remainder:
|
||||
larl %r2,memsetxc
|
||||
ex %r3,0(%r2)
|
||||
done:
|
||||
j main /* And call C */
|
||||
|
||||
memsetxc:
|
||||
xc 0(1,%r1),0(%r1)
|
||||
|
||||
|
||||
/*
|
||||
* void disabled_wait(void)
|
||||
|
||||
@@ -2501,6 +2501,14 @@ enabled via the ``-machine usb=on'' argument.
|
||||
|
||||
The ``-nodefconfig`` argument is a synonym for ``-no-user-config``.
|
||||
|
||||
@subsection -machine s390-squash-mcss=on|off (since 2.12.0)
|
||||
|
||||
The ``s390-squash-mcss=on`` property has been obsoleted by allowing the
|
||||
cssid to be chosen freely. Instead of squashing subchannels into the
|
||||
default channel subsystem image for guests that do not support multiple
|
||||
channel subsystems, all devices can be put into the default channel
|
||||
subsystem image.
|
||||
|
||||
@section qemu-img command line arguments
|
||||
|
||||
@subsection convert -s (since 2.0.0)
|
||||
|
||||
+7
-1
@@ -43,7 +43,7 @@ DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
|
||||
" suppress-vmdesc=on|off disables self-describing migration (default=off)\n"
|
||||
" nvdimm=on|off controls NVDIMM support (default=off)\n"
|
||||
" enforce-config-section=on|off enforce configuration section migration (default=off)\n"
|
||||
" s390-squash-mcss=on|off controls support for squashing into default css (default=off)\n",
|
||||
" s390-squash-mcss=on|off (deprecated) controls support for squashing into default css (default=off)\n",
|
||||
QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -machine [type=]@var{name}[,prop=@var{value}[,...]]
|
||||
@@ -98,6 +98,12 @@ Enables or disables NVDIMM support. The default is off.
|
||||
@item s390-squash-mcss=on|off
|
||||
Enables or disables squashing subchannels into the default css.
|
||||
The default is off.
|
||||
NOTE: This property is deprecated and will be removed in future releases.
|
||||
The ``s390-squash-mcss=on`` property has been obsoleted by allowing the
|
||||
cssid to be chosen freely. Instead of squashing subchannels into the
|
||||
default channel subsystem image for guests that do not support multiple
|
||||
channel subsystems, all devices can be put into the default channel
|
||||
subsystem image.
|
||||
@item enforce-config-section=on|off
|
||||
If @option{enforce-config-section} is set to @var{on}, force migration
|
||||
code to send configuration section even if the machine-type sets the
|
||||
|
||||
@@ -564,7 +564,7 @@ void HELPER(sacf)(CPUS390XState *env, uint64_t a1)
|
||||
break;
|
||||
default:
|
||||
HELPER_LOG("unknown sacf mode: %" PRIx64 "\n", a1);
|
||||
program_interrupt(env, PGM_SPECIFICATION, 2);
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, 2, GETPC());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-1
@@ -351,6 +351,9 @@ extern const struct VMStateDescription vmstate_s390_cpu;
|
||||
#define CR0_CPU_TIMER_SC 0x0000000000000400ULL
|
||||
#define CR0_SERVICE_SC 0x0000000000000200ULL
|
||||
|
||||
/* Control register 14 bits */
|
||||
#define CR14_CHANNEL_REPORT_SC 0x0000000010000000ULL
|
||||
|
||||
/* MMU */
|
||||
#define MMU_PRIMARY_IDX 0
|
||||
#define MMU_SECONDARY_IDX 1
|
||||
@@ -674,6 +677,26 @@ struct sysib_322 {
|
||||
#define MCIC_VB_CT 0x0000000000020000ULL
|
||||
#define MCIC_VB_CC 0x0000000000010000ULL
|
||||
|
||||
static inline uint64_t s390_build_validity_mcic(void)
|
||||
{
|
||||
uint64_t mcic;
|
||||
|
||||
/*
|
||||
* Indicate all validity bits (no damage) only. Other bits have to be
|
||||
* added by the caller. (storage errors, subclasses and subclass modifiers)
|
||||
*/
|
||||
mcic = MCIC_VB_WP | MCIC_VB_MS | MCIC_VB_PM | MCIC_VB_IA | MCIC_VB_FP |
|
||||
MCIC_VB_GR | MCIC_VB_CR | MCIC_VB_ST | MCIC_VB_AR | MCIC_VB_PR |
|
||||
MCIC_VB_FC | MCIC_VB_CT | MCIC_VB_CC;
|
||||
if (s390_has_feat(S390_FEAT_VECTOR)) {
|
||||
mcic |= MCIC_VB_VR;
|
||||
}
|
||||
if (s390_has_feat(S390_FEAT_GUARDED_STORAGE)) {
|
||||
mcic |= MCIC_VB_GS;
|
||||
}
|
||||
return mcic;
|
||||
}
|
||||
|
||||
|
||||
/* cpu.c */
|
||||
int s390_get_clock(uint8_t *tod_high, uint64_t *tod_low);
|
||||
@@ -699,6 +722,9 @@ static inline unsigned int s390_cpu_set_state(uint8_t cpu_state, S390CPU *cpu)
|
||||
/* cpu_models.c */
|
||||
void s390_cpu_list(FILE *f, fprintf_function cpu_fprintf);
|
||||
#define cpu_list s390_cpu_list
|
||||
void s390_set_qemu_cpu_model(uint16_t type, uint8_t gen, uint8_t ec_ga,
|
||||
const S390FeatInit feat_init);
|
||||
|
||||
|
||||
/* helper.c */
|
||||
#define cpu_init(cpu_model) cpu_generic_init(TYPE_S390_CPU, cpu_model)
|
||||
@@ -719,7 +745,9 @@ void s390_io_interrupt(uint16_t subchannel_id, uint16_t subchannel_nr,
|
||||
uint32_t io_int_parm, uint32_t io_int_word);
|
||||
/* automatically detect the instruction length */
|
||||
#define ILEN_AUTO 0xff
|
||||
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen);
|
||||
#define RA_IGNORED 0
|
||||
void s390_program_interrupt(CPUS390XState *env, uint32_t code, int ilen,
|
||||
uintptr_t ra);
|
||||
/* service interrupts are floating therefore we must not pass an cpustate */
|
||||
void s390_sclp_extint(uint32_t parm);
|
||||
|
||||
@@ -733,6 +761,7 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, uint8_t ar, void *hostbuf,
|
||||
s390_cpu_virt_mem_rw(cpu, laddr, ar, dest, len, true)
|
||||
#define s390_cpu_virt_mem_check_write(cpu, laddr, ar, len) \
|
||||
s390_cpu_virt_mem_rw(cpu, laddr, ar, NULL, len, true)
|
||||
void s390_cpu_virt_mem_handle_exc(S390CPU *cpu, uintptr_t ra);
|
||||
|
||||
|
||||
/* sigp.c */
|
||||
|
||||
+47
-56
@@ -15,7 +15,6 @@
|
||||
#include "internal.h"
|
||||
#include "kvm_s390x.h"
|
||||
#include "sysemu/kvm.h"
|
||||
#include "gen-features.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "qemu/error-report.h"
|
||||
@@ -81,6 +80,12 @@ static S390CPUDef s390_cpu_defs[] = {
|
||||
CPUDEF_INIT(0x3906, 14, 1, 47, 0x08000000U, "z14", "IBM z14 GA1"),
|
||||
};
|
||||
|
||||
#define QEMU_MAX_CPU_TYPE 0x2827
|
||||
#define QEMU_MAX_CPU_GEN 12
|
||||
#define QEMU_MAX_CPU_EC_GA 2
|
||||
static const S390FeatInit qemu_max_cpu_feat_init = { S390_FEAT_LIST_QEMU_MAX };
|
||||
static S390FeatBitmap qemu_max_cpu_feat;
|
||||
|
||||
/* features part of a base model but not relevant for finding a base model */
|
||||
S390FeatBitmap ignored_base_feat;
|
||||
|
||||
@@ -812,48 +817,6 @@ static void check_compatibility(const S390CPUModel *max_model,
|
||||
"available in the configuration: ");
|
||||
}
|
||||
|
||||
/**
|
||||
* The base TCG CPU model "qemu" is based on the z900. However, we already
|
||||
* can also emulate some additional features of later CPU generations, so
|
||||
* we add these additional feature bits here.
|
||||
*/
|
||||
static void add_qemu_cpu_model_features(S390FeatBitmap fbm)
|
||||
{
|
||||
static const int feats[] = {
|
||||
S390_FEAT_DAT_ENH,
|
||||
S390_FEAT_IDTE_SEGMENT,
|
||||
S390_FEAT_STFLE,
|
||||
S390_FEAT_SENSE_RUNNING_STATUS,
|
||||
S390_FEAT_EXTENDED_IMMEDIATE,
|
||||
S390_FEAT_EXTENDED_TRANSLATION_2,
|
||||
S390_FEAT_MSA,
|
||||
S390_FEAT_EXTENDED_TRANSLATION_3,
|
||||
S390_FEAT_LONG_DISPLACEMENT,
|
||||
S390_FEAT_LONG_DISPLACEMENT_FAST,
|
||||
S390_FEAT_ETF2_ENH,
|
||||
S390_FEAT_STORE_CLOCK_FAST,
|
||||
S390_FEAT_MOVE_WITH_OPTIONAL_SPEC,
|
||||
S390_FEAT_ETF3_ENH,
|
||||
S390_FEAT_COMPARE_AND_SWAP_AND_STORE,
|
||||
S390_FEAT_COMPARE_AND_SWAP_AND_STORE_2,
|
||||
S390_FEAT_GENERAL_INSTRUCTIONS_EXT,
|
||||
S390_FEAT_EXECUTE_EXT,
|
||||
S390_FEAT_FLOATING_POINT_SUPPPORT_ENH,
|
||||
S390_FEAT_STFLE_45,
|
||||
S390_FEAT_STFLE_49,
|
||||
S390_FEAT_LOCAL_TLB_CLEARING,
|
||||
S390_FEAT_STFLE_53,
|
||||
S390_FEAT_MSA_EXT_5,
|
||||
S390_FEAT_MSA_EXT_3,
|
||||
S390_FEAT_MSA_EXT_4,
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(feats); i++) {
|
||||
set_bit(feats[i], fbm);
|
||||
}
|
||||
}
|
||||
|
||||
static S390CPUModel *get_max_cpu_model(Error **errp)
|
||||
{
|
||||
static S390CPUModel max_model;
|
||||
@@ -866,12 +829,10 @@ static S390CPUModel *get_max_cpu_model(Error **errp)
|
||||
if (kvm_enabled()) {
|
||||
kvm_s390_get_host_cpu_model(&max_model, errp);
|
||||
} else {
|
||||
/* TCG emulates a z900 (with some optional additional features) */
|
||||
max_model.def = &s390_cpu_defs[0];
|
||||
bitmap_copy(max_model.features, max_model.def->default_feat,
|
||||
S390_FEAT_MAX);
|
||||
add_qemu_cpu_model_features(max_model.features);
|
||||
}
|
||||
max_model.def = s390_find_cpu_def(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN,
|
||||
QEMU_MAX_CPU_EC_GA, NULL);
|
||||
bitmap_copy(max_model.features, qemu_max_cpu_feat, S390_FEAT_MAX);
|
||||
}
|
||||
if (!*errp) {
|
||||
cached = true;
|
||||
return &max_model;
|
||||
@@ -1127,18 +1088,42 @@ static void s390_host_cpu_model_initfn(Object *obj)
|
||||
}
|
||||
#endif
|
||||
|
||||
static S390CPUDef s390_qemu_cpu_def;
|
||||
static S390CPUModel s390_qemu_cpu_model;
|
||||
|
||||
/* Set the qemu CPU model (on machine initialization). Must not be called
|
||||
* once CPUs have been created.
|
||||
*/
|
||||
void s390_set_qemu_cpu_model(uint16_t type, uint8_t gen, uint8_t ec_ga,
|
||||
const S390FeatInit feat_init)
|
||||
{
|
||||
const S390CPUDef *def = s390_find_cpu_def(type, gen, ec_ga, NULL);
|
||||
|
||||
g_assert(def);
|
||||
g_assert(QTAILQ_EMPTY(&cpus));
|
||||
|
||||
/* TCG emulates some features that can usually not be enabled with
|
||||
* the emulated machine generation. Make sure they can be enabled
|
||||
* when using the QEMU model by adding them to full_feat. We have
|
||||
* to copy the definition to do that.
|
||||
*/
|
||||
memcpy(&s390_qemu_cpu_def, def, sizeof(s390_qemu_cpu_def));
|
||||
bitmap_or(s390_qemu_cpu_def.full_feat, s390_qemu_cpu_def.full_feat,
|
||||
qemu_max_cpu_feat, S390_FEAT_MAX);
|
||||
|
||||
/* build the CPU model */
|
||||
s390_qemu_cpu_model.def = &s390_qemu_cpu_def;
|
||||
bitmap_zero(s390_qemu_cpu_model.features, S390_FEAT_MAX);
|
||||
s390_init_feat_bitmap(feat_init, s390_qemu_cpu_model.features);
|
||||
}
|
||||
|
||||
static void s390_qemu_cpu_model_initfn(Object *obj)
|
||||
{
|
||||
static S390CPUDef s390_qemu_cpu_defs;
|
||||
S390CPU *cpu = S390_CPU(obj);
|
||||
|
||||
cpu->model = g_malloc0(sizeof(*cpu->model));
|
||||
/* TCG emulates a z900 (with some optional additional features) */
|
||||
memcpy(&s390_qemu_cpu_defs, &s390_cpu_defs[0], sizeof(s390_qemu_cpu_defs));
|
||||
add_qemu_cpu_model_features(s390_qemu_cpu_defs.full_feat);
|
||||
cpu->model->def = &s390_qemu_cpu_defs;
|
||||
bitmap_copy(cpu->model->features, cpu->model->def->default_feat,
|
||||
S390_FEAT_MAX);
|
||||
/* copy the CPU model so we can modify it */
|
||||
memcpy(cpu->model, &s390_qemu_cpu_model, sizeof(*cpu->model));
|
||||
}
|
||||
|
||||
static void s390_cpu_model_finalize(Object *obj)
|
||||
@@ -1279,11 +1264,13 @@ static void init_ignored_base_feat(void)
|
||||
|
||||
static void register_types(void)
|
||||
{
|
||||
static const S390FeatInit qemu_latest_init = { S390_FEAT_LIST_QEMU_LATEST };
|
||||
int i;
|
||||
|
||||
init_ignored_base_feat();
|
||||
|
||||
/* init all bitmaps from gnerated data initially */
|
||||
s390_init_feat_bitmap(qemu_max_cpu_feat_init, qemu_max_cpu_feat);
|
||||
for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
|
||||
s390_init_feat_bitmap(s390_cpu_defs[i].base_init,
|
||||
s390_cpu_defs[i].base_feat);
|
||||
@@ -1293,6 +1280,10 @@ static void register_types(void)
|
||||
s390_cpu_defs[i].full_feat);
|
||||
}
|
||||
|
||||
/* initialize the qemu model with latest definition */
|
||||
s390_set_qemu_cpu_model(QEMU_MAX_CPU_TYPE, QEMU_MAX_CPU_GEN,
|
||||
QEMU_MAX_CPU_EC_GA, qemu_latest_init);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(s390_cpu_defs); i++) {
|
||||
char *base_name = s390_base_cpu_type_name(s390_cpu_defs[i].name);
|
||||
TypeInfo ti_base = {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define TARGET_S390X_CPU_MODELS_H
|
||||
|
||||
#include "cpu_features.h"
|
||||
#include "gen-features.h"
|
||||
#include "qom/cpu.h"
|
||||
|
||||
/* static CPU definition */
|
||||
|
||||
@@ -23,7 +23,6 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
|
||||
const uintptr_t ra = GETPC();
|
||||
const uint8_t mod = env->regs[0] & 0x80ULL;
|
||||
const uint8_t fc = env->regs[0] & 0x7fULL;
|
||||
CPUState *cs = CPU(s390_env_get_cpu(env));
|
||||
uint8_t subfunc[16] = { 0 };
|
||||
uint64_t param_addr;
|
||||
int i;
|
||||
@@ -35,8 +34,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
|
||||
case S390_FEAT_TYPE_PCKMO:
|
||||
case S390_FEAT_TYPE_PCC:
|
||||
if (mod) {
|
||||
cpu_restore_state(cs, ra);
|
||||
program_interrupt(env, PGM_SPECIFICATION, 4);
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -44,8 +42,7 @@ uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
|
||||
|
||||
s390_get_feat_block(type, subfunc);
|
||||
if (!test_be_bit(fc, subfunc)) {
|
||||
cpu_restore_state(cs, ra);
|
||||
program_interrupt(env, PGM_SPECIFICATION, 4);
|
||||
s390_program_interrupt(env, PGM_SPECIFICATION, 4, ra);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user