]>
Commit | Line | Data |
---|---|---|
74523b85 MT |
1 | /* |
2 | * This program is free software; you can redistribute it and/or modify | |
3 | * it under the terms of the GNU General Public License as published by | |
4 | * the Free Software Foundation; either version 2 of the License, or | |
5 | * (at your option) any later version. | |
6 | ||
7 | * This program is distributed in the hope that it will be useful, | |
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
10 | * GNU General Public License for more details. | |
11 | ||
12 | * You should have received a copy of the GNU General Public License along | |
13 | * with this program; if not, see <http://www.gnu.org/licenses/>. | |
14 | */ | |
bef3492d | 15 | #include "hw/acpi/pc-hotplug.h" |
74523b85 MT |
16 | |
17 | ACPI_EXTRACT_ALL_CODE ssdp_misc_aml | |
18 | ||
19 | DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1) | |
20 | { | |
21 | ||
22 | /**************************************************************** | |
23 | * PCI memory ranges | |
24 | ****************************************************************/ | |
25 | ||
26 | Scope(\) { | |
27 | ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start | |
28 | Name(P0S, 0x12345678) | |
29 | ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end | |
30 | Name(P0E, 0x12345678) | |
31 | ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid | |
32 | Name(P1V, 0x12) | |
33 | ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_start | |
34 | Name(P1S, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) | |
35 | ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_end | |
36 | Name(P1E, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) | |
37 | ACPI_EXTRACT_NAME_BUFFER8 acpi_pci64_length | |
38 | Name(P1L, Buffer() { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }) | |
39 | } | |
40 | ||
41 | ||
42 | /**************************************************************** | |
43 | * Suspend | |
44 | ****************************************************************/ | |
45 | ||
46 | Scope(\) { | |
47 | /* | |
48 | * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes: | |
49 | * must match piix4 emulation. | |
50 | */ | |
51 | ||
52 | ACPI_EXTRACT_NAME_STRING acpi_s3_name | |
53 | Name(_S3, Package(0x04) { | |
54 | One, /* PM1a_CNT.SLP_TYP */ | |
55 | One, /* PM1b_CNT.SLP_TYP */ | |
56 | Zero, /* reserved */ | |
57 | Zero /* reserved */ | |
58 | }) | |
59 | ACPI_EXTRACT_NAME_STRING acpi_s4_name | |
60 | ACPI_EXTRACT_PKG_START acpi_s4_pkg | |
61 | Name(_S4, Package(0x04) { | |
62 | 0x2, /* PM1a_CNT.SLP_TYP */ | |
63 | 0x2, /* PM1b_CNT.SLP_TYP */ | |
64 | Zero, /* reserved */ | |
65 | Zero /* reserved */ | |
66 | }) | |
67 | Name(_S5, Package(0x04) { | |
68 | Zero, /* PM1a_CNT.SLP_TYP */ | |
69 | Zero, /* PM1b_CNT.SLP_TYP */ | |
70 | Zero, /* reserved */ | |
71 | Zero /* reserved */ | |
72 | }) | |
73 | } | |
74 | ||
75 | External(\_SB.PCI0, DeviceObj) | |
76 | External(\_SB.PCI0.ISA, DeviceObj) | |
77 | ||
78 | Scope(\_SB.PCI0.ISA) { | |
79 | Device(PEVT) { | |
80 | Name(_HID, "QEMU0001") | |
81 | /* PEST will be patched to be Zero if no such device */ | |
82 | ACPI_EXTRACT_NAME_WORD_CONST ssdt_isa_pest | |
83 | Name(PEST, 0xFFFF) | |
84 | OperationRegion(PEOR, SystemIO, PEST, 0x01) | |
85 | Field(PEOR, ByteAcc, NoLock, Preserve) { | |
86 | PEPT, 8, | |
87 | } | |
88 | ||
89 | Method(_STA, 0, NotSerialized) { | |
90 | Store(PEST, Local0) | |
91 | If (LEqual(Local0, Zero)) { | |
92 | Return (0x00) | |
93 | } Else { | |
94 | Return (0x0F) | |
95 | } | |
96 | } | |
97 | ||
98 | Method(RDPT, 0, NotSerialized) { | |
99 | Store(PEPT, Local0) | |
100 | Return (Local0) | |
101 | } | |
102 | ||
103 | Method(WRPT, 1, NotSerialized) { | |
104 | Store(Arg0, PEPT) | |
105 | } | |
106 | ||
107 | Name(_CRS, ResourceTemplate() { | |
108 | IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO) | |
109 | }) | |
110 | ||
111 | CreateWordField(_CRS, IO._MIN, IOMN) | |
112 | CreateWordField(_CRS, IO._MAX, IOMX) | |
113 | ||
114 | Method(_INI, 0, NotSerialized) { | |
115 | Store(PEST, IOMN) | |
116 | Store(PEST, IOMX) | |
117 | } | |
118 | } | |
119 | } | |
bef3492d IM |
120 | |
121 | External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj) | |
122 | Scope(\_SB.PCI0) { | |
123 | Device(MEMORY_HOPTLUG_DEVICE) { | |
124 | Name(_HID, "PNP0A06") | |
125 | Name(_UID, "Memory hotplug resources") | |
126 | ||
127 | ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots | |
128 | Name(MEMORY_SLOTS_NUMBER, 0x12345678) | |
129 | ||
130 | /* Memory hotplug IO registers */ | |
131 | OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO, | |
132 | ACPI_MEMORY_HOTPLUG_BASE, | |
133 | ACPI_MEMORY_HOTPLUG_IO_LEN) | |
134 | ||
135 | Name(_CRS, ResourceTemplate() { | |
136 | IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE, | |
137 | 0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO) | |
138 | }) | |
139 | ||
140 | Method(_STA, 0) { | |
141 | If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { | |
142 | Return(0x0) | |
143 | } | |
144 | /* present, functioning, decoding, not shown in UI */ | |
145 | Return(0xB) | |
146 | } | |
147 | ||
148 | Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) { | |
149 | MEMORY_SLOT_ADDR_LOW, 32, // read only | |
150 | MEMORY_SLOT_ADDR_HIGH, 32, // read only | |
151 | MEMORY_SLOT_SIZE_LOW, 32, // read only | |
152 | MEMORY_SLOT_SIZE_HIGH, 32, // read only | |
153 | MEMORY_SLOT_PROXIMITY, 32, // read only | |
154 | } | |
155 | Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) { | |
156 | Offset(20), | |
157 | MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only | |
158 | MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event | |
159 | } | |
160 | ||
161 | Mutex (MEMORY_SLOT_LOCK, 0) | |
162 | Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) { | |
163 | MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only | |
164 | MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only | |
165 | MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only | |
166 | } | |
167 | ||
168 | Method(MEMORY_SLOT_SCAN_METHOD, 0) { | |
169 | If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { | |
170 | Return(Zero) | |
171 | } | |
172 | ||
173 | Store(Zero, Local0) // Mem devs iterrator | |
174 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) | |
175 | while (LLess(Local0, MEMORY_SLOTS_NUMBER)) { | |
176 | Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM | |
177 | If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check | |
178 | MEMORY_SLOT_NOTIFY_METHOD(Local0, 1) | |
179 | Store(1, MEMORY_SLOT_INSERT_EVENT) | |
180 | } | |
181 | // TODO: handle memory eject request | |
182 | Add(Local0, One, Local0) // goto next DIMM | |
183 | } | |
184 | Release(MEMORY_SLOT_LOCK) | |
185 | Return(One) | |
186 | } | |
187 | ||
188 | Method(MEMORY_SLOT_STATUS_METHOD, 1) { | |
189 | Store(Zero, Local0) | |
190 | ||
191 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) | |
192 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM | |
193 | ||
194 | If (LEqual(MEMORY_SLOT_ENABLED, One)) { | |
195 | Store(0xF, Local0) | |
196 | } | |
197 | ||
198 | Release(MEMORY_SLOT_LOCK) | |
199 | Return(Local0) | |
200 | } | |
201 | ||
202 | Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) { | |
203 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) | |
204 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM | |
205 | ||
206 | Name(MR64, ResourceTemplate() { | |
207 | QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, | |
208 | Cacheable, ReadWrite, | |
209 | 0x0000000000000000, // Address Space Granularity | |
210 | 0x0000000000000000, // Address Range Minimum | |
211 | 0xFFFFFFFFFFFFFFFE, // Address Range Maximum | |
212 | 0x0000000000000000, // Address Translation Offset | |
213 | 0xFFFFFFFFFFFFFFFF, // Address Length | |
214 | ,, MW64, AddressRangeMemory, TypeStatic) | |
215 | }) | |
216 | ||
217 | CreateDWordField(MR64, 14, MINL) | |
218 | CreateDWordField(MR64, 18, MINH) | |
219 | CreateDWordField(MR64, 38, LENL) | |
220 | CreateDWordField(MR64, 42, LENH) | |
221 | CreateDWordField(MR64, 22, MAXL) | |
222 | CreateDWordField(MR64, 26, MAXH) | |
223 | ||
224 | Store(MEMORY_SLOT_ADDR_HIGH, MINH) | |
225 | Store(MEMORY_SLOT_ADDR_LOW, MINL) | |
226 | Store(MEMORY_SLOT_SIZE_HIGH, LENH) | |
227 | Store(MEMORY_SLOT_SIZE_LOW, LENL) | |
228 | ||
229 | // 64-bit math: MAX = MIN + LEN - 1 | |
230 | Add(MINL, LENL, MAXL) | |
231 | Add(MINH, LENH, MAXH) | |
232 | If (LLess(MAXL, MINL)) { | |
233 | Add(MAXH, One, MAXH) | |
234 | } | |
235 | If (LLess(MAXL, One)) { | |
236 | Subtract(MAXH, One, MAXH) | |
237 | } | |
238 | Subtract(MAXL, One, MAXL) | |
239 | ||
240 | If (LEqual(MAXH, Zero)){ | |
241 | Name(MR32, ResourceTemplate() { | |
242 | DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, | |
243 | Cacheable, ReadWrite, | |
244 | 0x00000000, // Address Space Granularity | |
245 | 0x00000000, // Address Range Minimum | |
246 | 0xFFFFFFFE, // Address Range Maximum | |
247 | 0x00000000, // Address Translation Offset | |
248 | 0xFFFFFFFF, // Address Length | |
249 | ,, MW32, AddressRangeMemory, TypeStatic) | |
250 | }) | |
251 | CreateDWordField(MR32, MW32._MIN, MIN) | |
252 | CreateDWordField(MR32, MW32._MAX, MAX) | |
253 | CreateDWordField(MR32, MW32._LEN, LEN) | |
254 | Store(MINL, MIN) | |
255 | Store(MAXL, MAX) | |
256 | Store(LENL, LEN) | |
257 | ||
258 | Release(MEMORY_SLOT_LOCK) | |
259 | Return(MR32) | |
260 | } | |
261 | ||
262 | Release(MEMORY_SLOT_LOCK) | |
263 | Return(MR64) | |
264 | } | |
265 | ||
266 | Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) { | |
267 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) | |
268 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM | |
269 | Store(MEMORY_SLOT_PROXIMITY, Local0) | |
270 | Release(MEMORY_SLOT_LOCK) | |
271 | Return(Local0) | |
272 | } | |
273 | ||
274 | Method(MEMORY_SLOT_OST_METHOD, 4) { | |
275 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) | |
276 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM | |
277 | Store(Arg1, MEMORY_SLOT_OST_EVENT) | |
278 | Store(Arg2, MEMORY_SLOT_OST_STATUS) | |
279 | Release(MEMORY_SLOT_LOCK) | |
280 | } | |
281 | } // Device() | |
282 | } // Scope() | |
74523b85 | 283 | } |