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/>.
16 External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
19 Device(MEMORY_HOTPLUG_DEVICE) {
21 Name(_UID, "Memory hotplug resources")
22 External(MEMORY_SLOTS_NUMBER, IntObj)
24 /* Memory hotplug IO registers */
25 OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
26 ACPI_MEMORY_HOTPLUG_BASE,
27 ACPI_MEMORY_HOTPLUG_IO_LEN)
29 Name(_CRS, ResourceTemplate() {
30 IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
31 0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
35 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
38 /* present, functioning, decoding, not shown in UI */
42 Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
43 MEMORY_SLOT_ADDR_LOW, 32, // read only
44 MEMORY_SLOT_ADDR_HIGH, 32, // read only
45 MEMORY_SLOT_SIZE_LOW, 32, // read only
46 MEMORY_SLOT_SIZE_HIGH, 32, // read only
47 MEMORY_SLOT_PROXIMITY, 32, // read only
49 Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
51 MEMORY_SLOT_ENABLED, 1, // 1 if enabled, read only
52 MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
55 Mutex (MEMORY_SLOT_LOCK, 0)
56 Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
57 MEMORY_SLOT_SLECTOR, 32, // DIMM selector, write only
58 MEMORY_SLOT_OST_EVENT, 32, // _OST event code, write only
59 MEMORY_SLOT_OST_STATUS, 32, // _OST status code, write only
62 Method(MEMORY_SLOT_SCAN_METHOD, 0) {
63 If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
67 Store(Zero, Local0) // Mem devs iterrator
68 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
69 while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
70 Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
71 If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
72 MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
73 Store(1, MEMORY_SLOT_INSERT_EVENT)
75 // TODO: handle memory eject request
76 Add(Local0, One, Local0) // goto next DIMM
78 Release(MEMORY_SLOT_LOCK)
82 Method(MEMORY_SLOT_STATUS_METHOD, 1) {
85 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
86 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
88 If (LEqual(MEMORY_SLOT_ENABLED, One)) {
92 Release(MEMORY_SLOT_LOCK)
96 Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
97 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
98 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
100 Name(MR64, ResourceTemplate() {
101 QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
102 Cacheable, ReadWrite,
103 0x0000000000000000, // Address Space Granularity
104 0x0000000000000000, // Address Range Minimum
105 0xFFFFFFFFFFFFFFFE, // Address Range Maximum
106 0x0000000000000000, // Address Translation Offset
107 0xFFFFFFFFFFFFFFFF, // Address Length
108 ,, MW64, AddressRangeMemory, TypeStatic)
111 CreateDWordField(MR64, 14, MINL)
112 CreateDWordField(MR64, 18, MINH)
113 CreateDWordField(MR64, 38, LENL)
114 CreateDWordField(MR64, 42, LENH)
115 CreateDWordField(MR64, 22, MAXL)
116 CreateDWordField(MR64, 26, MAXH)
118 Store(MEMORY_SLOT_ADDR_HIGH, MINH)
119 Store(MEMORY_SLOT_ADDR_LOW, MINL)
120 Store(MEMORY_SLOT_SIZE_HIGH, LENH)
121 Store(MEMORY_SLOT_SIZE_LOW, LENL)
123 // 64-bit math: MAX = MIN + LEN - 1
124 Add(MINL, LENL, MAXL)
125 Add(MINH, LENH, MAXH)
126 If (LLess(MAXL, MINL)) {
129 If (LLess(MAXL, One)) {
130 Subtract(MAXH, One, MAXH)
132 Subtract(MAXL, One, MAXL)
134 If (LEqual(MAXH, Zero)){
135 Name(MR32, ResourceTemplate() {
136 DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
137 Cacheable, ReadWrite,
138 0x00000000, // Address Space Granularity
139 0x00000000, // Address Range Minimum
140 0xFFFFFFFE, // Address Range Maximum
141 0x00000000, // Address Translation Offset
142 0xFFFFFFFF, // Address Length
143 ,, MW32, AddressRangeMemory, TypeStatic)
145 CreateDWordField(MR32, MW32._MIN, MIN)
146 CreateDWordField(MR32, MW32._MAX, MAX)
147 CreateDWordField(MR32, MW32._LEN, LEN)
152 Release(MEMORY_SLOT_LOCK)
156 Release(MEMORY_SLOT_LOCK)
160 Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
161 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
162 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
163 Store(MEMORY_SLOT_PROXIMITY, Local0)
164 Release(MEMORY_SLOT_LOCK)
168 Method(MEMORY_SLOT_OST_METHOD, 4) {
169 Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
170 Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
171 Store(Arg1, MEMORY_SLOT_OST_EVENT)
172 Store(Arg2, MEMORY_SLOT_OST_STATUS)
173 Release(MEMORY_SLOT_LOCK)