blob: ef68bd23627b2bf4baf8aec559c7ffc9034f20f3 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#![deny(missing_docs)]
use std::collections::BTreeSet;
use std::fmt;
use crate::common::{PackageDetails, PackagedDriverDetails};
use assembly_file_relative_path::{FileRelativePathBuf, SupportsFileRelativePaths};
use assembly_images_config::BoardFilesystemConfig;
use serde::{Deserialize, Serialize};
/// This struct provides information about the "board" that a product is being
/// assembled to run on.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, SupportsFileRelativePaths)]
#[serde(deny_unknown_fields)]
pub struct BoardInformation {
/// The name of the board.
pub name: String,
/// Metadata about the board that's provided to the 'fuchsia.hwinfo.Board'
/// protocol and to the Board Driver via the PlatformID and BoardInfo ZBI
/// items.
#[serde(default)]
pub hardware_info: HardwareInfo,
/// The "features" that this board provides to the product.
///
/// NOTE: This is a still-evolving, loosely-coupled, set of identifiers.
/// It's an unstable interface between the boards and the platform.
#[serde(default)]
pub provided_features: Vec<String>,
/// Path to the devicetree binary (.dtb) this provided by this board.
#[serde(default)]
#[file_relative_paths]
pub devicetree: Option<FileRelativePathBuf>,
/// Configuration for the various filesystems that the product can choose to
/// include.
#[serde(default)]
#[file_relative_paths]
pub filesystems: BoardFilesystemConfig,
/// These are paths to the directories that are board input bundles that
/// this board configuration includes. Product assembly will always include
/// these into the images that it creates.
///
/// These are the board-specific artifacts that the Fuchsia platform needs
/// added to the assembled system in order to be able to boot Fuchsia on
/// this board.
///
/// Examples:
/// - the "board driver"
/// - storage drivers
///
/// If any of these artifacts are removed, even the 'bootstrap' feature set
/// may be unable to boot.
#[serde(default)]
#[file_relative_paths]
pub input_bundles: Vec<FileRelativePathBuf>,
/// Consolidated configuration from all of the BoardInputBundles. This is
/// not deserialized from the BoardConfiguration, but is instead created by
/// parsing each of the input_bundles and merging their configuration fields.
#[serde(skip_deserializing)]
#[file_relative_paths]
pub configuration: BoardProvidedConfig,
/// Configure kernel cmdline args
/// TODO: Move this into platform section below
#[serde(default)]
pub kernel: BoardKernelConfig,
/// Configure platform related feature
#[serde(default)]
pub platform: PlatformConfig,
}
/// This struct defines board-provided data for the 'fuchsia.hwinfo.Board' fidl
/// protocol and for the Platform_ID and Board_Info ZBI items.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct HardwareInfo {
/// This is the value returned in the 'BoardInfo.name' field, if different
/// from the name provided for the board itself. It's also the name that's
/// set in the PLATFORM_ID ZBI Item.
pub name: Option<String>,
/// The vendor id to add to a PLATFORM_ID ZBI Item.
pub vendor_id: Option<u32>,
/// The product id to add to a PLATFORM_ID ZBI Item.
pub product_id: Option<u32>,
/// The board revision to add to a BOARD_INFO ZBI Item.
pub revision: Option<u32>,
}
/// This struct defines a bundle of artifacts that can be included by the board
/// in the assembled image.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, SupportsFileRelativePaths)]
#[serde(deny_unknown_fields)]
pub struct BoardInputBundle {
/// These are the drivers that are included by this bundle.
#[file_relative_paths]
pub drivers: Vec<PackagedDriverDetails>,
/// These are the packages to include with this bundle.
#[file_relative_paths]
pub packages: Vec<PackageDetails>,
/// These are kernel boot arguments that are to be passed to the kernel when
/// this bundle is included in the assembled system.
pub kernel_boot_args: BTreeSet<String>,
/// Board-provided configuration for platform services. Each field of this
/// structure can only be provided by one of the BoardInputBundles that a
/// BoardInformation uses.
#[file_relative_paths]
pub configuration: Option<BoardProvidedConfig>,
}
/// This struct defines board-provided configuration for platform services and
/// features, used if those services are included by the product's supplied
/// platform configuration.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, SupportsFileRelativePaths)]
#[serde(deny_unknown_fields)]
pub struct BoardProvidedConfig {
/// Configuration for the cpu-manager service
#[file_relative_paths]
pub cpu_manager: Option<FileRelativePathBuf>,
/// Configuration for the power-manager service
#[file_relative_paths]
pub power_manager: Option<FileRelativePathBuf>,
/// Configuration for the power metrics recorder service
#[file_relative_paths]
pub power_metrics_recorder: Option<FileRelativePathBuf>,
/// Thermal configuration for the power-manager service
#[file_relative_paths]
pub thermal: Option<FileRelativePathBuf>,
}
/// This struct defines supported kernel features.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct BoardKernelConfig {
/// Enable the use of 'contiguous physical pages'. This should be enabled
/// when a significant contiguous memory size is required.
pub contiguous_physical_pages: bool,
}
/// This struct defines platform configurations specified by board.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct PlatformConfig {
/// Configure connectivity related features
#[serde(default)]
pub connectivity: ConnectivityConfig,
/// Configure development support related features
#[serde(default)]
pub development_support: DevelopmentSupportConfig,
}
/// This struct defines connectivity configurations.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct ConnectivityConfig {
/// Configure network related features
pub network: NetworkConfig,
}
/// This enum lists all the supported soc that can enable DAP
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum DapSoc {
/// Enable DAP for amlogic-t931g
#[serde(rename = "amlogic-t931g")]
AmlogicT931g,
/// Enable DAP for amlogic-s905d2
#[serde(rename = "amlogic-s905d2")]
AmlogicS905d2,
/// Enable DAP for amlogic-s905d3g
#[serde(rename = "amlogic-s905d3g")]
AmlogicS905d3g,
/// Enable DAP for amlogic-a311d
#[serde(rename = "amlogic-a311d")]
AmlogicA311d,
}
impl fmt::Display for DapSoc {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DapSoc::AmlogicT931g => write!(f, "amlogic-t931g"),
DapSoc::AmlogicS905d2 => write!(f, "amlogic-s905d2"),
DapSoc::AmlogicS905d3g => write!(f, "amlogic-s905d3g"),
DapSoc::AmlogicA311d => write!(f, "amlogic-a311d"),
}
}
}
/// This struct defines development support configurations.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct DevelopmentSupportConfig {
/// Configure debug access port for specific SoC
pub enable_debug_access_port_for_soc: Option<DapSoc>,
}
/// This struct defines network configurations.
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
#[serde(deny_unknown_fields)]
pub struct NetworkConfig {
/// This option instructs netsvc to use only the device whose topological
/// path ends with the option's value. All other devices are ignored by
/// netsvc. The topological path for a device can be determined from the
/// shell by running the `lsdev` command on the device
/// (e.g. `/dev/class/network/000` or `/dev/class/ethernet/000`).
pub netsvc_interface: Option<String>,
}
#[cfg(test)]
mod test {
use super::*;
use camino::Utf8PathBuf;
#[test]
fn test_basic_board_deserialize() {
let json = serde_json::json!({
"name": "sample board",
});
let parsed: BoardInformation = serde_json::from_value(json).unwrap();
let expected = BoardInformation { name: "sample board".to_owned(), ..Default::default() };
assert_eq!(parsed, expected);
}
#[test]
fn test_complete_board_deserialize_with_relative_paths() {
let board_dir = Utf8PathBuf::from("some/path/to/board");
let board_file = board_dir.join("board_configuration.json");
let json = serde_json::json!({
"name": "sample board",
"hardware_info": {
"name": "hwinfo_name",
"vendor_id": 1,
"product_id": 2,
"revision": 3,
},
"provided_features": [
"feature_a",
"feature_b"
],
"input_bundles": [
"bundle_a",
"bundle_b"
],
"devicetree": "test.dtb",
"kernel": {
"contiguous_physical_pages": true,
},
"platform": {
"development_support": {
"enable_debug_access_port_for_soc": "amlogic-t931g",
}
}
});
let parsed: BoardInformation = serde_json::from_value(json).unwrap();
let resolved = parsed.resolve_paths_from_file(board_file).unwrap();
let expected = BoardInformation {
name: "sample board".to_owned(),
hardware_info: HardwareInfo {
name: Some("hwinfo_name".into()),
vendor_id: Some(0x01),
product_id: Some(0x02),
revision: Some(0x03),
},
provided_features: vec!["feature_a".into(), "feature_b".into()],
input_bundles: vec![
FileRelativePathBuf::Resolved("some/path/to/board/bundle_a".into()),
FileRelativePathBuf::Resolved("some/path/to/board/bundle_b".into()),
],
devicetree: Some(FileRelativePathBuf::Resolved("some/path/to/board/test.dtb".into())),
kernel: BoardKernelConfig { contiguous_physical_pages: true },
platform: PlatformConfig {
connectivity: ConnectivityConfig::default(),
development_support: DevelopmentSupportConfig {
enable_debug_access_port_for_soc: Some(DapSoc::AmlogicT931g),
},
},
..Default::default()
};
assert_eq!(resolved, expected);
}
}