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.
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.
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/>.
15 #include "hw/acpi/pc-hotplug.h"
17 ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
19 DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
22 /****************************************************************
24 ****************************************************************/
27 ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_start
29 ACPI_EXTRACT_NAME_DWORD_CONST acpi_pci32_end
31 ACPI_EXTRACT_NAME_BYTE_CONST acpi_pci64_valid
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 })
42 /****************************************************************
44 ****************************************************************/
48 * S3 (suspend-to-ram), S4 (suspend-to-disk) and S5 (power-off) type codes:
49 * must match piix4 emulation.
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 */
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 */
67 Name(_S5, Package(0x04) {
68 Zero, /* PM1a_CNT.SLP_TYP */
69 Zero, /* PM1b_CNT.SLP_TYP */
75 External(\_SB.PCI0, DeviceObj)
76 External(\_SB.PCI0.ISA, DeviceObj)
78 Scope(\_SB.PCI0.ISA) {
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
84 OperationRegion(PEOR, SystemIO, PEST, 0x01)
85 Field(PEOR, ByteAcc, NoLock, Preserve) {
89 Method(_STA, 0, NotSerialized) {
91 If (LEqual(Local0, Zero)) {
98 Method(RDPT, 0, NotSerialized) {
103 Method(WRPT, 1, NotSerialized) {
107 Name(_CRS, ResourceTemplate() {
108 IO(Decode16, 0x00, 0x00, 0x01, 0x01, IO)
111 CreateWordField(_CRS, IO._MIN, IOMN)
112 CreateWordField(_CRS, IO._MAX, IOMX)
114 Method(_INI, 0, NotSerialized) {
121 External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
123 Device(MEMORY_HOTPLUG_DEVICE) {
124 Name(_HID, "PNP0A06")
125 Name(_UID, "Memory hotplug resources")
127 ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
128 Name(MEMORY_SLOTS_NUMBER, 0x12345678)
130 /* Memory hotplug IO registers */
131 OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
132 ACPI_MEMORY_HOTPLUG_BASE,
133 ACPI_MEMORY_HOTPLUG_IO_LEN)
135 Name(_CRS, ResourceTemplate() {
136 IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
137 0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
141 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
144 /* present, functioning, decoding, not shown in UI */
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
155 Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
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
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
168 Method(MEMORY_SLOT_SCAN_METHOD, 0) {
169 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
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)
181 // TODO: handle memory eject request
182 Add(Local0, One, Local0) // goto next DIMM
184 Release(MEMORY_SLOT_LOCK)
188 Method(MEMORY_SLOT_STATUS_METHOD, 1) {
191 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
192 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
194 If (LEqual(MEMORY_SLOT_ENABLED, One)) {
198 Release(MEMORY_SLOT_LOCK)
202 Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
203 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
204 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
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)
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)
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)
229 // 64-bit math: MAX = MIN + LEN - 1
230 Add(MINL, LENL, MAXL)
231 Add(MINH, LENH, MAXH)
232 If (LLess(MAXL, MINL)) {
235 If (LLess(MAXL, One)) {
236 Subtract(MAXH, One, MAXH)
238 Subtract(MAXL, One, MAXL)
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)
251 CreateDWordField(MR32, MW32._MIN, MIN)
252 CreateDWordField(MR32, MW32._MAX, MAX)
253 CreateDWordField(MR32, MW32._LEN, LEN)
258 Release(MEMORY_SLOT_LOCK)
262 Release(MEMORY_SLOT_LOCK)
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)
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)