* Compat machines for version 8.1

* Allow setting a chardev input file on the command line
 * Fix .travis.yml to work with non-public Travis instances, too
 * Move a lot of code from specifc_ss into softmmu_ss
 * Add a test case for TPM TIS I2C connected to Aspeed I2C controller
 * Update tests/vm/freebsd to version 13
 * Some more misc minor fixes here and there
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmRBDtMRHHRodXRoQHJl
 ZGhhdC5jb20ACgkQLtnXdP5wLbXfjw//UYytlyZsDOLAMfFNGQViMmVf29KbrDRe
 doDh4Nl1oZLNKm9C5XlQExhsRbLm6Hi9nyQvSCJs4CvZ1jBY6U7GfgMNIaozXWb3
 4gQyJb9ACe/z8bQmPUVF2sdW1QZ9zpf8LWpCOTGUZiI2Tevzkz7b/F5ZxiQiseG6
 dXe8UIwdZhG4jz2+6viqjHiGlKoBkegGYoJthcwnR07aRz2woiNr7rKRiJEiv2G7
 UfMVB96uLkpEhaDoohz440/rjviazO1nt6HDvgEajXT1X5P/8phT9IvT7olAZXZH
 R2Qm6YyYcSWavoPms3AryAWG8FjomcyBjuebfAVW5/x+fl/401sn9quBMoZrYPEX
 dfzF64vVokdXNQEH6+qc95PdB6/+d0CZPY8ilMRtAttf2sMw7IgqhG3zDLbj9t6R
 dns2/DY9zu2pp07IEAXn/iVbW4rl2HADUQncr6B/cPy++lYiFvv7LX8OE+YWOsk0
 gvxzYx6rRhr5j7xT1sP30pLwsG3mX7qRDfba1Bt19CzSbu7UGN+w+S1xclgZDoqE
 0AZIeVUuqqNTEoBLoa2xHUDGs9NjeI2+qIh0R5csS/bqDscLXj0cOluvJO48n4Rt
 +SGQSCSmU/lxn6EbBz4tw3orlp0clBH9fEaSg9lYxuUTYvQOpdYS7u4d63VQFvzp
 dwQ9LRDFNsA=
 =8ZFL
 -----END PGP SIGNATURE-----

Merge tag 'pull-request-2023-04-20' of https://gitlab.com/thuth/qemu into staging

* Compat machines for version 8.1
* Allow setting a chardev input file on the command line
* Fix .travis.yml to work with non-public Travis instances, too
* Move a lot of code from specifc_ss into softmmu_ss
* Add a test case for TPM TIS I2C connected to Aspeed I2C controller
* Update tests/vm/freebsd to version 13
* Some more misc minor fixes here and there

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmRBDtMRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbXfjw//UYytlyZsDOLAMfFNGQViMmVf29KbrDRe
# doDh4Nl1oZLNKm9C5XlQExhsRbLm6Hi9nyQvSCJs4CvZ1jBY6U7GfgMNIaozXWb3
# 4gQyJb9ACe/z8bQmPUVF2sdW1QZ9zpf8LWpCOTGUZiI2Tevzkz7b/F5ZxiQiseG6
# dXe8UIwdZhG4jz2+6viqjHiGlKoBkegGYoJthcwnR07aRz2woiNr7rKRiJEiv2G7
# UfMVB96uLkpEhaDoohz440/rjviazO1nt6HDvgEajXT1X5P/8phT9IvT7olAZXZH
# R2Qm6YyYcSWavoPms3AryAWG8FjomcyBjuebfAVW5/x+fl/401sn9quBMoZrYPEX
# dfzF64vVokdXNQEH6+qc95PdB6/+d0CZPY8ilMRtAttf2sMw7IgqhG3zDLbj9t6R
# dns2/DY9zu2pp07IEAXn/iVbW4rl2HADUQncr6B/cPy++lYiFvv7LX8OE+YWOsk0
# gvxzYx6rRhr5j7xT1sP30pLwsG3mX7qRDfba1Bt19CzSbu7UGN+w+S1xclgZDoqE
# 0AZIeVUuqqNTEoBLoa2xHUDGs9NjeI2+qIh0R5csS/bqDscLXj0cOluvJO48n4Rt
# +SGQSCSmU/lxn6EbBz4tw3orlp0clBH9fEaSg9lYxuUTYvQOpdYS7u4d63VQFvzp
# dwQ9LRDFNsA=
# =8ZFL
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 20 Apr 2023 11:07:15 AM BST
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [undefined]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [undefined]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [undefined]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2023-04-20' of https://gitlab.com/thuth/qemu: (23 commits)
  tests/vm/freebsd: Update to FreeBSD 13.2
  qtest: Add a test case for TPM TIS I2C connected to Aspeed I2C controller
  qtest: Move tpm_util_tis_transmit() into tpm-tis-utils.c and rename it
  qtest: Add functions for accessing devices on Aspeed I2C controller
  MAINTAINERS: Add Juan Quintela to developer guides review
  cpu: Remove parameter of list_cpus()
  hw/core: Move numa.c into the target independent source set
  softmmu: Move dirtylimit.c into the target independent source set
  hw/display: Compile vga.c as target-independent code
  softmmu: Make qtest.c target independent
  include/exec: Provide the tswap() functions for target independent code, too
  softmmu/qtest: Move the target-specific pseries RTAS code out of qtest.c
  hw/char: Move two more files from specific_ss to softmmu_ss
  target/i386: Set family/model/stepping of the "max" CPU according to LM bit
  tests/migration: Only run auto_converge in slow mode
  travis.yml: Add missing 'flex', 'bison' packages to 'GCC (user)' job
  travis.yml: Add missing clang-10 package to the 'Clang (disable-tcg)' job
  chardev: Allow setting file chardev input file on the command line
  qtest: Don't assert on "-qtest chardev:myid"
  test: Fix test-crypto-secret when compiling without keyring support
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2023-04-21 12:31:46 +01:00
commit 1093893f07
48 changed files with 1224 additions and 282 deletions

View File

@ -237,13 +237,15 @@ jobs:
- libglib2.0-dev - libglib2.0-dev
- libgnutls28-dev - libgnutls28-dev
- ninja-build - ninja-build
- flex
- bison
env: env:
- CONFIG="--disable-containers --disable-system" - CONFIG="--disable-containers --disable-system"
- name: "[s390x] Clang (disable-tcg)" - name: "[s390x] Clang (disable-tcg)"
arch: s390x arch: s390x
dist: focal dist: focal
compiler: clang compiler: clang-10
addons: addons:
apt_packages: apt_packages:
- libaio-dev - libaio-dev
@ -269,6 +271,7 @@ jobs:
- libvdeplug-dev - libvdeplug-dev
- libvte-2.91-dev - libvte-2.91-dev
- ninja-build - ninja-build
- clang-10
env: env:
- TEST_CMD="make check-unit" - TEST_CMD="make check-unit"
- CONFIG="--disable-containers --disable-tcg --enable-kvm --disable-tools - CONFIG="--disable-containers --disable-tcg --enable-kvm --disable-tools

View File

@ -70,6 +70,7 @@ R: Daniel P. Berrangé <berrange@redhat.com>
R: Thomas Huth <thuth@redhat.com> R: Thomas Huth <thuth@redhat.com>
R: Markus Armbruster <armbru@redhat.com> R: Markus Armbruster <armbru@redhat.com>
R: Philippe Mathieu-Daudé <philmd@linaro.org> R: Philippe Mathieu-Daudé <philmd@linaro.org>
R: Juan Quintela <quintela@redhat.com>
W: https://www.qemu.org/docs/master/devel/index.html W: https://www.qemu.org/docs/master/devel/index.html
S: Odd Fixes S: Odd Fixes
F: docs/devel/style.rst F: docs/devel/style.rst

View File

@ -100,6 +100,7 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
Error **errp) Error **errp)
{ {
const char *path = qemu_opt_get(opts, "path"); const char *path = qemu_opt_get(opts, "path");
const char *inpath = qemu_opt_get(opts, "input-path");
ChardevFile *file; ChardevFile *file;
backend->type = CHARDEV_BACKEND_KIND_FILE; backend->type = CHARDEV_BACKEND_KIND_FILE;
@ -107,9 +108,16 @@ static void qemu_chr_parse_file_out(QemuOpts *opts, ChardevBackend *backend,
error_setg(errp, "chardev: file: no filename given"); error_setg(errp, "chardev: file: no filename given");
return; return;
} }
#ifdef _WIN32
if (inpath) {
error_setg(errp, "chardev: file: input-path not supported on Windows");
return;
}
#endif
file = backend->u.file.data = g_new0(ChardevFile, 1); file = backend->u.file.data = g_new0(ChardevFile, 1);
qemu_chr_parse_common(opts, qapi_ChardevFile_base(file)); qemu_chr_parse_common(opts, qapi_ChardevFile_base(file));
file->out = g_strdup(path); file->out = g_strdup(path);
file->in = g_strdup(inpath);
file->has_append = true; file->has_append = true;
file->append = qemu_opt_get_bool(opts, "append", false); file->append = qemu_opt_get_bool(opts, "append", false);

View File

@ -805,6 +805,9 @@ QemuOptsList qemu_chardev_opts = {
},{ },{
.name = "path", .name = "path",
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,
},{
.name = "input-path",
.type = QEMU_OPT_STRING,
},{ },{
.name = "host", .name = "host",
.type = QEMU_OPT_STRING, .type = QEMU_OPT_STRING,

2
cpu.c
View File

@ -284,7 +284,7 @@ const char *parse_cpu_option(const char *cpu_option)
return cpu_type; return cpu_type;
} }
void list_cpus(const char *optarg) void list_cpus(void)
{ {
/* XXX: implement xxx_cpu_list for targets that still miss it */ /* XXX: implement xxx_cpu_list for targets that still miss it */
#if defined(cpu_list) #if defined(cpu_list)

View File

@ -111,7 +111,7 @@ Interfaces provided include:
CXL Root Ports (CXL RP) CXL Root Ports (CXL RP)
~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
A CXL Root Port servers te same purpose as a PCIe Root Port. A CXL Root Port serves the same purpose as a PCIe Root Port.
There are a number of CXL specific Designated Vendor Specific There are a number of CXL specific Designated Vendor Specific
Extended Capabilities (DVSEC) in PCIe Configuration Space Extended Capabilities (DVSEC) in PCIe Configuration Space
and associated component register access via PCI bars. and associated component register access via PCI bars.

View File

@ -27,7 +27,7 @@ Tiny Code Generator (TCG) capable of emulating many CPUs.
* - Hypervisor Framework (hvf) * - Hypervisor Framework (hvf)
- MacOS - MacOS
- x86 (64 bit only), Arm (64 bit only) - x86 (64 bit only), Arm (64 bit only)
* - Windows Hypervisor Platform (wphx) * - Windows Hypervisor Platform (whpx)
- Windows - Windows
- x86 - x86
* - NetBSD Virtual Machine Monitor (nvmm) * - NetBSD Virtual Machine Monitor (nvmm)

View File

@ -3234,10 +3234,17 @@ static void machvirt_machine_init(void)
} }
type_init(machvirt_machine_init); type_init(machvirt_machine_init);
static void virt_machine_8_0_options(MachineClass *mc) static void virt_machine_8_1_options(MachineClass *mc)
{ {
} }
DEFINE_VIRT_MACHINE_AS_LATEST(8, 0) DEFINE_VIRT_MACHINE_AS_LATEST(8, 1)
static void virt_machine_8_0_options(MachineClass *mc)
{
virt_machine_8_1_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
}
DEFINE_VIRT_MACHINE(8, 0)
static void virt_machine_7_2_options(MachineClass *mc) static void virt_machine_7_2_options(MachineClass *mc)
{ {

View File

@ -32,10 +32,9 @@ softmmu_ss.add(when: 'CONFIG_SIFIVE_UART', if_true: files('sifive_uart.c'))
softmmu_ss.add(when: 'CONFIG_SH_SCI', if_true: files('sh_serial.c')) softmmu_ss.add(when: 'CONFIG_SH_SCI', if_true: files('sh_serial.c'))
softmmu_ss.add(when: 'CONFIG_STM32F2XX_USART', if_true: files('stm32f2xx_usart.c')) softmmu_ss.add(when: 'CONFIG_STM32F2XX_USART', if_true: files('stm32f2xx_usart.c'))
softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_MMUART', if_true: files('mchp_pfsoc_mmuart.c')) softmmu_ss.add(when: 'CONFIG_MCHP_PFSOC_MMUART', if_true: files('mchp_pfsoc_mmuart.c'))
softmmu_ss.add(when: 'CONFIG_HTIF', if_true: files('riscv_htif.c'))
softmmu_ss.add(when: 'CONFIG_GOLDFISH_TTY', if_true: files('goldfish_tty.c'))
specific_ss.add(when: 'CONFIG_HTIF', if_true: files('riscv_htif.c'))
specific_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('terminal3270.c')) specific_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('terminal3270.c'))
specific_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-serial-bus.c')) specific_ss.add(when: 'CONFIG_VIRTIO', if_true: files('virtio-serial-bus.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_vty.c')) specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_vty.c'))
specific_ss.add(when: 'CONFIG_GOLDFISH_TTY', if_true: files('goldfish_tty.c'))

View File

@ -39,6 +39,9 @@
#include "hw/virtio/virtio.h" #include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-pci.h" #include "hw/virtio/virtio-pci.h"
GlobalProperty hw_compat_8_0[] = {};
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
GlobalProperty hw_compat_7_2[] = { GlobalProperty hw_compat_7_2[] = {
{ "e1000e", "migrate-timadj", "off" }, { "e1000e", "migrate-timadj", "off" },
{ "virtio-mem", "x-early-migration", "false" }, { "virtio-mem", "x-early-migration", "false" },

View File

@ -44,6 +44,7 @@ softmmu_ss.add(files(
'machine.c', 'machine.c',
'nmi.c', 'nmi.c',
'null-machine.c', 'null-machine.c',
'numa.c',
'qdev-fw.c', 'qdev-fw.c',
'qdev-properties-system.c', 'qdev-properties-system.c',
'sysbus.c', 'sysbus.c',
@ -53,5 +54,4 @@ softmmu_ss.add(files(
specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files( specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files(
'machine-qmp-cmds.c', 'machine-qmp-cmds.c',
'numa.c',
)) ))

View File

@ -36,7 +36,7 @@ softmmu_ss.add(when: 'CONFIG_CG3', if_true: files('cg3.c'))
softmmu_ss.add(when: 'CONFIG_MACFB', if_true: files('macfb.c')) softmmu_ss.add(when: 'CONFIG_MACFB', if_true: files('macfb.c'))
softmmu_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c')) softmmu_ss.add(when: 'CONFIG_NEXTCUBE', if_true: files('next-fb.c'))
specific_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c')) softmmu_ss.add(when: 'CONFIG_VGA', if_true: files('vga.c'))
if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or if (config_all_devices.has_key('CONFIG_VGA_CIRRUS') or
config_all_devices.has_key('CONFIG_VGA_PCI') or config_all_devices.has_key('CONFIG_VGA_PCI') or

View File

@ -26,7 +26,9 @@
#include "qemu/units.h" #include "qemu/units.h"
#include "sysemu/reset.h" #include "sysemu/reset.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "hw/core/cpu.h"
#include "hw/display/vga.h" #include "hw/display/vga.h"
#include "hw/i386/x86.h"
#include "hw/pci/pci.h" #include "hw/pci/pci.h"
#include "vga_int.h" #include "vga_int.h"
#include "vga_regs.h" #include "vga_regs.h"
@ -2244,11 +2246,8 @@ bool vga_common_init(VGACommonState *s, Object *obj, Error **errp)
* into a device attribute set by the machine/platform to remove * into a device attribute set by the machine/platform to remove
* all target endian dependencies from this file. * all target endian dependencies from this file.
*/ */
#if TARGET_BIG_ENDIAN s->default_endian_fb = target_words_bigendian();
s->default_endian_fb = true;
#else
s->default_endian_fb = false;
#endif
vga_dirty_log_start(s); vga_dirty_log_start(s);
return true; return true;
@ -2263,11 +2262,15 @@ static const MemoryRegionPortio vga_portio_list[] = {
PORTIO_END_OF_LIST(), PORTIO_END_OF_LIST(),
}; };
static const MemoryRegionPortio vbe_portio_list[] = { static const MemoryRegionPortio vbe_portio_list_x86[] = {
{ 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index }, { 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
# ifdef TARGET_I386
{ 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
# endif { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
PORTIO_END_OF_LIST(),
};
static const MemoryRegionPortio vbe_portio_list_no_x86[] = {
{ 0, 1, 2, .read = vbe_ioport_read_index, .write = vbe_ioport_write_index },
{ 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data }, { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data },
PORTIO_END_OF_LIST(), PORTIO_END_OF_LIST(),
}; };
@ -2278,9 +2281,19 @@ MemoryRegion *vga_init_io(VGACommonState *s, Object *obj,
const MemoryRegionPortio **vbe_ports) const MemoryRegionPortio **vbe_ports)
{ {
MemoryRegion *vga_mem; MemoryRegion *vga_mem;
MachineState *ms = MACHINE(qdev_get_machine());
/*
* We unfortunately need two VBE lists since non-x86 machines might
* not be able to do 16-bit accesses at unaligned addresses (0x1cf)
*/
if (object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE)) {
*vbe_ports = vbe_portio_list_x86;
} else {
*vbe_ports = vbe_portio_list_no_x86;
}
*vga_ports = vga_portio_list; *vga_ports = vga_portio_list;
*vbe_ports = vbe_portio_list;
vga_mem = g_malloc(sizeof(*vga_mem)); vga_mem = g_malloc(sizeof(*vga_mem));
memory_region_init_io(vga_mem, obj, &vga_mem_ops, s, memory_region_init_io(vga_mem, obj, &vga_mem_ops, s,

View File

@ -116,6 +116,9 @@
{ "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\ { "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\
{ "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, }, { "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },
GlobalProperty pc_compat_8_0[] = {};
const size_t pc_compat_8_0_len = G_N_ELEMENTS(pc_compat_8_0);
GlobalProperty pc_compat_7_2[] = { GlobalProperty pc_compat_7_2[] = {
{ "ICH9-LPC", "noreboot", "true" }, { "ICH9-LPC", "noreboot", "true" },
}; };

View File

@ -454,21 +454,31 @@ static void pc_i440fx_machine_options(MachineClass *m)
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE); machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
} }
static void pc_i440fx_8_0_machine_options(MachineClass *m) static void pc_i440fx_8_1_machine_options(MachineClass *m)
{ {
pc_i440fx_machine_options(m); pc_i440fx_machine_options(m);
m->alias = "pc"; m->alias = "pc";
m->is_default = true; m->is_default = true;
} }
DEFINE_I440FX_MACHINE(v8_1, "pc-i440fx-8.1", NULL,
pc_i440fx_8_1_machine_options);
static void pc_i440fx_8_0_machine_options(MachineClass *m)
{
pc_i440fx_8_1_machine_options(m);
m->alias = NULL;
m->is_default = false;
compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);
}
DEFINE_I440FX_MACHINE(v8_0, "pc-i440fx-8.0", NULL, DEFINE_I440FX_MACHINE(v8_0, "pc-i440fx-8.0", NULL,
pc_i440fx_8_0_machine_options); pc_i440fx_8_0_machine_options);
static void pc_i440fx_7_2_machine_options(MachineClass *m) static void pc_i440fx_7_2_machine_options(MachineClass *m)
{ {
pc_i440fx_8_0_machine_options(m); pc_i440fx_8_0_machine_options(m);
m->alias = NULL;
m->is_default = false;
compat_props_add(m->compat_props, hw_compat_7_2, hw_compat_7_2_len); compat_props_add(m->compat_props, hw_compat_7_2, hw_compat_7_2_len);
compat_props_add(m->compat_props, pc_compat_7_2, pc_compat_7_2_len); compat_props_add(m->compat_props, pc_compat_7_2, pc_compat_7_2_len);
} }

View File

@ -373,19 +373,29 @@ static void pc_q35_machine_options(MachineClass *m)
m->max_cpus = 288; m->max_cpus = 288;
} }
static void pc_q35_8_0_machine_options(MachineClass *m) static void pc_q35_8_1_machine_options(MachineClass *m)
{ {
pc_q35_machine_options(m); pc_q35_machine_options(m);
m->alias = "q35"; m->alias = "q35";
} }
DEFINE_Q35_MACHINE(v8_1, "pc-q35-8.1", NULL,
pc_q35_8_1_machine_options);
static void pc_q35_8_0_machine_options(MachineClass *m)
{
pc_q35_8_1_machine_options(m);
m->alias = NULL;
compat_props_add(m->compat_props, hw_compat_8_0, hw_compat_8_0_len);
compat_props_add(m->compat_props, pc_compat_8_0, pc_compat_8_0_len);
}
DEFINE_Q35_MACHINE(v8_0, "pc-q35-8.0", NULL, DEFINE_Q35_MACHINE(v8_0, "pc-q35-8.0", NULL,
pc_q35_8_0_machine_options); pc_q35_8_0_machine_options);
static void pc_q35_7_2_machine_options(MachineClass *m) static void pc_q35_7_2_machine_options(MachineClass *m)
{ {
pc_q35_8_0_machine_options(m); pc_q35_8_0_machine_options(m);
m->alias = NULL;
compat_props_add(m->compat_props, hw_compat_7_2, hw_compat_7_2_len); compat_props_add(m->compat_props, hw_compat_7_2, hw_compat_7_2_len);
compat_props_add(m->compat_props, pc_compat_7_2, pc_compat_7_2_len); compat_props_add(m->compat_props, pc_compat_7_2, pc_compat_7_2_len);
} }

View File

@ -347,10 +347,17 @@ type_init(virt_machine_register_types)
} \ } \
type_init(machvirt_machine_##major##_##minor##_init); type_init(machvirt_machine_##major##_##minor##_init);
static void virt_machine_8_0_options(MachineClass *mc) static void virt_machine_8_1_options(MachineClass *mc)
{ {
} }
DEFINE_VIRT_MACHINE(8, 0, true) DEFINE_VIRT_MACHINE(8, 1, true)
static void virt_machine_8_0_options(MachineClass *mc)
{
virt_machine_8_1_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
}
DEFINE_VIRT_MACHINE(8, 0, false)
static void virt_machine_7_2_options(MachineClass *mc) static void virt_machine_7_2_options(MachineClass *mc)
{ {

View File

@ -4735,14 +4735,25 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
type_init(spapr_machine_register_##suffix) type_init(spapr_machine_register_##suffix)
/* /*
* pseries-8.0 * pseries-8.1
*/ */
static void spapr_machine_8_0_class_options(MachineClass *mc) static void spapr_machine_8_1_class_options(MachineClass *mc)
{ {
/* Defaults for the latest behaviour inherited from the base class */ /* Defaults for the latest behaviour inherited from the base class */
} }
DEFINE_SPAPR_MACHINE(8_0, "8.0", true); DEFINE_SPAPR_MACHINE(8_1, "8.1", true);
/*
* pseries-8.0
*/
static void spapr_machine_8_0_class_options(MachineClass *mc)
{
spapr_machine_8_1_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
}
DEFINE_SPAPR_MACHINE(8_0, "8.0", false);
/* /*
* pseries-7.2 * pseries-7.2

View File

@ -33,6 +33,7 @@
#include "sysemu/cpus.h" #include "sysemu/cpus.h"
#include "sysemu/hw_accel.h" #include "sysemu/hw_accel.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "sysemu/qtest.h"
#include "kvm_ppc.h" #include "kvm_ppc.h"
#include "hw/ppc/spapr.h" #include "hw/ppc/spapr.h"
@ -548,6 +549,32 @@ uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args,
return H_PARAMETER; return H_PARAMETER;
} }
static bool spapr_qtest_callback(CharBackend *chr, gchar **words)
{
if (strcmp(words[0], "rtas") == 0) {
uint64_t res, args, ret;
unsigned long nargs, nret;
int rc;
rc = qemu_strtoul(words[2], NULL, 0, &nargs);
g_assert(rc == 0);
rc = qemu_strtou64(words[3], NULL, 0, &args);
g_assert(rc == 0);
rc = qemu_strtoul(words[4], NULL, 0, &nret);
g_assert(rc == 0);
rc = qemu_strtou64(words[5], NULL, 0, &ret);
g_assert(rc == 0);
res = qtest_rtas_call(words[1], nargs, args, nret, ret);
qtest_send_prefix(chr);
qtest_sendf(chr, "OK %"PRIu64"\n", res);
return true;
}
return false;
}
void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn) void spapr_rtas_register(int token, const char *name, spapr_rtas_fn fn)
{ {
assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX)); assert((token >= RTAS_TOKEN_BASE) && (token < RTAS_TOKEN_MAX));
@ -630,6 +657,8 @@ static void core_rtas_register_types(void)
rtas_ibm_nmi_register); rtas_ibm_nmi_register);
spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock", spapr_rtas_register(RTAS_IBM_NMI_INTERLOCK, "ibm,nmi-interlock",
rtas_ibm_nmi_interlock); rtas_ibm_nmi_interlock);
qtest_set_command_cb(spapr_qtest_callback);
} }
type_init(core_rtas_register_types) type_init(core_rtas_register_types)

View File

@ -826,14 +826,26 @@ bool css_migration_enabled(void)
} \ } \
type_init(ccw_machine_register_##suffix) type_init(ccw_machine_register_##suffix)
static void ccw_machine_8_1_instance_options(MachineState *machine)
{
}
static void ccw_machine_8_1_class_options(MachineClass *mc)
{
}
DEFINE_CCW_MACHINE(8_1, "8.1", true);
static void ccw_machine_8_0_instance_options(MachineState *machine) static void ccw_machine_8_0_instance_options(MachineState *machine)
{ {
ccw_machine_8_1_instance_options(machine);
} }
static void ccw_machine_8_0_class_options(MachineClass *mc) static void ccw_machine_8_0_class_options(MachineClass *mc)
{ {
ccw_machine_8_1_class_options(mc);
compat_props_add(mc->compat_props, hw_compat_8_0, hw_compat_8_0_len);
} }
DEFINE_CCW_MACHINE(8_0, "8.0", true); DEFINE_CCW_MACHINE(8_0, "8.0", false);
static void ccw_machine_7_2_instance_options(MachineState *machine) static void ccw_machine_7_2_instance_options(MachineState *machine)
{ {

View File

@ -21,6 +21,7 @@
#include "exec/cpu-common.h" #include "exec/cpu-common.h"
#include "exec/memory.h" #include "exec/memory.h"
#include "exec/tswap.h"
#include "qemu/thread.h" #include "qemu/thread.h"
#include "hw/core/cpu.h" #include "hw/core/cpu.h"
#include "qemu/rcu.h" #include "qemu/rcu.h"
@ -44,69 +45,6 @@
#define BSWAP_NEEDED #define BSWAP_NEEDED
#endif #endif
#ifdef BSWAP_NEEDED
static inline uint16_t tswap16(uint16_t s)
{
return bswap16(s);
}
static inline uint32_t tswap32(uint32_t s)
{
return bswap32(s);
}
static inline uint64_t tswap64(uint64_t s)
{
return bswap64(s);
}
static inline void tswap16s(uint16_t *s)
{
*s = bswap16(*s);
}
static inline void tswap32s(uint32_t *s)
{
*s = bswap32(*s);
}
static inline void tswap64s(uint64_t *s)
{
*s = bswap64(*s);
}
#else
static inline uint16_t tswap16(uint16_t s)
{
return s;
}
static inline uint32_t tswap32(uint32_t s)
{
return s;
}
static inline uint64_t tswap64(uint64_t s)
{
return s;
}
static inline void tswap16s(uint16_t *s)
{
}
static inline void tswap32s(uint32_t *s)
{
}
static inline void tswap64s(uint64_t *s)
{
}
#endif
#if TARGET_LONG_SIZE == 4 #if TARGET_LONG_SIZE == 4
#define tswapl(s) tswap32(s) #define tswapl(s) tswap32(s)
#define tswapls(s) tswap32s((uint32_t *)(s)) #define tswapls(s) tswap32s((uint32_t *)(s))

View File

@ -165,6 +165,6 @@ int cpu_memory_rw_debug(CPUState *cpu, vaddr addr,
/* vl.c */ /* vl.c */
extern int singlestep; extern int singlestep;
void list_cpus(const char *optarg); void list_cpus(void);
#endif /* CPU_COMMON_H */ #endif /* CPU_COMMON_H */

72
include/exec/tswap.h Normal file
View File

@ -0,0 +1,72 @@
/*
* Macros for swapping a value if the endianness is different
* between the target and the host.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#ifndef TSWAP_H
#define TSWAP_H
#include "hw/core/cpu.h"
#include "qemu/bswap.h"
/*
* If we're in target-specific code, we can hard-code the swapping
* condition, otherwise we have to do (slower) run-time checks.
*/
#ifdef NEED_CPU_H
#define target_needs_bswap() (HOST_BIG_ENDIAN != TARGET_BIG_ENDIAN)
#else
#define target_needs_bswap() (target_words_bigendian() != HOST_BIG_ENDIAN)
#endif
static inline uint16_t tswap16(uint16_t s)
{
if (target_needs_bswap()) {
return bswap16(s);
} else {
return s;
}
}
static inline uint32_t tswap32(uint32_t s)
{
if (target_needs_bswap()) {
return bswap32(s);
} else {
return s;
}
}
static inline uint64_t tswap64(uint64_t s)
{
if (target_needs_bswap()) {
return bswap64(s);
} else {
return s;
}
}
static inline void tswap16s(uint16_t *s)
{
if (target_needs_bswap()) {
*s = bswap16(*s);
}
}
static inline void tswap32s(uint32_t *s)
{
if (target_needs_bswap()) {
*s = bswap32(*s);
}
}
static inline void tswap64s(uint64_t *s)
{
if (target_needs_bswap()) {
*s = bswap64(*s);
}
}
#endif /* TSWAP_H */

View File

@ -381,6 +381,9 @@ struct MachineState {
} \ } \
type_init(machine_initfn##_register_types) type_init(machine_initfn##_register_types)
extern GlobalProperty hw_compat_8_0[];
extern const size_t hw_compat_8_0_len;
extern GlobalProperty hw_compat_7_2[]; extern GlobalProperty hw_compat_7_2[];
extern const size_t hw_compat_7_2_len; extern const size_t hw_compat_7_2_len;

View File

@ -38,6 +38,13 @@ OBJECT_DECLARE_TYPE(AspeedI2CState, AspeedI2CClass, ASPEED_I2C)
#define ASPEED_I2C_OLD_NUM_REG 11 #define ASPEED_I2C_OLD_NUM_REG 11
#define ASPEED_I2C_NEW_NUM_REG 22 #define ASPEED_I2C_NEW_NUM_REG 22
#define A_I2CD_M_STOP_CMD BIT(5)
#define A_I2CD_M_RX_CMD BIT(3)
#define A_I2CD_M_TX_CMD BIT(1)
#define A_I2CD_M_START_CMD BIT(0)
#define A_I2CD_MASTER_EN BIT(0)
/* Tx State Machine */ /* Tx State Machine */
#define I2CD_TX_STATE_MASK 0xf #define I2CD_TX_STATE_MASK 0xf
#define I2CD_IDLE 0x0 #define I2CD_IDLE 0x0

View File

@ -195,6 +195,9 @@ void pc_madt_cpu_entry(int uid, const CPUArchIdList *apic_ids,
/* sgx.c */ /* sgx.c */
void pc_machine_init_sgx_epc(PCMachineState *pcms); void pc_machine_init_sgx_epc(PCMachineState *pcms);
extern GlobalProperty pc_compat_8_0[];
extern const size_t pc_compat_8_0_len;
extern GlobalProperty pc_compat_7_2[]; extern GlobalProperty pc_compat_7_2[];
extern const size_t pc_compat_7_2_len; extern const size_t pc_compat_7_2_len;

View File

@ -14,6 +14,7 @@
#ifndef QTEST_H #ifndef QTEST_H
#define QTEST_H #define QTEST_H
#include "chardev/char.h"
extern bool qtest_allowed; extern bool qtest_allowed;
@ -22,6 +23,9 @@ static inline bool qtest_enabled(void)
return qtest_allowed; return qtest_allowed;
} }
void qtest_send_prefix(CharBackend *chr);
void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, const char *fmt, ...);
void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words));
bool qtest_driver(void); bool qtest_driver(void);
void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp); void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **errp);

View File

@ -3360,7 +3360,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
"-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n" "-chardev vc,id=id[[,width=width][,height=height]][[,cols=cols][,rows=rows]]\n"
" [,mux=on|off][,logfile=PATH][,logappend=on|off]\n" " [,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev ringbuf,id=id[,size=size][,logfile=PATH][,logappend=on|off]\n" "-chardev ringbuf,id=id[,size=size][,logfile=PATH][,logappend=on|off]\n"
"-chardev file,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" "-chardev file,id=id,path=path[,input-path=input-file][,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
"-chardev pipe,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" "-chardev pipe,id=id,path=path[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
#ifdef _WIN32 #ifdef _WIN32
"-chardev console,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n" "-chardev console,id=id[,mux=on|off][,logfile=PATH][,logappend=on|off]\n"
@ -3563,13 +3563,19 @@ The available backends are:
Create a ring buffer with fixed size ``size``. size must be a power Create a ring buffer with fixed size ``size``. size must be a power
of two and defaults to ``64K``. of two and defaults to ``64K``.
``-chardev file,id=id,path=path`` ``-chardev file,id=id,path=path[,input-path=input-path]``
Log all traffic received from the guest to a file. Log all traffic received from the guest to a file.
``path`` specifies the path of the file to be opened. This file will ``path`` specifies the path of the file to be opened. This file will
be created if it does not already exist, and overwritten if it does. be created if it does not already exist, and overwritten if it does.
``path`` is required. ``path`` is required.
If ``input-path`` is specified, this is the path of a second file
which will be used for input. If ``input-path`` is not specified,
no input will be available from the chardev.
Note that ``input-path`` is not supported on Windows hosts.
``-chardev pipe,id=id,path=path`` ``-chardev pipe,id=id,path=path``
Create a two-way connection to the guest. The behaviour differs Create a two-way connection to the guest. The behaviour differs
slightly between Windows hosts and other hosts: slightly between Windows hosts and other hosts:

View File

@ -20,6 +20,7 @@
#include "monitor/hmp.h" #include "monitor/hmp.h"
#include "monitor/monitor.h" #include "monitor/monitor.h"
#include "exec/memory.h" #include "exec/memory.h"
#include "exec/target_page.h"
#include "hw/boards.h" #include "hw/boards.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "trace.h" #include "trace.h"
@ -236,7 +237,7 @@ static inline int64_t dirtylimit_dirty_ring_full_time(uint64_t dirtyrate)
static uint64_t max_dirtyrate; static uint64_t max_dirtyrate;
uint32_t dirty_ring_size = kvm_dirty_ring_size(); uint32_t dirty_ring_size = kvm_dirty_ring_size();
uint64_t dirty_ring_size_meory_MB = uint64_t dirty_ring_size_meory_MB =
dirty_ring_size * TARGET_PAGE_SIZE >> 20; dirty_ring_size * qemu_target_page_size() >> 20;
if (max_dirtyrate < dirtyrate) { if (max_dirtyrate < dirtyrate) {
max_dirtyrate = dirtyrate; max_dirtyrate = dirtyrate;

View File

@ -3,8 +3,6 @@ specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files(
'ioport.c', 'ioport.c',
'memory.c', 'memory.c',
'physmem.c', 'physmem.c',
'qtest.c',
'dirtylimit.c',
'watchpoint.c', 'watchpoint.c',
)]) )])
@ -19,10 +17,12 @@ softmmu_ss.add(files(
'cpu-throttle.c', 'cpu-throttle.c',
'cpu-timers.c', 'cpu-timers.c',
'datadir.c', 'datadir.c',
'dirtylimit.c',
'dma-helpers.c', 'dma-helpers.c',
'globals.c', 'globals.c',
'memory_mapping.c', 'memory_mapping.c',
'qdev-monitor.c', 'qdev-monitor.c',
'qtest.c',
'rtc.c', 'rtc.c',
'runstate-action.c', 'runstate-action.c',
'runstate-hmp-cmds.c', 'runstate-hmp-cmds.c',

View File

@ -13,12 +13,12 @@
#include "qemu/osdep.h" #include "qemu/osdep.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "cpu.h"
#include "sysemu/qtest.h" #include "sysemu/qtest.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "chardev/char-fe.h" #include "chardev/char-fe.h"
#include "exec/ioport.h" #include "exec/ioport.h"
#include "exec/memory.h" #include "exec/memory.h"
#include "exec/tswap.h"
#include "hw/qdev-core.h" #include "hw/qdev-core.h"
#include "hw/irq.h" #include "hw/irq.h"
#include "qemu/accel.h" #include "qemu/accel.h"
@ -29,10 +29,6 @@
#include "qemu/module.h" #include "qemu/module.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qom/object_interfaces.h" #include "qom/object_interfaces.h"
#include CONFIG_DEVICES
#ifdef CONFIG_PSERIES
#include "hw/ppc/spapr_rtas.h"
#endif
#define MAX_IRQ 256 #define MAX_IRQ 256
@ -263,7 +259,7 @@ static int hex2nib(char ch)
} }
} }
static void qtest_send_prefix(CharBackend *chr) void qtest_send_prefix(CharBackend *chr)
{ {
if (!qtest_log_fp || !qtest_opened) { if (!qtest_log_fp || !qtest_opened) {
return; return;
@ -302,8 +298,7 @@ static void qtest_send(CharBackend *chr, const char *str)
qtest_server_send(qtest_server_send_opaque, str); qtest_server_send(qtest_server_send_opaque, str);
} }
static void G_GNUC_PRINTF(2, 3) qtest_sendf(CharBackend *chr, void qtest_sendf(CharBackend *chr, const char *fmt, ...)
const char *fmt, ...)
{ {
va_list ap; va_list ap;
gchar *buffer; gchar *buffer;
@ -361,6 +356,15 @@ static void qtest_clock_warp(int64_t dest)
qemu_clock_notify(QEMU_CLOCK_VIRTUAL); qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
} }
static bool (*process_command_cb)(CharBackend *chr, gchar **words);
void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words))
{
assert(!process_command_cb); /* Switch to a list if we need more than one */
process_command_cb = pc_cb;
}
static void qtest_process_command(CharBackend *chr, gchar **words) static void qtest_process_command(CharBackend *chr, gchar **words)
{ {
const gchar *command; const gchar *command;
@ -713,30 +717,11 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
qtest_send(chr, "OK\n"); qtest_send(chr, "OK\n");
} else if (strcmp(words[0], "endianness") == 0) { } else if (strcmp(words[0], "endianness") == 0) {
qtest_send_prefix(chr); qtest_send_prefix(chr);
#if TARGET_BIG_ENDIAN if (target_words_bigendian()) {
qtest_sendf(chr, "OK big\n"); qtest_sendf(chr, "OK big\n");
#else } else {
qtest_sendf(chr, "OK little\n"); qtest_sendf(chr, "OK little\n");
#endif }
#ifdef CONFIG_PSERIES
} else if (strcmp(words[0], "rtas") == 0) {
uint64_t res, args, ret;
unsigned long nargs, nret;
int rc;
rc = qemu_strtoul(words[2], NULL, 0, &nargs);
g_assert(rc == 0);
rc = qemu_strtou64(words[3], NULL, 0, &args);
g_assert(rc == 0);
rc = qemu_strtoul(words[4], NULL, 0, &nret);
g_assert(rc == 0);
rc = qemu_strtou64(words[5], NULL, 0, &ret);
g_assert(rc == 0);
res = qtest_rtas_call(words[1], nargs, args, nret, ret);
qtest_send_prefix(chr);
qtest_sendf(chr, "OK %"PRIu64"\n", res);
#endif
} else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) { } else if (qtest_enabled() && strcmp(words[0], "clock_step") == 0) {
int64_t ns; int64_t ns;
@ -777,6 +762,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words)
qtest_send_prefix(chr); qtest_send_prefix(chr);
qtest_sendf(chr, "OK %"PRIi64"\n", qtest_sendf(chr, "OK %"PRIi64"\n",
(int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
} else if (process_command_cb && process_command_cb(chr, words)) {
/* Command got consumed by the callback handler */
} else { } else {
qtest_send_prefix(chr); qtest_send_prefix(chr);
qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]); qtest_sendf(chr, "FAIL Unknown command '%s'\n", words[0]);
@ -867,7 +854,7 @@ void qtest_server_init(const char *qtest_chrdev, const char *qtest_log, Error **
} }
qtest = object_new(TYPE_QTEST); qtest = object_new(TYPE_QTEST);
object_property_set_str(qtest, "chardev", "qtest", &error_abort); object_property_set_str(qtest, "chardev", chr->label, &error_abort);
if (qtest_log) { if (qtest_log) {
object_property_set_str(qtest, "log", qtest_log, &error_abort); object_property_set_str(qtest, "log", qtest_log, &error_abort);
} }

View File

@ -2432,7 +2432,7 @@ static void qemu_process_help_options(void)
* to say '-cpu help -machine something'. * to say '-cpu help -machine something'.
*/ */
if (cpu_option && is_help_option(cpu_option)) { if (cpu_option && is_help_option(cpu_option)) {
list_cpus(cpu_option); list_cpus();
exit(0); exit(0);
} }

View File

@ -45,6 +45,8 @@
#include "disas/capstone.h" #include "disas/capstone.h"
#include "cpu-internal.h" #include "cpu-internal.h"
static void x86_cpu_realizefn(DeviceState *dev, Error **errp);
/* Helpers for building CPUID[2] descriptors: */ /* Helpers for building CPUID[2] descriptors: */
struct CPUID2CacheDescriptorInfo { struct CPUID2CacheDescriptorInfo {
@ -4316,6 +4318,25 @@ static Property max_x86_cpu_properties[] = {
DEFINE_PROP_END_OF_LIST() DEFINE_PROP_END_OF_LIST()
}; };
static void max_x86_cpu_realize(DeviceState *dev, Error **errp)
{
Object *obj = OBJECT(dev);
if (!object_property_get_int(obj, "family", &error_abort)) {
if (X86_CPU(obj)->env.features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
object_property_set_int(obj, "family", 15, &error_abort);
object_property_set_int(obj, "model", 107, &error_abort);
object_property_set_int(obj, "stepping", 1, &error_abort);
} else {
object_property_set_int(obj, "family", 6, &error_abort);
object_property_set_int(obj, "model", 6, &error_abort);
object_property_set_int(obj, "stepping", 3, &error_abort);
}
}
x86_cpu_realizefn(dev, errp);
}
static void max_x86_cpu_class_init(ObjectClass *oc, void *data) static void max_x86_cpu_class_init(ObjectClass *oc, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc);
@ -4327,6 +4348,7 @@ static void max_x86_cpu_class_init(ObjectClass *oc, void *data)
"Enables all features supported by the accelerator in the current host"; "Enables all features supported by the accelerator in the current host";
device_class_set_props(dc, max_x86_cpu_properties); device_class_set_props(dc, max_x86_cpu_properties);
dc->realize = max_x86_cpu_realize;
} }
static void max_x86_cpu_initfn(Object *obj) static void max_x86_cpu_initfn(Object *obj)
@ -4345,15 +4367,6 @@ static void max_x86_cpu_initfn(Object *obj)
*/ */
object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD, object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD,
&error_abort); &error_abort);
#ifdef TARGET_X86_64
object_property_set_int(OBJECT(cpu), "family", 15, &error_abort);
object_property_set_int(OBJECT(cpu), "model", 107, &error_abort);
object_property_set_int(OBJECT(cpu), "stepping", 1, &error_abort);
#else
object_property_set_int(OBJECT(cpu), "family", 6, &error_abort);
object_property_set_int(OBJECT(cpu), "model", 6, &error_abort);
object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort);
#endif
object_property_set_str(OBJECT(cpu), "model-id", object_property_set_str(OBJECT(cpu), "model-id",
"QEMU TCG CPU version " QEMU_HW_VERSION, "QEMU TCG CPU version " QEMU_HW_VERSION,
&error_abort); &error_abort);

