* Refine the distro support policy
* Deprecate 32-bit x86 and arm hosts for system emulation * Check bison version to be >= 3.0 * Compile vnc test only if vnc is really enabled * Check docs/config/ich9-ehci-uhci.cfg via the readconfig-test * s390x: Add support for list-directed IPL from ECKD DASD -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmQIQD0RHHRodXRoQHJl ZGhhdC5jb20ACgkQLtnXdP5wLbX+EA/5ATc/Rz9Y8TZF36/sUKrmjOxQnX91hgRW zovgZejoHtek1AC4pLd9kcpo1JonXkOfmbkNRYTw6+1wY6Ipt2apkWAc+MqfvQ80 dGznbLXnX/E2QHW7h5XqvAhRGvjog9b38zAQcR37PKZ9DkSfWBwMgTT2SXYpLUjR YWgqPGBYRq1ViG4q7hv2dHqi/idzh+DOWFGU5NAQC1fEBOmPYN9u6vfbX86dwZsy S9pqw16yN2MZKL2bgIViFIjdhPPMO3RFcv8NTPipzk3g/pHNIv58+xCE8r/Tp8LW JRQzdh6JbGvj1BXH68igXWGUFW6dhOXZWhgmFe4QEDaiCj91pHGvQCYgo2agx2bl rXaSQXSMhIcm+t9C9kO6UNxZf+1HohcM1ZlQXhvX6FcBPVMUx/52YEpiK+OtBKyq 43AlKp4fp1xXLFSOyMNgSMR90sksng6CEoQqTr0jCZtF8H18wb+eHfb6dME3XRCw SKQeNGhkP1FxaQnlRAkeBxW7GkDE5YBjf9pSIaLZ/8VsLdyo3SK/DLkre5+qnu/V lksZlt1K7xDLxRFopBuVJ3MHeFSRazBDbWfrRFOALkdbGEEeZnnmEPFjD3mag+P4 1y9WmBJHRLlvhlm195WA8babenUZoOfLkPrL0k7mNLs9sZyx1eIkZfOUgCWjFE2V 9VBOWL8oi/w= =p13b -----END PGP SIGNATURE----- Merge tag 'pull-request-2023-03-07' of https://gitlab.com/thuth/qemu into staging * Refine the distro support policy * Deprecate 32-bit x86 and arm hosts for system emulation * Check bison version to be >= 3.0 * Compile vnc test only if vnc is really enabled * Check docs/config/ich9-ehci-uhci.cfg via the readconfig-test * s390x: Add support for list-directed IPL from ECKD DASD # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmQIQD0RHHRodXRoQHJl # ZGhhdC5jb20ACgkQLtnXdP5wLbX+EA/5ATc/Rz9Y8TZF36/sUKrmjOxQnX91hgRW # zovgZejoHtek1AC4pLd9kcpo1JonXkOfmbkNRYTw6+1wY6Ipt2apkWAc+MqfvQ80 # dGznbLXnX/E2QHW7h5XqvAhRGvjog9b38zAQcR37PKZ9DkSfWBwMgTT2SXYpLUjR # YWgqPGBYRq1ViG4q7hv2dHqi/idzh+DOWFGU5NAQC1fEBOmPYN9u6vfbX86dwZsy # S9pqw16yN2MZKL2bgIViFIjdhPPMO3RFcv8NTPipzk3g/pHNIv58+xCE8r/Tp8LW # JRQzdh6JbGvj1BXH68igXWGUFW6dhOXZWhgmFe4QEDaiCj91pHGvQCYgo2agx2bl # rXaSQXSMhIcm+t9C9kO6UNxZf+1HohcM1ZlQXhvX6FcBPVMUx/52YEpiK+OtBKyq # 43AlKp4fp1xXLFSOyMNgSMR90sksng6CEoQqTr0jCZtF8H18wb+eHfb6dME3XRCw # SKQeNGhkP1FxaQnlRAkeBxW7GkDE5YBjf9pSIaLZ/8VsLdyo3SK/DLkre5+qnu/V # lksZlt1K7xDLxRFopBuVJ3MHeFSRazBDbWfrRFOALkdbGEEeZnnmEPFjD3mag+P4 # 1y9WmBJHRLlvhlm195WA8babenUZoOfLkPrL0k7mNLs9sZyx1eIkZfOUgCWjFE2V # 9VBOWL8oi/w= # =p13b # -----END PGP SIGNATURE----- # gpg: Signature made Wed 08 Mar 2023 07:58:53 GMT # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2023-03-07' of https://gitlab.com/thuth/qemu: pc-bios/s390-ccw: Update s390-ccw.img with the list-directed IPL fix pc-bios: Add support for List-Directed IPL from ECKD DASD docs/config: Set the "kvm" accelerator via "[accel]" section tests/qtest/readconfig: Test docs/config/ich9-ehci-uhci.cfg tests/qtest/readconfig: Rework test_object_rng_resp into a generic function gitlab-ci.d/crossbuilds: Drop the 32-bit arm system emulation jobs docs/about/deprecated: Deprecate 32-bit arm hosts for system emulation gitlab-ci.d/crossbuilds: Drop the i386 system emulation job docs/about/deprecated: Deprecate 32-bit x86 hosts for system emulation include/hw/i386: Clean up includes in x86.h test: Check vnc enable before compiling vnc test Hexagon (meson.build): define min bison version docs/about/build-platforms: Refine the distro support policy Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
dea644928d
|
@ -1,13 +1,6 @@
|
||||||
include:
|
include:
|
||||||
- local: '/.gitlab-ci.d/crossbuild-template.yml'
|
- local: '/.gitlab-ci.d/crossbuild-template.yml'
|
||||||
|
|
||||||
cross-armel-system:
|
|
||||||
extends: .cross_system_build_job
|
|
||||||
needs:
|
|
||||||
job: armel-debian-cross-container
|
|
||||||
variables:
|
|
||||||
IMAGE: debian-armel-cross
|
|
||||||
|
|
||||||
cross-armel-user:
|
cross-armel-user:
|
||||||
extends: .cross_user_build_job
|
extends: .cross_user_build_job
|
||||||
needs:
|
needs:
|
||||||
|
@ -15,13 +8,6 @@ cross-armel-user:
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian-armel-cross
|
IMAGE: debian-armel-cross
|
||||||
|
|
||||||
cross-armhf-system:
|
|
||||||
extends: .cross_system_build_job
|
|
||||||
needs:
|
|
||||||
job: armhf-debian-cross-container
|
|
||||||
variables:
|
|
||||||
IMAGE: debian-armhf-cross
|
|
||||||
|
|
||||||
cross-armhf-user:
|
cross-armhf-user:
|
||||||
extends: .cross_user_build_job
|
extends: .cross_user_build_job
|
||||||
needs:
|
needs:
|
||||||
|
@ -43,16 +29,6 @@ cross-arm64-user:
|
||||||
variables:
|
variables:
|
||||||
IMAGE: debian-arm64-cross
|
IMAGE: debian-arm64-cross
|
||||||
|
|
||||||
cross-i386-system:
|
|
||||||
extends:
|
|
||||||
- .cross_system_build_job
|
|
||||||
- .cross_test_artifacts
|
|
||||||
needs:
|
|
||||||
job: i386-fedora-cross-container
|
|
||||||
variables:
|
|
||||||
IMAGE: fedora-i386-cross
|
|
||||||
MAKE_CHECK_ARGS: check-qtest
|
|
||||||
|
|
||||||
cross-i386-user:
|
cross-i386-user:
|
||||||
extends:
|
extends:
|
||||||
- .cross_user_build_job
|
- .cross_user_build_job
|
||||||
|
|
|
@ -2262,6 +2262,7 @@ fi
|
||||||
# tests might fail. Prefer to keep the relevant files in their own
|
# tests might fail. Prefer to keep the relevant files in their own
|
||||||
# directory and symlink the directory instead.
|
# directory and symlink the directory instead.
|
||||||
LINKS="Makefile"
|
LINKS="Makefile"
|
||||||
|
LINKS="$LINKS docs/config"
|
||||||
LINKS="$LINKS pc-bios/optionrom/Makefile"
|
LINKS="$LINKS pc-bios/optionrom/Makefile"
|
||||||
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
|
LINKS="$LINKS pc-bios/s390-ccw/Makefile"
|
||||||
LINKS="$LINKS pc-bios/vof/Makefile"
|
LINKS="$LINKS pc-bios/vof/Makefile"
|
||||||
|
|
|
@ -67,7 +67,8 @@ Non-supported architectures may be removed in the future following the
|
||||||
Linux OS, macOS, FreeBSD, NetBSD, OpenBSD
|
Linux OS, macOS, FreeBSD, NetBSD, OpenBSD
|
||||||
-----------------------------------------
|
-----------------------------------------
|
||||||
|
|
||||||
The project aims to support the most recent major version at all times. Support
|
The project aims to support the most recent major version at all times for
|
||||||
|
up to five years after its initial release. Support
|
||||||
for the previous major version will be dropped 2 years after the new major
|
for the previous major version will be dropped 2 years after the new major
|
||||||
version is released or when the vendor itself drops support, whichever comes
|
version is released or when the vendor itself drops support, whichever comes
|
||||||
first. In this context, third-party efforts to extend the lifetime of a distro
|
first. In this context, third-party efforts to extend the lifetime of a distro
|
||||||
|
|
|
@ -196,6 +196,26 @@ CI coverage support may bitrot away before the deprecation process
|
||||||
completes. The little endian variants of MIPS (both 32 and 64 bit) are
|
completes. The little endian variants of MIPS (both 32 and 64 bit) are
|
||||||
still a supported host architecture.
|
still a supported host architecture.
|
||||||
|
|
||||||
|
System emulation on 32-bit x86 hosts (since 8.0)
|
||||||
|
''''''''''''''''''''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
|
Support for 32-bit x86 host deployments is increasingly uncommon in mainstream
|
||||||
|
OS distributions given the widespread availability of 64-bit x86 hardware.
|
||||||
|
The QEMU project no longer considers 32-bit x86 support for system emulation to
|
||||||
|
be an effective use of its limited resources, and thus intends to discontinue
|
||||||
|
it. Since all recent x86 hardware from the past >10 years is capable of the
|
||||||
|
64-bit x86 extensions, a corresponding 64-bit OS should be used instead.
|
||||||
|
|
||||||
|
System emulation on 32-bit arm hosts (since 8.0)
|
||||||
|
''''''''''''''''''''''''''''''''''''''''''''''''
|
||||||
|
|
||||||
|
Since QEMU needs a strong host machine for running full system emulation, and
|
||||||
|
all recent powerful arm hosts support 64-bit, the QEMU project deprecates the
|
||||||
|
support for running any system emulation on 32-bit arm hosts in general. Use
|
||||||
|
64-bit arm hosts for system emulation instead. (Note: "user" mode emulation
|
||||||
|
continues to be supported on 32-bit arm hosts, too)
|
||||||
|
|
||||||
|
|
||||||
QEMU API (QAPI) events
|
QEMU API (QAPI) events
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,11 @@
|
||||||
|
|
||||||
[machine]
|
[machine]
|
||||||
type = "virt"
|
type = "virt"
|
||||||
accel = "kvm"
|
|
||||||
gic-version = "host"
|
gic-version = "host"
|
||||||
|
|
||||||
|
[accel]
|
||||||
|
accel = "kvm"
|
||||||
|
|
||||||
[memory]
|
[memory]
|
||||||
size = "1024"
|
size = "1024"
|
||||||
|
|
||||||
|
|
|
@ -62,9 +62,11 @@
|
||||||
|
|
||||||
[machine]
|
[machine]
|
||||||
type = "virt"
|
type = "virt"
|
||||||
accel = "kvm"
|
|
||||||
gic-version = "host"
|
gic-version = "host"
|
||||||
|
|
||||||
|
[accel]
|
||||||
|
accel = "kvm"
|
||||||
|
|
||||||
[memory]
|
[memory]
|
||||||
size = "1024"
|
size = "1024"
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,8 @@
|
||||||
|
|
||||||
[machine]
|
[machine]
|
||||||
type = "q35"
|
type = "q35"
|
||||||
|
|
||||||
|
[accel]
|
||||||
accel = "kvm"
|
accel = "kvm"
|
||||||
|
|
||||||
[memory]
|
[memory]
|
||||||
|
|
|
@ -55,6 +55,8 @@
|
||||||
|
|
||||||
[machine]
|
[machine]
|
||||||
type = "q35"
|
type = "q35"
|
||||||
|
|
||||||
|
[accel]
|
||||||
accel = "kvm"
|
accel = "kvm"
|
||||||
|
|
||||||
[memory]
|
[memory]
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
|
|
||||||
[machine]
|
[machine]
|
||||||
type = "q35"
|
type = "q35"
|
||||||
|
|
||||||
|
[accel]
|
||||||
accel = "kvm"
|
accel = "kvm"
|
||||||
|
|
||||||
[memory]
|
[memory]
|
||||||
|
|
|
@ -18,10 +18,8 @@
|
||||||
#define HW_I386_X86_H
|
#define HW_I386_X86_H
|
||||||
|
|
||||||
#include "exec/hwaddr.h"
|
#include "exec/hwaddr.h"
|
||||||
#include "qemu/notify.h"
|
|
||||||
|
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
#include "hw/nmi.h"
|
|
||||||
#include "hw/intc/ioapic.h"
|
#include "hw/intc/ioapic.h"
|
||||||
#include "hw/isa/isa.h"
|
#include "hw/isa/isa.h"
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
|
|
Binary file not shown.
|
@ -72,42 +72,74 @@ static inline void verify_boot_info(BootInfo *bip)
|
||||||
"Bad block size in zIPL section of the 1st record.");
|
"Bad block size in zIPL section of the 1st record.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static block_number_t eckd_block_num(EckdCHS *chs)
|
static void eckd_format_chs(ExtEckdBlockPtr *ptr, bool ldipl,
|
||||||
|
uint64_t *c,
|
||||||
|
uint64_t *h,
|
||||||
|
uint64_t *s)
|
||||||
|
{
|
||||||
|
if (ldipl) {
|
||||||
|
*c = ptr->ldptr.chs.cylinder;
|
||||||
|
*h = ptr->ldptr.chs.head;
|
||||||
|
*s = ptr->ldptr.chs.sector;
|
||||||
|
} else {
|
||||||
|
*c = ptr->bptr.chs.cylinder;
|
||||||
|
*h = ptr->bptr.chs.head;
|
||||||
|
*s = ptr->bptr.chs.sector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static block_number_t eckd_chs_to_block(uint64_t c, uint64_t h, uint64_t s)
|
||||||
{
|
{
|
||||||
const uint64_t sectors = virtio_get_sectors();
|
const uint64_t sectors = virtio_get_sectors();
|
||||||
const uint64_t heads = virtio_get_heads();
|
const uint64_t heads = virtio_get_heads();
|
||||||
const uint64_t cylinder = chs->cylinder
|
const uint64_t cylinder = c + ((h & 0xfff0) << 12);
|
||||||
+ ((chs->head & 0xfff0) << 12);
|
const uint64_t head = h & 0x000f;
|
||||||
const uint64_t head = chs->head & 0x000f;
|
|
||||||
const block_number_t block = sectors * heads * cylinder
|
const block_number_t block = sectors * heads * cylinder
|
||||||
+ sectors * head
|
+ sectors * head
|
||||||
+ chs->sector
|
+ s - 1; /* block nr starts with zero */
|
||||||
- 1; /* block nr starts with zero */
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool eckd_valid_address(BootMapPointer *p)
|
static block_number_t eckd_block_num(EckdCHS *chs)
|
||||||
{
|
{
|
||||||
const uint64_t head = p->eckd.chs.head & 0x000f;
|
return eckd_chs_to_block(chs->cylinder, chs->head, chs->sector);
|
||||||
|
}
|
||||||
|
|
||||||
|
static block_number_t gen_eckd_block_num(ExtEckdBlockPtr *ptr, bool ldipl)
|
||||||
|
{
|
||||||
|
uint64_t cyl, head, sec;
|
||||||
|
eckd_format_chs(ptr, ldipl, &cyl, &head, &sec);
|
||||||
|
return eckd_chs_to_block(cyl, head, sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool eckd_valid_chs(uint64_t cyl, uint64_t head, uint64_t sector)
|
||||||
|
{
|
||||||
if (head >= virtio_get_heads()
|
if (head >= virtio_get_heads()
|
||||||
|| p->eckd.chs.sector > virtio_get_sectors()
|
|| sector > virtio_get_sectors()
|
||||||
|| p->eckd.chs.sector <= 0) {
|
|| sector <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!virtio_guessed_disk_nature() &&
|
if (!virtio_guessed_disk_nature() &&
|
||||||
eckd_block_num(&p->eckd.chs) >= virtio_get_blocks()) {
|
eckd_chs_to_block(cyl, head, sector) >= virtio_get_blocks()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
|
static bool eckd_valid_address(ExtEckdBlockPtr *ptr, bool ldipl)
|
||||||
|
{
|
||||||
|
uint64_t cyl, head, sec;
|
||||||
|
eckd_format_chs(ptr, ldipl, &cyl, &head, &sec);
|
||||||
|
return eckd_valid_chs(cyl, head, sec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static block_number_t load_eckd_segments(block_number_t blk, bool ldipl,
|
||||||
|
uint64_t *address)
|
||||||
{
|
{
|
||||||
block_number_t block_nr;
|
block_number_t block_nr;
|
||||||
int j, rc;
|
int j, rc, count;
|
||||||
BootMapPointer *bprs = (void *)_bprs;
|
BootMapPointer *bprs = (void *)_bprs;
|
||||||
bool more_data;
|
bool more_data;
|
||||||
|
|
||||||
|
@ -117,7 +149,7 @@ static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
|
||||||
do {
|
do {
|
||||||
more_data = false;
|
more_data = false;
|
||||||
for (j = 0;; j++) {
|
for (j = 0;; j++) {
|
||||||
block_nr = eckd_block_num(&bprs[j].xeckd.bptr.chs);
|
block_nr = gen_eckd_block_num(&bprs[j].xeckd, ldipl);
|
||||||
if (is_null_block_number(block_nr)) { /* end of chunk */
|
if (is_null_block_number(block_nr)) { /* end of chunk */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -129,11 +161,26 @@ static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
IPL_assert(block_size_ok(bprs[j].xeckd.bptr.size),
|
/* List directed pointer does not store block size */
|
||||||
|
IPL_assert(ldipl || block_size_ok(bprs[j].xeckd.bptr.size),
|
||||||
"bad chunk block size");
|
"bad chunk block size");
|
||||||
IPL_assert(eckd_valid_address(&bprs[j]), "bad chunk ECKD addr");
|
|
||||||
|
|
||||||
if ((bprs[j].xeckd.bptr.count == 0) && unused_space(&(bprs[j+1]),
|
if (!eckd_valid_address(&bprs[j].xeckd, ldipl)) {
|
||||||
|
/*
|
||||||
|
* If an invalid address is found during LD-IPL then break and
|
||||||
|
* retry as CCW
|
||||||
|
*/
|
||||||
|
IPL_assert(ldipl, "bad chunk ECKD addr");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ldipl) {
|
||||||
|
count = bprs[j].xeckd.ldptr.count;
|
||||||
|
} else {
|
||||||
|
count = bprs[j].xeckd.bptr.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0 && unused_space(&bprs[j + 1],
|
||||||
sizeof(EckdBlockPtr))) {
|
sizeof(EckdBlockPtr))) {
|
||||||
/* This is a "continue" pointer.
|
/* This is a "continue" pointer.
|
||||||
* This ptr should be the last one in the current
|
* This ptr should be the last one in the current
|
||||||
|
@ -149,11 +196,10 @@ static block_number_t load_eckd_segments(block_number_t blk, uint64_t *address)
|
||||||
/* Load (count+1) blocks of code at (block_nr)
|
/* Load (count+1) blocks of code at (block_nr)
|
||||||
* to memory (address).
|
* to memory (address).
|
||||||
*/
|
*/
|
||||||
rc = virtio_read_many(block_nr, (void *)(*address),
|
rc = virtio_read_many(block_nr, (void *)(*address), count + 1);
|
||||||
bprs[j].xeckd.bptr.count+1);
|
|
||||||
IPL_assert(rc == 0, "code chunk read failed");
|
IPL_assert(rc == 0, "code chunk read failed");
|
||||||
|
|
||||||
*address += (bprs[j].xeckd.bptr.count+1) * virtio_get_block_size();
|
*address += (count + 1) * virtio_get_block_size();
|
||||||
}
|
}
|
||||||
} while (more_data);
|
} while (more_data);
|
||||||
return block_nr;
|
return block_nr;
|
||||||
|
@ -237,8 +283,10 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr,
|
||||||
uint64_t address;
|
uint64_t address;
|
||||||
BootMapTable *bmt = (void *)sec;
|
BootMapTable *bmt = (void *)sec;
|
||||||
BootMapScript *bms = (void *)sec;
|
BootMapScript *bms = (void *)sec;
|
||||||
|
/* The S1B block number is NULL_BLOCK_NR if and only if it's an LD-IPL */
|
||||||
|
bool ldipl = (s1b_block_nr == NULL_BLOCK_NR);
|
||||||
|
|
||||||
if (menu_is_enabled_zipl()) {
|
if (menu_is_enabled_zipl() && !ldipl) {
|
||||||
loadparm = eckd_get_boot_menu_index(s1b_block_nr);
|
loadparm = eckd_get_boot_menu_index(s1b_block_nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +297,7 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr,
|
||||||
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
||||||
read_block(bmt_block_nr, sec, "Cannot read Boot Map Table");
|
read_block(bmt_block_nr, sec, "Cannot read Boot Map Table");
|
||||||
|
|
||||||
block_nr = eckd_block_num(&bmt->entry[loadparm].xeckd.bptr.chs);
|
block_nr = gen_eckd_block_num(&bmt->entry[loadparm].xeckd, ldipl);
|
||||||
IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry");
|
IPL_assert(block_nr != -1, "Cannot find Boot Map Table Entry");
|
||||||
|
|
||||||
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
||||||
|
@ -264,13 +312,18 @@ static void run_eckd_boot_script(block_number_t bmt_block_nr,
|
||||||
}
|
}
|
||||||
|
|
||||||
address = bms->entry[i].address.load_address;
|
address = bms->entry[i].address.load_address;
|
||||||
block_nr = eckd_block_num(&bms->entry[i].blkptr.xeckd.bptr.chs);
|
block_nr = gen_eckd_block_num(&bms->entry[i].blkptr.xeckd, ldipl);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
block_nr = load_eckd_segments(block_nr, &address);
|
block_nr = load_eckd_segments(block_nr, ldipl, &address);
|
||||||
} while (block_nr != -1);
|
} while (block_nr != -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ldipl && bms->entry[i].type != BOOT_SCRIPT_EXEC) {
|
||||||
|
/* Abort LD-IPL and retry as CCW-IPL */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC,
|
IPL_assert(bms->entry[i].type == BOOT_SCRIPT_EXEC,
|
||||||
"Unknown script entry type");
|
"Unknown script entry type");
|
||||||
write_reset_psw(bms->entry[i].address.load_address); /* no return */
|
write_reset_psw(bms->entry[i].address.load_address); /* no return */
|
||||||
|
@ -380,6 +433,23 @@ static void ipl_eckd_ldl(ECKD_IPL_mode_t mode)
|
||||||
/* no return */
|
/* no return */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static block_number_t eckd_find_bmt(ExtEckdBlockPtr *ptr)
|
||||||
|
{
|
||||||
|
block_number_t blockno;
|
||||||
|
uint8_t tmp_sec[MAX_SECTOR_SIZE];
|
||||||
|
BootRecord *br;
|
||||||
|
|
||||||
|
blockno = gen_eckd_block_num(ptr, 0);
|
||||||
|
read_block(blockno, tmp_sec, "Cannot read boot record");
|
||||||
|
br = (BootRecord *)tmp_sec;
|
||||||
|
if (!magic_match(br->magic, ZIPL_MAGIC)) {
|
||||||
|
/* If the boot record is invalid, return and try CCW-IPL instead */
|
||||||
|
return NULL_BLOCK_NR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gen_eckd_block_num(&br->pgt.xeckd, 1);
|
||||||
|
}
|
||||||
|
|
||||||
static void print_eckd_msg(void)
|
static void print_eckd_msg(void)
|
||||||
{
|
{
|
||||||
char msg[] = "Using ECKD scheme (block size *****), ";
|
char msg[] = "Using ECKD scheme (block size *****), ";
|
||||||
|
@ -401,28 +471,43 @@ static void print_eckd_msg(void)
|
||||||
|
|
||||||
static void ipl_eckd(void)
|
static void ipl_eckd(void)
|
||||||
{
|
{
|
||||||
XEckdMbr *mbr = (void *)sec;
|
IplVolumeLabel *vlbl = (void *)sec;
|
||||||
LDL_VTOC *vlbl = (void *)sec;
|
LDL_VTOC *vtoc = (void *)sec;
|
||||||
|
block_number_t ldipl_bmt; /* Boot Map Table for List-Directed IPL */
|
||||||
|
|
||||||
print_eckd_msg();
|
print_eckd_msg();
|
||||||
|
|
||||||
/* Grab the MBR again */
|
/* Block 2 can contain either the CDL VOL1 label or the LDL VTOC */
|
||||||
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
|
||||||
read_block(0, mbr, "Cannot read block 0 on DASD");
|
|
||||||
|
|
||||||
if (magic_match(mbr->magic, IPL1_MAGIC)) {
|
|
||||||
ipl_eckd_cdl(); /* only returns in case of error */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LDL/CMS? */
|
|
||||||
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
||||||
read_block(2, vlbl, "Cannot read block 2");
|
read_block(2, vlbl, "Cannot read block 2");
|
||||||
|
|
||||||
if (magic_match(vlbl->magic, CMS1_MAGIC)) {
|
/*
|
||||||
|
* First check for a list-directed-format pointer which would
|
||||||
|
* supersede the CCW pointer.
|
||||||
|
*/
|
||||||
|
if (eckd_valid_address((ExtEckdBlockPtr *)&vlbl->f.br, 0)) {
|
||||||
|
ldipl_bmt = eckd_find_bmt((ExtEckdBlockPtr *)&vlbl->f.br);
|
||||||
|
if (ldipl_bmt) {
|
||||||
|
sclp_print("List-Directed\n");
|
||||||
|
/* LD-IPL does not use the S1B bock, just make it NULL */
|
||||||
|
run_eckd_boot_script(ldipl_bmt, NULL_BLOCK_NR);
|
||||||
|
/* Only return in error, retry as CCW-IPL */
|
||||||
|
sclp_print("Retrying IPL ");
|
||||||
|
print_eckd_msg();
|
||||||
|
}
|
||||||
|
memset(sec, FREE_SPACE_FILLER, sizeof(sec));
|
||||||
|
read_block(2, vtoc, "Cannot read block 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not list-directed */
|
||||||
|
if (magic_match(vtoc->magic, VOL1_MAGIC)) {
|
||||||
|
ipl_eckd_cdl(); /* may return in error */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (magic_match(vtoc->magic, CMS1_MAGIC)) {
|
||||||
ipl_eckd_ldl(ECKD_CMS); /* no return */
|
ipl_eckd_ldl(ECKD_CMS); /* no return */
|
||||||
}
|
}
|
||||||
if (magic_match(vlbl->magic, LNX1_MAGIC)) {
|
if (magic_match(vtoc->magic, LNX1_MAGIC)) {
|
||||||
ipl_eckd_ldl(ECKD_LDL); /* no return */
|
ipl_eckd_ldl(ECKD_LDL); /* no return */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,23 @@ typedef struct EckdBlockPtr {
|
||||||
* it's 0 for TablePtr, ScriptPtr, and SectionPtr */
|
* it's 0 for TablePtr, ScriptPtr, and SectionPtr */
|
||||||
} __attribute__ ((packed)) EckdBlockPtr;
|
} __attribute__ ((packed)) EckdBlockPtr;
|
||||||
|
|
||||||
typedef struct ExtEckdBlockPtr {
|
typedef struct LdEckdCHS {
|
||||||
|
uint32_t cylinder;
|
||||||
|
uint8_t head;
|
||||||
|
uint8_t sector;
|
||||||
|
} __attribute__ ((packed)) LdEckdCHS;
|
||||||
|
|
||||||
|
typedef struct LdEckdBlockPtr {
|
||||||
|
LdEckdCHS chs; /* cylinder/head/sector is an address of the block */
|
||||||
|
uint8_t reserved[4];
|
||||||
|
uint16_t count;
|
||||||
|
uint32_t pad;
|
||||||
|
} __attribute__ ((packed)) LdEckdBlockPtr;
|
||||||
|
|
||||||
|
/* bptr is used for CCW type IPL, while ldptr is for list-directed IPL */
|
||||||
|
typedef union ExtEckdBlockPtr {
|
||||||
EckdBlockPtr bptr;
|
EckdBlockPtr bptr;
|
||||||
uint8_t reserved[8];
|
LdEckdBlockPtr ldptr;
|
||||||
} __attribute__ ((packed)) ExtEckdBlockPtr;
|
} __attribute__ ((packed)) ExtEckdBlockPtr;
|
||||||
|
|
||||||
typedef union BootMapPointer {
|
typedef union BootMapPointer {
|
||||||
|
@ -57,6 +71,15 @@ typedef union BootMapPointer {
|
||||||
ExtEckdBlockPtr xeckd;
|
ExtEckdBlockPtr xeckd;
|
||||||
} __attribute__ ((packed)) BootMapPointer;
|
} __attribute__ ((packed)) BootMapPointer;
|
||||||
|
|
||||||
|
typedef struct BootRecord {
|
||||||
|
uint8_t magic[4];
|
||||||
|
uint32_t version;
|
||||||
|
uint64_t res1;
|
||||||
|
BootMapPointer pgt;
|
||||||
|
uint8_t reserved[510 - 32];
|
||||||
|
uint16_t os_id;
|
||||||
|
} __attribute__ ((packed)) BootRecord;
|
||||||
|
|
||||||
/* aka Program Table */
|
/* aka Program Table */
|
||||||
typedef struct BootMapTable {
|
typedef struct BootMapTable {
|
||||||
uint8_t magic[4];
|
uint8_t magic[4];
|
||||||
|
@ -292,7 +315,8 @@ typedef struct IplVolumeLabel {
|
||||||
struct {
|
struct {
|
||||||
unsigned char key[4]; /* == "VOL1" */
|
unsigned char key[4]; /* == "VOL1" */
|
||||||
unsigned char volser[6];
|
unsigned char volser[6];
|
||||||
unsigned char reserved[6];
|
unsigned char reserved[64];
|
||||||
|
EckdCHS br; /* Location of Boot Record for list-directed IPL */
|
||||||
} f;
|
} f;
|
||||||
};
|
};
|
||||||
} __attribute__((packed)) IplVolumeLabel;
|
} __attribute__((packed)) IplVolumeLabel;
|
||||||
|
|
|
@ -183,7 +183,7 @@ if idef_parser_enabled and 'hexagon-linux-user' in target_dirs
|
||||||
)
|
)
|
||||||
|
|
||||||
bison = generator(
|
bison = generator(
|
||||||
find_program('bison'),
|
find_program('bison', version: '>=3.0'),
|
||||||
output: ['@BASENAME@.tab.c', '@BASENAME@.tab.h'],
|
output: ['@BASENAME@.tab.c', '@BASENAME@.tab.h'],
|
||||||
arguments: ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@']
|
arguments: ['@INPUT@', '--defines=@OUTPUT1@', '--output=@OUTPUT0@']
|
||||||
)
|
)
|
||||||
|
|
|
@ -309,11 +309,13 @@ qtests = {
|
||||||
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
|
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if vnc.found()
|
||||||
gvnc = dependency('gvnc-1.0', required: false)
|
gvnc = dependency('gvnc-1.0', required: false)
|
||||||
if gvnc.found()
|
if gvnc.found()
|
||||||
qtests += {'vnc-display-test': [gvnc]}
|
qtests += {'vnc-display-test': [gvnc]}
|
||||||
qtests_generic += [ 'vnc-display-test' ]
|
qtests_generic += [ 'vnc-display-test' ]
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if dbus_display
|
if dbus_display
|
||||||
qtests += {'dbus-display-test': [dbus_display1, gio]}
|
qtests += {'dbus-display-test': [dbus_display1, gio]}
|
||||||
|
|
|
@ -124,13 +124,15 @@ static void test_spice(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void test_object_rng_resp(QObject *res)
|
static void test_object_available(QObject *res, const char *name,
|
||||||
|
const char *type)
|
||||||
{
|
{
|
||||||
Visitor *v;
|
Visitor *v;
|
||||||
g_autoptr(ObjectPropertyInfoList) objs = NULL;
|
g_autoptr(ObjectPropertyInfoList) objs = NULL;
|
||||||
ObjectPropertyInfoList *tmp;
|
ObjectPropertyInfoList *tmp;
|
||||||
ObjectPropertyInfo *obj;
|
ObjectPropertyInfo *obj;
|
||||||
bool seen_rng = false;
|
bool object_available = false;
|
||||||
|
g_autofree char *childtype = g_strdup_printf("child<%s>", type);
|
||||||
|
|
||||||
g_assert(res);
|
g_assert(res);
|
||||||
v = qobject_input_visitor_new(res);
|
v = qobject_input_visitor_new(res);
|
||||||
|
@ -142,16 +144,15 @@ static void test_object_rng_resp(QObject *res)
|
||||||
g_assert(tmp->value);
|
g_assert(tmp->value);
|
||||||
|
|
||||||
obj = tmp->value;
|
obj = tmp->value;
|
||||||
if (g_str_equal(obj->name, "rng0") &&
|
if (g_str_equal(obj->name, name) && g_str_equal(obj->type, childtype)) {
|
||||||
g_str_equal(obj->type, "child<rng-builtin>")) {
|
object_available = true;
|
||||||
seen_rng = true;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_assert(seen_rng);
|
g_assert(object_available);
|
||||||
|
|
||||||
visit_free(v);
|
visit_free(v);
|
||||||
}
|
}
|
||||||
|
@ -170,7 +171,27 @@ static void test_object_rng(void)
|
||||||
resp = qtest_qmp(qts,
|
resp = qtest_qmp(qts,
|
||||||
"{ 'execute': 'qom-list',"
|
"{ 'execute': 'qom-list',"
|
||||||
" 'arguments': {'path': '/objects' }}");
|
" 'arguments': {'path': '/objects' }}");
|
||||||
test_object_rng_resp(qdict_get(resp, "return"));
|
test_object_available(qdict_get(resp, "return"), "rng0", "rng-builtin");
|
||||||
|
qobject_unref(resp);
|
||||||
|
|
||||||
|
qtest_quit(qts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_docs_config_ich9(void)
|
||||||
|
{
|
||||||
|
QTestState *qts;
|
||||||
|
QDict *resp;
|
||||||
|
QObject *qobj;
|
||||||
|
|
||||||
|
qts = qtest_initf("-nodefaults -readconfig docs/config/ich9-ehci-uhci.cfg");
|
||||||
|
|
||||||
|
resp = qtest_qmp(qts, "{ 'execute': 'qom-list',"
|
||||||
|
" 'arguments': {'path': '/machine/peripheral' }}");
|
||||||
|
qobj = qdict_get(resp, "return");
|
||||||
|
test_object_available(qobj, "ehci", "ich9-usb-ehci1");
|
||||||
|
test_object_available(qobj, "uhci-1", "ich9-usb-uhci1");
|
||||||
|
test_object_available(qobj, "uhci-2", "ich9-usb-uhci2");
|
||||||
|
test_object_available(qobj, "uhci-3", "ich9-usb-uhci3");
|
||||||
qobject_unref(resp);
|
qobject_unref(resp);
|
||||||
|
|
||||||
qtest_quit(qts);
|
qtest_quit(qts);
|
||||||
|
@ -186,6 +207,7 @@ int main(int argc, char *argv[])
|
||||||
if (g_str_equal(arch, "i386") ||
|
if (g_str_equal(arch, "i386") ||
|
||||||
g_str_equal(arch, "x86_64")) {
|
g_str_equal(arch, "x86_64")) {
|
||||||
qtest_add_func("readconfig/x86/memdev", test_x86_memdev);
|
qtest_add_func("readconfig/x86/memdev", test_x86_memdev);
|
||||||
|
qtest_add_func("readconfig/x86/ich9-ehci-uhci", test_docs_config_ich9);
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_SPICE
|
#ifdef CONFIG_SPICE
|
||||||
qtest_add_func("readconfig/spice", test_spice);
|
qtest_add_func("readconfig/spice", test_spice);
|
||||||
|
|
Loading…
Reference in New Issue