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 // 初始化acpi模块
197 void acpi_init();