1 /** 2 * 解析acpi信息的模块 3 **/ 4 5 #pragma once 6 7 #include <common/glib.h> 8 #include <mm/mm.h> 9 10 #define ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC 0 11 #define ACPI_ICS_TYPE_IO_APIC 1 12 #define ACPI_ICS_TYPE_INTERRUPT_SOURCE_OVERRIDE 2 13 #define ACPI_ICS_TYPE_NMI_SOURCE 3 14 #define ACPI_ICS_TYPE_LOCAL_APIC_NMI 4 15 #define ACPI_ICS_TYPE_LOCAL_APIC_ADDRESS_OVERRIDE 5 16 #define ACPI_ICS_TYPE_IO_SAPIC 6 17 #define ACPI_ICS_TYPE_LOCAL_SAPIC 7 18 #define ACPI_ICS_TYPE_PLATFORM_INTERRUPT_SOURCES 8 19 #define ACPI_ICS_TYPE_PROCESSOR_LOCAL_x2APIC 9 20 #define ACPI_ICS_TYPE_PROCESSOR_LOCAL_x2APIC_NMI 0xA 21 #define ACPI_ICS_TYPE_PROCESSOR_GICC 0xB 22 #define ACPI_ICS_TYPE_PROCESSOR_GICD 0xC 23 #define ACPI_ICS_TYPE_PROCESSOR_GIC_MSI_Frame 0xD 24 #define ACPI_ICS_TYPE_PROCESSOR_GICR 0xE 25 #define ACPI_ICS_TYPE_PROCESSOR_GIC_ITS 0xF 26 // 0x10-0x7f Reserved. OSPM skips structures of the reserved type. 27 // 0x80-0xff Reserved for OEM use 28 // extern const uint64_t acpi_rsdt_virt_addr_base ; // RSDT的虚拟地址 29 // extern const uint64_t acpi_description_header_base ; // RSDT中的第一个entry所在虚拟地址 30 31 bool acpi_use_xsdt = false; 32 struct acpi_RSDP_t 33 { 34 unsigned char Signature[8]; 35 unsigned char Checksum; 36 unsigned char OEMID[6]; 37 38 unsigned char Revision; 39 40 // 32bit physical address of the RSDT 41 uint RsdtAddress; 42 } __attribute__((packed)); 43 44 struct acpi_RSDP_2_t 45 { 46 struct acpi_RSDP_t rsdp1; 47 48 // fields below are only valid when the revision value is 2 or above 49 // 表的长度(单位:字节)从offset=0开始算 50 uint Length; 51 // 64bit的XSDT的物理地址 52 ul XsdtAddress; 53 unsigned char ExtendedChecksum; // 整个表的checksum,包括了之前的checksum区域 54 55 unsigned char Reserved[3]; 56 } __attribute__((packed)); 57 58 struct acpi_system_description_table_header_t 59 { 60 // The ascii string representation of the table header. 61 unsigned char Signature[4]; 62 // 整个表的长度(单位:字节),包括了header,从偏移量0处开始 63 uint Length; 64 // The revision of the structure corresponding to the signature field for this table. 65 unsigned char Revision; 66 // The entire table, including the checksum field, must add to zero to be considered valid. 67 char Checksum; 68 69 unsigned char OEMID[6]; 70 unsigned char OEM_Table_ID[8]; 71 uint OEMRevision; 72 uint CreatorID; 73 uint CreatorRevision; 74 } __attribute__((packed)); 75 76 // HPET描述符结构体,sign为HPET 77 struct acpi_HPET_description_table_t 78 { 79 struct acpi_system_description_table_header_t header; 80 81 uint8_t hardware_rev_id; 82 uint8_t comparator_count : 5; // Number of Comparators in 1st Timer Block 83 uint8_t counter_size : 1; // COUNT_SIZE_CAP counter size 84 uint8_t reserved0 : 1; 85 uint8_t legacy_replacement : 1; // LegacyReplacement IRQ Routing Capable 86 uint16_t pci_vendor_id; // PCI Vendor ID of 1st Timer Block 87 88 uint8_t address_space_id; // 0 - system memory, 1 - system I/O 89 uint8_t register_bit_width; 90 uint8_t register_bit_offset; 91 uint8_t reserved1; 92 uint64_t address; 93 94 uint8_t hpet_number; 95 uint16_t minimum_tick; // The minimum clock ticks can be set without lost interrupts while the counter is programmed to operate in periodic mode 96 97 uint8_t page_protection; 98 99 } __attribute__((packed)); 100 101 // =========== MADT结构,其中Signature为APIC ============ 102 struct acpi_Multiple_APIC_Description_Table_t 103 { 104 struct acpi_system_description_table_header_t header; 105 106 // 32bit的,每个处理器可访问的local中断控制器的物理地址 107 uint Local_Interrupt_Controller_Address; 108 109 // Multiple APIC flags, 详见 ACPI Specification Version 6.3, Table 5-44 110 uint flags; 111 112 // 接下来的(length-44)字节是Interrupt Controller Structure 113 }; 114 115 struct apic_Interrupt_Controller_Structure_header_t 116 { 117 unsigned char type; 118 unsigned char length; 119 }; 120 121 struct acpi_Processor_Local_APIC_Structure_t 122 { 123 // type=0 124 struct apic_Interrupt_Controller_Structure_header_t header; 125 unsigned char ACPI_Processor_UID; 126 // 处理器的local apic id 127 unsigned char local_apic_id; 128 //详见 ACPI Specification Version 6.3, Table 5-47 129 uint flags; 130 }; 131 132 struct acpi_IO_APIC_Structure_t 133 { 134 // type=1 135 struct apic_Interrupt_Controller_Structure_header_t header; 136 unsigned char IO_APIC_ID; 137 unsigned char Reserved; 138 // 32bit的IO APIC物理地址 (每个IO APIC都有一个独立的物理地址) 139 uint IO_APIC_Address; 140 // 当前IO APIC的全局系统中断向量号起始值 141 // The number of intr inputs is determined by the IO APIC's Max Redir Entry register. 142 uint Global_System_Interrupt_Base; 143 }; 144 145 // =========== RSDT 结构 ============= 146 struct acpi_RSDT_Structure_t 147 { 148 // 通过RSDT的header->Length可以计算出entry的数量n 149 // n = (length - 32)/4 150 struct acpi_system_description_table_header_t header; 151 152 // 一个包含了n个32bit物理地址的数组,指向了其他的description headers 153 uint Entry; 154 }; 155 156 // =========== XSDT 结构 ============= 157 struct acpi_XSDT_Structure_t 158 { 159 // 通过RSDT的header->Length可以计算出entry的数量n 160 // n = (length - 36)/8 161 struct acpi_system_description_table_header_t header; 162 163 // 一个包含了n个64bit物理地址的数组,指向了其他的description headers 164 ul Entry; 165 }; 166 167 /** 168 * @brief 迭代器,用于迭代描述符头(位于ACPI标准文件的Table 5-29) 169 * @param _fun 迭代操作调用的函数 170 * @param _data 数据 171 */ 172 void acpi_iter_SDT(bool (*_fun)(const struct acpi_system_description_table_header_t *, void *), 173 void *_data); 174 175 /** 176 * @brief 获取MADT信息 Multiple APIC Description Table 177 * 178 * @param _iter_data 要被迭代的信息的结构体 179 * @param _data 返回的MADT的虚拟地址 180 * @param count 返回数组的长度 181 * @return true 182 * @return false 183 */ 184 bool acpi_get_MADT(const struct acpi_system_description_table_header_t *_iter_data, void *_data); 185 186 /** 187 * @brief 获取HPET HPET_description_table 188 * 189 * @param _iter_data 要被迭代的信息的结构体 190 * @param _data 返回的HPET表的虚拟地址 191 * @return true 192 * @return false 193 */ 194 bool acpi_get_HPET(const struct acpi_system_description_table_header_t *_iter_data, void *_data); 195 196 /** 197 * @brief 获取MCFG MCFG_description_table 198 * 199 * @param _iter_data 要被迭代的信息的结构体 200 * @param _data 返回的MCFG表的虚拟地址 201 * @return true 202 * @return false 203 */ 204 bool acpi_get_MCFG(const struct acpi_system_description_table_header_t *_iter_data, void *_data); 205 // 初始化acpi模块 206 void acpi_init();