OpenDevicePartnership / OpenDevicePartnership/odp-platform-common
Support vendor IP separation in multi-party platform definitions
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 1
- Forks
- 5
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 9
Description
Problem
Patina's platform definition model assumes all platform code is compiled from source in a single build. This works well when one organization owns the entire stack, but breaks down when multiple parties with different IP constraints need to contribute to the same platform binary.
The concrete scenario driving this:
- OEMs (e.g. Dell) define proprietary platform components, services, and driver logic that they do not want visible to third parties — not as source, and ideally not modifiable at all.
- ODMs (Original Design Manufacturers) build the physical boards and need to customize configuration values (memory manager base addresses, chassis types, serial numbers, thermal limits, etc.) without access to the OEM's proprietary code.
- The same platform definition must work on both TianoCore (via
patina-tianocore) and Patina native (viapatina_dxe_core) without separate codepaths per backend.
In the traditional EDK2/TianoCore world, this is solved by:
- PCDs (Platform Configuration Database) — typed key-value pairs that ODMs set in VPD/DSC files without touching driver source
- Separate
.efiimages — each vendor ships a sealed PE/COFF binary, the DXE dispatcher wires them together at boot via protocol GUIDs and DEPEX expressions - IBV build pipelines — proprietary modules are compiled by the vendor's CI; ODMs submit configuration, not code
Patina intentionally moves away from PCDs and toward a typed component/service/config model. This is a better developer experience, but it removes the separation mechanism that PCDs provided. Currently:
Core<P: PlatformInfo>is generic and monomorphized — the platform type must be known at compile time as source, not a precompiled artifact.ComponentInfois not object-safe — it has aSizedbound and uses generic marker types (Add<'a, Component>), so it can't be erased behind a trait object or binary boundary.- Patina's
Storageis in-process — services registered by one component are visible to all others within the same binary, but there's no cross-.efi-image service resolution without falling back to UEFI protocol install/locate. - Rust has no stable ABI — precompiled
.rlibfiles are tied to the exact compiler version and can't be distributed as sealed artifacts across toolchain boundaries.
The net effect is that there's no supported way for one party to ship sealed platform logic and another party to provide configuration, within Patina's current architecture.
Constraints
Any solution should:
- Preserve Patina's typed service/config model (not regress to untyped PCDs)
- Work identically on TianoCore and Patina native backends
- Avoid changes to
patina_dxe_core::CoreorPlatformInfoif possible - Allow the IP-owning vendor to ship an artifact the ODM cannot read or modify
- Allow the ODM to provide configuration without access to the vendor's source
- Scale to platforms with many drivers and many configuration points
Prior exploration
Solutions explored so far and their tradeoffs:
| Approach | Why it doesn't fully work |
|---|---|
Split Platform trait into logic + config traits |
Only works on patina-tianocore path; Patina native's ComponentInfo has no equivalent config injection point |
ODM ships config as Service<dyn BoardSettings> in a separate .efi |
Storage doesn't cross .efi image boundaries; would require protocol bridge that Patina discourages |
Make ComponentInfo object-safe for binary distribution |
Requires core changes (const init breaks, associated types can't be erased, Add<T> is generic) |
Ship OEM crate as precompiled .rlib |
No stable Rust ABI; toolchain version coupling; generics in .rlib get monomorphized in downstream crate, potentially exposing logic |
| CI pipeline as trust boundary (OEM build server composes both) | Works today as a process solution but doesn't address the architectural gap |
Open questions
- Should Patina have a first-class concept for "configuration that crosses organizational boundaries" — something between PCDs and today's
Config<T>? - Is there a way to split
ComponentInforegistration so that components/services come from one source and configs come from another, without making the trait object-safe? - Could a build-system-level solution (e.g., a Cargo plugin or Patina build tool that manages sealed crate composition) be sufficient, or does the framework itself need to change?
- Are there other multi-vendor firmware ecosystems (Zephyr, coreboot, etc.) that have solved this in a way that could inform Patina's approach?
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing Core< P: PlatformInfo >, ComponentInfo, Storage, patina-tianocore, and patina_dxe_core as described in the issue, then compare their registration and configuration boundaries. Done means a documented, implementable design that preserves typed configuration, supports both backends, and provides a sealed vendor artifact with ODM-provided configuration.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- embedded-iot
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100