Comments (17)
Using EFI_SERIAL_IO_PROTOCOL
as an example, it's defined in the spec as:
typedef struct {
UINT32 Revision;
EFI_SERIAL_RESET Reset;
EFI_SERIAL_SET_ATTRIBUTES SetAttributes;
EFI_SERIAL_SET_CONTROL_BITS SetControl;
EFI_SERIAL_GET_CONTROL_BITS GetControl;
EFI_SERIAL_WRITE Write;
EFI_SERIAL_READ Read;
SERIAL_IO_MODE *Mode;
CONST EFI_GUID *DeviceTypeGuid; // Revision 1.1
} EFI_SERIAL_IO_PROTOCOL;
The type of SetControl
is EFI_SERIAL_SET_CONTROL_BITS
, which is a typedef defined under EFI_SERIAL_IO_PROTOCOL.SetControl
:
typedef
EFI_STATUS
(EFIAPI *EFI_SERIAL_SET_CONTROL_BITS) (
IN EFI_SERIAL_IO_PROTOCOL *This,
IN UINT32 Control
);
You can usually translate these function types pretty directly into Rust. Note that we don't bother with creating a type
alias in the Rust API, you can just write the function pointer type inline in the struct definition.
One last note, our definition of the function does look a little different from C in a couple ways:
- The name of the field is
set_control_bits
instead ofset_control
; that's actually just a mistake :) - The second arg's type is
ControlBits
instead of au32
, but thatControlBits
type is itself a wrapper around au32
type.
from uefi-rs.
I've put up a PR to add support for this protocol: #1109
Unfortunately, despite this having been added to the UEFI spec a while ago, it doesn't seem to be well supported. I tested a recent Lenovo, as well as OVMF in QEMU, and neither one has this protocol.
from uefi-rs.
Actually, the things I wanna ask you if some design about the callback,
Regarding how to use and implement callbacks, a good example is BootService::create_event:
uefi-rs/uefi/src/table/boot.rs
Lines 317 to 338 in 6093205
And here's an example of calling it:
uefi-rs/uefi-test-runner/src/boot/misc.rs
Lines 40 to 49 in 6093205
Note that although Rust does have closures (|param| { body }
), those can't be used here directly because we need to pass in a function with the correct ABI (efiapi
).
from uefi-rs.
Regarding the timestamp protocol, it seems to me that for whatever reason edk2 doesn't broadly enable it. I'm not 100% sure, but I don't think there's an easy way to just enable it at compile time; some code changes would be needed.
For the uefi-test-runner, it's intentional that it only works under QEMU. Originally it was more flexible and would only warn instead of fail if the environment was different, but this made the test less useful for actually finding errors. Several times I introduced a change that accidentally broke something, but we didn't notice because the test runner still "passed". So, we changed it to require QEMU, and provided prebuilt OVMF files that have various extra things enabled. See #553 for some more info.
from uefi-rs.
Hi, that protocol is not currently implemented in uefi-rs. (Contributions welcome, if you are interested in implementing it!) Depending on what your use case is, https://docs.rs/uefi/latest/uefi/table/runtime/struct.RuntimeServices.html#method.get_time might be an acceptable alternative.
from uefi-rs.
Hi, that protocol is not currently implemented in uefi-rs. (Contributions welcome, if you are interested in implementing it!) Depending on what your use case is, https://docs.rs/uefi/latest/uefi/table/runtime/struct.RuntimeServices.html#method.get_time might be an acceptable alternative.
if I want to implement it, how could I found the efiapi
which should be used. Is there any references or docs?
from uefi-rs.
First add the raw protocol in this directory: https://github.com/rust-osdev/uefi-rs/tree/main/uefi-raw/src/protocol. This could go in a new misc.rs
module. See protocol/loaded_image.rs
for an example of what this would look like -- basically just adding a TimestampProtocol
struct containing two function pointers, matching what's in the spec, and an associated GUID
constant.
Then you'll add the higher-level version to the uefi
package, in this directory: https://github.com/rust-osdev/uefi-rs/tree/main/uefi/src/proto. Again this would be a misc.rs
module, see proto/loaded_image.rs
for an example. Add a repr(transparent)
Timestamp
struct, and implement get_timestamp
and get_properties
.
That's the general outline, happy to answer questions about any of the details. And/or, feel free to put up a PR even if it's not complete, and I can make comments there too.
from uefi-rs.
First add the raw protocol in this directory: https://github.com/rust-osdev/uefi-rs/tree/main/uefi-raw/src/protocol. This could go in a new
misc.rs
module. Seeprotocol/loaded_image.rs
for an example of what this would look like -- basically just adding aTimestampProtocol
struct containing two function pointers, matching what's in the spec, and an associatedGUID
constant.Then you'll add the higher-level version to the
uefi
package, in this directory: https://github.com/rust-osdev/uefi-rs/tree/main/uefi/src/proto. Again this would be amisc.rs
module, seeproto/loaded_image.rs
for an example. Add arepr(transparent)
Timestamp
struct, and implementget_timestamp
andget_properties
.That's the general outline, happy to answer questions about any of the details. And/or, feel free to put up a PR even if it's not complete, and I can make comments there too.
like this:
uefi-rs/uefi-raw/src/protocol/console/serial.rs
Lines 78 to 98 in 86e200e
but I didn't know how to found out the
"efiapi"
's set_control_bits
func definition.from uefi-rs.
Weee!! I just completed the support of TimestampProtocol today yeah.
And another things, I have a doubt about ResetNotificationProtocol
and didn't know how to code it, it has a pointer to func which confuses me.
Docs:
EDK2:
from uefi-rs.
I've put up a PR to add support for this protocol: #1109
Unfortunately, despite this having been added to the UEFI spec a while ago, it doesn't seem to be well supported. I tested a recent Lenovo, as well as OVMF in QEMU, and neither one has this protocol.
I think its implementation is related to the UEFI Spec version number commonly used by vendors, probably an ancient version. It seem that I should find another way to get timestamp.
from uefi-rs.
One option you could try (if you are on x86) is the RDTSC
instruction, or RDTSCP
. These can be used to read a timestamp counter.
Depending on exactly what your needs are, this can be somewhat complex; see How to Benchmark Code Execution
Times on Intel IA-32 and IA-64 Instruction Set Architectures for details of execution barriers. Whether those details matter probably depends on whether you are microbenchmarking or looking at something longer running.
There's also the question of units. On new-ish processors the timestamp frequency is invariant, and on sufficiently new processors you can directly query the scaling factors needed to convert timestamps to seconds. See for example this code in edk2. On older processors you might need to figure out the frequency by measuring the timestamp on both sides of a call to BootServices::stall
. On the other hand, you can skip all of that if you only care about relative duration and don't need to convert to seconds.
from uefi-rs.
And another things, I have a doubt about ResetNotificationProtocol and didn't know how to code it, it has a pointer to func which confuses me.
A function pointer in Rust looks very much like a regular function definition. Here's an example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8ce6ab497a1119b2db8e1a22ac98742
extern "C" fn f2() {}
fn f1(fn_ptr: extern "C" fn() -> ()) {
dbg!(fn_ptr);
}
fn main() {
f1(f2);
}
from uefi-rs.
And another things, I have a doubt about ResetNotificationProtocol and didn't know how to code it, it has a pointer to func which confuses me.
A function pointer in Rust looks very much like a regular function definition. Here's an example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b8ce6ab497a1119b2db8e1a22ac98742
extern "C" fn f2() {} fn f1(fn_ptr: extern "C" fn() -> ()) { dbg!(fn_ptr); } fn main() { f1(f2); }
It seems that nothing different with C.
Actually, the things I wanna ask you if some design about the callback, I am new ruster, and for other language like Golang/Java has lambda function design. rust also has something like
let func_ptr = |x| -> {
fmt.println(x);
unsafe{
/* some code for ABI call */
}
}
set_callback(type, func_ptr);
I wanna know whether uefi-rs has any design or paradigm? The uefi-rs
would gives user or developer what kinds of ways/forms. the docs doesn't list any advices. I don't wanna break the rules.
Sorry for my poor English.
And Thanks for your guidance!
from uefi-rs.
One option you could try (if you are on x86) is the
RDTSC
instruction, orRDTSCP
. These can be used to read a timestamp counter.Depending on exactly what your needs are, this can be somewhat complex; see How to Benchmark Code Execution Times on Intel IA-32 and IA-64 Instruction Set Architectures for details of execution barriers. Whether those details matter probably depends on whether you are microbenchmarking or looking at something longer running.
There's also the question of units. On new-ish processors the timestamp frequency is invariant, and on sufficiently new processors you can directly query the scaling factors needed to convert timestamps to seconds. See for example this code in edk2. On older processors you might need to figure out the frequency by measuring the timestamp on both sides of a call to
BootServices::stall
. On the other hand, you can skip all of that if you only care about relative duration and don't need to convert to seconds.
yeah, the one that I need now is only the duration counter. I am an embeded developer for Arm Soc, it has a timer/counter which meet demand, And x86 should also has it. But now I try develop uefi app/driver at x86, just for fun, coding fun! but x86 is really complex which I couldn't easy to get the way.
thank you, I read the code, found they are using the reg named TSC (Time Stamp Counter), though affected by cpu hz. I ever use it in Linux.
and also could use the the ACPI Timer, HPET, or High Precision Event Timer, AP IC Timer/PIC and so on. see:
I found blog on the internet which recommend constant TSC > HPET > ACPI_PM > TSC > i8254
in Linux.
from uefi-rs.
PR #1116 , though in OVMF run at cargo run xtask
, review it please, and thanks for your teach. It print warn log as I code, hope that I don't make some mistake:
[ INFO]: uefi-test-runner\src\proto\misc.rs@020: Running loaded Timestamp Protocol test
[ WARN]: uefi-test-runner\src\proto\misc.rs@034: Failed to open Timestamp Protocol: Error { status: UNSUPPORTED, data: () }
[ INFO]: uefi-test-runner\src\proto\misc.rs@041: Running loaded ResetNotification protocol test
[ WARN]: uefi-test-runner\src\proto\misc.rs@076: Failed to open ResetNotification Protocol: Error { status: UNSUPPORTED, data: () }
the new log after I use readonly hook, I think it related to the runtime hook:
/// ```sh
[ INFO]: uefi-test-runner\src\proto\misc.rs@020: Running loaded Timestamp Protocol test
[ WARN]: uefi-test-runner\src\proto\misc.rs@037: Failed to found Timestamp Protocol: Error { status: NOT_FOUND, data: () }
[ INFO]: uefi-test-runner\src\proto\misc.rs@043: Running loaded ResetNotification protocol test
[ INFO]: uefi-test-runner\src\proto\misc.rs@053: ResetNotification Protocol register null test: Err(Error { status: INVALID_PARAMETER, data: () })
[ INFO]: uefi-test-runner\src\proto\misc.rs@059: ResetNotification Protocol unregister null test: Err(Error { status: INVALID_PARAMETER, data: () })
[ INFO]: uefi-test-runner\src\proto\misc.rs@078: ResetNotification Protocol register efi_reset_fn test: Ok(())
[ INFO]: uefi-test-runner\src\proto\misc.rs@084: ResetNotification Protocol unregister efi_reset_fn test: Ok(())
from uefi-rs.
Well, OVMF doesn't has the protocol compiled in, I suppose? Is there an easy way to add it to our pre-build OVMF version, @nicholasbishop ?
from uefi-rs.
Well, OVMF doesn't has the protocol compiled in, I suppose? Is there an easy way to add it to our pre-build OVMF version, @nicholasbishop ?
I run target/x86_64-unknown-uefi/debug/uefi-test-runner.efi
in VMware, and uefi-test-runner has a assert like this๏ผ
uefi-rs/uefi-test-runner/src/main.rs
Lines 24 to 42 in 6093205
I think it should be replaced as warnning if want to test on other platforms.
edit those two line assert code, I finally Test failed for VMware uefi firmware is old, even not support the console serial.
from uefi-rs.
Related Issues (20)
- Allow getting a MemoryMap from a pointer
- How do I get a device path of a efi image? HOT 2
- Nuke "uefi-services" from repository
- Feature Request: Implementing MP Protocol Compatibility in Hyper-V HOT 3
- Whether a lifecycle container/manager can be provided to store the currently open protocol? HOT 4
- Example application fails to build with "could not find `helpers` in `uefi`" HOT 3
- `uefi::helpers` not found / Rust UEFI Book out of sync HOT 2
- Can not write file HOT 2
- No graphics HOT 2
- Set default features for uefi crate
- Use `cargo xtask fmt --check` in CI
- After 1.83 is released: bump MSRV and un-gate error_in_core impls
- make MemoryMap own its buffer (Vec) HOT 2
- CI failing due to dead_code warnings on nightly HOT 2
- Change the book to build from the latest tag instead of the latest commit on main HOT 1
- Need help for ACPI table, rsdt and xsdt entries are aberrant HOT 3
- Just a question about how I can exit boot services correctly. HOT 4
- Redesign Allocator API HOT 5
- MemoryMapRef/MemoryMapRefMut constructors HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from uefi-rs.