Paolo Bonzini | 4f99ab7 | 2014-10-15 09:45:44 +0200 | [diff] [blame] | 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 */ |
Igor Mammedov | 2c6b94d | 2015-02-18 19:14:47 +0000 | [diff] [blame] | 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_SLECTOR, FieldUnitObj) // DIMM selector, write only |
| 33 | External(MEMORY_SLOT_OST_EVENT, FieldUnitObj) // _OST event code, write only |
| 34 | External(MEMORY_SLOT_OST_STATUS, FieldUnitObj) // _OST status code, write only |
Paolo Bonzini | 4f99ab7 | 2014-10-15 09:45:44 +0200 | [diff] [blame] | 35 | |
| 36 | Method(_STA, 0) { |
| 37 | If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { |
| 38 | Return(0x0) |
| 39 | } |
| 40 | /* present, functioning, decoding, not shown in UI */ |
| 41 | Return(0xB) |
| 42 | } |
| 43 | |
Paolo Bonzini | 4f99ab7 | 2014-10-15 09:45:44 +0200 | [diff] [blame] | 44 | Mutex (MEMORY_SLOT_LOCK, 0) |
Paolo Bonzini | 4f99ab7 | 2014-10-15 09:45:44 +0200 | [diff] [blame] | 45 | |
| 46 | Method(MEMORY_SLOT_SCAN_METHOD, 0) { |
| 47 | If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) { |
| 48 | Return(Zero) |
| 49 | } |
| 50 | |
| 51 | Store(Zero, Local0) // Mem devs iterrator |
| 52 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) |
| 53 | while (LLess(Local0, MEMORY_SLOTS_NUMBER)) { |
| 54 | Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM |
| 55 | If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check |
| 56 | MEMORY_SLOT_NOTIFY_METHOD(Local0, 1) |
| 57 | Store(1, MEMORY_SLOT_INSERT_EVENT) |
| 58 | } |
| 59 | // TODO: handle memory eject request |
| 60 | Add(Local0, One, Local0) // goto next DIMM |
| 61 | } |
| 62 | Release(MEMORY_SLOT_LOCK) |
| 63 | Return(One) |
| 64 | } |
| 65 | |
| 66 | Method(MEMORY_SLOT_STATUS_METHOD, 1) { |
| 67 | Store(Zero, Local0) |
| 68 | |
| 69 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) |
| 70 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM |
| 71 | |
| 72 | If (LEqual(MEMORY_SLOT_ENABLED, One)) { |
| 73 | Store(0xF, Local0) |
| 74 | } |
| 75 | |
| 76 | Release(MEMORY_SLOT_LOCK) |
| 77 | Return(Local0) |
| 78 | } |
| 79 | |
| 80 | Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) { |
| 81 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) |
| 82 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM |
| 83 | |
| 84 | Name(MR64, ResourceTemplate() { |
| 85 | QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, |
| 86 | Cacheable, ReadWrite, |
| 87 | 0x0000000000000000, // Address Space Granularity |
| 88 | 0x0000000000000000, // Address Range Minimum |
| 89 | 0xFFFFFFFFFFFFFFFE, // Address Range Maximum |
| 90 | 0x0000000000000000, // Address Translation Offset |
| 91 | 0xFFFFFFFFFFFFFFFF, // Address Length |
| 92 | ,, MW64, AddressRangeMemory, TypeStatic) |
| 93 | }) |
| 94 | |
| 95 | CreateDWordField(MR64, 14, MINL) |
| 96 | CreateDWordField(MR64, 18, MINH) |
| 97 | CreateDWordField(MR64, 38, LENL) |
| 98 | CreateDWordField(MR64, 42, LENH) |
| 99 | CreateDWordField(MR64, 22, MAXL) |
| 100 | CreateDWordField(MR64, 26, MAXH) |
| 101 | |
| 102 | Store(MEMORY_SLOT_ADDR_HIGH, MINH) |
| 103 | Store(MEMORY_SLOT_ADDR_LOW, MINL) |
| 104 | Store(MEMORY_SLOT_SIZE_HIGH, LENH) |
| 105 | Store(MEMORY_SLOT_SIZE_LOW, LENL) |
| 106 | |
| 107 | // 64-bit math: MAX = MIN + LEN - 1 |
| 108 | Add(MINL, LENL, MAXL) |
| 109 | Add(MINH, LENH, MAXH) |
| 110 | If (LLess(MAXL, MINL)) { |
| 111 | Add(MAXH, One, MAXH) |
| 112 | } |
| 113 | If (LLess(MAXL, One)) { |
| 114 | Subtract(MAXH, One, MAXH) |
| 115 | } |
| 116 | Subtract(MAXL, One, MAXL) |
| 117 | |
| 118 | If (LEqual(MAXH, Zero)){ |
| 119 | Name(MR32, ResourceTemplate() { |
| 120 | DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed, |
| 121 | Cacheable, ReadWrite, |
| 122 | 0x00000000, // Address Space Granularity |
| 123 | 0x00000000, // Address Range Minimum |
| 124 | 0xFFFFFFFE, // Address Range Maximum |
| 125 | 0x00000000, // Address Translation Offset |
| 126 | 0xFFFFFFFF, // Address Length |
| 127 | ,, MW32, AddressRangeMemory, TypeStatic) |
| 128 | }) |
| 129 | CreateDWordField(MR32, MW32._MIN, MIN) |
| 130 | CreateDWordField(MR32, MW32._MAX, MAX) |
| 131 | CreateDWordField(MR32, MW32._LEN, LEN) |
| 132 | Store(MINL, MIN) |
| 133 | Store(MAXL, MAX) |
| 134 | Store(LENL, LEN) |
| 135 | |
| 136 | Release(MEMORY_SLOT_LOCK) |
| 137 | Return(MR32) |
| 138 | } |
| 139 | |
| 140 | Release(MEMORY_SLOT_LOCK) |
| 141 | Return(MR64) |
| 142 | } |
| 143 | |
| 144 | Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) { |
| 145 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) |
| 146 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM |
| 147 | Store(MEMORY_SLOT_PROXIMITY, Local0) |
| 148 | Release(MEMORY_SLOT_LOCK) |
| 149 | Return(Local0) |
| 150 | } |
| 151 | |
| 152 | Method(MEMORY_SLOT_OST_METHOD, 4) { |
| 153 | Acquire(MEMORY_SLOT_LOCK, 0xFFFF) |
| 154 | Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM |
| 155 | Store(Arg1, MEMORY_SLOT_OST_EVENT) |
| 156 | Store(Arg2, MEMORY_SLOT_OST_STATUS) |
| 157 | Release(MEMORY_SLOT_LOCK) |
| 158 | } |
| 159 | } // Device() |
| 160 | } // Scope() |