Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apcb::load signature is different depending on whether we are in no_std or not #97

Closed
hanetzer opened this issue Jul 21, 2023 · 13 comments
Assignees

Comments

@hanetzer
Copy link

Ok so I don't grok rust at all, but managed to cook up the following code:

use std::{env, fs, process};
use amd_apcb::{Apcb, ApcbIoOptions};

fn main() {
    let file = if let Some(file) = env::args().nth(1) {
        file
    } else {
        eprintln!("apcb-parse <file>");
        process::exit(1);
    };

    let mut buffer = fs::read(file).unwrap();
    let mut apcb = Apcb::load(&mut buffer[0..], &ApcbIoOptions::default()).unwrap();
    let yaml = serde_yaml::to_string(&apcb)?;
}

This seems to be the right direction so far, but I'm utterly unfamiliar with rust semantics and
'the right way to do things', let alone reading a big lib like this to figure out what to do.

@daym
Copy link
Collaborator

daym commented Jul 22, 2023

Hello!

As the error message that Rust prints says, please do this:

13   |     let mut apcb = Apcb::load(std::borrow::Cow::Borrowed(&mut buffer[0..]), &ApcbIoOptions::default()).unwrap();                                                             

See also https://doc.rust-lang.org/std/borrow/enum.Cow.html for what this is for.

With this change (note: you also need features = ["serde"] on the amd-apcb dependency--but I think you have that already), your program builds and I get:

cargo run -- /tmp/APCB_GN_D4.bin 
Finished dev [unoptimized + debuginfo] target(s) in 0.02s
 Running `target/debug/tst-apcb /tmp/APCB_GN_D4.bin`
Error: Error("serializing nested enums in YAML is not supported yet")

And that's an upstream serde_yaml bug (I'm not saying it's good like that; but we shouldn't work around their bug). Could you file a bug report in serde_yaml? They even have a test case to ascertain that it doesn't work: https://github.com/dtolnay/serde-yaml/blob/6875bc7c7dcb2565358ef9ee5e926cfd2dec2e7b/tests/test_error.rs#L176

In production, we are using json5 and/or serde_json--those work fine. So please just substitute serde_yaml by serde_json in your program.

We use nested enums a lot, for example:

                                                                    tokens: [
                                                                            {
                                                                                    Bool: {
                                                                                            MemLrdimmCapable: true
                                                                                    }
                                                                            },

Why this isn't supposed to work in YAML (if the test case is any indication), the kitchen sink of formats, is beyond me :)

@daym daym self-assigned this Jul 22, 2023
@hanetzer
Copy link
Author

Gotcha, and thanks. So something like, serde_json::to_string or so?

@daym
Copy link
Collaborator

daym commented Jul 22, 2023

Yes, although I would use serde_json::to_string_pretty because it adds newlines and indentation.

@hanetzer
Copy link
Author

hrm. Unless I missed something you wrote, no joy.

use std::{env, fs, process};
use amd_apcb::{Apcb, ApcbIoOptions};

fn main() {
    let file = if let Some(file) = env::args().nth(1) {
        file
    } else {
        eprintln!("apcb-parse <file>");
        process::exit(1);
    };

    let mut buffer = fs::read(file).unwrap();
    let mut apcb = Apcb::load(std::borrow::Cow::Borrowed(&mut buffer[0..]), &ApcbIoOptions::default()).unwrap();
    let json = serde_json::to_string(&apcb);
    println!("{}", serde_json::to_string_pretty(&json).unwrap());
}

results in

error[E0277]: the trait bound `serde_json::Error: serde::ser::Serialize` is not satisfied
    --> src/main.rs:15:49
     |
15   |     println!("{}", serde_json::to_string_pretty(&json).unwrap());
     |                    ---------------------------- ^^^^^ the trait `serde::ser::Serialize` is not implemented for `serde_json::Error`
     |                    |
     |                    required by a bound introduced by this call
     |
     = help: the following other types implement trait `serde::ser::Serialize`:
               &'a T
               &'a mut T
               ()
               (T0, T1)
               (T0, T1, T2)
               (T0, T1, T2, T3)
               (T0, T1, T2, T3, T4)
               (T0, T1, T2, T3, T4, T5)
             and 312 others
     = note: required for `Result<std::string::String, serde_json::Error>` to implement `serde::ser::Serialize`
note: required by a bound in `to_string_pretty`
    --> ~/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_json-1.0.103/src/ser.rs:2215:17
     |
2215 |     T: ?Sized + Serialize,
     |                 ^^^^^^^^^ required by this bound in `to_string_pretty`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `apcb-parse` due to previous error

@daym
Copy link
Collaborator

daym commented Jul 22, 2023

serde_json::to_string_pretty(&apcb) ;)

