diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/guc.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/guc.rs index 0508843277..04bc7554d3 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/guc.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/guc.rs @@ -44,10 +44,37 @@ const WOPCM_GUC_SIZE: u32 = 512 * 1024; const GUC_GGTT_RESERVED_SIZE: u64 = 2 * 1024 * 1024; +const CTB_DESC_SIZE: usize = 64; +const CTB_H2G_BUFFER_SIZE: usize = 4096; +const CTB_G2H_BUFFER_SIZE: usize = 4096; +const CTB_OWNER_HOST: u32 = 0; + +const GUC_CTL_CTB_H2G_ADDR: usize = 0xC3C0; +const GUC_CTL_CTB_G2H_ADDR: usize = 0xC3C4; +const GUC_CTL_ADS_ADDR: usize = 0xC3D0; + +const ADS_SCHED_POLICIES_OFFSET: usize = 0; +const ADS_ENGINE_MAP_OFFSET: usize = 256; +const ADS_REGISTERS_OFFSET: usize = 512; +const ADS_GOLDEN_CTX_OFFSET: usize = 768; +const ADS_MMIO_OFFSET: usize = 1024; +const ADS_SIZE: usize = 4096; + +pub struct GuCctbChannel { + pub desc_addr: u64, + pub buffer_addr: u64, + pub size: u32, + pub head: u32, + pub tail: u32, +} + pub struct GucFirmware { mmio: Arc, loaded: bool, wopcm_base: u64, + ctb_h2g: Option, + ctb_g2h: Option, + ads_addr: Option, } impl GucFirmware { @@ -56,6 +83,9 @@ impl GucFirmware { mmio, loaded: false, wopcm_base: 0, + ctb_h2g: None, + ctb_g2h: None, + ads_addr: None, } } @@ -210,4 +240,63 @@ impl GucFirmware { pub fn is_loaded(&self) -> bool { self.loaded } + + pub fn init_ctb_channels(&mut self, gtt: &mut IntelGtt) -> Result<()> { + if !self.loaded { + return Err(DriverError::Initialization( + "cannot init CTB before GuC firmware is loaded", + )); + } + + let desc_size = CTB_DESC_SIZE as u64; + let h2g_desc_addr = gtt.alloc_range(desc_size)?; + let h2g_buf_addr = gtt.alloc_range(CTB_H2G_BUFFER_SIZE as u64)?; + let g2h_desc_addr = gtt.alloc_range(desc_size)?; + let g2h_buf_addr = gtt.alloc_range(CTB_G2H_BUFFER_SIZE as u64)?; + + self.mmio.write32(GUC_CTL_CTB_H2G_ADDR, h2g_desc_addr as u32); + self.mmio.write32(GUC_CTL_CTB_H2G_ADDR + 4, (h2g_desc_addr >> 32) as u32); + + self.mmio.write32(GUC_CTL_CTB_G2H_ADDR, g2h_desc_addr as u32); + self.mmio.write32(GUC_CTL_CTB_G2H_ADDR + 4, (g2h_desc_addr >> 32) as u32); + + self.ctb_h2g = Some(GuCctbChannel { + desc_addr: h2g_desc_addr, + buffer_addr: h2g_buf_addr, + size: CTB_H2G_BUFFER_SIZE as u32, + head: 0, + tail: 0, + }); + + self.ctb_g2h = Some(GuCctbChannel { + desc_addr: g2h_desc_addr, + buffer_addr: g2h_buf_addr, + size: CTB_G2H_BUFFER_SIZE as u32, + head: 0, + tail: 0, + }); + + info!( + "redox-drm-intel: GuC CTB channels initialized — H2G desc {:#010x} buf {:#010x}, G2H desc {:#010x} buf {:#010x}", + h2g_desc_addr, h2g_buf_addr, g2h_desc_addr, g2h_buf_addr + ); + Ok(()) + } + + pub fn setup_ads(&mut self, gtt: &mut IntelGtt) -> Result<()> { + let ads_addr = gtt.alloc_range(ADS_SIZE as u64)?; + self.mmio.write32(GUC_CTL_ADS_ADDR, ads_addr as u32); + self.mmio.write32(GUC_CTL_ADS_ADDR + 4, (ads_addr >> 32) as u32); + self.ads_addr = Some(ads_addr); + + info!( + "redox-drm-intel: GuC ADS initialized at GGTT {:#010x} ({} bytes)", + ads_addr, ADS_SIZE + ); + Ok(()) + } + + pub fn ctb_ready(&self) -> bool { + self.ctb_h2g.is_some() && self.ctb_g2h.is_some() + } } diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/hangcheck.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/hangcheck.rs index 0a51cfa35b..0640370ef9 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/hangcheck.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/hangcheck.rs @@ -12,6 +12,10 @@ const RING_TAIL_OFFSET: usize = 0x30; const RING_RESET_CTL_OFFSET: usize = 0xD0; const RING_HWSTAM_OFFSET: usize = 0x98; const RING_INSTPM_OFFSET: usize = 0xC0; +const RING_START_OFFSET: usize = 0x38; +const RING_CTL_OFFSET: usize = 0x3C; +const RING_ESR_OFFSET: usize = 0xB8; +const RING_EMR_OFFSET: usize = 0xB0; const RESET_CTL_REQUEST_RESET: u32 = 1 << 0; const RESET_CTL_READY_TO_RESET: u32 = 1 << 1; diff --git a/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs b/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs index 2c7819b0e5..37f82d6993 100644 --- a/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs +++ b/local/recipes/gpu/redox-drm/source/src/drivers/intel/mod.rs @@ -328,6 +328,8 @@ impl IntelDriver { if let Some(fw_data) = guc_data { info!("redox-drm-intel: loading GuC firmware for {guc_key}"); guc.upload(fw_data, &mut gtt)?; + guc.init_ctb_channels(&mut gtt)?; + guc.setup_ads(&mut gtt)?; } else { warn!("redox-drm-intel: GuC firmware key '{guc_key}' not in cache, continuing without"); } diff --git a/recipes/core/bootloader/recipe.toml b/recipes/core/bootloader/recipe.toml index 1d8069f6a3..2dbcfd238e 100644 --- a/recipes/core/bootloader/recipe.toml +++ b/recipes/core/bootloader/recipe.toml @@ -5,15 +5,12 @@ path = "../../../local/sources/bootloader" template = "custom" script = """ OUTDIR="${COOKBOOK_BUILD}" -# Override TARGET: redoxer sets x86_64-unknown-redox but bootloader needs uefi target -export TARGET="x86_64-unknown-uefi" mkdir -pv "${COOKBOOK_STAGE}/usr/lib/boot" function bootloader { - export TARGET="$1" src="$2" dst="$3" - "${COOKBOOK_MAKE}" -j "${COOKBOOK_MAKE_JOBS}" -f "${COOKBOOK_SOURCE}/Makefile" -C "${OUTDIR}" "${OUTDIR}/${src}" + TARGET="$1" "${COOKBOOK_MAKE}" -j "${COOKBOOK_MAKE_JOBS}" -f "${COOKBOOK_SOURCE}/Makefile" -C "${OUTDIR}" "${OUTDIR}/${src}" cp -v "${OUTDIR}/${src}" "${COOKBOOK_STAGE}/usr/lib/boot/${dst}" }