1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Support for firmware binaries designed to run on a RISC-V core. Such firmwares files have a 4 //! dedicated header. 5 6 use kernel::{ 7 device, 8 dma::Coherent, 9 firmware::Firmware, 10 prelude::*, // 11 }; 12 13 use crate::firmware::tlv::Tlv; 14 15 /// A parsed firmware for a RISC-V core, ready to be loaded and run. 16 pub(crate) struct RiscvFirmware { 17 /// Offset at which the code starts in the firmware image. 18 pub(crate) code_offset: u32, 19 /// Offset at which the data starts in the firmware image. 20 pub(crate) data_offset: u32, 21 /// Offset at which the manifest starts in the firmware image. 22 pub(crate) manifest_offset: u32, 23 /// Application version. 24 pub(crate) app_version: u32, 25 /// Device-mapped firmware image. 26 pub(crate) ucode: Coherent<[u8]>, 27 } 28 29 impl RiscvFirmware { 30 /// Parses the RISC-V firmware image contained in `fw`. 31 pub(crate) fn new(dev: &device::Device<device::Bound>, fw: &Firmware) -> Result<Self> { 32 let tlv = Tlv::new(fw.data())?; 33 dev_dbg!( 34 dev, 35 "loaded gsp bootloader firmware v{}\n", 36 tlv.get_string(b"VERS")? 37 ); 38 39 let code_offset = tlv.get_u32(b"CDOF")?; 40 let data_offset = tlv.get_u32(b"DAOF")?; 41 let manifest_offset = tlv.get_u32(b"MFOF")?; 42 let app_version = tlv.get_u32(b"APPV")?; 43 44 let ucode = Coherent::from_slice(dev, tlv.get_bytes(b"BLOB")?, GFP_KERNEL)?; 45 46 Ok(Self { 47 ucode, 48 code_offset, 49 data_offset, 50 manifest_offset, 51 app_version, 52 }) 53 } 54 } 55