Merge tag 'hw-misc-20241214' of https://github.com/philmd/qemu into staging

Misc HW patch queue

- Support string data for extendPCR in VirtIO NSM device (Dorjoy)
- Have PCI_BUS implement TYPE_FW_CFG_DATA_GENERATOR_INTERFACE (Phil)
- Decouple AHCI from PCI (Bernhard)
- Add status to usb_msd_packet_complete (Nick)
- Header cleanups (Alex, Phil)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmdcwx4ACgkQ4+MsLN6t
# wN52NRAAlFWIbtUMNt37pqUCmbf9f/rpYAfvKvMQ1h1u73VfOPdFpE9TEySj8+rm
# PM/kqsjRuTxrWreEon8SBqnKmXKSLOQ2CbB3TjCy2hlfa6vs5UtTdmzN4l1cagG5
# MtOOjh0yKUAel5DhI3NxA94HJf2dHSSY9dT+6+82eYnVNCBWvTuQp/xDq1TxsW4/
# KAD+ZFDCrUVSGqkU3ZcyHmHxuuFjo8pCfFGsCf9kHAjCxtj5M0GFjMIOcT4WAAnW
# PvAM1q84ceBx5LiObEYWu+NB95Xy3YvAjCMFNRIhS64C0SR6o+HhKo9TSprMmpW6
# ncDnNmg85SbUc5yhojvkg25D63uh5NROh9J3gqoibX+Jc1poZN/Xjt98EzqmrLiv
# cYyzs4FO5r1sdVBGrRi7iRhFui61chfTJrPbNYePRABGUgxXBjPNwTUm0OwHLdi9
# X9ehbYlYlxHqV0WGq1j47uMB5/SuyeXzYDO4im6fpk7RrpliNysa5zB1vBuDUNpR
# Bu5ypprg80km20SjFieC5R0LIT+A38H2ir2qo9buJ+wd2X/n/nqxK4Ucl1s8PLBF
# 76WPLIMOV71bshlEEh6KVn+U978BsY4yPr0dZ+javNvGRzZx8ioPK+2OCT+XN39N
# oeCcTnC+9YTyYeWJqmY3Hd/kqM+32Jl7FdEEoE0EADz3fSPcvQs=
# =cxm9
# -----END PGP SIGNATURE-----
# gpg: Signature made Fri 13 Dec 2024 18:28:30 EST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown]
# 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: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'hw-misc-20241214' of https://github.com/philmd/qemu:
  hw/xtensa: Include missing 'exec/tswap.h' header
  hw/sh4/r2d: Include missing 'exec/tswap.h' header
  hw/mips: Include missing 'exec/tswap.h' header
  hw/ide/ahci: Extract TYPE_SYSBUS_AHCI into dedicated file
  hw/ide/ahci: Decouple from PCI
  hw/usb/hcd-xhci-pci: Indentation fix
  hw/usb/hcd-xhci-nec: Remove unused XHCINecState::flags field
  hw/usb/msd: Add status to usb_msd_packet_complete() function
  hw/net/can: clean-up unnecessary includes
  hw/nvram/fw_cfg: Remove fw_cfg_add_extra_pci_roots()
  hw: Use pci_bus_add_fw_cfg_extra_pci_roots()
  hw/pci: Add pci_bus_add_fw_cfg_extra_pci_roots() helper
  hw/pci: Have PCI_BUS implement TYPE_FW_CFG_DATA_GENERATOR_INTERFACE
  hw/nvram/fw_cfg: Skip FW_CFG_DATA_GENERATOR when no data to generate
  hw/nvram/fw_cfg: Pass QOM parent to fw_cfg_add_file_from_generator()
  hw/nvram/fw_cfg: Rename fw_cfg_add_[file]_from_generator()
  hw/riscv/virt: Remove pointless GPEX_HOST() cast
  hw/virtio/virtio-nsm: Support string data for extendPCR
  hw/core/eif: Use stateful qcrypto apis
  docs/nitro-enclave: Fix terminal commands formatting

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2024-12-14 08:42:53 -05:00
37 changed files with 343 additions and 358 deletions
+4 -4
View File
@@ -48,13 +48,13 @@ Running a nitro-enclave VM
First, run `vhost-device-vsock`__ (or a similar tool that supports vhost-user-vsock).
The forward-cid option below with value 1 forwards all connections from the enclave
VM to the host machine and the forward-listen (port numbers separated by '+') is used
for forwarding connections from the host machine to the enclave VM.
__ https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock#using-the-vsock-backend
for forwarding connections from the host machine to the enclave VM::
$ vhost-device-vsock \
--vm guest-cid=4,forward-cid=1,forward-listen=9001+9002,socket=/tmp/vhost4.socket
__ https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-vsock#using-the-vsock-backend
Now run the necessary applications on the host machine so that the nitro-enclave VM
applications' vsock communication works. For example, the nitro-enclave VM's init
process connects to CID 3 and sends a single byte hello heartbeat (0xB7) to let the
@@ -65,7 +65,7 @@ the applications on the host machine that would typically be running in the pare
VM for successful communication with the enclave VM.
Then run the nitro-enclave VM using the following command where ``hello.eif`` is
an EIF file you would use to spawn a real AWS nitro enclave virtual machine:
an EIF file you would use to spawn a real AWS nitro enclave virtual machine::
$ qemu-system-x86_64 -M nitro-enclave,vsock=c,id=hello-world \
-kernel hello-world.eif -nographic -m 4G --enable-kvm -cpu host \
+5 -5
View File
@@ -71,7 +71,7 @@ config HIGHBANK
depends on TCG && ARM
select A9MPCORE
select A15MPCORE
select AHCI
select AHCI_SYSBUS
select ARM_TIMER # sp804
select ARM_V7M
select PL011 if !HAVE_RUST # UART
@@ -192,7 +192,7 @@ config SBSA_REF
depends on TCG && AARCH64
imply PCI_DEVICES
select DEVICE_TREE
select AHCI
select AHCI_SYSBUS
select ARM_SMMUV3
select GPIO_KEY
select PCI_EXPRESS
@@ -319,7 +319,7 @@ config ARM_V7M
config ALLWINNER_A10
bool
select AHCI
select AHCI_SYSBUS
select ALLWINNER_A10_PIT
select ALLWINNER_A10_PIC
select ALLWINNER_A10_CCM
@@ -352,7 +352,7 @@ config ALLWINNER_H3
config ALLWINNER_R40
bool
default y if TCG && ARM
select AHCI
select AHCI_SYSBUS
select ALLWINNER_SRAMC
select ALLWINNER_A10_PIT
select ALLWINNER_WDT
@@ -422,7 +422,7 @@ config XLNX_ZYNQMP_ARM
bool
default y if PIXMAN
depends on TCG && AARCH64
select AHCI
select AHCI_SYSBUS
select ARM_GIC
select CADENCE
select CPU_CLUSTER
+2 -1
View File
@@ -1750,7 +1750,8 @@ void virt_machine_done(Notifier *notifier, void *data)
exit(1);
}
fw_cfg_add_extra_pci_roots(vms->bus, vms->fw_cfg);
pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus,
&error_abort);
virt_acpi_setup(vms);
virt_build_smbios(vms);
+77 -125
View File
@@ -187,10 +187,16 @@ static void safe_unlink(char *f)
* Upon success, the caller is reponsible for unlinking and freeing *kernel_path
*/
static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
uint8_t *kernel, uint32_t *crc, Error **errp)
QCryptoHash *hash0, QCryptoHash *hash1,
uint32_t *crc, Error **errp)
{
size_t got;
FILE *tmp_file = NULL;
uint8_t *kernel = g_try_malloc(size);
if (!kernel) {
error_setg(errp, "Out of memory reading kernel section");
goto cleanup;
}
*kernel_path = NULL;
if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) {
@@ -218,6 +224,11 @@ static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
}
*crc = crc32(*crc, kernel, size);
if (qcrypto_hash_update(hash0, (char *)kernel, size, errp) != 0 ||
qcrypto_hash_update(hash1, (char *)kernel, size, errp) != 0) {
goto cleanup;
}
g_free(kernel);
fclose(tmp_file);
return true;
@@ -229,10 +240,12 @@ static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
g_free(*kernel_path);
*kernel_path = NULL;
g_free(kernel);
return false;
}
static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
QCryptoHash *hash0, QCryptoHash *hash1,
uint32_t *crc, Error **errp)
{
size_t got = fread(cmdline, 1, size, f);
@@ -242,28 +255,47 @@ static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
}
*crc = crc32(*crc, (uint8_t *)cmdline, size);
if (qcrypto_hash_update(hash0, cmdline, size, errp) != 0 ||
qcrypto_hash_update(hash1, cmdline, size, errp) != 0) {
return false;
}
return true;
}
static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size,
uint8_t *ramdisk, uint32_t *crc, Error **errp)
QCryptoHash *hash0, QCryptoHash *h, uint32_t *crc,
Error **errp)
{
size_t got;
bool ret = false;
uint8_t *ramdisk = g_try_malloc(size);
if (!ramdisk) {
error_setg(errp, "Out of memory reading initrd section");
goto cleanup;
}
got = fread(ramdisk, 1, size, eif);
if ((uint64_t) got != size) {
error_setg(errp, "Failed to read EIF ramdisk section data");
return false;
goto cleanup;
}
got = fwrite(ramdisk, 1, size, initrd);
if ((uint64_t) got != size) {
error_setg(errp, "Failed to write EIF ramdisk data to temporary file");
return false;
goto cleanup;
}
*crc = crc32(*crc, ramdisk, size);
return true;
if (qcrypto_hash_update(hash0, (char *)ramdisk, size, errp) != 0 ||
qcrypto_hash_update(h, (char *)ramdisk, size, errp) != 0) {
goto cleanup;
}
ret = true;
cleanup:
g_free(ramdisk);
return ret;
}
static bool get_signature_fingerprint_sha384(FILE *eif, uint64_t size,
@@ -391,34 +423,10 @@ static long get_file_size(FILE *f, Error **errp)
return size;
}
static bool get_SHA384_digest(GList *list, uint8_t *digest, Error **errp)
static bool get_SHA384_hash(QCryptoHash *h, uint8_t *hash, Error **errp)
{
size_t digest_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
size_t list_len = g_list_length(list);
struct iovec *iovec_list = g_new0(struct iovec, list_len);
bool ret = true;
GList *l;
int i;
for (i = 0, l = list; l != NULL; l = l->next, i++) {
iovec_list[i] = *(struct iovec *) l->data;
}
if (qcrypto_hash_bytesv(QCRYPTO_HASH_ALGO_SHA384, iovec_list, list_len,
&digest, &digest_len, errp) < 0) {
ret = false;
}
g_free(iovec_list);
return ret;
}
static void free_iovec(struct iovec *iov)
{
if (iov) {
g_free(iov->iov_base);
g_free(iov);
}
size_t hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
return qcrypto_hash_finalize_bytes(h, &hash, &hash_len, errp) == 0;
}
/*
@@ -427,8 +435,8 @@ static void free_iovec(struct iovec *iov)
*/
bool read_eif_file(const char *eif_path, const char *machine_initrd,
char **kernel_path, char **initrd_path, char **cmdline,
uint8_t *image_sha384, uint8_t *bootstrap_sha384,
uint8_t *app_sha384, uint8_t *fingerprint_sha384,
uint8_t *image_hash, uint8_t *bootstrap_hash,
uint8_t *app_hash, uint8_t *fingerprint_hash,
bool *signature_found, Error **errp)
{
FILE *f = NULL;
@@ -438,18 +446,29 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
uint32_t crc = 0;
EifHeader eif_header;
bool seen_sections[EIF_SECTION_MAX] = {false};
/* kernel + ramdisks + cmdline sha384 hash */
GList *iov_PCR0 = NULL;
/* kernel + boot ramdisk + cmdline sha384 hash */
GList *iov_PCR1 = NULL;
/* application ramdisk(s) hash */
GList *iov_PCR2 = NULL;
uint8_t *ptr = NULL;
struct iovec *iov_ptr = NULL;
/* kernel + ramdisks + cmdline SHA384 hash */
g_autoptr(QCryptoHash) hash0 = NULL;
/* kernel + boot ramdisk + cmdline SHA384 hash */
g_autoptr(QCryptoHash) hash1 = NULL;
/* application ramdisk(s) SHA384 hash */
g_autoptr(QCryptoHash) hash2 = NULL;
*signature_found = false;
*kernel_path = *initrd_path = *cmdline = NULL;
hash0 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
if (!hash0) {
goto cleanup;
}
hash1 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
if (!hash1) {
goto cleanup;
}
hash2 = qcrypto_hash_new(QCRYPTO_HASH_ALGO_SHA384, errp);
if (!hash2) {
goto cleanup;
}
f = fopen(eif_path, "rb");
if (f == NULL) {
error_setg_errno(errp, errno, "Failed to open %s", eif_path);
@@ -517,21 +536,8 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
goto cleanup;
}
ptr = g_try_malloc(hdr.section_size);
if (!ptr) {
error_setg(errp, "Out of memory reading kernel section");
goto cleanup;
}
iov_ptr = g_malloc(sizeof(struct iovec));
iov_ptr->iov_base = ptr;
iov_ptr->iov_len = hdr.section_size;
iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
if (!read_eif_kernel(f, hdr.section_size, kernel_path, ptr, &crc,
errp)) {
if (!read_eif_kernel(f, hdr.section_size, kernel_path, hash0,
hash1, &crc, errp)) {
goto cleanup;
}
@@ -539,7 +545,6 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
case EIF_SECTION_CMDLINE:
{
uint64_t size;
uint8_t *cmdline_copy;
if (seen_sections[EIF_SECTION_CMDLINE]) {
error_setg(errp, "Invalid EIF image. More than 1 cmdline "
"section");
@@ -551,33 +556,26 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
error_setg(errp, "Out of memory reading command line section");
goto cleanup;
}
if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) {
if (!read_eif_cmdline(f, size, *cmdline, hash0, hash1, &crc,
errp)) {
goto cleanup;
}
(*cmdline)[size] = '\0';
/*
* We make a copy of '*cmdline' for putting it in iovecs so that
* we can easily free all the iovec entries later as we cannot
* free '*cmdline' which is used by the caller.
*/
cmdline_copy = g_memdup2(*cmdline, size);
iov_ptr = g_malloc(sizeof(struct iovec));
iov_ptr->iov_base = cmdline_copy;
iov_ptr->iov_len = size;
iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
break;
}
case EIF_SECTION_RAMDISK:
{
QCryptoHash *h = hash2;
if (!seen_sections[EIF_SECTION_RAMDISK]) {
/*
* If this is the first time we are seeing a ramdisk section,
* we need to create the initrd temporary file.
* we need to:
* 1) hash it into bootstrap (hash1) instead of app (hash2)
* along with image (hash0)
* 2) create the initrd temporary file.
*/
h = hash1;
if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) {
goto cleanup;
}
@@ -589,29 +587,7 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
}
}
ptr = g_try_malloc(hdr.section_size);
if (!ptr) {
error_setg(errp, "Out of memory reading initrd section");
goto cleanup;
}
iov_ptr = g_malloc(sizeof(struct iovec));
iov_ptr->iov_base = ptr;
iov_ptr->iov_len = hdr.section_size;
iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
/*
* If it's the first ramdisk, we need to hash it into bootstrap
* i.e., iov_PCR1, otherwise we need to hash it into app i.e.,
* iov_PCR2.
*/
if (!seen_sections[EIF_SECTION_RAMDISK]) {
iov_PCR1 = g_list_append(iov_PCR1, iov_ptr);
} else {
iov_PCR2 = g_list_append(iov_PCR2, iov_ptr);
}
if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, ptr,
if (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, hash0, h,
&crc, errp)) {
goto cleanup;
}
@@ -621,7 +597,7 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
case EIF_SECTION_SIGNATURE:
*signature_found = true;
if (!get_signature_fingerprint_sha384(f, hdr.section_size,
fingerprint_sha384, &crc,
fingerprint_hash, &crc,
errp)) {
goto cleanup;
}
@@ -692,52 +668,28 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
goto cleanup;
}
ptr = g_try_malloc(machine_initrd_size);
if (!ptr) {
error_setg(errp, "Out of memory reading initrd file");
goto cleanup;
}
iov_ptr = g_malloc(sizeof(struct iovec));
iov_ptr->iov_base = ptr;
iov_ptr->iov_len = machine_initrd_size;
iov_PCR0 = g_list_append(iov_PCR0, iov_ptr);
iov_PCR2 = g_list_append(iov_PCR2, iov_ptr);
if (!read_eif_ramdisk(machine_initrd_f, initrd_path_f,
machine_initrd_size, ptr, &crc, errp)) {
machine_initrd_size, hash0, hash2, &crc, errp)) {
goto cleanup;
}
}
if (!get_SHA384_digest(iov_PCR0, image_sha384, errp)) {
if (!get_SHA384_hash(hash0, image_hash, errp)) {
goto cleanup;
}
if (!get_SHA384_digest(iov_PCR1, bootstrap_sha384, errp)) {
if (!get_SHA384_hash(hash1, bootstrap_hash, errp)) {
goto cleanup;
}
if (!get_SHA384_digest(iov_PCR2, app_sha384, errp)) {
if (!get_SHA384_hash(hash2, app_hash, errp)) {
goto cleanup;
}
/*
* We only need to free iov_PCR0 entries because iov_PCR1 and
* iov_PCR2 iovec entries are subsets of iov_PCR0 iovec entries.
*/
g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec);
g_list_free(iov_PCR1);
g_list_free(iov_PCR2);
fclose(f);
fclose(initrd_path_f);
safe_fclose(machine_initrd_f);
return true;
cleanup:
g_list_free_full(iov_PCR0, (GDestroyNotify) free_iovec);
g_list_free(iov_PCR1);
g_list_free(iov_PCR2);
safe_fclose(f);
safe_fclose(initrd_path_f);
safe_fclose(machine_initrd_f);
+1 -1
View File
@@ -240,7 +240,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
g_memdup2(qemu_version, sizeof(qemu_version)),
sizeof(qemu_version));
fw_cfg_add_extra_pci_roots(pci_bus, fw_cfg);
pci_bus_add_fw_cfg_extra_pci_roots(fw_cfg, pci_bus, &error_abort);
return fw_cfg;
}
+6 -6
View File
@@ -117,13 +117,13 @@ static void nitro_enclave_machine_reset(MachineState *machine, ResetType type)
memset(ne_state->vnsm->pcrs, 0, sizeof(ne_state->vnsm->pcrs));
/* PCR0 */
ne_state->vnsm->extend_pcr(ne_state->vnsm, 0, ne_state->image_sha384,
ne_state->vnsm->extend_pcr(ne_state->vnsm, 0, ne_state->image_hash,
QCRYPTO_HASH_DIGEST_LEN_SHA384);
/* PCR1 */
ne_state->vnsm->extend_pcr(ne_state->vnsm, 1, ne_state->bootstrap_sha384,
ne_state->vnsm->extend_pcr(ne_state->vnsm, 1, ne_state->bootstrap_hash,
QCRYPTO_HASH_DIGEST_LEN_SHA384);
/* PCR2 */
ne_state->vnsm->extend_pcr(ne_state->vnsm, 2, ne_state->app_sha384,
ne_state->vnsm->extend_pcr(ne_state->vnsm, 2, ne_state->app_hash,
QCRYPTO_HASH_DIGEST_LEN_SHA384);
/* PCR3 */
if (ne_state->parent_role) {
@@ -140,7 +140,7 @@ static void nitro_enclave_machine_reset(MachineState *machine, ResetType type)
/* PCR8 */
if (ne_state->signature_found) {
ne_state->vnsm->extend_pcr(ne_state->vnsm, 8,
ne_state->fingerprint_sha384,
ne_state->fingerprint_hash,
QCRYPTO_HASH_DIGEST_LEN_SHA384);
}
@@ -173,8 +173,8 @@ static void x86_load_eif(X86MachineState *x86ms, FWCfgState *fw_cfg,
if (!read_eif_file(machine->kernel_filename, machine->initrd_filename,
&eif_kernel, &eif_initrd, &eif_cmdline,
nems->image_sha384, nems->bootstrap_sha384,
nems->app_sha384, nems->fingerprint_sha384,
nems->image_hash, nems->bootstrap_hash,
nems->app_hash, nems->fingerprint_hash,
&(nems->signature_found), &err)) {
error_report_err(err);
exit(1);
+2 -1
View File
@@ -631,7 +631,8 @@ void pc_machine_done(Notifier *notifier, void *data)
/* set the number of CPUs */
x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_cpus);
fw_cfg_add_extra_pci_roots(pcms->pcibus, x86ms->fw_cfg);
pci_bus_add_fw_cfg_extra_pci_roots(x86ms->fw_cfg, pcms->pcibus,
&error_abort);
acpi_setup();
if (x86ms->fw_cfg) {
+4
View File
@@ -54,6 +54,10 @@ config AHCI_ICH9
depends on PCI
select AHCI
config AHCI_SYSBUS
bool
select AHCI
config IDE_SII3112
bool
select IDE_PCI
-1
View File
@@ -25,7 +25,6 @@
#define HW_IDE_AHCI_INTERNAL_H
#include "hw/ide/ahci.h"
#include "hw/pci/pci_device.h"
#include "ide-internal.h"
#define AHCI_MEM_BAR_SIZE 0x1000
+91
View File
@@ -0,0 +1,91 @@
/*
* QEMU AHCI Emulation (MMIO-mapped devices)
*
* Copyright (c) 2010 qiaochong@loongson.cn
* Copyright (c) 2010 Roland Elek <elek.roland@gmail.com>
* Copyright (c) 2010 Sebastian Herbszt <herbszt@gmx.de>
* Copyright (c) 2010 Alexander Graf <agraf@suse.de>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
*/
#include "qemu/osdep.h"
#include "exec/address-spaces.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "hw/ide/ahci-sysbus.h"
#include "ahci-internal.h"
static const VMStateDescription vmstate_sysbus_ahci = {
.name = "sysbus-ahci",
.fields = (const VMStateField[]) {
VMSTATE_AHCI(ahci, SysbusAHCIState),
VMSTATE_END_OF_LIST()
},
};
static void sysbus_ahci_reset(DeviceState *dev)
{
SysbusAHCIState *s = SYSBUS_AHCI(dev);
ahci_reset(&s->ahci);
}
static void sysbus_ahci_init(Object *obj)
{
SysbusAHCIState *s = SYSBUS_AHCI(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
ahci_init(&s->ahci, DEVICE(obj));
sysbus_init_mmio(sbd, &s->ahci.mem);
sysbus_init_irq(sbd, &s->ahci.irq);
}
static void sysbus_ahci_realize(DeviceState *dev, Error **errp)
{
SysbusAHCIState *s = SYSBUS_AHCI(dev);
ahci_realize(&s->ahci, dev, &address_space_memory);
}
static Property sysbus_ahci_properties[] = {
DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, ahci.ports, 1),
DEFINE_PROP_END_OF_LIST(),
};
static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = sysbus_ahci_realize;
dc->vmsd = &vmstate_sysbus_ahci;
device_class_set_props(dc, sysbus_ahci_properties);
device_class_set_legacy_reset(dc, sysbus_ahci_reset);
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo sysbus_ahci_types[] = {
{
.name = TYPE_SYSBUS_AHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysbusAHCIState),
.instance_init = sysbus_ahci_init,
.class_init = sysbus_ahci_class_init,
},
};
DEFINE_TYPES(sysbus_ahci_types)
+4 -102
View File
@@ -23,20 +23,13 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/pci/msi.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "migration/vmstate.h"
#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "sysemu/block-backend.h"
#include "sysemu/dma.h"
#include "hw/ide/pci.h"
#include "hw/ide/ahci-pci.h"
#include "hw/ide/ahci-sysbus.h"
#include "ahci-internal.h"
#include "ide-internal.h"
@@ -179,34 +172,6 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset)
return val;
}
static void ahci_irq_raise(AHCIState *s)
{
DeviceState *dev_state = s->container;
PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
TYPE_PCI_DEVICE);
trace_ahci_irq_raise(s);
if (pci_dev && msi_enabled(pci_dev)) {
msi_notify(pci_dev, 0);
} else {
qemu_irq_raise(s->irq);
}
}
static void ahci_irq_lower(AHCIState *s)
{
DeviceState *dev_state = s->container;
PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
TYPE_PCI_DEVICE);
trace_ahci_irq_lower(s);
if (!pci_dev || !msi_enabled(pci_dev)) {
qemu_irq_lower(s->irq);
}
}
static void ahci_check_irq(AHCIState *s)
{
int i;
@@ -222,9 +187,11 @@ static void ahci_check_irq(AHCIState *s)
trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
if (s->control_regs.irqstatus &&
(s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
ahci_irq_raise(s);
trace_ahci_irq_raise(s);
qemu_irq_raise(s->irq);
} else {
ahci_irq_lower(s);
trace_ahci_irq_lower(s);
qemu_irq_lower(s->irq);
}
}
@@ -1608,7 +1575,6 @@ static const IDEDMAOps ahci_dma_ops = {
void ahci_init(AHCIState *s, DeviceState *qdev)
{
s->container = qdev;
/* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,
"ahci", AHCI_MEM_BAR_SIZE);
@@ -1834,70 +1800,6 @@ const VMStateDescription vmstate_ahci = {
},
};
static const VMStateDescription vmstate_sysbus_ahci = {
.name = "sysbus-ahci",
.fields = (const VMStateField[]) {
VMSTATE_AHCI(ahci, SysbusAHCIState),
VMSTATE_END_OF_LIST()
},
};
static void sysbus_ahci_reset(DeviceState *dev)
{
SysbusAHCIState *s = SYSBUS_AHCI(dev);
ahci_reset(&s->ahci);
}
static void sysbus_ahci_init(Object *obj)
{
SysbusAHCIState *s = SYSBUS_AHCI(obj);
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
ahci_init(&s->ahci, DEVICE(obj));
sysbus_init_mmio(sbd, &s->ahci.mem);
sysbus_init_irq(sbd, &s->ahci.irq);
}
static void sysbus_ahci_realize(DeviceState *dev, Error **errp)
{
SysbusAHCIState *s = SYSBUS_AHCI(dev);
ahci_realize(&s->ahci, dev, &address_space_memory);
}
static Property sysbus_ahci_properties[] = {
DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, ahci.ports, 1),
DEFINE_PROP_END_OF_LIST(),
};
static void sysbus_ahci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = sysbus_ahci_realize;
dc->vmsd = &vmstate_sysbus_ahci;
device_class_set_props(dc, sysbus_ahci_properties);
device_class_set_legacy_reset(dc, sysbus_ahci_reset);
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
}
static const TypeInfo sysbus_ahci_info = {
.name = TYPE_SYSBUS_AHCI,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysbusAHCIState),
.instance_init = sysbus_ahci_init,
.class_init = sysbus_ahci_class_init,
};
static void sysbus_ahci_register_types(void)
{
type_register_static(&sysbus_ahci_info);
}
type_init(sysbus_ahci_register_types)
void ahci_ide_create_devs(AHCIState *ahci, DriveInfo **hd)
{
int i;
+15 -4
View File
@@ -61,7 +61,6 @@
*/
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/pci/msi.h"
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
@@ -91,6 +90,19 @@ static const VMStateDescription vmstate_ich9_ahci = {
},
};
static void pci_ich9_ahci_update_irq(void *opaque, int irq_num, int level)
{
PCIDevice *pci_dev = opaque;
if (msi_enabled(pci_dev)) {
if (level) {
msi_notify(pci_dev, 0);
}
} else {
pci_set_irq(pci_dev, level);
}
}
static void pci_ich9_reset(DeviceState *dev)
{
AHCIPCIState *d = ICH9_AHCI(dev);
@@ -102,7 +114,9 @@ static void pci_ich9_ahci_init(Object *obj)
{
AHCIPCIState *d = ICH9_AHCI(obj);
qemu_init_irq(&d->irq, pci_ich9_ahci_update_irq, d, 0);
ahci_init(&d->ahci, DEVICE(obj));
d->ahci.irq = &d->irq;
}
static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
@@ -125,8 +139,6 @@ static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
/* XXX Software should program this register */
dev->config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */
d->ahci.irq = pci_allocate_irq(dev);
pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO,
&d->ahci.idp);
pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -161,7 +173,6 @@ static void pci_ich9_uninit(PCIDevice *dev)
msi_uninit(dev);
ahci_uninit(&d->ahci);
qemu_free_irq(d->ahci.irq);
}
static void ich_ahci_class_init(ObjectClass *klass, void *data)
+1
View File
@@ -1,5 +1,6 @@
system_ss.add(when: 'CONFIG_AHCI', if_true: files('ahci.c'))
system_ss.add(when: 'CONFIG_AHCI_ICH9', if_true: files('ich.c'))
system_ss.add(when: 'CONFIG_AHCI_SYSBUS', if_true: files('ahci-sysbus.c'))
system_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('ahci-allwinner.c'))
system_ss.add(when: 'CONFIG_IDE_BUS', if_true: files('ide-bus.c'))
system_ss.add(when: 'CONFIG_IDE_CF', if_true: files('cf.c'))
+1
View File
@@ -40,6 +40,7 @@
#include "sysemu/reset.h"
#include "sysemu/sysemu.h"
#include "qemu/error-report.h"
#include "exec/tswap.h"
#define ENVP_PADDR 0x2000
#define ENVP_VADDR cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
+1
View File
@@ -28,6 +28,7 @@
#include "qemu/datadir.h"
#include "qemu/cutils.h"
#include "qemu/guest-random.h"
#include "exec/tswap.h"
#include "hw/clock.h"
#include "hw/southbridge/piix.h"
#include "hw/isa/superio.h"
-4
View File
@@ -30,12 +30,8 @@
*/
#include "qemu/osdep.h"
#include "qemu/event_notifier.h"
#include "qemu/module.h"
#include "qemu/thread.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "hw/irq.h"
#include "hw/pci/pci_device.h"
#include "hw/qdev-properties.h"
-4
View File
@@ -26,12 +26,8 @@
*/
#include "qemu/osdep.h"
#include "qemu/event_notifier.h"
#include "qemu/module.h"
#include "qemu/thread.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "hw/irq.h"
#include "hw/pci/pci_device.h"
#include "hw/qdev-properties.h"
-4
View File
@@ -26,12 +26,8 @@
*/
#include "qemu/osdep.h"
#include "qemu/event_notifier.h"
#include "qemu/module.h"
#include "qemu/thread.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "hw/irq.h"
#include "hw/pci/pci_device.h"
#include "hw/qdev-properties.h"
+1 -1
View File
@@ -27,7 +27,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "chardev/char.h"
#include "qemu/bitops.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "net/can_emu.h"
+2 -1
View File
@@ -28,7 +28,8 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "chardev/char.h"
#include "qemu/bswap.h"
#include "qemu/bitops.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "net/can_emu.h"

Some files were not shown because too many files have changed in this diff Show More