ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

QEMU 与 ACPI Generic Event Device(GED)接口详解:硬件精简平台的统一事件与热插拔机制

QEMU 与 ACPI Generic Event Device(GED)接口详解:硬件精简平台的统一事件与热插拔机制 虚拟化硬件仿真【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址https://gitcode.com/gh_mirrors/qe/qemu点击查看免费下载导读本文基于 QEMU 仓库中的 ACPI HW reduced hotplug 规范文档结合 hw/acpi/generic_event_device.c、include/hw/acpi/generic_event_device.h 等源码系统讲解 QEMU 与 ACPI BIOS 之间 Generic Event DeviceGEDACPI v6.1 引入的ACPI0013设备的接口协议。你将掌握GED 的 ASL 设备模型、4 字节事件选择器Event SelectorIO 接口的位语义、QEMU 侧中断注入与事件分发的实现原理以及它在 ARM virt 机器上如何统一承载内存、CPU、NVDIMM、PCI、电源按键与错误事件的热插拔与通知。一、背景为什么需要 GED传统 ACPI 平台依赖大量固定的 PM1a/PM1b 事件寄存器与分散的中断源来处理电源管理、热插拔等平台事件。而 ACPI v6.1 提出的Generic Event DeviceGED是面向 Hardware-reduced硬件精简平台的一种规范化设备GED 以命名空间设备形式出现_HID固定为ACPI0013它把所有平台事件包括热插拔事件统一由一个设备承载让 OSPM 能够用 ACPI ASL 语句处理中断其处理方式与 GPIO 事件的_EVT方法非常相似所有中断在_CRS中列出具体分发逻辑写在_EVT方法里。QEMU 实现的关键设计是只为 GED 设备分配一个中断通过一块 IO 内存区域来传递受中断影响的设备类型从而用单一中断支持最多32 种事件。这一点在文档与源码注释include/hw/acpi/generic_event_device.h中均有明确说明。适用场景ARM virt 等硬件精简机器如-M virt在启用 ACPI 后GED 取代了传统 x86 平台上的多套热插拔中断机制成为统一的事件入口。x86 的 pc 机器仍走传统的固定事件模型GED 主要服务硬件精简平台。二、GED 设备的 ASL 模型设备描述与_EVT分发文档给出了 GED 设备在 ACPI 命名空间中的典型 ASL 描述这也是 QEMU 中 build_ged_aml() 动态生成 ASL 的目标产物。完整示例如下Device (\_SB.GED) { Name (_HID, ACPI0013) Name (_UID, Zero) Name (_CRS, ResourceTemplate () { Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, ) { 0x00000029, } }) OperationRegion (EREG, SystemMemory, 0x09080000, 0x04) Field (EREG, DWordAcc, NoLock, WriteAsZeros) { ESEL, 32 } Method (_EVT, 1, Serialized) { Local0 ESEL // ESEL IO memory region which specifies the // device type. If (((Local0 One) One)) { MethodEvent1() } If ((Local0 0x2) 0x2) { MethodEvent2() } ... } }对照源码逐项拆解该模型的生成逻辑设备标识_HID为ACPI0013_UID为GED。对应 build_ged_aml() 中的aml_name_decl(_HID, aml_string(ACPI0013))与aml_name_decl(_UID, aml_string(GED_DEVICE))。中断资源_CRS中声明一个边沿触发、高电平有效、独占的中断。对应源码 aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, AML_EXCLUSIVE, ged_irq, 1)。示例中0x00000029十进制 41是 ARM 机器上VIRT_ACPI_GED映射的中断号QEMU 通过 virt-acpi-build.c 中的 build_ged_aml 调用 传入irqmap[VIRT_ACPI_GED] ARM_SPI_BASE即把机器中断映射表中的 GED 中断换算成 SPI 号。事件选择器 IO 区域OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)定义了 4 字节的系统内存区域其中0x09080000正是 ARM virt 机器上VIRT_ACPI_GED的基地址见 hw/arm/virt.c 的[VIRT_ACPI_GED] { 0x09080000, ACPI_GED_EVT_SEL_LEN }。Field中声明 32 位命名域ESEL。源码中使用宏 AML_GED_EVT_REG EREG 与 AML_GED_EVT_SEL ESEL并通过 aml_operation_region aml_field 生成相同结构。_EVT分发方法QEMU 生成的_EVT并非硬编码而是根据机器的ged-event事件位图动态生成。核心循环位于 build_ged_aml()先执行Local0 ESEL然后对每个已使能事件生成一个If ((Local0 event) event)条件块块内调用对应的事件处理动作。_EVT方法声明为aml_method(_EVT, 1, AML_SERIALIZED)即带 1 个参数、串行化执行。各事件位在_EVT中对应的处理动作源码 switch 分支事件位触发动作ASL 层面0x1内存热插拔调用MEMORY_DEVICES_CONTAINER.MEMORY_SLOT_SCAN_METHOD内存槽扫描方法0x2系统下电向电源按键设备PWRB发送通知值0x800x4NVDIMM 热插拔向\_SB.NVDR发送通知值0x800x8CPU 热插拔调用\_SB.GED.CSCNCPU 扫描方法0x10PCI 热插拔获取\_SB.PCI0.BLCK锁调用\_SB.PCI0.PCNT再释放锁0x20错误事件GHES向ACPI_APEI_ERROR_DEVICE发送通知值0x80ACPI 5.0b 表 5-135 规定的错误设备通知值从源码结构看事件位图循环使用ctpop32()统计已使能事件数若机器传入的位图包含ged_supported_events[]之外的位置QEMU 会报错并abort()从而保证_EVT中所有分支都有对应实现。三、GED IO 接口协议4 字节访问文档的核心章节定义了 GED IO 内存即EREG区域的读写语义。QEMU 侧由 ged_evt_read() / ged_evt_write() 实现对应MemoryRegionOps ged_evt_ops其valid.min_access_size与max_access_size均为4强制 4 字节DWord访问。3.1 读访问事件选择器Event Selector从[0x0-0x3]读取 32 位事件选择器位域该值由 QEMU 在触发事件时写入。各 bit 含义如下Bit含义0内存热插拔事件Memory hotplug1系统下电事件System power down2NVDIMM 热插拔事件3CPU 热插拔事件4-31保留与文档位表对应的源码宏定义include/hw/acpi/generic_event_device.h#define ACPI_GED_MEM_HOTPLUG_EVT 0x1 #define ACPI_GED_PWR_DOWN_EVT 0x2 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 #define ACPI_GED_CPU_HOTPLUG_EVT 0x8 #define ACPI_GED_PCI_HOTPLUG_EVT 0x10 #define ACPI_GED_ERROR_EVT 0x20需要注意文档只列出 0-3 四位但当前仓库源码实际支持的位域已扩展到 5 个新增0x10PCI 热插拔与0x20错误事件且 ged_supported_events[] 数组 中还有ACPI_GED_PCI_HOTPLUG_EVT与ACPI_GED_ERROR_EVT。这是文档与实现之间的已知演进读者应以后者为准。读取行为的关键细节QEMU 的 ged_evt_read() 在返回选择器值后会立即将其清零val ged_st-sel; ged_st-sel 0;。这意味着_EVT方法每次只消费一次中断对应的事件位且是读后即清的边沿语义避免同一事件被重复处理。3.2 写访问无操作文档明确指出Nothing is expected to be written into GED IO memory不期望向 GED IO 内存写入任何数据。对应的 ged_evt_write() 为空函数体仅作为 MemoryRegionOps 的占位实现。如果客户机向该区域写入数据会被静默忽略。四、QEMU 侧事件注入从设备事件到位图与中断理解 GED 的核心在于 QEMU 侧的事件注入路径入口是 acpi_ged_send_event()它是AcpiDeviceIf接口send_event回调的实现。整体流程如下状态位到选择器位的映射QEMU 内部统一使用 AcpiEventStatusBits 枚举描述平台事件这些值是客户机 ABI 的一部分不可更改ACPI_PCI_HOTPLUG_STATUS 2, ACPI_CPU_HOTPLUG_STATUS 4, ACPI_MEMORY_HOTPLUG_STATUS 8, ACPI_NVDIMM_HOTPLUG_STATUS 16, ACPI_VMGENID_CHANGE_STATUS 32, ACPI_POWER_DOWN_STATUS 64, ACPI_GENERIC_ERROR 128,acpi_ged_send_event() 按if / else if链将上述状态位转换为对应的 GED 选择器位若事件不在已知集合内则warn_report(GED: Unsupported event %d. No irq injected, ev)后直接返回不注入中断。置位并触发中断将选择器位写入ged_st-sel多个事件可通过sel | sel_bit累积随后调用qemu_irq_pulse(s-irq)向客户机产生一个脉冲中断源码 L356-L359。客户机侧消费OSPM 收到中断后执行_EVT读取ESEL获得选择器值按位判断并执行对应扫描方法如内存槽扫描MEMORY_SLOT_SCAN_METHOD、CPU 扫描\_SB.GED.CSCN。4.1 事件注册ged-event 属性机器通过ged-event属性声明要启用的 GED 事件位图属性定义见 acpi_ged_properties 中的DEFINE_PROP_UINT32(ged-event, AcpiGedState, ged_event_bitmap, 0)。ARM virt 机器在 create_acpi_ged() 中按需组装uint32_t event ACPI_GED_PWR_DOWN_EVT | ACPI_GED_ERROR_EVT; /* 默认启用 */ if (ms-ram_slots) event | ACPI_GED_MEM_HOTPLUG_EVT; /* 配置了内存槽 */ if (ms-nvdimms_state-is_enabled) event | ACPI_GED_NVDIMM_HOTPLUG_EVT; qdev_prop_set_uint32(dev, ged-event, event);也就是说电源下电与错误事件默认启用内存/NVDIMM 热插拔事件仅在相应功能开启时加入位图。在 acpi_ged_realize() 中QEMU 会按位图初始化对应的子设备区域CPU 热插拔容器、PCI 热插拔容器等并把 MMIO 区域暴露给板级代码映射。4.2 热插拔回调链acpi-ged设备实现了TYPE_HOTPLUG_HANDLER接口四个回调L254-L317按设备类型分派plug / unplug / unplug_request对TYPE_PC_DIMM区分普通 DIMM 与 NVDIMM走acpi_memory_plug_cb/nvdimm_acpi_plug_cb对TYPE_CPU走acpi_cpu_plug_cb对TYPE_PCI_DEVICE走acpi_pcihp_device_*_cb其他类型则报错。ospm_status汇总内存与 CPU 热插拔的 OSPM 状态acpi_ged_ospm_status供 QMPquery-acpi-ospm-status等接口使用。五、GED 的寄存器区域与系统控制除了事件选择器区域GED 设备还暴露了一块regs 寄存器区域ged_regs_read/write1 字节访问用于系统睡眠控制与复位。寄存器偏移定义在 generic_event_device.h偏移名称说明0x00ACPI_GED_REG_SLEEP_CTL睡眠控制寄存器写入SLP_TYPbit2-4与SLP_ENbit5若SLP_TYP S5且SLP_EN置位则触发qemu_system_shutdown_request0x01ACPI_GED_REG_SLEEP_STS睡眠状态寄存器写无操作0x02ACPI_GED_REG_RESET复位寄存器写入值0x42ACPI_GED_RESET_VALUE触发qemu_system_reset_request0x03区域总长度ACPI_GED_REG_COUNT——这补充了文档未展开的内容GED 不只是热插拔事件入口还承载了硬件精简平台上的电源管理与复位控制。六、完整工作流程示例内存热插拔综合以上机制一个典型的内存热插拔事件在 ARM virt ACPI 环境下的完整链路为用户通过 QMP/HMP 执行内存 device_addQEMU 热插拔框架调用acpi-ged的plug回调acpi_ged_device_plug_cb完成 DIMM 注册内存状态变化通过acpi_send_event()触发send_event回调acpi_ged_send_event() 将ACPI_MEMORY_HOTPLUG_STATUS映射为ACPI_GED_MEM_HOTPLUG_EVT0x1写入ged_st-selqemu_irq_pulse()向 GIC 注入 GED 中断ARM 上经sysbus_connect_irq(sbdev, 0, qdev_get_gpio_in(vms-gic, irq))连接见 virt.c客户机 OSPM 响应中断执行\_SB.GED._EVT读取ESEL得到0x1命中If ((Local0 One) One)分支调用内存槽扫描方法内存扫描方法检查槽位状态触发_EJ0/_OST等热插拔 ACPI 流程完成设备添加QEMU 侧ESEL已被读清零等待下一次事件。NVDIMM、CPU、PCI 热插拔以及电源按键、GHES 错误事件的分发路径完全一致差别仅在于_EVT中命中的分支与最终调用见第二节表格。七、与其他平台的对比与适用前提x86 传统平台pc/q35继续使用固定的 PM 事件寄存器、SCI 中断及各自独立的热插拔机制piix4/ich9中的acpi-mem-hotplug、CPU 热插拔等不使用 GED。硬件精简平台ARM virt 等在 ACPI 模式下通过 build_ged_aml() 生成\_SB.GED设备若未启用acpi-ged如纯设备树启动或未配置则回退到 GPIO 事件方式virt-acpi-build.c 中acpi_dsdt_add_gpio分支。32 事件上限单一 GED 中断 32 位选择器决定了最多支持 32 种事件当前实现实际使用 6 种。从源码结构看GED 的状态sel选择器、内存/CPU/PCI 热插拔子状态、GHES 相关状态均通过 VMStateDescription 纳入迁移协议acpi-ged及其memhp/cpuhp/ghes/pcihp/hest子区段保证迁移过程中事件状态不丢失——这属于实现层面可验证的结论。八、参考资料与深入阅读接口规范原始文档docs/specs/acpi_hw_reduced_hotplug.rstGED 设备实现hw/acpi/generic_event_device.cGED 头文件与宏定义include/hw/acpi/generic_event_device.h平台事件状态位guest ABIinclude/hw/acpi/acpi_dev_interface.hARM virt 机器 GED 实例化hw/arm/virt.cACPI DSDT 中 GED 的 ASL 生成hw/arm/virt-acpi-build.c赞分享虚拟化硬件仿真【免费下载链接】qemuOfficial QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are disabled. Please only use release tarballs from the QEMU website.项目地址https://gitcode.com/gh_mirrors/qe/qemu点击查看免费下载相关推荐QEMU sPAPR 动态重配置DRC机制完全解析设备树接口、RTAS 调用与热插拔事件实现QEMU sPAPR 动态重配置DRC机制完全解析设备树接口、RTAS 调用与热插拔事件实现 导读 sPAPRpSeries客户机依赖一套名为动态重虚拟化硬件仿真Headlamp 插件事件详解ResourceDetailsViewLoadedEvent 接口与详情视图加载事件机制Headlamp 插件事件详解ResourceDetailsViewLoadedEvent 接口与详情视图加载事件机制 导读 ResourceDetailsV云原生开发工具OpenMower OS 版本升级完全指南旧系统迁移与 A/B 在线更新的 6 个关键点OpenMower OS 版本升级完全指南旧系统迁移与 A/B 在线更新的 6 个关键点 OpenMower 机器人上的系统升级只有两条路往新硬件上 全新烧机器人嵌入式智能硬件硬件开发自动驾驶创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表