mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-18 23:52:14 -06:00
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----- 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:
commit
ca80a5d026
37 changed files with 343 additions and 358 deletions
|
@ -48,13 +48,13 @@ Running a nitro-enclave VM
|
||||||
First, run `vhost-device-vsock`__ (or a similar tool that supports vhost-user-vsock).
|
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
|
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
|
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.
|
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
|
|
||||||
|
|
||||||
$ vhost-device-vsock \
|
$ vhost-device-vsock \
|
||||||
--vm guest-cid=4,forward-cid=1,forward-listen=9001+9002,socket=/tmp/vhost4.socket
|
--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
|
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
|
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
|
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.
|
VM for successful communication with the enclave VM.
|
||||||
|
|
||||||
Then run the nitro-enclave VM using the following command where ``hello.eif`` is
|
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 \
|
$ qemu-system-x86_64 -M nitro-enclave,vsock=c,id=hello-world \
|
||||||
-kernel hello-world.eif -nographic -m 4G --enable-kvm -cpu host \
|
-kernel hello-world.eif -nographic -m 4G --enable-kvm -cpu host \
|
||||||
|
|
|
@ -71,7 +71,7 @@ config HIGHBANK
|
||||||
depends on TCG && ARM
|
depends on TCG && ARM
|
||||||
select A9MPCORE
|
select A9MPCORE
|
||||||
select A15MPCORE
|
select A15MPCORE
|
||||||
select AHCI
|
select AHCI_SYSBUS
|
||||||
select ARM_TIMER # sp804
|
select ARM_TIMER # sp804
|
||||||
select ARM_V7M
|
select ARM_V7M
|
||||||
select PL011 if !HAVE_RUST # UART
|
select PL011 if !HAVE_RUST # UART
|
||||||
|
@ -192,7 +192,7 @@ config SBSA_REF
|
||||||
depends on TCG && AARCH64
|
depends on TCG && AARCH64
|
||||||
imply PCI_DEVICES
|
imply PCI_DEVICES
|
||||||
select DEVICE_TREE
|
select DEVICE_TREE
|
||||||
select AHCI
|
select AHCI_SYSBUS
|
||||||
select ARM_SMMUV3
|
select ARM_SMMUV3
|
||||||
select GPIO_KEY
|
select GPIO_KEY
|
||||||
select PCI_EXPRESS
|
select PCI_EXPRESS
|
||||||
|
@ -319,7 +319,7 @@ config ARM_V7M
|
||||||
|
|
||||||
config ALLWINNER_A10
|
config ALLWINNER_A10
|
||||||
bool
|
bool
|
||||||
select AHCI
|
select AHCI_SYSBUS
|
||||||
select ALLWINNER_A10_PIT
|
select ALLWINNER_A10_PIT
|
||||||
select ALLWINNER_A10_PIC
|
select ALLWINNER_A10_PIC
|
||||||
select ALLWINNER_A10_CCM
|
select ALLWINNER_A10_CCM
|
||||||
|
@ -352,7 +352,7 @@ config ALLWINNER_H3
|
||||||
config ALLWINNER_R40
|
config ALLWINNER_R40
|
||||||
bool
|
bool
|
||||||
default y if TCG && ARM
|
default y if TCG && ARM
|
||||||
select AHCI
|
select AHCI_SYSBUS
|
||||||
select ALLWINNER_SRAMC
|
select ALLWINNER_SRAMC
|
||||||
select ALLWINNER_A10_PIT
|
select ALLWINNER_A10_PIT
|
||||||
select ALLWINNER_WDT
|
select ALLWINNER_WDT
|
||||||
|
@ -422,7 +422,7 @@ config XLNX_ZYNQMP_ARM
|
||||||
bool
|
bool
|
||||||
default y if PIXMAN
|
default y if PIXMAN
|
||||||
depends on TCG && AARCH64
|
depends on TCG && AARCH64
|
||||||
select AHCI
|
select AHCI_SYSBUS
|
||||||
select ARM_GIC
|
select ARM_GIC
|
||||||
select CADENCE
|
select CADENCE
|
||||||
select CPU_CLUSTER
|
select CPU_CLUSTER
|
||||||
|
|
|
@ -1750,7 +1750,8 @@ void virt_machine_done(Notifier *notifier, void *data)
|
||||||
exit(1);
|
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_acpi_setup(vms);
|
||||||
virt_build_smbios(vms);
|
virt_build_smbios(vms);
|
||||||
|
|
202
hw/core/eif.c
202
hw/core/eif.c
|
@ -187,10 +187,16 @@ static void safe_unlink(char *f)
|
||||||
* Upon success, the caller is reponsible for unlinking and freeing *kernel_path
|
* 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,
|
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;
|
size_t got;
|
||||||
FILE *tmp_file = NULL;
|
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;
|
*kernel_path = NULL;
|
||||||
if (!get_tmp_file("eif-kernel-XXXXXX", kernel_path, errp)) {
|
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);
|
*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);
|
fclose(tmp_file);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -229,10 +240,12 @@ static bool read_eif_kernel(FILE *f, uint64_t size, char **kernel_path,
|
||||||
g_free(*kernel_path);
|
g_free(*kernel_path);
|
||||||
*kernel_path = NULL;
|
*kernel_path = NULL;
|
||||||
|
|
||||||
|
g_free(kernel);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
|
static bool read_eif_cmdline(FILE *f, uint64_t size, char *cmdline,
|
||||||
|
QCryptoHash *hash0, QCryptoHash *hash1,
|
||||||
uint32_t *crc, Error **errp)
|
uint32_t *crc, Error **errp)
|
||||||
{
|
{
|
||||||
size_t got = fread(cmdline, 1, size, f);
|
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);
|
*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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool read_eif_ramdisk(FILE *eif, FILE *initrd, uint64_t size,
|
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;
|
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);
|
got = fread(ramdisk, 1, size, eif);
|
||||||
if ((uint64_t) got != size) {
|
if ((uint64_t) got != size) {
|
||||||
error_setg(errp, "Failed to read EIF ramdisk section data");
|
error_setg(errp, "Failed to read EIF ramdisk section data");
|
||||||
return false;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
got = fwrite(ramdisk, 1, size, initrd);
|
got = fwrite(ramdisk, 1, size, initrd);
|
||||||
if ((uint64_t) got != size) {
|
if ((uint64_t) got != size) {
|
||||||
error_setg(errp, "Failed to write EIF ramdisk data to temporary file");
|
error_setg(errp, "Failed to write EIF ramdisk data to temporary file");
|
||||||
return false;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
*crc = crc32(*crc, ramdisk, size);
|
*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,
|
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;
|
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 hash_len = QCRYPTO_HASH_DIGEST_LEN_SHA384;
|
||||||
size_t list_len = g_list_length(list);
|
return qcrypto_hash_finalize_bytes(h, &hash, &hash_len, errp) == 0;
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -427,8 +435,8 @@ static void free_iovec(struct iovec *iov)
|
||||||
*/
|
*/
|
||||||
bool read_eif_file(const char *eif_path, const char *machine_initrd,
|
bool read_eif_file(const char *eif_path, const char *machine_initrd,
|
||||||
char **kernel_path, char **initrd_path, char **cmdline,
|
char **kernel_path, char **initrd_path, char **cmdline,
|
||||||
uint8_t *image_sha384, uint8_t *bootstrap_sha384,
|
uint8_t *image_hash, uint8_t *bootstrap_hash,
|
||||||
uint8_t *app_sha384, uint8_t *fingerprint_sha384,
|
uint8_t *app_hash, uint8_t *fingerprint_hash,
|
||||||
bool *signature_found, Error **errp)
|
bool *signature_found, Error **errp)
|
||||||
{
|
{
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
|
@ -438,18 +446,29 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
|
||||||
uint32_t crc = 0;
|
uint32_t crc = 0;
|
||||||
EifHeader eif_header;
|
EifHeader eif_header;
|
||||||
bool seen_sections[EIF_SECTION_MAX] = {false};
|
bool seen_sections[EIF_SECTION_MAX] = {false};
|
||||||
/* kernel + ramdisks + cmdline sha384 hash */
|
/* kernel + ramdisks + cmdline SHA384 hash */
|
||||||
GList *iov_PCR0 = NULL;
|
g_autoptr(QCryptoHash) hash0 = NULL;
|
||||||
/* kernel + boot ramdisk + cmdline sha384 hash */
|
/* kernel + boot ramdisk + cmdline SHA384 hash */
|
||||||
GList *iov_PCR1 = NULL;
|
g_autoptr(QCryptoHash) hash1 = NULL;
|
||||||
/* application ramdisk(s) hash */
|
/* application ramdisk(s) SHA384 hash */
|
||||||
GList *iov_PCR2 = NULL;
|
g_autoptr(QCryptoHash) hash2 = NULL;
|
||||||
uint8_t *ptr = NULL;
|
|
||||||
struct iovec *iov_ptr = NULL;
|
|
||||||
|
|
||||||
*signature_found = false;
|
*signature_found = false;
|
||||||
*kernel_path = *initrd_path = *cmdline = NULL;
|
*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");
|
f = fopen(eif_path, "rb");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
error_setg_errno(errp, errno, "Failed to open %s", eif_path);
|
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;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = g_try_malloc(hdr.section_size);
|
if (!read_eif_kernel(f, hdr.section_size, kernel_path, hash0,
|
||||||
if (!ptr) {
|
hash1, &crc, errp)) {
|
||||||
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)) {
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +545,6 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
|
||||||
case EIF_SECTION_CMDLINE:
|
case EIF_SECTION_CMDLINE:
|
||||||
{
|
{
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint8_t *cmdline_copy;
|
|
||||||
if (seen_sections[EIF_SECTION_CMDLINE]) {
|
if (seen_sections[EIF_SECTION_CMDLINE]) {
|
||||||
error_setg(errp, "Invalid EIF image. More than 1 cmdline "
|
error_setg(errp, "Invalid EIF image. More than 1 cmdline "
|
||||||
"section");
|
"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");
|
error_setg(errp, "Out of memory reading command line section");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!read_eif_cmdline(f, size, *cmdline, &crc, errp)) {
|
if (!read_eif_cmdline(f, size, *cmdline, hash0, hash1, &crc,
|
||||||
|
errp)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
(*cmdline)[size] = '\0';
|
(*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;
|
break;
|
||||||
}
|
}
|
||||||
case EIF_SECTION_RAMDISK:
|
case EIF_SECTION_RAMDISK:
|
||||||
{
|
{
|
||||||
|
QCryptoHash *h = hash2;
|
||||||
if (!seen_sections[EIF_SECTION_RAMDISK]) {
|
if (!seen_sections[EIF_SECTION_RAMDISK]) {
|
||||||
/*
|
/*
|
||||||
* If this is the first time we are seeing a ramdisk section,
|
* 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)) {
|
if (!get_tmp_file("eif-initrd-XXXXXX", initrd_path, errp)) {
|
||||||
goto cleanup;
|
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 (!read_eif_ramdisk(f, initrd_path_f, hdr.section_size, hash0, h,
|
||||||
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,
|
|
||||||
&crc, errp)) {
|
&crc, errp)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -621,7 +597,7 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
|
||||||
case EIF_SECTION_SIGNATURE:
|
case EIF_SECTION_SIGNATURE:
|
||||||
*signature_found = true;
|
*signature_found = true;
|
||||||
if (!get_signature_fingerprint_sha384(f, hdr.section_size,
|
if (!get_signature_fingerprint_sha384(f, hdr.section_size,
|
||||||
fingerprint_sha384, &crc,
|
fingerprint_hash, &crc,
|
||||||
errp)) {
|
errp)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
@ -692,52 +668,28 @@ bool read_eif_file(const char *eif_path, const char *machine_initrd,
|
||||||
goto cleanup;
|
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,
|
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;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_SHA384_digest(iov_PCR0, image_sha384, errp)) {
|
if (!get_SHA384_hash(hash0, image_hash, errp)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!get_SHA384_digest(iov_PCR1, bootstrap_sha384, errp)) {
|
if (!get_SHA384_hash(hash1, bootstrap_hash, errp)) {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (!get_SHA384_digest(iov_PCR2, app_sha384, errp)) {
|
if (!get_SHA384_hash(hash2, app_hash, errp)) {
|
||||||
goto cleanup;
|
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(f);
|
||||||
fclose(initrd_path_f);
|
fclose(initrd_path_f);
|
||||||
safe_fclose(machine_initrd_f);
|
safe_fclose(machine_initrd_f);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
cleanup:
|
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(f);
|
||||||
safe_fclose(initrd_path_f);
|
safe_fclose(initrd_path_f);
|
||||||
safe_fclose(machine_initrd_f);
|
safe_fclose(machine_initrd_f);
|
||||||
|
|
|
@ -240,7 +240,7 @@ static FWCfgState *create_fw_cfg(MachineState *ms, PCIBus *pci_bus,
|
||||||
g_memdup2(qemu_version, sizeof(qemu_version)),
|
g_memdup2(qemu_version, sizeof(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;
|
return fw_cfg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
memset(ne_state->vnsm->pcrs, 0, sizeof(ne_state->vnsm->pcrs));
|
||||||
|
|
||||||
/* PCR0 */
|
/* 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);
|
QCRYPTO_HASH_DIGEST_LEN_SHA384);
|
||||||
/* PCR1 */
|
/* 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);
|
QCRYPTO_HASH_DIGEST_LEN_SHA384);
|
||||||
/* PCR2 */
|
/* 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);
|
QCRYPTO_HASH_DIGEST_LEN_SHA384);
|
||||||
/* PCR3 */
|
/* PCR3 */
|
||||||
if (ne_state->parent_role) {
|
if (ne_state->parent_role) {
|
||||||
|
@ -140,7 +140,7 @@ static void nitro_enclave_machine_reset(MachineState *machine, ResetType type)
|
||||||
/* PCR8 */
|
/* PCR8 */
|
||||||
if (ne_state->signature_found) {
|
if (ne_state->signature_found) {
|
||||||
ne_state->vnsm->extend_pcr(ne_state->vnsm, 8,
|
ne_state->vnsm->extend_pcr(ne_state->vnsm, 8,
|
||||||
ne_state->fingerprint_sha384,
|
ne_state->fingerprint_hash,
|
||||||
QCRYPTO_HASH_DIGEST_LEN_SHA384);
|
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,
|
if (!read_eif_file(machine->kernel_filename, machine->initrd_filename,
|
||||||
&eif_kernel, &eif_initrd, &eif_cmdline,
|
&eif_kernel, &eif_initrd, &eif_cmdline,
|
||||||
nems->image_sha384, nems->bootstrap_sha384,
|
nems->image_hash, nems->bootstrap_hash,
|
||||||
nems->app_sha384, nems->fingerprint_sha384,
|
nems->app_hash, nems->fingerprint_hash,
|
||||||
&(nems->signature_found), &err)) {
|
&(nems->signature_found), &err)) {
|
||||||
error_report_err(err);
|
error_report_err(err);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -631,7 +631,8 @@ void pc_machine_done(Notifier *notifier, void *data)
|
||||||
/* set the number of CPUs */
|
/* set the number of CPUs */
|
||||||
x86_rtc_set_cpus_count(x86ms->rtc, x86ms->boot_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();
|
acpi_setup();
|
||||||
if (x86ms->fw_cfg) {
|
if (x86ms->fw_cfg) {
|
||||||
|
|
|
@ -54,6 +54,10 @@ config AHCI_ICH9
|
||||||
depends on PCI
|
depends on PCI
|
||||||
select AHCI
|
select AHCI
|
||||||
|
|
||||||
|
config AHCI_SYSBUS
|
||||||
|
bool
|
||||||
|
select AHCI
|
||||||
|
|
||||||
config IDE_SII3112
|
config IDE_SII3112
|
||||||
bool
|
bool
|
||||||
select IDE_PCI
|
select IDE_PCI
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#define HW_IDE_AHCI_INTERNAL_H
|
#define HW_IDE_AHCI_INTERNAL_H
|
||||||
|
|
||||||
#include "hw/ide/ahci.h"
|
#include "hw/ide/ahci.h"
|
||||||
#include "hw/pci/pci_device.h"
|
|
||||||
#include "ide-internal.h"
|
#include "ide-internal.h"
|
||||||
|
|
||||||
#define AHCI_MEM_BAR_SIZE 0x1000
|
#define AHCI_MEM_BAR_SIZE 0x1000
|
||||||
|
|
91
hw/ide/ahci-sysbus.c
Normal file
91
hw/ide/ahci-sysbus.c
Normal 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)
|
106
hw/ide/ahci.c
106
hw/ide/ahci.c
|
@ -23,20 +23,13 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/irq.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 "migration/vmstate.h"
|
||||||
|
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "qemu/main-loop.h"
|
#include "qemu/main-loop.h"
|
||||||
#include "qemu/module.h"
|
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
#include "sysemu/dma.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 "ahci-internal.h"
|
||||||
#include "ide-internal.h"
|
#include "ide-internal.h"
|
||||||
|
|
||||||
|
@ -179,34 +172,6 @@ static uint32_t ahci_port_read(AHCIState *s, int port, int offset)
|
||||||
return val;
|
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)
|
static void ahci_check_irq(AHCIState *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -222,9 +187,11 @@ static void ahci_check_irq(AHCIState *s)
|
||||||
trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
|
trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
|
||||||
if (s->control_regs.irqstatus &&
|
if (s->control_regs.irqstatus &&
|
||||||
(s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
|
(s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
|
||||||
ahci_irq_raise(s);
|
trace_ahci_irq_raise(s);
|
||||||
|
qemu_irq_raise(s->irq);
|
||||||
} else {
|
} 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)
|
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 */
|
/* 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,
|
memory_region_init_io(&s->mem, OBJECT(qdev), &ahci_mem_ops, s,
|
||||||
"ahci", AHCI_MEM_BAR_SIZE);
|
"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)
|
void ahci_ide_create_devs(AHCIState *ahci, DriveInfo **hd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
19
hw/ide/ich.c
19
hw/ide/ich.c
|
@ -61,7 +61,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/irq.h"
|
|
||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
#include "hw/pci/pci.h"
|
#include "hw/pci/pci.h"
|
||||||
#include "migration/vmstate.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)
|
static void pci_ich9_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
AHCIPCIState *d = ICH9_AHCI(dev);
|
AHCIPCIState *d = ICH9_AHCI(dev);
|
||||||
|
@ -102,7 +114,9 @@ static void pci_ich9_ahci_init(Object *obj)
|
||||||
{
|
{
|
||||||
AHCIPCIState *d = ICH9_AHCI(obj);
|
AHCIPCIState *d = ICH9_AHCI(obj);
|
||||||
|
|
||||||
|
qemu_init_irq(&d->irq, pci_ich9_ahci_update_irq, d, 0);
|
||||||
ahci_init(&d->ahci, DEVICE(obj));
|
ahci_init(&d->ahci, DEVICE(obj));
|
||||||
|
d->ahci.irq = &d->irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)
|
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 */
|
/* XXX Software should program this register */
|
||||||
dev->config[0x90] = 1 << 6; /* Address Map Register - AHCI mode */
|
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,
|
pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO,
|
||||||
&d->ahci.idp);
|
&d->ahci.idp);
|
||||||
pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,
|
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);
|
msi_uninit(dev);
|
||||||
ahci_uninit(&d->ahci);
|
ahci_uninit(&d->ahci);
|
||||||
qemu_free_irq(d->ahci.irq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ich_ahci_class_init(ObjectClass *klass, void *data)
|
static void ich_ahci_class_init(ObjectClass *klass, void *data)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
system_ss.add(when: 'CONFIG_AHCI', if_true: files('ahci.c'))
|
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_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_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_BUS', if_true: files('ide-bus.c'))
|
||||||
system_ss.add(when: 'CONFIG_IDE_CF', if_true: files('cf.c'))
|
system_ss.add(when: 'CONFIG_IDE_CF', if_true: files('cf.c'))
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "sysemu/reset.h"
|
#include "sysemu/reset.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
#include "exec/tswap.h"
|
||||||
|
|
||||||
#define ENVP_PADDR 0x2000
|
#define ENVP_PADDR 0x2000
|
||||||
#define ENVP_VADDR cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
|
#define ENVP_VADDR cpu_mips_phys_to_kseg0(NULL, ENVP_PADDR)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "qemu/datadir.h"
|
#include "qemu/datadir.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qemu/guest-random.h"
|
#include "qemu/guest-random.h"
|
||||||
|
#include "exec/tswap.h"
|
||||||
#include "hw/clock.h"
|
#include "hw/clock.h"
|
||||||
#include "hw/southbridge/piix.h"
|
#include "hw/southbridge/piix.h"
|
||||||
#include "hw/isa/superio.h"
|
#include "hw/isa/superio.h"
|
||||||
|
|
|
@ -30,12 +30,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/event_notifier.h"
|
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/thread.h"
|
|
||||||
#include "qemu/sockets.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "chardev/char.h"
|
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "hw/pci/pci_device.h"
|
#include "hw/pci/pci_device.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
|
|
|
@ -26,12 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/event_notifier.h"
|
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/thread.h"
|
|
||||||
#include "qemu/sockets.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "chardev/char.h"
|
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "hw/pci/pci_device.h"
|
#include "hw/pci/pci_device.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
|
|
|
@ -26,12 +26,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/event_notifier.h"
|
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/thread.h"
|
|
||||||
#include "qemu/sockets.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "chardev/char.h"
|
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "hw/pci/pci_device.h"
|
#include "hw/pci/pci_device.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "chardev/char.h"
|
#include "qemu/bitops.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "net/can_emu.h"
|
#include "net/can_emu.h"
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
#include "chardev/char.h"
|
#include "qemu/bswap.h"
|
||||||
|
#include "qemu/bitops.h"
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "migration/vmstate.h"
|
#include "migration/vmstate.h"
|
||||||
#include "net/can_emu.h"
|
#include "net/can_emu.h"
|
||||||
|
|
|
@ -27,12 +27,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "qemu/event_notifier.h"
|
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu/thread.h"
|
|
||||||
#include "qemu/sockets.h"
|
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "chardev/char.h"
|
|
||||||
#include "hw/irq.h"
|
#include "hw/irq.h"
|
||||||
#include "hw/pci/pci_device.h"
|
#include "hw/pci/pci_device.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
|
|
|
@ -41,7 +41,6 @@
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "hw/acpi/aml-build.h"
|
#include "hw/acpi/aml-build.h"
|
||||||
#include "hw/pci/pci_bus.h"
|
|
||||||
#include "hw/loader.h"
|
#include "hw/loader.h"
|
||||||
|
|
||||||
#define FW_CFG_FILE_SLOTS_DFLT 0x20
|
#define FW_CFG_FILE_SLOTS_DFLT 0x20
|
||||||
|
@ -1027,27 +1026,29 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename,
|
bool fw_cfg_add_file_from_generator(FWCfgState *s,
|
||||||
const char *gen_id, Error **errp)
|
Object *parent, const char *part,
|
||||||
|
const char *filename, Error **errp)
|
||||||
{
|
{
|
||||||
|
ERRP_GUARD();
|
||||||
FWCfgDataGeneratorClass *klass;
|
FWCfgDataGeneratorClass *klass;
|
||||||
GByteArray *array;
|
GByteArray *array;
|
||||||
Object *obj;
|
Object *obj;
|
||||||
gsize size;
|
gsize size;
|
||||||
|
|
||||||
obj = object_resolve_path_component(object_get_objects_root(), gen_id);
|
obj = object_resolve_path_component(parent, part);
|
||||||
if (!obj) {
|
if (!obj) {
|
||||||
error_setg(errp, "Cannot find object ID '%s'", gen_id);
|
error_setg(errp, "Cannot find object ID '%s'", part);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!object_dynamic_cast(obj, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE)) {
|
if (!object_dynamic_cast(obj, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE)) {
|
||||||
error_setg(errp, "Object ID '%s' is not a '%s' subclass",
|
error_setg(errp, "Object ID '%s' is not a '%s' subclass",
|
||||||
gen_id, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE);
|
part, TYPE_FW_CFG_DATA_GENERATOR_INTERFACE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
klass = FW_CFG_DATA_GENERATOR_GET_CLASS(obj);
|
klass = FW_CFG_DATA_GENERATOR_GET_CLASS(obj);
|
||||||
array = klass->get_data(obj, errp);
|
array = klass->get_data(obj, errp);
|
||||||
if (!array) {
|
if (*errp || !array) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
size = array->len;
|
size = array->len;
|
||||||
|
@ -1056,28 +1057,6 @@ bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fw_cfg_add_extra_pci_roots(PCIBus *bus, FWCfgState *s)
|
|
||||||
{
|
|
||||||
int extra_hosts = 0;
|
|
||||||
|
|
||||||
if (!bus) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QLIST_FOREACH(bus, &bus->child, sibling) {
|
|
||||||
/* look for expander root buses */
|
|
||||||
if (pci_bus_is_root(bus)) {
|
|
||||||
extra_hosts++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extra_hosts && s) {
|
|
||||||
uint64_t *val = g_malloc(sizeof(*val));
|
|
||||||
*val = cpu_to_le64(extra_hosts);
|
|
||||||
fw_cfg_add_file(s, "etc/extra-pci-roots", val, sizeof(*val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fw_cfg_machine_reset(void *opaque)
|
static void fw_cfg_machine_reset(void *opaque)
|
||||||
{
|
{
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
|
||||||
|
|
53
hw/pci/pci.c
53
hw/pci/pci.c
|
@ -46,6 +46,7 @@
|
||||||
#include "hw/pci/msix.h"
|
#include "hw/pci/msix.h"
|
||||||
#include "hw/hotplug.h"
|
#include "hw/hotplug.h"
|
||||||
#include "hw/boards.h"
|
#include "hw/boards.h"
|
||||||
|
#include "hw/nvram/fw_cfg.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "qemu/cutils.h"
|
#include "qemu/cutils.h"
|
||||||
#include "pci-internal.h"
|
#include "pci-internal.h"
|
||||||
|
@ -216,11 +217,57 @@ static uint16_t pcibus_numa_node(PCIBus *bus)
|
||||||
return NUMA_NODE_UNASSIGNED;
|
return NUMA_NODE_UNASSIGNED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool pci_bus_add_fw_cfg_extra_pci_roots(FWCfgState *fw_cfg,
|
||||||
|
PCIBus *bus,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
Object *obj;
|
||||||
|
|
||||||
|
if (!bus) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
obj = OBJECT(bus);
|
||||||
|
|
||||||
|
return fw_cfg_add_file_from_generator(fw_cfg, obj->parent,
|
||||||
|
object_get_canonical_path_component(obj),
|
||||||
|
"etc/extra-pci-roots", errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GByteArray *pci_bus_fw_cfg_gen_data(Object *obj, Error **errp)
|
||||||
|
{
|
||||||
|
PCIBus *bus = PCI_BUS(obj);
|
||||||
|
GByteArray *byte_array;
|
||||||
|
uint64_t extra_hosts = 0;
|
||||||
|
|
||||||
|
if (!bus) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QLIST_FOREACH(bus, &bus->child, sibling) {
|
||||||
|
/* look for expander root buses */
|
||||||
|
if (pci_bus_is_root(bus)) {
|
||||||
|
extra_hosts++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!extra_hosts) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
extra_hosts = cpu_to_le64(extra_hosts);
|
||||||
|
|
||||||
|
byte_array = g_byte_array_new();
|
||||||
|
g_byte_array_append(byte_array,
|
||||||
|
(const void *)&extra_hosts, sizeof(extra_hosts));
|
||||||
|
|
||||||
|
return byte_array;
|
||||||
|
}
|
||||||
|
|
||||||
static void pci_bus_class_init(ObjectClass *klass, void *data)
|
static void pci_bus_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
BusClass *k = BUS_CLASS(klass);
|
BusClass *k = BUS_CLASS(klass);
|
||||||
PCIBusClass *pbc = PCI_BUS_CLASS(klass);
|
PCIBusClass *pbc = PCI_BUS_CLASS(klass);
|
||||||
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
||||||
|
FWCfgDataGeneratorClass *fwgc = FW_CFG_DATA_GENERATOR_CLASS(klass);
|
||||||
|
|
||||||
k->print_dev = pcibus_dev_print;
|
k->print_dev = pcibus_dev_print;
|
||||||
k->get_dev_path = pcibus_get_dev_path;
|
k->get_dev_path = pcibus_get_dev_path;
|
||||||
|
@ -232,6 +279,8 @@ static void pci_bus_class_init(ObjectClass *klass, void *data)
|
||||||
|
|
||||||
pbc->bus_num = pcibus_num;
|
pbc->bus_num = pcibus_num;
|
||||||
pbc->numa_node = pcibus_numa_node;
|
pbc->numa_node = pcibus_numa_node;
|
||||||
|
|
||||||
|
fwgc->get_data = pci_bus_fw_cfg_gen_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo pci_bus_info = {
|
static const TypeInfo pci_bus_info = {
|
||||||
|
@ -240,6 +289,10 @@ static const TypeInfo pci_bus_info = {
|
||||||
.instance_size = sizeof(PCIBus),
|
.instance_size = sizeof(PCIBus),
|
||||||
.class_size = sizeof(PCIBusClass),
|
.class_size = sizeof(PCIBusClass),
|
||||||
.class_init = pci_bus_class_init,
|
.class_init = pci_bus_class_init,
|
||||||
|
.interfaces = (InterfaceInfo[]) {
|
||||||
|
{ TYPE_FW_CFG_DATA_GENERATOR_INTERFACE },
|
||||||
|
{ }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const TypeInfo cxl_interface_info = {
|
static const TypeInfo cxl_interface_info = {
|
||||||
|
|
|
@ -1140,23 +1140,21 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
|
||||||
dev = qdev_new(TYPE_GPEX_HOST);
|
dev = qdev_new(TYPE_GPEX_HOST);
|
||||||
|
|
||||||
/* Set GPEX object properties for the virt machine */
|
/* Set GPEX object properties for the virt machine */
|
||||||
object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_BASE,
|
object_property_set_uint(OBJECT(dev), PCI_HOST_ECAM_BASE,
|
||||||
ecam_base, NULL);
|
ecam_base, NULL);
|
||||||
object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_SIZE,
|
object_property_set_int(OBJECT(dev), PCI_HOST_ECAM_SIZE,
|
||||||
ecam_size, NULL);
|
ecam_size, NULL);
|
||||||
object_property_set_uint(OBJECT(GPEX_HOST(dev)),
|
object_property_set_uint(OBJECT(dev), PCI_HOST_BELOW_4G_MMIO_BASE,
|
||||||
PCI_HOST_BELOW_4G_MMIO_BASE,
|
|
||||||
mmio_base, NULL);
|
mmio_base, NULL);
|
||||||
object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_BELOW_4G_MMIO_SIZE,
|
object_property_set_int(OBJECT(dev), PCI_HOST_BELOW_4G_MMIO_SIZE,
|
||||||
mmio_size, NULL);
|
mmio_size, NULL);
|
||||||
object_property_set_uint(OBJECT(GPEX_HOST(dev)),
|
object_property_set_uint(OBJECT(dev), PCI_HOST_ABOVE_4G_MMIO_BASE,
|
||||||
PCI_HOST_ABOVE_4G_MMIO_BASE,
|
|
||||||
high_mmio_base, NULL);
|
high_mmio_base, NULL);
|
||||||
object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ABOVE_4G_MMIO_SIZE,
|
object_property_set_int(OBJECT(dev), PCI_HOST_ABOVE_4G_MMIO_SIZE,
|
||||||
high_mmio_size, NULL);
|
high_mmio_size, NULL);
|
||||||
object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_BASE,
|
object_property_set_uint(OBJECT(dev), PCI_HOST_PIO_BASE,
|
||||||
pio_base, NULL);
|
pio_base, NULL);
|
||||||
object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_SIZE,
|
object_property_set_int(OBJECT(dev), PCI_HOST_PIO_SIZE,
|
||||||
pio_size, NULL);
|
pio_size, NULL);
|
||||||
|
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
||||||
|
@ -1189,7 +1187,7 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
|
||||||
gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i);
|
gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(GPEX_HOST(dev))->bus;
|
GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(dev)->bus;
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "hw/loader.h"
|
#include "hw/loader.h"
|
||||||
#include "hw/usb.h"
|
#include "hw/usb.h"
|
||||||
#include "hw/block/flash.h"
|
#include "hw/block/flash.h"
|
||||||
|
#include "exec/tswap.h"
|
||||||
|
|
||||||
#define FLASH_BASE 0x00000000
|
#define FLASH_BASE 0x00000000
|
||||||
#define FLASH_SIZE (16 * MiB)
|
#define FLASH_SIZE (16 * MiB)
|
||||||
|
|
|
@ -177,7 +177,7 @@ static const USBDesc desc = {
|
||||||
.str = desc_strings,
|
.str = desc_strings,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void usb_msd_packet_complete(MSDState *s)
|
static void usb_msd_packet_complete(MSDState *s, int status)
|
||||||
{
|
{
|
||||||
USBPacket *p = s->packet;
|
USBPacket *p = s->packet;
|
||||||
|
|
||||||
|
@ -187,6 +187,7 @@ static void usb_msd_packet_complete(MSDState *s)
|
||||||
* usb_packet_complete returns.
|
* usb_packet_complete returns.
|
||||||
*/
|
*/
|
||||||
trace_usb_msd_packet_complete();
|
trace_usb_msd_packet_complete();
|
||||||
|
p->status = status;
|
||||||
s->packet = NULL;
|
s->packet = NULL;
|
||||||
usb_packet_complete(&s->dev, p);
|
usb_packet_complete(&s->dev, p);
|
||||||
}
|
}
|
||||||
|
@ -196,8 +197,7 @@ static void usb_msd_fatal_error(MSDState *s)
|
||||||
trace_usb_msd_fatal_error();
|
trace_usb_msd_fatal_error();
|
||||||
|
|
||||||
if (s->packet) {
|
if (s->packet) {
|
||||||
s->packet->status = USB_RET_STALL;
|
usb_msd_packet_complete(s, USB_RET_STALL);
|
||||||
usb_msd_packet_complete(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -255,8 +255,8 @@ void usb_msd_transfer_data(SCSIRequest *req, uint32_t len)
|
||||||
usb_msd_copy_data(s, p);
|
usb_msd_copy_data(s, p);
|
||||||
p = s->packet;
|
p = s->packet;
|
||||||
if (p && p->actual_length == p->iov.size) {
|
if (p && p->actual_length == p->iov.size) {
|
||||||
p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
|
/* USB_RET_SUCCESS status clears previous ASYNC status */
|
||||||
usb_msd_packet_complete(s);
|
usb_msd_packet_complete(s, USB_RET_SUCCESS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,8 +295,8 @@ void usb_msd_command_complete(SCSIRequest *req, size_t resid)
|
||||||
s->mode = USB_MSDM_CSW;
|
s->mode = USB_MSDM_CSW;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p->status = USB_RET_SUCCESS; /* Clear previous ASYNC status */
|
/* USB_RET_SUCCESS status clears previous ASYNC status */
|
||||||
usb_msd_packet_complete(s);
|
usb_msd_packet_complete(s, USB_RET_SUCCESS);
|
||||||
} else if (s->data_len == 0) {
|
} else if (s->data_len == 0) {
|
||||||
s->mode = USB_MSDM_CSW;
|
s->mode = USB_MSDM_CSW;
|
||||||
}
|
}
|
||||||
|
@ -332,8 +332,7 @@ void usb_msd_handle_reset(USBDevice *dev)
|
||||||
assert(s->req == NULL);
|
assert(s->req == NULL);
|
||||||
|
|
||||||
if (s->packet) {
|
if (s->packet) {
|
||||||
s->packet->status = USB_RET_STALL;
|
usb_msd_packet_complete(s, USB_RET_STALL);
|
||||||
usb_msd_packet_complete(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&s->csw, 0, sizeof(s->csw));
|
memset(&s->csw, 0, sizeof(s->csw));
|
||||||
|
|
|
@ -30,10 +30,8 @@
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(XHCINecState, NEC_XHCI)
|
OBJECT_DECLARE_SIMPLE_TYPE(XHCINecState, NEC_XHCI)
|
||||||
|
|
||||||
struct XHCINecState {
|
struct XHCINecState {
|
||||||
/*< private >*/
|
|
||||||
XHCIPciState parent_obj;
|
XHCIPciState parent_obj;
|
||||||
/*< public >*/
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t intrs;
|
uint32_t intrs;
|
||||||
uint32_t slots;
|
uint32_t slots;
|
||||||
};
|
};
|
||||||
|
@ -51,7 +49,6 @@ static void nec_xhci_instance_init(Object *obj)
|
||||||
XHCIPciState *pci = XHCI_PCI(obj);
|
XHCIPciState *pci = XHCI_PCI(obj);
|
||||||
XHCINecState *nec = NEC_XHCI(obj);
|
XHCINecState *nec = NEC_XHCI(obj);
|
||||||
|
|
||||||
pci->xhci.flags = nec->flags;
|
|
||||||
pci->xhci.numintrs = nec->intrs;
|
pci->xhci.numintrs = nec->intrs;
|
||||||
pci->xhci.numslots = nec->slots;
|
pci->xhci.numslots = nec->slots;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,7 @@ static int xhci_pci_vmstate_post_load(void *opaque, int version_id)
|
||||||
PCIDevice *pci_dev = PCI_DEVICE(s);
|
PCIDevice *pci_dev = PCI_DEVICE(s);
|
||||||
int intr;
|
int intr;
|
||||||
|
|
||||||
for (intr = 0; intr < s->xhci.numintrs; intr++) {
|
for (intr = 0; intr < s->xhci.numintrs; intr++) {
|
||||||
if (s->xhci.intr[intr].msix_used) {
|
if (s->xhci.intr[intr].msix_used) {
|
||||||
msix_vector_use(pci_dev, intr);
|
msix_vector_use(pci_dev, intr);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -444,7 +444,7 @@ static bool handle_describe_pcr(VirtIONSM *vnsm, struct iovec *request,
|
||||||
* key = String("index"),
|
* key = String("index"),
|
||||||
* value = Uint8(pcr),
|
* value = Uint8(pcr),
|
||||||
* key = String("data"),
|
* key = String("data"),
|
||||||
* value = Byte_String(data),
|
* value = Byte_String(data) || String(data),
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
|
@ -504,14 +504,21 @@ static enum NSMResponseTypes get_nsm_extend_pcr_req(uint8_t *req, size_t len,
|
||||||
|
|
||||||
if (cbor_string_length(pair[i].key) == 4 &&
|
if (cbor_string_length(pair[i].key) == 4 &&
|
||||||
memcmp(str, "data", 4) == 0) {
|
memcmp(str, "data", 4) == 0) {
|
||||||
if (!cbor_isa_bytestring(pair[i].value)) {
|
if (cbor_isa_bytestring(pair[i].value)) {
|
||||||
|
str = cbor_bytestring_handle(pair[i].value);
|
||||||
|
if (!str) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
nsm_req->data_len = cbor_bytestring_length(pair[i].value);
|
||||||
|
} else if (cbor_isa_string(pair[i].value)) {
|
||||||
|
str = cbor_string_handle(pair[i].value);
|
||||||
|
if (!str) {
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
nsm_req->data_len = cbor_string_length(pair[i].value);
|
||||||
|
} else {
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
str = cbor_bytestring_handle(pair[i].value);
|
|
||||||
if (!str) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
nsm_req->data_len = cbor_bytestring_length(pair[i].value);
|
|
||||||
/*
|
/*
|
||||||
* nsm_req->data_len will be smaller than NSM_REQUEST_MAX_SIZE as
|
* nsm_req->data_len will be smaller than NSM_REQUEST_MAX_SIZE as
|
||||||
* we already check for the max request size before processing
|
* we already check for the max request size before processing
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define HW_XTENSA_BOOTPARAM_H
|
#define HW_XTENSA_BOOTPARAM_H
|
||||||
|
|
||||||
#include "exec/cpu-common.h"
|
#include "exec/cpu-common.h"
|
||||||
|
#include "exec/tswap.h"
|
||||||
|
|
||||||
#define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/
|
#define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/
|
||||||
#define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */
|
#define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "elf.h"
|
#include "elf.h"
|
||||||
#include "exec/memory.h"
|
#include "exec/memory.h"
|
||||||
|
#include "exec/tswap.h"
|
||||||
#include "hw/char/serial-mm.h"
|
#include "hw/char/serial-mm.h"
|
||||||
#include "net/net.h"
|
#include "net/net.h"
|
||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
|
|
|
@ -44,14 +44,14 @@ struct NitroEnclaveMachineState {
|
||||||
/* Machine state */
|
/* Machine state */
|
||||||
VirtIONSM *vnsm;
|
VirtIONSM *vnsm;
|
||||||
|
|
||||||
/* kernel + ramdisks + cmdline sha384 hash */
|
/* kernel + ramdisks + cmdline SHA384 hash */
|
||||||
uint8_t image_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
uint8_t image_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
||||||
/* kernel + boot ramdisk + cmdline sha384 hash */
|
/* kernel + boot ramdisk + cmdline SHA384 hash */
|
||||||
uint8_t bootstrap_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
uint8_t bootstrap_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
||||||
/* application ramdisk(s) hash */
|
/* application ramdisk(s) SHA384 hash */
|
||||||
uint8_t app_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
uint8_t app_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
||||||
/* certificate fingerprint hash */
|
/* certificate fingerprint SHA384 hash */
|
||||||
uint8_t fingerprint_sha384[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
uint8_t fingerprint_hash[QCRYPTO_HASH_DIGEST_LEN_SHA384];
|
||||||
bool signature_found;
|
bool signature_found;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "qom/object.h"
|
#include "qom/object.h"
|
||||||
#include "hw/ide/ahci.h"
|
#include "hw/ide/ahci.h"
|
||||||
#include "hw/pci/pci_device.h"
|
#include "hw/pci/pci_device.h"
|
||||||
|
#include "hw/irq.h"
|
||||||
|
|
||||||
#define TYPE_ICH9_AHCI "ich9-ahci"
|
#define TYPE_ICH9_AHCI "ich9-ahci"
|
||||||
OBJECT_DECLARE_SIMPLE_TYPE(AHCIPCIState, ICH9_AHCI)
|
OBJECT_DECLARE_SIMPLE_TYPE(AHCIPCIState, ICH9_AHCI)
|
||||||
|
@ -17,6 +18,7 @@ struct AHCIPCIState {
|
||||||
PCIDevice parent_obj;
|
PCIDevice parent_obj;
|
||||||
|
|
||||||
AHCIState ahci;
|
AHCIState ahci;
|
||||||
|
IRQState irq;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,8 +37,6 @@ typedef struct AHCIControlRegs {
|
||||||
} AHCIControlRegs;
|
} AHCIControlRegs;
|
||||||
|
|
||||||
typedef struct AHCIState {
|
typedef struct AHCIState {
|
||||||
DeviceState *container;
|
|
||||||
|
|
||||||
AHCIDevice *dev;
|
AHCIDevice *dev;
|
||||||
AHCIControlRegs control_regs;
|
AHCIControlRegs control_regs;
|
||||||
MemoryRegion mem;
|
MemoryRegion mem;
|
||||||
|
|
|
@ -30,8 +30,9 @@ struct FWCfgDataGeneratorClass {
|
||||||
* @obj: the object implementing this interface
|
* @obj: the object implementing this interface
|
||||||
* @errp: pointer to a NULL-initialized error object
|
* @errp: pointer to a NULL-initialized error object
|
||||||
*
|
*
|
||||||
* Returns: reference to a byte array containing the data on success,
|
* Returns: A byte array containing data to add, or NULL without
|
||||||
* or NULL on error.
|
* @errp set if no data is required, or NULL with @errp
|
||||||
|
* set on failure.
|
||||||
*
|
*
|
||||||
* The caller should release the reference when no longer
|
* The caller should release the reference when no longer
|
||||||
* required.
|
* required.
|
||||||
|
@ -291,33 +292,28 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, void *data,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fw_cfg_add_from_generator:
|
* fw_cfg_add_file_from_generator:
|
||||||
* @s: fw_cfg device being modified
|
* @s: fw_cfg device being modified
|
||||||
* @filename: name of new fw_cfg file item
|
* @filename: name of new fw_cfg file item
|
||||||
* @gen_id: name of object implementing FW_CFG_DATA_GENERATOR interface
|
* @part: name of object implementing FW_CFG_DATA_GENERATOR interface
|
||||||
|
* @parent: the object in which to resolve the @part
|
||||||
* @errp: pointer to a NULL initialized error object
|
* @errp: pointer to a NULL initialized error object
|
||||||
*
|
*
|
||||||
* Add a new NAMED fw_cfg item with the content generated from the
|
* If the @part object generates content, add a new NAMED fw_cfg item with it.
|
||||||
* @gen_id object. The data generated by the @gen_id object is copied
|
* The data generated by the @part object is copied into the data structure of
|
||||||
* into the data structure of the fw_cfg device.
|
* the fw_cfg device.
|
||||||
* The next available (unused) selector key starting at FW_CFG_FILE_FIRST
|
* The next available (unused) selector key starting at FW_CFG_FILE_FIRST
|
||||||
* will be used; also, a new entry will be added to the file directory
|
* will be used; also, a new entry will be added to the file directory
|
||||||
* structure residing at key value FW_CFG_FILE_DIR, containing the item name,
|
* structure residing at key value FW_CFG_FILE_DIR, containing the item name,
|
||||||
* data size, and assigned selector key value.
|
* data size, and assigned selector key value.
|
||||||
*
|
*
|
||||||
|
* If the @part object does not generate content, no fw_cfg item is added.
|
||||||
|
*
|
||||||
* Returns: %true on success, %false on error.
|
* Returns: %true on success, %false on error.
|
||||||
*/
|
*/
|
||||||
bool fw_cfg_add_from_generator(FWCfgState *s, const char *filename,
|
bool fw_cfg_add_file_from_generator(FWCfgState *s,
|
||||||
const char *gen_id, Error **errp);
|
Object *parent, const char *part,
|
||||||
|
const char *filename, Error **errp);
|
||||||
/**
|
|
||||||
* fw_cfg_add_extra_pci_roots:
|
|
||||||
* @bus: main pci root bus to be scanned from
|
|
||||||
* @s: fw_cfg device being modified
|
|
||||||
*
|
|
||||||
* Add a new fw_cfg item...
|
|
||||||
*/
|
|
||||||
void fw_cfg_add_extra_pci_roots(PCIBus *bus, FWCfgState *s);
|
|
||||||
|
|
||||||
FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
|
FWCfgState *fw_cfg_init_io_dma(uint32_t iobase, uint32_t dma_iobase,
|
||||||
AddressSpace *dma_as);
|
AddressSpace *dma_as);
|
||||||
|
|
|
@ -297,6 +297,9 @@ int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
|
||||||
uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus);
|
uint32_t pci_bus_get_slot_reserved_mask(PCIBus *bus);
|
||||||
void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask);
|
void pci_bus_set_slot_reserved_mask(PCIBus *bus, uint32_t mask);
|
||||||
void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask);
|
void pci_bus_clear_slot_reserved_mask(PCIBus *bus, uint32_t mask);
|
||||||
|
bool pci_bus_add_fw_cfg_extra_pci_roots(FWCfgState *fw_cfg,
|
||||||
|
PCIBus *bus,
|
||||||
|
Error **errp);
|
||||||
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
|
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
|
||||||
static inline int pci_swizzle(int slot, int pin)
|
static inline int pci_swizzle(int slot, int pin)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1184,7 +1184,8 @@ static int parse_fw_cfg(void *opaque, QemuOpts *opts, Error **errp)
|
||||||
size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
|
size = strlen(str); /* NUL terminator NOT included in fw_cfg blob */
|
||||||
buf = g_memdup(str, size);
|
buf = g_memdup(str, size);
|
||||||
} else if (nonempty_str(gen_id)) {
|
} else if (nonempty_str(gen_id)) {
|
||||||
if (!fw_cfg_add_from_generator(fw_cfg, name, gen_id, errp)) {
|
if (!fw_cfg_add_file_from_generator(fw_cfg, object_get_objects_root(),
|
||||||
|
gen_id, name, errp)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue