2015年12月23日 星期三

Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME (with Chinese translation comment)


Subject Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME
From "H. Peter Anvin" <>
Date Fri, 20 Dec 2013 08:57:03 -0800

But we prefer the TAD for that.  The case where the EFI runtime is the only source of that info is problematic as they are known to not work at runtime.  We could collect it at boot and then never change it, although you end up in definitional issues between EFI and the hw RTC.

/* 但是那樣的狀況下我們比較喜歡 TAD. 在某種案例下 EFI runtime 是唯一的資訊來源但是它卻有問題, 因為我們已知它們在 runtime 無法運作. 我們可以在開機時收集它然後永遠不修改, 但是你最終會遭遇 EFI 和 hw RTC 間的定義上問題.  */

Matthew Garrett <matthew.garrett@nebula.com> wrote:
>On Thu, 2013-12-19 at 20:22 -0800, H. Peter Anvin wrote:
>> On 12/19/2013 08:05 PM, joeyli wrote:
>> > Can we use EFI time services on x86_64 after Borislav's patches
>accepted
>> > to mainline?
/* 當 Borislav 的 patches 被上游允許之後, 在x86_64是否我們可以使用 EFI time services? */
>> > 
>> 
>> No.
/* 不行. */
>
>We will want to use them to (at minimum) obtain the clock timezone.
>Using them for general RTC access is less attractive.

/* 我們想要(最低限度)使用他們以獲得時鐘時區. 用他們作為一般的RTC存取(功能)並沒有吸引力. */
-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.


From Matthew Garrett <>
Subject Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME
Date Fri, 20 Dec 2013 16:58:33 +0000

On Fri, 2013-12-20 at 08:57 -0800, H. Peter Anvin wrote:
> But we prefer the TAD for that.  The case where the EFI runtime is the only source of that info is problematic as they are known to not work at runtime.  We could collect it at boot and then never change it, although you end up in definitional issues between EFI and the hw RTC.

Most shipping UEFI hardware has no TAD.
/* 大部份出貨的 UEFI 硬體沒有 TAD */

-- 
Matthew Garrett <matthew.garrett@nebula.com>


Subject Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME
From "H. Peter Anvin" <>
Date Fri, 20 Dec 2013 12:29:51 -0800

Yes, but the TZ isn't all that critical, either.  It certainly doesn't matter at all for a pure Linux system.

/* 對, 但是 TZ 並不是那麼的關鍵. 在一個純 Linux 系統上它並不重要 */

Matthew Garrett <matthew.garrett@nebula.com> wrote:
>On Fri, 2013-12-20 at 08:57 -0800, H. Peter Anvin wrote:
>> But we prefer the TAD for that.  The case where the EFI runtime is
>the only source of that info is problematic as they are known to not
>work at runtime.  We could collect it at boot and then never change it,
>although you end up in definitional issues between EFI and the hw RTC.
>
>Most shipping UEFI hardware has no TAD.

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.


From Matthew Garrett <>
Subject Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME
Date Fri, 20 Dec 2013 20:32:12 +0000

On Fri, 2013-12-20 at 12:29 -0800, H. Peter Anvin wrote:
> Yes, but the TZ isn't all that critical, either.  It certainly doesn't matter at all for a pure Linux system.

No, but it does matter for a great number of deployed Linux systems.
Dealing with the timezone over DST changes has been a perpetual problem,
and if we can make that work then life will be significantly better.

/* 不, 但它對於一個已大量佈署的 Linux 系統很重要. 處理在時區上的DST變化是個永遠的課題, 如果我們可以讓它運作, 那麼生活會更加美好 */
-- 
Matthew Garrett <matthew.garrett@nebula.com>

Date Fri, 20 Dec 2013 13:14:25 -0800
From "H. Peter Anvin" <>
Subject Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME

On 12/20/2013 12:32 PM, Matthew Garrett wrote:
> On Fri, 2013-12-20 at 12:29 -0800, H. Peter Anvin wrote:
>> Yes, but the TZ isn't all that critical, either.  It certainly doesn't matter at all for a pure Linux system.
> 
> No, but it does matter for a great number of deployed Linux systems.
> Dealing with the timezone over DST changes has been a perpetual problem,
> and if we can make that work then life will be significantly better.
> 

And as I pointed out, it can matter a lot for VMs, since the provider
doesn't want to provision the VMs differently for different types of guests.

/* 就像我指出的, 它對虛擬機更重要, 因為供應商不希望對於不同型態的 guest 提供有差別的虛擬機 */

 -hpa


Date Fri, 20 Dec 2013 13:12:52 -0800
From "H. Peter Anvin" <>
Subject Re: [RFC PATCH 00/14] Support timezone of ACPI TAD and EFI TIME

