Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging virtio,pci,pc: features, fixes intel_iommu: SVM support vhost: support for indirect descriptors in shadow virtqueue vhost-user: vhost-user-spi support vhost-user-blk inflight migration support vhost-user-blk inflight migration support misc fixes in pci, vhost, virtio, acpi, cxl cleanups in acpi/ghes Signed-off-by: Michael S. Tsirkin <mst@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQFDBAABCgAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmmEa9APHG1zdEByZWRo # YXQuY29tAAoJECgfDbjSjVRpqj8H/iBqAHZSTmAdBJgoLnmgoTLB01J9aUTrQU2H # BHKyrd+G3m54pwjgUNN5ieZARtlXscigf6fr0Gq2wrc8/kV/O5G5jViw9+1Bo8nW # OkLDW45nDzZGhap4oUedV+PJ3fCuW2fC8Jyb1n8OGlkadbhq0NU6GtqiEx6/7QIh # hk5WUDE/3LH4cTp8qNtr0/nYfM4FZk2sjq7aRyg4cz/uC7rIAFRq7BCZ/dfRqMh/ # T+rLnizSSAg9PFMd8slWqoxOGF9NzT9LIoDSkAlso1L9lUekUSNoUblhlWDrRlLn # DEEqqGCVounfBzA95WrTRmvWs6JodppjjAjI0M4isrMKGXXg8dg= # =HdgY # -----END PGP SIGNATURE----- # gpg: Signature made Thu Feb 5 10:07:12 2026 GMT # gpg: using RSA key 5D09FD0871C8F85B94CA8A0D281F0DB8D28D5469 # gpg: issuer "mst@redhat.com" # gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>" [full] # gpg: aka "Michael S. Tsirkin <mst@redhat.com>" [full] # Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67 # Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469 * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (38 commits) hw/cxl: Take into account how many media operations are requested for param check hw/cxl: Check for overflow on santize media as both base and offset 64bit. vhost-user-blk: support inter-host inflight migration vhost: add vmstate for inflight region with inner buffer vmstate: introduce VMSTATE_VBUFFER_UINT64 vhost-user: introduce protocol feature for skip drain on GET_VRING_BASE vhost-user.rst: specify vhost-user back-end action on GET_VRING_BASE virtio-gpu: use consistent error checking for virtio_gpu_create_mapping_iov virtio-gpu: fix error handling in virgl_cmd_resource_create_blob virtio-pmem: ignore empty queue notifications virtio-gpu-virgl: correct parent for blob memory region MAINTAINERS: Update VIOT maintainer cryptodev-builtin: Limit the maximum size hw/virtio/virtio-crypto: verify asym request size virtio-spi: Add vhost-user-spi device support standard-headers: Update virtio_spi.h from Linux v6.18-rc3 q35: Fix migration of SMRAM state pcie_sriov: Fix PCI_SRIOV_* accesses in pcie_sriov_pf_exit() virtio: Fix crash when sriov-pf is set for non-PCI-Express device virtio-dmabuf: Ensure UUID persistence for hash table insertion ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/MAINTAINERS b/MAINTAINERS index ebd27cd..65ac60b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -1249,11 +1249,13 @@ F: include/hw/net/ftgmac100.h F: docs/system/arm/aspeed.rst F: docs/system/arm/fby35.rst +F: docs/specs/aspeed* F: tests/functional/*/*aspeed* F: tests/*/*aspeed* F: tests/*/*ast2700* F: hw/arm/fby35.c F: pc-bios/ast27x0_bootrom.bin +F: roms/vbootrom NRF51 M: Joel Stanley <joel@jms.id.au>
diff --git a/backends/igvm-cfg.c b/backends/igvm-cfg.c index d00acf3..64589ca 100644 --- a/backends/igvm-cfg.c +++ b/backends/igvm-cfg.c
@@ -11,9 +11,15 @@ #include "qemu/osdep.h" -#include "system/igvm-cfg.h" #include "system/igvm.h" +#include "system/igvm-cfg.h" +#include "system/igvm-internal.h" +#include "system/reset.h" #include "qom/object_interfaces.h" +#include "hw/core/qdev.h" +#include "hw/core/boards.h" + +#include "trace.h" static char *get_igvm(Object *obj, Error **errp) { @@ -28,24 +34,78 @@ igvm->filename = g_strdup(value); } +static ResettableState *igvm_reset_state(Object *obj) +{ + IgvmCfg *igvm = IGVM_CFG(obj); + return &igvm->reset_state; +} + +static void igvm_reset_enter(Object *obj, ResetType type) +{ + trace_igvm_reset_enter(type); +} + +static void igvm_reset_hold(Object *obj, ResetType type) +{ + MachineState *ms = MACHINE(qdev_get_machine()); + IgvmCfg *igvm = IGVM_CFG(obj); + + trace_igvm_reset_hold(type); + + qigvm_process_file(igvm, ms, false, &error_fatal); +} + +static void igvm_reset_exit(Object *obj, ResetType type) +{ + trace_igvm_reset_exit(type); +} + +static void igvm_complete(UserCreatable *uc, Error **errp) +{ + IgvmCfg *igvm = IGVM_CFG(uc); + + igvm->file = qigvm_file_init(igvm->filename, errp); +} + OBJECT_DEFINE_TYPE_WITH_INTERFACES(IgvmCfg, igvm_cfg, IGVM_CFG, OBJECT, - { TYPE_USER_CREATABLE }, { NULL }) + { TYPE_USER_CREATABLE }, + { TYPE_RESETTABLE_INTERFACE }, + { NULL }) static void igvm_cfg_class_init(ObjectClass *oc, const void *data) { IgvmCfgClass *igvmc = IGVM_CFG_CLASS(oc); + ResettableClass *rc = RESETTABLE_CLASS(oc); + UserCreatableClass *uc = USER_CREATABLE_CLASS(oc); object_class_property_add_str(oc, "file", get_igvm, set_igvm); object_class_property_set_description(oc, "file", "Set the IGVM filename to use"); igvmc->process = qigvm_process_file; + + rc->get_state = igvm_reset_state; + rc->phases.enter = igvm_reset_enter; + rc->phases.hold = igvm_reset_hold; + rc->phases.exit = igvm_reset_exit; + + uc->complete = igvm_complete; } static void igvm_cfg_init(Object *obj) { + IgvmCfg *igvm = IGVM_CFG(obj); + + igvm->file = -1; + qemu_register_resettable(obj); } static void igvm_cfg_finalize(Object *obj) { + IgvmCfg *igvm = IGVM_CFG(obj); + + qemu_unregister_resettable(obj); + if (igvm->file >= 0) { + igvm_free(igvm->file); + } }
diff --git a/backends/igvm.c b/backends/igvm.c index 905bd8d..b01a19b 100644 --- a/backends/igvm.c +++ b/backends/igvm.c
@@ -12,21 +12,20 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "qemu/target-info-qapi.h" #include "system/igvm.h" +#include "system/igvm-cfg.h" +#include "system/igvm-internal.h" #include "system/memory.h" #include "system/address-spaces.h" #include "hw/core/cpu.h" +#include "trace.h" + #include <igvm/igvm.h> #include <igvm/igvm_defs.h> -typedef struct QIgvmParameterData { - QTAILQ_ENTRY(QIgvmParameterData) next; - uint8_t *data; - uint32_t size; - uint32_t index; -} QIgvmParameterData; /* * Some directives are specific to particular confidential computing platforms. @@ -62,36 +61,19 @@ #define IGVM_SEV_ID_BLOCK_VERSION 1 -/* - * QIgvm contains the information required during processing - * of a single IGVM file. - */ -typedef struct QIgvm { - IgvmHandle file; - ConfidentialGuestSupport *cgs; - ConfidentialGuestSupportClass *cgsc; - uint32_t compatibility_mask; - unsigned current_header_index; - QTAILQ_HEAD(, QIgvmParameterData) parameter_data; - IgvmPlatformType platform_type; - - /* - * SEV-SNP platforms can contain an ID block and authentication - * that should be verified by the guest. - */ - struct sev_id_block *id_block; - struct sev_id_authentication *id_auth; - - /* Define the guest policy for SEV guests */ - uint64_t sev_policy; - - /* These variables keep track of contiguous page regions */ - IGVM_VHS_PAGE_DATA region_prev_page_data; - uint64_t region_start; - unsigned region_start_index; - unsigned region_last_index; - unsigned region_page_count; -} QIgvm; +QIgvmParameterData* +qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index) +{ + QIgvmParameterData *param_entry; + QTAILQ_FOREACH(param_entry, &igvm->parameter_data, next) + { + if (param_entry->index == parameter_area_index) { + return param_entry; + } + } + warn_report("IGVM: No parameter area for index %u", parameter_area_index); + return NULL; +} static int qigvm_directive_page_data(QIgvm *ctx, const uint8_t *header_data, Error **errp); @@ -146,6 +128,8 @@ qigvm_directive_snp_id_block }, { IGVM_VHT_GUEST_POLICY, IGVM_HEADER_SECTION_INITIALIZATION, qigvm_initialization_guest_policy }, + { IGVM_VHT_MADT, IGVM_HEADER_SECTION_DIRECTIVE, + qigvm_directive_madt }, }; static int qigvm_handler(QIgvm *ctx, uint32_t type, Error **errp) @@ -220,7 +204,8 @@ g_autofree char *region_name = g_strdup_printf("igvm.%X", region_identifier); igvm_pages = g_new0(MemoryRegion, 1); - if (ctx->cgs && ctx->cgs->require_guest_memfd) { + if (ctx->machine_state->cgs && + ctx->machine_state->cgs->require_guest_memfd) { if (!memory_region_init_ram_guest_memfd(igvm_pages, NULL, region_name, size, errp)) { return NULL; @@ -340,7 +325,7 @@ * If a confidential guest support object is provided then use it to set the * guest state. */ - if (ctx->cgs) { + if (ctx->machine_state->cgs) { cgs_page_type = qigvm_type_to_cgs_type(page_type, flags->unmeasured, zero); if (cgs_page_type < 0) { @@ -442,7 +427,7 @@ data = (uint8_t *)igvm_get_buffer(ctx->file, data_handle); - if (ctx->cgs) { + if (ctx->machine_state->cgs) { result = ctx->cgsc->set_guest_state( vp_context->gpa, data, igvm_get_buffer_size(ctx->file, data_handle), CGS_PAGE_TYPE_VMSA, vp_context->vp_index, errp); @@ -494,31 +479,31 @@ return 0; } - QTAILQ_FOREACH(param_entry, &ctx->parameter_data, next) - { - if (param_entry->index == param->parameter_area_index) { - region = qigvm_prepare_memory(ctx, param->gpa, param_entry->size, - ctx->current_header_index, errp); - if (!region) { - return -1; - } - memcpy(region, param_entry->data, param_entry->size); - g_free(param_entry->data); - param_entry->data = NULL; + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; + } - /* - * If a confidential guest support object is provided then use it to - * set the guest state. - */ - if (ctx->cgs) { - result = ctx->cgsc->set_guest_state(param->gpa, region, - param_entry->size, - CGS_PAGE_TYPE_UNMEASURED, 0, - errp); - if (result < 0) { - return -1; - } - } + region = qigvm_prepare_memory(ctx, param->gpa, param_entry->size, + ctx->current_header_index, errp); + if (!region) { + return -1; + } + memcpy(region, param_entry->data, param_entry->size); + g_free(param_entry->data); + param_entry->data = NULL; + + /* + * If a confidential guest support object is provided then use it to + * set the guest state. + */ + if (ctx->machine_state->cgs) { + result = ctx->cgsc->set_guest_state(param->gpa, region, + param_entry->size, + CGS_PAGE_TYPE_UNMEASURED, 0, + errp); + if (result < 0) { + return -1; } } return 0; @@ -553,7 +538,7 @@ ConfidentialGuestMemoryMapEntry cgmm_entry; int retval = 0; - if (ctx->cgs && ctx->cgsc->get_mem_map_entry) { + if (ctx->machine_state->cgs && ctx->cgsc->get_mem_map_entry) { get_mem_map_entry = ctx->cgsc->get_mem_map_entry; } else if (target_arch() == SYS_EMU_TARGET_X86_64) { @@ -567,58 +552,54 @@ } /* Find the parameter area that should hold the memory map */ - QTAILQ_FOREACH(param_entry, &ctx->parameter_data, next) - { - if (param_entry->index == param->parameter_area_index) { - max_entry_count = - param_entry->size / sizeof(IGVM_VHS_MEMORY_MAP_ENTRY); - mm_entry = (IGVM_VHS_MEMORY_MAP_ENTRY *)param_entry->data; + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; + } - retval = get_mem_map_entry(entry, &cgmm_entry, errp); - while (retval == 0) { - if (entry >= max_entry_count) { - error_setg( - errp, - "IGVM: guest memory map size exceeds parameter area defined in IGVM file"); - return -1; - } - mm_entry[entry].starting_gpa_page_number = cgmm_entry.gpa >> 12; - mm_entry[entry].number_of_pages = cgmm_entry.size >> 12; + max_entry_count = param_entry->size / sizeof(IGVM_VHS_MEMORY_MAP_ENTRY); + mm_entry = (IGVM_VHS_MEMORY_MAP_ENTRY *)param_entry->data; - switch (cgmm_entry.type) { - case CGS_MEM_RAM: - mm_entry[entry].entry_type = - IGVM_MEMORY_MAP_ENTRY_TYPE_MEMORY; - break; - case CGS_MEM_RESERVED: - mm_entry[entry].entry_type = - IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED; - break; - case CGS_MEM_ACPI: - mm_entry[entry].entry_type = - IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED; - break; - case CGS_MEM_NVS: - mm_entry[entry].entry_type = - IGVM_MEMORY_MAP_ENTRY_TYPE_PERSISTENT; - break; - case CGS_MEM_UNUSABLE: - mm_entry[entry].entry_type = - IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED; - break; - } - retval = get_mem_map_entry(++entry, &cgmm_entry, errp); - } - if (retval < 0) { - return retval; - } - /* The entries need to be sorted */ - qsort(mm_entry, entry, sizeof(IGVM_VHS_MEMORY_MAP_ENTRY), - qigvm_cmp_mm_entry); + retval = get_mem_map_entry(entry, &cgmm_entry, errp); + while (retval == 0) { + if (entry >= max_entry_count) { + error_setg( + errp, + "IGVM: guest memory map size exceeds parameter area defined " + "in IGVM file"); + return -1; + } + mm_entry[entry].starting_gpa_page_number = cgmm_entry.gpa >> 12; + mm_entry[entry].number_of_pages = cgmm_entry.size >> 12; + switch (cgmm_entry.type) { + case CGS_MEM_RAM: + mm_entry[entry].entry_type = IGVM_MEMORY_MAP_ENTRY_TYPE_MEMORY; + break; + case CGS_MEM_RESERVED: + mm_entry[entry].entry_type = + IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED; + break; + case CGS_MEM_ACPI: + mm_entry[entry].entry_type = + IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED; + break; + case CGS_MEM_NVS: + mm_entry[entry].entry_type = IGVM_MEMORY_MAP_ENTRY_TYPE_PERSISTENT; + break; + case CGS_MEM_UNUSABLE: + mm_entry[entry].entry_type = + IGVM_MEMORY_MAP_ENTRY_TYPE_PLATFORM_RESERVED; break; } + retval = get_mem_map_entry(++entry, &cgmm_entry, errp); } + if (retval < 0) { + return retval; + } + /* The entries need to be sorted */ + qsort(mm_entry, entry, sizeof(IGVM_VHS_MEMORY_MAP_ENTRY), + qigvm_cmp_mm_entry); return 0; } @@ -630,18 +611,18 @@ uint32_t *vp_count; CPUState *cpu; - QTAILQ_FOREACH(param_entry, &ctx->parameter_data, next) - { - if (param_entry->index == param->parameter_area_index) { - vp_count = (uint32_t *)(param_entry->data + param->byte_offset); - *vp_count = 0; - CPU_FOREACH(cpu) - { - (*vp_count)++; - } - break; - } + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; } + + vp_count = (uint32_t *)(param_entry->data + param->byte_offset); + *vp_count = 0; + CPU_FOREACH(cpu) + { + (*vp_count)++; + } + return 0; } @@ -653,15 +634,15 @@ QIgvmParameterData *param_entry; IgvmEnvironmentInfo *environmental_state; - QTAILQ_FOREACH(param_entry, &ctx->parameter_data, next) - { - if (param_entry->index == param->parameter_area_index) { - environmental_state = - (IgvmEnvironmentInfo *)(param_entry->data + param->byte_offset); - environmental_state->memory_is_shared = 1; - break; - } + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; } + + environmental_state = + (IgvmEnvironmentInfo *)(param_entry->data + param->byte_offset); + environmental_state->memory_is_shared = 1; + return 0; } @@ -683,7 +664,7 @@ if (!region) { return -1; } - if (ctx->cgs) { + if (ctx->machine_state->cgs) { result = ctx->cgsc->set_guest_state(mem->gpa, region, mem->number_of_bytes, CGS_PAGE_TYPE_REQUIRED_MEMORY, 0, errp); @@ -801,14 +782,14 @@ sizeof( IGVM_VHS_VARIABLE_HEADER)); if ((platform->platform_type == IGVM_PLATFORM_TYPE_SEV_ES) && - ctx->cgs) { + ctx->machine_state->cgs) { if (ctx->cgsc->check_support( CGS_PLATFORM_SEV_ES, platform->platform_version, platform->highest_vtl, platform->shared_gpa_boundary)) { compatibility_mask_sev_es = platform->compatibility_mask; } } else if ((platform->platform_type == IGVM_PLATFORM_TYPE_SEV) && - ctx->cgs) { + ctx->machine_state->cgs) { if (ctx->cgsc->check_support( CGS_PLATFORM_SEV, platform->platform_version, platform->highest_vtl, platform->shared_gpa_boundary)) { @@ -816,7 +797,7 @@ } } else if ((platform->platform_type == IGVM_PLATFORM_TYPE_SEV_SNP) && - ctx->cgs) { + ctx->machine_state->cgs) { if (ctx->cgsc->check_support( CGS_PLATFORM_SEV_SNP, platform->platform_version, platform->highest_vtl, platform->shared_gpa_boundary)) { @@ -867,7 +848,7 @@ return 0; } -static IgvmHandle qigvm_file_init(char *filename, Error **errp) +IgvmHandle qigvm_file_init(char *filename, Error **errp) { IgvmHandle igvm; g_autofree uint8_t *buf = NULL; @@ -884,10 +865,12 @@ error_setg(errp, "Unable to parse IGVM file %s: %d", filename, igvm); return -1; } + + trace_igvm_file_loaded(filename, igvm); return igvm; } -int qigvm_process_file(IgvmCfg *cfg, ConfidentialGuestSupport *cgs, +int qigvm_process_file(IgvmCfg *cfg, MachineState *machine_state, bool onlyVpContext, Error **errp) { int32_t header_count; @@ -896,18 +879,23 @@ QIgvm ctx; memset(&ctx, 0, sizeof(ctx)); - ctx.file = qigvm_file_init(cfg->filename, errp); - if (ctx.file < 0) { + if (cfg->file < 0) { + error_setg(errp, "No IGVM file loaded."); return -1; } + ctx.file = cfg->file; + trace_igvm_process_file(cfg->file, onlyVpContext); + + ctx.machine_state = machine_state; /* * The ConfidentialGuestSupport object is optional and allows a confidential * guest platform to perform extra processing, such as page measurement, on * IGVM directives. */ - ctx.cgs = cgs; - ctx.cgsc = cgs ? CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(cgs) : NULL; + ctx.cgsc = machine_state->cgs ? + CONFIDENTIAL_GUEST_SUPPORT_GET_CLASS(machine_state->cgs) : + NULL; /* * Check that the IGVM file provides configuration for the current @@ -990,7 +978,5 @@ g_free(ctx.id_auth); cleanup: - igvm_free(ctx.file); - return retval; }
diff --git a/backends/trace-events b/backends/trace-events index 14a7ecf..8dc64a2 100644 --- a/backends/trace-events +++ b/backends/trace-events
@@ -23,3 +23,10 @@ iommufd_backend_invalidate_cache(int iommufd, uint32_t id, uint32_t data_type, uint32_t entry_len, uint32_t entry_num, uint32_t done_num, uint64_t data_ptr, int ret) " iommufd=%d id=%u data_type=%u entry_len=%u entry_num=%u done_num=%u data_ptr=0x%"PRIx64" (%d)" iommufd_backend_alloc_viommu(int iommufd, uint32_t dev_id, uint32_t type, uint32_t hwpt_id, uint32_t viommu_id, int ret) " iommufd=%d type=%u dev_id=%u hwpt_id=%u viommu_id=%u (%d)" iommufd_backend_alloc_vdev(int iommufd, uint32_t dev_id, uint32_t viommu_id, uint64_t virt_id, uint32_t vdev_id, int ret) " iommufd=%d dev_id=%u viommu_id=%u virt_id=0x%"PRIx64" vdev_id=%u (%d)" + +# igvm-cfg.c +igvm_reset_enter(int type) "type=%u" +igvm_reset_hold(int type) "type=%u" +igvm_reset_exit(int type) "type=%u" +igvm_file_loaded(const char *fn, int32_t handle) "fn=%s, handle=0x%x" +igvm_process_file(int32_t handle, bool context_only) "handle=0x%x context-only=%d"
diff --git a/disas/riscv.c b/disas/riscv.c index 85cd2a9..6f26674 100644 --- a/disas/riscv.c +++ b/disas/riscv.c
@@ -5409,7 +5409,7 @@ /* disassemble instruction */ static GString *disasm_inst(rv_isa isa, uint64_t pc, rv_inst inst, - RISCVCPUConfig *cfg) + const RISCVCPUConfig *cfg) { rv_decode dec = { 0 }; dec.pc = pc; @@ -5509,7 +5509,8 @@ } g_autoptr(GString) str = - disasm_inst(isa, memaddr, inst, (RISCVCPUConfig *)info->target_info); + disasm_inst(isa, memaddr, inst, + (const RISCVCPUConfig *)info->target_info); (*info->fprintf_func)(info->stream, "%s", str->str); return len;
diff --git a/disas/riscv.h b/disas/riscv.h index d211700..379e642 100644 --- a/disas/riscv.h +++ b/disas/riscv.h
@@ -189,7 +189,7 @@ } rv_opcode_data; typedef struct { - RISCVCPUConfig *cfg; + const RISCVCPUConfig *cfg; uint64_t pc; uint64_t inst; const rv_opcode_data *opcode_data;
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst index 97e14b7..d0054a7 100644 --- a/docs/system/arm/aspeed.rst +++ b/docs/system/arm/aspeed.rst
@@ -350,11 +350,9 @@ .. code-block:: bash IMGDIR=ast2700-default - UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin) $ qemu-system-aarch64 -M ast2700-evb \ - -device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot-nodtb.bin \ - -device loader,force-raw=on,addr=$((0x400000000 + ${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \ + -device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot.bin \ -device loader,force-raw=on,addr=0x430000000,file=${IMGDIR}/bl31.bin \ -device loader,force-raw=on,addr=0x430080000,file=${IMGDIR}/optee/tee-raw.bin \ -device loader,cpu-num=0,addr=0x430000000 \ @@ -409,11 +407,9 @@ .. code-block:: bash IMGDIR=ast2700-default - UBOOT_SIZE=$(stat --format=%s -L ${IMGDIR}/u-boot-nodtb.bin) $ qemu-system-aarch64 -M ast2700fc \ - -device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot-nodtb.bin \ - -device loader,force-raw=on,addr=$((0x400000000 + ${UBOOT_SIZE})),file=${IMGDIR}/u-boot.dtb \ + -device loader,force-raw=on,addr=0x400000000,file=${IMGDIR}/u-boot.bin \ -device loader,force-raw=on,addr=0x430000000,file=${IMGDIR}/bl31.bin \ -device loader,force-raw=on,addr=0x430080000,file=${IMGDIR}/optee/tee-raw.bin \ -device loader,cpu-num=0,addr=0x430000000 \
diff --git a/docs/system/igvm.rst b/docs/system/igvm.rst index 79508d9..9db8ae4 100644 --- a/docs/system/igvm.rst +++ b/docs/system/igvm.rst
@@ -166,8 +166,8 @@ ---------- [1] AMD64 Architecture Programmer's Manual, Volume 2: System Programming - Rev 3.41 - https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf + Rev 3.43 + https://docs.amd.com/v/u/en-US/24593_3.43 [2] ``buildigvm`` - A tool to build example IGVM files containing OVMF firmware - https://github.com/roy-hopkins/buildigvm \ No newline at end of file + https://gitlab.com/qemu-project/buildigvm
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index dad4cfc..ea1c415 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c
@@ -22,6 +22,7 @@ #include "qemu/osdep.h" #include <glib/gprintf.h> #include "hw/acpi/aml-build.h" +#include "hw/acpi/acpi.h" #include "qemu/bswap.h" #include "qemu/bitops.h" #include "system/numa.h" @@ -1741,6 +1742,7 @@ uint32_t table_len = desc->array->len - desc->table_offset; uint32_t table_len_le = cpu_to_le32(table_len); gchar *len_ptr = &desc->array->data[desc->table_offset + 4]; + uint8_t *table; /* patch "Length" field that has been reserved by acpi_table_begin() * to the actual length, i.e. accumulated table length from @@ -1748,8 +1750,14 @@ */ memcpy(len_ptr, &table_len_le, sizeof table_len_le); - bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE, - desc->table_offset, table_len, desc->table_offset + checksum_offset); + if (linker != NULL) { + bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE, + desc->table_offset, table_len, + desc->table_offset + checksum_offset); + } else { + table = (uint8_t *) &desc->array->data[desc->table_offset]; + table[checksum_offset] = acpi_checksum(table, table_len); + } } void *acpi_data_push(GArray *table_data, unsigned size)
diff --git a/hw/acpi/core.c b/hw/acpi/core.c index d9979b0..6b65e58 100644 --- a/hw/acpi/core.c +++ b/hw/acpi/core.c
@@ -83,7 +83,10 @@ return true; } -static int acpi_checksum(const uint8_t *data, int len) +/* Calculate the ACPI checksum value so that if used in the corresponding + * header field, the ACPI checksum verification will be successful. + */ +int acpi_checksum(const uint8_t *data, int len) { int sum, i; sum = 0;
diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c index fd3af30..3cc75bb 100644 --- a/hw/adc/aspeed_adc.c +++ b/hw/adc/aspeed_adc.c
@@ -228,7 +228,8 @@ qemu_log_mask(LOG_UNIMP, "%s: engine[%u]: " "0x%" HWADDR_PRIx " 0x%" PRIx64 "\n", __func__, s->engine_id, addr, value); - break; + /* Do not update the regs[] array */ + return; } s->regs[reg] = value;
diff --git a/hw/arm/aspeed_ast1700.c b/hw/arm/aspeed_ast1700.c new file mode 100644 index 0000000..e90302c --- /dev/null +++ b/hw/arm/aspeed_ast1700.c
@@ -0,0 +1,276 @@ +/* + * ASPEED AST1700 IO Expander + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/core/boards.h" +#include "qom/object.h" +#include "qapi/error.h" +#include "hw/core/qdev-properties.h" +#include "hw/arm/aspeed_ast1700.h" + +#define AST2700_SOC_LTPI_SIZE 0x01000000 +#define AST1700_SOC_SRAM_SIZE 0x00040000 +#define AST1700_SOC_I3C_SIZE 0x00010000 + +enum { + ASPEED_AST1700_DEV_SPI0, + ASPEED_AST1700_DEV_PWM, + ASPEED_AST1700_DEV_SRAM, + ASPEED_AST1700_DEV_ADC, + ASPEED_AST1700_DEV_SCU, + ASPEED_AST1700_DEV_GPIO, + ASPEED_AST1700_DEV_SGPIOM0, + ASPEED_AST1700_DEV_SGPIOM1, + ASPEED_AST1700_DEV_I2C, + ASPEED_AST1700_DEV_I3C, + ASPEED_AST1700_DEV_UART12, + ASPEED_AST1700_DEV_LTPI_CTRL, + ASPEED_AST1700_DEV_WDT, + ASPEED_AST1700_DEV_SPI0_MEM, +}; + +static const hwaddr aspeed_ast1700_io_memmap[] = { + [ASPEED_AST1700_DEV_SPI0] = 0x00030000, + [ASPEED_AST1700_DEV_PWM] = 0x000C0000, + [ASPEED_AST1700_DEV_SRAM] = 0x00BC0000, + [ASPEED_AST1700_DEV_ADC] = 0x00C00000, + [ASPEED_AST1700_DEV_SCU] = 0x00C02000, + [ASPEED_AST1700_DEV_GPIO] = 0x00C0B000, + [ASPEED_AST1700_DEV_SGPIOM0] = 0x00C0C000, + [ASPEED_AST1700_DEV_SGPIOM1] = 0x00C0D000, + [ASPEED_AST1700_DEV_I2C] = 0x00C0F000, + [ASPEED_AST1700_DEV_I3C] = 0x00C20000, + [ASPEED_AST1700_DEV_UART12] = 0x00C33B00, + [ASPEED_AST1700_DEV_LTPI_CTRL] = 0x00C34000, + [ASPEED_AST1700_DEV_WDT] = 0x00C37000, + [ASPEED_AST1700_DEV_SPI0_MEM] = 0x04000000, +}; + +static void aspeed_ast1700_realize(DeviceState *dev, Error **errp) +{ + AspeedAST1700SoCState *s = ASPEED_AST1700(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + char dev_name[32]; + + if (!s->dram_mr) { + error_setg(errp, TYPE_ASPEED_AST1700 ": 'dram' link not set"); + return; + } + + /* Occupy memory space for all controllers in AST1700 */ + memory_region_init(&s->iomem, OBJECT(s), TYPE_ASPEED_AST1700, + AST2700_SOC_LTPI_SIZE); + sysbus_init_mmio(sbd, &s->iomem); + + /* SRAM */ + snprintf(dev_name, sizeof(dev_name), "aspeed.ioexp-sram.%d", s->board_idx); + memory_region_init_ram(&s->sram, OBJECT(s), dev_name, + AST1700_SOC_SRAM_SIZE, errp); + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_SRAM], + &s->sram); + + /* UART */ + qdev_prop_set_uint8(DEVICE(&s->uart), "regshift", 2); + qdev_prop_set_uint32(DEVICE(&s->uart), "baudbase", 38400); + qdev_prop_set_uint8(DEVICE(&s->uart), "endianness", DEVICE_LITTLE_ENDIAN); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_UART12], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0)); + + /* SPI */ + object_property_set_link(OBJECT(&s->spi), "dram", + OBJECT(s->dram_mr), errp); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_SPI0], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->spi), 0)); + + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_SPI0_MEM], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->spi), 1)); + + /* ADC */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->adc), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_ADC], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->adc), 0)); + + /* SCU */ + qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", + s->silicon_rev); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_SCU], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->scu), 0)); + + /* GPIO */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->gpio), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_GPIO], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0)); + + /* I2C */ + snprintf(dev_name, sizeof(dev_name), "ioexp%d", s->board_idx); + qdev_prop_set_string(DEVICE(&s->i2c), "bus-label", dev_name); + + object_property_set_link(OBJECT(&s->i2c), "dram", + OBJECT(s->dram_mr), errp); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->i2c), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_I2C], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->i2c), 0)); + + /* PWM */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->pwm), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_PWM], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->pwm), 0)); + + /* LTPI controller */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->ltpi), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_LTPI_CTRL], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->ltpi), 0)); + + /* SGPIOM */ + for (int i = 0; i < AST1700_SGPIO_NUM; i++) { + if (!sysbus_realize(SYS_BUS_DEVICE(&s->sgpiom[i]), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_SGPIOM0 + i], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->sgpiom[i]), 0)); + } + + /* WDT */ + for (int i = 0; i < AST1700_WDT_NUM; i++) { + AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]); + hwaddr wdt_offset = aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_WDT] + + i * awc->iosize; + + object_property_set_link(OBJECT(&s->wdt[i]), "scu", OBJECT(&s->scu), + errp); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) { + return; + } + memory_region_add_subregion(&s->iomem, + wdt_offset, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->wdt[i]), 0)); + } + + /* I3C */ + qdev_prop_set_string(DEVICE(&s->i3c), "name", "ioexp-i3c"); + qdev_prop_set_uint64(DEVICE(&s->i3c), "size", AST1700_SOC_I3C_SIZE); + sysbus_realize(SYS_BUS_DEVICE(&s->i3c), errp); + memory_region_add_subregion_overlap(&s->iomem, + aspeed_ast1700_io_memmap[ASPEED_AST1700_DEV_I3C], + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->i3c), 0), + -1000); +} + +static void aspeed_ast1700_instance_init(Object *obj) +{ + AspeedAST1700SoCState *s = ASPEED_AST1700(obj); + + /* UART */ + object_initialize_child(obj, "uart", &s->uart, + TYPE_SERIAL_MM); + + /* SPI */ + object_initialize_child(obj, "ioexp-spi", &s->spi, + "aspeed.spi0-ast2700"); + + /* ADC */ + object_initialize_child(obj, "ioexp-adc", &s->adc, + "aspeed.adc-ast2700"); + + /* SCU */ + object_initialize_child(obj, "ioexp-scu", &s->scu, + TYPE_ASPEED_2700_SCU); + + /* GPIO */ + object_initialize_child(obj, "ioexp-gpio", &s->gpio, + "aspeed.gpio-ast2700"); + + /* I2C */ + object_initialize_child(obj, "ioexp-i2c", &s->i2c, + "aspeed.i2c-ast2700"); + + /* PWM */ + object_initialize_child(obj, "pwm", &s->pwm, TYPE_ASPEED_PWM); + + /* LTPI controller */ + object_initialize_child(obj, "ltpi-ctrl", + &s->ltpi, TYPE_ASPEED_LTPI); + + /* SGPIOM */ + for (int i = 0; i < AST1700_SGPIO_NUM; i++) { + object_initialize_child(obj, "ioexp-sgpiom[*]", &s->sgpiom[i], + "aspeed.sgpio-ast2700"); + } + + /* WDT */ + for (int i = 0; i < AST1700_WDT_NUM; i++) { + object_initialize_child(obj, "ioexp-wdt[*]", + &s->wdt[i], "aspeed.wdt-ast2700"); + } + + /* I3C */ + object_initialize_child(obj, "ioexp-i3c", &s->i3c, + TYPE_UNIMPLEMENTED_DEVICE); + + return; +} + +static const Property aspeed_ast1700_props[] = { + DEFINE_PROP_UINT8("board-idx", AspeedAST1700SoCState, board_idx, 0), + DEFINE_PROP_UINT32("silicon-rev", AspeedAST1700SoCState, silicon_rev, 0), + DEFINE_PROP_LINK("dram", AspeedAST1700SoCState, dram_mr, + TYPE_MEMORY_REGION, MemoryRegion *), +}; + +static void aspeed_ast1700_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = aspeed_ast1700_realize; + device_class_set_props(dc, aspeed_ast1700_props); +} + +static const TypeInfo aspeed_ast1700_info = { + .name = TYPE_ASPEED_AST1700, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(AspeedAST1700SoCState), + .class_init = aspeed_ast1700_class_init, + .instance_init = aspeed_ast1700_instance_init, +}; + +static void aspeed_ast1700_register_types(void) +{ + type_register_static(&aspeed_ast1700_info); +} + +type_init(aspeed_ast1700_register_types);
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 4c5a42e..efb1d8c 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c
@@ -81,7 +81,7 @@ [ASPEED_DEV_FSI1] = 0x1E79B000, [ASPEED_DEV_FSI2] = 0x1E79B100, [ASPEED_DEV_I3C] = 0x1E7A0000, - [ASPEED_DEV_PCIE_MMIO1] = 0x70000000, + [ASPEED_DEV_PCIE_MMIO1] = 0x60000000, [ASPEED_DEV_SDRAM] = 0x80000000, }; @@ -303,14 +303,14 @@ * * Model scope / limitations: * - Firmware supports RC_H only; this QEMU model does not support RC_L. - * - RC_H uses PHY1 and the MMIO window [0x70000000, 0x80000000] + * - RC_H uses PHY1 and the MMIO window [0x60000000, 0x80000000] * (aka MMIO1). * * Indexing convention (this model): * - Expose a single logical instance at index 0. * - pcie[0] -> hardware RC_H (PCIe1) * - phy[0] -> hardware PHY1 - * - mmio.0 -> guest address range MMIO1: 0x70000000-0x80000000 + * - mmio.0 -> guest address range MMIO1: 0x60000000-0x80000000 * - RC_L / PCIe0 is not created and mapped. */ static bool aspeed_soc_ast2600_pcie_realize(DeviceState *dev, Error **errp) @@ -346,7 +346,7 @@ memory_region_init_alias(&s->pcie_mmio_alias[0], OBJECT(&s->pcie[0].rc), "aspeed.pcie-mmio", mmio_mr, sc->memmap[ASPEED_DEV_PCIE_MMIO1], - 0x10000000); + 0x20000000); memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_PCIE_MMIO1], &s->pcie_mmio_alias[0]);
diff --git a/hw/arm/aspeed_ast2600_catalina.c b/hw/arm/aspeed_ast2600_catalina.c index 4edb30b..65495a5 100644 --- a/hw/arm/aspeed_ast2600_catalina.c +++ b/hw/arm/aspeed_ast2600_catalina.c
@@ -480,7 +480,7 @@ /* i2c0mux1ch1 */ /* io_expander7 - pca9535@20 */ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), - TYPE_PCA9552, 0x20); + TYPE_PCA9535, 0x20); /* eeprom@50 */ at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 1), 0x50, 8 * KiB, gb200io_eeprom, gb200io_eeprom_len); @@ -497,7 +497,7 @@ /* i2c0mux4ch1 */ /* io_expander8 - pca9535@21 */ i2c_slave_create_simple(pca954x_i2c_get_bus(i2c_mux, 1), - TYPE_PCA9552, 0x21); + TYPE_PCA9535, 0x21); /* eeprom@50 */ at24c_eeprom_init_rom(pca954x_i2c_get_bus(i2c_mux, 1), 0x50, 8 * KiB, gb200io_eeprom, gb200io_eeprom_len);
diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index cee937b..9b12ba6 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c
@@ -23,15 +23,15 @@ [ASPEED_DEV_SRAM] = 0x70000000, [ASPEED_DEV_INTC] = 0x72100000, [ASPEED_DEV_SCU] = 0x72C02000, + [ASPEED_DEV_TIMER1] = 0x72C10000, + [ASPEED_DEV_UART4] = 0x72C1A000, + [ASPEED_DEV_IPC0] = 0x72C1C000, [ASPEED_DEV_SCUIO] = 0x74C02000, + [ASPEED_DEV_INTCIO] = 0x74C18000, [ASPEED_DEV_UART0] = 0x74C33000, [ASPEED_DEV_UART1] = 0x74C33100, [ASPEED_DEV_UART2] = 0x74C33200, [ASPEED_DEV_UART3] = 0x74C33300, - [ASPEED_DEV_UART4] = 0x72C1A000, - [ASPEED_DEV_INTCIO] = 0x74C18000, - [ASPEED_DEV_IPC0] = 0x72C1C000, - [ASPEED_DEV_IPC1] = 0x74C39000, [ASPEED_DEV_UART5] = 0x74C33400, [ASPEED_DEV_UART6] = 0x74C33500, [ASPEED_DEV_UART7] = 0x74C33600, @@ -40,16 +40,17 @@ [ASPEED_DEV_UART10] = 0x74C33900, [ASPEED_DEV_UART11] = 0x74C33A00, [ASPEED_DEV_UART12] = 0x74C33B00, - [ASPEED_DEV_TIMER1] = 0x72C10000, + [ASPEED_DEV_IPC1] = 0x74C39000, }; static const int aspeed_soc_ast27x0ssp_irqmap[] = { + [ASPEED_DEV_UART4] = 8, [ASPEED_DEV_SCU] = 12, + [ASPEED_DEV_TIMER1] = 16, [ASPEED_DEV_UART0] = 164, [ASPEED_DEV_UART1] = 164, [ASPEED_DEV_UART2] = 164, [ASPEED_DEV_UART3] = 164, - [ASPEED_DEV_UART4] = 8, [ASPEED_DEV_UART5] = 164, [ASPEED_DEV_UART6] = 164, [ASPEED_DEV_UART7] = 164, @@ -58,7 +59,6 @@ [ASPEED_DEV_UART10] = 164, [ASPEED_DEV_UART11] = 164, [ASPEED_DEV_UART12] = 164, - [ASPEED_DEV_TIMER1] = 16, }; /* SSPINT 164 */
diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c index 9c11c01..e39d1dc 100644 --- a/hw/arm/aspeed_ast27x0-tsp.c +++ b/hw/arm/aspeed_ast27x0-tsp.c
@@ -23,15 +23,15 @@ [ASPEED_DEV_SRAM] = 0x70000000, [ASPEED_DEV_INTC] = 0x72100000, [ASPEED_DEV_SCU] = 0x72C02000, + [ASPEED_DEV_TIMER1] = 0x72C10000, + [ASPEED_DEV_UART4] = 0x72C1A000, + [ASPEED_DEV_IPC0] = 0x72C1C000, [ASPEED_DEV_SCUIO] = 0x74C02000, + [ASPEED_DEV_INTCIO] = 0x74C18000, [ASPEED_DEV_UART0] = 0x74C33000, [ASPEED_DEV_UART1] = 0x74C33100, [ASPEED_DEV_UART2] = 0x74C33200, [ASPEED_DEV_UART3] = 0x74C33300, - [ASPEED_DEV_UART4] = 0x72C1A000, - [ASPEED_DEV_INTCIO] = 0x74C18000, - [ASPEED_DEV_IPC0] = 0x72C1C000, - [ASPEED_DEV_IPC1] = 0x74C39000, [ASPEED_DEV_UART5] = 0x74C33400, [ASPEED_DEV_UART6] = 0x74C33500, [ASPEED_DEV_UART7] = 0x74C33600, @@ -40,16 +40,17 @@ [ASPEED_DEV_UART10] = 0x74C33900, [ASPEED_DEV_UART11] = 0x74C33A00, [ASPEED_DEV_UART12] = 0x74C33B00, - [ASPEED_DEV_TIMER1] = 0x72C10000, + [ASPEED_DEV_IPC1] = 0x74C39000, }; static const int aspeed_soc_ast27x0tsp_irqmap[] = { + [ASPEED_DEV_UART4] = 8, [ASPEED_DEV_SCU] = 12, + [ASPEED_DEV_TIMER1] = 16, [ASPEED_DEV_UART0] = 164, [ASPEED_DEV_UART1] = 164, [ASPEED_DEV_UART2] = 164, [ASPEED_DEV_UART3] = 164, - [ASPEED_DEV_UART4] = 8, [ASPEED_DEV_UART5] = 164, [ASPEED_DEV_UART6] = 164, [ASPEED_DEV_UART7] = 164, @@ -58,7 +59,6 @@ [ASPEED_DEV_UART10] = 164, [ASPEED_DEV_UART11] = 164, [ASPEED_DEV_UART12] = 164, - [ASPEED_DEV_TIMER1] = 16, }; /* TSPINT 164 */
diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index d17f446..61790ea 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c
@@ -26,7 +26,6 @@ #define AST2700_SOC_IO_SIZE 0x00FE0000 #define AST2700_SOC_IOMEM_SIZE 0x01000000 #define AST2700_SOC_DPMCU_SIZE 0x00040000 -#define AST2700_SOC_LTPI_SIZE 0x01000000 static const hwaddr aspeed_soc_ast2700_memmap[] = { [ASPEED_DEV_VBOOTROM] = 0x00000000, @@ -88,8 +87,13 @@ [ASPEED_DEV_UART10] = 0x14C33900, [ASPEED_DEV_UART11] = 0x14C33A00, [ASPEED_DEV_UART12] = 0x14C33B00, + [ASPEED_DEV_LTPI_CTRL1] = 0x14C34000, + [ASPEED_DEV_LTPI_CTRL2] = 0x14C35000, [ASPEED_DEV_WDT] = 0x14C37000, - [ASPEED_DEV_LTPI] = 0x30000000, + [ASPEED_DEV_LTPI_IO0] = 0x30000000, + [ASPEED_DEV_IOEXP0_INTCIO] = 0x30C18000, + [ASPEED_DEV_LTPI_IO1] = 0x50000000, + [ASPEED_DEV_IOEXP1_INTCIO] = 0x50C18000, [ASPEED_DEV_PCIE_MMIO0] = 0x60000000, [ASPEED_DEV_PCIE_MMIO1] = 0x80000000, [ASPEED_DEV_PCIE_MMIO2] = 0xA0000000, @@ -149,8 +153,14 @@ [ASPEED_DEV_ETH1] = 196, [ASPEED_DEV_ETH2] = 196, [ASPEED_DEV_ETH3] = 196, + [ASPEED_DEV_EHCI3] = 196, + [ASPEED_DEV_EHCI4] = 196, [ASPEED_DEV_PECI] = 197, [ASPEED_DEV_SDHCI] = 197, + [ASPEED_DEV_IOEXP0_I2C] = 198, + [ASPEED_DEV_IOEXP0_I3C] = 199, + [ASPEED_DEV_IOEXP1_I2C] = 200, + [ASPEED_DEV_IOEXP1_I3C] = 201, }; /* GICINT 192 */ @@ -207,6 +217,30 @@ [ASPEED_DEV_PECI] = 4, }; +/* Primary AST1700 Interrupts */ +/* A1: GICINT 198 */ +static const int ast2700_gic198_intcmap[] = { + [ASPEED_DEV_IOEXP0_I2C] = 0, /* 0 - 15 */ +}; + +/* Primary AST1700 Interrupts */ +/* A1: GINTC 199 */ +static const int ast2700_gic199_intcmap[] = { + [ASPEED_DEV_IOEXP0_I3C] = 0, /* 0 - 15 */ +}; + +/* Secondary AST1700 Interrupts */ +/* A1: GINTC 200 */ +static const int ast2700_gic200_intcmap[] = { + [ASPEED_DEV_IOEXP1_I2C] = 0, /* 0 - 15 */ +}; + +/* Secondary AST1700 Interrupts */ +/* A1: GINTC 201 */ +static const int ast2700_gic201_intcmap[] = { + [ASPEED_DEV_IOEXP1_I3C] = 0, /* 0 - 15 */ +}; + /* GICINT 192 ~ 201 */ struct gic_intc_irq_info { int irq; @@ -222,10 +256,10 @@ {195, 1, 3, ast2700_gic195_intcmap}, {196, 1, 4, ast2700_gic196_intcmap}, {197, 1, 5, ast2700_gic197_intcmap}, - {198, 1, 6, NULL}, - {199, 1, 7, NULL}, - {200, 1, 8, NULL}, - {201, 1, 9, NULL}, + {198, 2, 0, ast2700_gic198_intcmap}, + {199, 2, 1, ast2700_gic199_intcmap}, + {200, 3, 0, ast2700_gic200_intcmap}, + {201, 3, 1, ast2700_gic201_intcmap}, }; static qemu_irq aspeed_soc_ast2700_get_irq(AspeedSoCState *s, int dev) @@ -257,14 +291,23 @@ int or_idx; int idx; int i; + OrIRQState *porgates; for (i = 0; i < ARRAY_SIZE(ast2700_gic_intcmap); i++) { if (sc->irqmap[dev] == ast2700_gic_intcmap[i].irq) { assert(ast2700_gic_intcmap[i].ptr); or_idx = ast2700_gic_intcmap[i].orgate_idx; idx = ast2700_gic_intcmap[i].intc_idx; - return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]), + if (idx < ASPEED_INTC_NUM) { + porgates = &a->intc[idx].orgates[or_idx]; + return qdev_get_gpio_in(DEVICE(porgates), ast2700_gic_intcmap[i].ptr[dev] + index); + } else { + idx -= ASPEED_INTC_NUM; + porgates = &a->intcioexp[idx].orgates[or_idx]; + return qdev_get_gpio_in(DEVICE(porgates), + ast2700_gic_intcmap[i].ptr[dev] + index); + } } } @@ -442,6 +485,10 @@ object_initialize_child(obj, "intc", &a->intc[0], TYPE_ASPEED_2700_INTC); object_initialize_child(obj, "intcio", &a->intc[1], TYPE_ASPEED_2700_INTCIO); + object_initialize_child(obj, "intc-ioexp0", &a->intcioexp[0], + TYPE_ASPEED_2700_INTCIOEXP1); + object_initialize_child(obj, "intc-ioexp1", &a->intcioexp[1], + TYPE_ASPEED_2700_INTCIOEXP2); snprintf(typename, sizeof(typename), "aspeed.adc-%s", socname); object_initialize_child(obj, "adc", &s->adc, typename); @@ -489,10 +536,21 @@ object_property_set_int(OBJECT(&s->pcie[i]), "id", i, &error_abort); } + for (i = 0; i < ASPEED_IOEXP_NUM; i++) { + object_initialize_child(obj, "ltpi-ctrl[*]", + &s->ltpi_ctrl[i], TYPE_ASPEED_LTPI); + } + + for (i = 0; i < sc->ioexp_num; i++) { + /* AST1700 IOEXP */ + object_initialize_child(obj, "ioexp[*]", &s->ioexp[i], + TYPE_ASPEED_AST1700); + qdev_prop_set_uint32(DEVICE(&s->ioexp[i]), "silicon-rev", + sc->silicon_rev); + } + object_initialize_child(obj, "dpmcu", &s->dpmcu, TYPE_UNIMPLEMENTED_DEVICE); - object_initialize_child(obj, "ltpi", &s->ltpi, - TYPE_UNIMPLEMENTED_DEVICE); object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE); object_initialize_child(obj, "iomem0", &s->iomem0, @@ -677,6 +735,22 @@ aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&a->intc[1]), 0, sc->memmap[ASPEED_DEV_INTCIO]); + /* INTCIOEXP0 */ + if (!sysbus_realize(SYS_BUS_DEVICE(&a->intcioexp[0]), errp)) { + return; + } + + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&a->intcioexp[0]), 0, + sc->memmap[ASPEED_DEV_IOEXP0_INTCIO]); + + /* INTCIOEXP1 */ + if (!sysbus_realize(SYS_BUS_DEVICE(&a->intcioexp[1]), errp)) { + return; + } + + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(&a->intcioexp[1]), 0, + sc->memmap[ASPEED_DEV_IOEXP1_INTCIO]); + /* irq sources -> orgates -> INTC */ for (i = 0; i < ic->num_inpins; i++) { qdev_connect_gpio_out(DEVICE(&a->intc[0].orgates[i]), 0, @@ -972,14 +1046,82 @@ return; } + /* LTPI controller */ + for (i = 0; i < ASPEED_IOEXP_NUM; i++) { + AspeedLTPIState *ltpi_ctrl; + hwaddr ltpi_base; + + ltpi_ctrl = ASPEED_LTPI(&s->ltpi_ctrl[i]); + ltpi_base = sc->memmap[ASPEED_DEV_LTPI_CTRL1 + i]; + + if (!sysbus_realize(SYS_BUS_DEVICE(ltpi_ctrl), errp)) { + return; + } + aspeed_mmio_map(s->memory, SYS_BUS_DEVICE(ltpi_ctrl), 0, ltpi_base); + } + + /* IO Expander */ + for (i = 0; i < sc->ioexp_num; i++) { + AspeedI2CClass *i2c_ctl; + + qdev_prop_set_uint8(DEVICE(&s->ioexp[i]), "board-idx", i); + object_property_set_link(OBJECT(&s->ioexp[i]), "dram", + OBJECT(s->dram_mr), &error_abort); + if (!sysbus_realize(SYS_BUS_DEVICE(&s->ioexp[i]), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioexp[i]), 0, + sc->memmap[ASPEED_DEV_LTPI_IO0 + i]); + + icio = ASPEED_INTC_GET_CLASS(&a->intcioexp[i]); + /* INTC_IOEXP internal: orgate[i] -> input[i] */ + for (int j = 0; j < icio->num_inpins; j++) { + irq = qdev_get_gpio_in(DEVICE(&a->intcioexp[i]), j); + qdev_connect_gpio_out(DEVICE(&a->intcioexp[i].orgates[j]), 0, + irq); + } + + /* INTC_IOEXP output[i] -> INTC0.orgate[0].input[i] */ + for (int j = 0; j < icio->num_outpins; j++) { + irq = qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), j); + sysbus_connect_irq(SYS_BUS_DEVICE(&a->intcioexp[i]), j, + irq); + } + + /* ADC */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ioexp[i].adc), 0, + aspeed_soc_ast2700_get_irq(s, ASPEED_DEV_ADC)); + + /* GPIO */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ioexp[i].gpio), 0, + aspeed_soc_ast2700_get_irq(s, ASPEED_DEV_GPIO)); + + /* I2C */ + i2c_ctl = ASPEED_I2C_GET_CLASS(&s->ioexp[i].i2c); + for (int j = 0; j < i2c_ctl->num_busses; j++) { + /* + * For I2C on AST1700: + * I2C bus interrupts are connected to the OR gate from bit 0 to bit + * 15, and the OR gate output pin is connected to the input pin of + * GICINT192 of IO expander Interrupt controller (INTC2/3). Then, + * the output pin is connected to the INTC (CPU Die) input pin, and + * its output pin is connected to the GIC. + * + * I2C bus 0 is connected to the OR gate at bit 0. + * I2C bus 15 is connected to the OR gate at bit 15. + */ + irq = aspeed_soc_ast2700_get_irq_index(s, + ASPEED_DEV_IOEXP0_I2C + i, + j); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ioexp[i].i2c.busses[j]), + 0, irq); + } + } + aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->dpmcu), "aspeed.dpmcu", sc->memmap[ASPEED_DEV_DPMCU], AST2700_SOC_DPMCU_SIZE); - aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->ltpi), - "aspeed.ltpi", - sc->memmap[ASPEED_DEV_LTPI], - AST2700_SOC_LTPI_SIZE); aspeed_mmio_map_unimplemented(s->memory, SYS_BUS_DEVICE(&s->iomem), "aspeed.io", sc->memmap[ASPEED_DEV_IOMEM], @@ -1018,6 +1160,7 @@ sc->macs_num = 3; sc->uarts_num = 13; sc->num_cpus = 4; + sc->ioexp_num = 2; sc->uarts_base = ASPEED_DEV_UART0; sc->irqmap = aspeed_soc_ast2700a1_irqmap; sc->memmap = aspeed_soc_ast2700_memmap;
diff --git a/hw/arm/meson.build b/hw/arm/meson.build index c250487..47cdc51 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build
@@ -70,6 +70,7 @@ 'aspeed_ast10x0_evb.c', 'fby35.c')) arm_common_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files( + 'aspeed_ast1700.c', 'aspeed_ast27x0.c', 'aspeed_ast27x0_evb.c', 'aspeed_ast27x0-fc.c',
diff --git a/hw/gpio/pca9552.c b/hw/gpio/pca9552.c index dd3c795..dd3f153 100644 --- a/hw/gpio/pca9552.c +++ b/hw/gpio/pca9552.c
@@ -31,6 +31,7 @@ uint8_t pin_count; uint8_t max_reg; + bool has_led_support; }; typedef struct PCA955xClass PCA955xClass; @@ -113,32 +114,59 @@ for (i = 0; i < k->pin_count; i++) { uint8_t input_reg = PCA9552_INPUT0 + (i / 8); uint8_t bit_mask = 1 << (i % 8); - uint8_t config = pca955x_pin_get_config(s, i); uint8_t old_value = s->regs[input_reg] & bit_mask; uint8_t new_value; - switch (config) { - case PCA9552_LED_ON: - /* Pin is set to 0V to turn on LED */ - s->regs[input_reg] &= ~bit_mask; - break; - case PCA9552_LED_OFF: - /* - * Pin is set to Hi-Z to turn off LED and - * pullup sets it to a logical 1 unless - * external device drives it low. - */ - if (s->ext_state[i] == PCA9552_PIN_LOW) { + if (k->has_led_support) { + /* PCA9552: LED control behavior */ + uint8_t config = pca955x_pin_get_config(s, i); + + switch (config) { + case PCA9552_LED_ON: + /* Pin is set to 0V to turn on LED */ s->regs[input_reg] &= ~bit_mask; - } else { - s->regs[input_reg] |= bit_mask; + break; + case PCA9552_LED_OFF: + /* + * Pin is set to Hi-Z to turn off LED and + * pullup sets it to a logical 1 unless + * external device drives it low. + */ + if (s->ext_state[i] == PCA9552_PIN_LOW) { + s->regs[input_reg] &= ~bit_mask; + } else { + s->regs[input_reg] |= bit_mask; + } + break; + case PCA9552_LED_PWM0: + case PCA9552_LED_PWM1: + /* TODO */ + default: + break; } - break; - case PCA9552_LED_PWM0: - case PCA9552_LED_PWM1: - /* TODO */ - default: - break; + } else { + /* PCA9535: Simple GPIO behavior */ + uint8_t config_reg = PCA9535_CONFIG0 + (i / 8); + uint8_t output_reg = PCA9535_OUTPUT0 + (i / 8); + uint8_t polarity_reg = PCA9535_POLARITY0 + (i / 8); + + /* Check if pin is configured as input */ + if (s->regs[config_reg] & bit_mask) { + /* Input mode - reflect external state */ + if (s->ext_state[i] == PCA9552_PIN_LOW) { + s->regs[input_reg] &= ~bit_mask; + } else { + s->regs[input_reg] |= bit_mask; + } + } else { + /* Output mode - reflect output register value */ + uint8_t output_bit = s->regs[output_reg] & bit_mask; + uint8_t polarity_bit = s->regs[polarity_reg] & bit_mask; + + /* Apply polarity inversion if set */ + s->regs[input_reg] = (s->regs[input_reg] & ~bit_mask) | + ((output_bit ^ polarity_bit) & bit_mask); + } } /* update irq state only if pin state changed */ @@ -151,52 +179,52 @@ static uint8_t pca955x_read(PCA955xState *s, uint8_t reg) { - switch (reg) { - case PCA9552_INPUT0: - case PCA9552_INPUT1: - case PCA9552_PSC0: - case PCA9552_PWM0: - case PCA9552_PSC1: - case PCA9552_PWM1: - case PCA9552_LS0: - case PCA9552_LS1: - case PCA9552_LS2: - case PCA9552_LS3: - return s->regs[reg]; - default: + PCA955xClass *k = PCA955X_GET_CLASS(s); + + if (reg > k->max_reg) { qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected read to register %d\n", __func__, reg); return 0xFF; } + + return s->regs[reg]; } static void pca955x_write(PCA955xState *s, uint8_t reg, uint8_t data) { + PCA955xClass *k = PCA955X_GET_CLASS(s); uint16_t pins_status; - switch (reg) { - case PCA9552_PSC0: - case PCA9552_PWM0: - case PCA9552_PSC1: - case PCA9552_PWM1: - s->regs[reg] = data; - break; - - case PCA9552_LS0: - case PCA9552_LS1: - case PCA9552_LS2: - case PCA9552_LS3: - pins_status = pca955x_pins_get_status(s); - s->regs[reg] = data; - pca955x_update_pin_input(s); - pca955x_display_pins_status(s, pins_status); - break; - - case PCA9552_INPUT0: - case PCA9552_INPUT1: - default: + if (reg > k->max_reg) { qemu_log_mask(LOG_GUEST_ERROR, "%s: unexpected write to register %d\n", __func__, reg); + return; + } + + /* Handle read-only registers */ + if (reg == PCA9552_INPUT0 || reg == PCA9552_INPUT1) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: unexpected write to read-only register %d\n", + __func__, reg); + return; + } + + pins_status = pca955x_pins_get_status(s); + s->regs[reg] = data; + + /* Update GPIO state if this register affects outputs */ + if (k->has_led_support) { + /* PCA9552: Update on LED selector register writes */ + if (reg >= PCA9552_LS0 && reg <= PCA9552_LS3) { + pca955x_update_pin_input(s); + pca955x_display_pins_status(s, pins_status); + } + } else { + /* PCA9535: Update on OUTPUT, POLARITY, or CONFIG register writes */ + if (reg >= PCA9535_OUTPUT0 && reg <= PCA9535_CONFIG1) { + pca955x_update_pin_input(s); + pca955x_display_pins_status(s, pins_status); + } } } @@ -379,6 +407,26 @@ s->len = 0; } +static void pca9535_reset(DeviceState *dev) +{ + PCA955xState *s = PCA955X(dev); + + s->regs[PCA9535_INPUT0] = 0xFF; /* All inputs high (pull-ups) */ + s->regs[PCA9535_INPUT1] = 0xFF; /* All inputs high (pull-ups) */ + s->regs[PCA9535_OUTPUT0] = 0xFF; /* All outputs high */ + s->regs[PCA9535_OUTPUT1] = 0xFF; /* All outputs high */ + s->regs[PCA9535_POLARITY0] = 0x00; /* No polarity inversion */ + s->regs[PCA9535_POLARITY1] = 0x00; /* No polarity inversion */ + s->regs[PCA9535_CONFIG0] = 0xFF; /* All pins as inputs */ + s->regs[PCA9535_CONFIG1] = 0xFF; /* All pins as inputs */ + + memset(s->ext_state, PCA9552_PIN_HIZ, PCA955X_PIN_COUNT_MAX); + pca955x_update_pin_input(s); + + s->pointer = 0xFF; + s->len = 0; +} + static void pca955x_initfn(Object *obj) { PCA955xClass *k = PCA955X_GET_CLASS(obj); @@ -463,6 +511,19 @@ dc->vmsd = &pca9552_vmstate; pc->max_reg = PCA9552_LS3; pc->pin_count = 16; + pc->has_led_support = true; +} + +static void pca9535_class_init(ObjectClass *oc, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PCA955xClass *pc = PCA955X_CLASS(oc); + + device_class_set_legacy_reset(dc, pca9535_reset); + dc->vmsd = &pca9552_vmstate; + pc->max_reg = PCA9535_CONFIG1; + pc->pin_count = 16; + pc->has_led_support = false; } static const TypeInfo pca9552_info = { @@ -471,10 +532,17 @@ .class_init = pca9552_class_init, }; +static const TypeInfo pca9535_info = { + .name = TYPE_PCA9535, + .parent = TYPE_PCA955X, + .class_init = pca9535_class_init, +}; + static void pca955x_register_types(void) { type_register_static(&pca955x_info); type_register_static(&pca9552_info); + type_register_static(&pca9535_info); } type_init(pca955x_register_types)
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index 1b8ac56..fb3d6a5 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c
@@ -116,8 +116,6 @@ value = -1; break; } - - value = extract64(bus->dma_dram_offset, 0, 32); break; case A_I2CD_DMA_LEN: if (!aic->has_dma) { @@ -221,6 +219,64 @@ return SHARED_ARRAY_FIELD_EX32(bus->regs, R_I2CD_CMD, TX_STATE); } +/* + * The AST2700 support the maximum DRAM size is 8 GB. + * The DRAM offset range is from 0x0_0000_0000 to + * 0x1_FFFF_FFFF and it is enough to use bits [33:0] + * saving the dram offset. + * Therefore, save the high part physical address bit[1:0] + * of Tx/Rx buffer address as dma_dram_offset bit[33:32]. + */ +static void aspeed_i2c_set_tx_dma_dram_offset(AspeedI2CBus *bus) +{ + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + uint32_t value; + + assert(aic->has_dma); + + if (aspeed_i2c_is_new_mode(bus->controller)) { + value = bus->regs[R_I2CM_DMA_TX_ADDR]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 0, 32, + FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR)); + if (!aic->has_dma64) { + value = bus->regs[R_I2CM_DMA_TX_ADDR_HI]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 32, 32, + extract32(value, 0, 2)); + } + } else { + value = bus->regs[R_I2CD_DMA_ADDR]; + bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, + value & 0x3ffffffc); + } +} + +static void aspeed_i2c_set_rx_dma_dram_offset(AspeedI2CBus *bus) +{ + AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller); + uint32_t value; + + assert(aic->has_dma); + + if (aspeed_i2c_is_new_mode(bus->controller)) { + value = bus->regs[R_I2CM_DMA_RX_ADDR]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 0, 32, + FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR)); + if (!aic->has_dma64) { + value = bus->regs[R_I2CM_DMA_RX_ADDR_HI]; + bus->dma_dram_offset = + deposit64(bus->dma_dram_offset, 32, 32, + extract32(value, 0, 2)); + } + } else { + value = bus->regs[R_I2CD_DMA_ADDR]; + bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, + value & 0x3ffffffc); + } +} + static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data) { MemTxResult result; @@ -270,9 +326,14 @@ if (aspeed_i2c_is_new_mode(bus->controller)) { ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN_STS, TX_LEN, 0); } + aspeed_i2c_set_tx_dma_dram_offset(bus); while (bus->regs[reg_dma_len]) { uint8_t data; - aspeed_i2c_dma_read(bus, &data); + ret = aspeed_i2c_dma_read(bus, &data); + /* Check that we were able to read the DMA */ + if (ret) { + break; + } trace_aspeed_i2c_bus_send("DMA", bus->regs[reg_dma_len], bus->regs[reg_dma_len], data); ret = i2c_send(bus->bus, data); @@ -331,6 +392,7 @@ ARRAY_FIELD_DP32(bus->regs, I2CM_DMA_LEN_STS, RX_LEN, 0); } + aspeed_i2c_set_rx_dma_dram_offset(bus); while (bus->regs[reg_dma_len]) { MemTxResult result; @@ -397,6 +459,7 @@ } else if (SHARED_ARRAY_FIELD_EX32(bus->regs, reg_cmd, TX_DMA_EN)) { uint8_t data; + aspeed_i2c_set_tx_dma_dram_offset(bus); aspeed_i2c_dma_read(bus, &data); return data; } else { @@ -653,16 +716,10 @@ case A_I2CM_DMA_TX_ADDR: bus->regs[R_I2CM_DMA_TX_ADDR] = FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR); - bus->dma_dram_offset = - deposit64(bus->dma_dram_offset, 0, 32, - FIELD_EX32(value, I2CM_DMA_TX_ADDR, ADDR)); break; case A_I2CM_DMA_RX_ADDR: bus->regs[R_I2CM_DMA_RX_ADDR] = FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR); - bus->dma_dram_offset = - deposit64(bus->dma_dram_offset, 0, 32, - FIELD_EX32(value, I2CM_DMA_RX_ADDR, ADDR)); break; case A_I2CM_DMA_LEN: w1t = FIELD_EX32(value, I2CM_DMA_LEN, RX_BUF_LEN_W1T) || @@ -744,15 +801,6 @@ qemu_log_mask(LOG_UNIMP, "%s: Slave mode DMA TX is not implemented\n", __func__); break; - - /* - * The AST2700 support the maximum DRAM size is 8 GB. - * The DRAM offset range is from 0x0_0000_0000 to - * 0x1_FFFF_FFFF and it is enough to use bits [33:0] - * saving the dram offset. - * Therefore, save the high part physical address bit[1:0] - * of Tx/Rx buffer address as dma_dram_offset bit[33:32]. - */ case A_I2CM_DMA_TX_ADDR_HI: if (!aic->has_dma64) { qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA 64 bits support\n", @@ -762,8 +810,6 @@ bus->regs[R_I2CM_DMA_TX_ADDR_HI] = FIELD_EX32(value, I2CM_DMA_TX_ADDR_HI, ADDR_HI); - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32, - extract32(value, 0, 2)); break; case A_I2CM_DMA_RX_ADDR_HI: if (!aic->has_dma64) { @@ -774,8 +820,6 @@ bus->regs[R_I2CM_DMA_RX_ADDR_HI] = FIELD_EX32(value, I2CM_DMA_RX_ADDR_HI, ADDR_HI); - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32, - extract32(value, 0, 2)); break; case A_I2CS_DMA_TX_ADDR_HI: qemu_log_mask(LOG_UNIMP, @@ -791,8 +835,6 @@ bus->regs[R_I2CS_DMA_RX_ADDR_HI] = FIELD_EX32(value, I2CS_DMA_RX_ADDR_HI, ADDR_HI); - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 32, 32, - extract32(value, 0, 2)); break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n", @@ -883,9 +925,6 @@ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__); break; } - - bus->dma_dram_offset = deposit64(bus->dma_dram_offset, 0, 32, - value & 0x3ffffffc); break; case A_I2CD_DMA_LEN: @@ -1215,9 +1254,16 @@ "aspeed.i2c", aic->mem_size); sysbus_init_mmio(sbd, &s->iomem); + /* default value */ + if (!s->bus_label) { + s->bus_label = g_strdup(TYPE_ASPEED_I2C_BUS); + } + for (i = 0; i < aic->num_busses; i++) { Object *bus = OBJECT(&s->busses[i]); int offset = i < aic->gap ? 1 : 5; + g_autofree char *name = g_strdup_printf("%s.%d", + s->bus_label, i); if (!object_property_set_link(bus, "controller", OBJECT(s), errp)) { return; @@ -1227,6 +1273,10 @@ return; } + if (!object_property_set_str(bus, "bus-name", name, errp)) { + return; + } + if (!sysbus_realize(SYS_BUS_DEVICE(bus), errp)) { return; } @@ -1263,6 +1313,7 @@ static const Property aspeed_i2c_properties[] = { DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr, TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_STRING("bus-label", AspeedI2CState, bus_label), }; static void aspeed_i2c_class_init(ObjectClass *klass, const void *data) @@ -1423,24 +1474,26 @@ { AspeedI2CBus *s = ASPEED_I2C_BUS(dev); AspeedI2CClass *aic; - g_autofree char *name = g_strdup_printf(TYPE_ASPEED_I2C_BUS ".%d", s->id); - g_autofree char *pool_name = g_strdup_printf("%s.pool", name); + g_autofree char *pool_name = NULL; - if (!s->controller) { - error_setg(errp, TYPE_ASPEED_I2C_BUS ": 'controller' link not set"); + if (!s->controller || !s->name) { + error_setg(errp, TYPE_ASPEED_I2C_BUS + ": 'controller' or 'bus-name' not set"); return; } + pool_name = g_strdup_printf("%s.pool", s->name); + aic = ASPEED_I2C_GET_CLASS(s->controller); sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); - s->bus = i2c_init_bus(dev, name); + s->bus = i2c_init_bus(dev, s->name); s->slave = i2c_slave_create_simple(s->bus, TYPE_ASPEED_I2C_BUS_SLAVE, 0xff); memory_region_init_io(&s->mr, OBJECT(s), &aspeed_i2c_bus_ops, - s, name, aic->reg_size); + s, s->name, aic->reg_size); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mr); memory_region_init_io(&s->mr_pool, OBJECT(s), &aspeed_i2c_bus_pool_ops, @@ -1452,6 +1505,7 @@ DEFINE_PROP_UINT8("bus-id", AspeedI2CBus, id, 0), DEFINE_PROP_LINK("controller", AspeedI2CBus, controller, TYPE_ASPEED_I2C, AspeedI2CState *), + DEFINE_PROP_STRING("bus-name", AspeedI2CBus, name), }; static void aspeed_i2c_bus_class_init(ObjectClass *klass, const void *data)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 9446a9f..19c6236 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c
@@ -2249,3 +2249,12 @@ */ acpi_build_tables_cleanup(&tables, false); } + +GArray *acpi_build_madt_standalone(MachineState *machine) +{ + X86MachineState *x86ms = X86_MACHINE(machine); + GArray *table = g_array_new(false, true, 1); + acpi_build_madt(table, NULL, x86ms, x86ms->oem_id, + x86ms->oem_table_id); + return table; +}
diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h index 8ba3c33..00e19bb 100644 --- a/hw/i386/acpi-build.h +++ b/hw/i386/acpi-build.h
@@ -8,4 +8,6 @@ void acpi_setup(void); Object *acpi_get_i386_pci_host(void); +GArray *acpi_build_madt_standalone(MachineState *machine); + #endif
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index fea158f..878db572 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c
@@ -320,16 +320,6 @@ x86_nvdimm_acpi_dsmio, x86ms->fw_cfg, OBJECT(pcms)); } - -#if defined(CONFIG_IGVM) - /* Apply guest state from IGVM if supplied */ - if (x86ms->igvm) { - if (IGVM_CFG_GET_CLASS(x86ms->igvm) - ->process(x86ms->igvm, machine->cgs, false, &error_fatal) < 0) { - g_assert_not_reached(); - } - } -#endif } typedef enum PCSouthBridgeOption {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4d6046e..6e5a23d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c
@@ -328,16 +328,6 @@ x86_nvdimm_acpi_dsmio, x86ms->fw_cfg, OBJECT(pcms)); } - -#if defined(CONFIG_IGVM) - /* Apply guest state from IGVM if supplied */ - if (x86ms->igvm) { - if (IGVM_CFG_GET_CLASS(x86ms->igvm) - ->process(x86ms->igvm, machine->cgs, false, &error_fatal) < 0) { - g_assert_not_reached(); - } - } -#endif } #define DEFINE_Q35_MACHINE(major, minor) \
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index 77fae39..52f2f94 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c
@@ -793,6 +793,64 @@ .class_init = aspeed_2700_intc_class_init, }; +static AspeedINTCIRQ aspeed_2700_intcioexp2_irqs[ASPEED_INTC_MAX_INPINS] = { + {0, 8, 1, R_GICINT192_EN, R_GICINT192_STATUS}, + {1, 9, 1, R_GICINT193_EN, R_GICINT193_STATUS}, +}; + +static void aspeed_2700_intcioexp2_class_init(ObjectClass *klass, + const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); + + dc->desc = "ASPEED 2700 IOEXP2 INTC Controller"; + aic->num_lines = 32; + aic->num_inpins = 2; + aic->num_outpins = 10; + aic->mem_size = 0x400; + aic->nr_regs = 0x58 >> 2; + aic->reg_offset = 0x100; + aic->reg_ops = &aspeed_intcio_ops; + aic->irq_table = aspeed_2700_intcioexp2_irqs; + aic->irq_table_count = ARRAY_SIZE(aspeed_2700_intcioexp2_irqs); +} + +static const TypeInfo aspeed_2700_intcioexp2_info = { + .name = TYPE_ASPEED_2700_INTCIOEXP2, + .parent = TYPE_ASPEED_INTC, + .class_init = aspeed_2700_intcioexp2_class_init, +}; + +static AspeedINTCIRQ aspeed_2700_intcioexp1_irqs[ASPEED_INTC_MAX_INPINS] = { + {0, 6, 1, R_GICINT192_EN, R_GICINT192_STATUS}, + {1, 7, 1, R_GICINT193_EN, R_GICINT193_STATUS}, +}; + +static void aspeed_2700_intcioexp1_class_init(ObjectClass *klass, + const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); + + dc->desc = "ASPEED 2700 IOEXP1 INTC Controller"; + aic->num_lines = 32; + aic->num_inpins = 2; + aic->num_outpins = 10; + aic->mem_size = 0x400; + aic->nr_regs = 0x58 >> 2; + aic->reg_offset = 0x100; + aic->reg_ops = &aspeed_intcio_ops; + aic->irq_table = aspeed_2700_intcioexp1_irqs; + aic->irq_table_count = ARRAY_SIZE(aspeed_2700_intcioexp1_irqs); +} + +static const TypeInfo aspeed_2700_intcioexp1_info = { + .name = TYPE_ASPEED_2700_INTCIOEXP1, + .parent = TYPE_ASPEED_INTC, + .class_init = aspeed_2700_intcioexp1_class_init, +}; + static AspeedINTCIRQ aspeed_2700_intcio_irqs[ASPEED_INTC_MAX_INPINS] = { {0, 0, 1, R_GICINT192_EN, R_GICINT192_STATUS}, {1, 1, 1, R_GICINT193_EN, R_GICINT193_STATUS}, @@ -950,6 +1008,8 @@ type_register_static(&aspeed_intc_info); type_register_static(&aspeed_2700_intc_info); type_register_static(&aspeed_2700_intcio_info); + type_register_static(&aspeed_2700_intcioexp1_info); + type_register_static(&aspeed_2700_intcioexp2_info); type_register_static(&aspeed_2700ssp_intc_info); type_register_static(&aspeed_2700ssp_intcio_info); type_register_static(&aspeed_2700tsp_intc_info);
diff --git a/hw/misc/aspeed_ltpi.c b/hw/misc/aspeed_ltpi.c new file mode 100644 index 0000000..131cea9 --- /dev/null +++ b/hw/misc/aspeed_ltpi.c
@@ -0,0 +1,193 @@ +/* + * ASPEED LTPI Controller + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "migration/vmstate.h" +#include "hw/misc/aspeed_ltpi.h" + +#define ASPEED_LTPI_CTRL_BASE 0x000 +#define ASPEED_LTPI_PHY_BASE 0x200 +#define ASPEED_LTPI_TOP_BASE 0x800 + +#define LTPI_CTRL_LINK_MNG 0x42 +#define LTPI_PHY_MODE 0x0 + +static uint64_t aspeed_ltpi_top_read(void *opaque, hwaddr offset, unsigned size) +{ + AspeedLTPIState *s = opaque; + uint32_t idx = offset >> 2; + + return s->top_regs[idx]; +} + +static void aspeed_ltpi_top_write(void *opaque, hwaddr offset, + uint64_t val, unsigned size) +{ + AspeedLTPIState *s = opaque; + uint32_t idx = offset >> 2; + + switch (offset) { + default: + s->top_regs[idx] = (uint32_t)val; + break; + } +} + +static const MemoryRegionOps aspeed_ltpi_top_ops = { + .read = aspeed_ltpi_top_read, + .write = aspeed_ltpi_top_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static uint64_t aspeed_ltpi_phy_read(void *opaque, hwaddr offset, unsigned size) +{ + AspeedLTPIState *s = opaque; + uint32_t idx = offset >> 2; + + return s->phy_regs[idx]; +} + +static void aspeed_ltpi_phy_write(void *opaque, hwaddr offset, + uint64_t val, unsigned size) +{ + AspeedLTPIState *s = opaque; + uint32_t idx = offset >> 2; + + switch (offset) { + default: + s->phy_regs[idx] = (uint32_t)val; + break; + } +} + +static const MemoryRegionOps aspeed_ltpi_phy_ops = { + .read = aspeed_ltpi_phy_read, + .write = aspeed_ltpi_phy_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static uint64_t aspeed_ltpi_ctrl_read(void *opaque, + hwaddr offset, unsigned size) +{ + AspeedLTPIState *s = opaque; + uint32_t idx = offset >> 2; + + return s->ctrl_regs[idx]; +} + +static void aspeed_ltpi_ctrl_write(void *opaque, hwaddr offset, + uint64_t val, unsigned size) +{ + AspeedLTPIState *s = opaque; + uint32_t idx = offset >> 2; + + switch (offset) { + default: + s->ctrl_regs[idx] = (uint32_t)val; + break; + } +} + +static const MemoryRegionOps aspeed_ltpi_ctrl_ops = { + .read = aspeed_ltpi_ctrl_read, + .write = aspeed_ltpi_ctrl_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static void aspeed_ltpi_reset(DeviceState *dev) +{ + AspeedLTPIState *s = ASPEED_LTPI(dev); + + memset(s->ctrl_regs, 0, sizeof(s->ctrl_regs)); + memset(s->phy_regs, 0, sizeof(s->phy_regs)); + memset(s->top_regs, 0, sizeof(s->top_regs)); + /* set default values */ + s->ctrl_regs[LTPI_CTRL_LINK_MNG] = 0x11900007; + s->phy_regs[LTPI_PHY_MODE] = 0x2; +} + + +static const VMStateDescription vmstate_aspeed_ltpi = { + .name = TYPE_ASPEED_LTPI, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(ctrl_regs, AspeedLTPIState, + ASPEED_LTPI_CTRL_SIZE >> 2), + VMSTATE_UINT32_ARRAY(phy_regs, AspeedLTPIState, + ASPEED_LTPI_PHY_SIZE >> 2), + VMSTATE_UINT32_ARRAY(top_regs, AspeedLTPIState, + ASPEED_LTPI_TOP_SIZE >> 2), + + VMSTATE_END_OF_LIST() + } +}; + +static void aspeed_ltpi_realize(DeviceState *dev, Error **errp) +{ + AspeedLTPIState *s = ASPEED_LTPI(dev); + + memory_region_init(&s->mmio, OBJECT(s), TYPE_ASPEED_LTPI, + ASPEED_LTPI_TOTAL_SIZE); + + memory_region_init_io(&s->mmio_ctrl, OBJECT(s), + &aspeed_ltpi_ctrl_ops, s, + "aspeed-ltpi-ctrl", ASPEED_LTPI_CTRL_SIZE); + + memory_region_init_io(&s->mmio_phy, OBJECT(s), + &aspeed_ltpi_phy_ops, s, + "aspeed-ltpi-phy", ASPEED_LTPI_PHY_SIZE); + + memory_region_init_io(&s->mmio_top, OBJECT(s), + &aspeed_ltpi_top_ops, s, + "aspeed-ltpi-top", ASPEED_LTPI_TOP_SIZE); + + memory_region_add_subregion(&s->mmio, + ASPEED_LTPI_CTRL_BASE, &s->mmio_ctrl); + memory_region_add_subregion(&s->mmio, + ASPEED_LTPI_PHY_BASE, &s->mmio_phy); + memory_region_add_subregion(&s->mmio, + ASPEED_LTPI_TOP_BASE, &s->mmio_top); + + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio); +} + +static void aspeed_ltpi_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = aspeed_ltpi_realize; + dc->vmsd = &vmstate_aspeed_ltpi; + device_class_set_legacy_reset(dc, aspeed_ltpi_reset); +} + +static const TypeInfo aspeed_ltpi_info = { + .name = TYPE_ASPEED_LTPI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(AspeedLTPIState), + .class_init = aspeed_ltpi_class_init, +}; + +static void aspeed_ltpi_register_types(void) +{ + type_register_static(&aspeed_ltpi_info); +} + +type_init(aspeed_ltpi_register_types);
diff --git a/hw/misc/aspeed_pwm.c b/hw/misc/aspeed_pwm.c new file mode 100644 index 0000000..ee3d588 --- /dev/null +++ b/hw/misc/aspeed_pwm.c
@@ -0,0 +1,120 @@ +/* + * ASPEED PWM Controller + * + * Copyright (C) 2017-2021 IBM Corp. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/error-report.h" +#include "hw/misc/aspeed_pwm.h" +#include "qapi/error.h" +#include "migration/vmstate.h" + +#include "trace.h" + +static uint64_t aspeed_pwm_read(void *opaque, hwaddr addr, + unsigned int size) +{ + AspeedPWMState *s = ASPEED_PWM(opaque); + uint64_t val = 0; + + addr >>= 2; + + if (addr >= ASPEED_PWM_NR_REGS) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n", + __func__, addr << 2); + } else { + val = s->regs[addr]; + } + + trace_aspeed_pwm_read(addr << 2, val); + + return val; +} + +static void aspeed_pwm_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) +{ + AspeedPWMState *s = ASPEED_PWM(opaque); + + trace_aspeed_pwm_write(addr, data); + + addr >>= 2; + + if (addr >= ASPEED_PWM_NR_REGS) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n", + __func__, addr << 2); + return; + } + + s->regs[addr] = data; +} + +static const MemoryRegionOps aspeed_pwm_ops = { + .read = aspeed_pwm_read, + .write = aspeed_pwm_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static void aspeed_pwm_reset(DeviceState *dev) +{ + struct AspeedPWMState *s = ASPEED_PWM(dev); + + memset(s->regs, 0, sizeof(s->regs)); +} + +static void aspeed_pwm_realize(DeviceState *dev, Error **errp) +{ + AspeedPWMState *s = ASPEED_PWM(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + + sysbus_init_irq(sbd, &s->irq); + + memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_pwm_ops, s, + TYPE_ASPEED_PWM, 0x1000); + + sysbus_init_mmio(sbd, &s->iomem); +} + +static const VMStateDescription vmstate_aspeed_pwm = { + .name = TYPE_ASPEED_PWM, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, AspeedPWMState, ASPEED_PWM_NR_REGS), + VMSTATE_END_OF_LIST(), + } +}; + +static void aspeed_pwm_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->realize = aspeed_pwm_realize; + device_class_set_legacy_reset(dc, aspeed_pwm_reset); + dc->desc = "Aspeed PWM Controller"; + dc->vmsd = &vmstate_aspeed_pwm; +} + +static const TypeInfo aspeed_pwm_info = { + .name = TYPE_ASPEED_PWM, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(AspeedPWMState), + .class_init = aspeed_pwm_class_init, +}; + +static void aspeed_pwm_register_types(void) +{ + type_register_static(&aspeed_pwm_info); +} + +type_init(aspeed_pwm_register_types);
diff --git a/hw/misc/meson.build b/hw/misc/meson.build index c444e03..d304a98 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build
@@ -137,6 +137,8 @@ 'aspeed_hace.c', 'aspeed_i3c.c', 'aspeed_lpc.c', + 'aspeed_ltpi.c', + 'aspeed_pwm.c', 'aspeed_scu.c', 'aspeed_sbc.c', 'aspeed_sdmc.c',
diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 4cee8a2..d6af2fc 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events
@@ -299,6 +299,10 @@ aspeed_i3c_device_read(uint32_t deviceid, uint64_t offset, uint64_t data) "I3C Dev[%u] read: offset 0x%" PRIx64 " data 0x%" PRIx64 aspeed_i3c_device_write(uint32_t deviceid, uint64_t offset, uint64_t data) "I3C Dev[%u] write: offset 0x%" PRIx64 " data 0x%" PRIx64 +# aspeed_pwm.c +aspeed_pwm_read(uint64_t offset, uint64_t data) "read: offset 0x%" PRIx64 " data 0x%" PRIx64 +aspeed_pwm_write(uint64_t offset, uint64_t data) "write: offset 0x%" PRIx64 " data 0x%" PRIx64 + # aspeed_sdmc.c aspeed_sdmc_write(uint64_t reg, uint64_t data) "reg @0x%" PRIx64 " data: 0x%" PRIx64 aspeed_sdmc_read(uint64_t reg, uint64_t data) "reg @0x%" PRIx64 " data: 0x%" PRIx64
diff --git a/hw/pci-host/aspeed_pcie.c b/hw/pci-host/aspeed_pcie.c index 8eeba1f..c150496 100644 --- a/hw/pci-host/aspeed_pcie.c +++ b/hw/pci-host/aspeed_pcie.c
@@ -27,44 +27,6 @@ #include "trace.h" /* - * PCIe Root Device - * This device exists only on AST2600. - */ - -static void aspeed_pcie_root_device_class_init(ObjectClass *klass, - const void *data) -{ - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - DeviceClass *dc = DEVICE_CLASS(klass); - - set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); - dc->desc = "ASPEED PCIe Root Device"; - k->vendor_id = PCI_VENDOR_ID_ASPEED; - k->device_id = 0x2600; - k->class_id = PCI_CLASS_BRIDGE_HOST; - k->subsystem_vendor_id = k->vendor_id; - k->subsystem_id = k->device_id; - k->revision = 0; - - /* - * PCI-facing part of the host bridge, - * not usable without the host-facing part - */ - dc->user_creatable = false; -} - -static const TypeInfo aspeed_pcie_root_device_info = { - .name = TYPE_ASPEED_PCIE_ROOT_DEVICE, - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(AspeedPCIERootDeviceState), - .class_init = aspeed_pcie_root_device_class_init, - .interfaces = (const InterfaceInfo[]) { - { INTERFACE_CONVENTIONAL_PCI_DEVICE }, - { }, - }, -}; - -/* * PCIe Root Port */ @@ -291,18 +253,6 @@ &rc->dram_alias); pci_setup_iommu(pci->bus, &aspeed_pcie_rc_iommu_ops, rc); - /* setup root device */ - if (rc->has_rd) { - object_initialize_child(OBJECT(rc), "root_device", &rc->root_device, - TYPE_ASPEED_PCIE_ROOT_DEVICE); - qdev_prop_set_int32(DEVICE(&rc->root_device), "addr", - PCI_DEVFN(0, 0)); - qdev_prop_set_bit(DEVICE(&rc->root_device), "multifunction", false); - if (!qdev_realize(DEVICE(&rc->root_device), BUS(pci->bus), errp)) { - return; - } - } - /* setup root port */ qdev_prop_set_int32(DEVICE(&rc->root_port), "addr", rc->rp_addr); qdev_prop_set_uint16(DEVICE(&rc->root_port), "chassis", cfg->id); @@ -318,7 +268,7 @@ AspeedPCIECfgState *cfg = container_of(rc, AspeedPCIECfgState, rc); - snprintf(rc->name, sizeof(rc->name), "%04x:%02x", cfg->id, rc->bus_nr); + snprintf(rc->name, sizeof(rc->name), "%04x:00", cfg->id); return rc->name; } @@ -333,8 +283,6 @@ } static const Property aspeed_pcie_rc_props[] = { - DEFINE_PROP_UINT32("bus-nr", AspeedPCIERcState, bus_nr, 0), - DEFINE_PROP_BOOL("has-rd", AspeedPCIERcState, has_rd, 0), DEFINE_PROP_UINT32("rp-addr", AspeedPCIERcState, rp_addr, 0), DEFINE_PROP_UINT32("msi-addr", AspeedPCIERcState, msi_addr, 0), DEFINE_PROP_UINT64("dram-base", AspeedPCIERcState, dram_base, 0), @@ -540,17 +488,6 @@ offset = cfg_addr & 0xffc; pci = PCI_HOST_BRIDGE(rc); - - /* - * On the AST2600, the RC_H bus number range from 0x80 to 0xFF, with the - * root device and root port assigned to bus 0x80 instead of the standard - * 0x00. To allow the PCI subsystem to correctly discover devices on the - * root bus, bus 0x80 is remapped to 0x00. - */ - if (bus == rc->bus_nr) { - bus = 0; - } - pdev = pci_find_device(pci->bus, bus, devfn); if (!pdev) { s->regs[desc->rdata_reg] = ~0; @@ -700,12 +637,6 @@ apc->nr_regs << 2); sysbus_init_mmio(sbd, &s->mmio); - object_property_set_int(OBJECT(&s->rc), "bus-nr", - apc->rc_bus_nr, - &error_abort); - object_property_set_bool(OBJECT(&s->rc), "has-rd", - apc->rc_has_rd, - &error_abort); object_property_set_int(OBJECT(&s->rc), "rp-addr", apc->rc_rp_addr, &error_abort); @@ -744,8 +675,6 @@ apc->reg_map = &aspeed_regmap; apc->nr_regs = 0x100 >> 2; apc->rc_msi_addr = 0x1e77005C; - apc->rc_bus_nr = 0x80; - apc->rc_has_rd = true; apc->rc_rp_addr = PCI_DEVFN(8, 0); } @@ -865,8 +794,6 @@ apc->reg_map = &aspeed_2700_regmap; apc->nr_regs = 0x100 >> 2; apc->rc_msi_addr = 0x000000F0; - apc->rc_bus_nr = 0; - apc->rc_has_rd = false; apc->rc_rp_addr = PCI_DEVFN(0, 0); } @@ -1040,7 +967,6 @@ static void aspeed_pcie_register_types(void) { type_register_static(&aspeed_pcie_rc_info); - type_register_static(&aspeed_pcie_root_device_info); type_register_static(&aspeed_pcie_root_port_info); type_register_static(&aspeed_pcie_cfg_info); type_register_static(&aspeed_2700_pcie_cfg_info);
diff --git a/hw/uefi/var-service-vars.c b/hw/uefi/var-service-vars.c index 8533533..94f40ef 100644 --- a/hw/uefi/var-service-vars.c +++ b/hw/uefi/var-service-vars.c
@@ -475,7 +475,8 @@ goto rollback; } if (old_var && new_var) { - if (uefi_time_compare(&old_var->time, &new_var->time) > 0) { + if ((va->attributes & EFI_VARIABLE_APPEND_WRITE) == 0 && + uefi_time_compare(&old_var->time, &new_var->time) > 0) { trace_uefi_vars_security_violation("time check failed"); mvar->status = EFI_SECURITY_VIOLATION; goto rollback; @@ -592,7 +593,7 @@ return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE); } - ps->payload_size = uv->buf_size; + ps->payload_size = uv->buf_size - sizeof(*mhdr) - sizeof(*mvar); mvar->status = EFI_SUCCESS; return length; }
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h index 3b50ecf..9113527 100644 --- a/include/disas/dis-asm.h +++ b/include/disas/dis-asm.h
@@ -397,7 +397,7 @@ bool show_opcodes; /* Field intended to be used by targets in any way they deem suitable. */ - void *target_info; + const void *target_info; /* Options for Capstone disassembly. */ int cap_arch;
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h index 4b8ee09..b036116 100644 --- a/include/hw/acpi/acpi.h +++ b/include/hw/acpi/acpi.h
@@ -203,4 +203,7 @@ }; int acpi_get_slic_oem(AcpiSlicOem *oem); +/* core.c */ +int acpi_checksum(const uint8_t *data, int len); + #endif /* QEMU_HW_ACPI_H */
diff --git a/include/hw/arm/aspeed_ast1700.h b/include/hw/arm/aspeed_ast1700.h new file mode 100644 index 0000000..f7bd4e8 --- /dev/null +++ b/include/hw/arm/aspeed_ast1700.h
@@ -0,0 +1,54 @@ +/* + * ASPEED AST1700 IO Expander + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef ASPEED_AST1700_H +#define ASPEED_AST1700_H + +#include "hw/core/sysbus.h" +#include "hw/misc/aspeed_scu.h" +#include "hw/adc/aspeed_adc.h" +#include "hw/gpio/aspeed_gpio.h" +#include "hw/gpio/aspeed_sgpio.h" +#include "hw/i2c/aspeed_i2c.h" +#include "hw/misc/aspeed_ltpi.h" +#include "hw/misc/aspeed_pwm.h" +#include "hw/ssi/aspeed_smc.h" +#include "hw/watchdog/wdt_aspeed.h" +#include "hw/char/serial-mm.h" +#include "hw/misc/unimp.h" + +#define AST1700_SGPIO_NUM 2 +#define AST1700_WDT_NUM 9 + +#define TYPE_ASPEED_AST1700 "aspeed.ast1700" + +OBJECT_DECLARE_SIMPLE_TYPE(AspeedAST1700SoCState, ASPEED_AST1700) + +struct AspeedAST1700SoCState { + SysBusDevice parent_obj; + + MemoryRegion iomem; + MemoryRegion *dram_mr; + uint8_t board_idx; + uint32_t silicon_rev; + + AspeedLTPIState ltpi; + SerialMM uart; + MemoryRegion sram; + AspeedSMCState spi; + AspeedADCState adc; + AspeedSCUState scu; + AspeedGPIOState gpio; + AspeedSGPIOState sgpiom[AST1700_SGPIO_NUM]; + AspeedI2CState i2c; + AspeedPWMState pwm; + AspeedWDTState wdt[AST1700_WDT_NUM]; + + UnimplementedDeviceState i3c; +}; + +#endif /* ASPEED_AST1700_H */
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h index 18ff961..b185b04 100644 --- a/include/hw/arm/aspeed_soc.h +++ b/include/hw/arm/aspeed_soc.h
@@ -28,6 +28,7 @@ #include "hw/misc/aspeed_hace.h" #include "hw/misc/aspeed_sbc.h" #include "hw/misc/aspeed_sli.h" +#include "hw/misc/aspeed_pwm.h" #include "hw/watchdog/wdt_aspeed.h" #include "hw/net/ftgmac100.h" #include "target/arm/cpu.h" @@ -43,6 +44,8 @@ #include "hw/fsi/aspeed_apb2opb.h" #include "hw/char/serial-mm.h" #include "hw/intc/arm_gicv3.h" +#include "hw/misc/aspeed_ltpi.h" +#include "hw/arm/aspeed_ast1700.h" #define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin" @@ -55,6 +58,8 @@ #define ASPEED_UARTS_NUM 13 #define ASPEED_JTAG_NUM 2 #define ASPEED_PCIE_NUM 3 +#define ASPEED_INTC_NUM 2 +#define ASPEED_IOEXP_NUM 2 struct AspeedSoCState { DeviceState parent; @@ -86,6 +91,7 @@ MemoryRegion secsram; UnimplementedDeviceState sbc_unimplemented; AspeedSDMCState sdmc; + AspeedPWMState pwm; AspeedWDTState wdt[ASPEED_WDTS_NUM]; FTGMAC100State ftgmac100[ASPEED_MACS_NUM]; AspeedMiiState mii[ASPEED_MACS_NUM]; @@ -106,12 +112,12 @@ UnimplementedDeviceState video; UnimplementedDeviceState emmc_boot_controller; UnimplementedDeviceState dpmcu; - UnimplementedDeviceState pwm; UnimplementedDeviceState espi; UnimplementedDeviceState udc; - UnimplementedDeviceState ltpi; UnimplementedDeviceState jtag[ASPEED_JTAG_NUM]; AspeedAPB2OPBState fsi[2]; + AspeedLTPIState ltpi_ctrl[ASPEED_IOEXP_NUM]; + AspeedAST1700SoCState ioexp[ASPEED_IOEXP_NUM]; }; #define TYPE_ASPEED_SOC "aspeed-soc" @@ -141,7 +147,8 @@ AspeedSoCState parent; ARMCPU cpu[ASPEED_CPUS_NUM]; - AspeedINTCState intc[2]; + AspeedINTCState intc[ASPEED_INTC_NUM]; + AspeedINTCState intcioexp[ASPEED_IOEXP_NUM]; GICv3State gic; MemoryRegion dram_empty; }; @@ -174,6 +181,7 @@ int macs_num; int uarts_num; int uarts_base; + int ioexp_num; const int *irqmap; const hwaddr *memmap; uint32_t num_cpus; @@ -186,7 +194,6 @@ ASPEED_DEV_IOMEM, ASPEED_DEV_IOMEM0, ASPEED_DEV_IOMEM1, - ASPEED_DEV_LTPI, ASPEED_DEV_UART0, ASPEED_DEV_UART1, ASPEED_DEV_UART2, @@ -279,6 +286,16 @@ ASPEED_GIC_REDIST, ASPEED_DEV_IPC0, ASPEED_DEV_IPC1, + ASPEED_DEV_LTPI_CTRL1, + ASPEED_DEV_LTPI_CTRL2, + ASPEED_DEV_LTPI_IO0, + ASPEED_DEV_LTPI_IO1, + ASPEED_DEV_IOEXP0_I2C, + ASPEED_DEV_IOEXP1_I2C, + ASPEED_DEV_IOEXP0_INTCIO, + ASPEED_DEV_IOEXP1_INTCIO, + ASPEED_DEV_IOEXP0_I3C, + ASPEED_DEV_IOEXP1_I3C, }; const char *aspeed_soc_cpu_type(const char * const *valid_cpu_types);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 9867870..ef20cb3 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h
@@ -175,7 +175,7 @@ const char * (*gdb_arch_name)(CPUState *cpu); const char * (*gdb_get_core_xml_file)(CPUState *cpu); - void (*disas_set_info)(CPUState *cpu, disassemble_info *info); + void (*disas_set_info)(const CPUState *cpu, disassemble_info *info); const char *deprecation_note; struct AccelCPUClass *accel_cpu;
diff --git a/include/hw/gpio/pca9552.h b/include/hw/gpio/pca9552.h index c36525f..43b1752 100644 --- a/include/hw/gpio/pca9552.h +++ b/include/hw/gpio/pca9552.h
@@ -14,6 +14,7 @@ #define TYPE_PCA9552 "pca9552" #define TYPE_PCA955X "pca955x" +#define TYPE_PCA9535 "pca9535" typedef struct PCA955xState PCA955xState; DECLARE_INSTANCE_CHECKER(PCA955xState, PCA955X, TYPE_PCA955X)
diff --git a/include/hw/gpio/pca9552_regs.h b/include/hw/gpio/pca9552_regs.h index d8051cf..5a6bb03 100644 --- a/include/hw/gpio/pca9552_regs.h +++ b/include/hw/gpio/pca9552_regs.h
@@ -29,4 +29,14 @@ */ #define PCA9552_AUTOINC (1 << 4) +/* PCA9535 Registers (same addresses, different semantics) */ +#define PCA9535_INPUT0 0 /* read only input register 0 */ +#define PCA9535_INPUT1 1 /* read only input register 1 */ +#define PCA9535_OUTPUT0 2 /* read/write output register 0 */ +#define PCA9535_OUTPUT1 3 /* read/write output register 1 */ +#define PCA9535_POLARITY0 4 /* read/write polarity inversion register 0 */ +#define PCA9535_POLARITY1 5 /* read/write polarity inversion register 1 */ +#define PCA9535_CONFIG0 6 /* read/write configuration register 0 */ +#define PCA9535_CONFIG1 7 /* read/write configuration register 1 */ + #endif
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h index ffcff25..68bd138 100644 --- a/include/hw/i2c/aspeed_i2c.h +++ b/include/hw/i2c/aspeed_i2c.h
@@ -252,6 +252,7 @@ MemoryRegion mr_pool; I2CBus *bus; + char *name; uint8_t id; qemu_irq irq; @@ -269,6 +270,7 @@ uint32_t intr_status; uint32_t ctrl_global; uint32_t new_clk_divider; + char *bus_label; MemoryRegion pool_iomem; uint8_t share_pool[ASPEED_I2C_SHARE_POOL_SIZE];
diff --git a/include/hw/intc/aspeed_intc.h b/include/hw/intc/aspeed_intc.h index 5d10268..b25ef4a 100644 --- a/include/hw/intc/aspeed_intc.h +++ b/include/hw/intc/aspeed_intc.h
@@ -15,6 +15,8 @@ #define TYPE_ASPEED_INTC "aspeed.intc" #define TYPE_ASPEED_2700_INTC TYPE_ASPEED_INTC "-ast2700" #define TYPE_ASPEED_2700_INTCIO TYPE_ASPEED_INTC "io-ast2700" +#define TYPE_ASPEED_2700_INTCIOEXP1 TYPE_ASPEED_INTC "-ast2700-ioexp1" +#define TYPE_ASPEED_2700_INTCIOEXP2 TYPE_ASPEED_INTC "-ast2700-ioexp2" #define TYPE_ASPEED_2700SSP_INTC TYPE_ASPEED_INTC "-ast2700ssp" #define TYPE_ASPEED_2700SSP_INTCIO TYPE_ASPEED_INTC "io-ast2700ssp" #define TYPE_ASPEED_2700TSP_INTC TYPE_ASPEED_INTC "-ast2700tsp"
diff --git a/include/hw/misc/aspeed_ltpi.h b/include/hw/misc/aspeed_ltpi.h new file mode 100644 index 0000000..3330a49 --- /dev/null +++ b/include/hw/misc/aspeed_ltpi.h
@@ -0,0 +1,33 @@ +/* + * ASPEED LTPI Controller + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#ifndef ASPEED_LTPI_H +#define ASPEED_LTPI_H + +#include "hw/core/sysbus.h" + +#define TYPE_ASPEED_LTPI "aspeed.ltpi-ctrl" +OBJECT_DECLARE_SIMPLE_TYPE(AspeedLTPIState, ASPEED_LTPI) + +#define ASPEED_LTPI_TOTAL_SIZE 0x900 +#define ASPEED_LTPI_CTRL_SIZE 0x200 +#define ASPEED_LTPI_PHY_SIZE 0x100 +#define ASPEED_LTPI_TOP_SIZE 0x100 + +struct AspeedLTPIState { + SysBusDevice parent; + MemoryRegion mmio; + MemoryRegion mmio_ctrl; + MemoryRegion mmio_phy; + MemoryRegion mmio_top; + + uint32_t ctrl_regs[ASPEED_LTPI_CTRL_SIZE >> 2]; + uint32_t phy_regs[ASPEED_LTPI_PHY_SIZE >> 2]; + uint32_t top_regs[ASPEED_LTPI_TOP_SIZE >> 2]; +}; + +#endif /* ASPEED_LTPI_H */
diff --git a/include/hw/misc/aspeed_pwm.h b/include/hw/misc/aspeed_pwm.h new file mode 100644 index 0000000..f4104ad --- /dev/null +++ b/include/hw/misc/aspeed_pwm.h
@@ -0,0 +1,30 @@ +/* + * ASPEED PWM Controller + * + * Copyright (C) 2017-2021 IBM Corp. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef ASPEED_PWM_H +#define ASPEED_PWM_H + +#include "hw/core/sysbus.h" + +#define TYPE_ASPEED_PWM "aspeed.pwm" +#define ASPEED_PWM(obj) OBJECT_CHECK(AspeedPWMState, (obj), TYPE_ASPEED_PWM) + +#define ASPEED_PWM_NR_REGS (0x10C >> 2) + +typedef struct AspeedPWMState { + /* <private> */ + SysBusDevice parent; + + /*< public >*/ + MemoryRegion iomem; + qemu_irq irq; + + uint32_t regs[ASPEED_PWM_NR_REGS]; +} AspeedPWMState; + +#endif /* _ASPEED_PWM_H_ */
diff --git a/include/hw/pci-host/aspeed_pcie.h b/include/hw/pci-host/aspeed_pcie.h index e660119..143b356 100644 --- a/include/hw/pci-host/aspeed_pcie.h +++ b/include/hw/pci-host/aspeed_pcie.h
@@ -50,13 +50,6 @@ PCIESlot parent_obj; } AspeedPCIERootPortState; -#define TYPE_ASPEED_PCIE_ROOT_DEVICE "aspeed.pcie-root-device" -OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERootDeviceState, ASPEED_PCIE_ROOT_DEVICE); - -struct AspeedPCIERootDeviceState { - PCIBridge parent_obj; -}; - #define TYPE_ASPEED_PCIE_RC "aspeed.pcie-rc" OBJECT_DECLARE_SIMPLE_TYPE(AspeedPCIERcState, ASPEED_PCIE_RC); @@ -76,12 +69,9 @@ uint64_t dram_base; uint32_t msi_addr; uint32_t rp_addr; - uint32_t bus_nr; char name[16]; - bool has_rd; qemu_irq irq; - AspeedPCIERootDeviceState root_device; AspeedPCIERootPortState root_port; }; @@ -111,7 +101,6 @@ uint32_t rc_msi_addr; uint32_t rc_rp_addr; - uint64_t rc_bus_nr; uint64_t nr_regs; bool rc_has_rd; };
diff --git a/include/qemu/target-info.h b/include/qemu/target-info.h index 6235962..e328733 100644 --- a/include/qemu/target-info.h +++ b/include/qemu/target-info.h
@@ -71,4 +71,25 @@ */ bool target_aarch64(void); +/** + * target_base_ppc: + * + * Returns whether the target architecture is PowerPC 32-bit or 64-bit. + */ +bool target_base_ppc(void); + +/** + * target_ppc: + * + * Returns whether the target architecture is PowerPC 32-bit. + */ +bool target_ppc(void); + +/** + * target_ppc64: + * + * Returns whether the target architecture is PowerPC 64-bit. + */ +bool target_ppc64(void); + #endif
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index 4a94af9..416a8c9 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h
@@ -55,6 +55,7 @@ typedef struct HostMemoryBackend HostMemoryBackend; typedef struct I2CBus I2CBus; typedef struct I2SCodec I2SCodec; +typedef struct IgvmCfg IgvmCfg; typedef struct IOMMUMemoryRegion IOMMUMemoryRegion; typedef struct ISABus ISABus; typedef struct ISADevice ISADevice;
diff --git a/include/system/igvm-cfg.h b/include/system/igvm-cfg.h index 944f23a..e06d611 100644 --- a/include/system/igvm-cfg.h +++ b/include/system/igvm-cfg.h
@@ -12,19 +12,10 @@ #ifndef QEMU_IGVM_CFG_H #define QEMU_IGVM_CFG_H +#include "hw/core/boards.h" +#include "qemu/typedefs.h" #include "qom/object.h" -typedef struct IgvmCfg { - ObjectClass parent_class; - - /* - * filename: Filename that specifies a file that contains the configuration - * of the guest in Independent Guest Virtual Machine (IGVM) - * format. - */ - char *filename; -} IgvmCfg; - typedef struct IgvmCfgClass { ObjectClass parent_class; @@ -37,7 +28,7 @@ * * Returns 0 for ok and -1 on error. */ - int (*process)(IgvmCfg *cfg, ConfidentialGuestSupport *cgs, + int (*process)(IgvmCfg *cfg, MachineState *machine_state, bool onlyVpContext, Error **errp); } IgvmCfgClass;
diff --git a/include/system/igvm-internal.h b/include/system/igvm-internal.h new file mode 100644 index 0000000..38004bd --- /dev/null +++ b/include/system/igvm-internal.h
@@ -0,0 +1,82 @@ +/* + * QEMU IGVM private data structures + * + * Everything which depends on igvm library headers goes here. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef QEMU_IGVM_INTERNAL_H +#define QEMU_IGVM_INTERNAL_H + +#include "qemu/queue.h" +#include "qemu/typedefs.h" +#include "qom/object.h" +#include "hw/core/boards.h" +#include "hw/core/resettable.h" + +#include "system/confidential-guest-support.h" +#include <igvm/igvm.h> + +struct IgvmCfg { + ObjectClass parent_class; + + /* + * filename: Filename that specifies a file that contains the configuration + * of the guest in Independent Guest Virtual Machine (IGVM) + * format. + */ + char *filename; + IgvmHandle file; + ResettableState reset_state; +}; + +typedef struct QIgvmParameterData { + QTAILQ_ENTRY(QIgvmParameterData) next; + uint8_t *data; + uint32_t size; + uint32_t index; +} QIgvmParameterData; + +/* + * QIgvm contains the information required during processing of a single IGVM + * file. + */ +typedef struct QIgvm { + IgvmHandle file; + MachineState *machine_state; + ConfidentialGuestSupportClass *cgsc; + uint32_t compatibility_mask; + unsigned current_header_index; + QTAILQ_HEAD(, QIgvmParameterData) parameter_data; + IgvmPlatformType platform_type; + + /* + * SEV-SNP platforms can contain an ID block and authentication + * that should be verified by the guest. + */ + struct sev_id_block *id_block; + struct sev_id_authentication *id_auth; + + /* Define the guest policy for SEV guests */ + uint64_t sev_policy; + + /* These variables keep track of contiguous page regions */ + IGVM_VHS_PAGE_DATA region_prev_page_data; + uint64_t region_start; + unsigned region_start_index; + unsigned region_last_index; + unsigned region_page_count; +} QIgvm; + +IgvmHandle qigvm_file_init(char *filename, Error **errp); + +QIgvmParameterData* +qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index); + +/* + * IGVM parameter handlers + */ +int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp); + +#endif
diff --git a/include/system/igvm.h b/include/system/igvm.h index 48ce206..5573a61 100644 --- a/include/system/igvm.h +++ b/include/system/igvm.h
@@ -12,12 +12,13 @@ #ifndef BACKENDS_IGVM_H #define BACKENDS_IGVM_H +#include "hw/core/boards.h" +#include "qemu/typedefs.h" #include "system/confidential-guest-support.h" -#include "system/igvm-cfg.h" #include "qapi/error.h" -int qigvm_process_file(IgvmCfg *igvm, ConfidentialGuestSupport *cgs, - bool onlyVpContext, Error **errp); +int qigvm_process_file(IgvmCfg *igvm, MachineState *machine_state, + bool onlyVpContext, Error **errp); /* x86 native */ int qigvm_x86_get_mem_map_entry(int index,
diff --git a/pc-bios/ast27x0_bootrom.bin b/pc-bios/ast27x0_bootrom.bin index a4c94d6..626499b 100644 --- a/pc-bios/ast27x0_bootrom.bin +++ b/pc-bios/ast27x0_bootrom.bin Binary files differ
diff --git a/pc-bios/npcm7xx_bootrom.bin b/pc-bios/npcm7xx_bootrom.bin index 9228289..60e5517 100644 --- a/pc-bios/npcm7xx_bootrom.bin +++ b/pc-bios/npcm7xx_bootrom.bin Binary files differ
diff --git a/pc-bios/npcm8xx_bootrom.bin b/pc-bios/npcm8xx_bootrom.bin index 45fb40f..4b6f82f 100644 --- a/pc-bios/npcm8xx_bootrom.bin +++ b/pc-bios/npcm8xx_bootrom.bin Binary files differ
diff --git a/roms/vbootrom b/roms/vbootrom index 183c9ff..1c8e951 160000 --- a/roms/vbootrom +++ b/roms/vbootrom
@@ -1 +1 @@ -Subproject commit 183c9ff8056b7946db1ae49cc23e8980ac413174 +Subproject commit 1c8e9510b22c5b0fd7d7753f08042a4bcbd2939d
diff --git a/stubs/igvm.c b/stubs/igvm.c index 17cd1e9..47d5130 100644 --- a/stubs/igvm.c +++ b/stubs/igvm.c
@@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "system/igvm.h" +#include "system/igvm-internal.h" int qigvm_x86_get_mem_map_entry(int index, ConfidentialGuestMemoryMapEntry *entry, @@ -24,3 +25,8 @@ { return -1; } + +int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) +{ + return -1; +}
diff --git a/stubs/meson.build b/stubs/meson.build index 2b5fd8a..8a07059 100644 --- a/stubs/meson.build +++ b/stubs/meson.build
@@ -71,7 +71,9 @@ stub_ss.add(files('dump.c')) stub_ss.add(files('cmos.c')) stub_ss.add(files('fw_cfg.c')) - stub_ss.add(files('igvm.c')) + if igvm.found() + stub_ss.add(files('igvm.c')) + endif stub_ss.add(files('target-get-monitor-def.c')) stub_ss.add(files('target-monitor-defs.c')) stub_ss.add(files('win32-kbd-hook.c'))
diff --git a/target-info.c b/target-info.c index 24696ff..5a6d728 100644 --- a/target-info.c +++ b/target-info.c
@@ -73,3 +73,24 @@ { return target_arch() == SYS_EMU_TARGET_AARCH64; } + +bool target_base_ppc(void) +{ + switch (target_arch()) { + case SYS_EMU_TARGET_PPC: + case SYS_EMU_TARGET_PPC64: + return true; + default: + return false; + } +} + +bool target_ppc(void) +{ + return target_arch() == SYS_EMU_TARGET_PPC; +} + +bool target_ppc64(void) +{ + return target_arch() == SYS_EMU_TARGET_PPC64; +}
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c index 932cdda..1780db7 100644 --- a/target/alpha/cpu.c +++ b/target/alpha/cpu.c
@@ -98,7 +98,8 @@ return alpha_env_mmu_index(cpu_env(cs)); } -static void alpha_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +static void alpha_cpu_disas_set_info(const CPUState *cpu, + disassemble_info *info) { info->endian = BFD_ENDIAN_LITTLE; info->mach = bfd_mach_alpha_ev6;
diff --git a/target/alpha/gdbstub.c b/target/alpha/gdbstub.c index 1a7e2dd..a7110e8 100644 --- a/target/alpha/gdbstub.c +++ b/target/alpha/gdbstub.c
@@ -59,7 +59,7 @@ int alpha_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { CPUAlphaState *env = cpu_env(cs); - target_ulong tmp = ldq_le_p(mem_buf); + uint64_t tmp = ldq_le_p(mem_buf); CPU_DoubleU d; switch (n) {
diff --git a/target/alpha/helper.c b/target/alpha/helper.c index 126a53c..179dc2d 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c
@@ -129,7 +129,7 @@ bool maperr, uintptr_t retaddr) { CPUAlphaState *env = cpu_env(cs); - target_ulong mmcsr, cause; + uint64_t mmcsr, cause; /* Assuming !maperr, infer the missing protection. */ switch (access_type) { @@ -165,16 +165,17 @@ } #else /* Returns the OSF/1 entMM failure indication, or -1 on success. */ -static int get_physical_address(CPUAlphaState *env, target_ulong addr, +static int get_physical_address(CPUAlphaState *env, vaddr addr, int prot_need, int mmu_idx, - target_ulong *pphys, int *pprot) + hwaddr *pphys, int *pprot) { const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED; CPUState *cs = env_cpu(env); target_long saddr = addr; - target_ulong phys = 0; - target_ulong L1pte, L2pte, L3pte; - target_ulong pt, index; + hwaddr phys = 0; + uint64_t L1pte, L2pte, L3pte; + uint64_t pt; + uint16_t index; int prot = 0; int ret = MM_K_ACV; MemTxResult txres; @@ -296,7 +297,7 @@ hwaddr alpha_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { - target_ulong phys; + hwaddr phys; int prot, fail; fail = get_physical_address(cpu_env(cs), addr, 0, 0, &phys, &prot); @@ -308,7 +309,7 @@ bool probe, uintptr_t retaddr) { CPUAlphaState *env = cpu_env(cs); - target_ulong phys; + hwaddr phys; int prot, fail; fail = get_physical_address(env, addr, 1 << access_type,
diff --git a/target/alpha/machine.c b/target/alpha/machine.c index 6828b12..dcba5d4 100644 --- a/target/alpha/machine.c +++ b/target/alpha/machine.c
@@ -1,6 +1,7 @@ #include "qemu/osdep.h" #include "cpu.h" -#include "migration/cpu.h" +#include "migration/qemu-file-types.h" +#include "migration/vmstate.h" static int get_fpcr(QEMUFile *f, void *opaque, size_t size, const VMStateField *field)
diff --git a/target/alpha/meson.build b/target/alpha/meson.build index 7dbbd55..9447f80 100644 --- a/target/alpha/meson.build +++ b/target/alpha/meson.build
@@ -18,4 +18,4 @@ )) target_arch += {'alpha': alpha_ss} -target_system_arch += {'alpha': alpha_system_ss} +target_common_system_arch += {'alpha': alpha_system_ss}
diff --git a/target/alpha/translate.c b/target/alpha/translate.c index 48ac50a..4442462 100644 --- a/target/alpha/translate.c +++ b/target/alpha/translate.c
@@ -65,11 +65,11 @@ int tb_ftz; /* The set of registers active in the current context. */ - TCGv *ir; + TCGv_i64 *ir; /* Temporaries for $31 and $f31 as source and destination. */ - TCGv zero; - TCGv sink; + TCGv_i64 zero; + TCGv_i64 sink; }; #ifdef CONFIG_USER_ONLY @@ -86,21 +86,21 @@ #define DISAS_PC_STALE DISAS_TARGET_2 /* global register indexes */ -static TCGv cpu_std_ir[31]; -static TCGv cpu_fir[31]; -static TCGv cpu_pc; -static TCGv cpu_lock_addr; -static TCGv cpu_lock_value; +static TCGv_i64 cpu_std_ir[31]; +static TCGv_i64 cpu_fir[31]; +static TCGv_i64 cpu_pc; +static TCGv_i64 cpu_lock_addr; +static TCGv_i64 cpu_lock_value; #ifndef CONFIG_USER_ONLY -static TCGv cpu_pal_ir[31]; +static TCGv_i64 cpu_pal_ir[31]; #endif void alpha_translate_init(void) { #define DEF_VAR(V) { &cpu_##V, #V, offsetof(CPUAlphaState, V) } - typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar; + typedef struct { TCGv_i64 *var; const char *name; int ofs; } GlobalVar; static const GlobalVar vars[] = { DEF_VAR(pc), DEF_VAR(lock_addr), @@ -160,7 +160,7 @@ } } -static TCGv load_zero(DisasContext *ctx) +static TCGv_i64 load_zero(DisasContext *ctx) { if (!ctx->zero) { ctx->zero = tcg_constant_i64(0); @@ -168,10 +168,10 @@ return ctx->zero; } -static TCGv dest_sink(DisasContext *ctx) +static TCGv_i64 dest_sink(DisasContext *ctx) { if (!ctx->sink) { - ctx->sink = tcg_temp_new(); + ctx->sink = tcg_temp_new_i64(); } return ctx->sink; } @@ -184,7 +184,7 @@ } } -static TCGv load_gpr(DisasContext *ctx, unsigned reg) +static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg) { if (likely(reg < 31)) { return ctx->ir[reg]; @@ -193,7 +193,7 @@ } } -static TCGv load_gpr_lit(DisasContext *ctx, unsigned reg, +static TCGv_i64 load_gpr_lit(DisasContext *ctx, unsigned reg, uint8_t lit, bool islit) { if (islit) { @@ -205,7 +205,7 @@ } } -static TCGv dest_gpr(DisasContext *ctx, unsigned reg) +static TCGv_i64 dest_gpr(DisasContext *ctx, unsigned reg) { if (likely(reg < 31)) { return ctx->ir[reg]; @@ -214,7 +214,7 @@ } } -static TCGv load_fpr(DisasContext *ctx, unsigned reg) +static TCGv_i64 load_fpr(DisasContext *ctx, unsigned reg) { if (likely(reg < 31)) { return cpu_fir[reg]; @@ -223,7 +223,7 @@ } } -static TCGv dest_fpr(DisasContext *ctx, unsigned reg) +static TCGv_i64 dest_fpr(DisasContext *ctx, unsigned reg) { if (likely(reg < 31)) { return cpu_fir[reg]; @@ -243,17 +243,17 @@ return ofs; } -static void ld_flag_byte(TCGv val, unsigned shift) +static void ld_flag_byte(TCGv_i64 val, unsigned shift) { tcg_gen_ld8u_i64(val, tcg_env, get_flag_ofs(shift)); } -static void st_flag_byte(TCGv val, unsigned shift) +static void st_flag_byte(TCGv_i64 val, unsigned shift) { tcg_gen_st8_i64(val, tcg_env, get_flag_ofs(shift)); } -static void gen_pc_disp(DisasContext *ctx, TCGv dest, int32_t disp) +static void gen_pc_disp(DisasContext *ctx, TCGv_i64 dest, int32_t disp) { uint64_t addr = ctx->base.pc_next + disp; if (ctx->pcrel) { @@ -284,38 +284,38 @@ return gen_excp(ctx, EXCP_OPCDEC, 0); } -static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr) +static void gen_ldf(DisasContext *ctx, TCGv_i64 dest, TCGv_i64 addr) { TCGv_i32 tmp32 = tcg_temp_new_i32(); tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); gen_helper_memory_to_f(dest, tmp32); } -static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr) +static void gen_ldg(DisasContext *ctx, TCGv_i64 dest, TCGv_i64 addr) { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); gen_helper_memory_to_g(dest, tmp); } -static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr) +static void gen_lds(DisasContext *ctx, TCGv_i64 dest, TCGv_i64 addr) { TCGv_i32 tmp32 = tcg_temp_new_i32(); tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); gen_helper_memory_to_s(dest, tmp32); } -static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr) +static void gen_ldt(DisasContext *ctx, TCGv_i64 dest, TCGv_i64 addr) { tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); } static void gen_load_fp(DisasContext *ctx, int ra, int rb, int32_t disp16, - void (*func)(DisasContext *, TCGv, TCGv)) + void (*func)(DisasContext *, TCGv_i64, TCGv_i64)) { /* Loads to $f31 are prefetches, which we can treat as nops. */ if (likely(ra != 31)) { - TCGv addr = tcg_temp_new(); + TCGv_i64 addr = tcg_temp_new_i64(); tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); func(ctx, cpu_fir[ra], addr); } @@ -324,7 +324,7 @@ static void gen_load_int(DisasContext *ctx, int ra, int rb, int32_t disp16, MemOp op, bool clear, bool locked) { - TCGv addr, dest; + TCGv_i64 addr, dest; /* LDQ_U with ra $31 is UNOP. Other various loads are forms of prefetches, which we can treat as nops. No worries about @@ -333,7 +333,7 @@ return; } - addr = tcg_temp_new(); + addr = tcg_temp_new_i64(); tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); if (clear) { tcg_gen_andi_i64(addr, addr, ~0x7); @@ -350,36 +350,36 @@ } } -static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr) +static void gen_stf(DisasContext *ctx, TCGv_i64 src, TCGv_i64 addr) { TCGv_i32 tmp32 = tcg_temp_new_i32(); gen_helper_f_to_memory(tmp32, addr); tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); } -static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr) +static void gen_stg(DisasContext *ctx, TCGv_i64 src, TCGv_i64 addr) { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); gen_helper_g_to_memory(tmp, src); tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); } -static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr) +static void gen_sts(DisasContext *ctx, TCGv_i64 src, TCGv_i64 addr) { TCGv_i32 tmp32 = tcg_temp_new_i32(); gen_helper_s_to_memory(tmp32, src); tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL | UNALIGN(ctx)); } -static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr) +static void gen_stt(DisasContext *ctx, TCGv_i64 src, TCGv_i64 addr) { tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEUQ | UNALIGN(ctx)); } static void gen_store_fp(DisasContext *ctx, int ra, int rb, int32_t disp16, - void (*func)(DisasContext *, TCGv, TCGv)) + void (*func)(DisasContext *, TCGv_i64, TCGv_i64)) { - TCGv addr = tcg_temp_new(); + TCGv_i64 addr = tcg_temp_new_i64(); tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); func(ctx, load_fpr(ctx, ra), addr); } @@ -387,9 +387,9 @@ static void gen_store_int(DisasContext *ctx, int ra, int rb, int32_t disp16, MemOp op, bool clear) { - TCGv addr, src; + TCGv_i64 addr, src; - addr = tcg_temp_new(); + addr = tcg_temp_new_i64(); tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); if (clear) { tcg_gen_andi_i64(addr, addr, ~0x7); @@ -406,7 +406,7 @@ MemOp op) { TCGLabel *lab_fail, *lab_done; - TCGv addr, val; + TCGv_i64 addr, val; addr = tcg_temp_new_i64(); tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16); @@ -469,7 +469,8 @@ } static DisasJumpType gen_bcond_internal(DisasContext *ctx, TCGCond cond, - TCGv cmp, uint64_t imm, int32_t disp) + TCGv_i64 cmp, + uint64_t imm, int32_t disp) { TCGLabel *lab_true = gen_new_label(); @@ -616,9 +617,9 @@ #endif } -static TCGv gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp) +static TCGv_i64 gen_ieee_input(DisasContext *ctx, int reg, int fn11, int is_cmp) { - TCGv val; + TCGv_i64 val; if (unlikely(reg == 31)) { val = load_zero(ctx); @@ -674,9 +675,9 @@ } } -static void gen_cvtlq(TCGv vc, TCGv vb) +static void gen_cvtlq(TCGv_i64 vc, TCGv_i64 vb) { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); /* The arithmetic right shift here, plus the sign-extended mask below yields a sign-extended result without an explicit ext32s_i64. */ @@ -686,10 +687,10 @@ } static void gen_ieee_arith2(DisasContext *ctx, - void (*helper)(TCGv, TCGv_ptr, TCGv), + void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64), int rb, int rc, int fn11) { - TCGv vb; + TCGv_i64 vb; gen_qual_roundmode(ctx, fn11); gen_qual_flushzero(ctx, fn11); @@ -713,7 +714,7 @@ static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11) { - TCGv vb, vc; + TCGv_i64 vb, vc; /* No need to set flushzero, since we have an integer output. */ vb = gen_ieee_input(ctx, rb, fn11, 0); @@ -731,10 +732,10 @@ } static void gen_ieee_intcvt(DisasContext *ctx, - void (*helper)(TCGv, TCGv_ptr, TCGv), + void (*helper)(TCGv_i64, TCGv_ptr, TCGv_i64), int rb, int rc, int fn11) { - TCGv vb, vc; + TCGv_i64 vb, vc; gen_qual_roundmode(ctx, fn11); vb = load_fpr(ctx, rb); @@ -760,10 +761,11 @@ IEEE_INTCVT(cvtqs) IEEE_INTCVT(cvtqt) -static void gen_cpy_mask(TCGv vc, TCGv va, TCGv vb, bool inv_a, uint64_t mask) +static void gen_cpy_mask(TCGv_i64 vc, TCGv_i64 va, TCGv_i64 vb, + bool inv_a, uint64_t mask) { - TCGv vmask = tcg_constant_i64(mask); - TCGv tmp = tcg_temp_new_i64(); + TCGv_i64 vmask = tcg_constant_i64(mask); + TCGv_i64 tmp = tcg_temp_new_i64(); if (inv_a) { tcg_gen_andc_i64(tmp, vmask, va); @@ -776,10 +778,11 @@ } static void gen_ieee_arith3(DisasContext *ctx, - void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), + void (*helper)(TCGv_i64, TCGv_ptr, + TCGv_i64, TCGv_i64), int ra, int rb, int rc, int fn11) { - TCGv va, vb, vc; + TCGv_i64 va, vb, vc; gen_qual_roundmode(ctx, fn11); gen_qual_flushzero(ctx, fn11); @@ -808,10 +811,11 @@ IEEE_ARITH3(divt) static void gen_ieee_compare(DisasContext *ctx, - void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), + void (*helper)(TCGv_i64, TCGv_ptr, + TCGv_i64, TCGv_i64), int ra, int rb, int rc, int fn11) { - TCGv va, vb, vc; + TCGv_i64 va, vb, vc; va = gen_ieee_input(ctx, ra, fn11, 1); vb = gen_ieee_input(ctx, rb, fn11, 1); @@ -848,7 +852,7 @@ /* Implement zapnot with an immediate operand, which expands to some form of immediate AND. This is a basic building block in the definition of many of the other byte manipulation instructions. */ -static void gen_zapnoti(TCGv dest, TCGv src, uint8_t lit) +static void gen_zapnoti(TCGv_i64 dest, TCGv_i64 src, uint8_t lit) { switch (lit) { case 0x00: @@ -873,8 +877,8 @@ } /* EXTWH, EXTLH, EXTQH */ -static void gen_ext_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, - uint8_t lit, uint8_t byte_mask) +static void gen_ext_h(DisasContext *ctx, TCGv_i64 vc, TCGv_i64 va, + int rb, bool islit, uint8_t lit, uint8_t byte_mask) { if (islit) { int pos = (64 - lit * 8) & 0x3f; @@ -885,7 +889,7 @@ tcg_gen_movi_i64(vc, 0); } } else { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, load_gpr(ctx, rb), 3); tcg_gen_neg_i64(tmp, tmp); tcg_gen_andi_i64(tmp, tmp, 0x3f); @@ -895,8 +899,8 @@ } /* EXTBL, EXTWL, EXTLL, EXTQL */ -static void gen_ext_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, - uint8_t lit, uint8_t byte_mask) +static void gen_ext_l(DisasContext *ctx, TCGv_i64 vc, TCGv_i64 va, + int rb, bool islit, uint8_t lit, uint8_t byte_mask) { if (islit) { int pos = (lit & 7) * 8; @@ -906,7 +910,7 @@ } tcg_gen_extract_i64(vc, va, pos, len); } else { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_andi_i64(tmp, load_gpr(ctx, rb), 7); tcg_gen_shli_i64(tmp, tmp, 3); tcg_gen_shr_i64(vc, va, tmp); @@ -915,8 +919,8 @@ } /* INSWH, INSLH, INSQH */ -static void gen_ins_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, - uint8_t lit, uint8_t byte_mask) +static void gen_ins_h(DisasContext *ctx, TCGv_i64 vc, TCGv_i64 va, + int rb, bool islit, uint8_t lit, uint8_t byte_mask) { if (islit) { int pos = 64 - (lit & 7) * 8; @@ -927,8 +931,8 @@ tcg_gen_movi_i64(vc, 0); } } else { - TCGv tmp = tcg_temp_new(); - TCGv shift = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); + TCGv_i64 shift = tcg_temp_new_i64(); /* The instruction description has us left-shift the byte mask and extract bits <15:8> and apply that zap at the end. This @@ -951,8 +955,8 @@ } /* INSBL, INSWL, INSLL, INSQL */ -static void gen_ins_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, - uint8_t lit, uint8_t byte_mask) +static void gen_ins_l(DisasContext *ctx, TCGv_i64 vc, TCGv_i64 va, + int rb, bool islit, uint8_t lit, uint8_t byte_mask) { if (islit) { int pos = (lit & 7) * 8; @@ -962,8 +966,8 @@ } tcg_gen_deposit_z_i64(vc, va, pos, len); } else { - TCGv tmp = tcg_temp_new(); - TCGv shift = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); + TCGv_i64 shift = tcg_temp_new_i64(); /* The instruction description has us left-shift the byte mask and extract bits <15:8> and apply that zap at the end. This @@ -978,14 +982,14 @@ } /* MSKWH, MSKLH, MSKQH */ -static void gen_msk_h(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, - uint8_t lit, uint8_t byte_mask) +static void gen_msk_h(DisasContext *ctx, TCGv_i64 vc, TCGv_i64 va, + int rb, bool islit, uint8_t lit, uint8_t byte_mask) { if (islit) { gen_zapnoti(vc, va, ~((byte_mask << (lit & 7)) >> 8)); } else { - TCGv shift = tcg_temp_new(); - TCGv mask = tcg_temp_new(); + TCGv_i64 shift = tcg_temp_new_i64(); + TCGv_i64 mask = tcg_temp_new_i64(); /* The instruction description is as above, where the byte_mask is shifted left, and then we extract bits <15:8>. This can be @@ -1008,14 +1012,14 @@ } /* MSKBL, MSKWL, MSKLL, MSKQL */ -static void gen_msk_l(DisasContext *ctx, TCGv vc, TCGv va, int rb, bool islit, - uint8_t lit, uint8_t byte_mask) +static void gen_msk_l(DisasContext *ctx, TCGv_i64 vc, TCGv_i64 va, + int rb, bool islit, uint8_t lit, uint8_t byte_mask) { if (islit) { gen_zapnoti(vc, va, ~(byte_mask << (lit & 7))); } else { - TCGv shift = tcg_temp_new(); - TCGv mask = tcg_temp_new(); + TCGv_i64 shift = tcg_temp_new_i64(); + TCGv_i64 mask = tcg_temp_new_i64(); tcg_gen_andi_i64(shift, load_gpr(ctx, rb), 7); tcg_gen_shli_i64(shift, shift, 3); @@ -1100,7 +1104,7 @@ /* But make sure and store only the 3 IPL bits from the user. */ { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); tcg_gen_andi_i64(tmp, ctx->ir[IR_A0], PS_INT_MASK); st_flag_byte(tmp, ENV_FLAG_PS_SHIFT); } @@ -1151,7 +1155,7 @@ return gen_excp(ctx, EXCP_CALL_PAL, palcode); #else { - TCGv tmp = tcg_temp_new(); + TCGv_i64 tmp = tcg_temp_new_i64(); gen_pc_disp(ctx, tmp, 0); if (ctx->tbflags & ENV_FLAG_PAL_MODE) { @@ -1199,9 +1203,9 @@ return 0; } -static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv va, int regno) +static DisasJumpType gen_mfpr(DisasContext *ctx, TCGv_i64 va, int regno) { - void (*helper)(TCGv); + void (*helper)(TCGv_i64); int data; switch (regno) { @@ -1249,7 +1253,7 @@ return DISAS_NEXT; } -static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv vb, int regno) +static DisasJumpType gen_mtpr(DisasContext *ctx, TCGv_i64 vb, int regno) { int data; DisasJumpType ret = DISAS_NEXT; @@ -1361,7 +1365,7 @@ uint16_t fn11; uint8_t opc, ra, rb, rc, fpfn, fn7, lit; bool islit, real_islit; - TCGv va, vb, vc, tmp, tmp2; + TCGv_i64 va, vb, vc, tmp, tmp2; TCGv_i32 t32; DisasJumpType ret; @@ -1484,7 +1488,7 @@ break; case 0x02: /* S4ADDL */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 2); tcg_gen_add_i64(tmp, tmp, vb); tcg_gen_ext32s_i64(vc, tmp); @@ -1496,7 +1500,7 @@ break; case 0x0B: /* S4SUBL */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 2); tcg_gen_sub_i64(tmp, tmp, vb); tcg_gen_ext32s_i64(vc, tmp); @@ -1512,14 +1516,14 @@ break; case 0x12: /* S8ADDL */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 3); tcg_gen_add_i64(tmp, tmp, vb); tcg_gen_ext32s_i64(vc, tmp); break; case 0x1B: /* S8SUBL */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 3); tcg_gen_sub_i64(tmp, tmp, vb); tcg_gen_ext32s_i64(vc, tmp); @@ -1534,7 +1538,7 @@ break; case 0x22: /* S4ADDQ */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 2); tcg_gen_add_i64(vc, tmp, vb); break; @@ -1544,7 +1548,7 @@ break; case 0x2B: /* S4SUBQ */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 2); tcg_gen_sub_i64(vc, tmp, vb); break; @@ -1554,13 +1558,13 @@ break; case 0x32: /* S8ADDQ */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 3); tcg_gen_add_i64(vc, tmp, vb); break; case 0x3B: /* S8SUBQ */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_shli_i64(tmp, va, 3); tcg_gen_sub_i64(vc, tmp, vb); break; @@ -1570,7 +1574,7 @@ break; case 0x40: /* ADDL/V */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_ext32s_i64(tmp, va); tcg_gen_ext32s_i64(vc, vb); tcg_gen_add_i64(tmp, tmp, vc); @@ -1579,7 +1583,7 @@ break; case 0x49: /* SUBL/V */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_ext32s_i64(tmp, va); tcg_gen_ext32s_i64(vc, vb); tcg_gen_sub_i64(tmp, tmp, vc); @@ -1592,8 +1596,8 @@ break; case 0x60: /* ADDQ/V */ - tmp = tcg_temp_new(); - tmp2 = tcg_temp_new(); + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); tcg_gen_eqv_i64(tmp, va, vb); tcg_gen_mov_i64(tmp2, va); tcg_gen_add_i64(vc, va, vb); @@ -1605,8 +1609,8 @@ break; case 0x69: /* SUBQ/V */ - tmp = tcg_temp_new(); - tmp2 = tcg_temp_new(); + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); tcg_gen_xor_i64(tmp, va, vb); tcg_gen_mov_i64(tmp2, va); tcg_gen_sub_i64(vc, va, vb); @@ -1798,7 +1802,7 @@ if (islit) { tcg_gen_shri_i64(vc, va, lit & 0x3f); } else { - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); vb = load_gpr(ctx, rb); tcg_gen_andi_i64(tmp, vb, 0x3f); tcg_gen_shr_i64(vc, va, tmp); @@ -1813,7 +1817,7 @@ if (islit) { tcg_gen_shli_i64(vc, va, lit & 0x3f); } else { - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); vb = load_gpr(ctx, rb); tcg_gen_andi_i64(tmp, vb, 0x3f); tcg_gen_shl_i64(vc, va, tmp); @@ -1828,7 +1832,7 @@ if (islit) { tcg_gen_sari_i64(vc, va, lit & 0x3f); } else { - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); vb = load_gpr(ctx, rb); tcg_gen_andi_i64(tmp, vb, 0x3f); tcg_gen_sar_i64(vc, va, tmp); @@ -1891,12 +1895,12 @@ break; case 0x30: /* UMULH */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_mulu2_i64(tmp, vc, va, vb); break; case 0x40: /* MULL/V */ - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_ext32s_i64(tmp, va); tcg_gen_ext32s_i64(vc, vb); tcg_gen_mul_i64(tmp, tmp, vc); @@ -1905,8 +1909,8 @@ break; case 0x60: /* MULQ/V */ - tmp = tcg_temp_new(); - tmp2 = tcg_temp_new(); + tmp = tcg_temp_new_i64(); + tmp2 = tcg_temp_new_i64(); tcg_gen_muls2_i64(vc, tmp, va, vb); tcg_gen_sari_i64(tmp2, vc, 63); gen_helper_check_overflow(tcg_env, tmp, tmp2); @@ -2351,7 +2355,7 @@ prediction stack action, which of course we don't implement. */ vb = load_gpr(ctx, rb); if (ra != 31) { - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_andi_i64(tmp, vb, ~3); gen_pc_disp(ctx, ctx->ir[ra], 0); tcg_gen_mov_i64(cpu_pc, tmp); @@ -2366,7 +2370,7 @@ #ifndef CONFIG_USER_ONLY REQUIRE_TB_FLAG(ENV_FLAG_PAL_MODE); { - TCGv addr = tcg_temp_new(); + TCGv_i64 addr = tcg_temp_new_i64(); vb = load_gpr(ctx, rb); va = dest_gpr(ctx, ra); @@ -2615,7 +2619,7 @@ } tcg_gen_movi_i64(cpu_lock_addr, -1); st_flag_byte(load_zero(ctx), ENV_FLAG_RX_SHIFT); - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_andi_i64(tmp, vb, 1); st_flag_byte(tmp, ENV_FLAG_PAL_SHIFT); tcg_gen_andi_i64(cpu_pc, vb, ~3); @@ -2636,7 +2640,7 @@ /* Longword physical access */ va = load_gpr(ctx, ra); vb = load_gpr(ctx, rb); - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_addi_i64(tmp, vb, disp12); tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LESL | MO_ALIGN); break; @@ -2644,7 +2648,7 @@ /* Quadword physical access */ va = load_gpr(ctx, ra); vb = load_gpr(ctx, rb); - tmp = tcg_temp_new(); + tmp = tcg_temp_new_i64(); tcg_gen_addi_i64(tmp, vb, disp12); tcg_gen_qemu_st_i64(va, tmp, MMU_PHYS_IDX, MO_LEUQ | MO_ALIGN); break;
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h index a7ca410..f7b1437 100644 --- a/target/arm/cpu-features.h +++ b/target/arm/cpu-features.h
@@ -1643,6 +1643,6 @@ * Forward to the above feature tests given an ARMCPU pointer. */ #define cpu_isar_feature(name, cpu) \ - ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); }) + ({ const ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); }) #endif
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 5862020..c535b29 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c
@@ -789,10 +789,10 @@ } #endif -static void arm_disas_set_info(CPUState *cpu, disassemble_info *info) +static void arm_disas_set_info(const CPUState *cpu, disassemble_info *info) { - ARMCPU *ac = ARM_CPU(cpu); - CPUARMState *env = &ac->env; + const ARMCPU *ac = ARM_CPU(cpu); + const CPUARMState *env = &ac->env; bool sctlr_b = arm_sctlr_b(env); if (is_a64(env)) {
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 21fee5e..e146f7e 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h
@@ -1345,7 +1345,7 @@ /* Likewise, but using @sm = PSTATE.SM. */ uint32_t sve_vqm1_for_el(CPUARMState *env, int el); -static inline bool is_a64(CPUARMState *env) +static inline bool is_a64(const CPUARMState *env) { return env->aarch64; } @@ -2140,7 +2140,7 @@ ARM_FEATURE_BACKCOMPAT_CNTFRQ, /* 62.5MHz timer default */ }; -static inline int arm_feature(CPUARMState *env, int feature) +static inline int arm_feature(const CPUARMState *env, int feature) { return (env->features & (1ULL << feature)) != 0; } @@ -2385,7 +2385,7 @@ return (GET_IDREG(&cpu->isar, CLIDR) & R_V7M_CLIDR_CTYPE_ALL_MASK) != 0; } -static inline bool arm_sctlr_b(CPUARMState *env) +static inline bool arm_sctlr_b(const CPUARMState *env) { return /* We need not implement SCTLR.ITD in user-mode emulation, so
diff --git a/target/avr/cpu.c b/target/avr/cpu.c index 52237da..8579a72 100644 --- a/target/avr/cpu.c +++ b/target/avr/cpu.c
@@ -116,7 +116,7 @@ memset(env->r, 0, sizeof(env->r)); } -static void avr_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +static void avr_cpu_disas_set_info(const CPUState *cpu, disassemble_info *info) { info->endian = BFD_ENDIAN_LITTLE; info->mach = bfd_arch_avr;
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index 8ac4f49..58a22ee 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c
@@ -301,7 +301,8 @@ set_float_default_nan_pattern(0b11111111, &env->fp_status); } -static void hexagon_cpu_disas_set_info(CPUState *s, disassemble_info *info) +static void hexagon_cpu_disas_set_info(const CPUState *cs, + disassemble_info *info) { info->print_insn = print_insn_hexagon; info->endian = BFD_ENDIAN_LITTLE;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c index 0ca79ee..714f3bb 100644 --- a/target/hppa/cpu.c +++ b/target/hppa/cpu.c
@@ -150,7 +150,7 @@ return env->psw & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX; } -static void hppa_cpu_disas_set_info(CPUState *cs, disassemble_info *info) +static void hppa_cpu_disas_set_info(const CPUState *cs, disassemble_info *info) { info->mach = bfd_mach_hppa20; info->endian = BFD_ENDIAN_BIG;
diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 45f0b80..0a7b884 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c
@@ -10359,10 +10359,10 @@ } #endif /* !CONFIG_USER_ONLY */ -static void x86_disas_set_info(CPUState *cs, disassemble_info *info) +static void x86_disas_set_info(const CPUState *cs, disassemble_info *info) { - X86CPU *cpu = X86_CPU(cs); - CPUX86State *env = &cpu->env; + const X86CPU *cpu = X86_CPU(cs); + const CPUX86State *env = &cpu->env; info->endian = BFD_ENDIAN_LITTLE; info->mach = (env->hflags & HF_CS64_MASK ? bfd_mach_x86_64
diff --git a/target/i386/igvm.c b/target/i386/igvm.c index 457c253..f41b498 100644 --- a/target/i386/igvm.c +++ b/target/i386/igvm.c
@@ -13,7 +13,9 @@ #include "cpu.h" #include "hw/i386/e820_memory_layout.h" +#include "hw/i386/acpi-build.h" #include "system/igvm.h" +#include "system/igvm-internal.h" struct IgvmNativeVpContextX64 { uint64_t rax; @@ -178,3 +180,33 @@ qigvm_x86_load_context(bsp_context, env); } + +/* + * Process MADT IGVM parameter + */ +int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp) +{ + const IGVM_VHS_PARAMETER *param = (const IGVM_VHS_PARAMETER *)header_data; + QIgvmParameterData *param_entry; + int result = 0; + + /* Find the parameter area that should hold the MADT data */ + param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index); + if (param_entry == NULL) { + return 0; + } + + GArray *madt = acpi_build_madt_standalone(ctx->machine_state); + + if (madt->len <= param_entry->size) { + memcpy(param_entry->data, madt->data, madt->len); + } else { + error_setg( + errp, + "IGVM: MADT size exceeds parameter area defined in IGVM file"); + result = -1; + } + + g_array_free(madt, true); + return result; +}
diff --git a/target/i386/sev.c b/target/i386/sev.c index fef9f44..acdcb9c 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c
@@ -1892,8 +1892,7 @@ */ if (x86machine->igvm) { if (IGVM_CFG_GET_CLASS(x86machine->igvm) - ->process(x86machine->igvm, machine->cgs, true, errp) == - -1) { + ->process(x86machine->igvm, machine, true, errp) == -1) { return -1; } /*
diff --git a/target/i386/tcg/decode-new.c.inc b/target/i386/tcg/decode-new.c.inc index 086a3bc..bc105aa 100644 --- a/target/i386/tcg/decode-new.c.inc +++ b/target/i386/tcg/decode-new.c.inc
@@ -315,18 +315,18 @@ static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) { - return translator_lduw(env, &s->base, advance_pc(env, s, 2)); + return translator_lduw_end(env, &s->base, advance_pc(env, s, 2), MO_LE); } static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) { - return translator_ldl(env, &s->base, advance_pc(env, s, 4)); + return translator_ldl_end(env, &s->base, advance_pc(env, s, 4), MO_LE); } #ifdef TARGET_X86_64 static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) { - return translator_ldq(env, &s->base, advance_pc(env, s, 8)); + return translator_ldq_end(env, &s->base, advance_pc(env, s, 8), MO_LE); } #endif
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c index b653948..4fa629c 100644 --- a/target/loongarch/cpu.c +++ b/target/loongarch/cpu.c
@@ -506,7 +506,8 @@ cs->exception_index = -1; } -static void loongarch_cpu_disas_set_info(CPUState *s, disassemble_info *info) +static void loongarch_cpu_disas_set_info(const CPUState *cs, + disassemble_info *info) { info->endian = BFD_ENDIAN_LITTLE; info->print_insn = print_insn_loongarch;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index b55e604..c721a23 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c
@@ -176,7 +176,7 @@ env->pc = 0; } -static void m68k_cpu_disas_set_info(CPUState *s, disassemble_info *info) +static void m68k_cpu_disas_set_info(const CPUState *cs, disassemble_info *info) { info->print_insn = print_insn_m68k; info->endian = BFD_ENDIAN_BIG;
diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 7216686..a030993 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c
@@ -347,7 +347,7 @@ static inline uint16_t read_im16(CPUM68KState *env, DisasContext *s) { uint16_t im; - im = translator_lduw(env, &s->base, s->pc); + im = translator_lduw_end(env, &s->base, s->pc, MO_BE); s->pc += 2; return im; } @@ -1412,12 +1412,12 @@ if (s->pc % 4 != 0) { return false; } - test = translator_lduw(s->env, &s->base, s->pc - 4); + test = translator_lduw_end(s->env, &s->base, s->pc - 4, MO_BE); if (test != 0x4e71) { return false; } /* "... and followed by an invalid sentinel instruction movec %sp,0." */ - test = translator_ldl(s->env, &s->base, s->pc); + test = translator_ldl_end(s->env, &s->base, s->pc, MO_BE); if (test != 0x4e7bf000) { return false; }
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c index 53649ec..ae41a1a 100644 --- a/target/microblaze/cpu.c +++ b/target/microblaze/cpu.c
@@ -233,7 +233,7 @@ #endif } -static void mb_disas_set_info(CPUState *cpu, disassemble_info *info) +static void mb_disas_set_info(const CPUState *cpu, disassemble_info *info) { info->mach = bfd_arch_microblaze; info->print_insn = print_insn_microblaze;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c index f74a9d5..e424d11 100644 --- a/target/mips/cpu.c +++ b/target/mips/cpu.c
@@ -422,9 +422,12 @@ #endif } -static void mips_cpu_disas_set_info(CPUState *s, disassemble_info *info) +static void mips_cpu_disas_set_info(const CPUState *cs, disassemble_info *info) { - if (!(cpu_env(s)->insn_flags & ISA_NANOMIPS32)) { + const MIPSCPU *cpu = MIPS_CPU(cs); + const CPUMIPSState *env = &cpu->env; + + if (!(env->insn_flags & ISA_NANOMIPS32)) { info->endian = TARGET_BIG_ENDIAN ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; info->print_insn = TARGET_BIG_ENDIAN ? print_insn_big_mips
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c index 9bbfe22..c64542a 100644 --- a/target/openrisc/cpu.c +++ b/target/openrisc/cpu.c
@@ -94,7 +94,7 @@ return MMU_NOMMU_IDX; /* mmu is disabled */ } -static void openrisc_disas_set_info(CPUState *cpu, disassemble_info *info) +static void openrisc_disas_set_info(const CPUState *cpu, disassemble_info *info) { info->endian = BFD_ENDIAN_BIG; info->print_insn = print_insn_or1k;
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c index 58816c5..c36fd11 100644 --- a/target/ppc/cpu_init.c +++ b/target/ppc/cpu_init.c
@@ -7364,7 +7364,7 @@ { cpu_synchronize_state(cs); - return !FIELD_EX64(cpu_env(cs)->msr, MSR, LE); + return !ppc_env_is_little_endian(cpu_env(cs)); } static bool ppc_get_irq_stats(InterruptStatsProvider *obj, @@ -7452,15 +7452,13 @@ return pcc->pvr == pvr; } -static void ppc_disas_set_info(CPUState *cs, disassemble_info *info) +static void ppc_disas_set_info(const CPUState *cs, disassemble_info *info) { - CPUPPCState *env = cpu_env(cs); + const PowerPCCPU *cpu = POWERPC_CPU(cs); + const CPUPPCState *env = &cpu->env; - if ((env->hflags >> MSR_LE) & 1) { - info->endian = BFD_ENDIAN_LITTLE; - } else { - info->endian = BFD_ENDIAN_BIG; - } + info->endian = ppc_env_is_little_endian(env) ? BFD_ENDIAN_LITTLE + : BFD_ENDIAN_BIG; info->mach = env->bfd_mach; if (!env->bfd_mach) { #ifdef TARGET_PPC64
diff --git a/target/ppc/gdbstub.c b/target/ppc/gdbstub.c index 3b28d4e..b19c0f1 100644 --- a/target/ppc/gdbstub.c +++ b/target/ppc/gdbstub.c
@@ -84,7 +84,7 @@ void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len) { #ifndef CONFIG_USER_ONLY - if (!FIELD_EX64(env->msr, MSR, LE)) { + if (!ppc_env_is_little_endian(env)) { /* do nothing */ } else if (len == 4) { bswap32s((uint32_t *)mem_buf);
diff --git a/target/ppc/internal.h b/target/ppc/internal.h index 58f315f..dda23b6 100644 --- a/target/ppc/internal.h +++ b/target/ppc/internal.h
@@ -19,10 +19,27 @@ #define PPC_INTERNAL_H #include "exec/breakpoint.h" +#include "exec/memop.h" #include "hw/core/registerfields.h" #include "exec/page-protection.h" #include "accel/tcg/tb-cpu-state.h" +static inline bool ppc_env_is_little_endian(const CPUPPCState *env) +{ + return FIELD_EX64(env->msr, MSR, LE); +} + +/** + * ppc_data_endian_env: + * @env: the cpu context + * + * Return the MemOp endianness of the DATA path. + */ +static inline MemOp ppc_data_endian_env(const CPUPPCState *env) +{ + return ppc_env_is_little_endian(env) ? MO_LE : MO_BE; +} + /* PM instructions */ typedef enum { PPC_PM_DOZE,
diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c index 7318b02..119dc1d 100644 --- a/target/ppc/mem_helper.c +++ b/target/ppc/mem_helper.c
@@ -88,8 +88,11 @@ } } else { /* Slow path -- at least some of the operation requires i/o. */ + MemOp op = ppc_data_endian_env(env) | MO_UL | MO_UNALN; + MemOpIdx oi = make_memop_idx(op, mmu_idx); + for (; reg < 32; reg++) { - env->gpr[reg] = cpu_ldl_mmuidx_ra(env, addr, mmu_idx, raddr); + env->gpr[reg] = cpu_ldl_mmu(env, addr, oi, raddr); addr = addr_add(env, addr, 4); } } @@ -111,7 +114,10 @@ } else { /* Slow path -- at least some of the operation requires i/o. */ for (; reg < 32; reg++) { - cpu_stl_mmuidx_ra(env, addr, env->gpr[reg], mmu_idx, raddr); + MemOp op = ppc_data_endian_env(env) | MO_UL | MO_UNALN; + MemOpIdx oi = make_memop_idx(op, mmu_idx); + + cpu_stl_mmu(env, addr, env->gpr[reg], oi, raddr); addr = addr_add(env, addr, 4); } } @@ -152,9 +158,12 @@ break; } } else { + MemOp op = ppc_data_endian_env(env) | MO_UL | MO_UNALN; + MemOpIdx oi = make_memop_idx(op, mmu_idx); + /* Slow path -- at least some of the operation requires i/o. */ for (; nb > 3; nb -= 4) { - env->gpr[reg] = cpu_ldl_mmuidx_ra(env, addr, mmu_idx, raddr); + env->gpr[reg] = cpu_ldl_mmu(env, addr, oi, raddr); reg = (reg + 1) % 32; addr = addr_add(env, addr, 4); } @@ -165,10 +174,14 @@ val = cpu_ldub_mmuidx_ra(env, addr, mmu_idx, raddr) << 24; break; case 2: - val = cpu_lduw_mmuidx_ra(env, addr, mmu_idx, raddr) << 16; + op = ppc_data_endian_env(env) | MO_UW | MO_UNALN; + oi = make_memop_idx(op, mmu_idx); + val = cpu_ldw_mmu(env, addr, oi, raddr) << 16; break; case 3: - val = cpu_lduw_mmuidx_ra(env, addr, mmu_idx, raddr) << 16; + op = ppc_data_endian_env(env) | MO_UW | MO_UNALN; + oi = make_memop_idx(op, mmu_idx); + val = cpu_ldw_mmu(env, addr, oi, raddr) << 16; addr = addr_add(env, addr, 2); val |= cpu_ldub_mmuidx_ra(env, addr, mmu_idx, raddr) << 8; break; @@ -241,8 +254,11 @@ break; } } else { + MemOp op = ppc_data_endian_env(env) | MO_UL | MO_UNALN; + MemOpIdx oi = make_memop_idx(op, mmu_idx); + for (; nb > 3; nb -= 4) { - cpu_stl_mmuidx_ra(env, addr, env->gpr[reg], mmu_idx, raddr); + cpu_stl_mmu(env, addr, env->gpr[reg], oi, raddr); reg = (reg + 1) % 32; addr = addr_add(env, addr, 4); } @@ -252,10 +268,14 @@ cpu_stb_mmuidx_ra(env, addr, val >> 24, mmu_idx, raddr); break; case 2: - cpu_stw_mmuidx_ra(env, addr, val >> 16, mmu_idx, raddr); + op = ppc_data_endian_env(env) | MO_UW | MO_UNALN; + oi = make_memop_idx(op, mmu_idx); + cpu_stw_mmu(env, addr, val >> 16, oi, raddr); break; case 3: - cpu_stw_mmuidx_ra(env, addr, val >> 16, mmu_idx, raddr); + op = ppc_data_endian_env(env) | MO_UW | MO_UNALN; + oi = make_memop_idx(op, mmu_idx); + cpu_stw_mmu(env, addr, val >> 16, oi, raddr); addr = addr_add(env, addr, 2); cpu_stb_mmuidx_ra(env, addr, val >> 8, mmu_idx, raddr); break; @@ -284,8 +304,11 @@ haddr = probe_write(env, addr, dcbz_size, mmu_idx, retaddr); if (unlikely(!haddr)) { /* Slow path */ + MemOp op = ppc_data_endian_env(env) | MO_UQ | MO_UNALN; + MemOpIdx oi = make_memop_idx(op, mmu_idx); + for (int i = 0; i < dcbz_size; i += 8) { - cpu_stq_mmuidx_ra(env, addr + i, 0, mmu_idx, retaddr); + cpu_stq_mmu(env, addr + i, 0, oi, retaddr); } return; } @@ -320,22 +343,27 @@ void helper_icbi(CPUPPCState *env, target_ulong addr) { + unsigned mmu_idx = cpu_mmu_index(env_cpu(env), false); + MemOpIdx oi = make_memop_idx(MO_UL | MO_UNALN, mmu_idx); + addr &= ~(env->dcache_line_size - 1); /* * Invalidate one cache line : * PowerPC specification says this is to be treated like a load * (not a fetch) by the MMU. To be sure it will be so, - * do the load "by hand". + * do the load "by hand". As the returned data is not consumed, + * endianness is irrelevant. */ - cpu_ldl_data_ra(env, addr, GETPC()); + cpu_ldl_mmu(env, addr, oi, GETPC()); } void helper_icbiep(CPUPPCState *env, target_ulong addr) { #if !defined(CONFIG_USER_ONLY) + MemOpIdx oi = make_memop_idx(MO_UL | MO_UNALN, PPC_TLB_EPID_LOAD); /* See comments above */ addr &= ~(env->dcache_line_size - 1); - cpu_ldl_mmuidx_ra(env, addr, PPC_TLB_EPID_LOAD, GETPC()); + cpu_ldl_mmu(env, addr, oi, GETPC()); #endif } @@ -392,7 +420,7 @@ int adjust = HI_IDX * (n_elems - 1); \ int sh = sizeof(r->element[0]) >> 1; \ int index = (addr & 0xf) >> sh; \ - bool byteswap = FIELD_EX64(env->msr, MSR, LE); \ + bool byteswap = ppc_env_is_little_endian(env); \ \ if (byteswap) { \ index = n_elems - index - 1; \ @@ -418,7 +446,7 @@ int adjust = HI_IDX * (n_elems - 1); \ int sh = sizeof(r->element[0]) >> 1; \ int index = (addr & 0xf) >> sh; \ - bool byteswap = FIELD_EX64(env->msr, MSR, LE); \ + bool byteswap = ppc_env_is_little_endian(env); \ \ if (byteswap) { \ index = n_elems - index - 1; \ @@ -451,7 +479,7 @@ t.s128 = int128_zero(); \ if (nb) { \ nb = (nb >= 16) ? 16 : nb; \ - if (FIELD_EX64(env->msr, MSR, LE) && !lj) { \ + if (ppc_env_is_little_endian(env) && !lj) { \ for (i = 16; i > 16 - nb; i--) { \ t.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC()); \ addr = addr_add(env, addr, 1); \ @@ -482,7 +510,7 @@ } \ \ nb = (nb >= 16) ? 16 : nb; \ - if (FIELD_EX64(env->msr, MSR, LE) && !lj) { \ + if (ppc_env_is_little_endian(env) && !lj) { \ for (i = 16; i > 16 - nb; i--) { \ cpu_stb_data_ra(env, addr, xt->VsrB(i - 1), GETPC()); \ addr = addr_add(env, addr, 1); \
diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c index edecfb8..5e6c1e3 100644 --- a/target/ppc/tcg-excp_helper.c +++ b/target/ppc/tcg-excp_helper.c
@@ -160,14 +160,18 @@ target_ulong rb, uint64_t key, bool store) { uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; + unsigned mmu_idx = cpu_mmu_index(env_cpu(env), false); + MemOp op = ppc_data_endian_env(env) | MO_UQ; + MemOpIdx oi = make_memop_idx(op, mmu_idx); + uintptr_t retaddr = GETPC(); if (store) { - cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); + cpu_stq_mmu(env, ea, calculated_hash, oi, retaddr); } else { - loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); + loaded_hash = cpu_ldq_mmu(env, ea, oi, retaddr); if (loaded_hash != calculated_hash) { raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, - POWERPC_EXCP_TRAP, GETPC()); + POWERPC_EXCP_TRAP, retaddr); } } } @@ -424,22 +428,13 @@ cpu_loop_exit_noexc(cs); } -/* Return true iff byteswap is needed to load instruction */ -static inline bool insn_need_byteswap(CPUArchState *env) -{ - /* SYSTEM builds TARGET_BIG_ENDIAN. Need to swap when MSR[LE] is set */ - return !!(env->msr & ((target_ulong)1 << MSR_LE)); -} - uint32_t ppc_ldl_code(CPUArchState *env, target_ulong addr) { - uint32_t insn = cpu_ldl_code(env, addr); + CPUState *cs = env_cpu(env); + MemOp op_end = ppc_data_endian_env(env); + MemOpIdx oi = make_memop_idx(MO_UL | op_end, cpu_mmu_index(cs, true)); - if (insn_need_byteswap(env)) { - insn = bswap32(insn); - } - - return insn; + return cpu_ldl_code_mmu(env, addr, oi, 0); } #if defined(TARGET_PPC64)
diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 17e6d07..e9acfa2 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c
@@ -214,14 +214,15 @@ return !!(ctx->flags & POWERPC_FLAG_PPE42); } -/* Return true iff byteswap is needed in a scalar memop */ -static inline bool need_byteswap(const DisasContext *ctx) +/** + * ppc_code_endian_dc: + * @dc: the disassembly context + * + * Return the MemOp endianness of the CODE path. + */ +static inline MemOp ppc_code_endian_dc(const DisasContext *ctx) { -#if TARGET_BIG_ENDIAN - return ctx->le_mode; -#else - return !ctx->le_mode; -#endif + return MO_BE ^ (ctx->le_mode * MO_BSWAP); } /* True when active word size < size of target_long. */ @@ -6588,6 +6589,7 @@ DisasContext *ctx = container_of(dcbase, DisasContext, base); PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = cpu_env(cs); + MemOp mo_endian = ppc_code_endian_dc(ctx); target_ulong pc; uint32_t insn; bool ok; @@ -6597,7 +6599,7 @@ ctx->base.pc_next, ctx->mem_idx, (int)msr_ir); ctx->cia = pc = ctx->base.pc_next; - insn = translator_ldl_swap(env, dcbase, pc, need_byteswap(ctx)); + insn = translator_ldl_end(env, dcbase, pc, mo_endian); ctx->base.pc_next = pc += 4; if (!is_prefix_insn(ctx, insn)) { @@ -6613,8 +6615,7 @@ gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_INSN); ok = true; } else { - uint32_t insn2 = translator_ldl_swap(env, dcbase, pc, - need_byteswap(ctx)); + uint32_t insn2 = translator_ldl_end(env, dcbase, pc, mo_endian); ctx->base.pc_next = pc += 4; ok = decode_insn64(ctx, deposit64(insn2, 32, 32, insn)); }
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index e95eea0..e56470a 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c
@@ -795,10 +795,11 @@ #endif } -static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) +static void riscv_cpu_disas_set_info(const CPUState *s, disassemble_info *info) { - RISCVCPU *cpu = RISCV_CPU(s); - CPURISCVState *env = &cpu->env; + const RISCVCPU *cpu = RISCV_CPU(s); + const CPURISCVState *env = &cpu->env; + info->target_info = &cpu->cfg; /*
diff --git a/target/riscv/translate.c b/target/riscv/translate.c index f687c75..cb4f443 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c
@@ -1181,8 +1181,9 @@ DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUState *cpu = ctx->cs; CPURISCVState *env = cpu_env(cpu); + MemOpIdx oi = make_memop_idx(MO_LEUL, cpu_mmu_index(cpu, true)); - return cpu_ldl_code(env, pc); + return cpu_ldl_code_mmu(env, pc, oi, 0); } #define SS_MMU_INDEX(ctx) (ctx->mem_idx | MMU_IDX_SS_WRITE) @@ -1253,13 +1254,16 @@ * real one is 2 or 4 bytes. Instruction preload wouldn't trigger * additional page fault. */ - opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next); + opcode = translator_ldl_end(env, &ctx->base, ctx->base.pc_next, + mo_endian(ctx)); } else { /* * For unaligned pc, instruction preload may trigger additional * page fault so we only load 2 bytes here. */ - opcode = (uint32_t) translator_lduw(env, &ctx->base, ctx->base.pc_next); + opcode = (uint32_t) translator_lduw_end(env, &ctx->base, + ctx->base.pc_next, + mo_endian(ctx)); } ctx->ol = ctx->xl; @@ -1279,8 +1283,9 @@ if (!pc_is_4byte_align) { /* Load last 2 bytes of instruction here */ opcode = deposit32(opcode, 16, 16, - translator_lduw(env, &ctx->base, - ctx->base.pc_next + 2)); + translator_lduw_end(env, &ctx->base, + ctx->base.pc_next + 2, + mo_endian(ctx))); } ctx->opcode = opcode; @@ -1395,7 +1400,8 @@ if (page_ofs > TARGET_PAGE_SIZE - MAX_INSN_LEN) { uint16_t next_insn = - translator_lduw(env, &ctx->base, ctx->base.pc_next); + translator_lduw_end(env, &ctx->base, ctx->base.pc_next, + mo_endian(ctx)); int len = insn_len(next_insn); if (!translator_is_same_page(&ctx->base, ctx->base.pc_next + len - 1)) {
diff --git a/target/riscv/zce_helper.c b/target/riscv/zce_helper.c index 55221f5..15bf0a9 100644 --- a/target/riscv/zce_helper.c +++ b/target/riscv/zce_helper.c
@@ -23,6 +23,8 @@ target_ulong HELPER(cm_jalt)(CPURISCVState *env, uint32_t index) { + unsigned mmu_index = cpu_mmu_index(env_cpu(env), true); + MemOpIdx oi; #if !defined(CONFIG_USER_ONLY) RISCVException ret = smstateen_acc_ok(env, 0, SMSTATEEN0_JVT); @@ -43,11 +45,13 @@ } if (xlen == 32) { + oi = make_memop_idx(MO_LEUL, mmu_index); t0 = base + (index << 2); - target = cpu_ldl_code(env, t0); + target = cpu_ldl_code_mmu(env, t0, oi, 0); } else { + oi = make_memop_idx(MO_LEUQ, mmu_index); t0 = base + (index << 3); - target = cpu_ldq_code(env, t0); + target = cpu_ldq_code_mmu(env, t0, oi, 0); } return target & ~0x1;
diff --git a/target/rx/cpu.c b/target/rx/cpu.c index 0437edc..b528419 100644 --- a/target/rx/cpu.c +++ b/target/rx/cpu.c
@@ -178,7 +178,7 @@ } } -static void rx_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +static void rx_cpu_disas_set_info(const CPUState *cpu, disassemble_info *info) { info->endian = BFD_ENDIAN_LITTLE; info->mach = bfd_mach_rx;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index cd472d3..c074e12 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c
@@ -222,7 +222,7 @@ } } -static void s390_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +static void s390_cpu_disas_set_info(const CPUState *cpu, disassemble_info *info) { info->mach = bfd_mach_s390_64; info->cap_arch = CS_ARCH_SYSZ;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c index 1dd21ad..e2bde45 100644 --- a/target/sh4/cpu.c +++ b/target/sh4/cpu.c
@@ -164,7 +164,8 @@ set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); } -static void superh_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) +static void superh_cpu_disas_set_info(const CPUState *cpu, + disassemble_info *info) { info->endian = TARGET_BIG_ENDIAN ? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c index bfc6fb9..3991681 100644 --- a/target/sparc/cpu.c +++ b/target/sparc/cpu.c
@@ -103,7 +103,8 @@ } #endif /* !CONFIG_USER_ONLY */ -static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info) +static void cpu_sparc_disas_set_info(const CPUState *cpu, + disassemble_info *info) { info->print_insn = print_insn_sparc; info->endian = BFD_ENDIAN_BIG;
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c index ecc5e09..86ec899 100644 --- a/target/xtensa/cpu.c +++ b/target/xtensa/cpu.c
@@ -226,7 +226,8 @@ return oc; } -static void xtensa_cpu_disas_set_info(CPUState *cs, disassemble_info *info) +static void xtensa_cpu_disas_set_info(const CPUState *cs, + disassemble_info *info) { XtensaCPU *cpu = XTENSA_CPU(cs);
diff --git a/tests/functional/aarch64/test_aspeed_ast2700.py b/tests/functional/aarch64/test_aspeed_ast2700.py index 0ced1a2..61373ff 100755 --- a/tests/functional/aarch64/test_aspeed_ast2700.py +++ b/tests/functional/aarch64/test_aspeed_ast2700.py
@@ -9,60 +9,94 @@ import os from qemu_test import QemuSystemTest, Asset -from qemu_test import wait_for_console_pattern +from qemu_test import wait_for_console_pattern, exec_command from qemu_test import exec_command_and_wait_for_pattern class AST2x00MachineSDK(QemuSystemTest): - def do_test_aarch64_aspeed_sdk_start(self, image): + def do_test_aarch64_aspeed_sdk_start(self, image, bus_id): + bus_str = str(bus_id) self.require_netdev('user') self.vm.set_console() - self.vm.add_args('-device', - 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test') + self.vm.add_args( + '-device', + f'tmp105,' + f'bus=aspeed.i2c.bus.{bus_str},' + f'address=0x4d,' + f'id=tmp-test-{bus_str}' + ) self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw', '-net', 'nic', '-net', 'user', '-snapshot') self.vm.launch() def verify_vbootrom_firmware_flow(self): - wait_for_console_pattern(self, 'Found valid FIT image') - wait_for_console_pattern(self, '[uboot] loading') - wait_for_console_pattern(self, 'done') - wait_for_console_pattern(self, '[fdt] loading') - wait_for_console_pattern(self, 'done') - wait_for_console_pattern(self, '[tee] loading') - wait_for_console_pattern(self, 'done') - wait_for_console_pattern(self, '[atf] loading') - wait_for_console_pattern(self, 'done') + wait_for_console_pattern(self, 'Found valid caliptra flash image') + wait_for_console_pattern(self, 'Check flash image checksum') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Read abb header') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Read soc manifest') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Load atf image') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Load optee image') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Load uboot image') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Load ssp image') + wait_for_console_pattern(self, 'pass') + wait_for_console_pattern(self, 'Load tsp image') + wait_for_console_pattern(self, 'pass') wait_for_console_pattern(self, 'Jumping to BL31 (Trusted Firmware-A)') - def verify_openbmc_boot_start(self): + def enable_ast2700_pcie2(self): + wait_for_console_pattern(self, 'Hit any key to stop autoboot') + exec_command_and_wait_for_pattern(self, '\012', '=>') + exec_command_and_wait_for_pattern(self, + 'cp 100420000 403000000 900000', '=>') + exec_command_and_wait_for_pattern(self, + 'bootm start 403000000', '=>') + exec_command_and_wait_for_pattern(self, 'bootm loados', '=>') + exec_command_and_wait_for_pattern(self, 'bootm ramdisk', '=>') + exec_command_and_wait_for_pattern(self, 'bootm prep', '=>') + exec_command_and_wait_for_pattern(self, + 'fdt set /soc@14000000/pcie@140d0000 status "okay"', '=>') + exec_command(self, 'bootm go') + + def verify_openbmc_boot_start(self, enable_pcie=True): wait_for_console_pattern(self, 'U-Boot 2023.10') - wait_for_console_pattern(self, '## Loading kernel from FIT Image') + if enable_pcie: + self.enable_ast2700_pcie2() wait_for_console_pattern(self, 'Linux version ') - def verify_openbmc_boot_and_login(self, name): - self.verify_openbmc_boot_start() + def verify_openbmc_boot_and_login(self, name, enable_pcie=True): + self.verify_openbmc_boot_start(enable_pcie) wait_for_console_pattern(self, f'{name} login:') exec_command_and_wait_for_pattern(self, 'root', 'Password:') exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#') - ASSET_SDK_V908_AST2700A1 = Asset( - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2700-default-obmc.tar.gz', - 'eac3dc409b7ea3cd4b03d4792d3cebd469792ad893cb51e1d15f0fc20bd1e2cd') + ASSET_SDK_V1100_AST2700A1 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v11.00/ast2700-a1-obmc.tar.gz', + 'd5ceed511cd0dfefbb102fff2d731159e0472948a28066dc0d90bcd54be76525') - def do_ast2700_i2c_test(self): + ASSET_SDK_V1100_AST2700A1_DCSCM = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v11.00/ast2700-a1-dcscm-obmc.tar.gz', + '4f8778be176ece1b57d33c4aee13bb989be114c3e4703150eaeb6f996bd5587f') + + def do_ast2700_i2c_test(self, bus_id): + bus_str = str(bus_id) exec_command_and_wait_for_pattern(self, - 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ', - 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d') + f'echo lm75 0x4d > /sys/class/i2c-dev/i2c-{bus_str}/device/new_device ', + f'i2c i2c-{bus_str}: new_device: Instantiated device lm75 at 0x4d') exec_command_and_wait_for_pattern(self, - 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0') - self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test', + f'cat /sys/bus/i2c/devices/{bus_str}-004d/hwmon/hwmon*/temp1_input', '0') + self.vm.cmd('qom-set', path=f'/machine/peripheral/tmp-test-{bus_str}', property='temperature', value=18000) exec_command_and_wait_for_pattern(self, - 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000') + f'cat /sys/bus/i2c/devices/{bus_str}-004d/hwmon/hwmon*/temp1_input', '18000') def do_ast2700_pcie_test(self): exec_command_and_wait_for_pattern(self, @@ -77,21 +111,12 @@ def do_ast2700_pcie_test(self): 'ip addr show dev eth2', 'inet 10.0.2.15/24') - def start_ast2700_test(self, name): + def start_ast2700_test(self, name, bus_id): num_cpu = 4 - uboot_size = os.path.getsize(self.scratch_file(name, - 'u-boot-nodtb.bin')) - uboot_dtb_load_addr = hex(0x400000000 + uboot_size) - load_images_list = [ { 'addr': '0x400000000', - 'file': self.scratch_file(name, - 'u-boot-nodtb.bin') - }, - { - 'addr': str(uboot_dtb_load_addr), - 'file': self.scratch_file(name, 'u-boot.dtb') + 'file': self.scratch_file(name, 'u-boot.bin') }, { 'addr': '0x430000000', @@ -99,8 +124,7 @@ def start_ast2700_test(self, name): }, { 'addr': '0x430080000', - 'file': self.scratch_file(name, 'optee', - 'tee-raw.bin') + 'file': self.scratch_file(name, 'optee', 'tee-raw.bin') } ] @@ -116,35 +140,48 @@ def start_ast2700_test(self, name): self.vm.add_args('-smp', str(num_cpu)) self.do_test_aarch64_aspeed_sdk_start( - self.scratch_file(name, 'image-bmc')) + self.scratch_file(name, 'image-bmc'), bus_id) - def start_ast2700_test_vbootrom(self, name): + def start_ast2700_test_vbootrom(self, name, bus_id): self.vm.add_args('-bios', 'ast27x0_bootrom.bin') self.do_test_aarch64_aspeed_sdk_start( - self.scratch_file(name, 'image-bmc')) + self.scratch_file(name, 'image-bmc'), bus_id) - def test_aarch64_ast2700a1_evb_sdk_v09_08(self): + def test_aarch64_ast2700a1_evb_sdk_v11_00(self): self.set_machine('ast2700a1-evb') self.require_netdev('user') - self.archive_extract(self.ASSET_SDK_V908_AST2700A1) + self.archive_extract(self.ASSET_SDK_V1100_AST2700A1) self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.2') self.vm.add_args('-netdev', 'user,id=net1') - self.start_ast2700_test('ast2700-default') - self.verify_openbmc_boot_and_login('ast2700-default') - self.do_ast2700_i2c_test() + self.start_ast2700_test('ast2700-a1', 1) + self.verify_openbmc_boot_and_login('ast2700-a1') + self.do_ast2700_i2c_test(1) self.do_ast2700_pcie_test() - def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_08(self): + def test_aarch64_ast2700a1_evb_sdk_vbootrom_v11_00(self): self.set_machine('ast2700a1-evb') self.require_netdev('user') - self.archive_extract(self.ASSET_SDK_V908_AST2700A1) + self.archive_extract(self.ASSET_SDK_V1100_AST2700A1) self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.2') self.vm.add_args('-netdev', 'user,id=net1') - self.start_ast2700_test_vbootrom('ast2700-default') + self.start_ast2700_test_vbootrom('ast2700-a1', 1) self.verify_vbootrom_firmware_flow() self.verify_openbmc_boot_start() + def test_aarch64_ast2700a1_evb_ioexp_v11_00(self): + self.set_machine('ast2700a1-evb') + self.require_netdev('user') + + self.archive_extract(self.ASSET_SDK_V1100_AST2700A1_DCSCM) + self.vm.set_machine('ast2700a1-evb,fmc-model=w25q512jv') + self.vm.add_args('-device', + 'tmp105,bus=ioexp0.0,address=0x4d,id=tmp-test-16') + self.start_ast2700_test('ast2700-a1-dcscm', 8) + self.verify_openbmc_boot_and_login('ast2700-a1-dcscm', False) + self.do_ast2700_i2c_test(8) + self.do_ast2700_i2c_test(16) + if __name__ == '__main__': QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py index 8dbc8f2..47e56dc 100755 --- a/tests/functional/aarch64/test_aspeed_ast2700fc.py +++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py
@@ -9,7 +9,7 @@ import os from qemu_test import QemuSystemTest, Asset -from qemu_test import wait_for_console_pattern +from qemu_test import wait_for_console_pattern, exec_command from qemu_test import exec_command_and_wait_for_pattern @@ -27,9 +27,23 @@ def do_test_aarch64_aspeed_sdk_start(self, image): self.vm.launch() + def enable_ast2700_pcie2(self): + wait_for_console_pattern(self, 'Hit any key to stop autoboot') + exec_command_and_wait_for_pattern(self, '\012', '=>') + exec_command_and_wait_for_pattern(self, + 'cp 100420000 403000000 900000', '=>') + exec_command_and_wait_for_pattern(self, + 'bootm start 403000000', '=>') + exec_command_and_wait_for_pattern(self, 'bootm loados', '=>') + exec_command_and_wait_for_pattern(self, 'bootm ramdisk', '=>') + exec_command_and_wait_for_pattern(self, 'bootm prep', '=>') + exec_command_and_wait_for_pattern(self, + 'fdt set /soc@14000000/pcie@140d0000 status "okay"', '=>') + exec_command(self, 'bootm go') + def verify_openbmc_boot_and_login(self, name): wait_for_console_pattern(self, 'U-Boot 2023.10') - wait_for_console_pattern(self, '## Loading kernel from FIT Image') + self.enable_ast2700_pcie2() wait_for_console_pattern(self, 'Starting kernel ...') wait_for_console_pattern(self, f'{name} login:') @@ -47,9 +61,9 @@ def load_ast2700fc_coprocessor(self, name): self.vm.add_args('-device', f'loader,file={file},cpu-num={cpu_num}') - ASSET_SDK_V908_AST2700 = Asset( - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2700-default-obmc.tar.gz', - 'eac3dc409b7ea3cd4b03d4792d3cebd469792ad893cb51e1d15f0fc20bd1e2cd') + ASSET_SDK_V1100_AST2700 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v11.00/ast2700-a1-obmc.tar.gz', + 'd5ceed511cd0dfefbb102fff2d731159e0472948a28066dc0d90bcd54be76525') def do_ast2700_i2c_test(self): exec_command_and_wait_for_pattern(self, @@ -99,19 +113,10 @@ def do_ast2700fc_tsp_test(self): def start_ast2700fc_test(self, name): ca35_core = 4 - uboot_size = os.path.getsize(self.scratch_file(name, - 'u-boot-nodtb.bin')) - uboot_dtb_load_addr = hex(0x400000000 + uboot_size) - load_images_list = [ { 'addr': '0x400000000', - 'file': self.scratch_file(name, - 'u-boot-nodtb.bin') - }, - { - 'addr': str(uboot_dtb_load_addr), - 'file': self.scratch_file(name, 'u-boot.dtb') + 'file': self.scratch_file(name, 'u-boot.bin') }, { 'addr': '0x430000000', @@ -119,8 +124,7 @@ def start_ast2700fc_test(self, name): }, { 'addr': '0x430080000', - 'file': self.scratch_file(name, 'optee', - 'tee-raw.bin') + 'file': self.scratch_file(name, 'optee', 'tee-raw.bin') } ] @@ -144,24 +148,24 @@ def start_ast2700fc_test_vbootrom(self, name): self.do_test_aarch64_aspeed_sdk_start( self.scratch_file(name, 'image-bmc')) - def test_aarch64_ast2700fc_sdk_v09_08(self): + def test_aarch64_ast2700fc_sdk_v11_00(self): self.set_machine('ast2700fc') self.require_netdev('user') - self.archive_extract(self.ASSET_SDK_V908_AST2700) - self.start_ast2700fc_test('ast2700-default') - self.verify_openbmc_boot_and_login('ast2700-default') + self.archive_extract(self.ASSET_SDK_V1100_AST2700) + self.start_ast2700fc_test('ast2700-a1') + self.verify_openbmc_boot_and_login('ast2700-a1') self.do_ast2700_i2c_test() self.do_ast2700_pcie_test() self.do_ast2700fc_ssp_test() self.do_ast2700fc_tsp_test() - def test_aarch64_ast2700fc_sdk_vbootrom_v09_08(self): + def test_aarch64_ast2700fc_sdk_vbootrom_v11_00(self): self.set_machine('ast2700fc') - self.archive_extract(self.ASSET_SDK_V908_AST2700) - self.start_ast2700fc_test_vbootrom('ast2700-default') - self.verify_openbmc_boot_and_login('ast2700-default') + self.archive_extract(self.ASSET_SDK_V1100_AST2700) + self.start_ast2700fc_test_vbootrom('ast2700-a1') + self.verify_openbmc_boot_and_login('ast2700-a1') self.do_ast2700fc_ssp_test() self.do_ast2700fc_tsp_test()
diff --git a/tests/functional/arm/test_aspeed_ast1030.py b/tests/functional/arm/test_aspeed_ast1030.py index d1822ed..0defa7c 100755 --- a/tests/functional/arm/test_aspeed_ast1030.py +++ b/tests/functional/arm/test_aspeed_ast1030.py
@@ -12,17 +12,17 @@ class AST1030Machine(AspeedTest): - ASSET_ZEPHYR_3_03 = Asset( + ASSET_ZEPHYR_3_05 = Asset( ('https://github.com/AspeedTech-BMC' - '/zephyr/releases/download/v00.03.03/ast1030-evb-demo.zip'), - '27cd73cdee6374bceb4ee58b3ace87989fa3f0684f4e612510804b588b24d4e0') + '/zephyr/releases/download/v00.03.05/ast1030-evb-demo.zip'), + '057528d343490b1fbb5a721e91084b4f04fec60dc114bd65e724554f9c217f4b') - def test_arm_ast1030_zephyros_3_03(self): + def test_arm_ast1030_zephyros_3_05(self): self.set_machine('ast1030-evb') kernel_name = "ast1030-evb-demo/zephyr.elf" kernel_file = self.archive_extract( - self.ASSET_ZEPHYR_3_03, member=kernel_name) + self.ASSET_ZEPHYR_3_05, member=kernel_name) self.vm.set_console() self.vm.add_args('-kernel', kernel_file, '-nographic') @@ -72,7 +72,7 @@ def test_arm_ast1030_otp_blockdev_device(self): self.vm.set_machine("ast1030-evb") kernel_name = "ast1030-evb-demo/zephyr.elf" - kernel_file = self.archive_extract(self.ASSET_ZEPHYR_3_03, + kernel_file = self.archive_extract(self.ASSET_ZEPHYR_3_05, member=kernel_name) otp_img = self.generate_otpmem_image()
diff --git a/tests/functional/arm/test_aspeed_ast1060.py b/tests/functional/arm/test_aspeed_ast1060.py index 034efa5..eccb425 100644 --- a/tests/functional/arm/test_aspeed_ast1060.py +++ b/tests/functional/arm/test_aspeed_ast1060.py
@@ -11,18 +11,18 @@ class AST1060Machine(AspeedTest): - ASSET_ASPEED_AST1060_PROT_3_02 = Asset( + ASSET_ASPEED_AST1060_PROT_3_04 = Asset( ('https://github.com/AspeedTech-BMC' - '/aspeed-zephyr-project/releases/download/v03.02' - '/ast1060_prot_v03.02.tgz'), - 'dd5f1adc935316ddd1906506a02e15567bd7290657b52320f1a225564cc175bd') + '/aspeed-zephyr-project/releases/download/v03.04' + '/ast1060_prot_v03.04.tgz'), + 'c0319df55f5b7a547efefc5a6ba374b881223d5fe1a776bfdd36f97fd1f31d50') - def test_arm_ast1060_prot_3_02(self): + def test_arm_ast1060_prot_3_04(self): self.set_machine('ast1060-evb') kernel_name = "ast1060_prot/zephyr.bin" kernel_file = self.archive_extract( - self.ASSET_ASPEED_AST1060_PROT_3_02, member=kernel_name) + self.ASSET_ASPEED_AST1060_PROT_3_04, member=kernel_name) self.vm.set_console() self.vm.add_args('-kernel', kernel_file, '-nographic') @@ -35,7 +35,7 @@ def test_arm_ast1060_otp_blockdev_device(self): self.vm.set_machine("ast1060-evb") kernel_name = "ast1060_prot/zephyr.bin" - kernel_file = self.archive_extract(self.ASSET_ASPEED_AST1060_PROT_3_02, + kernel_file = self.archive_extract(self.ASSET_ASPEED_AST1060_PROT_3_04, member=kernel_name) otp_img = self.generate_otpmem_image()
diff --git a/tests/functional/arm/test_aspeed_ast2500.py b/tests/functional/arm/test_aspeed_ast2500.py index 5efd104..5d75e20 100755 --- a/tests/functional/arm/test_aspeed_ast2500.py +++ b/tests/functional/arm/test_aspeed_ast2500.py
@@ -10,15 +10,15 @@ class AST2500Machine(AspeedTest): - ASSET_BR2_202411_AST2500_FLASH = Asset( + ASSET_BR2_202511_AST2500_FLASH = Asset( ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2500-evb/buildroot-2024.11/flash.img'), - '641e6906c18c0f19a2aeb48099d66d4771929c361001d554d0d45c667413e13a') + 'images/ast2500-evb/buildroot-2025.11/flash.img'), + '31e5a8e280b982fb0e7c07eb71c94851002f99ac604dfe620e71a5d47cc87e78') def test_arm_ast2500_evb_buildroot(self): self.set_machine('ast2500-evb') - image_path = self.ASSET_BR2_202411_AST2500_FLASH.fetch() + image_path = self.ASSET_BR2_202511_AST2500_FLASH.fetch() self.vm.add_args('-device', 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test') @@ -37,14 +37,14 @@ def test_arm_ast2500_evb_buildroot(self): self.do_test_arm_aspeed_buildroot_poweroff() - ASSET_SDK_V908_AST2500 = Asset( - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2500-default-obmc.tar.gz', - 'c0a2ba169efd19be5eb77c50ec2a6afd9d826e196a0be3432f969fc72d4b7c0e') + ASSET_SDK_V1000_AST2500 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v10.00/ast2500-default-obmc.tar.gz', + '7d71a3f71d5f4d9f3451f59a73bf9baf8fd9f6a24107eb504a3216151a8b2b5b') def test_arm_ast2500_evb_sdk(self): self.set_machine('ast2500-evb') - self.archive_extract(self.ASSET_SDK_V908_AST2500) + self.archive_extract(self.ASSET_SDK_V1000_AST2500) self.do_test_arm_aspeed_sdk_start( self.scratch_file("ast2500-default", "image-bmc"))
diff --git a/tests/functional/arm/test_aspeed_ast2600_buildroot.py b/tests/functional/arm/test_aspeed_ast2600_buildroot.py index 575a5f6..3d130b9 100755 --- a/tests/functional/arm/test_aspeed_ast2600_buildroot.py +++ b/tests/functional/arm/test_aspeed_ast2600_buildroot.py
@@ -16,15 +16,15 @@ class AST2600Machine(AspeedTest): - ASSET_BR2_202411_AST2600_FLASH = Asset( + ASSET_BR2_202511_AST2600_FLASH = Asset( ('https://github.com/legoater/qemu-aspeed-boot/raw/master/' - 'images/ast2600-evb/buildroot-2024.11/flash.img'), - '4bb2f3dfdea31199b51d66b42f686dc5374c144a7346fdc650194a5578b73609') + 'images/ast2600-evb/buildroot-2025.11/flash.img'), + 'c64a0755501393d570ca318e326e1e9f8372edc5a6452cdccc3649bc9fd2c138') def test_arm_ast2600_evb_buildroot(self): self.set_machine('ast2600-evb') - image_path = self.ASSET_BR2_202411_AST2600_FLASH.fetch() + image_path = self.ASSET_BR2_202511_AST2600_FLASH.fetch() self.vm.add_args('-device', 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
diff --git a/tests/functional/arm/test_aspeed_ast2600_sdk.py b/tests/functional/arm/test_aspeed_ast2600_sdk.py index e3d4ed0..6236aeb 100755 --- a/tests/functional/arm/test_aspeed_ast2600_sdk.py +++ b/tests/functional/arm/test_aspeed_ast2600_sdk.py
@@ -14,22 +14,18 @@ class AST2600Machine(AspeedTest): - ASSET_SDK_V908_AST2600 = Asset( - 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2600-default-obmc.tar.gz', - 'a0414f14ad696550efe083c2156dbeda855c08cc9ae7f40fe1b41bf292295f82') + ASSET_SDK_V1100_AST2600 = Asset( + 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v11.00/ast2600-default-obmc.tar.gz', + '64d8926a7d01b649168be96c986603b5690f06391286c438a3a772c8c7039e93') def do_ast2600_pcie_test(self): exec_command_and_wait_for_pattern(self, - 'lspci -s 80:00.0', - '80:00.0 Host bridge: ' - 'ASPEED Technology, Inc. Device 2600') - exec_command_and_wait_for_pattern(self, - 'lspci -s 80:08.0', - '80:08.0 PCI bridge: ' + 'lspci -s 00:08.0', + '00:08.0 PCI bridge: ' 'ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge') exec_command_and_wait_for_pattern(self, - 'lspci -s 81:00.0', - '81:00.0 Ethernet controller: ' + 'lspci -s 01:00.0', + '01:00.0 Ethernet controller: ' 'Intel Corporation 82574L Gigabit Network Connection') exec_command_and_wait_for_pattern(self, 'ip addr show dev eth4', @@ -39,7 +35,7 @@ def test_arm_ast2600_evb_sdk(self): self.set_machine('ast2600-evb') self.require_netdev('user') - self.archive_extract(self.ASSET_SDK_V908_AST2600) + self.archive_extract(self.ASSET_SDK_V1100_AST2600) self.vm.add_args('-device', 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test') @@ -77,7 +73,7 @@ def test_arm_ast2600_evb_sdk(self): def test_arm_ast2600_otp_blockdev_device(self): self.vm.set_machine("ast2600-evb") - image_path = self.archive_extract(self.ASSET_SDK_V908_AST2600) + image_path = self.archive_extract(self.ASSET_SDK_V1100_AST2600) otp_img = self.generate_otpmem_image() self.vm.set_console()