View File

@ -200,6 +200,7 @@ qtests_arm = \
(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \ (config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed : []) + \
(config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \ (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
(config_all_devices.has_key('CONFIG_GENERIC_LOADER') ? ['hexloader-test'] : []) + \ (config_all_devices.has_key('CONFIG_GENERIC_LOADER') ? ['hexloader-test'] : []) + \
(config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
['arm-cpu-features', ['arm-cpu-features',
'microbit-test', 'microbit-test',
'test-arm-mptimer', 'test-arm-mptimer',
@ -212,6 +213,7 @@ qtests_aarch64 = \
['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \ ['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \ (config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \ (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
(config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
['arm-cpu-features', ['arm-cpu-features',
'numa-test', 'numa-test',
'boot-serial-test', 'boot-serial-test',
@ -304,6 +306,7 @@ qtests = {
'tpm-crb-test': [io, tpmemu_files], 'tpm-crb-test': [io, tpmemu_files],
'tpm-tis-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'], 'tpm-tis-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
'tpm-tis-test': [io, tpmemu_files, 'tpm-tis-util.c'], 'tpm-tis-test': [io, tpmemu_files, 'tpm-tis-util.c'],
'tpm-tis-i2c-test': [io, tpmemu_files, 'qtest_aspeed.c'],
'tpm-tis-device-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'], 'tpm-tis-device-swtpm-test': [io, tpmemu_files, 'tpm-tis-util.c'],
'tpm-tis-device-test': [io, tpmemu_files, 'tpm-tis-util.c'], 'tpm-tis-device-test': [io, tpmemu_files, 'tpm-tis-util.c'],
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'), 'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),

View File

@ -1796,6 +1796,21 @@ static void test_validate_uuid_dst_not_set(void)
do_test_validate_uuid(&args, false); do_test_validate_uuid(&args, false);
} }
/*
* The way auto_converge works, we need to do too many passes to
* run this test. Auto_converge logic is only run once every
* three iterations, so:
*
* - 3 iterations without auto_converge enabled
* - 3 iterations with pct = 5
* - 3 iterations with pct = 30
* - 3 iterations with pct = 55
* - 3 iterations with pct = 80
* - 3 iterations with pct = 95 (max(95, 80 + 25))
*
* To make things even worse, we need to run the initial stage at
* 3MB/s so we enter autoconverge even when host is (over)loaded.
*/
static void test_migrate_auto_converge(void) static void test_migrate_auto_converge(void)
{ {
g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs); g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
@ -2575,8 +2590,12 @@ int main(int argc, char **argv)
test_validate_uuid_src_not_set); test_validate_uuid_src_not_set);
qtest_add_func("/migration/validate_uuid_dst_not_set", qtest_add_func("/migration/validate_uuid_dst_not_set",
test_validate_uuid_dst_not_set); test_validate_uuid_dst_not_set);
/*
qtest_add_func("/migration/auto_converge", test_migrate_auto_converge); * See explanation why this test is slow on function definition
*/
if (g_test_slow()) {
qtest_add_func("/migration/auto_converge", test_migrate_auto_converge);
}
qtest_add_func("/migration/multifd/tcp/plain/none", qtest_add_func("/migration/multifd/tcp/plain/none",
test_multifd_tcp_none); test_multifd_tcp_none);
/* /*

117
tests/qtest/qtest_aspeed.c Normal file
View File

@ -0,0 +1,117 @@
/*
* Aspeed i2c bus interface for reading from and writing to i2c device registers
*
* Copyright (c) 2023 IBM Corporation
*
* Authors:
* Stefan Berger <stefanb@linux.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include "qtest_aspeed.h"
#include "hw/i2c/aspeed_i2c.h"
static void aspeed_i2c_startup(QTestState *s, uint32_t baseaddr,
uint8_t slave_addr, uint8_t reg)
{
uint32_t v;
static int once;
if (!once) {
/* one time: enable master */
qtest_writel(s, baseaddr + A_I2CC_FUN_CTRL, 0);
v = qtest_readl(s, baseaddr + A_I2CC_FUN_CTRL) | A_I2CD_MASTER_EN;
qtest_writel(s, baseaddr + A_I2CC_FUN_CTRL, v);
once = 1;
}
/* select device */
qtest_writel(s, baseaddr + A_I2CD_BYTE_BUF, slave_addr << 1);
qtest_writel(s, baseaddr + A_I2CD_CMD,
A_I2CD_M_START_CMD | A_I2CD_M_RX_CMD);
/* select the register to write to */
qtest_writel(s, baseaddr + A_I2CD_BYTE_BUF, reg);
qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_TX_CMD);
}
static uint32_t aspeed_i2c_read_n(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, size_t nbytes)
{
uint32_t res = 0;
uint32_t v;
size_t i;
aspeed_i2c_startup(s, baseaddr, slave_addr, reg);
for (i = 0; i < nbytes; i++) {
qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_RX_CMD);
v = qtest_readl(s, baseaddr + A_I2CD_BYTE_BUF) >> 8;
res |= (v & 0xff) << (i * 8);
}
qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_STOP_CMD);
return res;
}
uint32_t aspeed_i2c_readl(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr, uint8_t reg)
{
return aspeed_i2c_read_n(s, baseaddr, slave_addr, reg, sizeof(uint32_t));
}
uint16_t aspeed_i2c_readw(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr, uint8_t reg)
{
return aspeed_i2c_read_n(s, baseaddr, slave_addr, reg, sizeof(uint16_t));
}
uint8_t aspeed_i2c_readb(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr, uint8_t reg)
{
return aspeed_i2c_read_n(s, baseaddr, slave_addr, reg, sizeof(uint8_t));
}
static void aspeed_i2c_write_n(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint32_t v, size_t nbytes)
{
size_t i;
aspeed_i2c_startup(s, baseaddr, slave_addr, reg);
for (i = 0; i < nbytes; i++) {
qtest_writel(s, baseaddr + A_I2CD_BYTE_BUF, v & 0xff);
v >>= 8;
qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_TX_CMD);
}
qtest_writel(s, baseaddr + A_I2CD_CMD, A_I2CD_M_STOP_CMD);
}
void aspeed_i2c_writel(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint32_t v)
{
aspeed_i2c_write_n(s, baseaddr, slave_addr, reg, v, sizeof(v));
}
void aspeed_i2c_writew(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint16_t v)
{
aspeed_i2c_write_n(s, baseaddr, slave_addr, reg, v, sizeof(v));
}
void aspeed_i2c_writeb(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint8_t v)
{
aspeed_i2c_write_n(s, baseaddr, slave_addr, reg, v, sizeof(v));
}

View File

@ -0,0 +1,41 @@
/*
* Aspeed i2c bus interface to reading and writing to i2c device registers
*
* Copyright (c) 2023 IBM Corporation
*
* Authors:
* Stefan Berger <stefanb@linux.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef QTEST_ASPEED_H
#define QTEST_ASPEED_H
#include <stdint.h>
#include "libqtest.h"
#define AST2600_ASPEED_I2C_BASE_ADDR 0x1e78a000
/* Implements only AST2600 I2C controller */
static inline uint32_t ast2600_i2c_calc_bus_addr(uint8_t bus_num)
{
return AST2600_ASPEED_I2C_BASE_ADDR + 0x80 + bus_num * 0x80;
}
uint8_t aspeed_i2c_readb(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr, uint8_t reg);
uint16_t aspeed_i2c_readw(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr, uint8_t reg);
uint32_t aspeed_i2c_readl(QTestState *s,
uint32_t baseaddr, uint8_t slave_addr, uint8_t reg);
void aspeed_i2c_writeb(QTestState *s, uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint8_t v);
void aspeed_i2c_writew(QTestState *s, uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint16_t v);
void aspeed_i2c_writel(QTestState *s, uint32_t baseaddr, uint8_t slave_addr,
uint8_t reg, uint32_t v);
#endif

View File

@ -19,9 +19,6 @@
#include "tpm-tests.h" #include "tpm-tests.h"
#include "hw/acpi/tpm.h" #include "hw/acpi/tpm.h"
/* Not used but needed for linking */
uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
typedef struct TestState { typedef struct TestState {
char *src_tpm_path; char *src_tpm_path;
char *dst_tpm_path; char *dst_tpm_path;

View File

@ -19,9 +19,6 @@
#include "qemu/module.h" #include "qemu/module.h"
#include "tpm-emu.h" #include "tpm-emu.h"
/* Not used but needed for linking */
uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
#define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00" #define TPM_CMD "\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00"
static void tpm_crb_test(const void *data) static void tpm_crb_test(const void *data)

View File

@ -18,6 +18,7 @@
#include "libqtest.h" #include "libqtest.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "tpm-tests.h" #include "tpm-tests.h"
#include "tpm-tis-util.h"
#include "hw/acpi/tpm.h" #include "hw/acpi/tpm.h"
uint64_t tpm_tis_base_addr = 0xc000000; uint64_t tpm_tis_base_addr = 0xc000000;
@ -33,7 +34,7 @@ static void tpm_tis_swtpm_test(const void *data)
{ {
const TestState *ts = data; const TestState *ts = data;
tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer, tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_transfer,
"tpm-tis-device", MACHINE_OPTIONS); "tpm-tis-device", MACHINE_OPTIONS);
} }
@ -42,7 +43,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
const TestState *ts = data; const TestState *ts = data;
tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri, tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
tpm_util_tis_transfer, "tpm-tis-device", tpm_tis_transfer, "tpm-tis-device",
MACHINE_OPTIONS); MACHINE_OPTIONS);
} }

View File

@ -0,0 +1,663 @@
/*
* QTest testcases for TPM TIS on I2C (derived from TPM TIS test)
*
* Copyright (c) 2023 IBM Corporation
* Copyright (c) 2023 Red Hat, Inc.
*
* Authors:
* Stefan Berger <stefanb@linux.ibm.com>
* Marc-André Lureau <marcandre.lureau@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include <glib/gstdio.h>
#include "libqtest-single.h"
#include "hw/acpi/tpm.h"
#include "hw/pci/pci_ids.h"
#include "qtest_aspeed.h"
#include "tpm-emu.h"
#define DEBUG_TIS_TEST 0
#define DPRINTF(fmt, ...) do { \
if (DEBUG_TIS_TEST) { \
printf(fmt, ## __VA_ARGS__); \
} \
} while (0)
#define DPRINTF_ACCESS \
DPRINTF("%s: %d: locty=%d l=%d access=0x%02x pending_request_flag=0x%x\n", \
__func__, __LINE__, locty, l, access, pending_request_flag)
#define DPRINTF_STS \
DPRINTF("%s: %d: sts = 0x%08x\n", __func__, __LINE__, sts)
#define I2C_SLAVE_ADDR 0x2e
#define I2C_DEV_BUS_NUM 10
static const uint8_t TPM_CMD[12] =
"\x80\x01\x00\x00\x00\x0c\x00\x00\x01\x44\x00\x00";
static uint32_t aspeed_bus_addr;
static uint8_t cur_locty = 0xff;
static void tpm_tis_i2c_set_locty(uint8_t locty)
{
if (cur_locty != locty) {
cur_locty = locty;
aspeed_i2c_writeb(global_qtest, aspeed_bus_addr, I2C_SLAVE_ADDR,
TPM_I2C_REG_LOC_SEL, locty);
}
}
static uint8_t tpm_tis_i2c_readb(uint8_t locty, uint8_t reg)
{
tpm_tis_i2c_set_locty(locty);
return aspeed_i2c_readb(global_qtest, aspeed_bus_addr, I2C_SLAVE_ADDR, reg);
}
static uint16_t tpm_tis_i2c_readw(uint8_t locty, uint8_t reg)
{
tpm_tis_i2c_set_locty(locty);
return aspeed_i2c_readw(global_qtest, aspeed_bus_addr, I2C_SLAVE_ADDR, reg);
}
static uint32_t tpm_tis_i2c_readl(uint8_t locty, uint8_t reg)
{
tpm_tis_i2c_set_locty(locty);
return aspeed_i2c_readl(global_qtest, aspeed_bus_addr, I2C_SLAVE_ADDR, reg);
}
static void tpm_tis_i2c_writeb(uint8_t locty, uint8_t reg, uint8_t v)
{
if (reg != TPM_I2C_REG_LOC_SEL) {
tpm_tis_i2c_set_locty(locty);
}
aspeed_i2c_writeb(global_qtest, aspeed_bus_addr, I2C_SLAVE_ADDR, reg, v);
}
static void tpm_tis_i2c_writel(uint8_t locty, uint8_t reg, uint32_t v)
{
if (reg != TPM_I2C_REG_LOC_SEL) {
tpm_tis_i2c_set_locty(locty);
}
aspeed_i2c_writel(global_qtest, aspeed_bus_addr, I2C_SLAVE_ADDR, reg, v);
}
static void tpm_tis_i2c_test_basic(const void *data)
{
uint8_t access;
uint32_t v, v2;
/*
* All register accesses below must work without locality 0 being the
* active locality. Therefore, ensure access is released.
*/
tpm_tis_i2c_writeb(0, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = tpm_tis_i2c_readb(0, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* read interrupt capability -- none are supported */
v = tpm_tis_i2c_readl(0, TPM_I2C_REG_INT_CAPABILITY);
g_assert_cmpint(v, ==, 0);
/* try to enable all interrupts */
tpm_tis_i2c_writel(0, TPM_I2C_REG_INT_ENABLE, 0xffffffff);
v = tpm_tis_i2c_readl(0, TPM_I2C_REG_INT_ENABLE);
/* none could be enabled */
g_assert_cmpint(v, ==, 0);
/* enable csum */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_DATA_CSUM_ENABLE, TPM_DATA_CSUM_ENABLED);
/* check csum enable register has bit 0 set */
v = tpm_tis_i2c_readb(0, TPM_I2C_REG_DATA_CSUM_ENABLE);
g_assert_cmpint(v, ==, TPM_DATA_CSUM_ENABLED);
/* reading it as 32bit register returns same result */
v = tpm_tis_i2c_readl(0, TPM_I2C_REG_DATA_CSUM_ENABLE);
g_assert_cmpint(v, ==, TPM_DATA_CSUM_ENABLED);
/* disable csum */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_DATA_CSUM_ENABLE, 0);
/* check csum enable register has bit 0 clear */
v = tpm_tis_i2c_readb(0, TPM_I2C_REG_DATA_CSUM_ENABLE);
g_assert_cmpint(v, ==, 0);
/* write to unsupported register '1' */
tpm_tis_i2c_writel(0, 1, 0x12345678);
v = tpm_tis_i2c_readl(0, 1);
g_assert_cmpint(v, ==, 0xffffffff);
/* request use of locality */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_REQUEST_USE);
/* read byte from STS + 3 */
v = tpm_tis_i2c_readb(0, TPM_I2C_REG_STS + 3);
g_assert_cmpint(v, ==, 0);
/* check STS after writing to STS + 3 */
v = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
tpm_tis_i2c_writeb(0, TPM_I2C_REG_STS + 3, 0xf);
v2 = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
g_assert_cmpint(v, ==, v2);
/* release access */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
/* select locality 5 -- must not be possible */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_LOC_SEL, 5);
v = tpm_tis_i2c_readb(0, TPM_I2C_REG_LOC_SEL);
g_assert_cmpint(v, ==, 0);
}
static void tpm_tis_i2c_test_check_localities(const void *data)
{
uint8_t locty, l;
uint8_t access;
uint32_t capability, i2c_cap;
uint32_t didvid;
uint32_t rid;
for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
capability = tpm_tis_i2c_readl(locty, TPM_I2C_REG_INTF_CAPABILITY);
i2c_cap = (TPM_I2C_CAP_INTERFACE_TYPE |
TPM_I2C_CAP_INTERFACE_VER |
TPM_I2C_CAP_TPM2_FAMILY |
TPM_I2C_CAP_LOCALITY_CAP |
TPM_I2C_CAP_BUS_SPEED |
TPM_I2C_CAP_DEV_ADDR_CHANGE);
g_assert_cmpint(capability, ==, i2c_cap);
didvid = tpm_tis_i2c_readl(locty, TPM_I2C_REG_DID_VID);
g_assert_cmpint(didvid, ==, (1 << 16) | PCI_VENDOR_ID_IBM);
rid = tpm_tis_i2c_readl(locty, TPM_I2C_REG_RID);
g_assert_cmpint(rid, !=, 0);
g_assert_cmpint(rid, !=, 0xffffffff);
/* locality selection must be at locty */
l = tpm_tis_i2c_readb(locty, TPM_I2C_REG_LOC_SEL);
g_assert_cmpint(l, ==, locty);
}
}
static void tpm_tis_i2c_test_check_access_reg(const void *data)
{
uint8_t locty;
uint8_t access;
/* do not test locality 4 (hw only) */
for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES - 1; locty++) {
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* request use of locality */
tpm_tis_i2c_writeb(locty, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_REQUEST_USE);
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* release access */
tpm_tis_i2c_writeb(locty, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
}
}
/*
* Test case for seizing access by a higher number locality
*/
static void tpm_tis_i2c_test_check_access_reg_seize(const void *data)
{
int locty, l;
uint8_t access;
uint8_t pending_request_flag;
/* do not test locality 4 (hw only) */
for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES - 1; locty++) {
pending_request_flag = 0;
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* request use of locality */
tpm_tis_i2c_writeb(locty,
TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_REQUEST_USE);
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* lower localities cannot seize access */
for (l = 0; l < locty; l++) {
/* lower locality is not active */
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* try to request use from 'l' */
tpm_tis_i2c_writeb(l,
TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_REQUEST_USE);
/*
* requesting use from 'l' was not possible;
* we must see REQUEST_USE and possibly PENDING_REQUEST
*/
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_REQUEST_USE |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/*
* locality 'locty' must be unchanged;
* we must see PENDING_REQUEST
*/
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_PENDING_REQUEST |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* try to seize from 'l' */
tpm_tis_i2c_writeb(l,
TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_SEIZE);
/* seize from 'l' was not possible */
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_REQUEST_USE |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* locality 'locty' must be unchanged */
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_PENDING_REQUEST |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/*
* on the next loop we will have a PENDING_REQUEST flag
* set for locality 'l'
*/
pending_request_flag = TPM_TIS_ACCESS_PENDING_REQUEST;
}
/*
* higher localities can 'seize' access but not 'request use';
* note: this will activate first l+1, then l+2 etc.
*/
for (l = locty + 1; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
/* try to 'request use' from 'l' */
tpm_tis_i2c_writeb(l, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_REQUEST_USE);
/*
* requesting use from 'l' was not possible; we should see
* REQUEST_USE and may see PENDING_REQUEST
*/
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_REQUEST_USE |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/*
* locality 'l-1' must be unchanged; we should always
* see PENDING_REQUEST from 'l' requesting access
*/
access = tpm_tis_i2c_readb(l - 1, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_PENDING_REQUEST |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* try to seize from 'l' */
tpm_tis_i2c_writeb(l, TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_SEIZE);
/* seize from 'l' was possible */
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* l - 1 should show that it has BEEN_SEIZED */
access = tpm_tis_i2c_readb(l - 1, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_BEEN_SEIZED |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* clear the BEEN_SEIZED flag and make sure it's gone */
tpm_tis_i2c_writeb(l - 1, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_BEEN_SEIZED);
access = tpm_tis_i2c_readb(l - 1, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
}
/*
* PENDING_REQUEST will not be set if locty = 0 since all localities
* were active; in case of locty = 1, locality 0 will be active
* but no PENDING_REQUEST anywhere
*/
if (locty <= 1) {
pending_request_flag = 0;
}
/* release access from l - 1; this activates locty - 1 */
l--;
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
DPRINTF("%s: %d: relinquishing control on l = %d\n",
__func__, __LINE__, l);
tpm_tis_i2c_writeb(l, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
for (l = locty - 1; l >= 0; l--) {
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* release this locality */
tpm_tis_i2c_writeb(l, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
if (l == 1) {
pending_request_flag = 0;
}
}
/* no locality may be active now */
for (l = 0; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
}
}
}
/*
* Test case for getting access when higher number locality relinquishes access
*/
static void tpm_tis_i2c_test_check_access_reg_release(const void *data)
{
int locty, l;
uint8_t access;
uint8_t pending_request_flag;
/* do not test locality 4 (hw only) */
for (locty = TPM_TIS_NUM_LOCALITIES - 2; locty >= 0; locty--) {
pending_request_flag = 0;
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* request use of locality */
tpm_tis_i2c_writeb(locty, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_REQUEST_USE);
access = tpm_tis_i2c_readb(locty, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* request use of all other localities */
for (l = 0; l < TPM_TIS_NUM_LOCALITIES - 1; l++) {
if (l == locty) {
continue;
}
/*
* request use of locality 'l' -- we MUST see REQUEST USE and
* may see PENDING_REQUEST
*/
tpm_tis_i2c_writeb(l, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_REQUEST_USE);
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_REQUEST_USE |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
pending_request_flag = TPM_TIS_ACCESS_PENDING_REQUEST;
}
/* release locality 'locty' */
tpm_tis_i2c_writeb(locty, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
/*
* highest locality should now be active; release it and make sure the
* next higest locality is active afterwards
*/
for (l = TPM_TIS_NUM_LOCALITIES - 2; l >= 0; l--) {
if (l == locty) {
continue;
}
/* 'l' should be active now */
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
/* 'l' relinquishes access */
tpm_tis_i2c_writeb(l, TPM_I2C_REG_ACCESS,
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = tpm_tis_i2c_readb(l, TPM_I2C_REG_ACCESS);
DPRINTF_ACCESS;
if (l == 1 || (locty <= 1 && l == 2)) {
pending_request_flag = 0;
}
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
pending_request_flag |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
}
}
}
/*
* Test case for transmitting packets
*/
static void tpm_tis_i2c_test_check_transmit(const void *data)
{
const TPMTestState *s = data;
uint8_t access;
uint32_t sts, v;
uint16_t bcount, csum, bcount2;
size_t i;
/* enable csum */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_DATA_CSUM_ENABLE, TPM_DATA_CSUM_ENABLED);
/* check csum enable register has bit 0 set */
v = tpm_tis_i2c_readb(0, TPM_I2C_REG_DATA_CSUM_ENABLE);
g_assert_cmpint(v, ==, TPM_DATA_CSUM_ENABLED);
/* reading it as 32bit register returns same result */
v = tpm_tis_i2c_readl(0, TPM_I2C_REG_DATA_CSUM_ENABLE);
g_assert_cmpint(v, ==, TPM_DATA_CSUM_ENABLED);
/* request use of locality 0 */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_REQUEST_USE);
access = tpm_tis_i2c_readb(0, TPM_I2C_REG_ACCESS);
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_ACTIVE_LOCALITY |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
sts = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
DPRINTF_STS;
g_assert_cmpint(sts & 0xff, ==, 0);
bcount = (sts >> 8) & 0xffff;
g_assert_cmpint(bcount, >=, 128);
/* read bcount from STS + 1 must work also */
bcount2 = tpm_tis_i2c_readw(0, TPM_I2C_REG_STS + 1);
g_assert_cmpint(bcount, ==, bcount2);
/* ic2 must have bits 26-31 zero */
g_assert_cmpint(sts & (0x1f << 26), ==, 0);
tpm_tis_i2c_writel(0, TPM_I2C_REG_STS, TPM_TIS_STS_COMMAND_READY);
sts = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
DPRINTF_STS;
g_assert_cmpint(sts & 0xff, ==, TPM_TIS_STS_COMMAND_READY);
/* transmit command */
for (i = 0; i < sizeof(TPM_CMD); i++) {
tpm_tis_i2c_writeb(0, TPM_I2C_REG_DATA_FIFO, TPM_CMD[i]);
sts = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
DPRINTF_STS;
if (i < sizeof(TPM_CMD) - 1) {
g_assert_cmpint(sts & 0xff, ==,
TPM_TIS_STS_EXPECT | TPM_TIS_STS_VALID);
} else {
g_assert_cmpint(sts & 0xff, ==, TPM_TIS_STS_VALID);
}
g_assert_cmpint((sts >> 8) & 0xffff, ==, --bcount);
}
/* read the checksum */
csum = tpm_tis_i2c_readw(0, TPM_I2C_REG_DATA_CSUM_GET);
g_assert_cmpint(csum, ==, 0x6733);
/* start processing */
tpm_tis_i2c_writeb(0, TPM_I2C_REG_STS, TPM_TIS_STS_TPM_GO);
uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
do {
sts = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
break;
}
} while (g_get_monotonic_time() < end_time);
sts = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
DPRINTF_STS;
g_assert_cmpint(sts & 0xff, == ,
TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE);
bcount = (sts >> 8) & 0xffff;
/* read response */
uint8_t tpm_msg[sizeof(struct tpm_hdr)];
g_assert_cmpint(sizeof(tpm_msg), ==, bcount);
for (i = 0; i < sizeof(tpm_msg); i++) {
tpm_msg[i] = tpm_tis_i2c_readb(0, TPM_I2C_REG_DATA_FIFO);
sts = tpm_tis_i2c_readl(0, TPM_I2C_REG_STS);
DPRINTF_STS;
if (sts & TPM_TIS_STS_DATA_AVAILABLE) {
g_assert_cmpint((sts >> 8) & 0xffff, ==, --bcount);
}
}
g_assert_cmpmem(tpm_msg, sizeof(tpm_msg), s->tpm_msg, sizeof(*s->tpm_msg));
/* relinquish use of locality 0 */
tpm_tis_i2c_writeb(0,
TPM_I2C_REG_ACCESS, TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = tpm_tis_i2c_readb(0, TPM_I2C_REG_ACCESS);
}
int main(int argc, char **argv)
{
int ret;
char *args;
char *tmp_path = g_dir_make_tmp("qemu-tpm-tis-i2c-test.XXXXXX", NULL);
GThread *thread;
TPMTestState test;
module_call_init(MODULE_INIT_QOM);
g_test_init(&argc, &argv, NULL);
test.addr = g_new0(SocketAddress, 1);
test.addr->type = SOCKET_ADDRESS_TYPE_UNIX;
test.addr->u.q_unix.path = g_build_filename(tmp_path, "sock", NULL);
g_mutex_init(&test.data_mutex);
g_cond_init(&test.data_cond);
test.data_cond_signal = false;
test.tpm_version = TPM_VERSION_2_0;
thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test);
tpm_emu_test_wait_cond(&test);
aspeed_bus_addr = ast2600_i2c_calc_bus_addr(I2C_DEV_BUS_NUM);
args = g_strdup_printf(
"-machine rainier-bmc -accel tcg "
"-chardev socket,id=chr,path=%s "
"-tpmdev emulator,id=tpm0,chardev=chr "
"-device tpm-tis-i2c,tpmdev=tpm0,bus=aspeed.i2c.bus.%d,address=0x%x",
test.addr->u.q_unix.path,
I2C_DEV_BUS_NUM,
I2C_SLAVE_ADDR);
qtest_start(args);
qtest_add_data_func("/tpm-tis-i2c/test_basic", &test,
tpm_tis_i2c_test_basic);
qtest_add_data_func("/tpm-tis-i2c/test_check_localities", &test,
tpm_tis_i2c_test_check_localities);
qtest_add_data_func("/tpm-tis-i2c/check_access_reg", &test,
tpm_tis_i2c_test_check_access_reg);
qtest_add_data_func("/tpm-tis-i2c/check_access_reg_seize", &test,
tpm_tis_i2c_test_check_access_reg_seize);
qtest_add_data_func("/tpm-tis-i2c/check_access_reg_release", &test,
tpm_tis_i2c_test_check_access_reg_release);
qtest_add_data_func("/tpm-tis-i2c/test_check_transmit", &test,
tpm_tis_i2c_test_check_transmit);
ret = g_test_run();
qtest_end();
g_thread_join(thread);
g_unlink(test.addr->u.q_unix.path);
qapi_free_SocketAddress(test.addr);
g_rmdir(tmp_path);
g_free(tmp_path);
g_free(args);
return ret;
}

View File

@ -17,6 +17,7 @@
#include "libqtest.h" #include "libqtest.h"
#include "qemu/module.h" #include "qemu/module.h"
#include "tpm-tests.h" #include "tpm-tests.h"
#include "tpm-tis-util.h"
#include "hw/acpi/tpm.h" #include "hw/acpi/tpm.h"
uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE; uint64_t tpm_tis_base_addr = TPM_TIS_ADDR_BASE;
@ -31,7 +32,7 @@ static void tpm_tis_swtpm_test(const void *data)
{ {
const TestState *ts = data; const TestState *ts = data;
tpm_test_swtpm_test(ts->src_tpm_path, tpm_util_tis_transfer, tpm_test_swtpm_test(ts->src_tpm_path, tpm_tis_transfer,
"tpm-tis", NULL); "tpm-tis", NULL);
} }
@ -40,7 +41,7 @@ static void tpm_tis_swtpm_migration_test(const void *data)
const TestState *ts = data; const TestState *ts = data;
tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri, tpm_test_swtpm_migration_test(ts->src_tpm_path, ts->dst_tpm_path, ts->uri,
tpm_util_tis_transfer, "tpm-tis", NULL); tpm_tis_transfer, "tpm-tis", NULL);
} }
int main(int argc, char **argv) int main(int argc, char **argv)

View File

@ -52,7 +52,7 @@ void tpm_tis_test_check_localities(const void *data)
uint32_t rid; uint32_t rid;
for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) { for (locty = 0; locty < TPM_TIS_NUM_LOCALITIES; locty++) {
access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS)); access = readb(TIS_REG(locty, TPM_TIS_REG_ACCESS));
g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS | g_assert_cmpint(access, ==, TPM_TIS_ACCESS_TPM_REG_VALID_STS |
TPM_TIS_ACCESS_TPM_ESTABLISHMENT); TPM_TIS_ACCESS_TPM_ESTABLISHMENT);
@ -449,3 +449,48 @@ void tpm_tis_test_check_transmit(const void *data)
writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_ACTIVE_LOCALITY); writeb(TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_ACTIVE_LOCALITY);
access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS)); access = readb(TIS_REG(0, TPM_TIS_REG_ACCESS));
} }
void tpm_tis_transfer(QTestState *s,
const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size)
{
uint32_t sts;
uint16_t bcount;
size_t i;
/* request use of locality 0 */
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
qtest_writel(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
bcount = (sts >> 8) & 0xffff;
g_assert_cmpint(bcount, >=, req_size);
/* transmit command */
for (i = 0; i < req_size; i++) {
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO), req[i]);
}
/* start processing */
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
do {
sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
break;
}
} while (g_get_monotonic_time() < end_time);
sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
bcount = (sts >> 8) & 0xffff;
memset(rsp, 0, rsp_size);
for (i = 0; i < bcount; i++) {
rsp[i] = qtest_readb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
}
/* relinquish use of locality 0 */
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS),
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
}

View File

@ -20,4 +20,8 @@ void tpm_tis_test_check_access_reg_seize(const void *data);
void tpm_tis_test_check_access_reg_release(const void *data); void tpm_tis_test_check_access_reg_release(const void *data);
void tpm_tis_test_check_transmit(const void *data); void tpm_tis_test_check_transmit(const void *data);
void tpm_tis_transfer(QTestState *s,
const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size);
#endif /* TESTS_TPM_TIS_UTIL_H */ #endif /* TESTS_TPM_TIS_UTIL_H */

View File

@ -51,51 +51,6 @@ void tpm_util_crb_transfer(QTestState *s,
qtest_memread(s, raddr, rsp, rsp_size); qtest_memread(s, raddr, rsp, rsp_size);
} }
void tpm_util_tis_transfer(QTestState *s,
const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size)
{
uint32_t sts;
uint16_t bcount;
size_t i;
/* request use of locality 0 */
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS), TPM_TIS_ACCESS_REQUEST_USE);
qtest_writel(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_COMMAND_READY);
sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
bcount = (sts >> 8) & 0xffff;
g_assert_cmpint(bcount, >=, req_size);
/* transmit command */
for (i = 0; i < req_size; i++) {
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO), req[i]);
}
/* start processing */
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_STS), TPM_TIS_STS_TPM_GO);
uint64_t end_time = g_get_monotonic_time() + 50 * G_TIME_SPAN_SECOND;
do {
sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
if ((sts & TPM_TIS_STS_DATA_AVAILABLE) != 0) {
break;
}
} while (g_get_monotonic_time() < end_time);
sts = qtest_readl(s, TIS_REG(0, TPM_TIS_REG_STS));
bcount = (sts >> 8) & 0xffff;
memset(rsp, 0, rsp_size);
for (i = 0; i < bcount; i++) {
rsp[i] = qtest_readb(s, TIS_REG(0, TPM_TIS_REG_DATA_FIFO));
}
/* relinquish use of locality 0 */
qtest_writeb(s, TIS_REG(0, TPM_TIS_REG_ACCESS),
TPM_TIS_ACCESS_ACTIVE_LOCALITY);
}
void tpm_util_startup(QTestState *s, tx_func *tx) void tpm_util_startup(QTestState *s, tx_func *tx)
{ {
unsigned char buffer[1024]; unsigned char buffer[1024];

View File

@ -27,9 +27,6 @@ typedef void (tx_func)(QTestState *s,
void tpm_util_crb_transfer(QTestState *s, void tpm_util_crb_transfer(QTestState *s,
const unsigned char *req, size_t req_size, const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size); unsigned char *rsp, size_t rsp_size);
void tpm_util_tis_transfer(QTestState *s,
const unsigned char *req, size_t req_size,
unsigned char *rsp, size_t rsp_size);
void tpm_util_startup(QTestState *s, tx_func *tx); void tpm_util_startup(QTestState *s, tx_func *tx);
void tpm_util_pcrextend(QTestState *s, tx_func *tx); void tpm_util_pcrextend(QTestState *s, tx_func *tx);

View File

@ -24,7 +24,7 @@
#include "crypto/secret.h" #include "crypto/secret.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/module.h" #include "qemu/module.h"
#ifdef CONFIG_KEYUTILS #if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING)
#include "crypto/secret_keyring.h" #include "crypto/secret_keyring.h"
#include <keyutils.h> #include <keyutils.h>
#endif #endif
@ -128,7 +128,7 @@ static void test_secret_indirect_emptyfile(void)
g_free(fname); g_free(fname);
} }
#ifdef CONFIG_KEYUTILS #if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING)
#define DESCRIPTION "qemu_test_secret" #define DESCRIPTION "qemu_test_secret"
#define PAYLOAD "Test Payload" #define PAYLOAD "Test Payload"
@ -268,7 +268,7 @@ static void test_secret_keyring_bad_key_access_right(void)
keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING); keyctl_unlink(key, KEY_SPEC_PROCESS_KEYRING);
} }
#endif /* CONFIG_KEYUTILS */ #endif /* CONFIG_KEYUTILS && CONFIG_SECRET_KEYRING */
static void test_secret_noconv_base64_good(void) static void test_secret_noconv_base64_good(void)
{ {
@ -571,7 +571,7 @@ int main(int argc, char **argv)
g_test_add_func("/crypto/secret/indirect/emptyfile", g_test_add_func("/crypto/secret/indirect/emptyfile",
test_secret_indirect_emptyfile); test_secret_indirect_emptyfile);
#ifdef CONFIG_KEYUTILS #if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING)
g_test_add_func("/crypto/secret/keyring/good", g_test_add_func("/crypto/secret/keyring/good",
test_secret_keyring_good); test_secret_keyring_good);
g_test_add_func("/crypto/secret/keyring/revoked_key", g_test_add_func("/crypto/secret/keyring/revoked_key",
@ -582,7 +582,7 @@ int main(int argc, char **argv)
test_secret_keyring_bad_serial_key); test_secret_keyring_bad_serial_key);
g_test_add_func("/crypto/secret/keyring/bad_key_access_right", g_test_add_func("/crypto/secret/keyring/bad_key_access_right",
test_secret_keyring_bad_key_access_right); test_secret_keyring_bad_key_access_right);
#endif /* CONFIG_KEYUTILS */ #endif /* CONFIG_KEYUTILS && CONFIG_SECRET_KEYRING */
g_test_add_func("/crypto/secret/noconv/base64/good", g_test_add_func("/crypto/secret/noconv/base64/good",
test_secret_noconv_base64_good); test_secret_noconv_base64_good);

View File

@ -28,15 +28,15 @@ class FreeBSDVM(basevm.BaseVM):
name = "freebsd" name = "freebsd"
arch = "x86_64" arch = "x86_64"
link = "https://download.freebsd.org/ftp/releases/ISO-IMAGES/12.4/FreeBSD-12.4-RELEASE-amd64-disc1.iso.xz" link = "https://download.freebsd.org/releases/CI-IMAGES/13.2-RELEASE/amd64/Latest/FreeBSD-13.2-RELEASE-amd64-BASIC-CI.raw.xz"
csum = "1dcf6446e31bf3f81b582e9aba3319a258c29a937a2af6138ee4b181ed719a87" csum = "a4fb3b6c7b75dd4d58fb0d75e4caf72844bffe0ca00e66459c028b198ffb3c0e"
size = "20G" size = "20G"
pkgs = [ pkgs = [
# build tools # build tools
"git", "git",
"pkgconf", "pkgconf",
"bzip2", "bzip2",
"python37", "python39",
"ninja", "ninja",
# gnu tools # gnu tools
@ -78,72 +78,42 @@ class FreeBSDVM(basevm.BaseVM):
mkdir src build; cd src; mkdir src build; cd src;
tar -xf /dev/vtbd1; tar -xf /dev/vtbd1;
cd ../build cd ../build
../src/configure --python=python3.7 {configure_opts}; ../src/configure --python=python3.9 {configure_opts};
gmake --output-sync -j{jobs} {target} {verbose}; gmake --output-sync -j{jobs} {target} {verbose};
""" """
def console_boot_serial(self):
self.console_wait_send("Autoboot", "3")
self.console_wait_send("OK", "set console=comconsole\n")
self.console_wait_send("OK", "boot\n")
def build_image(self, img): def build_image(self, img):
self.print_step("Downloading install iso") self.print_step("Downloading disk image")
cimg = self._download_with_cache(self.link, sha256sum=self.csum) cimg = self._download_with_cache(self.link, sha256sum=self.csum)
img_tmp = img + ".tmp" tmp_raw = img + ".tmp.raw"
iso = img + ".install.iso" tmp_raw_xz = tmp_raw + ".xz"
iso_xz = iso + ".xz" img_tmp = img + ".tmp.qcow2"
self.print_step("Preparing iso and disk image") self.print_step("Preparing disk image")
subprocess.check_call(["cp", "-f", cimg, iso_xz]) subprocess.check_call(["cp", "-f", cimg, tmp_raw_xz])
subprocess.check_call(["xz", "-dvf", iso_xz]) subprocess.check_call(["xz", "-dvf", tmp_raw_xz])
self.exec_qemu_img("create", "-f", "qcow2", img_tmp, self.size) self.exec_qemu_img("convert", "-O", "qcow2", tmp_raw, img_tmp)
self.exec_qemu_img("resize", img_tmp, self.size)
os.remove(tmp_raw)
self.print_step("Booting installer") self.print_step("Preparing disk image")
self.boot(img_tmp, extra_args = [ self.boot(img_tmp, extra_args = [
"-machine", "graphics=off", "-machine", "graphics=off",
"-device", "VGA", "-vga", "none"
"-cdrom", iso
]) ])
self.console_init() self.console_init()
self.console_boot_serial() self.console_wait_send("login:", "root\n")
self.console_wait_send("Console type", "xterm\n") self.console_wait_send("~ #", "service growfs onestart\n")
# pre-install configuration # root user
self.console_wait_send("Welcome", "\n") self.console_wait_send("~ #", "passwd\n")
self.console_wait_send("Keymap Selection", "\n")
self.console_wait_send("Set Hostname", "freebsd\n")
self.console_wait_send("Distribution Select", "\n")
self.console_wait_send("Partitioning", "\n")
self.console_wait_send("Partition", "\n")
self.console_wait_send("Scheme", "\n")
self.console_wait_send("Editor", "f")
self.console_wait_send("Confirmation", "c")
self.print_step("Installation started now, this will take a while")
# post-install configuration
self.console_wait("New Password:") self.console_wait("New Password:")
self.console_send("%s\n" % self._config["root_pass"]) self.console_send("%s\n" % self._config["root_pass"])
self.console_wait("Retype New Password:") self.console_wait("Retype New Password:")
self.console_send("%s\n" % self._config["root_pass"]) self.console_send("%s\n" % self._config["root_pass"])
self.console_wait_send("Network Configuration", "\n")
self.console_wait_send("IPv4", "y")
self.console_wait_send("DHCP", "y")
self.console_wait_send("IPv6", "n")
self.console_wait_send("Resolver", "\n")
self.console_wait_send("Time Zone Selector", "0\n")
self.console_wait_send("Confirmation", "y")
self.console_wait_send("Time & Date", "\n")
self.console_wait_send("Time & Date", "\n")
self.console_wait_send("System Configuration", "\n")
self.console_wait_send("System Hardening", "\n")
# qemu user # qemu user
self.console_wait_send("Add User Accounts", "y") self.console_wait_send("~ #", "adduser\n")
self.console_wait("Username") self.console_wait("Username")
self.console_send("%s\n" % self._config["guest_user"]) self.console_send("%s\n" % self._config["guest_user"])
self.console_wait("Full name") self.console_wait("Full name")
@ -165,13 +135,7 @@ class FreeBSDVM(basevm.BaseVM):
self.console_wait_send("Lock out", "\n") self.console_wait_send("Lock out", "\n")
self.console_wait_send("OK", "yes\n") self.console_wait_send("OK", "yes\n")
self.console_wait_send("Add another user", "no\n") self.console_wait_send("Add another user", "no\n")
self.console_wait_send("~ #", "exit\n")
self.console_wait_send("Final Configuration", "\n")
self.console_wait_send("Manual Configuration", "\n")
self.console_wait_send("Complete", "\n")
self.print_step("Installation finished, rebooting")
self.console_boot_serial()
# setup qemu user # setup qemu user
prompt = "$" prompt = "$"
@ -183,35 +147,20 @@ class FreeBSDVM(basevm.BaseVM):
self.console_ssh_init(prompt, "root", self._config["root_pass"]) self.console_ssh_init(prompt, "root", self._config["root_pass"])
self.console_sshd_config(prompt) self.console_sshd_config(prompt)
# setup serial console
self.console_wait(prompt)
self.console_send("echo 'console=comconsole' >> /boot/loader.conf\n")
# setup boot delay
self.console_wait(prompt)
self.console_send("echo 'autoboot_delay=1' >> /boot/loader.conf\n")
# setup virtio-blk #1 (tarfile) # setup virtio-blk #1 (tarfile)
self.console_wait(prompt) self.console_wait(prompt)
self.console_send("echo 'chmod 666 /dev/vtbd1' >> /etc/rc.local\n") self.console_send("echo 'chmod 666 /dev/vtbd1' >> /etc/rc.local\n")
self.print_step("Configuration finished, rebooting")
self.console_wait_send(prompt, "reboot\n")
self.console_wait("login:")
self.wait_ssh()
self.print_step("Installing packages") self.print_step("Installing packages")
self.ssh_root_check("pkg install -y %s\n" % " ".join(self.pkgs)) self.ssh_root_check("pkg install -y %s\n" % " ".join(self.pkgs))
# shutdown # shutdown
self.ssh_root(self.poweroff) self.ssh_root(self.poweroff)
self.console_wait("Uptime:")
self.wait() self.wait()
if os.path.exists(img): if os.path.exists(img):
os.remove(img) os.remove(img)
os.rename(img_tmp, img) os.rename(img_tmp, img)
os.remove(iso)
self.print_step("All done") self.print_step("All done")
if __name__ == "__main__": if __name__ == "__main__":