I'd use either serde_json::to_string_pretty(&apcb) or serde_json::to_string(&apcb), not both.

@hanetzer
Copy link
Author

hanetzer commented Jul 22, 2023

oh wait, I'm dumb. Note that I hit the apcb with to_string, and then try to hit that with to_string_pretty. works now.

@hanetzer
Copy link
Author

On a non-rust related note: any kind of sharable documentation on the fields and meanings and such?
Once my 3200g arrives sometime next week I'm going to be trying to port a consumer desktop board
to coreboot (yeah I know its a different project/boot flow than what you guys use but I'm firmly entrenched
in the gentoo linux world).

@daym
Copy link
Collaborator

daym commented Jul 22, 2023

works now.

Great!

Is there a text Unknown in the resulting JSON output? Then that means the library could not identify what that is.

This will probably happen when you are using non-Milan-server architectures. It would be nice for someone to collect those and also the information what CPU model it is exactly, in order to have a set of tokens used per CPU model. Paging @orangecms, if he is interested :)

@hanetzer
Copy link
Author

yeah, there are 53 unknown fields; 52 of them are just

{
  "Unknown": [
    0
  ]
}

which I assume to just be padding of some form
while there's one which seems more significant:

          {
            "custom_error_type": "Smu",
            "peak_map": 21845,
            "peak_attr": {
              "peak_count": 15,
              "pulse_width": 3,
              "repeat_count": 0,
              "_reserved_1": 0
            }
          },
          {
            "custom_error_type": "Unknown",
            "peak_map": 21845,
            "peak_attr": {
              "peak_count": 3,
              "pulse_width": 3,
              "repeat_count": 0,
              "_reserved_1": 0
            }
          }

@hanetzer
Copy link
Author

(The above was produced from APCB_mandolin.bin in the coreboot blobs repo)

@daym
Copy link
Collaborator

daym commented Jul 22, 2023

Only? That's great and a lot better than I expected.

Yeah, AMD likes to add padding, sometimes, so that subsequent records are aligned to a 32 bit boundary.

@daym
Copy link
Collaborator

daym commented Jul 22, 2023

On a non-rust related note: any kind of sharable documentation on the fields and meanings and such?

I filed #98 for the documentation request

@daym daym changed the title help a bad rustacean: deserialize/print APCB binary file? Apcb::load is different depending on whether we are in no_std or in std Jul 22, 2023
@daym daym changed the title Apcb::load is different depending on whether we are in no_std or in std Apcb::load signature is different depending on whether we are in no_std or in std Jul 22, 2023
@daym daym changed the title Apcb::load signature is different depending on whether we are in no_std or in std Apcb::load signature is different depending on whether we are in no_std or not Jul 22, 2023
@daym
Copy link
Collaborator

daym commented Jul 22, 2023

Closing this as won't-fix (I wouldn't know how, and Cow is really OK).

But if you have further questions, feel free to ask. (For now, just creating issues for those questions is OK, but I'll look into whether we want to enable github discussion forum or something. But really, when there are questions like this it means we should improve the documentation, so it IS an issue :) )

@daym daym closed this as not planned Won't fix, can't repro, duplicate, stale Jul 22, 2023
daym added a commit that referenced this issue Jul 24, 2023
daym added a commit that referenced this issue Jul 24, 2023
daym added a commit that referenced this issue Jul 24, 2023
daym added a commit that referenced this issue Aug 7, 2023
daym added a commit that referenced this issue Aug 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants