Re: [Qemu-devel] [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger()
On 24/04/2015 13:56, Yao, Jiewen wrote: > BTW: I am not sure how QEMU emulate SMI. Does SMI can be trigger by > 0xB2 port? And CPU will run to SMBASE in real mode? Yes, operation is the same. Paolo
Re: [Qemu-devel] [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger()
Got it. Thanks! -Original Message- From: Paolo Bonzini [mailto:pbonz...@redhat.com] Sent: Friday, April 24, 2015 9:01 PM To: Yao, Jiewen; edk2-de...@lists.sourceforge.net; Gerd Hoffmann Cc: qemu-devel@nongnu.org; m...@redhat.com Subject: Re: [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger() On 24/04/2015 13:56, Yao, Jiewen wrote: > BTW: I am not sure how QEMU emulate SMI. Does SMI can be trigger by > 0xB2 port? And CPU will run to SMBASE in real mode? Yes, operation is the same. Paolo
Re: [Qemu-devel] [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger()
On 04/24/15 16:50, Yao, Jiewen wrote: > Hi Laszlo > > I think there is good resource for your reference - Intel Quark. > https://downloadcenter.intel.com/download/23197 > > You may download "Board_Support_Package_Sources_for_Intel_Quark_v1.1.0.7z", > and find "Quark_EDKII_v1.1.0" > > IA32FamilyCpuBasePkg\PiSmmCpuDxeSmm - it is CPUSMM driver. > IA32FamilyCpuBasePkg\PiSmmCommunication - it is CommunicationPeim. > > PiSmmCpuDxeSmm works for Quark, but I think it should be easy to port to QEMU > platform. > PiSmmCommunication should be generic, it might be able to put to UefiCpuPkg > later. Jiewen, thank you so much -- this is perfect. Exactly what I needed. It provides EFI_SMM_CONFIGURATION_PROTOCOL and SMM_S3_RESUME_STATE: -rw---. 1 13909 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/CpuS3.c -rw---. 1 16290 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/CpuService.c -rw---. 1 8100 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/CpuService.h -rw---. 1 7221 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S -rw---. 1 7072 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm -rw---. 1 3304 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c -rw---. 1 3013 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c -rw---. 1 5470 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S -rw---. 1 5574 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm -rw---. 1 38464 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmiException.S -rw---. 1 26268 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm -rw---. 1 4115 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S -rw---. 1 4331 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm -rw---. 1 2801 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c -rw---. 1 3553 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h -rw---. 1 54847 Apr 24 18:32 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/MpService.c -rwx--. 1 59571 Apr 24 18:34 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c -rw---. 1 25929 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h -rw---. 1 5318 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf -rw---. 1 8619 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/SmmFeatures.c -rw---. 1 5062 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/SmmFeatures.h -rw---. 1 40893 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/SmmProfile.c -rw---. 1 2290 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/SmmProfile.h -rw---. 1 5357 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/SmmProfileInternal.h -rw---. 1 3391 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCpuDxeSmm/SyncTimer.c (~360K) and even EFI_PEI_SMM_COMMUNICATION_PPI: -rw---. 1 15508 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCommunication/PiSmmCommunicationPei.c -rw---. 1 2706 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCommunication/PiSmmCommunicationPei.inf -rw---. 1 1981 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCommunication/PiSmmCommunicationPrivate.h -rw---. 1 13522 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCommunication/PiSmmCommunicationSmm.c -rw---. 1 3004 Feb 16 10:55 Quark_EDKII_v1.1.0/IA32FamilyCpuBasePkg/PiSmmCommunication/PiSmmCommunicationSmm.inf and "Quark_EDKII_v1.1.0/LICENSE" is the 3-clause BSDL. Awesome. Thanks! Laszlo
Re: [Qemu-devel] [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger() (was: [PATCH 6/6] [wip] tseg, part2, not (yet) tested)
Hi Laszlo Below is my thought. 2) You are right. According to IA32 manual - "Maskable hardware interrupts, exceptions, NMI interrupts, SMI interrupts, A20M interrupts, single-step traps, breakpoint traps, and INIT operations are inhibited when the processor enters SMM." You can also find more detail in "34.6 EXCEPTIONS AND INTERRUPTS WITHIN SMM" In below doc, the "SMM Timer is initialized" means the timer used by BSP to check if APs are all pulled into SMM for CPU Rendez-vous. A typical implementation is ACPI timer (PCH), or APIC timer (CPU). BSP just check timer count, but the timer does not generate any interrupt. 3) Yes. SmmCoreEntry is useful function as bridge between a real CPU_SMM driver and SMM_CORE. In real world, when SMI happen, CPU will jump to SM_BASE in real mode. Then it will jump to X64 mode immediately. The all CPUs will be in election phase. Only one will be elected as BSP. Just in case, some APIs are not in SMM yet, the BSP will send IPI to try pull those APs into SMM mode. (SMM timer is used at this moment). Above process is called CPU rendez-vous. Then BSP will do enter SMM_CORE entry point (registered by SmmCoreEntry), while APs are in loop state. After BSP returns from SMM_CORE, it will let APs leave loop state, and all CPUs run RSM instruction to return back. Hope that helps. BTW: I am not sure how QEMU emulate SMI. Does SMI can be trigger by 0xB2 port? And CPU will run to SMBASE in real mode? Thank you Yao Jiewen -Original Message- From: Laszlo Ersek [mailto:ler...@redhat.com] Sent: Wednesday, April 22, 2015 4:32 AM To: Paolo Bonzini; Gerd Hoffmann Cc: edk2-devel list; qemu-devel@nongnu.org; m...@redhat.com Subject: [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger() (was: [PATCH 6/6] [wip] tseg, part2, not (yet) tested) (b) This is actually the opposite argument. Since SMM is security sensitive, *and* UEFI is single-processor / single-threaded (well you can use multiple processors, you just can't run any UEFI code on anything but the BP), the timer interrupt should be blocked / masked *anyway* while in SMM, no? Otherwise edk2 could start running a plain timer event callback in the middle of an SMM handler. Which makes me think that this locking / interrupt masking must already be in place, and it's not the responsibility of the individual EFI_SMM_CONTROL2_PROTOCOL.Trigger() implementation. (PI 1.3 vol4 doesn't mention this responsibility in any case.) I've learned about the "EDK II SMM Call Topology" document from a piwg message: http://sourceforge.net/projects/edk2/files/General%20Documentation/EDK%20II%20SMM%20call%20topology.pdf/download It doesn't speak about masking the timer. Does SMI mask other interrupts "architecturally" perhaps? ... (3) Oh, this is sad. Well, I am sad. Turns out there's a third UEFI protocol that OVMF needs to implement: EFI_SMM_CONFIGURATION_PROTOCOL. Its only interesting member is RegisterSmmEntry(), and that function is supposed to bind the central entry point (which is already available in the edk2 tree) to the processor-level SMI handler. (I'm kind of confused, because last time I experimented with faking SMRAM / SMM in OVMF, my fake Trigger() function just returned success, and there was no EFI_SMM_CONFIGURATION_PROTOCOL at all, and things seemed to work. In retrospect I can't imagine how control was transferred at all, without actual SMM / SMI support in both QEMU and OVMF. Hm... looking at occurrences of "SmmEntryPointRegistered", this may have been intentional in edk2.) EFI_SMM_CONFIGURATION_PROTOCOL discussed in the "EDK II SMM Call Topology" document, on the "SmmDriverDispatcher" and especially the "SMBASE Relocation" pages. It takes a separate CPU driver, and (obviously) assembly code. The "SMBASE Relocation" page references "IA32FamilyCpuPkg", which is not open source. Nothing in edk2 produces gEfiSmmConfigurationProtocol, and no source file contains the RSM instruction. The Vlv2TbltDevicePkg package (ValleyView2 Tablet?) makes several references to IA32FamilyCpuPkg, but those are only references. I guess IA32FamilyCpuPkg is exactly the kind of chipset code that Intel has not opened up. Our "SMM in OVMF" effort just got set back by months. :( Laszlo -- BPM Camp - Free Virtual Workshop May 6th at 10am PDT/1PM EDT Develop your own process in accordance with the BPMN 2 standard Learn Process modeling best practices with Bonita BPM through live exercises http://www.bonitasoft.com/be-part-of-it/events/bpm-camp-virtual- event?utm_ source=Sourceforge_BPM_Camp_5_6_15&utm_medium=email&utm_campaign=VA_SF ___ edk2-devel mailing list edk2-de...@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel
Re: [Qemu-devel] [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger() (was: [PATCH 6/6] [wip] tseg, part2, not (yet) tested)
Hi Laszlo I think there is good resource for your reference - Intel Quark. https://downloadcenter.intel.com/download/23197 You may download "Board_Support_Package_Sources_for_Intel_Quark_v1.1.0.7z", and find "Quark_EDKII_v1.1.0" IA32FamilyCpuBasePkg\PiSmmCpuDxeSmm - it is CPUSMM driver. IA32FamilyCpuBasePkg\PiSmmCommunication - it is CommunicationPeim. PiSmmCpuDxeSmm works for Quark, but I think it should be easy to port to QEMU platform. PiSmmCommunication should be generic, it might be able to put to UefiCpuPkg later. Thank you Yao Jiewen -Original Message- From: Yao, Jiewen [mailto:jiewen@intel.com] Sent: Friday, April 24, 2015 7:56 PM To: edk2-de...@lists.sourceforge.net; Paolo Bonzini; Gerd Hoffmann Cc: qemu-devel@nongnu.org; m...@redhat.com Subject: Re: [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger() (was: [PATCH 6/6] [wip] tseg, part2, not (yet) tested) Hi Laszlo Below is my thought. 2) You are right. According to IA32 manual - "Maskable hardware interrupts, exceptions, NMI interrupts, SMI interrupts, A20M interrupts, single-step traps, breakpoint traps, and INIT operations are inhibited when the processor enters SMM." You can also find more detail in "34.6 EXCEPTIONS AND INTERRUPTS WITHIN SMM" In below doc, the "SMM Timer is initialized" means the timer used by BSP to check if APs are all pulled into SMM for CPU Rendez-vous. A typical implementation is ACPI timer (PCH), or APIC timer (CPU). BSP just check timer count, but the timer does not generate any interrupt. 3) Yes. SmmCoreEntry is useful function as bridge between a real CPU_SMM driver and SMM_CORE. In real world, when SMI happen, CPU will jump to SM_BASE in real mode. Then it will jump to X64 mode immediately. The all CPUs will be in election phase. Only one will be elected as BSP. Just in case, some APIs are not in SMM yet, the BSP will send IPI to try pull those APs into SMM mode. (SMM timer is used at this moment). Above process is called CPU rendez-vous. Then BSP will do enter SMM_CORE entry point (registered by SmmCoreEntry), while APs are in loop state. After BSP returns from SMM_CORE, it will let APs leave loop state, and all CPUs run RSM instruction to return back. Hope that helps. BTW: I am not sure how QEMU emulate SMI. Does SMI can be trigger by 0xB2 port? And CPU will run to SMBASE in real mode? Thank you Yao Jiewen -Original Message- From: Laszlo Ersek [mailto:ler...@redhat.com] Sent: Wednesday, April 22, 2015 4:32 AM To: Paolo Bonzini; Gerd Hoffmann Cc: edk2-devel list; qemu-devel@nongnu.org; m...@redhat.com Subject: [edk2] implementing EFI_SMM_CONTROL2_PROTOCOL.Trigger() (was: [PATCH 6/6] [wip] tseg, part2, not (yet) tested) (b) This is actually the opposite argument. Since SMM is security sensitive, *and* UEFI is single-processor / single-threaded (well you can use multiple processors, you just can't run any UEFI code on anything but the BP), the timer interrupt should be blocked / masked *anyway* while in SMM, no? Otherwise edk2 could start running a plain timer event callback in the middle of an SMM handler. Which makes me think that this locking / interrupt masking must already be in place, and it's not the responsibility of the individual EFI_SMM_CONTROL2_PROTOCOL.Trigger() implementation. (PI 1.3 vol4 doesn't mention this responsibility in any case.) I've learned about the "EDK II SMM Call Topology" document from a piwg message: http://sourceforge.net/projects/edk2/files/General%20Documentation/EDK%20II%20SMM%20call%20topology.pdf/download It doesn't speak about masking the timer. Does SMI mask other interrupts "architecturally" perhaps? ... (3) Oh, this is sad. Well, I am sad. Turns out there's a third UEFI protocol that OVMF needs to implement: EFI_SMM_CONFIGURATION_PROTOCOL. Its only interesting member is RegisterSmmEntry(), and that function is supposed to bind the central entry point (which is already available in the edk2 tree) to the processor-level SMI handler. (I'm kind of confused, because last time I experimented with faking SMRAM / SMM in OVMF, my fake Trigger() function just returned success, and there was no EFI_SMM_CONFIGURATION_PROTOCOL at all, and things seemed to work. In retrospect I can't imagine how control was transferred at all, without actual SMM / SMI support in both QEMU and OVMF. Hm... looking at occurrences of "SmmEntryPointRegistered", this may have been intentional in edk2.) EFI_SMM_CONFIGURATION_PROTOCOL discussed in the "EDK II SMM Call Topology" document, on the "SmmDriverDispatcher" and especially the "SMBASE Relocation" pages. It takes a separate CPU driver, and (obviously) assembly code. The "SMBASE Relocation" page references "IA32FamilyCpuPkg", which is not open source. Nothing in edk2 produces gEfiSmmConfigurationProtocol, and no source file contains the RSM instruction. The Vlv2TbltDevicePkg package (ValleyView2 Tablet?) makes several references to IA32FamilyCpuPkg, but those are on