Message ID | 1342002726-18258-4-git-send-email-vasilis.liaskovitis@profitbricks.com |
---|---|
State | New |
Headers | show |
At 07/11/2012 06:31 PM, Vasilis Liaskovitis Wrote: > Extend the DSDT to include methods for handling memory hot-add and hot-remove > notifications and memory device status requests. These functions are called > from the memory device SSDT methods. > > Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> > --- > src/acpi-dsdt.dsl | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 68 insertions(+), 2 deletions(-) > > diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl > index 2060686..5d3e92b 100644 > --- a/src/acpi-dsdt.dsl > +++ b/src/acpi-dsdt.dsl > @@ -737,6 +737,71 @@ DefinitionBlock ( > } > Return(One) > } > + /* Objects filled in by run-time generated SSDT */ > + External(MTFY, MethodObj) > + External(MEON, PkgObj) > + > + Method (CMST, 1, NotSerialized) { > + // _STA method - return ON status of memdevice > + // Local0 = MEON flag for this cpu > + Store(DerefOf(Index(MEON, Arg0)), Local0) > + If (Local0) { Return(0xF) } Else { Return(0x0) } > + } > + > + /* Memory hotplug notify array */ > + OperationRegion(MEST, SystemIO, 0xaf80, 32) > + Field (MEST, ByteAcc, NoLock, Preserve) > + { > + MES, 256 > + } > + > + /* Memory eject byte */ > + OperationRegion(MEMJ, SystemIO, 0xafa0, 1) > + Field (MEMJ, ByteAcc, NoLock, Preserve) > + { > + MPE, 8 > + } > + > + Method(MESC, 0) { > + // Local5 = active memdevice bitmap > + Store (MES, Local5) > + // Local2 = last read byte from bitmap > + Store (Zero, Local2) > + // Local0 = memory device iterator > + Store (Zero, Local0) > + While (LLess(Local0, SizeOf(MEON))) { > + // Local1 = MEON flag for this memory device > + Store(DerefOf(Index(MEON, Local0)), Local1) > + If (And(Local0, 0x07)) { > + // Shift down previously read bitmap byte > + ShiftRight(Local2, 1, Local2) > + } Else { > + // Read next byte from memdevice bitmap > + Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2) > + } > + // Local3 = active state for this memory device > + Store(And(Local2, 1), Local3) > + > + If (LNotEqual(Local1, Local3)) { There are two ways to hot remove a memory device: 1. dimm_del 2. echo 1 >/sys/bus/acpi/devices/PNP0C80:XX/eject In the 2nd case, we cannot hotplug this memory device again, because both Local1 and Local3 are 1. So, I think MEON flag for this meory device should be set to 0 in method _EJ0 or implement method _PS3 for memory device. Thanks Wen Congyang > + // State change - update MEON with new state > + Store(Local3, Index(MEON, Local0)) > + // Do MEM notify > + If (LEqual(Local3, 1)) { > + MTFY(Local0, 1) > + } Else { > + MTFY(Local0, 3) > + } > + } > + Increment(Local0) > + } > + Return(One) > + } > + > + Method (MPEJ, 2, NotSerialized) { > + // _EJ0 method - eject callback > + Store(Arg0, MPE) > + Sleep(200) > + } > } > > > @@ -759,8 +824,9 @@ DefinitionBlock ( > // CPU hotplug event > Return(\_SB.PRSC()) > } > - Method(_L03) { > - Return(0x01) > + Method(_E03) { > + // Memory hotplug event > + Return(\_SB.MESC()) > } > Method(_L04) { > Return(0x01)
On Tue, Jul 17, 2012 at 03:23:00PM +0800, Wen Congyang wrote: > > + Method(MESC, 0) { > > + // Local5 = active memdevice bitmap > > + Store (MES, Local5) > > + // Local2 = last read byte from bitmap > > + Store (Zero, Local2) > > + // Local0 = memory device iterator > > + Store (Zero, Local0) > > + While (LLess(Local0, SizeOf(MEON))) { > > + // Local1 = MEON flag for this memory device > > + Store(DerefOf(Index(MEON, Local0)), Local1) > > + If (And(Local0, 0x07)) { > > + // Shift down previously read bitmap byte > > + ShiftRight(Local2, 1, Local2) > > + } Else { > > + // Read next byte from memdevice bitmap > > + Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2) > > + } > > + // Local3 = active state for this memory device > > + Store(And(Local2, 1), Local3) > > + > > + If (LNotEqual(Local1, Local3)) { > > There are two ways to hot remove a memory device: > 1. dimm_del > 2. echo 1 >/sys/bus/acpi/devices/PNP0C80:XX/eject > > In the 2nd case, we cannot hotplug this memory device again, > because both Local1 and Local3 are 1. > > So, I think MEON flag for this meory device should be set to 0 in method _EJ0 > or implement method _PS3 for memory device. good catch. Both internal seabios state (MEON) and the machine qemu bitmap (mems_sts in hw/acpi_piix4.c) have to be updated when the ejection comes from OSPM action. I will implement a _PS3 method that updates the MEON flag and also signals qemu to change the mems_sts bitmap. thanks, - Vasilis
diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl index 2060686..5d3e92b 100644 --- a/src/acpi-dsdt.dsl +++ b/src/acpi-dsdt.dsl @@ -737,6 +737,71 @@ DefinitionBlock ( } Return(One) } + /* Objects filled in by run-time generated SSDT */ + External(MTFY, MethodObj) + External(MEON, PkgObj) + + Method (CMST, 1, NotSerialized) { + // _STA method - return ON status of memdevice + // Local0 = MEON flag for this cpu + Store(DerefOf(Index(MEON, Arg0)), Local0) + If (Local0) { Return(0xF) } Else { Return(0x0) } + } + + /* Memory hotplug notify array */ + OperationRegion(MEST, SystemIO, 0xaf80, 32) + Field (MEST, ByteAcc, NoLock, Preserve) + { + MES, 256 + } + + /* Memory eject byte */ + OperationRegion(MEMJ, SystemIO, 0xafa0, 1) + Field (MEMJ, ByteAcc, NoLock, Preserve) + { + MPE, 8 + } + + Method(MESC, 0) { + // Local5 = active memdevice bitmap + Store (MES, Local5) + // Local2 = last read byte from bitmap + Store (Zero, Local2) + // Local0 = memory device iterator + Store (Zero, Local0) + While (LLess(Local0, SizeOf(MEON))) { + // Local1 = MEON flag for this memory device + Store(DerefOf(Index(MEON, Local0)), Local1) + If (And(Local0, 0x07)) { + // Shift down previously read bitmap byte + ShiftRight(Local2, 1, Local2) + } Else { + // Read next byte from memdevice bitmap + Store(DerefOf(Index(Local5, ShiftRight(Local0, 3))), Local2) + } + // Local3 = active state for this memory device + Store(And(Local2, 1), Local3) + + If (LNotEqual(Local1, Local3)) { + // State change - update MEON with new state + Store(Local3, Index(MEON, Local0)) + // Do MEM notify + If (LEqual(Local3, 1)) { + MTFY(Local0, 1) + } Else { + MTFY(Local0, 3) + } + } + Increment(Local0) + } + Return(One) + } + + Method (MPEJ, 2, NotSerialized) { + // _EJ0 method - eject callback + Store(Arg0, MPE) + Sleep(200) + } } @@ -759,8 +824,9 @@ DefinitionBlock ( // CPU hotplug event Return(\_SB.PRSC()) } - Method(_L03) { - Return(0x01) + Method(_E03) { + // Memory hotplug event + Return(\_SB.MESC()) } Method(_L04) { Return(0x01)
Extend the DSDT to include methods for handling memory hot-add and hot-remove notifications and memory device status requests. These functions are called from the memory device SSDT methods. Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> --- src/acpi-dsdt.dsl | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 68 insertions(+), 2 deletions(-)