I was told to report the ASSERT error here because «even if it’s user error, it should properly prompt an error or halt».
I mostly assume i’ve done something wrong but wont hurt to post this.
Specs
CPU: Xeon E5606
RAM: 8GB
opencore-2021-02-06-123800.txt
EFI.zip
Hi. Yeah, this clearly looks like a bug on our end (some memory is tried to be freed that is not allocated). It should not crash like this. However, it is not possible to determine the location with just this log, so your help is needed, most likely involving running some test builds to produce more logs to determine the problem.
If you are up to this, could you tell me a bit more about what you are trying to do:
- This looks like a VMware-like hypervisor trying to boot a dmg recovery, is it right? Could you tell me about the versions for both?
- How much memory is the VM assigned? Does increasing RAM help?
- Could you try to load the DMG recovery for macOS 10.15 or macOS 11 and provide me the log?
Thanks for getting back to me. I am happy to do anything to see what we can do.
Yes, I am running an extremely unsupported environment here but just trying to see how far I can actually get. Mentally prepare yourself…
I am running Hyper-V on Windows. The Host has 44GB of RAM and 8GB of that is statically assigned to the VM. Increase/decreasing memory doesn’t help unfortunately. However setting the memory before about 4500MB results in a verbosed error. OCB LoadImage failed - Unsupported
This is further than it previously got. I can try with 10.15 and 11 a bit later this evening or tomorrow. I have attached a log of booting the VM with 4096MB of RAM which seems to help a bit.
opencore-2021-02-06-185610.txt
Yeah, there is no point in reducing the memory size, it dies earlier actually with an out of memory report. Provide a log with 11 dmg, and I will see what more prints I need to add to figure this out.
Okay, here is a build with more logging added. Please replace your OpenCore.efi and redo the log with 11. Please make sure that AppleDebug = YES is set. I will not promise this one will be enough to locate the bug, but I added relevant prints. Please let me know how it goes.
OpenCore-LT-r1.zip
I found and fixed one bug with this code. However, I am quite unsure whether this is the one you observe. Yours might be a bug in the firmware itself. In addition to fixing the issue I also added even more logging.
OpenCore-LT-r3.zip
It really makes no sense. We allocate and what we allocated is freed by us soon after. Yet the firmware reports it is an anvalid tree. I kind of get it that there may be some memory corruption, but to me it sounds like a memory corruption outside of OpenCore.
Hm, I’ll do a memtest to check. That might explain why lowering the ram doesn’t crash opencore
Not sure it is a hardware issue actually. Lowering the RAM makes OpenCore stop earlier due to not enough memory. Here I would say a bug would be in the firmware code rather than hardware. Maybe try to understand what exactly breaks it at least. Try this version. It will likely error differently. include the log.
OpenCore-LT-r4.zip
So, EFI_BOOT_SERVICES::GetMemoryMap on your side somehow corrupts the allocated memory. Now the question is what can we do to it…
Np… But I am out of ideas for the time being. We simply call the firmware, and it overwrites random data out of bounds @_@. I will provide some build to try to diagnose it in a better way later, but there hardly is a way to deal with such an obvious firmware bug.
I’m no expert with any sort of UEFI booting. I have done some googling of «GetMemoryMap and Hyper-V» and some bug reports of different Linux having to do some patches. Not sure if any of that could help?
Hopefully you’ll figure something out xD
I have same error with Debug version on my Haier Y11C laptop, here is the log
opencore-2021-02-07-214439.txt
Actually, I get black screen (with boot chime being played in a loop) when I enable OpenCanopy with PickerMode : External
property. I have unlocked BIOS, so if I enable CSM. OpenCore menu is shown but it’s really slow and laggy. Enabling CSM isn’t right solution anyway.
With OC v0.6.5 I fixed by setting Resolution : 1366x768
(max resolution of internal display), and it worked well even with CSM disabled. updated to OC v0.6.6, issue is back now and even Resolution property have no effect now. that’s the reason I went for Debug version to check logs and ended up with this ASSERT_EFI_ERROR
I understand that I should create separate issue for Black-Screen, just trying to state whole problem and actually I didn’t get positive response from my last reply Keypad. on Lenovo Y530 doesn’t work #303.
I didn’t get this ASSERT_EFI_ERROR once, so here is the log if you need it. with Resolution : Max
opencore-2021-02-07-215002.txt
Just a random update. Installed Hyper-V on my Windows 10 PC and I actually get much further. It starts calling the Kernel. See log attached. The biggest different (aside from the hardware) is this is Hyper-V config version 9 where as the other machine has 8.
Hmm, in this case I would rather leave this unchanged on our side. Basically «a fix» would be some hack workarounding a firmware bug. We do add such hacks, but mainly for real firmwares. If the firmware is software only and the bug is fixed in a newer release, it is better to leave it unmodified on our side.
At this step it is clear that older Hyper-V within the call to VmAllocateMemoryPool inside OcGetCurrentMemoryMapAlloc corrupts the pool allocated memory as soon as GetMemoryMap is called, making this memory no longer available for free. You can probably workaround it by changing FreePool here to gBS->FreePool, simply ignoring the memory corruption, but I do not want to merge it.
@chilledHamza your PS2 issue was forgotten about. Sorry. Replied.
As for ASSERT, it is not in the log, so we need a photo. Create a separate issue for it.
Содержание
- Русские Блоги
- UEFI реализует несколько последовательных портов одновременно и вывода
- Внедрение платформы с длинным клетками
- Как UEFI поддерживает многосериальные устройства
- (1) Последовательный порт, используемый на стадии сборки
- (2) Печать последовательного порта, используемая на стадии C
- UEFI issues with KANOTIX ISO images on older systems #187
- Comments
- ASSERT_EFI_ERROR (Status = Invalid Parameter) #1476
- Comments
- Footer
Русские Блоги
UEFI реализует несколько последовательных портов одновременно и вывода
Внедрение платформы с длинным клетками
Недавно, в сочетании с BMC для отладки функции SOL, вам необходимо вывести журнал BIOS на устройство UART BMC, а затем необходимо удаленно вывести соответствующие последовательные данные на веб -страницу на BMC, то есть функция удаленного управления биос. Конечно, этот последовательный порт должен одновременно поддерживать операции ввода и вывода. Потому что на платформе Dragon Core, последовательный порт, используемый последовательным портом отладки по умолчанию, находится внутри процессора. Когда ЦП инициализирует базовую конфигурацию, вернитесь, чтобы инициализировать этот последовательный порт в качестве тестового последовательного порта. Конечно, каждый озабоченный человек знает, как неудобно отладить программу, если нет отладочного последовательного порта. В связи с спросом, последовательный порт ЦП и последовательный порт ЦП необходимы для поддержки операции ввода и вывода.
Как UEFI поддерживает многосериальные устройства
(1) Последовательный порт, используемый на стадии сборки
Последовательный порт ЦП инициализируется в файле start.s UEFI, и его можно использовать, и его можно использовать на стадии сборки. Режим, используемый здесь, заключается в том, что общий принцип состоит в том, чтобы потерять данные в реестре последовательного порта, поэтому данные будут выброшены. Конкретный код инициализации выглядит следующим образом:
После инициализации серийный порт в основном доступен. Так что, если вы хотите распечатать строку в это время или несколько чисел, как ее использовать? Следующий код:
Приведенный выше код подробно представляет PrintStr («Выключите подчиненные ядер r n»). Он распечатана. Посмотрите на код, чтобы увидеть.
Это раздел строки. Если вы хотите распечатать кусок данных, вы можете напрямую вызвать функцию Hexserial. Вам нужно распечатать данные в регистр A0. A0 — это регистр, который сначала передает платформу MIPS.
(2) Печать последовательного порта, используемая на стадии C
В тот момент, когда UEFI вошел в среду C, инициализация последовательного порта была быстро названа. Здесь вызов относительно расплывчат, и он не будет найден на некоторое время. Вызов функции вызова выглядит следующим образом:
Функция ProceslibraryConstructorList здесь вызывает функцию инициализации последовательного порта. Эта функция реализована в LIB серийного порта. Он содержит Defuglib в secmain.inf. Путь отладки объявляется в файле DSC.
Давайте посмотрим на подробный процесс вызова ProcessLibraryConstructorList:
Приведенный выше код реализован в Secmain/Debug/Autogen.c, который представляет собой автоматический код компиляции. SerialPortinitialize — это функция инициализации библиотеки хранения. Библиотека на нашей платформе реализует инициализацию CPU UART0. В настоящее время нам нужно инициализировать последовательный порт BMC, поэтому нам нужно реализовать только библиотеку для инициализации UART BMC. Но потому что BMC UART ссылается на автобус LPC Bridge. И если мы хотим получить доступ к этому устройству, нам нужно подождать, пока устройство LPC получит его, чтобы инициализировать его, поэтому его нельзя инициализировать на стадии SEC для инициализации последовательного порта BMC. Мы находимся на стадии DXE, потому что после того, как мост инициализируется на стадии PEI, пространство IO LPC может быть доступно. Давайте посмотрим, как стадия DXE инициализирует последовательный порт BMC и как зарегистрироваться в консоли.
Мы осознали драйвер отдельно. Оригинальный драйвер и оригинальный драйвер последовательного порта очень похожи на адрес серийного адреса и некоторую инициализацию контроллера SUPIO, поскольку этот UART является контроллером SUPIO через шину LPC. Итак, сначала инициализируйте контроллер Supio. Подробный код заключается в следующем:
Из приведенного выше кода видно, что функция консоли, поддерживающей несколько последовательных устройств, в основном реализуется следующим кодом. Протокол в UEFI может поддерживать регистрацию нескольких интерфейсов. Резерсие и другие функции зарегистрированы через MSerialOtemplate. Точно так же тот же интерфейс зарегистрирован на последовательном приводе CPU UART, но конкретная операция — это разные устройства.
Так как же это устройство UART зарегистрировано в консоли? Эта регистрация зарегистрирована в драйвере терминала. Подробный код заключается в следующем:
Вот открытый gefiserialioprotocolguid. В настоящее время он получает интерфейс. В настоящее время получены два адреса, что соответствует адресу глобальной переменной, зарегистрированной в предыдущей регистрации.
Позднее интерфейс был предоставлен TerminalDevice-> Serialio, так что серийное устройство устанавливает связь с тройным устройством.
Устройство терминала зарегистрировано в задней части, которая включает в себя устройства ввода и выходные устройства. Кодовое шоу, как ниже:
Таким образом, консоль поддерживает вход и вывод нескольких последовательных портов.
Давайте посмотрим на инициализацию BMC UART. Вам нужно обратить внимание на некоторые моменты здесь:
(1) Логика работы контроллера Supio, каждое устройство Supio имеет концепцию логического устройства. Вам нужно читать и писать регистры в соответствии с логикой, соответствующей протоколу.
(2) В то же время количество прерывания устройства Supio под LPC составляет 3, а некоторые — 4, а все архитектуры одинаковы. Наше устройство 4, чип по умолчанию.
(3) Характеристики триггера прерываний, некоторые чипсы по умолчанию имеют высокие триггеры, некоторые из них низкие, некоторые из них поднимаются, некоторые из которых являются нисходящими краями. требует внимания.
(4) Необходимо настроить часы контроллера SUPIO. Он должен быть известен без настройки часов по умолчанию, поскольку расчет скорости гонка UART требует часов.
Ниже приведен подробный код инициализации:
Вся функция журнала печати UEFI выводится через функцию DebugPrint, за исключением фазы компиляции, тогда здесь вызывает функцию SolSerialPortWrite, и UART BMC также выведет ту же информацию об этом UART. Мы сделали переключатель здесь, чтобы управлять выходом журнала BMC.
Вход — это вход, полученный консолью. Конец консоли будет вызывать функцию ввода, соответствующую последовательному порту. Процесс кода очень сложный, включая множество протоколов. Я следил за этим раньше, вот подробное введение по временным причинам.
Источник
UEFI issues with KANOTIX ISO images on older systems #187
After enabling «vtdebug on» in grub.cfg I found an error with my boards for Sandy Bridge, Ivy Bridge and Haswell CPUs. My boards for Skylake and newer can boot fine.
FSBindingSupported
FSBindingStart
Could not read block at address 00000040: [2]
error: not a ISO9660 filesystem.
The text was updated successfully, but these errors were encountered:
Can you try ventoy-1.0.13?
The error is now different. Currently it is not possible to boot KANOTIX at all — even with a newer system using EFI.
ASSERT_EFI_ERROR (Status = Invalid Parameter)
ASSERT [Ventoy] . MemoryAllocationLib.c(813): !EFI_ERROR (Status)
No bootfile found for UEFI!
Maybe the image does not support X64 UEFI!
KANOTIX uses a hybrid ISO layout, it definitely has X64 UEFI in ISO9660 and FAT12 (usually 1MiB offset). (The 32 bit images have got the 32 bit UEFI). The «live» folder is similar to Debian live.
Ventoy up to 1.0.12 used the /dev/mapper/ventoy approach to boot.
Btw. compared to other images KANOTIX has even an Apple Partition Map with appended HFS+ partition (with USB-Stick ImageWriter for Mac). Unpatched parted tools usually crash. Created by
ISO=kanotix64-silverfire-nightly-KDE-extra.iso
blkid —probe —offset=$(($(stat -c %s $ISO)-1048576)) $ISO
Maybe the hack in line 148 of isohybrid-acritox is problematic for Ventoy.
Источник
ASSERT_EFI_ERROR (Status = Invalid Parameter) #1476
I was told to report the ASSERT error here because «even if it’s user error, it should properly prompt an error or halt».
I mostly assume i’ve done something wrong but wont hurt to post this.
Specs
CPU: Xeon E5606
RAM: 8GB
The text was updated successfully, but these errors were encountered:
Hi. Yeah, this clearly looks like a bug on our end (some memory is tried to be freed that is not allocated). It should not crash like this. However, it is not possible to determine the location with just this log, so your help is needed, most likely involving running some test builds to produce more logs to determine the problem.
If you are up to this, could you tell me a bit more about what you are trying to do:
- This looks like a VMware-like hypervisor trying to boot a dmg recovery, is it right? Could you tell me about the versions for both?
- How much memory is the VM assigned? Does increasing RAM help?
- Could you try to load the DMG recovery for macOS 10.15 or macOS 11 and provide me the log?
Thanks for getting back to me. I am happy to do anything to see what we can do.
Yes, I am running an extremely unsupported environment here but just trying to see how far I can actually get. Mentally prepare yourself.
I am running Hyper-V on Windows. The Host has 44GB of RAM and 8GB of that is statically assigned to the VM. Increase/decreasing memory doesn’t help unfortunately. However setting the memory before about 4500MB results in a verbosed error. OCB LoadImage failed — Unsupported
This is further than it previously got. I can try with 10.15 and 11 a bit later this evening or tomorrow. I have attached a log of booting the VM with 4096MB of RAM which seems to help a bit.
Yeah, there is no point in reducing the memory size, it dies earlier actually with an out of memory report. Provide a log with 11 dmg, and I will see what more prints I need to add to figure this out.
Attached both with relevant names
Okay, here is a build with more logging added. Please replace your OpenCore.efi and redo the log with 11. Please make sure that AppleDebug = YES is set. I will not promise this one will be enough to locate the bug, but I added relevant prints. Please let me know how it goes.
A bit confused, try this one (also need logs).
OpenCore-LT-r2.zip
I found and fixed one bug with this code. However, I am quite unsure whether this is the one you observe. Yours might be a bug in the firmware itself. In addition to fixing the issue I also added even more logging.
It really makes no sense. We allocate and what we allocated is freed by us soon after. Yet the firmware reports it is an anvalid tree. I kind of get it that there may be some memory corruption, but to me it sounds like a memory corruption outside of OpenCore.
Hm, I’ll do a memtest to check. That might explain why lowering the ram doesn’t crash opencore
Not sure it is a hardware issue actually. Lowering the RAM makes OpenCore stop earlier due to not enough memory. Here I would say a bug would be in the firmware code rather than hardware. Maybe try to understand what exactly breaks it at least. Try this version. It will likely error differently. include the log.
Here’s the log, I’ve also shutdown any VMS just incase
Okay, what about this one?
Ok we’ve got a much different error.
So, EFI_BOOT_SERVICES::GetMemoryMap on your side somehow corrupts the allocated memory. Now the question is what can we do to it…
Maybe try to increase the reserve 😡 Try this one. Need logs.
What about this?
Np… But I am out of ideas for the time being. We simply call the firmware, and it overwrites random data out of bounds @_@. I will provide some build to try to diagnose it in a better way later, but there hardly is a way to deal with such an obvious firmware bug.
I’m no expert with any sort of UEFI booting. I have done some googling of «GetMemoryMap and Hyper-V» and some bug reports of different Linux having to do some patches. Not sure if any of that could help?
Hopefully you’ll figure something out xD
Just a random update. Installed Hyper-V on my Windows 10 PC and I actually get much further. It starts calling the Kernel. See log attached. The biggest different (aside from the hardware) is this is Hyper-V config version 9 where as the other machine has 8.
I have same error with Debug version on my Haier Y11C laptop, here is the log
opencore-2021-02-07-214439.txt
Actually, I get black screen (with boot chime being played in a loop) when I enable OpenCanopy with PickerMode : External property. I have unlocked BIOS, so if I enable CSM. OpenCore menu is shown but it’s really slow and laggy. Enabling CSM isn’t right solution anyway.
With OC v0.6.5 I fixed by setting Resolution : 1366×768 (max resolution of internal display), and it worked well even with CSM disabled. updated to OC v0.6.6, issue is back now and even Resolution property have no effect now. that’s the reason I went for Debug version to check logs and ended up with this ASSERT_EFI_ERROR
I understand that I should create separate issue for Black-Screen, just trying to state whole problem and actually I didn’t get positive response from my last reply Keypad. on Lenovo Y530 doesn’t work #303.
I didn’t get this ASSERT_EFI_ERROR once, so here is the log if you need it. with Resolution : Max
opencore-2021-02-07-215002.txt
Just a random update. Installed Hyper-V on my Windows 10 PC and I actually get much further. It starts calling the Kernel. See log attached. The biggest different (aside from the hardware) is this is Hyper-V config version 9 where as the other machine has 8.
Hmm, in this case I would rather leave this unchanged on our side. Basically «a fix» would be some hack workarounding a firmware bug. We do add such hacks, but mainly for real firmwares. If the firmware is software only and the bug is fixed in a newer release, it is better to leave it unmodified on our side.
At this step it is clear that older Hyper-V within the call to VmAllocateMemoryPool inside OcGetCurrentMemoryMapAlloc corrupts the pool allocated memory as soon as GetMemoryMap is called, making this memory no longer available for free. You can probably workaround it by changing FreePool here to gBS->FreePool, simply ignoring the memory corruption, but I do not want to merge it.
@chilledHamza your PS2 issue was forgotten about. Sorry. Replied.
As for ASSERT, it is not in the log, so we need a photo. Create a separate issue for it.
© 2023 GitHub, Inc.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Источник
Posts: 16
Threads: 5
Joined: Apr 2020
Reputation:
0
08-05-2020, 11:09 AM
(This post was last modified: 08-05-2020, 11:10 AM by Nierewa.)
Hi,
I love ventoy.
But there’s a problem I have.
I made an Multiboot-USB Stick. With ventoy so easy.
But if I edit an ISO the error: «No bootfile found for UEFI! Maybe the image does not support X64 UEFI!» occured.
In this case it’s Acronis 2019.
Inside iso is a file for Mac: AcronisTrueImage2019-17000.dmg
I delete this one to safe space. Now I bood end get the error.
Kaspersky rescue disc the same.
But I did the same thing with Acronis 2017 ago… this worked fine.
I use PowerISO or UltraIso to edit the isos.
Can someone help me with this?
Best regards
Posts: 16
Threads: 5
Joined: Apr 2020
Reputation:
0
08-10-2020, 11:55 AM
(This post was last modified: 08-10-2020, 11:55 AM by Nierewa.)
I made a new GPT ventoy stick with Ventoy-1.0.18_Modified_EN and Support for SecureBoot.
Now I get this error message:
ASSERT_EFI_ERROR (Status = Invalid Parameter)
ASSERT [Ventoy] /home/share/Ventoy/EDKII/edk2-edk2-stable201911/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c(813): !EFI_ERROR (Status)
No bootfile found for UEFI!
Maybe the image does not support X64 UEFI!
Posts: 51
Threads: 5
Joined: May 2020
Reputation:
2
(08-05-2020, 11:09 AM)Nierewa Wrote: Hi,
I love ventoy.
But there’s a problem I have.I made an Multiboot-USB Stick. With ventoy so easy.
But if I edit an ISO the error: «No bootfile found for UEFI! Maybe the image does not support X64 UEFI!» occured.In this case it’s Acronis 2019.
Inside iso is a file for Mac: AcronisTrueImage2019-17000.dmg
I delete this one to safe space. Now I bood end get the error.Kaspersky rescue disc the same.
But I did the same thing with Acronis 2017 ago… this worked fine.
I use PowerISO or UltraIso to edit the isos.
Can someone help me with this?
Best regards
- Kaspersky Rescue DiskFor krd.iso, grub signature check was enabled in UEFI mode by default. Ventoy must do some hook to avoid «kernel.dat not found» error, but the hook will be denied by the check.So in UEFI mode, after the kaspersky boot menu was shown, you need to run set check_signatures=no in the grub shell before boot.
Posts: 37
Threads: 5
Joined: May 2020
Reputation:
3
(08-10-2020, 11:55 AM)Nierewa Wrote: I made a new GPT ventoy stick with Ventoy-1.0.18_Modified_EN and Support for SecureBoot.
Now I get this error message:ASSERT_EFI_ERROR (Status = Invalid Parameter)
ASSERT [Ventoy] /home/share/Ventoy/EDKII/edk2-edk2-stable201911/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c(813): !EFI_ERROR (Status)
No bootfile found for UEFI!
Maybe the image does not support X64 UEFI!
Modifiye ventoy çalışmayı yüklerken sisteminizde çalışan antivirüs veya defender usb sürücünüze erişimi engelleyip dosyaların yüklenmesini engellemiş olabilir ! önce dosyaların usb aygıtınıza yüklendiğine emin olun.
Dosyalar hatasız yüklenmişse hata aldığınız iso dosyasının adı nedir ? ve müdahele edilmiş bir iso dosyasımı bilmiyoruz.
Ventoy tarafından desteklenmeyen veya standart uefi kurulumu olmayan iso dosyaları için F6 kısa yol tuşuna basıp grubfm çalıştırıp iso dosyasını yüklemek için alternatif yükleme seçeneklerini deneyin ve ventoy,da F1 memdisk metodununu kullanarak ayrıca test edin.
Burada yazmak yerine paylaşım yapılan sitede ventoy konusunda sorunu yazabilirsiniz, bildiğim bir konu ise yardımcı olmaya çalışırım.
Posts: 16
Threads: 5
Joined: Apr 2020
Reputation:
0
Sorry, I can’t speak turkish and the Google translater shows a mess.
May you write in english please?
Внедрение платформы с длинным клетками
Недавно, в сочетании с BMC для отладки функции SOL, вам необходимо вывести журнал BIOS на устройство UART BMC, а затем необходимо удаленно вывести соответствующие последовательные данные на веб -страницу на BMC, то есть функция удаленного управления биос. Конечно, этот последовательный порт должен одновременно поддерживать операции ввода и вывода. Потому что на платформе Dragon Core, последовательный порт, используемый последовательным портом отладки по умолчанию, находится внутри процессора. Когда ЦП инициализирует базовую конфигурацию, вернитесь, чтобы инициализировать этот последовательный порт в качестве тестового последовательного порта. Конечно, каждый озабоченный человек знает, как неудобно отладить программу, если нет отладочного последовательного порта. В связи с спросом, последовательный порт ЦП и последовательный порт ЦП необходимы для поддержки операции ввода и вывода.
Как UEFI поддерживает многосериальные устройства
(1) Последовательный порт, используемый на стадии сборки
Последовательный порт ЦП инициализируется в файле start.s UEFI, и его можно использовать, и его можно использовать на стадии сборки. Режим, используемый здесь, заключается в том, что общий принцип состоит в том, чтобы потерять данные в реестре последовательного порта, поэтому данные будут выброшены. Конкретный код инициализации выглядит следующим образом:
LEAF(initserial)
.set mips64
.set noreorder
dli a0, 0x900000001fe001e0
li t1, 128
sb t1, 3(a0)
#ifdef BONITO_100M
/* divider, highest possible baud rate,for 100M crystal*/
li t1, 0x36
#else
/* divider, highest possible baud rate,for 25M crystal*/
li t1, 0x0d
#endif
sb t1, 0(a0)
/* divider, highest possible baud rate*/
li t1, 0x0
sb t1, 1(a0)
li t1, 3
sb t1, 3(a0)
li t1, 0
sb t1, 1(a0)
li t1, 71
sb t1, 2(a0)
jr ra
nop
END(initserial)
После инициализации серийный порт в основном доступен. Так что, если вы хотите распечатать строку в это время или несколько чисел, как ее использовать? Следующий код:
LEAF(tgt_putchar)
.set mips64
.set noreorder
dli v0, 0x900000001fe001e0
1:
lbu v1, 0x5(v0)
and v1, 0x20
beqz v1, 1b
nop
sb a0, 0x0(v0)
move v1, v0
jr ra
nop
END(tgt_putchar)
LEAF(hexserial)
.set mips64
.set noreorder
#ifdef ASM_DEBUG
move a2, ra
move a1, a0
li a3, 8
1:
rol a0, a1, 4
move a1, a0
and a0, 0xf
dla v0, hexchar
li s0, FV_OFFSET
daddu s0, FLASH_CODE_SECFV_BASE_ADDRESS
dli v1, 0xfffff
and v0,v1
daddu v0, s0
daddu v0, a0
lbu a0, 0(v0)
bal tgt_putchar
nop
daddu a3, -1
bnez a3, 1b
nop
move ra, a2
#endif
jr ra
nop
END(hexserial)
PRINTSTR("Shut down slave coresrn")
#define PRINTSTR TTYDBG
#define_TTYDBG(x)
.rdata;98: .asciz x; .text; dla a0, 98b; bal stringserial; nop
LEAF(stringserial)
.set mips64
.set noreorder
move a2, ra
li s0, FV_OFFSET
daddu s0, FLASH_CODE_SECFV_BASE_ADDRESS
and a0, 0xfffff
daddu a1, a0, s0
lbu a0, 0(a1)
1:
beqz a0, 2f
nop
bal tgt_putchar
nop
addiu a1, 1
lbu a0, 0(a1)
b 1b
nop
2:
move ra, a2
jr ra
nop
END(stringserial)
Приведенный выше код подробно представляет PrintStr («Выключите подчиненные ядер r n»). Он распечатана. Посмотрите на код, чтобы увидеть.
Это раздел строки. Если вы хотите распечатать кусок данных, вы можете напрямую вызвать функцию Hexserial. Вам нужно распечатать данные в регистр A0. A0 — это регистр, который сначала передает платформу MIPS.
(2) Печать последовательного порта, используемая на стадии C
В тот момент, когда UEFI вошел в среду C, инициализация последовательного порта была быстро названа. Здесь вызов относительно расплывчат, и он не будет найден на некоторое время. Вызов функции вызова выглядит следующим образом:
VOID
EFIAPI
SecCoreStartupWithStack(
IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
IN VOID *TopOfCurrentStack
)
{
EFI_SEC_PEI_HAND_OFF SecCoreData;
EFI_FIRMWARE_VOLUME_HEADER *BootPeiFv = (EFI_FIRMWARE_VOLUME_HEADER*) BootFv;
ProcessLibraryConstructorList(NULL, NULL);
DbgPrint(EFI_D_INFO, "Entering C environmentn");
// |-------------| <-- TopOfCurrentStack
// | Stack |
// | of | 64k
// | APs |
// |-------------| <-- TopOfBSP'sStack
// | Stack | 32k
// |-------------|
// | Heap | 32k
// |-------------| <-- SecCoreData.TemporaryRamBase
//
//
// Initialize SEC hand-off state
//
SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
DbgPrint(EFI_D_INFO,
"&SecCoreData.DataSize=%lx SecCoreData.DataSize=%lxn",
(UINT64)&(SecCoreData.DataSize),
(UINT64)(SecCoreData.DataSize));
Функция ProceslibraryConstructorList здесь вызывает функцию инициализации последовательного порта. Эта функция реализована в LIB серийного порта. Он содержит Defuglib в secmain.inf. Путь отладки объявляется в файле DSC.
DebugLib | MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
Давайте посмотрим на подробный процесс вызова ProcessLibraryConstructorList:
VOID
EFIAPI
ProcessLibraryConstructorList (
VOID
)
{
EFI_STATUS Status;
Status = BaseDebugLibSerialPortConstructor ();
ASSERT_EFI_ERROR (Status);
}
RETURN_STATUS
EFIAPI
BaseDebugLibSerialPortConstructor (
VOID
)
{
return SerialPortInitialize ();
}
}
Приведенный выше код реализован в Secmain/Debug/Autogen.c, который представляет собой автоматический код компиляции. SerialPortinitialize — это функция инициализации библиотеки хранения. Библиотека на нашей платформе реализует инициализацию CPU UART0. В настоящее время нам нужно инициализировать последовательный порт BMC, поэтому нам нужно реализовать только библиотеку для инициализации UART BMC. Но потому что BMC UART ссылается на автобус LPC Bridge. И если мы хотим получить доступ к этому устройству, нам нужно подождать, пока устройство LPC получит его, чтобы инициализировать его, поэтому его нельзя инициализировать на стадии SEC для инициализации последовательного порта BMC. Мы находимся на стадии DXE, потому что после того, как мост инициализируется на стадии PEI, пространство IO LPC может быть доступно. Давайте посмотрим, как стадия DXE инициализирует последовательный порт BMC и как зарегистрироваться в консоли.
Мы осознали драйвер отдельно. Оригинальный драйвер и оригинальный драйвер последовательного порта очень похожи на адрес серийного адреса и некоторую инициализацию контроллера SUPIO, поскольку этот UART является контроллером SUPIO через шину LPC. Итак, сначала инициализируйте контроллер Supio. Подробный код заключается в следующем:
Путь драйвера заключается в следующем:
LoongsonPlatformPkg/Drivers/SolSerialDxe/SerialDxe.inf
Файл INF выглядит следующим образом: (здесь он зависит от SolSerialPortLib, этот LIB должен реализовать функции, связанные с BMC UART и чтение и запись)
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SolSerialDxe
MODULE_UNI_FILE = SerialDxe.uni
FILE_GUID = D3987D4B-971A-435F-8CAF-4967EB627242
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = SerialDxeInitialize
[Sources.common]
SerialIo.c
[Packages]
MdePkg/MdePkg.dec
LoongsonDemoBoardPkg/Script/Loongson.dec
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
DebugLib
PcdLib
SolSerialPortLib
Давайте посмотрим на основной код этого драйвера:
FI_STATUS
EFIAPI
SerialDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
mSerialIoMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
mSerialIoMode.DataBits = (UINT32) PcdGet8 (PcdUartDefaultDataBits);
mSerialIoMode.Parity = (UINT32) PcdGet8 (PcdUartDefaultParity);
mSerialIoMode.StopBits = (UINT32) PcdGet8 (PcdUartDefaultStopBits);
mSerialIoMode.ReceiveFifoDepth = PcdGet16 (PcdUartDefaultReceiveFifoDepth);
mSerialDevicePath.Uart.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
mSerialDevicePath.Uart.DataBits = PcdGet8 (PcdUartDefaultDataBits);
mSerialDevicePath.Uart.Parity = PcdGet8 (PcdUartDefaultParity);
mSerialDevicePath.Uart.StopBits = PcdGet8 (PcdUartDefaultStopBits);
//
// Issue a reset to initialize the Serial Port
//
Status = mSerialIoTemplate.Reset (&mSerialIoTemplate);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Make a new handle with Serial IO protocol and its device path on it.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&mSerialHandle,
&gEfiSerialIoProtocolGuid, &mSerialIoTemplate,
&gEfiDevicePathProtocolGuid, &mSerialDevicePath,
NULL
);
ASSERT_EFI_ERROR (Status);
return Status;
}
EFI_SERIAL_IO_PROTOCOL mSerialIoTemplate = {
SERIAL_IO_INTERFACE_REVISION,
SerialReset,
SerialSetAttributes,
SerialSetControl,
SerialGetControl,
SerialWrite,
SerialRead,
&mSerialIoMode
};
EFI_STATUS
EFIAPI
SerialReset (
IN EFI_SERIAL_IO_PROTOCOL *This
)
{
EFI_STATUS Status;
Status = SolSerialPortInitialize ();
if (EFI_ERROR (Status)) {
return Status;
}
//
// Go set the current attributes
//
Status = This->SetAttributes (
This,
This->Mode->BaudRate,
This->Mode->ReceiveFifoDepth,
This->Mode->Timeout,
(EFI_PARITY_TYPE) This->Mode->Parity,
(UINT8) This->Mode->DataBits,
(EFI_STOP_BITS_TYPE) This->Mode->StopBits
);
//
// The serial device may not support some of the attributes. To prevent
// later failure, always return EFI_SUCCESS when SetAttributes is returning
// EFI_INVALID_PARAMETER.
//
if (Status == EFI_INVALID_PARAMETER) {
return EFI_SUCCESS;
}
return Status;
}
Из приведенного выше кода видно, что функция консоли, поддерживающей несколько последовательных устройств, в основном реализуется следующим кодом. Протокол в UEFI может поддерживать регистрацию нескольких интерфейсов. Резерсие и другие функции зарегистрированы через MSerialOtemplate. Точно так же тот же интерфейс зарегистрирован на последовательном приводе CPU UART, но конкретная операция — это разные устройства.
Status = gBS->InstallMultipleProtocolInterfaces (
&mSerialHandle,
&gEfiSerialIoProtocolGuid, &mSerialIoTemplate,
&gEfiDevicePathProtocolGuid, &mSerialDevicePath,
NULL
);
Так как же это устройство UART зарегистрировано в консоли? Эта регистрация зарегистрирована в драйвере терминала. Подробный код заключается в следующем:
TerminalDriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
EFI_SERIAL_IO_PROTOCOL *SerialIo;
EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
EFI_DEVICE_PATH_PROTOCOL *Vendor;
EFI_HANDLE SerialIoHandle;
EFI_SERIAL_IO_MODE *Mode;
UINTN SerialInTimeOut;
TERMINAL_DEV *TerminalDevice;
UINT8 TerminalType;
EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
UINTN EntryCount;
UINTN Index;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOutput;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextInput;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
//
// Get the Device Path Protocol to build the device path of the child device
//
Status = gBS->OpenProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
(VOID **) &ParentDevicePath,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
ASSERT ((Status == EFI_SUCCESS) || (Status == EFI_ALREADY_STARTED));
//
// Open the Serial I/O Protocol BY_DRIVER. It might already be started.
//
Status = gBS->OpenProtocol (
Controller,
&gEfiSerialIoProtocolGuid,
(VOID **) &SerialIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
Вот открытый gefiserialioprotocolguid. В настоящее время он получает интерфейс. В настоящее время получены два адреса, что соответствует адресу глобальной переменной, зарегистрированной в предыдущей регистрации.
Позднее интерфейс был предоставлен TerminalDevice-> Serialio, так что серийное устройство устанавливает связь с тройным устройством.
Устройство терминала зарегистрировано в задней части, которая включает в себя устройства ввода и выходные устройства. Кодовое шоу, как ниже:
Таким образом, консоль поддерживает вход и вывод нескольких последовательных портов.
Давайте посмотрим на инициализацию BMC UART. Вам нужно обратить внимание на некоторые моменты здесь:
(1) Логика работы контроллера Supio, каждое устройство Supio имеет концепцию логического устройства. Вам нужно читать и писать регистры в соответствии с логикой, соответствующей протоколу.
UINT8 SuperioWrite(UINT64 Dev, UINT64 Addr,UINT8 Data)
{
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0xa5);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0xa5);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0x7);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2f), Dev);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), Addr);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2f), Data);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0xaa);
return 0;
}
UINT8 SuperioRead(UINT64 Dev, UINT64 Addr)
{
UINT8 Data = 0;
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0xa5);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0xa5);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0x7);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2f), Dev);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), Addr);
Data = MmioRead8 (LPC_IO_BASE + 0x2f);
MmioWrite8 ((UINTN) (LPC_IO_BASE + 0x2e), 0xaa);
return Data;
}
(2) В то же время количество прерывания устройства Supio под LPC составляет 3, а некоторые — 4, а все архитектуры одинаковы. Наше устройство 4, чип по умолчанию.
(3) Характеристики триггера прерываний, некоторые чипсы по умолчанию имеют высокие триггеры, некоторые из них низкие, некоторые из них поднимаются, некоторые из которых являются нисходящими краями. требует внимания.
(4) Необходимо настроить часы контроллера SUPIO. Он должен быть известен без настройки часов по умолчанию, поскольку расчет скорости гонка UART требует часов.
** Формула расчета скорости гончара: divisor = (superio_uart_clk) / (16 *(vgbps)); здесь делитель - это значение регистра частотного деления, VGBPS - это скорость готтера: 115200: 115200
Superio_uart_clk - это часы. **
Ниже приведен подробный код инициализации:
RETURN_STATUS
EFIAPI
SolSerialPortInitialize (
VOID
)
{
UINTN SerialRegisterBase;
UINT16 Divisor;
// enable superio contrller
SuperioWrite(2, 0x30, 0x1);
// set superio clk 24M
SuperioWrite(2, 0xf0, 0x2);
// set superio irq num default is 4
SuperioWrite(2, 0x70, 0x04);
// set superio irq trig low
// 0x1:low 0x3:high
SuperioWrite(2, 0x71, 0x01);
Divisor = (SUPERIO_UART_CLK) / (16 * (VgBps));
//
// Get the base address of the serial port in either I/O or MMIO space
//
SerialRegisterBase = SolGetSerialRegisterBase ();
SolSerialPortWriteRegister (SerialRegisterBase, NS16550_FIFO, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4);
SolSerialPortWriteRegister (SerialRegisterBase, NS16550_CFCR, CFCR_DLAB);
SolSerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8));
SolSerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff));
SolSerialPortWriteRegister (SerialRegisterBase, NS16550_CFCR, CFCR_8BITS);
SolSerialPortWriteRegister (SerialRegisterBase, NS16550_MCR, MCR_DTR|MCR_RTS);
SolSerialPortWriteRegister (SerialRegisterBase, NS16550_IER, 0x00);
*(volatile UINT32 *)(SOL_UART_SWITCH_ADDR) = TURN_ON;
return RETURN_SUCCESS;
}
Код, в котором печатается напечатана, и код потери данных из этого последовательного порта, заключается в следующем:
VOID
EFIAPI
DebugPrint (
IN UINTN ErrorLevel,
IN CONST CHAR8 *Format,
...
)
{
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
VA_LIST Marker;
//
// If Format is NULL, then ASSERT().
//
ASSERT (Format != NULL);
//
// Check driver debug mask value and global mask
//
if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
return;
}
//
// Convert the DEBUG() message to an ASCII String
//
VA_START (Marker, Format);
AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
VA_END (Marker);
//
// Send the print string to a Serial Port
//
SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
if(*(volatile UINT32 *)(SOL_UART_SWITCH_ADDR) == TURN_ON){
SolSerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer));
}
}
Вся функция журнала печати UEFI выводится через функцию DebugPrint, за исключением фазы компиляции, тогда здесь вызывает функцию SolSerialPortWrite, и UART BMC также выведет ту же информацию об этом UART. Мы сделали переключатель здесь, чтобы управлять выходом журнала BMC.
Вход — это вход, полученный консолью. Конец консоли будет вызывать функцию ввода, соответствующую последовательному порту. Процесс кода очень сложный, включая множество протоколов. Я следил за этим раньше, вот подробное введение по временным причинам.
#1
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 10 August 2020 — 07:27 AM
Hi,
I’ve been using ventoy for a while now and I love it.
But there’s a problem I have.
I made an Multiboot-USB Stick. With ventoy so easy.
But if I edit an ISO the error: «No bootfile found for UEFI! Maybe the image does not support X64 UEFI!» occured.
In this case it’s Acronis 2019.
Inside iso is a file for Mac: AcronisTrueImage2019-17000.dmg
I delete this one to safe space. Now I boot and get the error.
Kaspersky rescue disc the same.
But I did the same thing with Acronis 2017 ago… this worked fine.
I use PowerISO or UltraIso to edit the isos.
Can someone help me with this?
Best regards
- Back to top
#2
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 10 August 2020 — 07:34 AM
Are you testing booting on a real system?
- Back to top
#3
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 10 August 2020 — 08:05 AM
Hi
On a real system.
- Back to top
#4
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 10 August 2020 — 08:07 AM
Does the modified ISO UEFI-boot from an Easy2Boot v2 USB drive?
- Back to top
#5
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 10 August 2020 — 08:10 AM
Can’t test because I have no Easy2Boot USb drive.
- Back to top
#6
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 10 August 2020 — 09:38 AM
So I’ve tested with Easy2Boot v2… same problem.
«No bootfile found for UEFI»
- Back to top
#7
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 10 August 2020 — 09:40 AM
OK — so if you extract the files from each ISO and compare the contents, what differences do you see?
- Back to top
#8
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 10 August 2020 — 10:52 AM
Content is the same.
Only folder doc and the file AcronisTrueImage2019-17000.dmg are deleted.
I had a screenshot but no idea how to attaching it
- Back to top
#9
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 10 August 2020 — 11:25 AM
I made a new GPT ventoy stick with Ventoy-1.0.18_Modified_EN and Support for SecureBoot.
Now I get this error message:
ASSERT_EFI_ERROR (Status = Invalid Parameter)
ASSERT [Ventoy] /home/share/Ventoy/EDKII/edk2-edk2-stable201911/MdePkg/Library/UefiMemoryAllocationLib/MemoryAllocationLib.c(813): !EFI_ERROR (Status)
No bootfile found for UEFI!
Maybe the image does not support X64 UEFI!
- Back to top
#10
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 10 August 2020 — 12:55 PM
Are you sure the unmodified ISO boots OK?
I have downloaded AcronisTrueImage2019_14110.iso and it also gives a UEFI boot error in E2B UEFI64 agFM grub2 (unmodified).
It does not contain any dmg file. I think you can get ISOs for PC or for MAC — maybe yours is the MAC one?
AcronisTrueImage2019_14110.iso UEFI64 boots OK if I use the agFM .isomem boot option however.
- Back to top
#11
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 13 August 2020 — 08:01 PM
Yes, it boots ok.
No, Its not the MAC one.
Only the modified doesn’t boot uefi.
Screenshot merged ISOs
- Back to top
#12
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 13 August 2020 — 10:33 PM
Check file contents using 7zip — so you can see [BOOT] files.
- Back to top
#13
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 13 August 2020 — 11:15 PM
The files in [BOOT] folder are the same in both ISOs:
1. 1-Boot-NoEmul.img size: 2048
2. 2-Boot-NoEmul.img size: 0
Hmm, can it be some kind of signature?
- Back to top
#14
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 13 August 2020 — 11:27 PM
How can it UEFI-boot if there are no .EFI boot files???
- Back to top
#15
alacran
alacran
-
-
.script developer
-
- 2710 posts
Platinum Member
-
Mexico
Posted 13 August 2020 — 11:57 PM
UEFI boot files should be located into efi folder and I didn’t see it on the pictures link on Post No, 11
See attached pictures from AcronisBootableMedia2016.iso
alacran
Attached Thumbnails
- Back to top
#16
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 14 August 2020 — 08:00 AM
UEFI boot files should be located into efi folder
It sems that there are more then one ISO-Versions outside.
As I wrote in Post 1 the Acronis 2017 ISO has the same content like your 2016 ISO.
The Acronis 2019 ISO unmodified boots UEFI.
AcronisTrueImage2019_14110.iso UEFI64 boots OK if I use the agFM .isomem boot option however.
As I wrote I use the modified ventoy Version.
If I boot .isomem nothing happens. Can you tell me how you did this?
- Back to top
#17
steve6375
steve6375
-
-
Developer
-
- 7565 posts
Platinum Member
- Location:UK
- Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films
-
United Kingdom
Posted 14 August 2020 — 08:15 AM
My ISO contains a EFI folder. I don’t see how your ISO can UEFI boot as it does not have EFI files — are you SURE it UEFI boots when unmodified?
To test:
I just made an E2B v2.04 USB drive using Windows 10
Added the ISO to _ISOBACKUP folder
UEFI64 booted
and chose the .isomem option.
Attached Thumbnails
- Back to top
#18
Wonko the Sane
Wonko the Sane
-
-
Advanced user
-
- 16065 posts
The Finder
- Location:The Outside of the Asylum (gate is closed)
-
Italy
Posted 14 August 2020 — 08:45 AM
I use PowerISO or UltraIso to edit the isos.
Then don’t and instead of editing a .iso (that by definition cannot be edited) re-create one.
Making a .iso that dual boots BIOS and UEFI is «tough» and it is very likely — not to say probable — that the original .iso has *some* settings[1] that «generic automagic» tools like PowerIso or UltraIso simply miss, or at least that was the case before:
https://msfn.org/boa…comment=1080917
Compare with:
http://reboot.pro/topic/21664-makeiso/
http://reboot.pro/to…-under-windows/
Basically you need to understand how (EXACTLY) the original .iso is made and then find a way to recreate it with mkisofs or oscdimg, start here:
https://msfn.org/boa…-torito-images/
Wonko
[1] possibly unrelated, but Acronis has historically made «strange» .iso’s:
http://reboot.pro/to…-grub2-at-uefi/
https://msfn.org/boa…oot-on-uefi-pc/
- Back to top
#19
cdob
cdob
-
-
Expert
-
- 1469 posts
Gold Member
Posted 14 August 2020 — 05:02 PM
2. 2-Boot-NoEmul.img size: 0
.
Compare this at ImDisk or ISOBuster.
.
This is the EFI boot image, It’s a approximate 400 MB floppy image.
- Back to top
#20
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 16 August 2020 — 07:20 PM
Compare this at ImDisk or ISOBuster.
Comparing with IsoBuster shows the difference
There only three entrys in Spur 1 in the modified ISO and the BiitImage.img with 0kib
Strange
- Back to top
#21
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 16 August 2020 — 07:20 PM
Compare this at ImDisk or ISOBuster.
Comparing with IsoBuster shows the difference
There only three entrys in Spur 1 in the modified ISO and the BiitImage.img with 0kib
Strange
Attached Thumbnails
- Back to top
#22
Wonko the Sane
Wonko the Sane
-
-
Advanced user
-
- 16065 posts
The Finder
- Location:The Outside of the Asylum (gate is closed)
-
Italy
Posted 17 August 2020 — 10:27 AM
Strange
Please read as «normal for Acronis», as seen in the given threads.
What very likely happens is that the size of the boot image is mis-reported, not entirely unlike what happened here:
http://reboot.pro/to…ting-iso-files/
with a «more normal» isolinux .iso.
Wonko
- Back to top
#23
cdob
cdob
-
-
Expert
-
- 1469 posts
Gold Member
Posted 17 August 2020 — 08:07 PM
Comparing with IsoBuster shows the difference
The original ISO contains two ~ 400 MB boot images.
Guessed: one PC and another Mac one. Then one image should be mountable at ImDisk.
The boot images are missing at the edited ISO, UEFI boot fails.
- Back to top
#24
nierewa
nierewa
-
-
Advanced user
-
- 107 posts
Frequent Member
-
Germany
Posted 19 August 2020 — 09:18 AM
Best Answer
Ok, I give up.
So I use the original Image instead.
Thanks all for your help
- Back to top
#25
cdob
cdob
-
-
Expert
-
- 1469 posts
Gold Member
Posted 19 August 2020 — 04:32 PM
I wonder the file size: why a 1.6 GB ISO image?
Dosn’t Acronis offer a about 700 MB CD image anymore?
- Back to top
/** Fault Tolerant Write protocol notification event handler. Non-Volatile variable write may needs FTW protocol to reclaim when writting variable. @param[in] Event Event whose notification function is being invoked. @param[in] Context Pointer to the notification function's context. **/ VOID EFIAPI FtwNotificationEvent ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvbProtocol; EFI_FAULT_TOLERANT_WRITE_PROTOCOL *FtwProtocol; EFI_PHYSICAL_ADDRESS NvStorageVariableBase; EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; EFI_PHYSICAL_ADDRESS BaseAddress; UINT64 Length; EFI_PHYSICAL_ADDRESS VariableStoreBase; UINT64 VariableStoreLength; // // Ensure FTW protocol is installed. // Status = GetFtwProtocol ((VOID**) &FtwProtocol); if (EFI_ERROR (Status)) { return ; } // // Find the proper FVB protocol for variable. // NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet64 (PcdFlashNvStorageVariableBase64); if (NvStorageVariableBase == 0) { NvStorageVariableBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashNvStorageVariableBase); } Status = GetFvbInfoByAddress (NvStorageVariableBase, NULL, &FvbProtocol); if (EFI_ERROR (Status)) { return ; } mVariableModuleGlobal->FvbInstance = FvbProtocol; // // Mark the variable storage region of the FLASH as RUNTIME. // VariableStoreBase = mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase; VariableStoreLength = ((VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase)->Size; BaseAddress = VariableStoreBase & (~EFI_PAGE_MASK); Length = VariableStoreLength + (VariableStoreBase - BaseAddress); Length = (Length + EFI_PAGE_SIZE - 1) & (~EFI_PAGE_MASK); Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdDescriptor); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.n")); } else { Status = gDS->SetMemorySpaceAttributes ( BaseAddress, Length, GcdDescriptor.Attributes | EFI_MEMORY_RUNTIME ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_WARN, "Variable driver failed to add EFI_MEMORY_RUNTIME attribute to Flash.n")); } } Status = VariableWriteServiceInitialize (); ASSERT_EFI_ERROR (Status); // // Install the Variable Write Architectural protocol. // Status = gBS->InstallProtocolInterface ( &mHandle, &gEfiVariableWriteArchProtocolGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); // // Close the notify event to avoid install gEfiVariableWriteArchProtocolGuid again. // gBS->CloseEvent (Event); }
/** Main entry point to DXE Core. @param HobStart Pointer to the beginning of the HOB List from PEI. @return This function should never return. **/ VOID EFIAPI DxeMain ( IN VOID *HobStart ) { EFI_STATUS Status; EFI_PHYSICAL_ADDRESS MemoryBaseAddress; UINT64 MemoryLength; PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; UINTN Index; EFI_HOB_GUID_TYPE *GuidHob; EFI_VECTOR_HANDOFF_INFO *VectorInfoList; EFI_VECTOR_HANDOFF_INFO *VectorInfo; // // Setup the default exception handlers // VectorInfoList = NULL; GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); if (GuidHob != NULL) { VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob)); } Status = InitializeCpuExceptionHandlers (VectorInfoList); ASSERT_EFI_ERROR (Status); // // Initialize Debug Agent to support source level debug in DXE phase // InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_CORE, HobStart, NULL); // // Initialize Memory Services // CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength); // // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table // gDxeCoreST = AllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate); ASSERT (gDxeCoreST != NULL); gDxeCoreRT = AllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate); ASSERT (gDxeCoreRT != NULL); gDxeCoreST->RuntimeServices = gDxeCoreRT; // // Start the Image Services. // Status = CoreInitializeImageServices (HobStart); ASSERT_EFI_ERROR (Status); // // Call constructor for all libraries // ProcessLibraryConstructorList (gDxeCoreImageHandle, gDxeCoreST); PERF_END (NULL,"PEI", NULL, 0) ; PERF_START (NULL,"DXE", NULL, 0) ; // // Report DXE Core image information to the PE/COFF Extra Action Library // ZeroMem (&ImageContext, sizeof (ImageContext)); ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreLoadedImage->ImageBase; ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); PeCoffLoaderRelocateImageExtraAction (&ImageContext); // // Initialize the Global Coherency Domain Services // Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength); ASSERT_EFI_ERROR (Status); // // Install the DXE Services Table into the EFI System Tables's Configuration Table // Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDxeCoreDS); ASSERT_EFI_ERROR (Status); // // Install the HOB List into the EFI System Tables's Configuration Table // Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart); ASSERT_EFI_ERROR (Status); // // Install Memory Type Information Table into the EFI System Tables's Configuration Table // Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation); ASSERT_EFI_ERROR (Status); // // If Loading modules At fixed address feature is enabled, install Load moduels at fixed address // Configuration Table so that user could easily to retrieve the top address to load Dxe and PEI // Code and Tseg base to load SMM driver. // if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) { Status = CoreInstallConfigurationTable (&gLoadFixedAddressConfigurationTableGuid, &gLoadModuleAtFixAddressConfigurationTable); ASSERT_EFI_ERROR (Status); } // // Report Status Code here for DXE_ENTRY_POINT once it is available // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT) ); // // Create the aligned system table pointer structure that is used by external // debuggers to locate the system table... Also, install debug image info // configuration table. // CoreInitializeDebugImageInfoTable (); CoreNewDebugImageInfoEntry ( EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, gDxeCoreLoadedImage, gDxeCoreImageHandle ); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "HOBLIST address in DXE = 0x%pn", HobStart)); DEBUG_CODE_BEGIN (); EFI_PEI_HOB_POINTERS Hob; for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Memory Allocation 0x%08x 0x%0lx - 0x%0lxn", Hob.MemoryAllocation->AllocDescriptor.MemoryType, Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress, Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength - 1)); } } for (Hob.Raw = HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) { if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV2 Hob 0x%0lx - 0x%0lxn", Hob.FirmwareVolume2->BaseAddress, Hob.FirmwareVolume2->BaseAddress + Hob.FirmwareVolume2->Length - 1)); } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) { DEBUG ((DEBUG_INFO | DEBUG_LOAD, "FV Hob 0x%0lx - 0x%0lxn", Hob.FirmwareVolume->BaseAddress, Hob.FirmwareVolume->BaseAddress + Hob.FirmwareVolume2->Length - 1)); } } DEBUG_CODE_END (); // // Initialize the Event Services // Status = CoreInitializeEventServices (); ASSERT_EFI_ERROR (Status); // // Get persisted vector hand-off info from GUIDeed HOB again due to HobStart may be updated, // and install configuration table // GuidHob = GetNextGuidHob (&gEfiVectorHandoffInfoPpiGuid, HobStart); if (GuidHob != NULL) { VectorInfoList = (EFI_VECTOR_HANDOFF_INFO *) (GET_GUID_HOB_DATA(GuidHob)); VectorInfo = VectorInfoList; Index = 1; while (VectorInfo->Attribute != EFI_VECTOR_HANDOFF_LAST_ENTRY) { VectorInfo ++; Index ++; } VectorInfo = AllocateCopyPool (sizeof (EFI_VECTOR_HANDOFF_INFO) * Index, (VOID *) VectorInfoList); ASSERT (VectorInfo != NULL); Status = CoreInstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) VectorInfo); ASSERT_EFI_ERROR (Status); } // // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs // // These Protocols are not architectural. This implementation is sharing code between // PEI and DXE in order to save FLASH space. These Protocols could also be implemented // as part of the DXE Core. However, that would also require the DXE Core to be ported // each time a different CPU is used, a different Decompression algorithm is used, or a // different Image type is used. By placing these Protocols in PEI, the DXE Core remains // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform, // and from CPU to CPU. // // // Publish the EFI, Tiano, and Custom Decompress protocols for use by other DXE components // Status = CoreInstallMultipleProtocolInterfaces ( &mDecompressHandle, &gEfiDecompressProtocolGuid, &gEfiDecompress, NULL ); ASSERT_EFI_ERROR (Status); // // Register for the GUIDs of the Architectural Protocols, so the rest of the // EFI Boot Services and EFI Runtime Services tables can be filled in. // Also register for the GUIDs of optional protocols. // CoreNotifyOnProtocolInstallation (); // // Produce Firmware Volume Protocols, one for each FV in the HOB list. // Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gDxeCoreST); ASSERT_EFI_ERROR (Status); Status = FwVolDriverInit (gDxeCoreImageHandle, gDxeCoreST); ASSERT_EFI_ERROR (Status); // // Produce the Section Extraction Protocol // Status = InitializeSectionExtraction (gDxeCoreImageHandle, gDxeCoreST); ASSERT_EFI_ERROR (Status); // // Initialize the DXE Dispatcher // PERF_START (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ; CoreInitializeDispatcher (); PERF_END (NULL,"CoreInitializeDispatcher", "DxeMain", 0) ; // // Invoke the DXE Dispatcher // PERF_START (NULL, "CoreDispatcher", "DxeMain", 0); CoreDispatcher (); PERF_END (NULL, "CoreDispatcher", "DxeMain", 0); // // Display Architectural protocols that were not loaded if this is DEBUG build // DEBUG_CODE_BEGIN (); CoreDisplayMissingArchProtocols (); DEBUG_CODE_END (); // // Display any drivers that were not dispatched because dependency expression // evaluated to false if this is a debug build // DEBUG_CODE_BEGIN (); CoreDisplayDiscoveredNotDispatched (); DEBUG_CODE_END (); // // Assert if the Architectural Protocols are not present. // Status = CoreAllEfiServicesAvailable (); if (EFI_ERROR(Status)) { // // Report Status code that some Architectural Protocols are not present. // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH) ); } ASSERT_EFI_ERROR (Status); // // Report Status code before transfer control to BDS // REPORT_STATUS_CODE ( EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT) ); // // Transfer control to the BDS Architectural Protocol // gBds->Entry (gBds); // // BDS should never return // ASSERT (FALSE); CpuDeadLoop (); }
/** Entry point of this module. @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @return Status. **/ EFI_STATUS EFIAPI PeimEntryMA ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; TIS_TPM_HANDLE TpmHandle; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) { DEBUG ((EFI_D_ERROR, "No TPM12 instance required!n")); return EFI_UNSUPPORTED; } if (PcdGetBool (PcdHideTpmSupport) && PcdGetBool (PcdHideTpm)) { return EFI_UNSUPPORTED; } // // Initialize TPM device // Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // In S3 path, skip shadow logic. no measurement is required // if (BootMode != BOOT_ON_S3_RESUME) { Status = (**PeiServices).RegisterForShadow(FileHandle); if (Status == EFI_ALREADY_STARTED) { mImageInMemory = TRUE; } else if (Status == EFI_NOT_FOUND) { ASSERT_EFI_ERROR (Status); } } if (!mImageInMemory) { TpmHandle = (TIS_TPM_HANDLE)(UINTN)TPM_BASE_ADDRESS; Status = TisPcRequestUseTpm ((TIS_PC_REGISTERS_PTR)TpmHandle); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "TPM not detected!n")); return Status; } if (PcdGet8 (PcdTpmInitializationPolicy) == 1) { Status = TpmCommStartup ((EFI_PEI_SERVICES**)PeiServices, TpmHandle, BootMode); if (EFI_ERROR (Status) ) { return Status; } } // // TpmSelfTest is optional on S3 path, skip it to save S3 time // if (BootMode != BOOT_ON_S3_RESUME) { Status = TpmCommContinueSelfTest ((EFI_PEI_SERVICES**)PeiServices, TpmHandle); if (EFI_ERROR (Status)) { return Status; } } Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); } if (mImageInMemory) { Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices); if (EFI_ERROR (Status)) { return Status; } } return Status; }
STATIC UINT64* GetBlockEntryListFromAddress ( IN UINT64 *RootTable, IN UINT64 RegionStart, OUT UINTN *TableLevel, IN OUT UINT64 *BlockEntrySize, IN OUT UINT64 **LastBlockEntry ) { UINTN RootTableLevel; UINTN RootTableEntryCount; UINT64 *TranslationTable; UINT64 *BlockEntry; UINT64 BlockEntryAddress; UINTN BaseAddressAlignment; UINTN PageLevel; UINTN Index; UINTN IndexLevel; UINTN T0SZ; UINT64 Attributes; UINT64 TableAttributes; // Initialize variable BlockEntry = NULL; // Ensure the parameters are valid if (!(TableLevel && BlockEntrySize && LastBlockEntry)) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return NULL; } // Ensure the Region is aligned on 4KB boundary if ((RegionStart & (SIZE_4KB - 1)) != 0) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return NULL; } // Ensure the required size is aligned on 4KB boundary if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0) { ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); return NULL; } // // Calculate LastBlockEntry from T0SZ - this is the last block entry of the root Translation table // T0SZ = ArmGetTCR () & TCR_T0SZ_MASK; // Get the Table info from T0SZ GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount); // The last block of the root table depends on the number of entry in this table *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(RootTable, RootTableEntryCount); // If the start address is 0x0 then we use the size of the region to identify the alignment if (RegionStart == 0) { // Identify the highest possible alignment for the Region Size for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; BaseAddressAlignment++) { if ((1 << BaseAddressAlignment) & *BlockEntrySize) { break; } } } else { // Identify the highest possible alignment for the Base Address for (BaseAddressAlignment = 0; BaseAddressAlignment < 64; BaseAddressAlignment++) { if ((1 << BaseAddressAlignment) & RegionStart) { break; } } } // Identify the Page Level the RegionStart must belongs to PageLevel = 3 - ((BaseAddressAlignment - 12) / 9); // If the required size is smaller than the current block size then we need to go to the page below. // The PageLevel was calculated on the Base Address alignment but did not take in account the alignment // of the allocation size if (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) { // It does not fit so we need to go a page level above PageLevel++; } // Expose the found PageLevel to the caller *TableLevel = PageLevel; // Now, we have the Table Level we can get the Block Size associated to this table *BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel); // // Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries // TranslationTable = RootTable; for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) { BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart); if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) { // Go to the next table TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE); // If we are at the last level then update the output if (IndexLevel == PageLevel) { // And get the appropriate BlockEntry at the next level BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel + 1, RegionStart); // Set the last block for this new table *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT); } } else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) { // If we are not at the last level then we need to split this BlockEntry if (IndexLevel != PageLevel) { // Retrieve the attributes from the block entry Attributes = *BlockEntry & TT_ATTRIBUTES_MASK; // Convert the block entry attributes into Table descriptor attributes TableAttributes = TT_TABLE_AP_NO_PERMISSION; if (Attributes & TT_PXN_MASK) { TableAttributes = TT_TABLE_PXN; } if (Attributes & TT_UXN_MASK) { TableAttributes = TT_TABLE_XN; } if (Attributes & TT_NS) { TableAttributes = TT_TABLE_NS; } // Get the address corresponding at this entry BlockEntryAddress = RegionStart; BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel); // Shift back to right to set zero before the effective address BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel); // Set the correct entry type for the next page level if ((IndexLevel + 1) == 3) { Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3; } else { Attributes |= TT_TYPE_BLOCK_ENTRY; } // Create a new translation table TranslationTable = (UINT64*)AllocatePages (EFI_SIZE_TO_PAGES((TT_ENTRY_COUNT * sizeof(UINT64)) + TT_ALIGNMENT_DESCRIPTION_TABLE)); if (TranslationTable == NULL) { return NULL; } TranslationTable = (UINT64*)((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE); // Fill the BlockEntry with the new TranslationTable *BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY; // Update the last block entry with the newly created translation table *LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, TT_ENTRY_COUNT); // Populate the newly created lower level table BlockEntry = TranslationTable; for (Index = 0; Index < TT_ENTRY_COUNT; Index++) { *BlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1))); BlockEntry++; } // Block Entry points at the beginning of the Translation Table BlockEntry = TranslationTable; } } else { if (IndexLevel != PageLevel) {
/** This notification function is invoked when an instance of the EFI_DEVICE_PATH_PROTOCOL is produced. @param Event The event that occured @param Context For EFI compatiblity. Not used. **/ VOID EFIAPI NotifyDevPath ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_HANDLE Handle; EFI_STATUS Status; UINTN BufferSize; EFI_DEVICE_PATH_PROTOCOL *DevPathNode; ATAPI_DEVICE_PATH *Atapi; // // Examine all new handles // for (;;) { // // Get the next handle // BufferSize = sizeof (Handle); Status = gBS->LocateHandle ( ByRegisterNotify, NULL, mEfiDevPathNotifyReg, &BufferSize, &Handle ); // // If not found, we're done // if (EFI_NOT_FOUND == Status) { break; } if (EFI_ERROR (Status)) { continue; } // // Get the DevicePath protocol on that handle // Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode); ASSERT_EFI_ERROR (Status); while (!IsDevicePathEnd (DevPathNode)) { // // Find the handler to dump this device path node // if ( (DevicePathType(DevPathNode) == MESSAGING_DEVICE_PATH) && (DevicePathSubType(DevPathNode) == MSG_ATAPI_DP) ) { Atapi = (ATAPI_DEVICE_PATH*) DevPathNode; PciOr16 ( PCI_LIB_ADDRESS ( 0, 1, 1, (Atapi->PrimarySecondary == 1) ? 0x42: 0x40 ), BIT15 ); } // // Next device path node // DevPathNode = NextDevicePathNode (DevPathNode); } } return; }
/** Communicates with a registered handler. This function provides a service to send and receive messages from a registered UEFI service. @param[in] This The EFI_PEI_SMM_COMMUNICATION_PPI instance. @param[in, out] CommBuffer A pointer to the buffer to convey into SMRAM. @param[in, out] CommSize The size of the data buffer being passed in.On exit, the size of data being returned. Zero if the handler does not wish to reply with any data. @retval EFI_SUCCESS The message was successfully posted. @retval EFI_INVALID_PARAMETER The CommBuffer was NULL. @retval EFI_NOT_STARTED The service is NOT started. **/ EFI_STATUS EFIAPI Communicate ( IN CONST EFI_PEI_SMM_COMMUNICATION_PPI *This, IN OUT VOID *CommBuffer, IN OUT UINTN *CommSize ) { EFI_STATUS Status; PEI_SMM_CONTROL_PPI *SmmControl; PEI_SMM_ACCESS_PPI *SmmAccess; UINT8 SmiCommand; UINTN Size; EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext; DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Entern")); if (CommBuffer == NULL) { return EFI_INVALID_PARAMETER; } // // Get needed resource // Status = PeiServicesLocatePpi ( &gPeiSmmControlPpiGuid, 0, NULL, (VOID **)&SmmControl ); if (EFI_ERROR (Status)) { return EFI_NOT_STARTED; } Status = PeiServicesLocatePpi ( &gPeiSmmAccessPpiGuid, 0, NULL, (VOID **)&SmmAccess ); if (EFI_ERROR (Status)) { return EFI_NOT_STARTED; } // // Check SMRAM locked, it should be done after SMRAM lock. // if (!SmmAccess->LockState) { DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %xn", (UINTN)SmmAccess->LockState)); return EFI_NOT_STARTED; } SmmCommunicationContext = GetCommunicationContext (); DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei BufferPtrAddress - 0x%016lx, BufferPtr: 0x%016lxn", SmmCommunicationContext->BufferPtrAddress, *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress)); // // No need to check if BufferPtr is 0, because it is in PEI phase. // *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer; DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei CommBuffer - %xn", (UINTN)CommBuffer)); // // Send command // SmiCommand = (UINT8)SmmCommunicationContext->SwSmiNumber; Size = sizeof(SmiCommand); Status = SmmControl->Trigger ( (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmControl, (INT8 *)&SmiCommand, &Size, FALSE, 0 ); ASSERT_EFI_ERROR (Status); // // Setting BufferPtr to 0 means this transaction is done. // *(EFI_PHYSICAL_ADDRESS *)(UINTN)SmmCommunicationContext->BufferPtrAddress = 0; DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei Communicate Exitn")); return EFI_SUCCESS; }
EFI_STATUS EFIAPI WinNtTimerDriverInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) /*++ Routine Description: Initialize the Timer Architectural Protocol driver Arguments: ImageHandle - ImageHandle of the loaded driver SystemTable - Pointer to the System Table Returns: EFI_SUCCESS - Timer Architectural Protocol created EFI_OUT_OF_RESOURCES - Not enough resources available to initialize driver. EFI_DEVICE_ERROR - A device error occured attempting to initialize the driver. --*/ { EFI_STATUS Status; UINTN Result; EFI_HANDLE Handle; EFI_HANDLE hSourceProcessHandle; EFI_HANDLE hSourceHandle; EFI_HANDLE hTargetProcessHandle; // // Make sure the Timer Architectural Protocol is not already installed in the system // ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); // // Get the CPU Architectural Protocol instance // Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID**)&mCpu); ASSERT_EFI_ERROR (Status); // // Get our handle so the timer tick thread can suspend // hSourceProcessHandle = gWinNt->GetCurrentProcess (); hSourceHandle = gWinNt->GetCurrentThread (); hTargetProcessHandle = gWinNt->GetCurrentProcess (); Result = gWinNt->DuplicateHandle ( hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, &mNtMainThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS ); if (Result == 0) { return EFI_DEVICE_ERROR; } // // Initialize Critical Section used to update variables shared between the main // thread and the timer interrupt thread. // gWinNt->InitializeCriticalSection (&mNtCriticalSection); // // Start the timer thread at the default timer period // Status = mTimer.SetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); if (EFI_ERROR (Status)) { gWinNt->DeleteCriticalSection (&mNtCriticalSection); return Status; } // // Install the Timer Architectural Protocol onto a new handle // Handle = NULL; Status = gBS->InstallProtocolInterface ( &Handle, &gEfiTimerArchProtocolGuid, EFI_NATIVE_INTERFACE, &mTimer ); if (EFI_ERROR (Status)) { // // Cancel the timer // mTimer.SetTimerPeriod (&mTimer, 0); gWinNt->DeleteCriticalSection (&mNtCriticalSection); return Status; } return EFI_SUCCESS; }
/** PEI termination callback. @param[in] PeiServices General purpose services available to every PEIM. @param[in] NotifyDescriptor Not uesed. @param[in] Ppi Not uesed. @retval EFI_SUCCESS If the interface could be successfully installed. **/ EFI_STATUS EndOfPeiPpiNotifyCallback ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; UINT64 MemoryTop; UINT64 LowUncableBase; EFI_PLATFORM_INFO_HOB *PlatformInfo; UINT32 HecBaseHigh; EFI_BOOT_MODE BootMode; Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); ASSERT_EFI_ERROR (Status); // // Set the some PCI and chipset range as UC // And align to 1M at leaset // PlatformInfo = PcdGetPtr (PcdPlatformInfo); UpdateDefaultSetupValue (PlatformInfo); DEBUG ((EFI_D_ERROR, "Memory TOLM: %Xn", PlatformInfo->MemData.MemTolm)); DEBUG ((EFI_D_ERROR, "PCIE OSBASE: %lXn", PlatformInfo->PciData.PciExpressBase)); DEBUG ( (EFI_D_ERROR, "PCIE BASE: %lX Size : %Xn", PlatformInfo->PciData.PciExpressBase, PlatformInfo->PciData.PciExpressSize) ); DEBUG ( (EFI_D_ERROR, "PCI32 BASE: %X Limit: %Xn", PlatformInfo->PciData.PciResourceMem32Base, PlatformInfo->PciData.PciResourceMem32Limit) ); DEBUG ( (EFI_D_ERROR, "PCI64 BASE: %lX Limit: %lXn", PlatformInfo->PciData.PciResourceMem64Base, PlatformInfo->PciData.PciResourceMem64Limit) ); DEBUG ((EFI_D_ERROR, "UC START: %lX End : %lXn", PlatformInfo->MemData.MemMir0, PlatformInfo->MemData.MemMir1)); LowUncableBase = PlatformInfo->MemData.MemMaxTolm; LowUncableBase &= (0x0FFF00000); MemoryTop = (0x100000000); if (BootMode != BOOT_ON_S3_RESUME) { // // In BIOS, HECBASE will be always below 4GB // HecBaseHigh = (UINT32) RShiftU64 (PlatformInfo->PciData.PciExpressBase, 28); ASSERT (HecBaseHigh < 16); // // Programe HECBASE for DXE phase // } return Status; }
EFI_STATUS EFIAPI SpiProtocolInit ( IN EFI_SPI_PROTOCOL *This, IN SPI_INIT_TABLE *InitTable ) /*++ Routine Description: Initialize the host controller to execute SPI command. Arguments: This Pointer to the EFI_SPI_PROTOCOL instance. InitTable Initialization data to be programmed into the SPI host controller. Returns: EFI_SUCCESS Initialization completed. EFI_ACCESS_DENIED The SPI static configuration interface has been locked-down. EFI_INVALID_PARAMETER Bad input parameters. EFI_UNSUPPORTED Can't get Descriptor mode VSCC values --*/ { EFI_STATUS Status; UINT8 Index; UINT16 OpcodeType; SPI_INSTANCE *SpiInstance; UINTN PchRootComplexBar; UINT8 UnlockCmdOpcodeIndex; UINT8 FlashPartId[3]; SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This); PchRootComplexBar = SpiInstance->PchRootComplexBar; if (InitTable != NULL) { // // Copy table into SPI driver Private data structure // CopyMem ( &SpiInstance->SpiInitTable, InitTable, sizeof (SPI_INIT_TABLE) ); } else { return EFI_INVALID_PARAMETER; } // // Check if the SPI interface has been locked-down. // if ((MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS) & B_QNC_RCRB_SPIS_SCL) != 0) { ASSERT_EFI_ERROR (EFI_ACCESS_DENIED); return EFI_ACCESS_DENIED; } // // Clear all the status bits for status regs. // MmioOr16 ( (UINTN) (PchRootComplexBar + R_QNC_RCRB_SPIS), (UINT16) ((B_QNC_RCRB_SPIS_CDS | B_QNC_RCRB_SPIS_BAS)) ); MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIS); // // Set the Prefix Opcode registers. // MmioWrite16 ( PchRootComplexBar + R_QNC_RCRB_SPIPREOP, (SpiInstance->SpiInitTable.PrefixOpcode[1] << 8) | InitTable->PrefixOpcode[0] ); MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIPREOP); // // Set Opcode Type Configuration registers. // for (Index = 0, OpcodeType = 0; Index < SPI_NUM_OPCODE; Index++) { switch (SpiInstance->SpiInitTable.OpcodeMenu[Index].Type) { case EnumSpiOpcodeRead: OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_ADD_READ << (Index * 2)); break; case EnumSpiOpcodeWrite: OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_ADD_WRITE << (Index * 2)); break; case EnumSpiOpcodeWriteNoAddr: OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_NOADD_WRITE << (Index * 2)); break; default: OpcodeType |= (UINT16) (B_QNC_RCRB_SPIOPTYPE_NOADD_READ << (Index * 2)); break; } } MmioWrite16 (PchRootComplexBar + R_QNC_RCRB_SPIOPTYPE, OpcodeType); MmioRead16 (PchRootComplexBar + R_QNC_RCRB_SPIOPTYPE); // // Setup the Opcode Menu registers. // UnlockCmdOpcodeIndex = SPI_NUM_OPCODE; for (Index = 0; Index < SPI_NUM_OPCODE; Index++) { MmioWrite8 ( PchRootComplexBar + R_QNC_RCRB_SPIOPMENU + Index, SpiInstance->SpiInitTable.OpcodeMenu[Index].Code ); MmioRead8 (PchRootComplexBar + R_QNC_RCRB_SPIOPMENU + Index); if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationJedecId) { Status = SpiProtocolExecute ( This, Index, 0, TRUE, TRUE, FALSE, (UINTN) 0, 3, FlashPartId, EnumSpiRegionDescriptor ); if (EFI_ERROR (Status)) { return Status; } if (FlashPartId[0] != SpiInstance->SpiInitTable.VendorId || FlashPartId[1] != SpiInstance->SpiInitTable.DeviceId0 || FlashPartId[2] != SpiInstance->SpiInitTable.DeviceId1) { return EFI_INVALID_PARAMETER; } } if (SpiInstance->SpiInitTable.OpcodeMenu[Index].Operation == EnumSpiOperationWriteStatus) { UnlockCmdOpcodeIndex = Index; } } Status = UnlockFlashComponents ( This, UnlockCmdOpcodeIndex ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Unlock flash components fail!n")); } SpiPhaseInit (); FillOutPublicInfoStruct (SpiInstance); SpiInstance->InitDone = TRUE; return EFI_SUCCESS; }
/** Dispatch initialization request to sub status code devices based on customized feature flags. **/ VOID InitializationDispatcherWorker ( VOID ) { EFI_PEI_HOB_POINTERS Hob; EFI_STATUS Status; MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader; MEMORY_STATUSCODE_RECORD *Record; UINTN Index; UINTN MaxRecordNumber; // // If enable UseSerial, then initialize serial port. // if enable UseRuntimeMemory, then initialize runtime memory status code worker. // if (FeaturePcdGet (PcdStatusCodeUseSerial)) { // // Call Serial Port Lib API to initialize serial port. // Status = SerialPortInitialize (); ASSERT_EFI_ERROR (Status); } if (FeaturePcdGet (PcdStatusCodeUseMemory)) { Status = RtMemoryStatusCodeInitializeWorker (); ASSERT_EFI_ERROR (Status); } // // Replay Status code which saved in GUID'ed HOB to all supported devices. // if (FeaturePcdGet (PcdStatusCodeReplayIn)) { // // Journal GUID'ed HOBs to find all record entry, if found, // then output record to support replay device. // Hob.Raw = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid); if (Hob.Raw != NULL) { PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid); Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1); MaxRecordNumber = (UINTN) PacketHeader->RecordIndex; if (PacketHeader->PacketIndex > 0) { // // Record has been wrapped around. So, record number has arrived at max number. // MaxRecordNumber = (UINTN) PacketHeader->MaxRecordsNumber; } for (Index = 0; Index < MaxRecordNumber; Index++) { // // Dispatch records to devices based on feature flag. // if (FeaturePcdGet (PcdStatusCodeUseSerial)) { SerialStatusCodeReportWorker ( Record[Index].CodeType, Record[Index].Value, Record[Index].Instance, NULL, NULL ); } if (FeaturePcdGet (PcdStatusCodeUseMemory)) { RtMemoryStatusCodeReportWorker ( Record[Index].CodeType, Record[Index].Value, Record[Index].Instance, NULL, NULL ); } } } } }
EFI_STATUS EFIAPI VBoxVgaGraphicsOutputBlt ( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height, IN UINTN Delta ) /*++ Routine Description: Graphics Output protocol instance to block transfer for CirrusLogic device Arguments: This - Pointer to Graphics Output protocol instance BltBuffer - The data to transfer to screen BltOperation - The operation to perform SourceX - The X coordinate of the source for BltOperation SourceY - The Y coordinate of the source for BltOperation DestinationX - The X coordinate of the destination for BltOperation DestinationY - The Y coordinate of the destination for BltOperation Width - The width of a rectangle in the blt rectangle in pixels Height - The height of a rectangle in the blt rectangle in pixels Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation. If a Delta of 0 is used, the entire BltBuffer will be operated on. If a subrectangle of the BltBuffer is used, then Delta represents the number of bytes in a row of the BltBuffer. Returns: EFI_INVALID_PARAMETER - Invalid parameter passed in EFI_SUCCESS - Blt operation success --*/ { VBOX_VGA_PRIVATE_DATA *Private; EFI_TPL OriginalTPL; UINTN DstY; UINTN SrcY; UINT32 CurrentMode; UINTN ScreenWidth; UINTN ScreenHeight; EFI_STATUS Status; Private = VBOX_VGA_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); CurrentMode = This->Mode->Mode; ScreenWidth = Private->ModeData[CurrentMode].HorizontalResolution; ScreenHeight = Private->ModeData[CurrentMode].VerticalResolution; if ((BltOperation < 0) || (BltOperation >= EfiGraphicsOutputBltOperationMax)) { return EFI_INVALID_PARAMETER; } if (Width == 0 || Height == 0) { return EFI_INVALID_PARAMETER; } // // If Delta is zero, then the entire BltBuffer is being used, so Delta // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, // the number of bytes in each row can be computed. // if (Delta == 0) { Delta = Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL); } // code below assumes a Delta value in pixels, not bytes Delta /= sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL); // // Make sure the SourceX, SourceY, DestinationX, DestinationY, Width, and Height parameters // are valid for the operation and the current screen geometry. // if (BltOperation == EfiBltVideoToBltBuffer || BltOperation == EfiBltVideoToVideo) { if (SourceY + Height > ScreenHeight) { return EFI_INVALID_PARAMETER; } if (SourceX + Width > ScreenWidth) { return EFI_INVALID_PARAMETER; } } if (BltOperation == EfiBltBufferToVideo || BltOperation == EfiBltVideoToVideo || BltOperation == EfiBltVideoFill) { if (DestinationY + Height > ScreenHeight) { return EFI_INVALID_PARAMETER; } if (DestinationX + Width > ScreenWidth) { return EFI_INVALID_PARAMETER; } } // // We have to raise to TPL Notify, so we make an atomic write the frame buffer. // We would not want a timer based event (Cursor, ...) to come in while we are // doing this operation. // OriginalTPL = gBS->RaiseTPL (TPL_NOTIFY); switch (BltOperation) { case EfiBltVideoToBltBuffer: // // Video to BltBuffer: Source is Video, destination is BltBuffer // for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY) && BltBuffer; SrcY++, DstY++) { /// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL Status = Private->PciIo->Mem.Read ( Private->PciIo, EfiPciIoWidthUint32, Private->BarIndexFB, ((SrcY * ScreenWidth) + SourceX) * 4, Width, BltBuffer + (DstY * Delta) + DestinationX ); ASSERT_EFI_ERROR((Status)); } break; case EfiBltBufferToVideo: // // BltBuffer to Video: Source is BltBuffer, destination is Video // for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { /// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL Status = Private->PciIo->Mem.Write ( Private->PciIo, EfiPciIoWidthUint32, Private->BarIndexFB, ((DstY * ScreenWidth) + DestinationX) * 4, Width, BltBuffer + (SrcY * Delta) + SourceX ); ASSERT_EFI_ERROR((Status)); } break; case EfiBltVideoToVideo: // // Video to Video: Source is Video, destination is Video // if (DestinationY <= SourceY) { // forward copy for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { /// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL Status = Private->PciIo->CopyMem ( Private->PciIo, EfiPciIoWidthUint32, Private->BarIndexFB, ((DstY * ScreenWidth) + DestinationX) * 4, Private->BarIndexFB, ((SrcY * ScreenWidth) + SourceX) * 4, Width ); ASSERT_EFI_ERROR((Status)); } } else { // reverse copy for (SrcY = SourceY + Height - 1, DstY = DestinationY + Height - 1; SrcY >= SourceY && SrcY <= SourceY + Height - 1; SrcY--, DstY--) { /// @todo assumes that color depth is 32 (*4, EfiPciIoWidthUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL Status = Private->PciIo->CopyMem ( Private->PciIo, EfiPciIoWidthUint32, Private->BarIndexFB, ((DstY * ScreenWidth) + DestinationX) * 4, Private->BarIndexFB, ((SrcY * ScreenWidth) + SourceX) * 4, Width ); ASSERT_EFI_ERROR((Status)); } } break; case EfiBltVideoFill: // // Video Fill: Source is BltBuffer, destination is Video // if (DestinationX == 0 && Width == ScreenWidth) { /// @todo assumes that color depth is 32 (*4, EfiPciIoWidthFillUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL Status = Private->PciIo->Mem.Write ( Private->PciIo, EfiPciIoWidthFillUint32, Private->BarIndexFB, DestinationY * ScreenWidth * 4, (Width * Height), BltBuffer ); ASSERT_EFI_ERROR((Status)); } else { for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { /// @todo assumes that color depth is 32 (*4, EfiPciIoWidthFillUint32) and format matches EFI_GRAPHICS_OUTPUT_BLT_PIXEL Status = Private->PciIo->Mem.Write ( Private->PciIo, EfiPciIoWidthFillUint32, Private->BarIndexFB, ((DstY * ScreenWidth) + DestinationX) * 4, Width, BltBuffer ); ASSERT_EFI_ERROR((Status)); } } break; default: ASSERT (FALSE); } gBS->RestoreTPL (OriginalTPL); return EFI_SUCCESS; }
/** The module Entry Point of the Firmware Performance Data Table DXE driver. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval Other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI FirmwarePerformanceDxeEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HOB_GUID_TYPE *GuidHob; FIRMWARE_SEC_PERFORMANCE *Performance; // // Get Report Status Code Handler Protocol. // Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol); ASSERT_EFI_ERROR (Status); // // Register report status code listener for OS Loader load and start. // Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL); ASSERT_EFI_ERROR (Status); // // Register the notify function to update FPDT on ExitBootServices Event. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FpdtExitBootServicesEventNotify, NULL, &gEfiEventExitBootServicesGuid, &mExitBootServicesEvent ); ASSERT_EFI_ERROR (Status); // // Create ready to boot event to install ACPI FPDT table. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FpdtReadyToBootEventNotify, NULL, &gEfiEventReadyToBootGuid, &mReadyToBootEvent ); ASSERT_EFI_ERROR (Status); // // Create legacy boot event to log OsLoaderStartImageStart for legacy boot. // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FpdtLegacyBootEventNotify, NULL, &gEfiEventLegacyBootGuid, &mLegacyBootEvent ); ASSERT_EFI_ERROR (Status); // // Retrieve GUID HOB data that contains the ResetEnd. // GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid); if (GuidHob != NULL) { Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob); mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd; } else { // // SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0. // DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!n")); } return EFI_SUCCESS; }
/** Install ACPI Firmware Performance Data Table (FPDT). @return Status code. **/ EFI_STATUS InstallFirmwarePerformanceDataTable ( VOID ) { EFI_STATUS Status; EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; EFI_PHYSICAL_ADDRESS Address; UINTN Size; UINT8 SmmBootRecordCommBuffer[SMM_BOOT_RECORD_COMM_SIZE]; EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; SMM_BOOT_RECORD_COMMUNICATE *SmmCommData; UINTN CommSize; UINTN PerformanceRuntimeDataSize; UINT8 *PerformanceRuntimeData; UINT8 *PerformanceRuntimeDataHead; EFI_SMM_COMMUNICATION_PROTOCOL *Communication; FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable; // // Get AcpiTable Protocol. // Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol); if (EFI_ERROR (Status)) { return Status; } // // Collect boot records from SMM drivers. // SmmCommData = NULL; Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication); if (!EFI_ERROR (Status)) { // // Initialize communicate buffer // SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER*)SmmBootRecordCommBuffer; SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)SmmCommBufferHeader->Data; ZeroMem((UINT8*)SmmCommData, sizeof(SMM_BOOT_RECORD_COMMUNICATE)); CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gEfiFirmwarePerformanceGuid); SmmCommBufferHeader->MessageLength = sizeof(SMM_BOOT_RECORD_COMMUNICATE); CommSize = SMM_BOOT_RECORD_COMM_SIZE; // // Get the size of boot records. // SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE; SmmCommData->BootRecordData = NULL; Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); if (!EFI_ERROR (SmmCommData->ReturnStatus) && SmmCommData->BootRecordSize != 0) { // // Get all boot records // SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA; SmmCommData->BootRecordData = AllocateZeroPool(SmmCommData->BootRecordSize); ASSERT (SmmCommData->BootRecordData != NULL); Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize); ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(SmmCommData->ReturnStatus); } } // // Prepare memory for runtime Performance Record. // Runtime performance records includes two tables S3 performance table and Boot performance table. // S3 Performance table includes S3Resume and S3Suspend records. // Boot Performance table includes BasicBoot record, and one or more appended Boot Records. // PerformanceRuntimeData = NULL; PerformanceRuntimeDataSize = sizeof (S3_PERFORMANCE_TABLE) + sizeof (BOOT_PERFORMANCE_TABLE) + mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize); if (SmmCommData != NULL) { PerformanceRuntimeDataSize += SmmCommData->BootRecordSize; } // // Try to allocate the same runtime buffer as last time boot. // ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable)); Size = sizeof (PerformanceVariable); Status = gRT->GetVariable ( EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, &gEfiFirmwarePerformanceGuid, NULL, &Size, &PerformanceVariable ); if (!EFI_ERROR (Status)) { Address = PerformanceVariable.S3PerformanceTablePointer; Status = gBS->AllocatePages ( AllocateAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES (PerformanceRuntimeDataSize), &Address ); if (!EFI_ERROR (Status)) { PerformanceRuntimeData = (UINT8 *) (UINTN) Address; } } if (PerformanceRuntimeData == NULL) { // // Fail to allocate at specified address, continue to allocate at any address. // PerformanceRuntimeData = FpdtAllocateReservedMemoryBelow4G (PerformanceRuntimeDataSize); } DEBUG ((EFI_D_INFO, "FPDT: Performance Runtime Data address = 0x%xn", PerformanceRuntimeData)); if (PerformanceRuntimeData == NULL) { if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) { FreePool (SmmCommData->BootRecordData); } return EFI_OUT_OF_RESOURCES; } PerformanceRuntimeDataHead = PerformanceRuntimeData; if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) { // // Prepare S3 Performance Table. // mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) PerformanceRuntimeData; CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate)); PerformanceRuntimeData = PerformanceRuntimeData + mAcpiS3PerformanceTable->Header.Length; DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%xn", mAcpiS3PerformanceTable)); // // Save S3 Performance Table address to Variable for use in Firmware Performance PEIM. // PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable; // // Update S3 Performance Table Pointer in template. // mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) PerformanceVariable.S3PerformanceTablePointer; } else { // // Exclude S3 Performance Table Pointer from FPDT table template. // mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD); } // // Prepare Boot Performance Table. // mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) PerformanceRuntimeData; // // Fill Basic Boot record to Boot Performance Table. // CopyMem (PerformanceRuntimeData, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate)); PerformanceRuntimeData = PerformanceRuntimeData + mAcpiBootPerformanceTable->Header.Length; // // Fill Boot records from boot drivers. // CopyMem (PerformanceRuntimeData, mBootRecordBuffer, mBootRecordSize); mAcpiBootPerformanceTable->Header.Length += mBootRecordSize; PerformanceRuntimeData = PerformanceRuntimeData + mBootRecordSize; if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) { // // Fill Boot records from SMM drivers. // CopyMem (PerformanceRuntimeData, SmmCommData->BootRecordData, SmmCommData->BootRecordSize); FreePool (SmmCommData->BootRecordData); mAcpiBootPerformanceTable->Header.Length = (UINT32) (mAcpiBootPerformanceTable->Header.Length + SmmCommData->BootRecordSize); PerformanceRuntimeData = PerformanceRuntimeData + SmmCommData->BootRecordSize; } // // Reserve space for boot records after ReadyToBoot. // PerformanceRuntimeData = PerformanceRuntimeData + PcdGet32 (PcdExtFpdtBootRecordPadSize); DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%xn", mAcpiBootPerformanceTable)); // // Save Boot Performance Table address to Variable for use in S4 resume. // PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable; // // Update Boot Performance Table Pointer in template. // mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable; // // Save Runtime Performance Table pointers to Variable. // Status = gRT->SetVariable ( EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, &gEfiFirmwarePerformanceGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof (PerformanceVariable), &PerformanceVariable ); ASSERT_EFI_ERROR (Status); // // Publish Firmware Performance Data Table. // FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length); Status = AcpiTableProtocol->InstallAcpiTable ( AcpiTableProtocol, &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length, &mFirmwarePerformanceTableTemplateKey ); if (EFI_ERROR (Status)) { FreePool (PerformanceRuntimeDataHead); mAcpiBootPerformanceTable = NULL; mAcpiS3PerformanceTable = NULL; return Status; } // // Free temp Boot record, and update Boot Record to point to Basic Boot performance table. // if (mBootRecordBuffer != NULL) { FreePool (mBootRecordBuffer); } mBootRecordBuffer = (UINT8 *) mAcpiBootPerformanceTable; mBootRecordSize = mAcpiBootPerformanceTable->Header.Length; mBootRecordMaxSize = mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize); return EFI_SUCCESS; }
/** Variable Driver main entry point. The Variable driver places the 4 EFI runtime services in the EFI System Table and installs arch protocols for variable read and write services being availible. It also registers a notification function for an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS Variable service successfully initialized. **/ EFI_STATUS EFIAPI VariableServiceInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT ReadyToBootEvent; Status = VariableCommonInitialize (); ASSERT_EFI_ERROR (Status); SystemTable->RuntimeServices->GetVariable = VariableServiceGetVariable; SystemTable->RuntimeServices->GetNextVariableName = VariableServiceGetNextVariableName; SystemTable->RuntimeServices->SetVariable = VariableServiceSetVariable; SystemTable->RuntimeServices->QueryVariableInfo = VariableServiceQueryVariableInfo; // // Now install the Variable Runtime Architectural protocol on a new handle. // Status = gBS->InstallProtocolInterface ( &mHandle, &gEfiVariableArchProtocolGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); // // Register FtwNotificationEvent () notify function. // EfiCreateProtocolNotifyEvent ( &gEfiFaultTolerantWriteProtocolGuid, TPL_CALLBACK, FtwNotificationEvent, (VOID *)SystemTable, &mFtwRegistration ); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, VariableClassAddressChangeEvent, NULL, &gEfiEventVirtualAddressChangeGuid, &mVirtualAddressChangeEvent ); ASSERT_EFI_ERROR (Status); // // Register the event handling function to reclaim variable for OS usage. // Status = EfiCreateEventReadyToBootEx ( TPL_NOTIFY, OnReadyToBoot, NULL, &ReadyToBootEvent ); return EFI_SUCCESS; }
/** Function to read a single line (up to but not including the n) from a file. If the position upon start is 0, then the Ascii Boolean will be set. This should be maintained and not changed for all operations with the same file. The function will not return the r and n character in buffer. When an empty line is read a CHAR_NULL character will be returned in buffer. @param[in] Handle FileHandle to read from. @param[in, out] Buffer The pointer to buffer to read into. @param[in, out] Size The pointer to number of bytes in Buffer. @param[in] Truncate If the buffer is large enough, this has no effect. If the buffer is is too small and Truncate is TRUE, the line will be truncated. If the buffer is is too small and Truncate is FALSE, then no read will occur. @param[in, out] Ascii Boolean value for indicating whether the file is Ascii (TRUE) or UCS2 (FALSE). @retval EFI_SUCCESS The operation was successful. The line is stored in Buffer. @retval EFI_INVALID_PARAMETER Handle was NULL. @retval EFI_INVALID_PARAMETER Size was NULL. @retval EFI_BUFFER_TOO_SMALL Size was not large enough to store the line. Size was updated to the minimum space required. @sa FileHandleRead **/ EFI_STATUS EFIAPI FileHandleReadLine( IN EFI_FILE_HANDLE Handle, IN OUT CHAR16 *Buffer, IN OUT UINTN *Size, IN BOOLEAN Truncate, IN OUT BOOLEAN *Ascii ) { EFI_STATUS Status; CHAR16 CharBuffer; UINT64 FileSize; UINTN CharSize; UINTN CountSoFar; UINTN CrCount; UINT64 OriginalFilePosition; if (Handle == NULL ||Size == NULL ||(Buffer==NULL&&*Size!=0) ){ return (EFI_INVALID_PARAMETER); } if (Buffer != NULL && *Size != 0) { *Buffer = CHAR_NULL; } Status = FileHandleGetSize (Handle, &FileSize); if (EFI_ERROR (Status)) { return Status; } else if (FileSize == 0) { *Ascii = TRUE; return EFI_SUCCESS; } FileHandleGetPosition(Handle, &OriginalFilePosition); if (OriginalFilePosition == 0) { CharSize = sizeof(CHAR16); Status = FileHandleRead(Handle, &CharSize, &CharBuffer); ASSERT_EFI_ERROR(Status); if (CharBuffer == gUnicodeFileTag) { *Ascii = FALSE; } else { *Ascii = TRUE; FileHandleSetPosition(Handle, OriginalFilePosition); } } CrCount = 0; for (CountSoFar = 0;;CountSoFar++){ CharBuffer = 0; if (*Ascii) { CharSize = sizeof(CHAR8); } else { CharSize = sizeof(CHAR16); } Status = FileHandleRead(Handle, &CharSize, &CharBuffer); if ( EFI_ERROR(Status) || CharSize == 0 || (CharBuffer == L'n' && !(*Ascii)) || (CharBuffer == 'n' && *Ascii) ){ break; } else if ( (CharBuffer == L'r' && !(*Ascii)) || (CharBuffer == 'r' && *Ascii) ) { CrCount++; continue; } // // if we have space save it... // if ((CountSoFar+1-CrCount)*sizeof(CHAR16) < *Size){ ASSERT(Buffer != NULL); ((CHAR16*)Buffer)[CountSoFar-CrCount] = CharBuffer; ((CHAR16*)Buffer)[CountSoFar+1-CrCount] = CHAR_NULL; } } // // if we ran out of space tell when... // if ((CountSoFar+1-CrCount)*sizeof(CHAR16) > *Size){ *Size = (CountSoFar+1-CrCount)*sizeof(CHAR16); if (!Truncate) { if (Buffer != NULL && *Size != 0) { ZeroMem(Buffer, *Size); } FileHandleSetPosition(Handle, OriginalFilePosition); return (EFI_BUFFER_TOO_SMALL); } else { DEBUG((DEBUG_WARN, "The line was truncated in FileHandleReadLine")); return (EFI_SUCCESS); } } return (Status); }
/** This function attempts to boot for the boot order specified by platform policy. **/ VOID BdsBootDeviceSelect ( VOID ) { EFI_STATUS Status; LIST_ENTRY *Link; BDS_COMMON_OPTION *BootOption; UINTN ExitDataSize; CHAR16 *ExitData; UINT16 Timeout; LIST_ENTRY BootLists; CHAR16 Buffer[20]; BOOLEAN BootNextExist; LIST_ENTRY *LinkBootNext; EFI_EVENT ConnectConInEvent; // // Got the latest boot option // BootNextExist = FALSE; LinkBootNext = NULL; ConnectConInEvent = NULL; InitializeListHead (&BootLists); // // First check the boot next option // ZeroMem (Buffer, sizeof (Buffer)); // // Create Event to signal ConIn connection request // if (PcdGetBool (PcdConInConnectOnDemand)) { Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, BdsEmptyCallbackFunction, NULL, &gConnectConInEventGuid, &ConnectConInEvent ); if (EFI_ERROR(Status)) { ConnectConInEvent = NULL; } } if (mBootNext != NULL) { // // Indicate we have the boot next variable, so this time // boot will always have this boot option // BootNextExist = TRUE; // // Clear the this variable so it's only exist in this time boot // Status = gRT->SetVariable ( L"BootNext", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, 0, NULL ); // // Deleting variable with current variable implementation shouldn't fail. // ASSERT_EFI_ERROR (Status); // // Add the boot next boot option // UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *mBootNext); BootOption = BdsLibVariableToOption (&BootLists, Buffer); // // If fail to get boot option from variable, just return and do nothing. // if (BootOption == NULL) { return; } BootOption->BootCurrent = *mBootNext; } // // Parse the boot order to get boot option // BdsLibBuildOptionFromVar (&BootLists, L"BootOrder"); // // When we didn't have chance to build boot option variables in the first // full configuration boot (e.g.: Reset in the first page or in Device Manager), // we have no boot options in the following mini configuration boot. // Give the last chance to enumerate the boot options. // if (IsListEmpty (&BootLists)) { BdsLibEnumerateAllBootOption (&BootLists); } Link = BootLists.ForwardLink; // // Parameter check, make sure the loop will be valid // if (Link == NULL) { return ; } // // Here we make the boot in a loop, every boot success will // return to the front page // for (;;) { // // Check the boot option list first // if (Link == &BootLists) { // // When LazyConIn enabled, signal connect ConIn event before enter UI // if (PcdGetBool (PcdConInConnectOnDemand) && ConnectConInEvent != NULL) { gBS->SignalEvent (ConnectConInEvent); } // // There are two ways to enter here: // 1. There is no active boot option, give user chance to // add new boot option // 2. All the active boot option processed, and there is no // one is success to boot, then we back here to allow user // add new active boot option // Timeout = 0xffff; PlatformBdsEnterFrontPage (Timeout, FALSE); InitializeListHead (&BootLists); BdsLibBuildOptionFromVar (&BootLists, L"BootOrder"); Link = BootLists.ForwardLink; continue; } // // Get the boot option from the link list // BootOption = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); // // According to EFI Specification, if a load option is not marked // as LOAD_OPTION_ACTIVE, the boot manager will not automatically // load the option. // if (!IS_LOAD_OPTION_TYPE (BootOption->Attribute, LOAD_OPTION_ACTIVE)) { // // skip the header of the link list, because it has no boot option // Link = Link->ForwardLink; continue; } // // Make sure the boot option device path connected, // but ignore the BBS device path // if (DevicePathType (BootOption->DevicePath) != BBS_DEVICE_PATH) { // // Notes: the internal shell can not been connected with device path // so we do not check the status here // BdsLibConnectDevicePath (BootOption->DevicePath); } // // Restore to original mode before launching boot option. // // BdsSetConsoleMode (FALSE); // // All the driver options should have been processed since // now boot will be performed. // Status = BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData); if (Status != EFI_SUCCESS) { // // Call platform action to indicate the boot fail // BootOption->StatusString = NULL; //GetStringById (STRING_TOKEN (STR_BOOT_FAILED)); //PlatformBdsBootFail (BootOption, Status, ExitData, ExitDataSize); // // Check the next boot option // Link = Link->ForwardLink; } else { // // Call platform action to indicate the boot success // BootOption->StatusString = GetStringById (STRING_TOKEN (STR_BOOT_SUCCEEDED)); PlatformBdsBootSuccess (BootOption); // // Boot success, then stop process the boot order, and // present the boot manager menu, front page // // // When LazyConIn enabled, signal connect ConIn Event before enter UI // if (PcdGetBool (PcdConInConnectOnDemand) && ConnectConInEvent != NULL) { gBS->SignalEvent (ConnectConInEvent); } Timeout = 0xffff; PlatformBdsEnterFrontPage (Timeout, FALSE); // // Rescan the boot option list, avoid potential risk of the boot // option change in front page // if (BootNextExist) { LinkBootNext = BootLists.ForwardLink; } InitializeListHead (&BootLists); if (LinkBootNext != NULL) { // // Reserve the boot next option // InsertTailList (&BootLists, LinkBootNext); } BdsLibBuildOptionFromVar (&BootLists, L"BootOrder"); Link = BootLists.ForwardLink; } } }
/** Provides the DMA controller-specific addresses needed to access system memory. Operation is relative to the DMA bus master. @param Operation Indicates if the bus master is going to read or write to system memory. @param HostAddress The system memory address to map to the DMA controller. @param NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped. @param DeviceAddress The resulting map address for the bus master controller to use to access the hosts HostAddress. @param Mapping A resulting value to pass to Unmap(). @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. **/ EFI_STATUS EFIAPI DmaMap ( IN DMA_MAP_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping ) { EFI_STATUS Status; MAP_INFO_INSTANCE *Map; VOID *Buffer; EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL ) { return EFI_INVALID_PARAMETER; } if (Operation >= MapOperationMaximum) { return EFI_INVALID_PARAMETER; } // // The debug implementation of UncachedMemoryAllocationLib in ArmPkg returns // a virtual uncached alias, and unmaps the cached ID mapping of the buffer, // in order to catch inadvertent references to the cached mapping. // Since HostToDeviceAddress () expects ID mapped input addresses, convert // the host address to an ID mapped address first. // *DeviceAddress = HostToDeviceAddress (ConvertToPhysicalAddress (HostAddress)); // Remember range so we can flush on the other side Map = AllocatePool (sizeof (MAP_INFO_INSTANCE)); if (Map == NULL) { return EFI_OUT_OF_RESOURCES; } if ((((UINTN)HostAddress & (mCpu->DmaBufferAlignment - 1)) != 0) || ((*NumberOfBytes & (mCpu->DmaBufferAlignment - 1)) != 0)) { // Get the cacheability of the region Status = gDS->GetMemorySpaceDescriptor ((UINTN)HostAddress, &GcdDescriptor); if (EFI_ERROR(Status)) { goto FreeMapInfo; } // If the mapped buffer is not an uncached buffer if ((GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) != 0) { // // Operations of type MapOperationBusMasterCommonBuffer are only allowed // on uncached buffers. // if (Operation == MapOperationBusMasterCommonBuffer) { DEBUG ((EFI_D_ERROR, "%a: Operation type 'MapOperationBusMasterCommonBuffer' is only supportedn" "on memory regions that were allocated using DmaAllocateBuffer ()n", __FUNCTION__)); Status = EFI_UNSUPPORTED; goto FreeMapInfo; } // // If the buffer does not fill entire cache lines we must double buffer into // uncached memory. Device (PCI) address becomes uncached page. // Map->DoubleBuffer = TRUE; Status = DmaAllocateBuffer (EfiBootServicesData, EFI_SIZE_TO_PAGES (*NumberOfBytes), &Buffer); if (EFI_ERROR (Status)) { goto FreeMapInfo; } if (Operation == MapOperationBusMasterRead) { CopyMem (Buffer, HostAddress, *NumberOfBytes); } *DeviceAddress = HostToDeviceAddress (ConvertToPhysicalAddress (Buffer)); Map->BufferAddress = Buffer; } else { Map->DoubleBuffer = FALSE; } } else { Map->DoubleBuffer = FALSE; DEBUG_CODE_BEGIN (); // // The operation type check above only executes if the buffer happens to be // misaligned with respect to CWG, but even if it is aligned, we should not // allow arbitrary buffers to be used for creating consistent mappings. // So duplicate the check here when running in DEBUG mode, just to assert // that we are not trying to create a consistent mapping for cached memory. // Status = gDS->GetMemorySpaceDescriptor ((UINTN)HostAddress, &GcdDescriptor); ASSERT_EFI_ERROR(Status); ASSERT (Operation != MapOperationBusMasterCommonBuffer || (GcdDescriptor.Attributes & (EFI_MEMORY_WB | EFI_MEMORY_WT)) == 0); DEBUG_CODE_END (); // Flush the Data Cache (should not have any effect if the memory region is uncached) mCpu->FlushDataCache (mCpu, (UINTN)HostAddress, *NumberOfBytes, EfiCpuFlushTypeWriteBackInvalidate); } Map->HostAddress = (UINTN)HostAddress; Map->NumberOfBytes = *NumberOfBytes; Map->Operation = Operation; *Mapping = Map; return EFI_SUCCESS; FreeMapInfo: FreePool (Map); return Status; }
VOID Flash_Start_OS ( ) { UINT32 Index = 0; UINTN FDTConfigTable = 0; EFI_STATUS Status; ESL_LINUX LinuxKernel = (ESL_LINUX)(0x80000); if (!PcdGet32(PcdIsMPBoot)) { for (Index = 0; Index < gST->NumberOfTableEntries; Index ++) { if (CompareGuid (&gFdtTableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) { FDTConfigTable = (UINTN)gST->ConfigurationTable[Index].VendorTable; DEBUG ((EFI_D_ERROR, "FDTConfigTable Address: 0x%lxn",FDTConfigTable)); break; } } gBS->CopyMem((void *)0x6000000,(void *)FDTConfigTable,0x100000); MicroSecondDelay(20000); gBS->CopyMem((void *)LinuxKernel,(void *)0x90100000,0x1F00000); MicroSecondDelay(200000); gBS->CopyMem((void *)0x7000000,(void *)0x92000000,0x4000000); MicroSecondDelay(200000); DEBUG((EFI_D_ERROR,"Update FDTn")); Status = EFIFdtUpdate(0x06000000); if(EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR,"EFIFdtUpdate ERRORn")); goto Exit; } } else { Status = LzmaDecompressKernel (LinuxKernel); if(EFI_ERROR(Status)) { goto Exit; } gBS->CopyMem((void *)0x6000000, (void *)0xA47C0000, 0x20000); MicroSecondDelay(20000); gBS->CopyMem((void *)0x7000000, (void *)0xA4000000, 0x7C0000); MicroSecondDelay(200000); } Status = ShutdownUefiBootServices (); if(EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%Xn", Status)); goto Exit; } // // Switch off interrupts, caches, mmu, etc // Status = PreparePlatformHardware (); ASSERT_EFI_ERROR(Status); LinuxKernel (0x06000000,0,0,0); // Kernel should never exit // After Life services are not provided ASSERT(FALSE); Exit: // Only be here if we fail to start Linux Print (L"ERROR : Can not start the kernel. Status=0x%Xn", Status); // Free Runtimee Memory (kernel and FDT) return ; }
/** Function for 'drivers' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunDrivers ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; CHAR8 *Language; CONST CHAR16 *Lang; EFI_HANDLE *HandleList; EFI_HANDLE *HandleWalker; UINTN ChildCount; UINTN DeviceCount; CHAR16 *Temp2; CONST CHAR16 *FullDriverName; CHAR16 *TruncatedDriverName; CHAR16 *FormatString; UINT32 DriverVersion; BOOLEAN DriverConfig; BOOLEAN DriverDiag; BOOLEAN SfoFlag; ShellStatus = SHELL_SUCCESS; Status = EFI_SUCCESS; Language = NULL; FormatString = NULL; SfoFlag = FALSE; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); Status = CommandInit(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDriver1HiiHandle, L"drivers", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { if (ShellCommandLineGetCount(Package) > 1) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDriver1HiiHandle, L"drivers"); ShellStatus = SHELL_INVALID_PARAMETER; } else { if (ShellCommandLineGetFlag(Package, L"-l")){ Lang = ShellCommandLineGetValue(Package, L"-l"); if (Lang != NULL) { Language = AllocateZeroPool(StrSize(Lang)); AsciiSPrint(Language, StrSize(Lang), "%S", Lang); } else { ASSERT(Language == NULL); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDriver1HiiHandle, L"drivers", L"-l"); ShellCommandLineFreeVarList (Package); return (SHELL_INVALID_PARAMETER); } } if (ShellCommandLineGetFlag (Package, L"-sfo")) { SfoFlag = TRUE; FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE_SFO), Language); // // print the SFO header // ShellPrintHiiEx ( -1, -1, Language, STRING_TOKEN (STR_GEN_SFO_HEADER), gShellDriver1HiiHandle, L"drivers"); } else { FormatString = HiiGetString (gShellDriver1HiiHandle, STRING_TOKEN (STR_DRIVERS_ITEM_LINE), Language); // // print the header row // ShellPrintHiiEx( -1, -1, Language, STRING_TOKEN (STR_DRIVERS_HEADER_LINES), gShellDriver1HiiHandle); } HandleList = GetHandleListByProtocol(&gEfiDriverBindingProtocolGuid); for (HandleWalker = HandleList ; HandleWalker != NULL && *HandleWalker != NULL ; HandleWalker++){ ChildCount = 0; DeviceCount = 0; Status = ParseHandleDatabaseForChildDevices (*HandleWalker, &ChildCount , NULL); Status = PARSE_HANDLE_DATABASE_DEVICES (*HandleWalker, &DeviceCount, NULL); Temp2 = GetDevicePathTextForHandle(*HandleWalker); DriverVersion = ReturnDriverVersion(*HandleWalker); DriverConfig = ReturnDriverConfig(*HandleWalker); DriverDiag = ReturnDriverDiag (*HandleWalker); FullDriverName = GetStringNameFromHandle(*HandleWalker, Language); TruncatedDriverName = NULL; if (!SfoFlag && (FullDriverName != NULL)) { TruncatedDriverName = AllocateZeroPool ((MAX_LEN_DRIVER_NAME + 1) * sizeof (CHAR16)); StrnCpyS (TruncatedDriverName, MAX_LEN_DRIVER_NAME + 1, FullDriverName, MAX_LEN_DRIVER_NAME); } ShellPrintEx( -1, -1, FormatString, ConvertHandleToHandleIndex(*HandleWalker), DriverVersion, ChildCount > 0?L'B':(DeviceCount > 0?L'D':L'?'), DriverConfig?L'Y':L'N', DriverDiag?L'Y':L'N', DeviceCount, ChildCount, SfoFlag?FullDriverName:TruncatedDriverName, Temp2==NULL?L"":Temp2 ); if (TruncatedDriverName != NULL) { FreePool (TruncatedDriverName); } if (Temp2 != NULL) { FreePool(Temp2); } if (ShellGetExecutionBreakFlag ()) { ShellStatus = SHELL_ABORTED; break; } } } SHELL_FREE_NON_NULL(Language); ShellCommandLineFreeVarList (Package); SHELL_FREE_NON_NULL(FormatString); } return (ShellStatus); }
VOID ESL_Start_OS ( ) { EFI_STATUS Status; UINTN Reg_Value; ESL_LINUX LinuxKernel = (ESL_LINUX)(0x80000); if(!PcdGet32(PcdIsMPBoot)) { DEBUG((EFI_D_ERROR,"Update FDTn")); Status = EFIFdtUpdate(0x06000000); if(EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR,"EFIFdtUpdate ERRORn")); goto Exit; } } DEBUG((EFI_D_ERROR, "[%a]:[%dL] Start to boot Linuxn", __FUNCTION__, __LINE__)); SmmuConfigForLinux(); ITSCONFIG(); if(PcdGet32(PcdIsMPBoot)) { *(volatile UINT32 *)(0x60016220) = 0x7; *(volatile UINT32 *)(0x60016230) = 0x40016260; *(volatile UINT32 *)(0x60016234) = 0X0; *(volatile UINT32 *)(0x60016238) = 0x60016260; *(volatile UINT32 *)(0x6001623C) = 0x400; *(volatile UINT32 *)(0x60016240) = 0x40016260; *(volatile UINT32 *)(0x60016244) = 0x400; *(volatile UINT32 *)(0x40016220) = 0x7; *(volatile UINT32 *)(0x40016230) = 0x60016260; *(volatile UINT32 *)(0x40016234) = 0X0; *(volatile UINT32 *)(0x40016238) = 0x60016260; *(volatile UINT32 *)(0x4001623C) = 0x400; *(volatile UINT32 *)(0x40016240) = 0x40016260; *(volatile UINT32 *)(0x40016244) = 0x400; *(volatile UINT32 *)(0x60016220 + S1_BASE) = 0x7; *(volatile UINT32 *)(0x60016230 + S1_BASE) = 0x40016260; *(volatile UINT32 *)(0x60016234 + S1_BASE) = 0X0; *(volatile UINT32 *)(0x60016238 + S1_BASE) = 0x60016260; *(volatile UINT32 *)(0x6001623C + S1_BASE) = 0x0; *(volatile UINT32 *)(0x60016240 + S1_BASE) = 0x40016260; *(volatile UINT32 *)(0x60016244 + S1_BASE) = 0x400; *(volatile UINT32 *)(0x40016220 + S1_BASE) = 0x7; *(volatile UINT32 *)(0x40016230 + S1_BASE) = 0x60016260; *(volatile UINT32 *)(0x40016234 + S1_BASE) = 0X0; *(volatile UINT32 *)(0x40016238 + S1_BASE) = 0x60016260; *(volatile UINT32 *)(0x4001623C + S1_BASE) = 0x400; *(volatile UINT32 *)(0x40016240 + S1_BASE) = 0x40016260; *(volatile UINT32 *)(0x40016244 + S1_BASE) = 0x0; } Status = ShutdownUefiBootServices (); if(EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR,"ERROR: Can not shutdown UEFI boot services. Status=0x%Xn", Status)); goto Exit; } // // Switch off interrupts, caches, mmu, etc // Status = PreparePlatformHardware (); ASSERT_EFI_ERROR(Status); *(volatile UINT32*)0xFFF8 = 0x0; *(volatile UINT32*)0xFFFC = 0x0; asm("DSB SY"); asm("ISB"); if (!PcdGet64 (PcdTrustedFirmwareEnable)) { StartupAp(); } Reg_Value = asm_read_reg(); DEBUG((EFI_D_ERROR,"CPUECTLR_EL1 = 0x%llxn",Reg_Value)); MN_CONFIG (); DEBUG((EFI_D_ERROR, "[%a]:[%dL] Start to jump Linux kerneln", __FUNCTION__, __LINE__)); LinuxKernel (0x06000000,0,0,0); // Kernel should never exit // After Life services are not provided ASSERT(FALSE); Exit: // Only be here if we fail to start Linux Print (L"ERROR : Can not start the kernel. Status=0x%Xn", Status); // Free Runtimee Memory (kernel and FDT) return ; }
/** Function for 'tftp' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). @return SHELL_SUCCESS The 'tftp' command completed successfully. @return SHELL_ABORTED The Shell Library initialization failed. @return SHELL_INVALID_PARAMETER At least one of the command's arguments is not valid. @return SHELL_OUT_OF_RESOURCES A memory allocation failed. @return SHELL_NOT_FOUND Network Interface Card not found or server error or file error. **/ SHELL_STATUS EFIAPI ShellCommandRunTftp ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { SHELL_STATUS ShellStatus; EFI_STATUS Status; LIST_ENTRY *CheckPackage; CHAR16 *ProblemParam; UINTN ParamCount; CONST CHAR16 *UserNicName; BOOLEAN NicFound; CONST CHAR16 *ValueStr; CONST CHAR16 *RemoteFilePath; CHAR8 *AsciiRemoteFilePath; UINTN FilePathSize; CONST CHAR16 *Walker; CONST CHAR16 *LocalFilePath; EFI_MTFTP4_CONFIG_DATA Mtftp4ConfigData; EFI_HANDLE *Handles; UINTN HandleCount; UINTN NicNumber; CHAR16 NicName[IP4_CONFIG2_INTERFACE_INFO_NAME_LENGTH]; EFI_HANDLE ControllerHandle; EFI_HANDLE Mtftp4ChildHandle; EFI_MTFTP4_PROTOCOL *Mtftp4; UINTN FileSize; VOID *Data; SHELL_FILE_HANDLE FileHandle; UINT16 BlockSize; ShellStatus = SHELL_INVALID_PARAMETER; ProblemParam = NULL; NicFound = FALSE; AsciiRemoteFilePath = NULL; Handles = NULL; FileSize = 0; BlockSize = MTFTP_DEFAULT_BLKSIZE; // // Initialize the Shell library (we must be in non-auto-init...) // Status = ShellInitialize (); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return SHELL_ABORTED; } // // Parse the command line. // Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); if (EFI_ERROR (Status)) { if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL) ) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellTftpHiiHandle, L"tftp", ProblemParam ); FreePool (ProblemParam); } else { ASSERT (FALSE); } goto Error; } // // Check the number of parameters // ParamCount = ShellCommandLineGetCount (CheckPackage); if (ParamCount > 4) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellTftpHiiHandle, L"tftp" ); goto Error; } if (ParamCount < 3) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellTftpHiiHandle, L"tftp" ); goto Error; } Mtftp4ConfigData = DefaultMtftp4ConfigData; // // Check the host IPv4 address // ValueStr = ShellCommandLineGetRawValue (CheckPackage, 1); Status = NetLibStrToIp4 (ValueStr, &Mtftp4ConfigData.ServerIp); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } RemoteFilePath = ShellCommandLineGetRawValue (CheckPackage, 2); ASSERT(RemoteFilePath != NULL); FilePathSize = StrLen (RemoteFilePath) + 1; AsciiRemoteFilePath = AllocatePool (FilePathSize); if (AsciiRemoteFilePath == NULL) { ShellStatus = SHELL_OUT_OF_RESOURCES; goto Error; } UnicodeStrToAsciiStrS (RemoteFilePath, AsciiRemoteFilePath, FilePathSize); if (ParamCount == 4) { LocalFilePath = ShellCommandLineGetRawValue (CheckPackage, 3); } else { Walker = RemoteFilePath + StrLen (RemoteFilePath); while ((--Walker) >= RemoteFilePath) { if ((*Walker == L'\') || (*Walker == L'/' ) ) { break; } } LocalFilePath = Walker + 1; } // // Get the name of the Network Interface Card to be used if any. // UserNicName = ShellCommandLineGetValue (CheckPackage, L"-i"); ValueStr = ShellCommandLineGetValue (CheckPackage, L"-l"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.LocalPort)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-r"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.InitialServerPort)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-c"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TryCount)) { goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-t"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &Mtftp4ConfigData.TimeoutValue)) { goto Error; } if (Mtftp4ConfigData.TimeoutValue == 0) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } } ValueStr = ShellCommandLineGetValue (CheckPackage, L"-s"); if (ValueStr != NULL) { if (!StringToUint16 (ValueStr, &BlockSize)) { goto Error; } if (BlockSize < MTFTP_MIN_BLKSIZE || BlockSize > MTFTP_MAX_BLKSIZE) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellTftpHiiHandle, L"tftp", ValueStr ); goto Error; } } // // Locate all MTFTP4 Service Binding protocols // ShellStatus = SHELL_NOT_FOUND; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiManagedNetworkServiceBindingProtocolGuid, NULL, &HandleCount, &Handles ); if (EFI_ERROR (Status) || (HandleCount == 0)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NO_NIC), gShellTftpHiiHandle ); goto Error; } for (NicNumber = 0; (NicNumber < HandleCount) && (ShellStatus != SHELL_SUCCESS); NicNumber++) { ControllerHandle = Handles[NicNumber]; Data = NULL; Status = GetNicName (ControllerHandle, NicNumber, NicName); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NAME), gShellTftpHiiHandle, NicNumber, Status ); continue; } if (UserNicName != NULL) { if (StrCmp (NicName, UserNicName) != 0) { continue; } NicFound = TRUE; } Status = CreateServiceChildAndOpenProtocol ( ControllerHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &gEfiMtftp4ProtocolGuid, &Mtftp4ChildHandle, (VOID**)&Mtftp4 ); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_OPEN_PROTOCOL), gShellTftpHiiHandle, NicName, Status ); continue; } Status = Mtftp4->Configure (Mtftp4, &Mtftp4ConfigData); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_CONFIGURE), gShellTftpHiiHandle, NicName, Status ); goto NextHandle; } Status = GetFileSize (Mtftp4, AsciiRemoteFilePath, &FileSize); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_FILE_SIZE), gShellTftpHiiHandle, RemoteFilePath, NicName, Status ); goto NextHandle; } Status = DownloadFile (Mtftp4, RemoteFilePath, AsciiRemoteFilePath, FileSize, BlockSize, &Data); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_DOWNLOAD), gShellTftpHiiHandle, RemoteFilePath, NicName, Status ); goto NextHandle; } if (!EFI_ERROR (ShellFileExists (LocalFilePath))) { ShellDeleteFileByName (LocalFilePath); } Status = ShellOpenFileByName ( LocalFilePath, &FileHandle, EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, 0 ); if (EFI_ERROR (Status)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellTftpHiiHandle, L"tftp", LocalFilePath ); goto NextHandle; } Status = ShellWriteFile (FileHandle, &FileSize, Data); if (!EFI_ERROR (Status)) { ShellStatus = SHELL_SUCCESS; } else { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_WRITE), gShellTftpHiiHandle, LocalFilePath, Status ); } ShellCloseFile (&FileHandle); NextHandle: if (Data != NULL) { gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)Data, EFI_SIZE_TO_PAGES (FileSize)); } CloseProtocolAndDestroyServiceChild ( ControllerHandle, &gEfiMtftp4ServiceBindingProtocolGuid, &gEfiMtftp4ProtocolGuid, Mtftp4ChildHandle ); } if ((UserNicName != NULL) && (!NicFound)) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_TFTP_ERR_NIC_NOT_FOUND), gShellTftpHiiHandle, UserNicName ); } Error: ShellCommandLineFreeVarList (CheckPackage); if (AsciiRemoteFilePath != NULL) { FreePool (AsciiRemoteFilePath); } if (Handles != NULL) { FreePool (Handles); } return ShellStatus; }
/** Function for 'attrib' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunAttrib ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { UINT64 FileAttributesToAdd; UINT64 FileAttributesToRemove; EFI_STATUS Status; LIST_ENTRY *Package; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; UINTN ParamNumberCount; CONST CHAR16 *FileName; EFI_SHELL_FILE_INFO *ListOfFiles; EFI_SHELL_FILE_INFO *FileNode; EFI_FILE_INFO *FileInfo; ListOfFiles = NULL; ShellStatus = SHELL_SUCCESS; ProblemParam = NULL; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); ASSERT_EFI_ERROR(Status); // // parse the command line // Status = ShellCommandLineParse (AttribParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"attrib", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } else { ASSERT(FALSE); } } else { // // check for "-?" // if (ShellCommandLineGetFlag(Package, L"-?")) { ASSERT(FALSE); } else { FileAttributesToAdd = 0; FileAttributesToRemove = 0; // // apply or remove each flag // if (ShellCommandLineGetFlag(Package, L"+a")) { FileAttributesToAdd |= EFI_FILE_ARCHIVE; } if (ShellCommandLineGetFlag(Package, L"-a")) { FileAttributesToRemove |= EFI_FILE_ARCHIVE; } if (ShellCommandLineGetFlag(Package, L"+s")) { FileAttributesToAdd |= EFI_FILE_SYSTEM; } if (ShellCommandLineGetFlag(Package, L"-s")) { FileAttributesToRemove |= EFI_FILE_SYSTEM; } if (ShellCommandLineGetFlag(Package, L"+h")) { FileAttributesToAdd |= EFI_FILE_HIDDEN; } if (ShellCommandLineGetFlag(Package, L"-h")) { FileAttributesToRemove |= EFI_FILE_HIDDEN; } if (ShellCommandLineGetFlag(Package, L"+r")) { FileAttributesToAdd |= EFI_FILE_READ_ONLY; } if (ShellCommandLineGetFlag(Package, L"-r")) { FileAttributesToRemove |= EFI_FILE_READ_ONLY; } if (FileAttributesToRemove == 0 && FileAttributesToAdd == 0) { // // Do display as we have no attributes to change // for ( ParamNumberCount = 1 ; ; ParamNumberCount++ ){ FileName = ShellCommandLineGetRawValue(Package, ParamNumberCount); // if we dont have anything left, move on... if (FileName == NULL && ParamNumberCount == 1) { FileName = (CHAR16*)AllFiles; } else if (FileName == NULL) { break; } ASSERT(ListOfFiles == NULL); Status = ShellOpenFileMetaArg((CHAR16*)FileName, EFI_FILE_MODE_READ, &ListOfFiles); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount)); ShellStatus = SHELL_NOT_FOUND; } else { for (FileNode = (EFI_SHELL_FILE_INFO*)GetFirstNode(&ListOfFiles->Link) ; !IsNull(&ListOfFiles->Link, &FileNode->Link) ; FileNode = (EFI_SHELL_FILE_INFO*)GetNextNode(&ListOfFiles->Link, &FileNode->Link) ){ ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_ATTRIB_OUTPUT_LINE), gShellLevel2HiiHandle, FileNode->Info->Attribute&EFI_FILE_DIRECTORY? L'D':L' ', FileNode->Info->Attribute&EFI_FILE_ARCHIVE? L'A':L' ', FileNode->Info->Attribute&EFI_FILE_SYSTEM? L'S':L' ', FileNode->Info->Attribute&EFI_FILE_HIDDEN? L'H':L' ', FileNode->Info->Attribute&EFI_FILE_READ_ONLY? L'R':L' ', FileNode->FileName ); if (ShellGetExecutionBreakFlag()) { ShellStatus = SHELL_ABORTED; break; } } Status = ShellCloseFileMetaArg(&ListOfFiles); ListOfFiles = NULL; if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount)); ShellStatus = SHELL_NOT_FOUND; } } // for loop for handling wildcard filenames } // for loop for printing out the info } else if ((FileAttributesToRemove & FileAttributesToAdd) != 0) { // // fail as we have conflcting params. // ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_CON), gShellLevel2HiiHandle, L"attrib"); ShellStatus = SHELL_INVALID_PARAMETER; } else { // // enumerate through all the files/directories and apply the attributes // for ( ParamNumberCount = 1 ; ; ParamNumberCount++ ){ FileName = ShellCommandLineGetRawValue(Package, ParamNumberCount); // if we dont have anything left, move on... if (FileName == NULL) { // // make sure we are not failing on the first one we do... if yes that's an error... // if (ParamNumberCount == 1) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"attrib"); ShellStatus = SHELL_INVALID_PARAMETER; } break; } // // OpenFileByName / GetFileInfo / Change attributes / SetFileInfo / CloseFile / free memory // for each file or directory on the line. // // // Open the file(s) // ASSERT(ListOfFiles == NULL); Status = ShellOpenFileMetaArg((CHAR16*)FileName, EFI_FILE_MODE_READ, &ListOfFiles); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_OPEN_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount)); ShellStatus = SHELL_NOT_FOUND; } else { for (FileNode = (EFI_SHELL_FILE_INFO*)GetFirstNode(&ListOfFiles->Link) ; !IsNull(&ListOfFiles->Link, &FileNode->Link) ; FileNode = (EFI_SHELL_FILE_INFO*)GetNextNode(&ListOfFiles->Link, &FileNode->Link) ){ // // skip the directory traversing stuff... // if (StrCmp(FileNode->FileName, L".") == 0 || StrCmp(FileNode->FileName, L"..") == 0) { continue; } FileInfo = gEfiShellProtocol->GetFileInfo(FileNode->Handle); // // if we are removing Read-Only we need to do that alone // if ((FileAttributesToRemove & EFI_FILE_READ_ONLY) == EFI_FILE_READ_ONLY) { FileInfo->Attribute &= ~EFI_FILE_READ_ONLY; // // SetFileInfo // Status = ShellSetFileInfo(FileNode->Handle, FileInfo); if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount)); ShellStatus = SHELL_ACCESS_DENIED; } } // // change the attribute // FileInfo->Attribute &= ~FileAttributesToRemove; FileInfo->Attribute |= FileAttributesToAdd; // // SetFileInfo // Status = ShellSetFileInfo(FileNode->Handle, FileInfo); if (EFI_ERROR(Status)) {; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_AD), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount)); ShellStatus = SHELL_ACCESS_DENIED; } SHELL_FREE_NON_NULL(FileInfo); } Status = ShellCloseFileMetaArg(&ListOfFiles); ListOfFiles = NULL; if (EFI_ERROR(Status)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_CLOSE_FAIL), gShellLevel2HiiHandle, L"attrib", ShellCommandLineGetRawValue(Package, ParamNumberCount)); ShellStatus = SHELL_NOT_FOUND; } } // for loop for handling wildcard filenames } } } } // // free the command line package // ShellCommandLineFreeVarList (Package); // // return the status // return (ShellStatus); }
EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; UINT32 LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath; EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath; UINTN FdtDevicePathSize; UINTN CmdLineSize; UINTN InitrdSize; EFI_DEVICE_PATH* Initrd; UINT16 LoadOptionIndexSize; if (IS_ARM_BDS_BOOTENTRY (BootOption)) { Status = EFI_UNSUPPORTED; OptionalData = BootOption->OptionalData; LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if (LoaderType == BDS_LOADER_EFI_APPLICATION) { // Need to connect every drivers to ensure no dependencies are missing for the application BdsConnectAllDrivers(); Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxAtag (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1)); // CmdLine } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } // Get the default FDT device path Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); ASSERT_EFI_ERROR(Status); DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); // Get the FDT device path FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath); Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid, DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath); ASSERT_EFI_ERROR(Status); Status = BdsBootLinuxFdt (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1), FdtDevicePath); FreePool (FdtDevicePath); } } else { // Set BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); // Clear BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); } return Status; }
/** Main entry point. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS Successfully initialized. **/ EFI_STATUS EFIAPI FvbInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; VOID *Ptr; VOID *SubPtr; BOOLEAN Initialize; EFI_HANDLE Handle; EFI_PHYSICAL_ADDRESS Address; DEBUG ((EFI_D_INFO, "EMU Variable FVB Startedn")); // // Verify that the PCD's are set correctly. // if ( (PcdGet32 (PcdVariableStoreSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) ) > EMU_FVB_BLOCK_SIZE ) { DEBUG ((EFI_D_ERROR, "EMU Variable invalid PCD sizesn")); return EFI_INVALID_PARAMETER; } // // By default we will initialize the FV contents. But, if // PcdEmuVariableNvStoreReserved is non-zero, then we will // use this location for our buffer. // // If this location does not have a proper FV header, then // we will initialize it. // Initialize = TRUE; if (PcdGet64 (PcdEmuVariableNvStoreReserved) != 0) { Ptr = (VOID*)(UINTN) PcdGet64 (PcdEmuVariableNvStoreReserved); DEBUG (( EFI_D_INFO, "EMU Variable FVB: Using pre-reserved block at %pn", Ptr )); Status = ValidateFvHeader (Ptr); if (!EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "EMU Variable FVB: Found valid pre-existing FVn")); Initialize = FALSE; } } else { Ptr = AllocateAlignedRuntimePages ( EFI_SIZE_TO_PAGES (EMU_FVB_SIZE), SIZE_64KB ); } mEmuVarsFvb.BufferPtr = Ptr; // // Initialize the main FV header and variable store header // if (Initialize) { SetMem (Ptr, EMU_FVB_SIZE, ERASED_UINT8); InitializeFvAndVariableStoreHeaders (Ptr); } PcdSet32 (PcdFlashNvStorageVariableBase, (UINT32)(UINTN) Ptr); // // Initialize the Fault Tolerant Write data area // SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize)); if (Initialize) { InitializeFtwState (SubPtr); } PcdSet32 (PcdFlashNvStorageFtwWorkingBase, (UINT32)(UINTN) SubPtr); // // Initialize the Fault Tolerant Write spare block // SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE); PcdSet32 (PcdFlashNvStorageFtwSpareBase, (UINT32)(UINTN) SubPtr); // // Setup FVB device path // Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Ptr; mEmuVarsFvb.DevicePath.MemMapDevPath.StartingAddress = Address; mEmuVarsFvb.DevicePath.MemMapDevPath.EndingAddress = Address + EMU_FVB_SIZE - 1; // // Install the protocols // DEBUG ((EFI_D_INFO, "Installing FVB for EMU Variable supportn")); Handle = 0; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &mEmuVarsFvb.FwVolBlockInstance, &gEfiDevicePathProtocolGuid, &mEmuVarsFvb.DevicePath, NULL ); ASSERT_EFI_ERROR (Status); // // Register for the virtual address change event // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FvbVirtualAddressChangeEvent, NULL, &gEfiEventVirtualAddressChangeGuid, &mEmuVarsFvbAddrChangeEvent ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut. @param[in] Handle - Handle of PCI device instance @param[in] PciIo - PCI IO protocol instance @param[in] Pci - PCI Header register block @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. @retval EFI_STATUS - PCI Device check or Console variable update fail. **/ EFI_STATUS EFIAPI DetectAndPreparePlatformPciDevicePath ( IN EFI_HANDLE Handle, IN EFI_PCI_IO_PROTOCOL *PciIo, IN PCI_TYPE00 *Pci ) { EFI_STATUS Status; Status = PciIo->Attributes ( PciIo, EfiPciIoAttributeOperationEnable, EFI_PCI_DEVICE_ENABLE, NULL ); ASSERT_EFI_ERROR (Status); if (!mDetectVgaOnly) { // // Here we decide whether it is LPC Bridge // if ((IS_PCI_LPC (Pci)) || ((IS_PCI_ISA_PDECODE (Pci)) && (Pci->Hdr.VendorId == 0x8086) && (Pci->Hdr.DeviceId == 0x7000) ) ) { // // Add IsaKeyboard to ConIn, // add IsaSerial to ConOut, ConIn, ErrOut // DEBUG ((EFI_D_INFO, "Found LPC Bridge devicen")); PrepareLpcBridgeDevicePath (Handle); return EFI_SUCCESS; } // // Here we decide which Serial device to enable in PCI bus // if (IS_PCI_16550SERIAL (Pci)) { // // Add them to ConOut, ConIn, ErrOut. // DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL devicen")); PreparePciSerialDevicePath (Handle); return EFI_SUCCESS; } } // // Here we decide which VGA device to enable in PCI bus // if (IS_PCI_VGA (Pci)) { // // Add them to ConOut. // DEBUG ((EFI_D_INFO, "Found PCI VGA devicen")); PreparePciVgaDevicePath (Handle); return EFI_SUCCESS; } return Status; }
/** The user Entry Point for English module. This function initializes unicode character mapping and then installs Unicode Collation & Unicode Collation 2 Protocols based on the feature flags. @param ImageHandle The firmware allocated handle for the EFI image. @param SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI InitializeUnicodeCollationEng ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN Index; UINTN Index2; // // Initialize mapping tables for the supported languages // for (Index = 0; Index < MAP_TABLE_SIZE; Index++) { mEngUpperMap[Index] = (CHAR8) Index; mEngLowerMap[Index] = (CHAR8) Index; mEngInfoMap[Index] = 0; if ((Index >= 'a' && Index <= 'z') || (Index >= 0xe0 && Index <= 0xf6) || (Index >= 0xf8 && Index <= 0xfe)) { Index2 = Index - 0x20; mEngUpperMap[Index] = (CHAR8) Index2; mEngLowerMap[Index2] = (CHAR8) Index; mEngInfoMap[Index] |= CHAR_FAT_VALID; mEngInfoMap[Index2] |= CHAR_FAT_VALID; } } for (Index = 0; mOtherChars[Index] != 0; Index++) { Index2 = mOtherChars[Index]; mEngInfoMap[Index2] |= CHAR_FAT_VALID; } if (FeaturePcdGet (PcdUnicodeCollation2Support)) { if (FeaturePcdGet (PcdUnicodeCollationSupport)) { Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiUnicodeCollationProtocolGuid, &UnicodeEng, &gEfiUnicodeCollation2ProtocolGuid, &Unicode2Eng, NULL ); ASSERT_EFI_ERROR (Status); } else { Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiUnicodeCollation2ProtocolGuid, &Unicode2Eng, NULL ); ASSERT_EFI_ERROR (Status); } } else { if (FeaturePcdGet (PcdUnicodeCollationSupport)) { Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiUnicodeCollationProtocolGuid, &UnicodeEng, NULL ); ASSERT_EFI_ERROR (Status); } else { // // This module must support to produce at least one of Unicode Collation Protocol // and Unicode Collation 2 Protocol. // ASSERT (FALSE); Status = EFI_UNSUPPORTED; } } return Status; }
/** Measure FV image. Add it into the measured FV list after the FV is measured successfully. @param[in] FvBase Base address of FV image. @param[in] FvLength Length of FV image. @retval EFI_SUCCESS Fv image is measured successfully or it has been already measured. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS EFIAPI MeasureFvImage ( IN EFI_PHYSICAL_ADDRESS FvBase, IN UINT64 FvLength ) { UINT32 Index; EFI_STATUS Status; EFI_PLATFORM_FIRMWARE_BLOB FvBlob; TCG_PCR_EVENT_HDR TcgEventHdr; TIS_TPM_HANDLE TpmHandle; TpmHandle = (TIS_TPM_HANDLE) (UINTN) TPM_BASE_ADDRESS; // // Check if it is in Excluded FV list // if (mMeasurementExcludedFvPpi != NULL) { for (Index = 0; Index < mMeasurementExcludedFvPpi->Count; Index ++) { if (mMeasurementExcludedFvPpi->Fv[Index].FvBase == FvBase) { DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei starts at: 0x%xn", FvBase)); DEBUG ((DEBUG_INFO, "The FV which is excluded by TcgPei has the size: 0x%xn", FvLength)); return EFI_SUCCESS; } } } // // Check whether FV is in the measured FV list. // for (Index = 0; Index < mMeasuredBaseFvIndex; Index ++) { if (mMeasuredBaseFvInfo[Index].BlobBase == FvBase) { return EFI_SUCCESS; } } // // Measure and record the FV to the TPM // FvBlob.BlobBase = FvBase; FvBlob.BlobLength = FvLength; DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei starts at: 0x%xn", FvBlob.BlobBase)); DEBUG ((DEBUG_INFO, "The FV which is measured by TcgPei has the size: 0x%xn", FvBlob.BlobLength)); TcgEventHdr.PCRIndex = 0; TcgEventHdr.EventType = EV_EFI_PLATFORM_FIRMWARE_BLOB; TcgEventHdr.EventSize = sizeof (FvBlob); Status = HashLogExtendEvent ( (EFI_PEI_SERVICES **) GetPeiServicesTablePointer(), (UINT8*) (UINTN) FvBlob.BlobBase, (UINTN) FvBlob.BlobLength, TpmHandle, &TcgEventHdr, (UINT8*) &FvBlob ); ASSERT_EFI_ERROR (Status); // // Add new FV into the measured FV list. // ASSERT (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)); if (mMeasuredBaseFvIndex < FixedPcdGet32 (PcdPeiCoreMaxFvSupported)) { mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobBase = FvBase; mMeasuredBaseFvInfo[mMeasuredBaseFvIndex].BlobLength = FvLength; mMeasuredBaseFvIndex++; } return Status; }
/** Function to write a line of text to a file. If the file is a Unicode file (with UNICODE file tag) then write the unicode text. If the file is an ASCII file then write the ASCII text. If the size of file is zero (without file tag at the beginning) then write ASCII text as default. @param[in] Handle FileHandle to write to. @param[in] Buffer Buffer to write, if NULL the function will take no action and return EFI_SUCCESS. @retval EFI_SUCCESS The data was written. Buffer is NULL. @retval EFI_INVALID_PARAMETER Handle is NULL. @retval EFI_OUT_OF_RESOURCES Unable to allocate temporary space for ASCII string due to out of resources. @sa FileHandleWrite **/ EFI_STATUS EFIAPI FileHandleWriteLine( IN EFI_FILE_HANDLE Handle, IN CHAR16 *Buffer ) { EFI_STATUS Status; CHAR16 CharBuffer; UINTN Size; UINTN Index; UINTN CharSize; UINT64 FileSize; UINT64 OriginalFilePosition; BOOLEAN Ascii; CHAR8 *AsciiBuffer; if (Buffer == NULL) { return (EFI_SUCCESS); } if (Handle == NULL) { return (EFI_INVALID_PARAMETER); } Ascii = FALSE; AsciiBuffer = NULL; Status = FileHandleGetPosition(Handle, &OriginalFilePosition); if (EFI_ERROR(Status)) { return Status; } Status = FileHandleSetPosition(Handle, 0); if (EFI_ERROR(Status)) { return Status; } Status = FileHandleGetSize(Handle, &FileSize); if (EFI_ERROR(Status)) { return Status; } if (FileSize == 0) { Ascii = TRUE; } else { CharSize = sizeof (CHAR16); Status = FileHandleRead (Handle, &CharSize, &CharBuffer); ASSERT_EFI_ERROR (Status); if (CharBuffer == gUnicodeFileTag) { Ascii = FALSE; } else { Ascii = TRUE; } } Status = FileHandleSetPosition(Handle, OriginalFilePosition); if (EFI_ERROR(Status)) { return Status; } if (Ascii) { Size = ( StrSize(Buffer) / sizeof(CHAR16) ) * sizeof(CHAR8); AsciiBuffer = (CHAR8 *)AllocateZeroPool(Size); if (AsciiBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } UnicodeStrToAsciiStrS (Buffer, AsciiBuffer, Size); for (Index = 0; Index < Size; Index++) { if ((AsciiBuffer[Index] & BIT7) != 0) { FreePool(AsciiBuffer); return EFI_INVALID_PARAMETER; } } Size = AsciiStrSize(AsciiBuffer) - sizeof(CHAR8); Status = FileHandleWrite(Handle, &Size, AsciiBuffer); if (EFI_ERROR(Status)) { FreePool (AsciiBuffer); return (Status); } Size = AsciiStrSize("rn") - sizeof(CHAR8); Status = FileHandleWrite(Handle, &Size, "rn"); } else { if (OriginalFilePosition == 0) { Status = FileHandleSetPosition (Handle, sizeof(CHAR16)); if (EFI_ERROR(Status)) { return Status; } } Size = StrSize(Buffer) - sizeof(CHAR16); Status = FileHandleWrite(Handle, &Size, Buffer); if (EFI_ERROR(Status)) { return (Status); } Size = StrSize(L"rn") - sizeof(CHAR16); Status = FileHandleWrite(Handle, &Size, L"rn"); } if (AsciiBuffer != NULL) { FreePool (AsciiBuffer); } return Status; }
/** Provides the controller-specific addresses required to access system memory from a DMA bus master. On SEV guest, the DMA operations must be performed on shared buffer hence we allocate a bounce buffer to map the HostAddress to a DeviceAddress. The Encryption attribute is removed from the DeviceAddress buffer. @param This The protocol instance pointer. @param Operation Indicates if the bus master is going to read or write to system memory. @param HostAddress The system memory address to map to the PCI controller. @param NumberOfBytes On input the number of bytes to map. On output the number of bytes that were mapped. @param DeviceAddress The resulting map address for the bus master PCI controller to use to access the hosts HostAddress. @param Mapping A resulting value to pass to Unmap(). @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. @retval EFI_INVALID_PARAMETER One or more parameters are invalid. @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. **/ EFI_STATUS EFIAPI IoMmuMap ( IN EDKII_IOMMU_PROTOCOL *This, IN EDKII_IOMMU_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping ) { EFI_STATUS Status; MAP_INFO *MapInfo; EFI_ALLOCATE_TYPE AllocateType; COMMON_BUFFER_HEADER *CommonBufferHeader; VOID *DecryptionSource; DEBUG (( DEBUG_VERBOSE, "%a: Operation=%a Host=0x%p Bytes=0x%Lxn", __FUNCTION__, ((Operation >= 0 && Operation < ARRAY_SIZE (mBusMasterOperationName)) ? mBusMasterOperationName[Operation] : "Invalid"), HostAddress, (UINT64)((NumberOfBytes == NULL) ? 0 : *NumberOfBytes) )); if (HostAddress == NULL || NumberOfBytes == NULL || DeviceAddress == NULL || Mapping == NULL) { return EFI_INVALID_PARAMETER; } // // Allocate a MAP_INFO structure to remember the mapping when Unmap() is // called later. // MapInfo = AllocatePool (sizeof (MAP_INFO)); if (MapInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Failed; } // // Initialize the MAP_INFO structure, except the PlainTextAddress field // ZeroMem (&MapInfo->Link, sizeof MapInfo->Link); MapInfo->Signature = MAP_INFO_SIG; MapInfo->Operation = Operation; MapInfo->NumberOfBytes = *NumberOfBytes; MapInfo->NumberOfPages = EFI_SIZE_TO_PAGES (MapInfo->NumberOfBytes); MapInfo->CryptedAddress = (UINTN)HostAddress; // // In the switch statement below, we point "MapInfo->PlainTextAddress" to the // plaintext buffer, according to Operation. We also set "DecryptionSource". // MapInfo->PlainTextAddress = MAX_ADDRESS; AllocateType = AllocateAnyPages; DecryptionSource = (VOID *)(UINTN)MapInfo->CryptedAddress; switch (Operation) { // // For BusMasterRead[64] and BusMasterWrite[64] operations, a bounce buffer // is necessary regardless of whether the original (crypted) buffer crosses // the 4GB limit or not -- we have to allocate a separate plaintext buffer. // The only variable is whether the plaintext buffer should be under 4GB. // case EdkiiIoMmuOperationBusMasterRead: case EdkiiIoMmuOperationBusMasterWrite: MapInfo->PlainTextAddress = BASE_4GB - 1; AllocateType = AllocateMaxAddress; // // fall through // case EdkiiIoMmuOperationBusMasterRead64: case EdkiiIoMmuOperationBusMasterWrite64: // // Allocate the implicit plaintext bounce buffer. // Status = gBS->AllocatePages ( AllocateType, EfiBootServicesData, MapInfo->NumberOfPages, &MapInfo->PlainTextAddress ); if (EFI_ERROR (Status)) { goto FreeMapInfo; } break; // // For BusMasterCommonBuffer[64] operations, a to-be-plaintext buffer and a // stash buffer (for in-place decryption) have been allocated already, with // AllocateBuffer(). We only check whether the address of the to-be-plaintext // buffer is low enough for the requested operation. // case EdkiiIoMmuOperationBusMasterCommonBuffer: if ((MapInfo->CryptedAddress > BASE_4GB) || (EFI_PAGES_TO_SIZE (MapInfo->NumberOfPages) > BASE_4GB - MapInfo->CryptedAddress)) { // // CommonBuffer operations cannot be remapped. If the common buffer is // above 4GB, then it is not possible to generate a mapping, so return an // error. // Status = EFI_UNSUPPORTED; goto FreeMapInfo; } // // fall through // case EdkiiIoMmuOperationBusMasterCommonBuffer64: // // The buffer at MapInfo->CryptedAddress comes from AllocateBuffer(). // MapInfo->PlainTextAddress = MapInfo->CryptedAddress; // // Stash the crypted data. // CommonBufferHeader = (COMMON_BUFFER_HEADER *)( (UINTN)MapInfo->CryptedAddress - EFI_PAGE_SIZE ); ASSERT (CommonBufferHeader->Signature == COMMON_BUFFER_SIG); CopyMem ( CommonBufferHeader->StashBuffer, (VOID *)(UINTN)MapInfo->CryptedAddress, MapInfo->NumberOfBytes ); // // Point "DecryptionSource" to the stash buffer so that we decrypt // it to the original location, after the switch statement. // DecryptionSource = CommonBufferHeader->StashBuffer; break; default: // // Operation is invalid // Status = EFI_INVALID_PARAMETER; goto FreeMapInfo; } // // Clear the memory encryption mask on the plaintext buffer. // Status = MemEncryptSevClearPageEncMask ( 0, MapInfo->PlainTextAddress, MapInfo->NumberOfPages, TRUE ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { CpuDeadLoop (); } // // If this is a read operation from the Bus Master's point of view, // then copy the contents of the real buffer into the mapped buffer // so the Bus Master can read the contents of the real buffer. // // For BusMasterCommonBuffer[64] operations, the CopyMem() below will decrypt // the original data (from the stash buffer) back to the original location. // if (Operation == EdkiiIoMmuOperationBusMasterRead || Operation == EdkiiIoMmuOperationBusMasterRead64 || Operation == EdkiiIoMmuOperationBusMasterCommonBuffer || Operation == EdkiiIoMmuOperationBusMasterCommonBuffer64) { CopyMem ( (VOID *) (UINTN) MapInfo->PlainTextAddress, DecryptionSource, MapInfo->NumberOfBytes ); } // // Track all MAP_INFO structures. // InsertHeadList (&mMapInfos, &MapInfo->Link); // // Populate output parameters. // *DeviceAddress = MapInfo->PlainTextAddress; *Mapping = MapInfo; DEBUG (( DEBUG_VERBOSE, "%a: Mapping=0x%p Device(PlainText)=0x%Lx Crypted=0x%Lx Pages=0x%Lxn", __FUNCTION__, MapInfo, MapInfo->PlainTextAddress, MapInfo->CryptedAddress, (UINT64)MapInfo->NumberOfPages )); return EFI_SUCCESS; FreeMapInfo: FreePool (MapInfo); Failed: *NumberOfBytes = 0; return Status; }
/** The RegisterKeystrokeNotify() function registers a function which will be called when a specified keystroke will occur. @param This A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL instance. @param KeyData A pointer to a buffer that is filled in with the keystroke information for the key that was pressed. @param KeyNotificationFunction Points to the function to be called when the key sequence is typed specified by KeyData. @param NotifyHandle Points to the unique handle assigned to the registered notification. @retval EFI_SUCCESS The device state was set appropriately. @retval EFI_OUT_OF_RESOURCES Unable to allocate necessary data structures. **/ EFI_STATUS EFIAPI EmuGopSimpleTextInExRegisterKeyNotify ( IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT EFI_HANDLE *NotifyHandle ) { EFI_STATUS Status; GOP_PRIVATE_DATA *Private; EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *CurrentNotify; LIST_ENTRY *Link; EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *NewNotify; if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL) { return EFI_INVALID_PARAMETER; } Private = GOP_PRIVATE_DATA_FROM_TEXT_IN_EX_THIS (This); // // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. // for (Link = Private->NotifyList.ForwardLink; Link != &Private->NotifyList; Link = Link->ForwardLink) { CurrentNotify = CR ( Link, EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY, NotifyEntry, EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE ); if (GopPrivateIsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { *NotifyHandle = CurrentNotify->NotifyHandle; return EFI_SUCCESS; } } } // // Allocate resource to save the notification function // NewNotify = (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY *) AllocateZeroPool (sizeof (EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY)); if (NewNotify == NULL) { return EFI_OUT_OF_RESOURCES; } NewNotify->Signature = EMU_GOP_SIMPLE_TEXTIN_EX_NOTIFY_SIGNATURE; NewNotify->KeyNotificationFn = KeyNotificationFunction; NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify; CopyMem (&NewNotify->KeyData, KeyData, sizeof (KeyData)); InsertTailList (&Private->NotifyList, &NewNotify->NotifyEntry); Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, EmuGopRegisterKeyCallback, NewNotify, &NewNotify->Event ); ASSERT_EFI_ERROR (Status); *NotifyHandle = NewNotify->NotifyHandle; return EFI_SUCCESS; }
Представляю версию 64-разрядного дистрибутива Runtu LITE 22.04 х64, собранную на пакетной базе релиза Jammy Jellyfish 22.04 LTS. Сборка имеет базовый набор пользовательского ПО с возможностью установки на жёсткий диск.
Основные элементы системы:
Менеджер дисплея LightDM 1.30
Оконный менеджер Openbox 3.6.1
Файловый менеджер PCManFM 1.3.2
Панель рабочего стола LXPanel 0.10.1
Менеджер сети NetworkManager 1.36.4 (pptp, l2tp, ssh, openvpn и vpnc)
Текстовый редактор Geany 1.38
Браузер Firefox 99.0.1
Видеоплеер VLC 3.0.16
Аудиоплеер DeaDBeeF 1.8.8
Менеджер питания xfce4-power-manager
Менеджер Bluetooth Blueman
Звуковой сервер PulseAudio
Версия ядра: 5.15.0-25-generic
Версия Xorg: 2:21.1.3
Минимальные системные требования:
RAM — 1024Mb
CPU — x64
HDD — 5Gb
Логин: runtu
Пароль: пустой
Скриншоты рабочего окружения:
===========================
===========================
Служебные комментарии:
— заблокирована возможность установки snap-приложений на уровне приоритетов APT. При необходимости поддержки данного типа пакетов нужно удалить конфиг /etc/apt/preferences.d/nosnap.pref и обновить индекс пакетной базы;
— браузер Firefox установлен в виде deb-пакета из подключенного PPA-репозитория Mozillateam, т.к. штатно в релизе 22.04 Firefox поставляется в виде snap. Предустановлено расширение uBlock Origin.
В меню «Офис» добавлены ярлыки для установки LibreOffice и подсистемы печати. Если установка данного ПО не планируется и ярлыки в меню не нужны, следует удалить файлы printinstall и lo_install в каталоге /var/lib/misc/.
Пожелания, предложения по составу и функционалу дистрибутива приветствуются.
Ссылки на загрузку:
Загрузить с Sourceforge.net
Загрузить с Зеркала на mephi.ru
Файл: runtu-lite-22.04-amd64_20220424.iso
Размер: 1151 Мб
md5: 889295457f02cd9c3d9c25498a0d0475
sha1: 0be5c2d87ba85b0c5a00c3a762cd1a89b5e35cfd
Поддержать проект: ссылка на тему форума.
Description of problem: Guest didn't boot up when passthrough device using vfio-pci with ovmf Version-Release number of selected component (if applicable): kernel-3.10.0-433.el7.x86_64 qemu-kvm-rhev-2.6.0-5.el7.x86_64 OVMF-20160608-1.git988715a.el7.noarch.rpm How reproducible: 3/3 Steps to Reproduce: 1. Boot guest with following cli [root@localhost home]# cat q35-ovmf.sh /usr/libexec/qemu-kvm -M q35 -cpu Nehalem -monitor stdio -m 4G -vga qxl -drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 -debugcon file:/home/q35.ovmf.log -global isa-debugcon.iobase=0x402 -spice port=5932,disable-ticketing -smp 4,sockets=4,cores=1,threads=1 -device ioh3420,bus=pcie.0,id=root1.0,slot=1 -device x3130-upstream,bus=root1.0,id=upstream1.1 -device xio3130-downstream,bus=upstream1.1,id=downstream1.1,chassis=2 -device virtio-net-pci,bus=downstream1.1,netdev=tap10,mac=9a:6a:6b:6c:6d:6e -netdev tap,id=tap10 -device ioh3420,bus=pcie.0,id=root1.1,slot=2 -device x3130-upstream,bus=root1.1,id=upstream1.2 -device xio3130-downstream,bus=upstream1.2,id=downstream1.2,chassis=3 -device xio3130-downstream,bus=upstream1.2,id=downstream1.3,chassis=4 -drive if=none,id=drive0,file=/home/pxb-ovmf.qcow2 -device virtio-blk-pci,drive=drive0,scsi=off,bus=downstream1.2,disable-legacy=on,disable-modern=off -device ioh3420,bus=pcie.0,id=root1.2,slot=3 -device vfio-pci,host=0000:03:00.0,id=vfio,bus=downstream1.3 Actual results: Guest didn't boot up successfully, please check the attachment of ovmf log Expected results: Gust can boot up successfully Additional info:
Jing Zhao, two remarks / questions: - Your use of OVMF_VARS.fd is not correct. Please refer to bug 1308678 comment 23 bullet (1) for details. (This is independent from the functionality being tested -- it's a general remark, but I think it's worth pointing out.) - I checked the attached OVMF log file, from comment 1. It says PciHostBridgeGetRootBridges: 2 extra root buses reported by QEMU InitRootBridge: populated root bus 0, with room for 7 subordinate bus(es) InitRootBridge: populated root bus 8, with room for 11 subordinate bus(es) InitRootBridge: populated root bus 20, with room for 235 subordinate bus(es) However, this doesn't seem to match the command line given in comment 0 -- on that command line, you do not have any pxb-pcie devices. At the moment it appears to me that you tried VFIO device assignment in combination with pxb-pcie, and you ran into the bus_nr problem that we've been discussing in bug 1345738. Looking at the OVMF debug log, this is the impression I'm getting. And I think you ended up pasting a different QEMU command line (without pxb-pcie devices) into comment 0. Can you please clarify? Thanks.
Jing Zhao, another remark: *assuming* that you intend to place (a) the assigned device, and/or (b) the *modern* virtio-blk device, behind a pxb-pcie extra root bridge, please be aware of bug 1323976. Namely, unlike SeaBIOS, the edk2 PCI infrastructure built into OVMF prefers to allocate 64-bit MMIO BARs of PCI devices outside of the 32-bit address space. This works fine if you place such PCI device directly on the "main" root bridge (bus_nr=0), but it can break if the PCI device with 64-bit MMIO BARs is elsewhere. The possible breakage is due to QEMU's ACPI generator producing incorrect resource descriptors --> see bug 1323976. This may affect both modern virtio devices, and assigned physical devices. There are two work-arounds: - Plug these devices directly into "pcie.0". - Alternatively, pass the following switch to QEMU, disabling the 64-bit MMIO aperture for OVMF: -fw_cfg name=opt/ovmf/X-PciMmio64Mb,string=0 Thanks.
Sigh, I CC'd Marcel while writing my previous comment, but of course Bugzilla had to apply some automatic changes meanwhile, so my metadata changes went lost. Adding the CC now.
(In reply to jingzhao from comment #0)
> -device vfio-pci,host=0000:03:00.0,id=vfio,bus=downstream1.3
What is this device? Please always identify the device being assigned.
Laszlo has additional questions in comment 3 that also needinfo regarding the consistency of the original report.
Created attachment 1168522 [details]
ovmf debug log
Reproduced with 82576 PF:
# lspci -vs 7:00.0
07:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01)
Subsystem: Intel Corporation Gigabit ET Dual Port Server Adapter
Physical Slot: 5
Flags: fast devsel, IRQ 16
Memory at ef420000 (32-bit, non-prefetchable) [disabled] [size=128K]
Memory at ef000000 (32-bit, non-prefetchable) [disabled] [size=4M]
I/O ports at 8020 [disabled] [size=32]
Memory at ef4c4000 (32-bit, non-prefetchable) [disabled] [size=16K]
Expansion ROM at eec00000 [disabled] [size=4M]
OVMF log ends with:
PciHostBridge: SubmitResources for PciRoot(0x0)
I/O: Granularity/SpecificFlag = 0 / 01
Length/Alignment = 0x3000 / 0xFFF
Mem: Granularity/SpecificFlag = 32 / 00
Length/Alignment = 0x1E8200000 / 0xEF49FFFF
PciBus: HostBridge->SubmitResources() - Invalid Parameter
ASSERT_EFI_ERROR (Status = Invalid Parameter)
ASSERT /builddir/build/BUILD/ovmf-988715a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c(561): !EFI_ERROR (Status)
VM boots with SeaBIOS.
OVMF-20160608-1.git988715a.el7.noarch
qemu-kvm-rhev-2.6.0-6.el7.x86_64
Seems like an OVMF bug, reassigning
The command works with either a non-SR-IOV capable device (82579LM) or a VF (82576), is it the SR-IOV enumeration that kills OVMF? Did I get lucky picking an SR-IOV PF on my first try?
NB, vfio exposes the SR-IOV capability as read-only, in case that's confusing OVMF, but it would seem unusual for OVMF to blindly attempt to enable SR-IOV.
Yes, if vfio hides the sr-iov capability on the device, OVMF boots.
Thanks Laszlo Correct information of bug 1) the nic information which passthrough to the guest [root@hp-z800-01 home]# lspci -vvv -s 03:00.0 03:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) Subsystem: Intel Corporation Gigabit ET Dual Port Server Adapter Physical Slot: 1 Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Interrupt: pin A routed to IRQ 29 Region 0: Memory at e4800000 (32-bit, non-prefetchable) [disabled] [size=128K] Region 1: Memory at e4000000 (32-bit, non-prefetchable) [disabled] [size=4M] Region 2: I/O ports at c000 [disabled] [size=32] Region 3: Memory at e4840000 (32-bit, non-prefetchable) [disabled] [size=16K] Capabilities: [40] Power Management version 3 Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+) Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1 PME- Capabilities: [50] MSI: Enable- Count=1/1 Maskable+ 64bit+ Address: 0000000000000000 Data: 0000 Masking: 00000000 Pending: 00000000 Capabilities: [70] MSI-X: Enable- Count=10 Masked- Vector table: BAR=3 offset=00000000 PBA: BAR=3 offset=00002000 Capabilities: [a0] Express (v2) Endpoint, MSI 00 DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported- RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset- MaxPayload 256 bytes, MaxReadReq 512 bytes DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend- LnkCap: Port #0, Speed 2.5GT/s, Width x4, ASPM L0s L1, Exit Latency L0s <4us, L1 <64us ClockPM- Surprise- LLActRep- BwNot- LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+ ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt- LnkSta: Speed 2.5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt- DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR-, OBFF Not Supported DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis- Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS- Compliance De-emphasis: -6dB LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1- EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest- Capabilities: [100 v1] Advanced Error Reporting UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol- UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol- UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol- CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+ AERCap: First Error Pointer: 00, GenCap- CGenEn- ChkCap- ChkEn- Capabilities: [140 v1] Device Serial Number 00-1b-21-ff-ff-42-33-84 Capabilities: [150 v1] Alternative Routing-ID Interpretation (ARI) ARICap: MFVC- ACS-, Next Function: 1 ARICtl: MFVC- ACS-, Function Group: 0 Capabilities: [160 v1] Single Root I/O Virtualization (SR-IOV) IOVCap: Migration-, Interrupt Message Number: 000 IOVCtl: Enable- Migration- Interrupt- MSE- ARIHierarchy+ IOVSta: Migration- Initial VFs: 8, Total VFs: 8, Number of VFs: 0, Function Dependency Link: 00 VF offset: 128, stride: 2, Device ID: 10ca Supported Page Size: 00000553, System Page Size: 00000001 Region 0: Memory at 00000000e4848000 (64-bit, non-prefetchable) Region 3: Memory at 00000000e4868000 (64-bit, non-prefetchable) VF Migration: offset: 00000000, BIR: 0 Kernel driver in use: vfio-pci 2. the test command line /usr/libexec/qemu-kvm -M q35 -cpu Nehalem -monitor stdio -m 4G -vga qxl -drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=/home/my_varstore.fd,if=pflash,format=raw,unit=1 -debugcon file:/home/q35.ovmf.log -global isa-debugcon.iobase=0x402 -spice port=5932,disable-ticketing -smp 4,sockets=4,cores=1,threads=1 -device ioh3420,bus=pcie.0,id=root1.0,slot=1 -device x3130-upstream,bus=root1.0,id=upstream1.1 -device xio3130-downstream,bus=upstream1.1,id=downstream1.1,chassis=2 -device virtio-net-pci,bus=downstream1.1,netdev=tap10,mac=9a:6a:6b:6c:6d:6e -netdev tap,id=tap10 -device ioh3420,bus=pcie.0,id=root1.1,slot=2 -device x3130-upstream,bus=root1.1,id=upstream1.2 -device xio3130-downstream,bus=upstream1.2,id=downstream1.2,chassis=3 -device xio3130-downstream,bus=upstream1.2,id=downstream1.3,chassis=4 -drive if=none,id=drive0,file=/home/pxb-ovmf.qcow2 -device virtio-blk-pci,drive=drive0,scsi=off,bus=downstream1.2,disable-legacy=on,disable-modern=off -device ioh3420,bus=pcie.0,id=root1.2,slot=3 -device vfio-pci,host=0000:03:00.0,id=vfio,bus=downstream1.3 3. Update the ovmf log of my testing Thanks Jing Zhao
(In reply to Alex Williamson from comment #9) > Did I get lucky picking an SR-IOV PF on my first try? Yes. In both OVMF log files (comment 7, comment 13), I can see messages such as: > PciBus: Discovered PCI @ [07|00|00] > ARI: CapOffset = 0x150 > SR-IOV: SupportedPageSize = 0x553; SystemPageSize = 0x1; FirstVFOffset = > 0x180; InitialVFs = 0x8; ReservedBusNum = 0x2; CapOffset = 0x160 > BAR[0]: Type = Mem32; Alignment = 0x1FFFF; Length = > 0x20000; Offset = 0x10 > BAR[1]: Type = Mem32; Alignment = 0x3FFFFF; Length = > 0x400000; Offset = 0x14 > BAR[2]: Type = Io32; Alignment = 0x1F; Length = 0x20; Offset = > 0x18 > BAR[3]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; > Offset = 0x1C > VFBAR[0]: Type = Mem64; Alignment = 0xEF49FFFF; Length = > 0xEF4A0000; Offset = 0x184 > VFBAR[2]: Type = Mem64; Alignment = 0xEF47FFFF; Length = > 0xEF480000; Offset = 0x190 (which is the very first time I see VFBARs in this section of the log). Then, when the collected resources are submitted to PciHostBridgeDxe, it blows up: > PciHostBridge: SubmitResources for PciRoot(0x0) > I/O: Granularity/SpecificFlag = 0 / 01 > Length/Alignment = 0x3000 / 0xFFF > Mem: Granularity/SpecificFlag = 32 / 00 > Length/Alignment = 0x1E8200000 / 0xEF49FFFF > PciBus: HostBridge->SubmitResources() - Invalid Parameter > > ASSERT_EFI_ERROR (Status = Invalid Parameter) > ASSERT > /builddir/build/BUILD/ovmf-988715a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c(561): > /EFI_ERROR (Status) The direct reason being that the Length field (which is the sum of MMIO resources for the bridge, 0x1E8200000) is greater than 4GB, but the resource type is 32-bit MMIO (Granularity=32). It seems that the Length and Alignment fields have special meanings for VF BARs (I skimmed the SR-IOV spec very-very superficially). ... Hm, I think I might even suspect what causes this. I believe it is <https://github.com/tianocore/edk2/commit/05070c1b471b0>. The 64-bit MMIO BAR is degraded to 32-bit if it is a VFBAR and the device has an option ROM. (See the DegradeResource() function in the linked patch.) I don't understand the reasoning behind this. I'll take the discussion to the upstream list. Meanwhile, Alex, Jing Zhao, can you please repeat your tests, with the small modification that the ROM BAR for the assigned device be turned off? -device vfio-pci,...,rombar=0 ^^^^^^^^ Thanks!
Laszlo, note that 82576 has very modest MMIO requirements for the MMIO space, this is typically the "works anywhere" SR-IOV device because it requires <= 2MB of MMIO space, which is the minimum bridge granularity. If we're coming up with needing more than 4G, it's probably because the read-only SR-IOV capability is being misinterpreted, ie. no sanity checks on the sizing.
FWIW, I'm also open to the idea that QEMU hide the SR-IOV capability from the VM. We have no support for the VM enabling SR-IOV, so there's really no dependency on exposing this capability. Kernel-level vfio exposes the capability read-only to prevent users from creating VFs, but it's still up to the hypervisor whether to further expose such capabilities to the VM.
I'll try to follow whatever you deem best -- I guess first we should hear back from the maintainers of PciBusDxe in edk2, about their goals with VF BARs to begin with. In edk2 there is a feature flag, defined in "MdeModulePkg/MdeModulePkg.dec": ## Indicates if the Single Root I/O virtualization is supported.<BR><BR> # TRUE - Single Root I/O virtualization is supported.<BR> # FALSE - Single Root I/O virtualization is not supported.<BR> # @Prompt Enable SRIOV support. gEfiMdeModulePkgTokenSpaceGuid.PcdSrIovSupport|TRUE|BOOLEAN|0x10000044 OVMF inherits the default value (TRUE) without overriding it, for the time being. (It can override it if we want it to.) I don't know precisely what this feature flag controls. But, if it controls the "creation of VFs", then I guess we should disable it? Based on your comment 18.
(In reply to Laszlo Ersek from comment #14)
> (In reply to Alex Williamson from comment #9)
>
> > Did I get lucky picking an SR-IOV PF on my first try?
>
> Yes. In both OVMF log files (comment 7, comment 13), I can see messages such
> as:
>
> > PciBus: Discovered PCI @ [07|00|00]
> > ARI: CapOffset = 0x150
> > SR-IOV: SupportedPageSize = 0x553; SystemPageSize = 0x1; FirstVFOffset =
> > 0x180; InitialVFs = 0x8; ReservedBusNum = 0x2; CapOffset = 0x160
> > BAR[0]: Type = Mem32; Alignment = 0x1FFFF; Length =
> > 0x20000; Offset = 0x10
> > BAR[1]: Type = Mem32; Alignment = 0x3FFFFF; Length =
> > 0x400000; Offset = 0x14
> > BAR[2]: Type = Io32; Alignment = 0x1F; Length = 0x20; Offset =
> > 0x18
> > BAR[3]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000;
> > Offset = 0x1C
> > VFBAR[0]: Type = Mem64; Alignment = 0xEF49FFFF; Length =
> > 0xEF4A0000; Offset = 0x184
> > VFBAR[2]: Type = Mem64; Alignment = 0xEF47FFFF; Length =
> > 0xEF480000; Offset = 0x190
>
> (which is the very first time I see VFBARs in this section of the log).
> Then, when the collected resources are submitted to PciHostBridgeDxe, it
> blows up:
>
> > PciHostBridge: SubmitResources for PciRoot(0x0)
> > I/O: Granularity/SpecificFlag = 0 / 01
> > Length/Alignment = 0x3000 / 0xFFF
> > Mem: Granularity/SpecificFlag = 32 / 00
> > Length/Alignment = 0x1E8200000 / 0xEF49FFFF
> > PciBus: HostBridge->SubmitResources() - Invalid Parameter
> >
> > ASSERT_EFI_ERROR (Status = Invalid Parameter)
> > ASSERT
> > /builddir/build/BUILD/ovmf-988715a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c(561):
> > /EFI_ERROR (Status)
>
> The direct reason being that the Length field (which is the sum of MMIO
> resources for the bridge, 0x1E8200000) is greater than 4GB, but the resource
> type is 32-bit MMIO (Granularity=32).
>
> It seems that the Length and Alignment fields have special meanings for VF
> BARs (I skimmed the SR-IOV spec very-very superficially).
>
> ... Hm, I think I might even suspect what causes this. I believe it is
> <https://github.com/tianocore/edk2/commit/05070c1b471b0>. The 64-bit MMIO
> BAR is degraded to 32-bit if it is a VFBAR and the device has an option ROM.
> (See the DegradeResource() function in the linked patch.)
>
> I don't understand the reasoning behind this. I'll take the discussion to
> the upstream list.
>
> Meanwhile, Alex, Jing Zhao, can you please repeat your tests, with the small
> modification that the ROM BAR for the assigned device be turned off?
>
> -device vfio-pci,...,rombar=0
> ^^^^^^^^
>
> Thanks!
Repeat the test with above changed, and failed. please check the ovmf log of add rombar parameter
Thank you for checking; the symptoms in the log file are identical. So it looks like rombar=0 makes no difference, and I should instrument the edk2 code with debug messages and experiment a little with it.
(In reply to Laszlo Ersek from comment #24)
> Upstream thread #2, from a different angle:
> http://thread.gmane.org/gmane.comp.bios.edk2.devel/13437
Lazslo, some folks think that allowing the guest to enable sr-iov on an assigned device is not a completely insane thing to do, see http://www.spinics.net/lists/kvm/msg134370.html
The more I think about it, the more I think vfio is asking ovmf to detect something non-standard per the spec. Sure, it might be robust to detect that the VFBARs aren't getting sized correctly, but is that something we can reasonably expect of guest software? We can have QEMU hide the SR-IOV capability, though this also gets a little ugly because extended capabilities always start at 0x100 in PCI config space and it's not feasible to relocated capabilities, which means we need to support stubbing that first entry to something a guest will traverse, but not recognize. If we hope that the guest follows the spec to the letter, we could use capability ID 0x0, except QEMU-pci uses this internally. ID 0xFFFF also has special meaning for root complex register block based capabilities, which might mean a guest would assume no capabilities at all. That leaves unlikely to be assigned values, like 0xFFFE. It's all generally unappealing, but we do some hiding of capabilities in the kernel too, so I'll look to see whether we have a better algorithm there.
Another possibility is that we virtualize the VFBARs to allow them to be sized, but leave the rest of the capability read-only. I'll need to look through the spec to see if we have any leeway to do this.
Sounds great to me, thanks for looking into this! (And yes, the blurb on the referenced patch set seems reasonable as well.0 Regarding any possible stubbing out for the SR-IOV capability: the CreatePciIoDevice() function in [MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c] has a section like this: > // > // Initialization for SR-IOV > // > > if (PcdGetBool (PcdSrIovSupport)) { > Status = LocatePciExpressCapabilityRegBlock ( > PciIoDevice, > EFI_PCIE_CAPABILITY_ID_SRIOV, > &PciIoDevice->SrIovCapabilityOffset, > NULL > ); > if (!EFI_ERROR (Status)) { If you can make that LocatePciExpressCapabilityRegBlock() function call to fail, then SR-IOV will not be used, I think. (Similarly to the effect of setting PcdSrIovSupport to FALSE in the OVMF platform description files.) The LocatePciExpressCapabilityRegBlock() function is at the end of "MdeModulePkg/Bus/Pci/PciBusDxe/PciCommand.c", and it seems to perform a "fairly standard" traversal of the PCI Express config space. AFAICT, LocatePciExpressCapabilityRegBlock() is called in three places in total, looking for: - EFI_PCIE_CAPABILITY_ID_ARI (0x0E) - EFI_PCIE_CAPABILITY_ID_SRIOV (0x10) - EFI_PCIE_CAPABILITY_ID_MRIOV (0x11) These macro definitions are in "MdePkg/Include/IndustryStandard/PciExpress21.h". Grepping header files for "EFI_PCIE_CAPABILITY_ID_", I find no other header files with definitions. And, all the definitions I find in this header, are: > #define EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY 0x10 > #define EFI_PCIE_CAPABILITY_ID_ARI 0x0E > #define EFI_PCIE_CAPABILITY_ID_ATS 0x0F > #define EFI_PCIE_CAPABILITY_ID_SRIOV 0x10 > #define EFI_PCIE_CAPABILITY_ID_MRIOV 0x11 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_CAPABILITIES 0x04 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL 0x08 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_STATUS 0x0A > #define EFI_PCIE_CAPABILITY_ID_SRIOV_INITIALVFS 0x0C > #define EFI_PCIE_CAPABILITY_ID_SRIOV_TOTALVFS 0x0E > #define EFI_PCIE_CAPABILITY_ID_SRIOV_NUMVFS 0x10 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_FUNCTION_DEPENDENCY_LINK 0x12 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_FIRSTVF 0x14 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_VFSTRIDE 0x16 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_VFDEVICEID 0x1A > #define EFI_PCIE_CAPABILITY_ID_SRIOV_SUPPORTED_PAGE_SIZE 0x1C > #define EFI_PCIE_CAPABILITY_ID_SRIOV_SYSTEM_PAGE_SIZE 0x20 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0 0x24 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR1 0x28 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR2 0x2C > #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR3 0x30 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR4 0x34 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5 0x38 > #define EFI_PCIE_CAPABILITY_ID_SRIOV_VF_MIGRATION_STATE 0x3C I think it might be worth a shot to try 0xFFFE or similar. ... But, given how the effect of that would be practically identical to setting PcdSrIovSupport to FALSE in OvmfPkg/*.dsc (for the time being anyway!), I don't see a problem with that either. I'm happy to try out both, assuming I get access to a machine with a suitable NIC. (Obviously for the stubbing, you would have to provide the QEMU patch :)) Thanks!
I managed to reproduce this error, in the following environment: - assigned device (I350-T2V2 (8086:1521) PF): 03:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01) - domain XML snippet (Q35): <controller type='pci' index='3' model='pcie-root-port'> <model name='ioh3420'/> <target chassis='3' port='0xe8'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x1d' function='0x0'/> </controller> <controller type='pci' index='4' model='pcie-switch-upstream-port'> <model name='x3130-upstream'/> <address type='pci' domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> </controller> <controller type='pci' index='5' model='pcie-switch-downstream-port'> <model name='xio3130-downstream'/> <target chassis='5' port='0x0'/> <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> </controller> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> </source> <address type='pci' domain='0x0000' bus='0x05' slot='0x00' function='0x0'/> </hostdev> This generates a QEMU command line like -device ioh3420,port=0xe8,chassis=3,id=pci.3,bus=pcie.0,addr=0x1d -device x3130-upstream,id=pci.4,bus=pci.3,addr=0x0 -device xio3130-downstream,port=0x0,chassis=5,id=pci.5,bus=pci.4,addr=0x0 -device vfio-pci,host=03:00.0,id=hostdev3,bus=pci.5,addr=0x0 - QEMU: upstream v2.6.0-1395-g40428fe - host kernel: 4.4.5-200.fc22.x86_64 I confirm that toggling the ROM BAR on/off makes no difference, so the error is not due to any 64->32 bit resource degradation like I initially suspected. I'll go ahead and test Alex's upstream patch (comment 28).
Yes, the patch works: > PciBus: Discovered PCI @ [03|00|00] > ARI: forwarding enabled for PPB[02:00:00] > ARI: CapOffset = 0x150 > BAR[0]: Type = Mem32; Alignment = 0xFFFFF; Length = 0x100000; Offset = 0x10 > BAR[3]: Type = Mem32; Alignment = 0x3FFF; Length = 0x4000; Offset = 0x1C > > [...] > > PciBus: Resource Map for Bridge [02|00|00] > Type = Mem32; Base = 0x99200000; Length = 0x200000; Alignment = 0xFFFFF > Base = 0x99200000; Length = 0x100000; Alignment = 0xFFFFF; Owner = PCI [03|00|00:10] > Base = 0x99300000; Length = 0x4000; Alignment = 0x3FFF; Owner = PCI [03|00|00:1C] The Windows Server 2012 R2 guest OS was also launched. The driver for the NIC was installed automatically. The device looks fine in Device Manager. I'm still having network connectivity problems though -- I'm debugging them. (Almost certainly an issue with the dnsmasq / iptables setup on my the gateway machine.) I'd like to have an all-positive result before replying on the list.
Fix included in qemu-kvm-rhev-2.6.0-12.el7
Verified it kernel-3.10.0-489.el7.x86_64 qemu-img-rhev-2.6.0-19.el7.x86_64 OVMF-20160608-3.git988715a.el7.noarch Following is the verfied steps: 1. Boot guest with following cmd: /usr/libexec/qemu-kvm -M q35 -cpu Nehalem -monitor stdio -m 4G -vga qxl -drive file=/usr/share/OVMF/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on -drive file=/home/OVMF_VARS.fd,if=pflash,format=raw,unit=1 -debugcon file:/home/q35.ovmf.log -global isa-debugcon.iobase=0x402 -spice port=5932,disable-ticketing -smp 4,sockets=4,cores=1,threads=1 -device ioh3420,bus=pcie.0,id=root1.0,slot=1 -device x3130-upstream,bus=root1.0,id=upstream1.1 -device xio3130-downstream,bus=upstream1.1,id=downstream1.1,chassis=2 -device virtio-net-pci,bus=downstream1.1,netdev=tap10,mac=9a:6a:6b:6c:6d:6e -netdev tap,id=tap10 -device ioh3420,bus=pcie.0,id=root1.1,slot=2 -device x3130-upstream,bus=root1.1,id=upstream1.2 -device xio3130-downstream,bus=upstream1.2,id=downstream1.2,chassis=3 -device xio3130-downstream,bus=upstream1.2,id=downstream1.3,chassis=4 -drive if=none,id=drive0,file=/home/pxb-ovmf.qcow2 -device virtio-blk-pci,drive=drive0,scsi=off,bus=downstream1.2,disable-legacy=on,disable-modern=off -device ioh3420,bus=pcie.0,id=root1.2,slot=3 -device vfio-pci,host=03:00.0,id=vf-00.0,bus=root1.2 2. guest can boot up successfully 3. check the nic which passthrough from host in the guest [root@dhcp-66-145-44 ~]# lspci 00:00.0 Host bridge: Intel Corporation 82G33/G31/P35/P31 Express DRAM Controller 00:01.0 VGA compatible controller: Red Hat, Inc. QXL paravirtual graphic card (rev 04) 00:02.0 PCI bridge: Intel Corporation 7500/5520/5500/X58 I/O Hub PCI Express Root Port 0 (rev 02) 00:03.0 PCI bridge: Intel Corporation 7500/5520/5500/X58 I/O Hub PCI Express Root Port 0 (rev 02) 00:04.0 PCI bridge: Intel Corporation 7500/5520/5500/X58 I/O Hub PCI Express Root Port 0 (rev 02) 00:1f.0 ISA bridge: Intel Corporation 82801IB (ICH9) LPC Interface Controller (rev 02) 00:1f.2 SATA controller: Intel Corporation 82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] (rev 02) 00:1f.3 SMBus: Intel Corporation 82801I (ICH9 Family) SMBus Controller (rev 02) 01:00.0 PCI bridge: Texas Instruments XIO3130 PCI Express Switch (Upstream) (rev 02) 02:00.0 PCI bridge: Texas Instruments XIO3130 PCI Express Switch (Downstream) (rev 01) 03:00.0 Ethernet controller: Red Hat, Inc Virtio network device (rev 01) 04:00.0 PCI bridge: Texas Instruments XIO3130 PCI Express Switch (Upstream) (rev 02) 05:00.0 PCI bridge: Texas Instruments XIO3130 PCI Express Switch (Downstream) (rev 01) 05:01.0 PCI bridge: Texas Instruments XIO3130 PCI Express Switch (Downstream) (rev 01) 06:00.0 SCSI storage controller: Red Hat, Inc Virtio block device (rev 01) 08:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) [root@dhcp-66-145-44 ~]# lspci -vvv -t -[0000:00]-+-00.0 Intel Corporation 82G33/G31/P35/P31 Express DRAM Controller +-01.0 Red Hat, Inc. QXL paravirtual graphic card +-02.0-[01-03]----00.0-[02-03]----00.0-[03]----00.0 Red Hat, Inc Virtio network device +-03.0-[04-07]----00.0-[05-07]--+-00.0-[06]----00.0 Red Hat, Inc Virtio block device | -01.0-[07]-- +-04.0-[08]----00.0 Intel Corporation 82576 Gigabit Network Connection +-1f.0 Intel Corporation 82801IB (ICH9) LPC Interface Controller +-1f.2 Intel Corporation 82801IR/IO/IH (ICH9R/DO/DH) 6 port SATA Controller [AHCI mode] -1f.3 Intel Corporation 82801I (ICH9 Family) SMBus Controller [root@dhcp-66-145-44 ~]# ifconfig ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 00:1b:21:42:33:84 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0x98400000-9841ffff eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.66.145.44 netmask 255.255.252.0 broadcast 10.66.147.255 inet6 2620:52:0:4292:986a:6bff:fe6c:6d6e prefixlen 64 scopeid 0x0<global> inet6 fe80::986a:6bff:fe6c:6d6e prefixlen 64 scopeid 0x20<link> ether 9a:6a:6b:6c:6d:6e txqueuelen 1000 (Ethernet) RX packets 788 bytes 57561 (56.2 KiB) RX errors 0 dropped 6 overruns 0 frame 0 TX packets 150 bytes 20636 (20.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 Thanks Jing Zhao
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://rhn.redhat.com/errata/RHBA-2016-2673.html |
b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c @@ -940,22 +940,21 @@ Ip4StartAutoConfig ( &Instance->Dhcp4Handle ); - if (Status == EFI_UNSUPPORTED) { - // - // No DHCPv4 Service Binding protocol, register a notify. - // - if (Instance->Dhcp4SbNotifyEvent == NULL) { - Instance->Dhcp4SbNotifyEvent = EfiCreateProtocolNotifyEvent ( - &gEfiDhcp4ServiceBindingProtocolGuid, - TPL_CALLBACK, - Ip4Config2OnDhcp4SbInstalled, - (VOID *) Instance, - &Instance->Registration - ); - } - } - if (EFI_ERROR (Status)) { + if (Status == EFI_UNSUPPORTED) {^M + //^M + // No DHCPv4 Service Binding protocol, register a notify.^M + //^M + if (Instance->Dhcp4SbNotifyEvent == NULL) {^M + Instance->Dhcp4SbNotifyEvent = EfiCreateProtocolNotifyEvent (^M + &gEfiDhcp4ServiceBindingProtocolGuid,^M + TPL_CALLBACK,^M + Ip4Config2OnDhcp4SbInstalled,^M + (VOID *) Instance,^M + &Instance->Registration^M + );^M + }^M + }^M return Status; }