On 12/20/2013 07:16 AM, Matthew Garrett wrote:
> On Thu, 2013-12-19 at 20:22 -0800, H. Peter Anvin wrote:
>> On 12/19/2013 08:05 PM, joeyli wrote:
>>> Can we use EFI time services on x86_64 after Borislav's patches accepted
>>> to mainline?
>>>
>>
>> No.
> 
> We will want to use them to (at minimum) obtain the clock timezone.
> Using them for general RTC access is less attractive.
> 

One option is to use the EFI runtime call to get and save the clock
timezone before we call ExitBootServices() in the EFI stub.  This
doesn't obviate the need for proper handling of the TAD, though,
especially since it is likely that future hardware will not have a RTC
in the current form (it is a way more complex device than is needed,
which wouldn't normally be a problem, but the fact that it has to
operate in the Vbat well makes it a major one.)

/* 有個選項是我們可以在 EFI stub 內, 調用 ExitBootServices() 之前, 使用 EFI runtime call 取得和儲存時鐘時區. 雖然這樣仍無法避免需妥善處理 TAD, 特別是因為未來的硬體很可能沒有現在這種形式的 RTC (它是一種比需求更複雜的設備, 這通常不會是個問題, 但事實上, 它必須具備在Vbat(電池)下運作良好的重大特性) */

 -hpa

2015年12月22日 星期二

Check the EFI time servies usage status of Windows 10 on qemu

In Hackweek 13, I checked the newest Windows version, Windows 10, that it uses EFI time services to restore timezone information to UEFI firmware.

My original target is checking the ACPI Time and Alarm usage status in Windows 10, but I didn't find checked build of Windows 10. So I check the EFI time services usage status.

Install Windows 10 with OVMF as a Qemu guest

First I need install a Windows 10 guest in qemu. I downloaded the Windows 10 evaluation edition from TechNet Evaluation Center:

10586.0.151029-1700.TH2_RELEASE_CLIENTENTERPRISEEVAL_OEMRET_X64FRE_EN-US.ISO

My host environment is openSUSE 13.2:

qemu-x86-2.1.3-7.2.x86_64
qemu-2.1.3-7.2.x86_64
qemu-kvm-2.1.3-7.2.x86_64
qemu-seabios-1.7.5-2.9.noarch
qemu-tools-2.1.3-7.2.x86_64
qemu-sgabios-8-2.9.noarch
qemu-ksm-2.1.0-2.9.x86_64
qemu-ovmf-x86_64-0.1+svn19110-11.1.noarch
qemu-vgabios-1.7.5-2.9.noarch

virt-install-1.3.0-329.4.noarch
libvirt-daemon-1.2.9-23.1.x86_64
libvirt-daemon-driver-qemu-1.2.9-23.1.x86_64
virt-manager-common-1.3.0-329.4.noarch
virt-manager-1.3.0-329.4.noarch
libvirt-daemon-qemu-1.2.9-23.1.x86_64
libvirt-client-1.2.9-23.1.x86_64

At beginning I run virt-install to install Windows 10 on qemu. Unfortunately it didn't success because the ovmf on openSUSE that it doesn't include Microsoft's key for Windows platform. So I need disable secure boot before install Windows 10. To keep the secure boot BIOS option, I setup nvram parameter in /etc/libvirt/qemu.conf before running virt-manager to install Windows 10:

vi /etc/libvirt/qemu.conf
...
nvram = [ "/usr/share/qemu/ovmf-x86_64-ms-code.bin:/usr/share/qemu/ovmf-x86_64-ms-vars.bin" ]

Then running a QEMU/KVM guest, I disabled secure boot in UEFI option. The change should save to nvram file:

# virsh dumpxml win8.1
...
  <os>
    <type arch='x86_64' machine='pc-i440fx-2.1'>hvm</type>
    <loader readonly='yes' type='pflash'>/usr/share/qemu/ovmf-x86_64-ms-code.bin</loader>
    <nvram>/var/lib/libvirt/qemu/nvram/win8.1_VARS.fd</nvram>
    <boot dev='hd'/>
  </os>

Please ignore the wrong guest name win8.1 :p

Another problem when I am installing Windows 10 is that it always sticks on Windows start up screen but didn't run installation process. After upgrade ovmf to qemu-ovmf-x86_64-0.1+svn19110-11.1.noarch, this issue gone.

When using virt-manager to install Windows 10, need choice UEFI to be the BIOS for installation:

Choice "Customize configuration before install":

Choice Firmware:

Remember to disable secure boot before running Windows 10 installation first.

Windows 10 installation and boot success on qemu:


Enable serial console log of OVMF

Thanks for Gary Lin's help. He told me the way to enable serial console log of ovmf is adding the following qemu parameters:
    -global isa-debugcon.iobase=0x402 -debugcon file:debug.log

Add the above parameters to print ovmf's debug log to debug.log file. I am using libvirt, so need add those parameters to the XML of domain. So, using virsh to edit xml:

# virsh edit win8.1

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
[...snip]
  <qemu:commandline>
    <qemu:arg value='-global'/>
    <qemu:arg value='isa-debugcon.iobase=0x402'/>
    <qemu:arg value='-debugcon'/>
    <qemu:arg value='file:/tmp/debug.log'/>
    <qemu:arg value='-s'/>
  </qemu:commandline>
</domain>

As the above, please add xml name space of qemu in domain element, then add "qemu:commandline" element in the end of domain. Please note you need have the access right of the folder of debug.log file.

You can tail /tmp/debug.log after starting Windows 10 guest:

# tail -f /tmp/debug.log
SecCoreStartupWithStack(0xFFFCC000, 0x818000)
Register PPI Notify: DCD0BE23-9586-40F4-B643-06522CED4EDE
Install PPI: 8C8CE578-8A3D-4F1C-9935-896185C32DD3
Install PPI: 5473C07A-3DCB-4DCA-BD6F-1E9689E7349A
The 0th FV start address is 0x00000820000, size is 0x000E0000, handle is 0x820000
Register PPI Notify: 49EDB1C1-BF21-4761-BB12-EB0031AABB39
Register PPI Notify: EA7CA24B-DED5-4DAD-A389-BF827E8F9B38
Install PPI: B9E0ABFE-5979-4914-977F-6DEE78C278A6
[...snip]

PcAtChipsetPkg/KbcResetDxe/ResetEntry.c:  SystemTable->RuntimeServices->ResetSystem = KbcResetSystem;

Add debug log to getTime()/setTime() in OVMF 

Here is my patch to EDK2 to add debug log in OVMF for detecting the usage status by OS:
    https://github.com/joeyli/edk2/commit/bf1dc51b2f2b9b9a765fdbaadc740b4806265fbb

There have some different code paths in EDK2 that implemented get time and set time functions. I added some debug log in different code path and got Gary Lin's help to find the right runtime services functions that are used by OVMF. The point is finding out some codes to define function points in "SystemTable->RuntimeServices" table:

PcAtChipsetPkg/KbcResetDxe/ResetEntry.c:  SystemTable->RuntimeServices->ResetSystem = KbcResetSystem;

MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.c:  gRT = SystemTable->RuntimeServices;
PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c:
                                                          gRT->GetTime       = PcRtcEfiGetTime;
                                                          gRT->SetTime       = PcRtcEfiSetTime;
                                                          gRT->GetWakeupTime = PcRtcEfiGetWakeupTime;
                                                          gRT->SetWakeupTime = PcRtcEfiSetWakeupTime;

And should make sure those packages used by OvmfPkg package.
e.g.
ovmf-0.1+svn19289/OvmfPkg> grep -r "UefiRuntimeServicesTableLib" *
[...snip]
OvmfPkgX64.dsc:  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf

The OVMF debug log of booting Windows 10

Here is the ovmf debug log result file of booting Windows 10:
    https://github.com/joeyli/hackweek/blob/master/windows10-uefi-time-services/windows10-qemu-ovmf-debug.log

For the the first line to 2908 line is the log of ovmf booting stage. I go to the UEFI menu and wait all log written to file, then select Windows 10 booting item in UEFI boot manager. I add "[[Windows 10 boot START]]" tag in windows10-qemu-ovmf-debug.log as a mark to start Winddows 10 booting.

In the log file, I saw many "PcRtcEfiGetTime" but I didn't see any "PcRtcEfiSetTime" log in Windows 10 booting process. After booting to Windows 10 desktop I tried to set time by "Settings -> Time & language -> Date & time" functions. But I didn't see any ovmf log from Windows 10 call runtime services. Actually, I didn't see any runtime services log after Windows 10 boot finished, even "VariableServiceGetVariable" or "VariableServiceSetVariable".

Windows 10 doesn't aware timezone change by UEFI shell

Base on ovmf debug log, looks Windows 10 doesn't use EFI time services to set date/time and timezone to EFI firmware. Then I boot to EFI shell to change timezone. The original timezone field is Local (2047):

    Shell> timezone
    Local

I set it to GMT+05:00

    Shell> timezone -s 5:00
    Shell> timezone
    GMT+05:00

Then reboot to Windows 10, I didn't see the timzone field in "Settings -> Time & language -> Date & time" changed to sync with the timezone that's set by EFI shell. So Windows 10 doesn't aware timezone field from EFI time services even it calls getTime() time services. Looks it just ignore it and keeps timezone by itself.

Summary

The timezone and daylight fields in EFI time services are useful to a OS dual boot environment to sync the date/time status in different OS. Windows is the most popular OS but looks it doesn't use timezone field that it is provided by EFI time services. That causes that doesn't have enough benefits to support this functions. At least it doesn't help on dual boot environment.

The good news is that Windows 10 accesses getTime() runtime service in booting process, that meas at least this function will be tested in all OEM/ODM QA process.