相关参考

相关资料下载:
链接: https://pan.baidu.com/s/1uUwhHKztLcZlruONLPm-oA 密码: 7kgf

ACPI协议中关键点

  • P120 Table 5-29 描述了 /sys/firmware/acpi/tables/ 中各表项 内容

ACPI使用

因为ACPI不是研究的重点,但X86系统各方面离不开这玩意,所以先介绍下Linux下使用
可以参考:Linux内核软件架构基础-鲲鹏920 是比设备树更牛逼的东西。

先不用去就纠结这些表咋来的,只需要怎么获取,后期对照相关架构的硬件手册来看即可。

ACPI系统描述表的获取

首先要知道系统中 ACPI有个系统描述表
可参考 ACPI协议规范 Chapter 5.2: ACPI System Description Tables

在用户空间可解析这些表信息

  1. sudo apt-get install -y iasl acpica-tools
  2. sudo su # need root
  3. ############## acpi工具快速打印################
  4. ### acpidump 可快速打印出所有的表项概要
  5. root@inno-MS-7B89:testacpi# acpidump -s
  6. ACPI: SSDT 0x0000000000000000 003EC9 (v01 AMD AMD CPU 00000001 AMD 00000001)
  7. ACPI: MCFG 0x0000000000000000 00003C (v01 ALASKA A M I 01072009 MSFT 00010013)
  8. ACPI: APIC 0x0000000000000000 00015E (v03 ALASKA A M I 01072009 AMI 00010013)
  9. ACPI: CRAT 0x0000000000000000 000ED8 (v01 AMD AMD CRAT 00000001 AMD 00000001)
  10. ACPI: PCCT 0x0000000000000000 00006E (v01 AMD AMD PCCT 00000001 AMD 00000000)
  11. ACPI: SSDT 0x0000000000000000 008C98 (v02 AMD AMD ALIB 00000002 MSFT 04000000)
  12. ACPI: CDIT 0x0000000000000000 000029 (v01 AMD AMD CDIT 00000001 AMD 00000001)
  13. ACPI: UEFI 0x0000000000000000 000042 (v01 ALASKA A M I 00000002 01000013)
  14. ACPI: IVRS 0x0000000000000000 0000D0 (v02 AMD AMD IVRS 00000001 AMD 00000000)
  15. ACPI: DSDT 0x0000000000000000 007C55 (v02 ALASKA A M I 01072009 INTL 20120913)
  16. ACPI: WSMT 0x0000000000000000 000028 (v01 ALASKA A M I 01072009 AMI 00010013)
  17. ACPI: SSDT 0x0000000000000000 001D4A (v01 AMD AmdTable 00000001 INTL 20120913)
  18. ACPI: SSDT 0x0000000000000000 003776 (v01 AMD AMD AOD 00000001 INTL 20120913)
  19. ACPI: FACP 0x0000000000000000 000114 (v06 ALASKA A M I 01072009 AMI 00010013)
  20. ACPI: FPDT 0x0000000000000000 000044 (v01 ALASKA A M I 01072009 AMI 00010013)
  21. ACPI: SSDT 0x0000000000000000 0000FC (v02 ALASKA CPUSSDT 01072009 AMI 01072009)
  22. ACPI: HPET 0x0000000000000000 000038 (v01 ALASKA A M I 01072009 AMI 00000005)
  23. ACPI: SSDT 0x0000000000000000 0000BF (v01 AMD AMD PT 00001000 INTL 20120913)
  24. ACPI: FIDT 0x0000000000000000 00009C (v01 ALASKA A M I 01072009 AMI 00010013)
  25. ACPI: FACS 0x0000000000000000 000040
  26. ACPI: BGRT 0x0000000000000000 000038 (v01 ALASKA A M I 01072009 AMI 00010013)
  27. mkdir -p testacpi && cd testacpi
  28. acpidump > acpidump.out # 将ACPI表二进制打印到文件
  29. acpixtract -a acpidump.out # 解析acpi表,生成各个dat文件
  30. iasl -d xxx.dat # iasl会解析acpi 二进制表,生成xxx.dsl描述文件
  31. 注:也可将cp /sys/firmware/acpi/tables/* 中的文件拷贝到其他目录(sysfs下不能用iasl去解析),
  32. 然后用iasl去解析
  33. mkdir -p testacpi && cp /sys/firmware/acpi/tables/* ./testacpi -r
  34. cd testacpi
  35. rm data dynamic -rf
  36. iasl -d *
  37. 会给每个文件生成对应的 .dsl文件,这是将acpi翻译成描述信息的内容

内核代码中获取ACPI表信息 demo

  1. // 比如:./drivers/iommu/intel/dmar.c中
  2. detect_intel_iommu
  3. dmar_table_detect();
  4. acpi_status status = acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_tbl);
  5. acpi_put_table(dmar_tbl);
  6. struct acpi_table_header {
  7. char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
  8. u32 length; /* Length of table in bytes, including this header */
  9. u8 revision; /* ACPI Specification minor version number */
  10. u8 checksum; /* To make sum of entire table == 0 */
  11. char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
  12. char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
  13. u32 oem_revision; /* OEM revision number */
  14. char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */
  15. u32 asl_compiler_revision; /* ASL compiler version */
  16. };
  17. cat dmar.dsl | more
  18. [000h 0000 4] Signature : "DMAR" [DMA Remapping table]
  19. [004h 0004 4] Table Length : 000000A8
  20. [008h 0008 1] Revision : 01
  21. [009h 0009 1] Checksum : 2A
  22. [00Ah 0010 6] Oem ID : "INTEL "
  23. [010h 0016 8] Oem Table ID : "NUC8i3BE"
  24. [018h 0024 4] Oem Revision : 00000040
  25. [01Ch 0028 4] Asl Compiler ID : " "
  26. [020h 0032 4] Asl Compiler Revision : 01000013
  27. ......

ACPI的METHOD获取

在看PCI代码的时候,遇到关键点的时候,总是被ACPI打断,导致无法继续分析

比如:PCI域的获取,PCI mcfg的地址,PCI资源信息

  1. acpi_pci_root_add
  2. |- acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL,
  3. &segment);
  4. acpi_pci_root_get_mcfg_addr
  5. |- status = acpi_evaluate_integer(handle, METHOD_NAME__CBA,
  6. NULL, &mcfg_addr);
  7. acpi_evaluate_integer()实际调用 acpi_evaluate_object()。
  8. 这个实现在./drivers/acpi/acpica/nsxfeval.c中,其最终的实现是这个函数:
  9. acpi_ns_evaluate(info)->acpi_ps_execute_method(info)->acpi_ps_parse_aml()
  10. ......
  11. #define METHOD_NAME__CBA "_CBA"
  12. #define METHOD_NAME__SEG "_SEG"
  13. #define METHOD_NAME__SRS "_SRS"
  14. #define METHOD_NAME__STA "_STA"
  15. #define METHOD_NAME__SUB "_SUB"
  16. #define METHOD_NAME__UID "_UID"

Linux内核软件架构基础-鲲鹏920 中描述了:acpi_evaluate_object 是调用ACPI的 (AML作为一种抽象语言集成在ACPI的数据结构中,由)OS一侧 的AML虚拟机解释执行。

什么是ACPI

ACPI与UEFI
ACPI规范阅读笔记

高级配置与电源接口(Advanced Configuration and Power Interface),简称ACPI,1997年由IntelMicrosoftToshiba 所共同制定提供操作系统应用程序管理所有电源管理接口
**

ACPI的目标

ASL教程:asl_tutorial_v20190625.pdf中描述
image.png
ACPI就是根据 硬件手册 去抽象出 计算机中 所有components, 生成AML文件,然后进行所有的组件管理等任务。

ACPI规范不是仅仅针对某一项调节,而是要协调各个部分,综合管理,使其达到最佳状态

ACPI是一种工业级的接口协议,它同时规范了硬件和软件的接口,使得OS可以直接配置和电源管理所有设备以及整个系统。操作系统可以收集用户、应用、硬件等各方面信息做出综合判断以及执行。

支持传统BIOS电源管理的电脑从传统模式启动然后等到ACPI OS启动之后转换到工作状态。而不支持传统模式的电脑如(RISC:ARM)直接冲G3直接到G0。

ACPI整体框图

image.png
**

ACPI主要包含以下几个部分:

  • 1.系统电源管理(System power management)
  • 2.设备电源管理(Device power management)
  • 3. 处理器电源管理(Processor power management)
  • 4.设备和处理器性能管理(Device and processor performance management)
  • 5.配置/即插即用(Configuration/Plug and Play)
  • 6.系统事件(System Event)
  • 7.电池管理(Battery management)
  • 8.温度管理(Thermal management)
  • 9.嵌入式控制器(Embedded Controller)
  • 10.SMBus控制器(SMBus Controller)