[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH 09/25] tools/xenbindgen: Add support for bitmaps in TOML specs
Signed-off-by: Alejandro Vallejo <alejandro.vallejo@xxxxxxxxx> --- tools/rust/xenbindgen/src/c_lang.rs | 62 ++++++++++++++++++++++++++++- tools/rust/xenbindgen/src/spec.rs | 51 ++++++++++++++++++++++-- 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/tools/rust/xenbindgen/src/c_lang.rs b/tools/rust/xenbindgen/src/c_lang.rs index f15feca8df91..bba310233e60 100644 --- a/tools/rust/xenbindgen/src/c_lang.rs +++ b/tools/rust/xenbindgen/src/c_lang.rs @@ -17,7 +17,7 @@ use std::fmt::Write; -use crate::spec::{EnumDef, OutFileDef, StructDef, Typ}; +use crate::spec::{BitmapDef, EnumDef, OutFileDef, StructDef, Typ}; use convert_case::{Case, Casing}; use log::{debug, error, trace}; @@ -51,6 +51,20 @@ fn structfield(filedef: &OutFileDef, typ: &Typ, name: &str) -> String { ) } Typ::Struct(x) => format!("struct {x} {name}"), + Typ::Bitmap(x) => { + // Dealing with bitfields at the ABI boundary is a + // pain, so we just use the underlying type instead. + let Some(e) = filedef.bitmaps.iter().find(|y| *x == y.name) else { + error!("Can't find bitmap {x}. Typo?"); + trace!("{filedef:#?}"); + std::process::exit(1); + }; + format!( + "{} /* See {} */", + structfield(filedef, &e.typ, name), + e.name + ) + } Typ::Enum(x) => { // C can't use an enum as a field and fix its width. Look for its // underlying layout and use that type instead. @@ -137,6 +151,48 @@ fn enumgen(out: &mut String, def: &EnumDef) { writeln!(out).unwrap(); } +/// Write a C-compatible enum onto `out` +fn bitmapgen(out: &mut String, def: &BitmapDef) { + debug!("bitmap {}", def.name); + + comment(out, &def.description, Indentation(0)); + writeln!(out, "struct {} {{}}; /* GREP FODDER */", def.name).unwrap(); + + let mut mask = 0; + for f in &def.bits { + trace!(" shift {}={}", f.name, f.shift); + + if (1 << f.shift) & mask != 0 { + error!("Bad shift({}) on {}. Shadows another bit.", f.shift, f.name); + std::process::exit(1); + } + + mask |= 1 << f.shift; + + comment(out, &f.description, Indentation(0)); + writeln!( + out, + "#define {}_{} (1U{} << {})", + def.name.from_case(Case::Snake).to_case(Case::UpperSnake), + f.name.from_case(Case::Snake).to_case(Case::UpperSnake), + if def.typ == Typ::U64 { "LL" } else { "" }, + f.shift + ) + .unwrap(); + } + + comment(out, "Mask covering all defined bits", Indentation(0)); + writeln!( + out, + "#define {}__ALL ({:#X}U{})", + def.name.from_case(Case::Snake).to_case(Case::UpperSnake), + mask, + if def.typ == Typ::U64 { "LL" } else { "" }, + ) + .unwrap(); + writeln!(out).unwrap(); +} + /// Generates a single `.h` file. /// /// `filedef` is a language-agnostic high level description of what the output @@ -160,6 +216,10 @@ pub fn parse(filedef: &OutFileDef) -> String { enumgen(&mut out, def); } + for def in &filedef.bitmaps { + bitmapgen(&mut out, def); + } + for def in &filedef.structs { structgen(&mut out, filedef, def); } diff --git a/tools/rust/xenbindgen/src/spec.rs b/tools/rust/xenbindgen/src/spec.rs index f6cfedad2150..4a9c5e7d028b 100644 --- a/tools/rust/xenbindgen/src/spec.rs +++ b/tools/rust/xenbindgen/src/spec.rs @@ -28,6 +28,7 @@ use log::{debug, info}; #[derive(Debug, serde::Deserialize, PartialEq)] #[serde(rename_all = "lowercase", tag = "tag", content = "args")] pub enum Typ { + Bitmap(String), Enum(String), Struct(String), U8, @@ -72,7 +73,7 @@ pub struct FieldDef { pub struct EnumDef { /// snake-cased name of this enumeration. /// - /// Must be converted to whatever is idiomatic in the target language. + /// Must be converted to idiomatic casing in the target language. pub name: String, /// Description of what the type is for. /// @@ -88,11 +89,43 @@ pub struct EnumDef { pub variants: Vec<VariantDef>, } -/// A lang-agnostic description of a single variant of an enumerated type. +/// Lang-agnostic description of a bitmap type. +#[derive(Debug, serde::Deserialize)] +pub struct BitmapDef { + /// Snake-cased name of this bitmap. + /// + /// Must be converted to idiomatic casing in the target language. + pub name: String, + /// Description of what the type is for. + /// + /// Must be turned into documentation in the autogenerated file. + pub description: String, + /// Width of the type given as an equivalent primitive unsigned integer + /// of the same width. + pub typ: Typ, + /// List of bits in the bitmap with a described meaning. All other bits are + /// reserved to zero. + pub bits: Vec<BitDef>, +} + +/// Lang-agnostic description of a single bit within a particular bitmap type. +#[derive(Debug, serde::Deserialize)] +pub struct BitDef { + /// Snake-cased name of this bit. Depending on the backend, the name + /// might be prefixed by the name of its type (as is commonly done in C). + pub name: String, + /// Meaning of this bit in the context of its type. + pub description: String, + /// Position of the bit in the underlying type, following a little-endian + /// convention. + pub shift: u8, +} + +/// Lang-agnostic description of a single variant of an enumerated type. #[derive(Debug, serde::Deserialize)] pub struct VariantDef { - /// Name of this variant. Depending on the backend, the name might be - /// prefixed by the name of its type (as is commonly done in C). + /// Snake-cased name of this variant. Depending on the backend, the name + /// might be prefixed by the name of its type (as is commonly done in C). pub name: String, /// Meaning of this variant in the context of its type. pub description: String, @@ -108,6 +141,8 @@ struct InFileDef { structs: Option<Vec<StructDef>>, /// List of lang-agnostic enumerated descriptions. enums: Option<Vec<EnumDef>>, + /// List of lang-agnostic bitmap descriptions. + bitmaps: Option<Vec<BitmapDef>>, } /// Description of an abstract output (i.e: `.rs`, `.h`, etc). @@ -123,6 +158,10 @@ pub struct OutFileDef { /// /// Implementation is lang-specific. pub enums: Vec<EnumDef>, + /// List of bitmap descriptions. + /// + /// Implementation is lang-specific. + pub bitmaps: Vec<BitmapDef>, } impl OutFileDef { @@ -139,6 +178,7 @@ impl OutFileDef { name, structs: Vec::new(), enums: Vec::new(), + bitmaps: Vec::new(), }; for entry in from_ioerr(dir.read_dir())? { @@ -152,6 +192,9 @@ impl OutFileDef { if let Some(enums) = filedef.enums { ret.enums.extend(enums); } + if let Some(bitmaps) = filedef.bitmaps { + ret.bitmaps.extend(bitmaps); + } } Ok(ret) -- 2.47.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |