]> git.proxmox.com Git - mirror_qemu.git/blob - hw/i386/acpi-dsdt-mem-hotplug.dsl
acpi: add hardware implementation for memory hot unplug
[mirror_qemu.git] / hw / i386 / acpi-dsdt-mem-hotplug.dsl
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 */
15
16 External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
17
18 Scope(\_SB.PCI0) {
19 Device(MEMORY_HOTPLUG_DEVICE) {
20 Name(_HID, "PNP0A06")
21 Name(_UID, "Memory hotplug resources")
22 External(MEMORY_SLOTS_NUMBER, IntObj)
23
24 /* Memory hotplug IO registers */
25 External(MEMORY_SLOT_ADDR_LOW, FieldUnitObj) // read only
26 External(MEMORY_SLOT_ADDR_HIGH, FieldUnitObj) // read only
27 External(MEMORY_SLOT_SIZE_LOW, FieldUnitObj) // read only
28 External(MEMORY_SLOT_SIZE_HIGH, FieldUnitObj) // read only
29 External(MEMORY_SLOT_PROXIMITY, FieldUnitObj) // read only
30 External(MEMORY_SLOT_ENABLED, FieldUnitObj) // 1 if enabled, read only
31 External(MEMORY_SLOT_INSERT_EVENT, FieldUnitObj) // (read) 1 if has a insert event. (write) 1 to clear event
32 External(MEMORY_SLOT_REMOVE_EVENT, FieldUnitObj) // (read) 1 if has a remove event. (write) 1 to clear event
33 External(MEMORY_SLOT_EJECT, FieldUnitObj) // initiates device eject, write only
34 External(MEMORY_SLOT_SLECTOR, FieldUnitObj) // DIMM selector, write only
35 External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event code, write only
36 External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status code, write only
37
38 Method(_STA, 0) {
39 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
40 Return(0x0)
41 }
42 /* present, functioning, decoding, not shown in UI */
43 Return(0xB)
44 }
45
46 Mutex (MEMORY_SLOT_LOCK, 0)
47
48 Method(MEMORY_SLOT_SCAN_METHOD, 0) {
49 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
50 Return(Zero)
51 }
52
53 Store(Zero, Local0) // Mem devs iterrator
54 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
55 while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
56 Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
57 If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
58 MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
59 Store(1, MEMORY_SLOT_INSERT_EVENT)
60 } Elseif (LEqual(MEMORY_SLOT_REMOVE_EVENT, One)) { // Ejection request
61 MEMORY_SLOT_NOTIFY_METHOD(Local0, 3)
62 Store(1, MEMORY_SLOT_REMOVE_EVENT)
63 }
64 Add(Local0, One, Local0) // goto next DIMM
65 }
66 Release(MEMORY_SLOT_LOCK)
67 Return(One)
68 }
69
70 Method(MEMORY_SLOT_STATUS_METHOD, 1) {
71 Store(Zero, Local0)
72
73 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
74 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
75
76 If (LEqual(MEMORY_SLOT_ENABLED, One)) {
77 Store(0xF, Local0)
78 }
79
80 Release(MEMORY_SLOT_LOCK)
81 Return(Local0)
82 }
83
84 Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
85 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
86 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
87
88 Name(MR64, ResourceTemplate() {
89 QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
90 Cacheable, ReadWrite,
91 0x0000000000000000, // Address Space Granularity
92 0x0000000000000000, // Address Range Minimum
93 0xFFFFFFFFFFFFFFFE, // Address Range Maximum
94 0x0000000000000000, // Address Translation Offset
95 0xFFFFFFFFFFFFFFFF, // Address Length
96 ,, MW64, AddressRangeMemory, TypeStatic)
97 })
98
99 CreateDWordField(MR64, 14, MINL)
100 CreateDWordField(MR64, 18, MINH)
101 CreateDWordField(MR64, 38, LENL)
102 CreateDWordField(MR64, 42, LENH)
103 CreateDWordField(MR64, 22, MAXL)
104 CreateDWordField(MR64, 26, MAXH)
105
106 Store(MEMORY_SLOT_ADDR_HIGH, MINH)
107 Store(MEMORY_SLOT_ADDR_LOW, MINL)
108 Store(MEMORY_SLOT_SIZE_HIGH, LENH)
109 Store(MEMORY_SLOT_SIZE_LOW, LENL)
110
111 // 64-bit math: MAX = MIN + LEN - 1
112 Add(MINL, LENL, MAXL)
113 Add(MINH, LENH, MAXH)
114 If (LLess(MAXL, MINL)) {
115 Add(MAXH, One, MAXH)
116 }
117 If (LLess(MAXL, One)) {
118 Subtract(MAXH, One, MAXH)
119 }
120 Subtract(MAXL, One, MAXL)
121
122 If (LEqual(MAXH, Zero)){
123 Name(MR32, ResourceTemplate() {
124 DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
125 Cacheable, ReadWrite,
126 0x00000000, // Address Space Granularity
127 0x00000000, // Address Range Minimum
128 0xFFFFFFFE, // Address Range Maximum
129 0x00000000, // Address Translation Offset
130 0xFFFFFFFF, // Address Length
131 ,, MW32, AddressRangeMemory, TypeStatic)
132 })
133 CreateDWordField(MR32, MW32._MIN, MIN)
134 CreateDWordField(MR32, MW32._MAX, MAX)
135 CreateDWordField(MR32, MW32._LEN, LEN)
136 Store(MINL, MIN)
137 Store(MAXL, MAX)
138 Store(LENL, LEN)
139
140 Release(MEMORY_SLOT_LOCK)
141 Return(MR32)
142 }
143
144 Release(MEMORY_SLOT_LOCK)
145 Return(MR64)
146 }
147
148 Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
149 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
150 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
151 Store(MEMORY_SLOT_PROXIMITY, Local0)
152 Release(MEMORY_SLOT_LOCK)
153 Return(Local0)
154 }
155
156 Method(MEMORY_SLOT_OST_METHOD, 4) {
157 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
158 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
159 Store(Arg1, MEMORY_SLOT_OST_EVENT)
160 Store(Arg2, MEMORY_SLOT_OST_STATUS)
161 Release(MEMORY_SLOT_LOCK)
162 }
163
164 Method(MEMORY_SLOT_EJECT_METHOD, 2) {
165 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
166 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
167 Store(1, MEMORY_SLOT_EJECT)
168 Release(MEMORY_SLOT_LOCK)
169 }
170 } // Device()
171 } // Scope()