Skip to content

Commit

Permalink
Read VBT from UEFI FFS
Browse files Browse the repository at this point in the history
Remove the embedded VBT file and instead read it from a file added in
edk2.

Signed-off-by: Tim Crawford <[email protected]>
  • Loading branch information
crawfxrd committed Dec 18, 2024
1 parent 530583c commit 43ab3c5
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 17 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,4 @@ jobs:
rustup show active-toolchain || rustup toolchain install
- name: Build UEFI application
env:
FIRMWARE_OPEN_VBT: "../lemp9.vbt"
run: make
9 changes: 3 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ license = "GPL-3.0-only"
lto = true

[dependencies]
redox_uefi_std = "0.1.13"
#redox_uefi_std = "0.1.13"
redox_uefi_std = { git = "https://gitlab.redox-os.org/tcrawford/uefi.git", branch = "dev/vbt" }
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
# System76 Platform GOP Policy

A VBT file is required for building.
A driver that installs the Intel Platform GOP Policy protocol. Requires a VBT
file included in the UEFI FFS with a specific GUID.

```
FIRMWARE_OPEN_VBT=../lemp9.vbt make
FILE FREEFORM = 56752da9-de6b-4895-8819-1945b6b76c22 {
SECTION RAW = vbt.rom
SECTION UI = "IntelGopVbt"
}
```

```
make
```

The `qemu` target will use the target directory as a pseudo-drive so the
driver files can be viewed.

```
FIRMWARE_OPEN_VBT=../lemp9.vbt make qemu
make qemu
```

In QEMU, the driver can be loaded using the UEFI Shell `load` command.
Expand Down
Binary file removed lemp9.vbt
Binary file not shown.
63 changes: 58 additions & 5 deletions src/gop_policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
#![allow(unused)]

use std::prelude::*;
use std::uefi::boot::InterfaceType;
use std::uefi::boot::{InterfaceType, LocateSearchType};
use std::uefi::firmware::{FirmwareVolume2, SectionType};
use std::uefi::memory::PhysicalAddress;

static VBT: &[u8] = include_bytes!(env!("FIRMWARE_OPEN_VBT"));
// From edk2
const VBT_FILE_GUID: Guid = guid!("56752da9-de6b-4895-8819-1945b6b76c22");

// Protocol definition

#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
#[repr(transparent)]
Expand Down Expand Up @@ -46,6 +50,8 @@ impl GopPolicy {
pub const REVISION_03: u32 = 0x03;
}

// Protocol implementation

extern "efiapi" fn GetPlatformLidStatus(CurrentLidStatus: *mut LidStatus) -> Status {
if CurrentLidStatus.is_null() {
return Status::INVALID_PARAMETER;
Expand All @@ -62,10 +68,56 @@ extern "efiapi" fn GetVbtData(VbtAddress: *mut PhysicalAddress, VbtSize: *mut u3
return Status::INVALID_PARAMETER;
}

unsafe { *VbtAddress = PhysicalAddress(VBT.as_ptr() as u64) };
unsafe { *VbtSize = VBT.len() as u32 };
let mut status = Status::SUCCESS;
let uefi = unsafe { std::system_table_mut() };

let mut count = 0;
let mut hbuffer = core::ptr::null_mut();
status = (uefi.BootServices.LocateHandleBuffer)(
LocateSearchType::ByProtocol,
&FirmwareVolume2::GUID,
core::ptr::null(),
&mut count,
&mut hbuffer,
);
if status.is_error() {
return Status::NOT_FOUND;
}

Status::SUCCESS
let handles = unsafe { core::slice::from_raw_parts(hbuffer, count) };
for handle in handles {
let mut interface = 0;
let _ = (uefi.BootServices.HandleProtocol)(
*handle,
&FirmwareVolume2::GUID,
&mut interface,
);

let mut vbt_ptr = core::ptr::null_mut();
let mut vbt_size = 0;
let mut auth_status = 0;

let fv: &FirmwareVolume2 = unsafe { &*(interface as *const FirmwareVolume2) };
let status = (fv.ReadSection)(
fv,
&VBT_FILE_GUID,
SectionType::RAW,
0,
&mut vbt_ptr,
&mut vbt_size,
&mut auth_status,
);

if status.is_success() {
unsafe { *VbtAddress = PhysicalAddress(vbt_ptr as u64) };
unsafe { *VbtSize = vbt_size as u32 };
break;
}
}

(uefi.BootServices.FreePool)(hbuffer as usize);

status
}

extern "efiapi" fn GetPlatformDockStatus(_CurrentDockStatus: DockStatus) -> Status {
Expand All @@ -86,6 +138,7 @@ impl GopPolicy {
pub fn install(self: Box<Self>) -> Result<()> {
let uefi = unsafe { std::system_table_mut() };

// NOTE: This leaks the handle so that it does not get dropped.
let self_ptr = Box::into_raw(self);
let mut handle = Handle(0);
Result::from((uefi.BootServices.InstallProtocolInterface)(
Expand Down

0 comments on commit 43ab3c5

Please sign in to comment.