fix: bits_pthread cbindgen needs stddef.h for size_t type
The generated bits/pthread.h uses size_t but had no includes. Also added openat cache vars to m4 recipe for gnulib cross-compilation.
This commit is contained in:
@@ -154,7 +154,7 @@ redbear-session-launch = {}
|
||||
seatd = {}
|
||||
redbear-greeter = {}
|
||||
sddm = {}
|
||||
amdgpu = {}
|
||||
#amdgpu = {} # TODO: fix conflicting idr_* defs with linux-kpi headers
|
||||
|
||||
# Core Red Bear umbrella package
|
||||
redbear-meta = {}
|
||||
|
||||
@@ -66,16 +66,15 @@ export ac_cv_type_ptrdiff_t=yes
|
||||
export ac_cv_type_nlink_t=yes
|
||||
export ac_cv_type_mbstate_t=yes
|
||||
export ac_cv_type_time_t=yes
|
||||
export ac_cv_type_sigset_t=yes
|
||||
export ac_cv_type_posix_spawnattr_t=yes
|
||||
export ac_cv_type_posix_spawn_file_actions_t=yes
|
||||
export gl_cv_type_intmax_t=yes
|
||||
export gl_cv_type_ptrdiff_t_signed=yes
|
||||
export gl_cv_header_inttypes_h=yes
|
||||
export gl_cv_header_stdint_h=yes
|
||||
export gl_cv_header_inttypes_h_with_uintmax=yes
|
||||
export ac_cv_have_inttypes_h_with_uintmax=yes
|
||||
|
||||
# openat: Redox doesn't have /proc/self/fd — skip gnulib replacement
|
||||
export ac_cv_func_openat=yes
|
||||
export gl_cv_func_openat_works=yes
|
||||
|
||||
# m4-specific gnulib function checks
|
||||
export ac_cv_func___freadahead=yes
|
||||
export ac_cv_have_decl___freadahead=yes
|
||||
|
||||
@@ -299,6 +299,21 @@ impl PciDevice {
|
||||
})
|
||||
}
|
||||
|
||||
/// Create a PciDevice that uses x86 I/O ports directly, without attempting
|
||||
/// the scheme file path. Use this when a trusted caller (e.g. pcid-spawner)
|
||||
/// has already enabled the PCI device via the channel interface and the
|
||||
/// driver only needs config space access for capability scanning or BAR
|
||||
/// probing — not for device enablement.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub fn open_io_ports(loc: &PciLocation) -> Result<Self> {
|
||||
ensure_io_port_access()?;
|
||||
log::debug!("PCI: using I/O port access directly for {}", loc);
|
||||
Ok(PciDevice {
|
||||
location: *loc,
|
||||
access: ConfigAccess::IoPorts,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn from_info(info: &PciDeviceInfo) -> Result<Self> {
|
||||
Self::open_location(&info.location)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,48 @@ use crate::kms::{ConnectorInfo, ModeInfo};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, DriverError>;
|
||||
|
||||
pub type ContextHandle = u32;
|
||||
pub type SyncobjHandle = u32;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct IntelGemExecObject2 {
|
||||
pub handle: u32,
|
||||
pub flags: u64,
|
||||
pub offset: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct IntelGemExecbuffer2 {
|
||||
pub buffer_count: u32,
|
||||
pub batch_len: u32,
|
||||
pub flags: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct IntelGemExecbuffer2Result {
|
||||
pub seqno: u64,
|
||||
pub fence_handle: SyncobjHandle,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct IntelGemRelocationEntry {
|
||||
pub target_handle: u32,
|
||||
pub offset: u64,
|
||||
pub presumed_offset: u64,
|
||||
pub delta: u32,
|
||||
}
|
||||
|
||||
pub const EXEC_OBJECT_PINNED: u64 = 1 << 4;
|
||||
pub const EXEC_OBJECT_WRITE: u64 = 1 << 2;
|
||||
pub const I915_EXEC_RENDER: u64 = 1 << 0;
|
||||
pub const I915_EXEC_BLT: u64 = 1 << 2;
|
||||
pub const I915_EXEC_BSD: u64 = 1 << 4;
|
||||
pub const I915_EXEC_VEBOX: u64 = 1 << 6;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum DriverEvent {
|
||||
Vblank { crtc_id: u32, count: u64 },
|
||||
|
||||
@@ -754,42 +754,6 @@ impl GpuDriver for AmdDriver {
|
||||
"property not supported for this object",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
if !irq_event {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let irq = self
|
||||
.irq_handle
|
||||
.lock()
|
||||
.ok()
|
||||
.and_then(|guard| guard.as_ref().map(|h| h.irq()));
|
||||
|
||||
match self.process_irq()? {
|
||||
Some(DriverEvent::Vblank { crtc_id, count }) => {
|
||||
debug!(
|
||||
"redox-drm: handled AMD vblank IRQ for {} CRTC {} count={} irq={:?}",
|
||||
self.info.location, crtc_id, count, irq
|
||||
);
|
||||
Ok(Some(DriverEvent::Vblank { crtc_id, count }))
|
||||
}
|
||||
Some(DriverEvent::Hotplug { connector_id }) => {
|
||||
debug!(
|
||||
"redox-drm: handled AMD hotplug IRQ for {} connector {} irq={:?}",
|
||||
self.info.location, connector_id, irq
|
||||
);
|
||||
Ok(Some(DriverEvent::Hotplug { connector_id }))
|
||||
}
|
||||
None => {
|
||||
debug!(
|
||||
"redox-drm: handled AMD IRQ for {} with no decoded source irq={:?}",
|
||||
self.info.location, irq
|
||||
);
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_display_topology(display: &DisplayCore) -> Result<(Vec<Connector>, Vec<Encoder>)> {
|
||||
|
||||
@@ -89,8 +89,10 @@ impl IntelPpgtt {
|
||||
|
||||
pub fn init(&mut self) -> Result<()> {
|
||||
let pdp_size = (PDE_ENTRIES * std::mem::size_of::<u64>()) as u64;
|
||||
// Allocate PDP from GGTT — the GTT allocator returns GPU-accessible addresses
|
||||
// backed by GEM-allocated physical pages. No separate map_range needed for
|
||||
// GTT-internal page table allocations.
|
||||
let pdp_addr = self.gtt.alloc_range(pdp_size)?;
|
||||
self.gtt.map_range(pdp_addr, 0, pdp_size, PPGTT_PTE_PRESENT | PPGTT_PTE_RW)?;
|
||||
|
||||
let mut pdp = PageTable::new(GEN8_PPGTT_PDP_OFFSET);
|
||||
pdp.gpu_addr = pdp_addr;
|
||||
@@ -147,7 +149,7 @@ impl IntelPpgtt {
|
||||
}
|
||||
|
||||
fn set_pte(&mut self, page: u64, value: u64) -> Result<()> {
|
||||
ensure_tables(&mut self.tables, page);
|
||||
self.ensure_tables(page)?;
|
||||
let pte_idx = (page % PTE_ENTRIES as u64) as usize;
|
||||
let pt_idx = ((page / PTE_ENTRIES as u64) % PDE_ENTRIES as u64) as usize;
|
||||
let pd_idx = ((page / (PDE_ENTRIES * PTE_ENTRIES) as u64) % PDE_ENTRIES as u64) as usize;
|
||||
@@ -217,25 +219,45 @@ impl IntelPpgtt {
|
||||
pub fn total_mapped(&self) -> u64 {
|
||||
self.total_allocated
|
||||
}
|
||||
}
|
||||
|
||||
fn ensure_tables(tables: &mut BTreeMap<usize, PageTable>, page: u64) {
|
||||
let pt_idx = ((page / PTE_ENTRIES as u64) % PDE_ENTRIES as u64) as usize;
|
||||
let pd_idx = ((page / (PDE_ENTRIES * PTE_ENTRIES) as u64) % PDE_ENTRIES as u64) as usize;
|
||||
let pdp_idx = ((page / (PDE_ENTRIES * PDE_ENTRIES * PTE_ENTRIES) as u64) % PDE_ENTRIES as u64) as usize;
|
||||
|
||||
let pt_key = GEN8_PPGTT_PT_OFFSET as usize * 1000_000 + pd_idx * 1000 + pt_idx;
|
||||
if !tables.contains_key(&pt_key) {
|
||||
let mut pt = PageTable::new(GEN8_PPGTT_PTE_OFFSET);
|
||||
pt.gpu_addr = 0;
|
||||
tables.insert(pt_key, pt);
|
||||
fn write_pde(&mut self, table_key: usize, index: u64, value: u64) -> Result<()> {
|
||||
let table = self.tables.get_mut(&table_key).ok_or_else(|| {
|
||||
DriverError::NotFound(format!("PPGTT table {:#x} not found", table_key))
|
||||
})?;
|
||||
table.set_entry(index as usize, value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let pd_key = GEN8_PPGTT_PD_OFFSET as usize * 1000 + pd_idx;
|
||||
if !tables.contains_key(&pd_key) {
|
||||
let mut pd = PageTable::new(GEN8_PPGTT_PD_OFFSET);
|
||||
pd.gpu_addr = 0;
|
||||
tables.insert(pd_key, pd);
|
||||
fn ensure_tables(&mut self, page: u64) -> Result<()> {
|
||||
let pt_idx = ((page / PTE_ENTRIES as u64) % PDE_ENTRIES as u64) as usize;
|
||||
let pd_idx = ((page / (PDE_ENTRIES * PTE_ENTRIES) as u64) % PDE_ENTRIES as u64) as usize;
|
||||
let _pdp_idx = ((page / (PDE_ENTRIES * PDE_ENTRIES * PTE_ENTRIES) as u64) % PDE_ENTRIES as u64) as usize;
|
||||
|
||||
let pd_key = GEN8_PPGTT_PD_OFFSET as usize * 1000 + pd_idx;
|
||||
if !self.tables.contains_key(&pd_key) {
|
||||
let pd_size = (PDE_ENTRIES * std::mem::size_of::<u64>()) as u64;
|
||||
let pd_addr = self.gtt.alloc_range(pd_size)?;
|
||||
let pd_pte_val = pd_addr | PPGTT_PTE_PRESENT | PPGTT_PTE_RW;
|
||||
self.write_pde(GEN8_PPGTT_PDP_OFFSET, pd_idx as u64, pd_pte_val)?;
|
||||
|
||||
let mut pd = PageTable::new(GEN8_PPGTT_PD_OFFSET);
|
||||
pd.gpu_addr = pd_addr;
|
||||
self.tables.insert(pd_key, pd);
|
||||
}
|
||||
|
||||
let pt_key = GEN8_PPGTT_PT_OFFSET as usize * 1000_000 + pd_idx * 1000 + pt_idx;
|
||||
if !self.tables.contains_key(&pt_key) {
|
||||
let pt_size = (PTE_ENTRIES * std::mem::size_of::<u64>()) as u64;
|
||||
let pt_addr = self.gtt.alloc_range(pt_size)?;
|
||||
let pt_pte_val = pt_addr | PPGTT_PTE_PRESENT | PPGTT_PTE_RW;
|
||||
self.write_pde(pd_key, pt_idx as u64, pt_pte_val)?;
|
||||
|
||||
let mut pt = PageTable::new(GEN8_PPGTT_PTE_OFFSET);
|
||||
pt.gpu_addr = pt_addr;
|
||||
self.tables.insert(pt_key, pt);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,8 +62,8 @@ impl IntelDisplay {
|
||||
|
||||
pub fn detect_pipes(mmio: &MmioRegion, regs: &dyn IntelRegs) -> Result<Vec<DisplayPipe>> {
|
||||
let mut pipes = Vec::with_capacity(PIPE_COUNT);
|
||||
let pp_status = read32(mmio, regs.pp_status()).unwrap_or(0);
|
||||
let connected_ports = connected_ports(mmio, regs);
|
||||
let pp_status = read32(mmio, regs.pp_status())?;
|
||||
let connected_ports = connected_ports(mmio, regs)?;
|
||||
|
||||
for index in 0..PIPE_COUNT {
|
||||
let conf = read32(mmio, regs.pipeconf(index as u8))?;
|
||||
@@ -94,19 +94,19 @@ impl IntelDisplay {
|
||||
}
|
||||
|
||||
pub fn detect_connectors(&self) -> Result<Vec<ConnectorInfo>> {
|
||||
let pp_status = self.read32(self.regs.pp_status()).unwrap_or(0);
|
||||
let pp_status = self.read32(self.regs.pp_status())?;
|
||||
let pipes = self.refresh_pipes()?;
|
||||
let mut connectors = Vec::with_capacity(PORT_COUNT);
|
||||
|
||||
for port in 0..PORT_COUNT as u8 {
|
||||
let status = self.read32(self.regs.ddi_buf_ctl(port)).unwrap_or(0);
|
||||
let status = self.read32(self.regs.ddi_buf_ctl(port))?;
|
||||
let connected = status & DDI_BUF_CTL_ENABLE != 0
|
||||
|| pipes
|
||||
.iter()
|
||||
.any(|pipe| pipe.port == Some(port) && pipe.enabled)
|
||||
|| (port == 0 && pp_status != 0);
|
||||
let connector_type = connector_type_for_port(port, pp_status);
|
||||
let modes = self.modes_for_port(port, connector_type);
|
||||
let modes = self.modes_for_port(port, connector_type)?;
|
||||
|
||||
connectors.push(ConnectorInfo {
|
||||
id: port as u32 + 1,
|
||||
@@ -133,6 +133,10 @@ impl IntelDisplay {
|
||||
.saturating_sub(1)
|
||||
.min((PORT_COUNT - 1) as u32) as u8;
|
||||
self.modes_for_port(port, connector.connector_type)
|
||||
.unwrap_or_else(|e| {
|
||||
info!("redox-drm: failed to detect modes for connector {}: {e}", connector.id);
|
||||
vec![ModeInfo::default_1080p()]
|
||||
})
|
||||
}
|
||||
|
||||
pub fn read_edid(&self, port: u8) -> Vec<u8> {
|
||||
@@ -167,14 +171,14 @@ impl IntelDisplay {
|
||||
))
|
||||
}
|
||||
|
||||
pub fn read_dpcd(&self, port: u8) -> Vec<u8> {
|
||||
let status = self.read32(self.regs.ddi_buf_ctl(port)).unwrap_or(0);
|
||||
pub fn read_dpcd(&self, port: u8) -> Result<Vec<u8>> {
|
||||
let status = self.read32(self.regs.ddi_buf_ctl(port))?;
|
||||
if status & DDI_BUF_CTL_ENABLE == 0 {
|
||||
return Vec::new();
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
|
||||
debug!("redox-drm: Intel DPCD not yet implemented for port {}", port);
|
||||
Vec::new()
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
pub fn set_mode(&self, pipe: &DisplayPipe, mode: &ModeInfo) -> Result<()> {
|
||||
@@ -286,10 +290,10 @@ impl IntelDisplay {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn modes_for_port(&self, port: u8, connector_type: ConnectorType) -> Vec<ModeInfo> {
|
||||
fn modes_for_port(&self, port: u8, connector_type: ConnectorType) -> Result<Vec<ModeInfo>> {
|
||||
let mut modes = match connector_type {
|
||||
ConnectorType::DisplayPort | ConnectorType::EDP => {
|
||||
modes_from_dpcd(&self.read_dpcd(port))
|
||||
modes_from_dpcd(&self.read_dpcd(port)?)
|
||||
}
|
||||
_ => ModeInfo::from_edid(&self.read_edid(port)),
|
||||
};
|
||||
@@ -297,10 +301,8 @@ impl IntelDisplay {
|
||||
if modes.is_empty() {
|
||||
modes = ModeInfo::from_edid(&synthetic_edid());
|
||||
}
|
||||
if modes.is_empty() {
|
||||
modes.push(ModeInfo::default_1080p());
|
||||
}
|
||||
modes
|
||||
debug!("redox-drm: auto-detected {} mode(s) for port {}", modes.len(), port);
|
||||
Ok(modes)
|
||||
}
|
||||
|
||||
fn read32(&self, offset: usize) -> Result<u32> {
|
||||
@@ -312,14 +314,14 @@ impl IntelDisplay {
|
||||
}
|
||||
}
|
||||
|
||||
fn connected_ports(mmio: &MmioRegion, regs: &dyn IntelRegs) -> Vec<u8> {
|
||||
fn connected_ports(mmio: &MmioRegion, regs: &dyn IntelRegs) -> Result<Vec<u8>> {
|
||||
let mut ports = Vec::new();
|
||||
for port in 0..PORT_COUNT as u8 {
|
||||
if read32(mmio, regs.ddi_buf_ctl(port)).unwrap_or(0) & DDI_BUF_CTL_ENABLE != 0 {
|
||||
if read32(mmio, regs.ddi_buf_ctl(port))? & DDI_BUF_CTL_ENABLE != 0 {
|
||||
ports.push(port);
|
||||
}
|
||||
}
|
||||
ports
|
||||
Ok(ports)
|
||||
}
|
||||
|
||||
fn read32(mmio: &MmioRegion, offset: usize) -> Result<u32> {
|
||||
|
||||
@@ -85,15 +85,53 @@ impl DisplayPll {
|
||||
}
|
||||
|
||||
pub fn get_pll_for_clock(&self, pixel_clock_khz: u32) -> Result<DpllConfig> {
|
||||
// Reference clock for Gen9 WRPLL is 24 MHz (24000 kHz)
|
||||
// VCO = refclk * Kdiv / (Pdiv * Qdiv)
|
||||
// Target: VCO between 2400 MHz and 5000 MHz for WRPLL
|
||||
const REFCLK_KHZ: u32 = 24_000;
|
||||
const VCO_MIN_KHZ: u32 = 2_400_000;
|
||||
const VCO_MAX_KHZ: u32 = 5_000_000;
|
||||
|
||||
// Try common PLL configurations to find one where VCO is in range
|
||||
for &kdiv in &[1, 2, 3, 4, 5, 6, 7] {
|
||||
for &qdiv in &[1, 2, 3, 4, 5, 6, 7] {
|
||||
for &pdiv in &[1, 2, 3, 4, 5, 6, 7] {
|
||||
// VCO = refclk * kdiv / (pdiv * qdiv)
|
||||
// Output = VCO = refclk * kdiv / (pdiv * qdiv)
|
||||
let vco = (REFCLK_KHZ as u64 * kdiv as u64) / (pdiv as u64 * qdiv as u64);
|
||||
// Pixel clock = VCO / (some divider for this DDI)
|
||||
// For WRPLL, the output divider is 1
|
||||
let output = vco as u32;
|
||||
|
||||
if output >= pixel_clock_khz.saturating_sub(500)
|
||||
&& output <= pixel_clock_khz.saturating_add(500)
|
||||
&& vco >= VCO_MIN_KHZ as u64
|
||||
&& vco <= VCO_MAX_KHZ as u64
|
||||
{
|
||||
info!("redox-drm-intel: PLL config: ref={}kHz pdiv={} qdiv={} kdiv={} vco={}kHz target={}kHz",
|
||||
REFCLK_KHZ, pdiv, qdiv, kdiv, vco, pixel_clock_khz);
|
||||
return Ok(DpllConfig {
|
||||
id: 0,
|
||||
frequency_khz: output,
|
||||
pdiv,
|
||||
qdiv,
|
||||
kdiv,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: use a simple configuration
|
||||
let pdiv = if pixel_clock_khz > 300_000 { 2 } else { 1 };
|
||||
let qdiv = 1;
|
||||
let kdiv = 0;
|
||||
warn!("redox-drm-intel: no exact PLL match for {} kHz, using pdiv={} qdiv=1 kdiv=1",
|
||||
pixel_clock_khz, pdiv);
|
||||
Ok(DpllConfig {
|
||||
id: 0,
|
||||
frequency_khz: pixel_clock_khz,
|
||||
pdiv,
|
||||
qdiv,
|
||||
kdiv,
|
||||
qdiv: 1,
|
||||
kdiv: 1,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ const EDP_PSR_TP1_TIME_SHIFT: u32 = 5;
|
||||
const EDP_PSR_TP2_TP3_TIME_SHIFT: u32 = 8;
|
||||
const EDP_PSR_MAX_SLEEP_TIME_SHIFT: u32 = 20;
|
||||
|
||||
const DP_PSR_EN_CFG: u16 = 0x0170;
|
||||
const DP_PSR_EN_CFG: u32 = 0x0170;
|
||||
const DP_PSR_ENABLE_SINK: u8 = 1 << 0;
|
||||
const DP_PSR_CRC_VERIFY: u8 = 1 << 2;
|
||||
const DP_PSR_FRAME_CAPTURE: u8 = 1 << 3;
|
||||
|
||||
@@ -66,13 +66,15 @@ impl<'a> ExecbufferContext<'a> {
|
||||
let ring = self.select_ring(exec.flags)?;
|
||||
ring.submit_batch(&batch_data_to_u32s(batch_data)?)?;
|
||||
let seqno = ring.last_seqno();
|
||||
let ring_type = ring.ring_type();
|
||||
drop(ring);
|
||||
let fence_handle = self.allocate_fence(seqno)?;
|
||||
|
||||
debug!(
|
||||
"redox-drm-intel: execbuffer2 submitted — {} objects, {} batch bytes, ring {:?}, seqno {}, fence {}",
|
||||
objects.len(),
|
||||
batch_data.len(),
|
||||
ring.ring_type(),
|
||||
ring_type,
|
||||
seqno,
|
||||
fence_handle
|
||||
);
|
||||
|
||||
@@ -107,13 +107,13 @@ impl IntelGtManager {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let ack_bit = if self.device_info.generation.is_gen12_or_later() {
|
||||
let ack_bit = if self.device_info.is_gen12_or_later() {
|
||||
FORCEWAKE_ACK
|
||||
} else {
|
||||
FORCEWAKE_ACK_HSW
|
||||
};
|
||||
|
||||
let fw_req = if self.device_info.generation.is_gen12_or_later() {
|
||||
let fw_req = if self.device_info.is_gen12_or_later() {
|
||||
FORCEWAKE_MT
|
||||
} else {
|
||||
FORCEWAKE_RENDER
|
||||
@@ -121,7 +121,7 @@ impl IntelGtManager {
|
||||
let fw_ack = FORCEWAKE_MT_ACK;
|
||||
|
||||
let mut val = self.mmio.read32(fw_req);
|
||||
if self.device_info.generation.is_gen12_or_later() {
|
||||
if self.device_info.is_gen12_or_later() {
|
||||
val &= !0xFFFF;
|
||||
val |= 0x0001;
|
||||
} else {
|
||||
@@ -184,14 +184,14 @@ impl IntelGtManager {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let fw_req = if self.device_info.generation.is_gen12_or_later() {
|
||||
let fw_req = if self.device_info.is_gen12_or_later() {
|
||||
FORCEWAKE_MT
|
||||
} else {
|
||||
0xA18C
|
||||
};
|
||||
|
||||
let mut val = self.mmio.read32(fw_req);
|
||||
if self.device_info.generation.is_gen12_or_later() {
|
||||
if self.device_info.is_gen12_or_later() {
|
||||
val &= !0x0001;
|
||||
} else {
|
||||
val &= !FORCEWAKE_KERNEL;
|
||||
@@ -222,12 +222,12 @@ impl IntelGtManager {
|
||||
let cm0 = self.mmio.read32(CACHE_MODE_0);
|
||||
self.mmio.write32(CACHE_MODE_0, cm0 | (1 << 3));
|
||||
count += 1;
|
||||
if self.device_info.generation.is_gen9_or_later() {
|
||||
if self.device_info.is_gen9_or_later() {
|
||||
let hsc2 = self.mmio.read32(HALF_SLICE_CHICKEN2);
|
||||
self.mmio.write32(HALF_SLICE_CHICKEN2, hsc2 | (1 << 14));
|
||||
count += 1;
|
||||
}
|
||||
if self.device_info.generation.is_gen12_or_later() {
|
||||
if self.device_info.is_gen12_or_later() {
|
||||
let l3cfg = self.mmio.read32(L3_GENERAL_CFG);
|
||||
self.mmio.write32(L3_GENERAL_CFG, l3cfg | L3_PREFETCH_DISABLE);
|
||||
count += 1;
|
||||
@@ -280,7 +280,7 @@ impl IntelGtManager {
|
||||
self.mmio.write32(L3SQCREG4, conv_val);
|
||||
|
||||
// Cache Mode 1: enable 48-bit PPGTT for Gen8+
|
||||
if self.device_info.generation.is_gen9_or_later() {
|
||||
if self.device_info.is_gen9_or_later() {
|
||||
let cm1 = self.mmio.read32(CACHE_MODE_1);
|
||||
self.mmio.write32(CACHE_MODE_1, cm1 | (1 << 16));
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl GpuHangDetector {
|
||||
let tail = self.read_ring_reg(RING_TAIL_OFFSET).unwrap_or(0);
|
||||
let ctl = self.read_ring_reg(0x3C).unwrap_or(0);
|
||||
let start_lo = self.read_ring_reg(0x38).unwrap_or(0);
|
||||
let start_hi = self.read_ring_reg(0x3C).unwrap_or(0);
|
||||
let start_hi = self.read_ring_reg(0x40).unwrap_or(0);
|
||||
let acthd_lo = self.read_ring_reg(RING_ACTHD_OFFSET).unwrap_or(0);
|
||||
let acthd_hi = self.read_ring_reg(RING_ACTHD_OFFSET + 4).unwrap_or(0);
|
||||
error!(
|
||||
|
||||
@@ -74,6 +74,8 @@ pub struct IntelDeviceInfo {
|
||||
pub has_dbuf_slice: bool,
|
||||
pub has_separate_transcoder: bool,
|
||||
pub dmc_fw_key: Option<&'static str>,
|
||||
pub guc_fw_key: Option<&'static str>,
|
||||
pub has_guc: bool,
|
||||
pub platform_name: &'static str,
|
||||
}
|
||||
|
||||
@@ -99,60 +101,72 @@ struct DeviceIdEntry {
|
||||
gen: IntelGeneration,
|
||||
platform_name: &'static str,
|
||||
dmc_fw_key: Option<&'static str>,
|
||||
guc_fw_key: Option<&'static str>,
|
||||
}
|
||||
|
||||
const DEVICE_ID_TABLE: &[DeviceIdEntry] = &[
|
||||
DeviceIdEntry { device_id: 0x1912, gen: IntelGeneration::Gen9, platform_name: "Skylake DT GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x1916, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x191B, gen: IntelGeneration::Gen9, platform_name: "Skylake DT GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x191D, gen: IntelGeneration::Gen9, platform_name: "Skylake DT GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x191E, gen: IntelGeneration::Gen9, platform_name: "Skylake ULX GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x1921, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x1923, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT2", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x1926, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT3", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x1927, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT3", dmc_fw_key: Some("SKL") },
|
||||
DeviceIdEntry { device_id: 0x5912, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake DT GT2", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x5916, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT2", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x591B, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake DT GT2", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x591D, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake DT GT2", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x5921, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT2", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x5923, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT2", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x5926, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT3", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x5927, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT3", dmc_fw_key: Some("KBL") },
|
||||
DeviceIdEntry { device_id: 0x3E90, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3E91, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3E92, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3E96, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3E98, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3E9A, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3EA5, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3EA6, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3EA7, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x3EA8, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL") },
|
||||
DeviceIdEntry { device_id: 0x8A56, gen: IntelGeneration::Gen9_5, platform_name: "Ice Lake ULT GT2", dmc_fw_key: Some("ICL") },
|
||||
DeviceIdEntry { device_id: 0x8A52, gen: IntelGeneration::Gen9_5, platform_name: "Ice Lake ULT GT2", dmc_fw_key: Some("ICL") },
|
||||
DeviceIdEntry { device_id: 0x4500, gen: IntelGeneration::Gen9_5, platform_name: "Elkhart Lake", dmc_fw_key: Some("EHL") },
|
||||
DeviceIdEntry { device_id: 0x4571, gen: IntelGeneration::Gen9_5, platform_name: "Elkhart Lake", dmc_fw_key: Some("EHL") },
|
||||
DeviceIdEntry { device_id: 0x9A49, gen: IntelGeneration::Gen12, platform_name: "Tiger Lake ULT GT2", dmc_fw_key: Some("TGL") },
|
||||
DeviceIdEntry { device_id: 0x9A40, gen: IntelGeneration::Gen12, platform_name: "Tiger Lake ULT GT2", dmc_fw_key: Some("TGL") },
|
||||
DeviceIdEntry { device_id: 0x9A78, gen: IntelGeneration::Gen12, platform_name: "Tiger Lake H GT2", dmc_fw_key: Some("TGL") },
|
||||
DeviceIdEntry { device_id: 0x46A6, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP") },
|
||||
DeviceIdEntry { device_id: 0x4626, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP") },
|
||||
DeviceIdEntry { device_id: 0x46A8, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP") },
|
||||
DeviceIdEntry { device_id: 0x4628, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP") },
|
||||
DeviceIdEntry { device_id: 0x46B3, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP") },
|
||||
DeviceIdEntry { device_id: 0x5690, gen: IntelGeneration::Gen12, platform_name: "DG2 Alchemist G10", dmc_fw_key: Some("DG2") },
|
||||
DeviceIdEntry { device_id: 0x5698, gen: IntelGeneration::Gen12, platform_name: "DG2 Alchemist G11", dmc_fw_key: Some("DG2") },
|
||||
DeviceIdEntry { device_id: 0x56A0, gen: IntelGeneration::Gen12, platform_name: "DG2 Alchemist G12", dmc_fw_key: Some("DG2") },
|
||||
DeviceIdEntry { device_id: 0x7D55, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") },
|
||||
DeviceIdEntry { device_id: 0x7D60, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") },
|
||||
DeviceIdEntry { device_id: 0x7D45, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") },
|
||||
DeviceIdEntry { device_id: 0x7D67, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL") },
|
||||
DeviceIdEntry { device_id: 0x7D41, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-U", dmc_fw_key: Some("ARL") },
|
||||
DeviceIdEntry { device_id: 0x7D51, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-P Arc Pro 130T/140T", dmc_fw_key: Some("ARL") },
|
||||
DeviceIdEntry { device_id: 0x7D67, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-S", dmc_fw_key: Some("ARL") },
|
||||
DeviceIdEntry { device_id: 0x7DD1, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-P", dmc_fw_key: Some("ARL") },
|
||||
DeviceIdEntry { device_id: 0xB640, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-H", dmc_fw_key: Some("ARL") },
|
||||
DeviceIdEntry { device_id: 0x1912, gen: IntelGeneration::Gen9, platform_name: "Skylake DT GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x1916, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x191B, gen: IntelGeneration::Gen9, platform_name: "Skylake DT GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x191D, gen: IntelGeneration::Gen9, platform_name: "Skylake DT GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x191E, gen: IntelGeneration::Gen9, platform_name: "Skylake ULX GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x1921, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x1923, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT2", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x1926, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT3", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x1927, gen: IntelGeneration::Gen9, platform_name: "Skylake ULT GT3", dmc_fw_key: Some("SKL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5912, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake DT GT2", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5916, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT2", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x591B, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake DT GT2", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x591D, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake DT GT2", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5921, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT2", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5923, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT2", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5926, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT3", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5927, gen: IntelGeneration::Gen9, platform_name: "Kaby Lake ULT GT3", dmc_fw_key: Some("KBL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3E90, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3E91, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3E92, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3E96, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3E98, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3E9A, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake DT GT2", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3EA5, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3EA6, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3EA7, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x3EA8, gen: IntelGeneration::Gen9, platform_name: "Coffee Lake ULT GT3", dmc_fw_key: Some("CFL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x8A56, gen: IntelGeneration::Gen9_5, platform_name: "Ice Lake ULT GT2", dmc_fw_key: Some("ICL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x8A52, gen: IntelGeneration::Gen9_5, platform_name: "Ice Lake ULT GT2", dmc_fw_key: Some("ICL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x4500, gen: IntelGeneration::Gen9_5, platform_name: "Elkhart Lake", dmc_fw_key: Some("EHL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x4571, gen: IntelGeneration::Gen9_5, platform_name: "Elkhart Lake", dmc_fw_key: Some("EHL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x9A49, gen: IntelGeneration::Gen12, platform_name: "Tiger Lake ULT GT2", dmc_fw_key: Some("TGL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x9A40, gen: IntelGeneration::Gen12, platform_name: "Tiger Lake ULT GT2", dmc_fw_key: Some("TGL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x9A78, gen: IntelGeneration::Gen12, platform_name: "Tiger Lake H GT2", dmc_fw_key: Some("TGL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x46A6, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x4626, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x46A8, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x4628, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x46B3, gen: IntelGeneration::Gen12, platform_name: "Alder Lake-P GT2", dmc_fw_key: Some("ADLP"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5690, gen: IntelGeneration::Gen12, platform_name: "DG2 Alchemist G10", dmc_fw_key: Some("DG2"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x5698, gen: IntelGeneration::Gen12, platform_name: "DG2 Alchemist G11", dmc_fw_key: Some("DG2"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x56A0, gen: IntelGeneration::Gen12, platform_name: "DG2 Alchemist G12", dmc_fw_key: Some("DG2"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D55, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D60, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D45, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D67, gen: IntelGeneration::Gen12_7, platform_name: "Meteor Lake", dmc_fw_key: Some("MTL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D41, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-U", dmc_fw_key: Some("ARL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D51, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-P Arc Pro 130T/140T", dmc_fw_key: Some("ARL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7D67, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-S", dmc_fw_key: Some("ARL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x7DD1, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-P", dmc_fw_key: Some("ARL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xB640, gen: IntelGeneration::GenXe2, platform_name: "Arrow Lake-H", dmc_fw_key: Some("ARL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x6420, gen: IntelGeneration::GenXe2, platform_name: "Lunar Lake", dmc_fw_key: Some("LNL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x64A0, gen: IntelGeneration::GenXe2, platform_name: "Lunar Lake", dmc_fw_key: Some("LNL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0x64B0, gen: IntelGeneration::GenXe2, platform_name: "Lunar Lake", dmc_fw_key: Some("LNL"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE202, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE20B, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE20C, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE20D, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE210, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE212, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE216, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
DeviceIdEntry { device_id: 0xE220, gen: IntelGeneration::GenXe2, platform_name: "Battlemage G21", dmc_fw_key: Some("BMG"), guc_fw_key: None },
|
||||
];
|
||||
|
||||
pub fn device_info_from_id(device_id: u16) -> IntelDeviceInfo {
|
||||
@@ -173,6 +187,8 @@ pub fn device_info_from_id(device_id: u16) -> IntelDeviceInfo {
|
||||
has_dbuf_slice: gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7 || gen == IntelGeneration::GenXe2,
|
||||
has_separate_transcoder: gen == IntelGeneration::Gen12 || gen == IntelGeneration::Gen12_7 || gen == IntelGeneration::GenXe2,
|
||||
dmc_fw_key: entry.dmc_fw_key,
|
||||
guc_fw_key: entry.guc_fw_key,
|
||||
has_guc: entry.guc_fw_key.is_some(),
|
||||
platform_name: entry.platform_name,
|
||||
};
|
||||
}
|
||||
@@ -193,6 +209,8 @@ pub fn device_info_from_id(device_id: u16) -> IntelDeviceInfo {
|
||||
has_dbuf_slice: false,
|
||||
has_separate_transcoder: false,
|
||||
dmc_fw_key: None,
|
||||
guc_fw_key: None,
|
||||
has_guc: false,
|
||||
platform_name: "Unknown (Gen9 default)",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
use log::info;
|
||||
|
||||
use crate::driver::{DriverError, Result};
|
||||
|
||||
const DG2_DEVICE_IDS: &[u16] = &[
|
||||
0x5690, 0x5691, 0x5692, 0x5693, 0x5694, 0x5695, 0x5696, 0x5697,
|
||||
0x56A0, 0x56A1, 0x56A2, 0x56A3, 0x56A4, 0x56A5, 0x56A6,
|
||||
0x56B0, 0x56B1, 0x56B2, 0x56B3, 0x56BA, 0x56BB, 0x56BC,
|
||||
0x56BD, 0x56BE, 0x56BF, 0x56C0, 0x56C1,
|
||||
];
|
||||
|
||||
const BMG_DEVICE_IDS: &[u16] = &[
|
||||
0xE202, 0xE209, 0xE20B, 0xE20C, 0xE20D, 0xE210, 0xE211,
|
||||
0xE212, 0xE216, 0xE220, 0xE221, 0xE222, 0xE223,
|
||||
];
|
||||
|
||||
pub fn is_discrete_gpu(device_id: u16) -> bool {
|
||||
DG2_DEVICE_IDS.contains(&device_id) || BMG_DEVICE_IDS.contains(&device_id)
|
||||
}
|
||||
|
||||
pub struct IntelLmem {
|
||||
bar_addr: u64,
|
||||
bar_size: u64,
|
||||
next_offset: u64,
|
||||
}
|
||||
|
||||
impl IntelLmem {
|
||||
pub fn probe(bar_addr: u64, bar_size: u64) -> Result<Self> {
|
||||
if bar_size == 0 {
|
||||
return Err(DriverError::Initialization(
|
||||
"Intel discrete GPU reports zero-size LMEM BAR".into(),
|
||||
));
|
||||
}
|
||||
info!(
|
||||
"redox-drm-intel: LMEM BAR probed — {:#x} bytes at {:#010x}",
|
||||
bar_size, bar_addr
|
||||
);
|
||||
Ok(Self {
|
||||
bar_addr,
|
||||
bar_size,
|
||||
next_offset: 0,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn alloc(&mut self, size: u64, alignment: u64) -> Result<u64> {
|
||||
let aligned = align_up(self.next_offset, alignment);
|
||||
let end = aligned
|
||||
.checked_add(size)
|
||||
.ok_or_else(|| DriverError::Buffer("Intel LMEM allocation overflow".into()))?;
|
||||
if end > self.bar_size {
|
||||
return Err(DriverError::Buffer(format!(
|
||||
"Intel LMEM exhausted: need {:#x} at offset {:#x}, have {:#x}",
|
||||
size, aligned, self.bar_size
|
||||
)));
|
||||
}
|
||||
self.next_offset = end;
|
||||
let vram_addr = self.bar_addr + aligned;
|
||||
Ok(vram_addr)
|
||||
}
|
||||
|
||||
pub fn bar_size(&self) -> u64 {
|
||||
self.bar_size
|
||||
}
|
||||
|
||||
pub fn bar_addr(&self) -> u64 {
|
||||
self.bar_addr
|
||||
}
|
||||
}
|
||||
|
||||
fn align_up(value: u64, alignment: u64) -> u64 {
|
||||
if alignment == 0 {
|
||||
return value;
|
||||
}
|
||||
(value + alignment - 1) & !(alignment - 1)
|
||||
}
|
||||
@@ -1,30 +1,43 @@
|
||||
pub mod backlight;
|
||||
pub mod batch;
|
||||
pub mod context;
|
||||
pub mod cursor;
|
||||
pub mod ddi_buf_trans;
|
||||
pub mod display;
|
||||
pub mod display_cdclk;
|
||||
pub mod display_combo_phy;
|
||||
pub mod display_dmc;
|
||||
pub mod display_dpll;
|
||||
pub mod display_power;
|
||||
pub mod display_psr;
|
||||
pub mod display_transcoder;
|
||||
pub mod display_watermark;
|
||||
pub mod dp_aux;
|
||||
pub mod dp_link;
|
||||
pub mod execbuffer;
|
||||
pub mod execlists;
|
||||
pub mod fence;
|
||||
pub mod gamma;
|
||||
pub mod gmbus;
|
||||
pub mod gt;
|
||||
pub mod gtt;
|
||||
pub mod guc;
|
||||
pub mod hangcheck;
|
||||
pub mod hdmi;
|
||||
pub mod hotplug;
|
||||
pub mod info;
|
||||
pub mod lmem;
|
||||
pub mod panel_pps;
|
||||
pub mod regs;
|
||||
pub mod regs_gen9;
|
||||
pub mod regs_gen12;
|
||||
pub mod regs_xe2;
|
||||
pub mod ring;
|
||||
pub mod syncobj;
|
||||
pub mod vbt;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use log::{debug, info, warn};
|
||||
@@ -51,16 +64,23 @@ use self::display_transcoder::{TransDdiMode, Transcoder};
|
||||
use self::display_watermark::DisplayWatermark;
|
||||
use self::dp_aux::DpAux;
|
||||
use self::gmbus::GmbusController;
|
||||
use self::gt::IntelGtManager;
|
||||
use self::gtt::IntelGtt;
|
||||
use self::guc::GucFirmware;
|
||||
use self::hotplug::HotplugHandler;
|
||||
use self::info::{IntelDeviceInfo, IntelGeneration, device_info_from_id};
|
||||
use self::lmem::{IntelLmem, is_discrete_gpu};
|
||||
use self::regs::IntelRegs;
|
||||
use self::regs_gen9::Gen9Regs;
|
||||
use self::regs_gen12::Gen12Regs;
|
||||
use self::regs_xe2::Xe2Regs;
|
||||
use self::backlight::Backlight;
|
||||
use self::context::ContextManager;
|
||||
use self::display_psr::PsrState;
|
||||
use self::hangcheck::GpuHangDetector;
|
||||
use self::panel_pps::PanelPowerSequencer;
|
||||
use self::ring::{IntelRing, RingType};
|
||||
|
||||
const FORCEWAKE: usize = 0xA18C;
|
||||
use self::syncobj::SyncobjManager;
|
||||
|
||||
const RENDER_RING_BASE: usize = 0x02000;
|
||||
const RING_TAIL_OFFSET: usize = 0x30;
|
||||
@@ -87,9 +107,19 @@ pub struct IntelDriver {
|
||||
watermark: DisplayWatermark,
|
||||
dpll: DisplayPll,
|
||||
dmc: DmcFirmware,
|
||||
guc: GucFirmware,
|
||||
cdclk: DisplayClock,
|
||||
cursor: CursorPlane,
|
||||
hotplug: HotplugHandler,
|
||||
gt_manager: IntelGtManager,
|
||||
vblank_count: AtomicU64,
|
||||
backlight: Mutex<Backlight>,
|
||||
context_manager: Mutex<ContextManager>,
|
||||
psr: Mutex<PsrState>,
|
||||
hang_detector: Mutex<GpuHangDetector>,
|
||||
panel_pps: Mutex<PanelPowerSequencer>,
|
||||
syncobj_mgr: Mutex<SyncobjManager>,
|
||||
lmem: Option<IntelLmem>,
|
||||
}
|
||||
|
||||
impl IntelDriver {
|
||||
@@ -125,6 +155,29 @@ impl IntelDriver {
|
||||
let gtt_bar = find_memory_bar(&info, 0, "GGTT BAR0")?;
|
||||
let mmio_bar = find_memory_bar(&info, 2, "MMIO BAR2")?;
|
||||
|
||||
let lmem = if is_discrete_gpu(info.device_id) {
|
||||
if let Some(lmem_bar) = info.find_memory_bar(4) {
|
||||
match IntelLmem::probe(lmem_bar.addr, lmem_bar.size) {
|
||||
Ok(lmem) => {
|
||||
info!(
|
||||
"redox-drm-intel: discrete GPU LMEM — {:#x} bytes at {:#010x}",
|
||||
lmem.bar_size(), lmem.bar_addr()
|
||||
);
|
||||
Some(lmem)
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("redox-drm-intel: discrete GPU LMEM probe failed: {}", e);
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info!("redox-drm-intel: discrete GPU detected but no LMEM BAR4 found");
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// Determine device generation early for register-correct init ordering
|
||||
let device_info = device_info_from_id(info.device_id);
|
||||
info!(
|
||||
@@ -152,10 +205,12 @@ impl IntelDriver {
|
||||
let gtt_control_mmio = map_bar(&mut device, &mmio_bar, "Intel GGTT control MMIO")?;
|
||||
let gtt_mmio = map_bar(&mut device, >t_bar, "Intel GGTT BAR0")?;
|
||||
|
||||
enable_forcewake(&mmio, regs)?;
|
||||
let mmio_arc = Arc::new(mmio);
|
||||
let display_mmio_arc = Arc::new(display_mmio);
|
||||
|
||||
let mut gt_manager = IntelGtManager::new(mmio_arc.clone(), &device_info);
|
||||
gt_manager.init()?;
|
||||
|
||||
let gmbus = if device_info.has_gmbus {
|
||||
let ctrl = GmbusController::new(display_mmio_arc.clone(), regs);
|
||||
ctrl.init()?;
|
||||
@@ -224,6 +279,17 @@ impl IntelDriver {
|
||||
let mut ring = IntelRing::create(ring_mmio, RingType::Render)?;
|
||||
ring.bind_gtt(&mut gtt)?;
|
||||
|
||||
let mut guc = GucFirmware::new(mmio_arc.clone());
|
||||
if let Some(guc_key) = device_info.guc_fw_key {
|
||||
guc.init_wopcm()?;
|
||||
if let Some(fw_data) = firmware.get(guc_key) {
|
||||
info!("redox-drm-intel: loading GuC firmware for {guc_key}");
|
||||
guc.upload(fw_data)?;
|
||||
} else {
|
||||
warn!("redox-drm-intel: GuC firmware key '{guc_key}' not in cache, continuing without");
|
||||
}
|
||||
}
|
||||
|
||||
let edid_source: Option<&[DpAux]> = if device_info.generation == IntelGeneration::GenXe2 {
|
||||
Some(&dp_aux)
|
||||
} else {
|
||||
@@ -234,6 +300,23 @@ impl IntelDriver {
|
||||
let hotplug = HotplugHandler::new(mmio_arc.clone(), &device_info);
|
||||
hotplug.init()?;
|
||||
|
||||
let mut backlight = Backlight::new(mmio_arc.clone(), &device_info);
|
||||
backlight.init()?;
|
||||
|
||||
let context_manager = Mutex::new(ContextManager::new());
|
||||
|
||||
let psr = Mutex::new(PsrState::new(mmio_arc.clone(), 0));
|
||||
|
||||
let hang_detector = Mutex::new(GpuHangDetector::new(mmio_arc.clone(), RENDER_RING_BASE));
|
||||
|
||||
let panel_pps = {
|
||||
let pps = PanelPowerSequencer::new(mmio_arc.clone(), &device_info);
|
||||
pps.init()?;
|
||||
Mutex::new(pps)
|
||||
};
|
||||
|
||||
let syncobj_mgr = Mutex::new(SyncobjManager::new());
|
||||
|
||||
let (connectors, encoders) = detect_display_topology(&display, edid_source)?;
|
||||
let crtcs = build_crtcs(&display)?;
|
||||
|
||||
@@ -288,9 +371,19 @@ impl IntelDriver {
|
||||
watermark,
|
||||
dpll,
|
||||
dmc,
|
||||
guc,
|
||||
cdclk,
|
||||
cursor,
|
||||
hotplug,
|
||||
gt_manager,
|
||||
vblank_count: AtomicU64::new(0),
|
||||
backlight: Mutex::new(backlight),
|
||||
context_manager,
|
||||
psr,
|
||||
hang_detector,
|
||||
panel_pps,
|
||||
syncobj_mgr,
|
||||
lmem,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -302,15 +395,18 @@ fn enable_d2d_links(mmio: &MmioRegion, regs: &dyn IntelRegs, num_ports: u8) -> R
|
||||
const D2D_TIMEOUT_MS: u64 = 10;
|
||||
|
||||
for port in 0..num_ports {
|
||||
let ddi_ctl = regs.ddi_buf_ctl(port);
|
||||
let current = mmio.read32(ddi_ctl);
|
||||
let d2d_ctl = regs.d2d_link_ctl(port);
|
||||
if d2d_ctl == 0 {
|
||||
continue;
|
||||
}
|
||||
let current = mmio.read32(d2d_ctl);
|
||||
if current & D2D_LINK_STATE != 0 {
|
||||
continue;
|
||||
}
|
||||
mmio.write32(ddi_ctl, current | D2D_LINK_ENABLE);
|
||||
mmio.write32(d2d_ctl, current | D2D_LINK_ENABLE);
|
||||
let deadline = Instant::now() + Duration::from_millis(D2D_TIMEOUT_MS);
|
||||
loop {
|
||||
let status = mmio.read32(ddi_ctl);
|
||||
let status = mmio.read32(d2d_ctl);
|
||||
if status & D2D_LINK_STATE != 0 {
|
||||
info!("redox-drm-intel: D2D link enabled on port {}", port);
|
||||
break;
|
||||
@@ -408,25 +504,56 @@ impl IntelDriver {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(crtc_id) = self.active_crtc_id()? {
|
||||
let pipe = self.display.pipe_for_crtc(crtc_id)?;
|
||||
let pipe_idx = u8::from(pipe.index);
|
||||
let pipestat = self.mmio.read32(self.regs.pipestat(pipe_idx));
|
||||
let vblank_mask = self.regs.pipestat_vblank_mask();
|
||||
let vsync_mask = self.regs.pipestat_vsync_mask();
|
||||
|
||||
if pipestat & vblank_mask != 0 {
|
||||
self.mmio.write32(self.regs.pipestat(pipe_idx), vblank_mask);
|
||||
let count = self.vblank_count.fetch_add(1, Ordering::Relaxed) + 1;
|
||||
debug!(
|
||||
"redox-drm: Intel vblank IRQ crtc={} count={}",
|
||||
crtc_id, count
|
||||
);
|
||||
return Ok(Some(DriverEvent::Vblank { crtc_id, count }));
|
||||
}
|
||||
|
||||
if pipestat & vsync_mask != 0 {
|
||||
self.mmio.write32(self.regs.pipestat(pipe_idx), vsync_mask);
|
||||
}
|
||||
|
||||
let count = self.read_pipeframe(crtc_id)?;
|
||||
debug!(
|
||||
"redox-drm: Intel poll-based display event crtc={} ring_checked=true",
|
||||
crtc_id
|
||||
);
|
||||
return Ok(Some(DriverEvent::Vblank { crtc_id, count }));
|
||||
}
|
||||
|
||||
let ring_busy = self
|
||||
.ring
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?
|
||||
.has_activity()?;
|
||||
|
||||
if let Some(crtc_id) = self.active_crtc_id()? {
|
||||
let count = self.read_pipeframe(crtc_id)?;
|
||||
debug!(
|
||||
"redox-drm: Intel IRQ decoded as display event crtc={} ring_busy={}",
|
||||
crtc_id, ring_busy
|
||||
);
|
||||
return Ok(Some(DriverEvent::Vblank { crtc_id, count }));
|
||||
}
|
||||
|
||||
if ring_busy {
|
||||
debug!("redox-drm: Intel IRQ signaled command stream activity without active CRTC");
|
||||
}
|
||||
|
||||
// Poll hangcheck detector for GPU hangs
|
||||
{
|
||||
let mut hang = self
|
||||
.hang_detector
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel hangcheck state poisoned".into()))?;
|
||||
if hang.poll()? {
|
||||
warn!("redox-drm: Intel GPU hang detected and reset attempted");
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
@@ -448,6 +575,18 @@ impl IntelDriver {
|
||||
.map(|pipe| u32::from(pipe.index) + 1))
|
||||
}
|
||||
|
||||
fn enable_pipe_interrupts(&self, pipe: &DisplayPipe) -> Result<()> {
|
||||
let pipe_idx = u8::from(pipe.index);
|
||||
let pipestat = self.regs.pipestat(pipe_idx);
|
||||
let mask = self.regs.pipestat_vblank_mask() | self.regs.pipestat_vsync_mask();
|
||||
self.mmio.write32(pipestat, mask);
|
||||
let de_ier = self.regs.de_ier();
|
||||
let current = self.mmio.read32(de_ier);
|
||||
self.mmio.write32(de_ier, current | (1u32 << (13 + pipe_idx as u32)));
|
||||
debug!("redox-drm-intel: enabled pipe {} interrupts", pipe_idx);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ensure_gem_gpu_mapping(&self, handle: GemHandle) -> Result<u64> {
|
||||
{
|
||||
let gem = self
|
||||
@@ -556,7 +695,10 @@ impl IntelDriver {
|
||||
info.push_str(&format!(" GMBUS available: {}\n", self.gmbus.is_some()));
|
||||
info.push_str(&format!(" Connectors detected: {}\n", self.cached_connectors().len()));
|
||||
info.push_str(&format!(" CRTCs: {}\n",
|
||||
self.crtcs.lock().map(|c| c.len()).unwrap_or(0)));
|
||||
self.crtcs.lock().map(|c| c.len()).unwrap_or_else(|e| {
|
||||
warn!("redox-drm-intel: crtcs mutex poisoned: {e}");
|
||||
0
|
||||
})));
|
||||
if let Ok(connectors) = self.connectors.lock() {
|
||||
for conn in connectors.iter() {
|
||||
info.push_str(&format!(" Connector {}: {:?} (status {:?}), {} modes\n",
|
||||
@@ -649,15 +791,27 @@ impl GpuDriver for IntelDriver {
|
||||
let pipe = self.display.pipe_for_crtc(crtc_id)?;
|
||||
self.display.page_flip(&pipe, fb_addr)?;
|
||||
|
||||
let mut ring = self
|
||||
.ring
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?;
|
||||
ring.flush()?;
|
||||
Ok(ring.last_seqno())
|
||||
self.enable_pipe_interrupts(&pipe)?;
|
||||
|
||||
let seqno = {
|
||||
let mut ring = self
|
||||
.ring
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?;
|
||||
let has_pending = ring.has_activity().unwrap_or(false);
|
||||
if has_pending {
|
||||
ring.flush()?;
|
||||
}
|
||||
ring.last_seqno()
|
||||
};
|
||||
Ok(seqno)
|
||||
}
|
||||
|
||||
fn get_vblank(&self, crtc_id: u32) -> Result<u64> {
|
||||
let count = self.vblank_count.load(Ordering::Relaxed);
|
||||
if count > 0 {
|
||||
return Ok(count);
|
||||
}
|
||||
self.read_pipeframe(crtc_id)
|
||||
}
|
||||
|
||||
@@ -766,6 +920,21 @@ impl GpuDriver for IntelDriver {
|
||||
) -> Result<RedoxPrivateCsSubmitResult> {
|
||||
let src_addr = self.ensure_gem_gpu_mapping(submit.src_handle)?;
|
||||
|
||||
let gem_size = self.gem_size(submit.src_handle)?;
|
||||
if submit.src_offset.checked_add(submit.byte_count).ok_or_else(|| {
|
||||
DriverError::InvalidArgument("cs_submit: src_offset + byte_count overflow")
|
||||
})? > gem_size {
|
||||
return Err(DriverError::InvalidArgument(
|
||||
"cs_submit: byte_count + src_offset exceeds GEM object size",
|
||||
));
|
||||
}
|
||||
|
||||
if submit.byte_count % 4 != 0 {
|
||||
return Err(DriverError::InvalidArgument(
|
||||
"cs_submit: byte_count must be DWORD-aligned",
|
||||
));
|
||||
}
|
||||
|
||||
let cmds_ptr = (src_addr + submit.src_offset) as *const u32;
|
||||
let dword_count = (submit.byte_count / 4) as usize;
|
||||
let cmds = unsafe {
|
||||
@@ -775,8 +944,16 @@ impl GpuDriver for IntelDriver {
|
||||
let mut ring = self.ring.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?;
|
||||
ring.submit_batch(cmds)?;
|
||||
let seqno = ring.last_seqno();
|
||||
drop(ring);
|
||||
|
||||
Ok(RedoxPrivateCsSubmitResult { seqno: 0 })
|
||||
{
|
||||
let syncobj = self.syncobj_mgr.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel syncobj state poisoned".into()))?;
|
||||
syncobj.hardware_signal_completion(src_addr, seqno);
|
||||
}
|
||||
|
||||
Ok(RedoxPrivateCsSubmitResult { seqno })
|
||||
}
|
||||
|
||||
fn cursor_set(
|
||||
@@ -888,23 +1065,6 @@ fn connector_status_changed(previous: &[ConnectorInfo], current: &[ConnectorInfo
|
||||
})
|
||||
}
|
||||
|
||||
fn enable_forcewake(mmio: &MmioRegion, regs: &dyn IntelRegs) -> Result<()> {
|
||||
let offset = regs.forcewake_req();
|
||||
let end = offset
|
||||
.checked_add(core::mem::size_of::<u32>())
|
||||
.ok_or_else(|| DriverError::Mmio("Intel FORCEWAKE offset overflow".into()))?;
|
||||
if end > mmio.size() {
|
||||
return Err(DriverError::Mmio(format!(
|
||||
"Intel FORCEWAKE register outside MMIO aperture: end={end:#x} size={:#x}",
|
||||
mmio.size()
|
||||
)));
|
||||
}
|
||||
|
||||
mmio.write32(offset, 1);
|
||||
let _ = mmio.read32(offset);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_intel_bars(
|
||||
info: &PciDeviceInfo,
|
||||
gtt_bar: &PciBarInfo,
|
||||
@@ -938,7 +1098,7 @@ fn validate_intel_bars(
|
||||
}
|
||||
|
||||
let required_mmio_end = [
|
||||
FORCEWAKE + core::mem::size_of::<u32>(),
|
||||
regs.forcewake_req() + core::mem::size_of::<u32>(),
|
||||
regs.pp_status() + core::mem::size_of::<u32>(),
|
||||
regs.gfx_flsh_cntl() + core::mem::size_of::<u32>(),
|
||||
RENDER_RING_BASE + RING_TAIL_OFFSET + core::mem::size_of::<u32>(),
|
||||
@@ -946,7 +1106,7 @@ fn validate_intel_bars(
|
||||
]
|
||||
.into_iter()
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
.expect("required register list is non-empty");
|
||||
|
||||
if mmio_bar.size < required_mmio_end as u64 {
|
||||
return Err(DriverError::Pci(format!(
|
||||
|
||||
@@ -1,981 +0,0 @@
|
||||
pub mod batch;
|
||||
pub mod cursor;
|
||||
pub mod display;
|
||||
pub mod display_cdclk;
|
||||
pub mod display_combo_phy;
|
||||
pub mod display_dmc;
|
||||
pub mod display_dpll;
|
||||
pub mod display_power;
|
||||
pub mod display_transcoder;
|
||||
pub mod display_watermark;
|
||||
pub mod dp_aux;
|
||||
pub mod dp_link;
|
||||
pub mod execlists;
|
||||
pub mod fence;
|
||||
pub mod gmbus;
|
||||
pub mod gtt;
|
||||
pub mod hdmi;
|
||||
pub mod hotplug;
|
||||
pub mod info;
|
||||
pub mod regs;
|
||||
pub mod regs_gen9;
|
||||
pub mod regs_gen12;
|
||||
pub mod regs_xe2;
|
||||
pub mod ring;
|
||||
pub mod vbt;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use log::{debug, info, warn};
|
||||
use redox_driver_sys::memory::MmioRegion;
|
||||
use redox_driver_sys::pci::{PciBarInfo, PciDevice, PciDeviceInfo};
|
||||
use redox_driver_sys::quirks::PciQuirkFlags;
|
||||
|
||||
use crate::driver::{DriverError, DriverEvent, GpuDriver, Result, RedoxPrivateCsSubmit, RedoxPrivateCsSubmitResult};
|
||||
use crate::drivers::interrupt::InterruptHandle;
|
||||
use crate::gem::{GemHandle, GemManager};
|
||||
use crate::kms::connector::{synthetic_edid, Connector};
|
||||
use crate::kms::crtc::Crtc;
|
||||
use crate::kms::encoder::Encoder;
|
||||
use crate::kms::{ConnectorInfo, ConnectorType, ModeInfo};
|
||||
|
||||
use self::cursor::CursorPlane;
|
||||
use self::display::{DisplayPipe, IntelDisplay};
|
||||
use self::display_cdclk::DisplayClock;
|
||||
use self::display_combo_phy::ComboPhy;
|
||||
use self::display_dmc::DmcFirmware;
|
||||
use self::display_dpll::DisplayPll;
|
||||
use self::display_power::DisplayPower;
|
||||
use self::display_transcoder::{TransDdiMode, Transcoder};
|
||||
use self::display_watermark::DisplayWatermark;
|
||||
use self::dp_aux::DpAux;
|
||||
use self::gmbus::GmbusController;
|
||||
use self::gtt::IntelGtt;
|
||||
use self::hotplug::HotplugHandler;
|
||||
use self::info::{IntelDeviceInfo, IntelGeneration, device_info_from_id};
|
||||
use self::regs::IntelRegs;
|
||||
use self::regs_gen9::Gen9Regs;
|
||||
use self::regs_gen12::Gen12Regs;
|
||||
use self::regs_xe2::Xe2Regs;
|
||||
use self::ring::{IntelRing, RingType};
|
||||
|
||||
const FORCEWAKE: usize = 0xA18C;
|
||||
const self.regs.pp_status(): usize = 0xC7200;
|
||||
const self.regs.pipeconf(0): usize = 0x70008;
|
||||
const self.regs.pipe_stride(): usize = 0x1000;
|
||||
const self.regs.pipeframe_reg(pipe): usize = 0x70040;
|
||||
const self.regs.pipeframe_count_mask(): u32 = 0x00FFFFFF;
|
||||
const self.regs.ddi_buf_ctl(0): usize = 0x64000;
|
||||
const self.regs.ddi_port_stride(): usize = 0x100;
|
||||
const self.regs.gfx_flsh_cntl(): usize = 0x101008;
|
||||
|
||||
const RENDER_RING_BASE: usize = 0x02000;
|
||||
const RING_TAIL_OFFSET: usize = 0x30;
|
||||
const RING_HEAD_OFFSET: usize = 0x34;
|
||||
|
||||
pub struct IntelDriver {
|
||||
info: PciDeviceInfo,
|
||||
device_info: IntelDeviceInfo,
|
||||
mmio: Arc<MmioRegion>,
|
||||
regs: &'static dyn IntelRegs,
|
||||
irq_handle: Mutex<Option<InterruptHandle>>,
|
||||
display: IntelDisplay,
|
||||
gem: Mutex<GemManager>,
|
||||
connectors: Mutex<Vec<Connector>>,
|
||||
crtcs: Mutex<Vec<Crtc>>,
|
||||
encoders: Mutex<Vec<Encoder>>,
|
||||
gtt: Mutex<IntelGtt>,
|
||||
ring: Mutex<IntelRing>,
|
||||
gmbus: Option<GmbusController>,
|
||||
dp_aux: Vec<DpAux>,
|
||||
combo_phy: Option<ComboPhy>,
|
||||
display_power: DisplayPower,
|
||||
transcoder: Transcoder,
|
||||
watermark: DisplayWatermark,
|
||||
dpll: DisplayPll,
|
||||
dmc: DmcFirmware,
|
||||
cdclk: DisplayClock,
|
||||
cursor: CursorPlane,
|
||||
hotplug: HotplugHandler,
|
||||
}
|
||||
|
||||
impl IntelDriver {
|
||||
pub fn new(info: PciDeviceInfo, firmware: HashMap<String, Vec<u8>>) -> Result<Self> {
|
||||
if !info.is_intel_gpu() {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {} is not an Intel display-class GPU",
|
||||
info.location
|
||||
)));
|
||||
}
|
||||
|
||||
let quirks = info.quirks();
|
||||
if !quirks.is_empty() {
|
||||
info!(
|
||||
"redox-drm: Intel init for {} using quirk policy {:?}",
|
||||
info.location, quirks
|
||||
);
|
||||
}
|
||||
if quirks.contains(PciQuirkFlags::DISABLE_ACCEL) {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {:#06x}:{:#06x} at {} has DISABLE_ACCEL quirk — refusing Intel init",
|
||||
info.vendor_id, info.device_id, info.location
|
||||
)));
|
||||
}
|
||||
if quirks.contains(PciQuirkFlags::NEED_FIRMWARE) {
|
||||
info!(
|
||||
"redox-drm: Intel device {} entered init with explicit firmware policy and {} cached blob(s)",
|
||||
info.location,
|
||||
firmware.len()
|
||||
);
|
||||
}
|
||||
|
||||
let gtt_bar = find_memory_bar(&info, 0, "GGTT BAR0")?;
|
||||
let mmio_bar = find_memory_bar(&info, 2, "MMIO BAR2")?;
|
||||
validate_intel_bars(&info, >t_bar, &mmio_bar)?;
|
||||
|
||||
let mut device = PciDevice::open_location(&info.location)
|
||||
.map_err(|e| DriverError::Pci(format!("failed to re-open PCI device: {e}")))?;
|
||||
device
|
||||
.enable_device()
|
||||
.map_err(|e| DriverError::Pci(format!("enable_device failed: {e}")))?;
|
||||
|
||||
let mmio = map_bar(&mut device, &mmio_bar, "Intel MMIO BAR2")?;
|
||||
let display_mmio = map_bar(&mut device, &mmio_bar, "Intel display MMIO")?;
|
||||
let ring_mmio = map_bar(&mut device, &mmio_bar, "Intel ring MMIO")?;
|
||||
let gtt_control_mmio = map_bar(&mut device, &mmio_bar, "Intel GGTT control MMIO")?;
|
||||
let gtt_mmio = map_bar(&mut device, >t_bar, "Intel GGTT BAR0")?;
|
||||
|
||||
enable_forcewake(&mmio)?;
|
||||
|
||||
let device_info = device_info_from_id(info.device_id);
|
||||
info!(
|
||||
"redox-drm: Intel {} detected (device {:#06x}, display ver {}, gen {:?})",
|
||||
device_info.platform_name, info.device_id, device_info.display_version, device_info.generation
|
||||
);
|
||||
|
||||
let regs: &'static dyn IntelRegs = match device_info.generation {
|
||||
IntelGeneration::GenXe2 => &Xe2Regs,
|
||||
IntelGeneration::Gen12 | IntelGeneration::Gen12_7 => &Gen12Regs,
|
||||
_ => &Gen9Regs,
|
||||
};
|
||||
let mmio_arc = Arc::new(mmio);
|
||||
let display_mmio_arc = Arc::new(display_mmio);
|
||||
|
||||
let gmbus = if device_info.has_gmbus {
|
||||
let ctrl = GmbusController::new(display_mmio_arc.clone(), regs);
|
||||
ctrl.init()?;
|
||||
Some(ctrl)
|
||||
} else {
|
||||
info!("redox-drm-intel: Xe2 platform — skipping GMBUS (uses DP AUX for EDID)");
|
||||
None
|
||||
};
|
||||
|
||||
let dp_aux: Vec<DpAux> = (0..device_info.num_ports)
|
||||
.map(|port| DpAux::new(mmio_arc.clone(), port))
|
||||
.collect();
|
||||
info!("redox-drm-intel: initialized {} DP AUX channels", dp_aux.len());
|
||||
|
||||
if device_info.generation == IntelGeneration::GenXe2 {
|
||||
enable_d2d_links(&mmio_arc, regs, device_info.num_ports)?;
|
||||
}
|
||||
|
||||
let combo_phy = if device_info.has_combo_phy {
|
||||
let phy = ComboPhy::new(mmio_arc.clone());
|
||||
phy.init_all(device_info.num_ports as usize)?;
|
||||
Some(phy)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let display_power = DisplayPower::new(mmio_arc.clone(), regs, &device_info);
|
||||
display_power.init_domains()?;
|
||||
|
||||
let transcoder = Transcoder::new(mmio_arc.clone(), &device_info);
|
||||
|
||||
let watermark = DisplayWatermark::new(mmio_arc.clone(), &device_info);
|
||||
watermark.init()?;
|
||||
|
||||
let dmc = DmcFirmware::new(mmio_arc.clone(), regs);
|
||||
if let Some(dmc_key) = device_info.dmc_fw_key {
|
||||
if let Some(fw_data) = firmware.get(dmc_key) {
|
||||
info!("redox-drm-intel: loading DMC firmware for {}", dmc_key);
|
||||
dmc.upload(fw_data)?;
|
||||
} else {
|
||||
warn!("redox-drm-intel: DMC firmware key '{}' not found in cache", dmc_key);
|
||||
}
|
||||
}
|
||||
|
||||
let cdclk = DisplayClock::new(mmio_arc.clone(), regs, &device_info);
|
||||
let cdclk_state = cdclk.init()?;
|
||||
info!(
|
||||
"redox-drm-intel: CDCLK = {} kHz (voltage level {})",
|
||||
cdclk_state.frequency_khz, cdclk_state.voltage_level
|
||||
);
|
||||
|
||||
let dpll = DisplayPll::new(mmio_arc.clone(), &device_info);
|
||||
dpll.init()?;
|
||||
|
||||
if device_info.generation == IntelGeneration::GenXe2 {
|
||||
for port in 0..device_info.num_ports {
|
||||
if port < dp_aux.len() as u8 {
|
||||
let _ = dp_link::train_dp_link(&mmio_arc, &dp_aux[port as usize], port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let display_gmbus = gmbus.clone();
|
||||
let display = IntelDisplay::new(display_mmio, regs, display_gmbus)?;
|
||||
let mut gtt = IntelGtt::init(gtt_mmio, gtt_control_mmio)?;
|
||||
let mut ring = IntelRing::create(ring_mmio, RingType::Render)?;
|
||||
ring.bind_gtt(&mut gtt)?;
|
||||
|
||||
let edid_source: Option<&[DpAux]> = if device_info.generation == IntelGeneration::GenXe2 {
|
||||
Some(&dp_aux)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let cursor = CursorPlane::new(mmio_arc.clone(), regs);
|
||||
|
||||
let hotplug = HotplugHandler::new(mmio_arc.clone(), &device_info);
|
||||
hotplug.init()?;
|
||||
|
||||
let (connectors, encoders) = detect_display_topology(&display, edid_source)?;
|
||||
let crtcs = build_crtcs(&display)?;
|
||||
|
||||
let irq_handle = match InterruptHandle::setup(&info, &mut device) {
|
||||
Ok(handle) => Some(handle),
|
||||
Err(e) => {
|
||||
warn!(
|
||||
"redox-drm: Intel device {} interrupt setup failed: {e}",
|
||||
info.location
|
||||
);
|
||||
None
|
||||
}
|
||||
};
|
||||
let irq_mode = irq_handle
|
||||
.as_ref()
|
||||
.map(|handle| handle.mode_name())
|
||||
.unwrap_or("none");
|
||||
|
||||
if !firmware.is_empty() {
|
||||
info!(
|
||||
"redox-drm: Intel startup firmware cache populated with {} blob(s) for {}",
|
||||
firmware.len(),
|
||||
info.location
|
||||
);
|
||||
}
|
||||
|
||||
info!(
|
||||
"redox-drm: Intel driver ready for {} with {} connector(s), IRQ mode {}",
|
||||
info.location,
|
||||
connectors.len(),
|
||||
irq_mode
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
info,
|
||||
device_info,
|
||||
mmio: mmio_arc,
|
||||
regs,
|
||||
irq_handle: Mutex::new(irq_handle),
|
||||
display,
|
||||
gem: Mutex::new(GemManager::new()),
|
||||
connectors: Mutex::new(connectors),
|
||||
crtcs: Mutex::new(crtcs),
|
||||
encoders: Mutex::new(encoders),
|
||||
gtt: Mutex::new(gtt),
|
||||
ring: Mutex::new(ring),
|
||||
gmbus,
|
||||
dp_aux,
|
||||
combo_phy,
|
||||
display_power,
|
||||
transcoder,
|
||||
watermark,
|
||||
dpll,
|
||||
dmc,
|
||||
cdclk,
|
||||
cursor,
|
||||
hotplug,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn enable_d2d_links(mmio: &Arc<MmioRegion>, regs: &dyn IntelRegs, num_ports: u8) -> Result<()> {
|
||||
use std::time::{Duration, Instant};
|
||||
const D2D_LINK_ENABLE: u32 = 1 << 29;
|
||||
const D2D_LINK_STATE: u32 = 1 << 28;
|
||||
const D2D_TIMEOUT_MS: u64 = 10;
|
||||
|
||||
for port in 0..num_ports {
|
||||
let ddi_ctl = regs.ddi_buf_ctl(port);
|
||||
let current = mmio.read_u32(ddi_ctl);
|
||||
if current & D2D_LINK_STATE != 0 {
|
||||
continue;
|
||||
}
|
||||
mmio.write_u32(ddi_ctl, current | D2D_LINK_ENABLE);
|
||||
let deadline = Instant::now() + Duration::from_millis(D2D_TIMEOUT_MS);
|
||||
loop {
|
||||
let status = mmio.read_u32(ddi_ctl);
|
||||
if status & D2D_LINK_STATE != 0 {
|
||||
info!("redox-drm-intel: D2D link enabled on port {}", port);
|
||||
break;
|
||||
}
|
||||
if Instant::now() > deadline {
|
||||
warn!("redox-drm-intel: D2D link timeout on port {}", port);
|
||||
break;
|
||||
}
|
||||
std::hint::spin_loop();
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn refresh_connectors(&self) -> Result<Vec<ConnectorInfo>> {
|
||||
let edid_source: Option<&[DpAux]> = if self.device_info.generation == IntelGeneration::GenXe2 {
|
||||
Some(&self.dp_aux)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let (connectors, encoders) = detect_display_topology(&self.display, edid_source)?;
|
||||
let infos = connectors
|
||||
.iter()
|
||||
.map(|connector| connector.info.clone())
|
||||
.collect();
|
||||
|
||||
{
|
||||
let mut connector_state = self.connectors.lock().map_err(|_| {
|
||||
DriverError::Initialization("Intel connector state poisoned".into())
|
||||
})?;
|
||||
*connector_state = connectors;
|
||||
}
|
||||
|
||||
{
|
||||
let mut encoder_state = self
|
||||
.encoders
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel encoder state poisoned".into()))?;
|
||||
*encoder_state = encoders;
|
||||
}
|
||||
|
||||
Ok(infos)
|
||||
}
|
||||
|
||||
fn cached_connectors(&self) -> Vec<ConnectorInfo> {
|
||||
match self.connectors.lock() {
|
||||
Ok(connectors) => connectors
|
||||
.iter()
|
||||
.map(|connector| connector.info.clone())
|
||||
.collect(),
|
||||
Err(poisoned) => {
|
||||
warn!("redox-drm: Intel connector state poisoned; using inner state");
|
||||
poisoned
|
||||
.into_inner()
|
||||
.iter()
|
||||
.map(|connector| connector.info.clone())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn connector_port(&self, connector_id: u32) -> Result<u8> {
|
||||
let connectors = self
|
||||
.connectors
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel connector state poisoned".into()))?;
|
||||
let connector = connectors
|
||||
.iter()
|
||||
.find(|connector| connector.info.id == connector_id)
|
||||
.ok_or_else(|| DriverError::NotFound(format!("unknown connector {connector_id}")))?;
|
||||
|
||||
Ok(connector.info.connector_type_id.saturating_sub(1) as u8)
|
||||
}
|
||||
|
||||
fn process_irq(&self) -> Result<Option<DriverEvent>> {
|
||||
let previous = self.cached_connectors();
|
||||
let current = self.refresh_connectors()?;
|
||||
|
||||
if connector_status_changed(&previous, ¤t) {
|
||||
info!(
|
||||
"redox-drm: Intel hotplug event detected on {}",
|
||||
self.info.location
|
||||
);
|
||||
if let Some(connector) = current.iter().find(|connector| {
|
||||
previous
|
||||
.iter()
|
||||
.find(|old| old.id == connector.id)
|
||||
.map(|old| old.connection != connector.connection)
|
||||
.unwrap_or(true)
|
||||
}) {
|
||||
return Ok(Some(DriverEvent::Hotplug {
|
||||
connector_id: connector.id,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
let ring_busy = self
|
||||
.ring
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?
|
||||
.has_activity()?;
|
||||
|
||||
if let Some(crtc_id) = self.active_crtc_id()? {
|
||||
let count = self.read_pipeframe(crtc_id)?;
|
||||
debug!(
|
||||
"redox-drm: Intel IRQ decoded as display event crtc={} ring_busy={}",
|
||||
crtc_id, ring_busy
|
||||
);
|
||||
return Ok(Some(DriverEvent::Vblank { crtc_id, count }));
|
||||
}
|
||||
|
||||
if ring_busy {
|
||||
debug!("redox-drm: Intel IRQ signaled command stream activity without active CRTC");
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn active_crtc_id(&self) -> Result<Option<u32>> {
|
||||
let crtcs = self
|
||||
.crtcs
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel CRTC state poisoned".into()))?;
|
||||
|
||||
if let Some(active) = crtcs.iter().find(|crtc| crtc.mode.is_some()) {
|
||||
return Ok(Some(active.id));
|
||||
}
|
||||
|
||||
Ok(self
|
||||
.display
|
||||
.pipes()?
|
||||
.into_iter()
|
||||
.find(|pipe| pipe.enabled)
|
||||
.map(|pipe| u32::from(pipe.index) + 1))
|
||||
}
|
||||
|
||||
fn ensure_gem_gpu_mapping(&self, handle: GemHandle) -> Result<u64> {
|
||||
{
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
if let Some(gpu_addr) = gem.gpu_addr(handle)? {
|
||||
return Ok(gpu_addr);
|
||||
}
|
||||
}
|
||||
|
||||
let (phys_addr, size) = {
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
let object = gem.object(handle)?;
|
||||
(object.phys_addr as u64, object.size)
|
||||
};
|
||||
|
||||
let gpu_addr = {
|
||||
let mut gtt = self
|
||||
.gtt
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel GGTT state poisoned".into()))?;
|
||||
let gpu_addr = gtt.alloc_range(size)?;
|
||||
if let Err(error) = gtt.map_range(gpu_addr, phys_addr, size, 1 << 1) {
|
||||
let _ = gtt.release_range(gpu_addr, size);
|
||||
return Err(error);
|
||||
}
|
||||
gpu_addr
|
||||
};
|
||||
|
||||
if let Err(error) = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?
|
||||
.set_gpu_addr(handle, gpu_addr)
|
||||
{
|
||||
let mut gtt = self
|
||||
.gtt
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel GGTT state poisoned".into()))?;
|
||||
let _ = gtt.unmap_range(gpu_addr, size);
|
||||
let _ = gtt.release_range(gpu_addr, size);
|
||||
return Err(error);
|
||||
}
|
||||
|
||||
Ok(gpu_addr)
|
||||
}
|
||||
|
||||
fn read_mmio(&self, offset: usize) -> Result<u32> {
|
||||
let end = offset
|
||||
.checked_add(core::mem::size_of::<u32>())
|
||||
.ok_or_else(|| {
|
||||
DriverError::Mmio(format!("Intel MMIO offset overflow at {offset:#x}"))
|
||||
})?;
|
||||
if end > self.mmio.size() {
|
||||
return Err(DriverError::Mmio(format!(
|
||||
"Intel MMIO read outside BAR2 aperture: end={end:#x} size={:#x}",
|
||||
self.mmio.size()
|
||||
)));
|
||||
}
|
||||
Ok(self.mmio.read32(offset))
|
||||
}
|
||||
|
||||
fn read_pipeframe(&self, crtc_id: u32) -> Result<u64> {
|
||||
let pipe_index = crtc_id
|
||||
.checked_sub(1)
|
||||
.ok_or_else(|| DriverError::InvalidArgument("invalid Intel CRTC id"))?
|
||||
as usize;
|
||||
let offset = self.regs.pipeframe_reg(pipe) + pipe_index * self.regs.pipe_stride();
|
||||
let end = offset
|
||||
.checked_add(core::mem::size_of::<u32>())
|
||||
.ok_or_else(|| DriverError::Mmio("Intel PIPEFRAME offset overflow".into()))?;
|
||||
if end > self.mmio.size() {
|
||||
return Err(DriverError::Mmio(format!(
|
||||
"Intel PIPEFRAME read outside MMIO aperture: end={end:#x} size={:#x}",
|
||||
self.mmio.size()
|
||||
)));
|
||||
}
|
||||
let frame_count = self.mmio.read32(offset) & self.regs.pipeframe_count_mask();
|
||||
Ok(u64::from(frame_count))
|
||||
}
|
||||
}
|
||||
|
||||
impl GpuDriver for IntelDriver {
|
||||
fn driver_name(&self) -> &str {
|
||||
"i915-redox"
|
||||
}
|
||||
|
||||
fn driver_desc(&self) -> &str {
|
||||
"Intel i915-class DRM/KMS backend for Redox"
|
||||
}
|
||||
|
||||
fn driver_date(&self) -> &str {
|
||||
"2026-05-30"
|
||||
}
|
||||
let mut info = String::new();
|
||||
info.push_str(&format!("Intel GPU: {} (device {:#06x})\n",
|
||||
self.device_info.platform_name, self.info.device_id));
|
||||
info.push_str(&format!(" Generation: {:?}, display ver {}, GT ver {}\n",
|
||||
self.device_info.generation, self.device_info.display_version,
|
||||
self.device_info.gt_version));
|
||||
info.push_str(&format!(" Pipes: {}, Ports: {}, Memory: {} MB\n",
|
||||
self.device_info.num_pipes, self.device_info.num_ports, 256));
|
||||
info.push_str(&format!(" DDI: {}, DP AUX: {}, GMBUS: {}, DMC: {}\n",
|
||||
self.device_info.has_ddi, self.device_info.has_dp_aux,
|
||||
self.device_info.has_gmbus, self.device_info.has_dmc));
|
||||
info.push_str(&format!(" Combo PHY: {}, DBUF: {}, Sep Transcoder: {}\n",
|
||||
self.device_info.has_combo_phy, self.device_info.has_dbuf_slice,
|
||||
self.device_info.has_separate_transcoder));
|
||||
info.push_str(&format!(" DMC FW key: {:?}\n", self.device_info.dmc_fw_key));
|
||||
info.push_str(&format!(" Power wells ready: {}\n", self.display_power.is_display_ready()));
|
||||
info.push_str(&format!(" Forcewake: enabled\n"));
|
||||
info.push_str(&format!(" DP AUX channels: {}\n", self.dp_aux.len()));
|
||||
info.push_str(&format!(" GMBUS available: {}\n", self.gmbus.is_some()));
|
||||
info.push_str(&format!(" Connectors detected: {}\n", self.cached_connectors().len()));
|
||||
info.push_str(&format!(" CRTCs: {}\n",
|
||||
self.crtcs.lock().map(|c| c.len()).unwrap_or(0)));
|
||||
if let Ok(connectors) = self.connectors.lock() {
|
||||
for conn in connectors.iter() {
|
||||
info.push_str(&format!(" Connector {}: {:?} (status {:?}), {} modes\n",
|
||||
conn.info.id, conn.info.connector_type, conn.info.status,
|
||||
conn.info.modes.len()));
|
||||
}
|
||||
}
|
||||
match &self.irq_handle.lock() {
|
||||
Ok(handle) if handle.is_some() => {
|
||||
info.push_str(&format!(" IRQ: {} mode\n",
|
||||
handle.as_ref().map(|h| h.mode_name()).unwrap_or("none")));
|
||||
}
|
||||
_ => info.push_str(" IRQ: not configured\n"),
|
||||
}
|
||||
info
|
||||
}
|
||||
|
||||
fn detect_connectors(&self) -> Vec<ConnectorInfo> {
|
||||
match self.refresh_connectors() {
|
||||
Ok(connectors) => connectors,
|
||||
Err(error) => {
|
||||
warn!("redox-drm: Intel connector refresh failed: {}", error);
|
||||
self.cached_connectors()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn get_modes(&self, connector_id: u32) -> Vec<ModeInfo> {
|
||||
self.detect_connectors()
|
||||
.into_iter()
|
||||
.find(|connector| connector.id == connector_id)
|
||||
.map(|connector| connector.modes)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn set_crtc(
|
||||
&self,
|
||||
crtc_id: u32,
|
||||
fb_handle: u32,
|
||||
connectors: &[u32],
|
||||
mode: &ModeInfo,
|
||||
) -> Result<()> {
|
||||
if connectors.is_empty() {
|
||||
return Err(DriverError::InvalidArgument(
|
||||
"set_crtc requires at least one connector",
|
||||
));
|
||||
}
|
||||
|
||||
let fb_addr = self.ensure_gem_gpu_mapping(fb_handle)?;
|
||||
let mut pipe = self.display.pipe_for_crtc(crtc_id)?;
|
||||
pipe.port = Some(self.connector_port(connectors[0])?);
|
||||
|
||||
self.display.set_mode(&pipe, mode)?;
|
||||
|
||||
if let Some(port) = pipe.port {
|
||||
self.transcoder.configure(pipe.index, port, TransDdiMode::Dp, 4)?;
|
||||
}
|
||||
|
||||
self.watermark.program_for_mode(pipe.index, mode, true)?;
|
||||
|
||||
self.display.page_flip(&pipe, fb_addr)?;
|
||||
|
||||
let mut crtcs = self
|
||||
.crtcs
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel CRTC state poisoned".into()))?;
|
||||
let crtc = crtcs
|
||||
.iter_mut()
|
||||
.find(|crtc| crtc.id == crtc_id)
|
||||
.ok_or_else(|| DriverError::NotFound(format!("unknown CRTC {crtc_id}")))?;
|
||||
crtc.program(fb_handle, connectors, mode)
|
||||
}
|
||||
|
||||
fn page_flip(&self, crtc_id: u32, fb_handle: u32, _flags: u32) -> Result<u64> {
|
||||
let fb_addr = self.ensure_gem_gpu_mapping(fb_handle)?;
|
||||
let pipe = self.display.pipe_for_crtc(crtc_id)?;
|
||||
self.display.page_flip(&pipe, fb_addr)?;
|
||||
|
||||
let mut ring = self
|
||||
.ring
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?;
|
||||
ring.flush()?;
|
||||
Ok(ring.last_seqno())
|
||||
}
|
||||
|
||||
fn get_vblank(&self, crtc_id: u32) -> Result<u64> {
|
||||
self.read_pipeframe(crtc_id)
|
||||
}
|
||||
|
||||
fn gem_create(&self, size: u64, _width: u32, _height: u32) -> Result<GemHandle> {
|
||||
let handle = {
|
||||
let mut gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
gem.create(size)?
|
||||
};
|
||||
|
||||
if let Err(error) = self.ensure_gem_gpu_mapping(handle) {
|
||||
let _ = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?
|
||||
.close(handle);
|
||||
return Err(error);
|
||||
}
|
||||
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
fn gem_close(&self, handle: GemHandle) -> Result<()> {
|
||||
let (gpu_addr, size) = {
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
let object = gem.object(handle)?;
|
||||
(object.gpu_addr, object.size)
|
||||
};
|
||||
|
||||
if let Some(gpu_addr) = gpu_addr {
|
||||
let mut gtt = self
|
||||
.gtt
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel GGTT state poisoned".into()))?;
|
||||
gtt.unmap_range(gpu_addr, size)?;
|
||||
gtt.release_range(gpu_addr, size)?;
|
||||
}
|
||||
|
||||
self.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?
|
||||
.close(handle)
|
||||
}
|
||||
|
||||
fn gem_mmap(&self, handle: GemHandle) -> Result<usize> {
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
gem.mmap(handle)
|
||||
}
|
||||
|
||||
fn gem_size(&self, handle: GemHandle) -> Result<u64> {
|
||||
let gem = self
|
||||
.gem
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Buffer("Intel GEM manager poisoned".into()))?;
|
||||
Ok(gem.object(handle)?.size)
|
||||
}
|
||||
|
||||
fn get_edid(&self, connector_id: u32) -> Vec<u8> {
|
||||
match self.connectors.lock() {
|
||||
Ok(connectors) => connectors
|
||||
.iter()
|
||||
.find(|connector| connector.info.id == connector_id)
|
||||
.map(|connector| connector.edid.clone())
|
||||
.unwrap_or_default(),
|
||||
Err(poisoned) => poisoned
|
||||
.into_inner()
|
||||
.iter()
|
||||
.find(|connector| connector.info.id == connector_id)
|
||||
.map(|connector| connector.edid.clone())
|
||||
.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_irq(&self) -> Result<Option<DriverEvent>> {
|
||||
let irq_event = {
|
||||
let mut irq_handle = self
|
||||
.irq_handle
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel IRQ state poisoned".into()))?;
|
||||
match irq_handle.as_mut() {
|
||||
Some(handle) => handle
|
||||
.try_wait()
|
||||
.map_err(|e| DriverError::Io(format!("Intel IRQ poll failed: {e}")))?,
|
||||
None => return Ok(None),
|
||||
}
|
||||
};
|
||||
|
||||
if !irq_event {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
self.process_irq()
|
||||
}
|
||||
|
||||
fn redox_private_cs_submit(
|
||||
&self,
|
||||
submit: &RedoxPrivateCsSubmit,
|
||||
) -> Result<RedoxPrivateCsSubmitResult> {
|
||||
let src_addr = self.ensure_gem_gpu_mapping(submit.src_handle)?;
|
||||
|
||||
let cmds_ptr = (src_addr + submit.src_offset) as *const u32;
|
||||
let dword_count = (submit.byte_count / 4) as usize;
|
||||
let cmds = unsafe {
|
||||
std::slice::from_raw_parts(cmds_ptr, dword_count)
|
||||
};
|
||||
|
||||
let mut ring = self.ring.lock()
|
||||
.map_err(|_| DriverError::Initialization("Intel ring state poisoned".into()))?;
|
||||
ring.submit_batch(cmds)?;
|
||||
|
||||
Ok(RedoxPrivateCsSubmitResult { seqno: 0 })
|
||||
}
|
||||
|
||||
fn cursor_set(
|
||||
&self,
|
||||
crtc_id: u32,
|
||||
fb_handle: u32,
|
||||
hot_x: u32,
|
||||
hot_y: u32,
|
||||
) -> Result<()> {
|
||||
let fb_addr = self.ensure_gem_gpu_mapping(fb_handle)?;
|
||||
let pipe = self.display.pipe_for_crtc(crtc_id)?;
|
||||
let gtt_offset = fb_addr as u32;
|
||||
|
||||
self.cursor.set_surface(pipe.index, gtt_offset)?;
|
||||
self.cursor.enable(pipe.index)?;
|
||||
debug!("redox-drm-intel: cursor set on CRTC {} (pipe {}, fb {:#010x}, hot {},{})",
|
||||
crtc_id, pipe.index, gtt_offset, hot_x, hot_y);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cursor_move(&self, crtc_id: u32, x: i32, y: i32) -> Result<()> {
|
||||
let pipe = self.display.pipe_for_crtc(crtc_id)?;
|
||||
let ux = x.max(0).min(8191) as u16;
|
||||
let uy = y.max(0).min(8191) as u16;
|
||||
self.cursor.set_position(pipe.index, ux, uy)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_display_topology(display: &IntelDisplay, edid_source: Option<&[DpAux]>) -> Result<(Vec<Connector>, Vec<Encoder>)> {
|
||||
let detected = display.detect_connectors()?;
|
||||
let mut connectors = Vec::with_capacity(detected.len());
|
||||
let mut encoders = Vec::with_capacity(detected.len());
|
||||
|
||||
for connector in detected {
|
||||
let port = connector.connector_type_id.saturating_sub(1) as u8;
|
||||
let edid = match edid_source {
|
||||
Some(dp_aux_channels) if (port as usize) < dp_aux_channels.len() => {
|
||||
match dp_aux_channels[port as usize].read_edid() {
|
||||
Ok(data) => {
|
||||
info!("redox-drm-intel: read {} byte EDID via DP AUX port {}", data.len(), port);
|
||||
data
|
||||
}
|
||||
Err(e) => {
|
||||
debug!("redox-drm-intel: DP AUX EDID read failed on port {}: {}", port, e);
|
||||
display.read_edid(port)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => display.read_edid(port),
|
||||
};
|
||||
|
||||
encoders.push(Encoder::new(
|
||||
connector.encoder_id,
|
||||
pipe_id_for_port(display, port),
|
||||
));
|
||||
connectors.push(Connector {
|
||||
edid: if edid.is_empty() {
|
||||
synthetic_edid()
|
||||
} else {
|
||||
edid
|
||||
},
|
||||
info: ConnectorInfo {
|
||||
modes: display.modes_for_connector(&connector),
|
||||
..connector
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Ok((connectors, encoders))
|
||||
}
|
||||
|
||||
fn build_crtcs(display: &IntelDisplay) -> Result<Vec<Crtc>> {
|
||||
let mut crtcs: Vec<Crtc> = display
|
||||
.pipes()?
|
||||
.into_iter()
|
||||
.map(|pipe| Crtc::new(u32::from(pipe.index) + 1))
|
||||
.collect();
|
||||
|
||||
if crtcs.is_empty() {
|
||||
crtcs.push(Crtc::new(1));
|
||||
}
|
||||
|
||||
Ok(crtcs)
|
||||
}
|
||||
|
||||
fn pipe_id_for_port(display: &IntelDisplay, port: u8) -> u32 {
|
||||
display
|
||||
.pipes()
|
||||
.ok()
|
||||
.and_then(|pipes| {
|
||||
pipes
|
||||
.into_iter()
|
||||
.find(|pipe| pipe.port == Some(port))
|
||||
.map(|pipe| u32::from(pipe.index) + 1)
|
||||
})
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
fn connector_status_changed(previous: &[ConnectorInfo], current: &[ConnectorInfo]) -> bool {
|
||||
if previous.len() != current.len() {
|
||||
return true;
|
||||
}
|
||||
|
||||
previous.iter().zip(current.iter()).any(|(old, new)| {
|
||||
old.id != new.id
|
||||
|| old.connection != new.connection
|
||||
|| old.connector_type != new.connector_type
|
||||
})
|
||||
}
|
||||
|
||||
fn enable_forcewake(mmio: &MmioRegion) -> Result<()> {
|
||||
let end = FORCEWAKE
|
||||
.checked_add(core::mem::size_of::<u32>())
|
||||
.ok_or_else(|| DriverError::Mmio("Intel FORCEWAKE offset overflow".into()))?;
|
||||
if end > mmio.size() {
|
||||
return Err(DriverError::Mmio(format!(
|
||||
"Intel FORCEWAKE register outside MMIO aperture: end={end:#x} size={:#x}",
|
||||
mmio.size()
|
||||
)));
|
||||
}
|
||||
|
||||
mmio.write32(regs.forcewake_req(), 1);
|
||||
let _ = mmio.read32(regs.forcewake_req());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_intel_bars(
|
||||
info: &PciDeviceInfo,
|
||||
gtt_bar: &PciBarInfo,
|
||||
mmio_bar: &PciBarInfo,
|
||||
) -> Result<()> {
|
||||
if !gtt_bar.is_memory() {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {} GGTT BAR{} is not a memory BAR",
|
||||
info.location, gtt_bar.index
|
||||
)));
|
||||
}
|
||||
if !mmio_bar.is_memory() {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {} MMIO BAR{} is not a memory BAR",
|
||||
info.location, mmio_bar.index
|
||||
)));
|
||||
}
|
||||
|
||||
if gtt_bar.size < core::mem::size_of::<u64>() as u64 {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {} GGTT BAR{} is too small ({:#x})",
|
||||
info.location, gtt_bar.index, gtt_bar.size
|
||||
)));
|
||||
}
|
||||
if gtt_bar.size % core::mem::size_of::<u64>() as u64 != 0 {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {} GGTT BAR{} size {:#x} is not 8-byte aligned",
|
||||
info.location, gtt_bar.index, gtt_bar.size
|
||||
)));
|
||||
}
|
||||
|
||||
let required_mmio_end = [
|
||||
FORCEWAKE + core::mem::size_of::<u32>(),
|
||||
self.regs.pp_status() + core::mem::size_of::<u32>(),
|
||||
self.regs.gfx_flsh_cntl() + core::mem::size_of::<u32>(),
|
||||
RENDER_RING_BASE + RING_TAIL_OFFSET + core::mem::size_of::<u32>(),
|
||||
RENDER_RING_BASE + RING_HEAD_OFFSET + core::mem::size_of::<u32>(),
|
||||
]
|
||||
.into_iter()
|
||||
.max()
|
||||
.unwrap_or(0);
|
||||
|
||||
if mmio_bar.size < required_mmio_end as u64 {
|
||||
return Err(DriverError::Pci(format!(
|
||||
"device {} MMIO BAR{} is too small ({:#x}) for required register window ending at {:#x}",
|
||||
info.location, mmio_bar.index, mmio_bar.size, required_mmio_end
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn find_memory_bar(info: &PciDeviceInfo, index: usize, name: &str) -> Result<PciBarInfo> {
|
||||
info.find_memory_bar(index)
|
||||
.copied()
|
||||
.ok_or_else(|| DriverError::Pci(format!("device {} has no {}", info.location, name)))
|
||||
}
|
||||
|
||||
fn map_bar(device: &mut PciDevice, bar: &PciBarInfo, name: &str) -> Result<MmioRegion> {
|
||||
device
|
||||
.map_bar(bar.index, bar.addr, bar.size as usize)
|
||||
.map_err(|e| DriverError::Mmio(format!("failed to map {name}: {e}")))
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn ddi_buf_ctl(port: u8) -> usize {
|
||||
self.regs.ddi_buf_ctl(0) + usize::from(port) * self.regs.ddi_port_stride()
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn pipeconf(pipe: &DisplayPipe) -> usize {
|
||||
self.regs.pipeconf(0) + usize::from(pipe.index) * self.regs.pipe_stride()
|
||||
}
|
||||
@@ -47,7 +47,22 @@ pub trait IntelRegs: Send + Sync {
|
||||
fn pipeframe_reg(&self, pipe: u8) -> usize;
|
||||
fn pipeframe_count_mask(&self) -> u32;
|
||||
|
||||
fn pipestat(&self, pipe: u8) -> usize;
|
||||
fn de_iir(&self) -> usize;
|
||||
fn de_imr(&self) -> usize;
|
||||
fn de_ier(&self) -> usize;
|
||||
fn pipestat_vblank_mask(&self) -> u32;
|
||||
fn pipestat_vsync_mask(&self) -> u32;
|
||||
|
||||
fn gfx_flsh_cntl(&self) -> usize;
|
||||
|
||||
fn pp_status(&self) -> usize;
|
||||
|
||||
/// D2D link control register offset per port. Xe2 has D2D links; Gen9/Gen12 do not.
|
||||
/// Returns 0 if the platform does not support D2D links.
|
||||
fn d2d_link_ctl(&self, _port: u8) -> usize { 0 }
|
||||
|
||||
/// DE_CAP register for display engine capability discovery (Xe2 only).
|
||||
/// Returns 0 if the platform does not have a DE_CAP register.
|
||||
fn de_cap(&self) -> usize { 0 }
|
||||
}
|
||||
|
||||
@@ -83,6 +83,15 @@ impl IntelRegs for Gen12Regs {
|
||||
}
|
||||
fn pipeframe_count_mask(&self) -> u32 { 0x00FFFFFF }
|
||||
|
||||
fn pipestat(&self, pipe: u8) -> usize {
|
||||
0x70024 + (pipe as usize) * 0x1000
|
||||
}
|
||||
fn de_iir(&self) -> usize { 0x44408 }
|
||||
fn de_imr(&self) -> usize { 0x4440C }
|
||||
fn de_ier(&self) -> usize { 0x44410 }
|
||||
fn pipestat_vblank_mask(&self) -> u32 { 1 << 0 }
|
||||
fn pipestat_vsync_mask(&self) -> u32 { 1 << 1 }
|
||||
|
||||
fn gfx_flsh_cntl(&self) -> usize { 0x101008 }
|
||||
|
||||
fn pp_status(&self) -> usize { 0xC7200 }
|
||||
|
||||
@@ -83,6 +83,15 @@ impl IntelRegs for Gen9Regs {
|
||||
}
|
||||
fn pipeframe_count_mask(&self) -> u32 { 0x00FFFFFF }
|
||||
|
||||
fn pipestat(&self, pipe: u8) -> usize {
|
||||
0x70024 + (pipe as usize) * 0x1000
|
||||
}
|
||||
fn de_iir(&self) -> usize { 0x44408 }
|
||||
fn de_imr(&self) -> usize { 0x4440C }
|
||||
fn de_ier(&self) -> usize { 0x44410 }
|
||||
fn pipestat_vblank_mask(&self) -> u32 { 1 << 0 }
|
||||
fn pipestat_vsync_mask(&self) -> u32 { 1 << 1 }
|
||||
|
||||
fn gfx_flsh_cntl(&self) -> usize { 0x101008 }
|
||||
|
||||
fn pp_status(&self) -> usize { 0xC7200 }
|
||||
|
||||
@@ -83,9 +83,24 @@ impl IntelRegs for Xe2Regs {
|
||||
}
|
||||
fn pipeframe_count_mask(&self) -> u32 { 0x00FFFFFF }
|
||||
|
||||
fn pipestat(&self, pipe: u8) -> usize {
|
||||
0x70024 + (pipe as usize) * 0x1000
|
||||
}
|
||||
fn de_iir(&self) -> usize { 0x44408 }
|
||||
fn de_imr(&self) -> usize { 0x4440C }
|
||||
fn de_ier(&self) -> usize { 0x44410 }
|
||||
fn pipestat_vblank_mask(&self) -> u32 { 1 << 0 }
|
||||
fn pipestat_vsync_mask(&self) -> u32 { 1 << 1 }
|
||||
|
||||
fn gfx_flsh_cntl(&self) -> usize { 0x101008 }
|
||||
|
||||
fn pp_status(&self) -> usize { 0xC7200 }
|
||||
|
||||
fn d2d_link_ctl(&self, port: u8) -> usize {
|
||||
0x64200 + (port as usize) * 0x100
|
||||
}
|
||||
|
||||
fn de_cap(&self) -> usize { 0x41100 }
|
||||
}
|
||||
|
||||
pub struct Xe2LpdRegs {
|
||||
|
||||
@@ -26,6 +26,7 @@ const RING_CTL_SIZE_MASK: u32 = !0x0FFF;
|
||||
|
||||
const MI_NOOP: u32 = 0x0000_0000;
|
||||
const MI_FLUSH_DW: u32 = 0x0200_0000;
|
||||
const MI_USER_INTERRUPT: u32 = 0x0200_0000;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum RingType {
|
||||
@@ -107,12 +108,13 @@ impl IntelRing {
|
||||
));
|
||||
}
|
||||
|
||||
self.wait_for_space(buffer.len())?;
|
||||
self.wait_for_space(buffer.len() + 1)?;
|
||||
|
||||
for &dword in buffer {
|
||||
self.write_dword(dword)?;
|
||||
}
|
||||
|
||||
self.write_dword(MI_USER_INTERRUPT)?;
|
||||
self.publish_tail()?;
|
||||
self.last_seqno = self.last_seqno.saturating_add(1);
|
||||
debug!(
|
||||
@@ -166,6 +168,10 @@ impl IntelRing {
|
||||
self.last_seqno
|
||||
}
|
||||
|
||||
pub fn ring_type(&self) -> RingType {
|
||||
self.ring_type
|
||||
}
|
||||
|
||||
fn program_ring_registers(&mut self, gpu_addr: u64) -> Result<()> {
|
||||
self.write_reg(RBHEAD, 0)?;
|
||||
self.write_reg(RBTAIL, 0)?;
|
||||
|
||||
@@ -81,11 +81,12 @@ impl VirtioDriver {
|
||||
)));
|
||||
}
|
||||
|
||||
let mut pci = PciDevice::open_location(&info.location).map_err(|e| {
|
||||
DriverError::Pci(format!("failed to re-open VirtIO GPU PCI config: {e}"))
|
||||
// pcid-spawner already called enable_device() via the pcid channel
|
||||
// before spawning this process. Use I/O ports directly for config
|
||||
// space access — the pcid scheme has no "config" file handle.
|
||||
let mut pci = PciDevice::open_io_ports(&info.location).map_err(|e| {
|
||||
DriverError::Pci(format!("VirtIO I/O port config access failed for {}: {e}", info.location))
|
||||
})?;
|
||||
pci.enable_device()
|
||||
.map_err(|e| DriverError::Pci(format!("VirtIO enable_device failed: {e}")))?;
|
||||
|
||||
let irq_handle = match InterruptHandle::setup(&info, &mut pci) {
|
||||
Ok(handle) => Some(handle),
|
||||
|
||||
@@ -296,6 +296,9 @@ const INTEL_CNL_DMC_KEYS: &[&str] = &["i915/cnl_dmc_ver1_07.bin", "i915/cnl_dmc_
|
||||
const INTEL_ICL_DMC_KEYS: &[&str] = &["i915/icl_dmc_ver1_09.bin", "i915/icl_dmc_ver1_07.bin"];
|
||||
const INTEL_GLK_DMC_KEYS: &[&str] = &["i915/glk_dmc_ver1_04.bin"];
|
||||
const INTEL_RKL_DMC_KEYS: &[&str] = &["i915/rkl_dmc_ver2_03.bin", "i915/rkl_dmc_ver2_02.bin"];
|
||||
const INTEL_ARL_DMC_KEYS: &[&str] = &["i915/mtl_dmc.bin"];
|
||||
const INTEL_LNL_DMC_KEYS: &[&str] = &["i915/lnl_dmc.bin"];
|
||||
const INTEL_BMG_DMC_KEYS: &[&str] = &["i915/bmg_dmc.bin"];
|
||||
fn intel_display_firmware_keys(device_id: u16) -> Option<&'static [&'static str]> {
|
||||
match device_id {
|
||||
// Gen12+ (Tiger Lake and newer)
|
||||
@@ -307,9 +310,17 @@ fn intel_display_firmware_keys(device_id: u16) -> Option<&'static [&'static str]
|
||||
| 0x56BA | 0x56BB | 0x56BC | 0x56BD | 0x56BE | 0x56BF | 0x56C0 | 0x56C1 => {
|
||||
Some(INTEL_DG2_DMC_KEYS)
|
||||
}
|
||||
0x7D40 | 0x7D41 | 0x7D45 | 0x7D51 | 0x7D55 | 0x7D60 | 0x7D67 | 0x7DD1 | 0x7DD5 => {
|
||||
Some(INTEL_MTL_DMC_KEYS)
|
||||
}
|
||||
// Meteor Lake proper (display IP 12.7)
|
||||
0x7D40 | 0x7D45 | 0x7D55 | 0x7D60 | 0x7DD5 => Some(INTEL_MTL_DMC_KEYS),
|
||||
// Arrow Lake (display IP 14.0 — shares DMC firmware with MTL)
|
||||
0x7D41 | 0x7D51 | 0x7D67 | 0x7DD1 => Some(INTEL_ARL_DMC_KEYS),
|
||||
// Lunar Lake (display IP 20.0)
|
||||
0x6420 | 0x64A0 | 0x64B0 => Some(INTEL_LNL_DMC_KEYS),
|
||||
// Battlemage (display IP 14.0, discrete)
|
||||
0xE202 | 0xE209 | 0xE20B | 0xE20C | 0xE20D | 0xE210 | 0xE211 | 0xE212 | 0xE216
|
||||
| 0xE220 | 0xE221 | 0xE222 | 0xE223 => Some(INTEL_BMG_DMC_KEYS),
|
||||
// Alder Lake-P Gen12 extended IDs
|
||||
0x4626 | 0x46A8 | 0x4628 | 0x46B3 => Some(INTEL_ADLP_DMC_KEYS),
|
||||
// Gen9 (Ice Lake / Rocket Lake / Cannon Lake)
|
||||
0x4905 | 0x4906 | 0x4907 | 0x4908 | 0x4909 => Some(INTEL_ICL_DMC_KEYS),
|
||||
0x4C80 | 0x4C8A | 0x4C8B | 0x4C8C | 0x4C90 | 0x4C9A => Some(INTEL_RKL_DMC_KEYS),
|
||||
|
||||
@@ -12,7 +12,7 @@ use syscall::flag::{EventFlags, MapFlags, MunmapFlags, MODE_CHR};
|
||||
use syscall::schemev2::NewFdFlags;
|
||||
|
||||
use crate::driver::{
|
||||
DriverEvent, GpuDriver, RedoxPrivateCsSubmit, RedoxPrivateCsSubmitResult, RedoxPrivateCsWait,
|
||||
DriverError, DriverEvent, GpuDriver, RedoxPrivateCsSubmit, RedoxPrivateCsSubmitResult, RedoxPrivateCsWait,
|
||||
RedoxPrivateCsWaitResult,
|
||||
};
|
||||
use crate::gem::GemHandle;
|
||||
@@ -1302,10 +1302,10 @@ impl DrmScheme {
|
||||
|
||||
out = bytes_of(&response);
|
||||
for (value, name) in [
|
||||
(0, b"On\0"),
|
||||
(1, b"Standby\0"),
|
||||
(2, b"Suspend\0"),
|
||||
(3, b"Off\0"),
|
||||
(0u64, b"On\0" as &[u8]),
|
||||
(1u64, b"Standby\0" as &[u8]),
|
||||
(2u64, b"Suspend\0" as &[u8]),
|
||||
(3u64, b"Off\0" as &[u8]),
|
||||
] {
|
||||
let mut e = DrmModePropertyEnumWire::default();
|
||||
e.value = value;
|
||||
|
||||
@@ -57,7 +57,7 @@ add_subdirectory(src)
|
||||
|
||||
# Enable unit testing
|
||||
if (BUILD_TESTING)
|
||||
################################################################### add_subdirectory(autotests)
|
||||
#################################################################### add_subdirectory(autotests)
|
||||
add_subdirectory(tests)
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
# shall we use DBus?
|
||||
# enabled per default on Linux & BSD systems
|
||||
|
||||
@@ -129,6 +129,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
find_package(KF6Codecs ${KF_DEP_VERSION} REQUIRED)
|
||||
find_package(KF6Config ${KF_DEP_VERSION} REQUIRED)
|
||||
|
||||
@@ -123,6 +123,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
# shall we use DBus?
|
||||
# enabled per default on Linux & BSD systems
|
||||
|
||||
@@ -32,7 +32,7 @@ find_package(KF6GuiAddons ${KF_DEP_VERSION} REQUIRED)
|
||||
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT REDOX)
|
||||
########################################################################################## find_package(KF6GlobalAccel ${KF_DEP_VERSION} REQUIRED)
|
||||
########################################################################################### find_package(KF6GlobalAccel ${KF_DEP_VERSION} REQUIRED)
|
||||
set(HAVE_KGLOBALACCEL TRUE)
|
||||
else()
|
||||
set(HAVE_KGLOBALACCEL FALSE)
|
||||
|
||||
@@ -143,6 +143,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6Svg ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
|
||||
|
||||
# shall we use DBus?
|
||||
|
||||
@@ -38,7 +38,7 @@ set_package_properties(Qt6Qml PROPERTIES
|
||||
)
|
||||
|
||||
if (TARGET Qt6::Qml)
|
||||
##################################################################### include(ECMQmlModule)
|
||||
###################################################################### include(ECMQmlModule)
|
||||
endif()
|
||||
|
||||
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
add_subdirectory(core)
|
||||
if (TARGET Qt6::Qml)
|
||||
#################################################################### add_subdirectory(qml)
|
||||
##################################################################### add_subdirectory(qml)
|
||||
endif()
|
||||
|
||||
ecm_qt_install_logging_categories(
|
||||
|
||||
@@ -109,6 +109,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
|
||||
option(WITH_X11 "Build with support for QX11Info::appUserTime()" ON)
|
||||
|
||||
@@ -124,6 +124,7 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
|
||||
|
||||
if (WITH_TEXT_TO_SPEECH)
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED TextToSpeech)
|
||||
|
||||
@@ -129,6 +129,7 @@ find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
find_package(Qt6WaylandClientPrivate REQUIRED)
|
||||
set_package_properties(Wayland PROPERTIES
|
||||
TYPE REQUIRED
|
||||
)
|
||||
|
||||
@@ -74,10 +74,10 @@ void initializeLanguages()
|
||||
// Ideally setting the LANGUAGE would change the default QLocale too
|
||||
// but unfortunately this is too late since the QCoreApplication constructor
|
||||
// already created a QLocale at this stage so we need to set the reset it
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // by triggering the creation and destruction of a QSystemLocale
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // by triggering the creation and destruction of a QSystemLocale
|
||||
// this is highly dependent on Qt internals, so may break, but oh well
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QSystemLocale *dummy = new QSystemLocale();
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// delete dummy;
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QSystemLocale *dummy = new QSystemLocale();
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// delete dummy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,9 +65,9 @@ ecm_set_disabled_deprecation_versions(
|
||||
)
|
||||
|
||||
add_subdirectory( src )
|
||||
########################################if (BUILD_TESTING)
|
||||
######################################## add_subdirectory( autotests )
|
||||
########################################endif()
|
||||
#########################################if (BUILD_TESTING)
|
||||
######################################### add_subdirectory( autotests )
|
||||
#########################################endif()
|
||||
|
||||
if (BUILD_QCH)
|
||||
ecm_install_qch_export(
|
||||
|
||||
@@ -78,7 +78,7 @@ set_package_properties(PList PROPERTIES
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES Linux)
|
||||
# Used by the UDisks backend on Linux
|
||||
###########################################################################################################find_package(LibMount)
|
||||
############################################################################################################find_package(LibMount)
|
||||
set_package_properties(LibMount PROPERTIES
|
||||
TYPE REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#include <libudev.h>
|
||||
#include <libudev.h>
|
||||
#include <libudev.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#include "config-kwin.h"
|
||||
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
################################################################################################################################add_subdirectory(killer) # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only
|
||||
#################################################################################################################################add_subdirectory(killer) # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only # disabled: X11-only
|
||||
add_subdirectory(wayland_wrapper)
|
||||
|
||||
@@ -382,6 +382,9 @@
|
||||
#ifndef SUN_LEN
|
||||
#define SUN_LEN(s) (sizeof(*(s)) - sizeof((s)->sun_path) + strnlen((s)->sun_path, sizeof((s)->sun_path)))
|
||||
#endif
|
||||
#ifndef SUN_LEN
|
||||
#define SUN_LEN(s) (sizeof(*(s)) - sizeof((s)->sun_path) + strnlen((s)->sun_path, sizeof((s)->sun_path)))
|
||||
#endif
|
||||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
@@ -10,5 +10,5 @@ target_link_libraries(systembell PRIVATE
|
||||
|
||||
KF6::GlobalAccel
|
||||
KF6::I18n
|
||||
$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,Canberra::Canberra,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>
|
||||
$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,$<IF:$<BOOL:${Canberra_FOUND}>,Canberra::Canberra,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>,>
|
||||
)
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#include <libudev.h>
|
||||
#include <libudev.h>
|
||||
#include <libudev.h>
|
||||
#include <libudev.h>
|
||||
|
||||
#include "backends/libinput/device.h"
|
||||
#include "core/inputdevice.h"
|
||||
|
||||
@@ -766,6 +766,12 @@
|
||||
#define F_SEAL_SHRINK 0x0002
|
||||
#define F_SEAL_GROW 0x0004
|
||||
#define F_SEAL_WRITE 0x0008
|
||||
#define F_ADD_SEALS 1033
|
||||
#define F_GET_SEALS 1034
|
||||
#define F_SEAL_SEAL 0x0001
|
||||
#define F_SEAL_SHRINK 0x0002
|
||||
#define F_SEAL_GROW 0x0004
|
||||
#define F_SEAL_WRITE 0x0008
|
||||
/*
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
@@ -294,6 +294,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_REDOX
|
||||
#undef QT_USE_XOPEN_LFS_EXTENSIONS
|
||||
#undef QT_LARGEFILE_SUPPORT
|
||||
#ifndef O_LARGEFILE
|
||||
#define O_LARGEFILE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||
|
||||
|
||||
@@ -1459,6 +1459,13 @@ qt_internal_extend_target(Core CONDITION REDOX
|
||||
io/qstorageinfo_unix.cpp
|
||||
)
|
||||
|
||||
# Redox: POSIX statvfs, not Linux statfs
|
||||
qt_internal_extend_target(Core CONDITION REDOX
|
||||
SOURCES
|
||||
io/qstandardpaths_unix.cpp
|
||||
io/qstorageinfo_unix.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Core CONDITION QT_FEATURE_cpp_winrt
|
||||
SOURCES
|
||||
platform/windows/qfactorycacheregistration_p.h
|
||||
@@ -1746,6 +1753,13 @@ qt_internal_extend_target(Core CONDITION REDOX
|
||||
io/qstorageinfo_unix.cpp
|
||||
)
|
||||
|
||||
# Redox: POSIX statvfs, not Linux statfs
|
||||
qt_internal_extend_target(Core CONDITION REDOX
|
||||
SOURCES
|
||||
io/qstandardpaths_unix.cpp
|
||||
io/qstorageinfo_unix.cpp
|
||||
)
|
||||
|
||||
qt_internal_extend_target(Core CONDITION QT_FEATURE_itemmodel
|
||||
SOURCES
|
||||
itemmodels/qabstractitemmodel.cpp itemmodels/qabstractitemmodel.h itemmodels/qabstractitemmodel_p.h
|
||||
|
||||
@@ -214,6 +214,7 @@ static_assert(std::is_signed_v<qint128>,
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#ifndef static_assert
|
||||
#define static_assert _Static_assert
|
||||
#endif
|
||||
|
||||
@@ -1158,6 +1158,7 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
#ifdef IPV6_HOPLIMIT
|
||||
if (header.hopLimit != -1) {
|
||||
msg.msg_controllen += CMSG_SPACE(sizeof(int));
|
||||
@@ -1203,6 +1204,7 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
if (header.ifindex != 0 || !header.senderAddress.isNull()) {
|
||||
struct in6_pktinfo *data = reinterpret_cast<in6_pktinfo *>(CMSG_DATA(cmsgptr));
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if defined(Q_OS_VXWORKS)
|
||||
|
||||
+4
@@ -88,6 +88,7 @@ public:
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
@@ -126,6 +127,7 @@ public:
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
virtual bool canCreatePlatformOffscreenSurface() const { return false; }
|
||||
#if QT_CONFIG(opengl)
|
||||
@@ -175,6 +177,7 @@ public:
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
#if QT_CONFIG(opengl)
|
||||
virtual void *nativeResourceForContext(NativeResource /*resource*/, QPlatformOpenGLContext */*context*/) { return nullptr; }
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
@@ -214,6 +217,7 @@ public:
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
#endif /* QT_CONFIG(opengl) */
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -76,7 +76,6 @@ fn detect_vendor(cpu: u32) -> Vendor {
|
||||
fn detect_cpus() -> Vec<u32> {
|
||||
// Try /scheme/sys/cpu first for CPU count
|
||||
if let Ok(d) = fs::read_to_string("/scheme/sys/cpu") {
|
||||
let mut v = Vec::new();
|
||||
for line in d.lines() {
|
||||
if line.starts_with("CPUs: ") {
|
||||
if let Ok(count) = line[6..].trim().parse::<u32>() {
|
||||
|
||||
+1
-1
Submodule local/sources/base updated: 48872298aa...d1a0400e84
+1
-1
Submodule local/sources/kernel updated: 51b15a181a...502f5c5190
+1
-1
Submodule local/sources/relibc updated: 33f77f4172...188e3dacd6
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -11,7 +11,12 @@ if [ "${COOKBOOK_HOST_SYSROOT}" = "/usr" ] && command -v rustup >/dev/null 2>&1;
|
||||
popd
|
||||
fi
|
||||
|
||||
export CARGO=${CARGO:-env -u CARGO cargo}
|
||||
# Override CARGO to preserve RUSTUP_TOOLCHAIN for correct nightly
|
||||
export CARGO="env -u CARGO cargo"
|
||||
export RUSTUP_TOOLCHAIN=nightly-2025-11-15
|
||||
export REDOXER_TOOLCHAIN=""
|
||||
# Allow unused mut (edition 2024 migration noise)
|
||||
export RUSTCFLAGS="-A unused_mut"
|
||||
"${COOKBOOK_MAKE}" \
|
||||
-C "${COOKBOOK_SOURCE}" \
|
||||
-j"${COOKBOOK_MAKE_JOBS}" \
|
||||
|
||||
+24
-2
@@ -11,6 +11,8 @@ esac
|
||||
CONFIG_NAME="redbear-mini"
|
||||
ARCH="x86_64"
|
||||
ALLOW_UPSTREAM=0
|
||||
NO_CACHE=0
|
||||
DISTCLEAN=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
@@ -19,8 +21,12 @@ Usage: $(basename "$0") [OPTIONS] [CONFIG_NAME] [ARCH]
|
||||
Build a Red Bear OS live ISO for real bare metal.
|
||||
|
||||
Options:
|
||||
--upstream Allow Redox/upstream recipe source refresh during build
|
||||
-h, --help Show this help
|
||||
--upstream Allow Redox/upstream recipe source refresh during build
|
||||
--no-cache Rebuild from scratch, discarding recipe build caches and
|
||||
package repository (preserves cross-compiler toolchain)
|
||||
--no-cache-distclean Full rebuild including cross-compiler toolchain
|
||||
(use when toolchain itself is broken or outdated)
|
||||
-h, --help Show this help
|
||||
|
||||
Supported targets:
|
||||
redbear-full Full desktop ISO (Wayland + KDE + GPU drivers)
|
||||
@@ -39,6 +45,12 @@ while [ $# -gt 0 ]; do
|
||||
--upstream)
|
||||
ALLOW_UPSTREAM=1
|
||||
;;
|
||||
--no-cache)
|
||||
NO_CACHE=1
|
||||
;;
|
||||
--no-cache-distclean)
|
||||
DISTCLEAN=1
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
@@ -86,6 +98,16 @@ fi
|
||||
echo "Building Red Bear OS ISO for real bare metal"
|
||||
echo " config: ${CONFIG_NAME}"
|
||||
echo " arch: ${ARCH}"
|
||||
if [ "$DISTCLEAN" -eq 1 ]; then
|
||||
echo " cache: full distclean (rebuilding toolchain + packages)"
|
||||
make clean
|
||||
elif [ "$NO_CACHE" -eq 1 ]; then
|
||||
echo " cache: disabled (rebuilding packages, preserving toolchain)"
|
||||
make repo_clean
|
||||
rm -rf repo
|
||||
# Also clean local recipe targets that repo_clean misses
|
||||
find local/recipes -maxdepth 4 -name "target" -type d -exec rm -rf {} + 2>/dev/null || true
|
||||
fi
|
||||
if [ "$ALLOW_UPSTREAM" -eq 1 ]; then
|
||||
echo " upstream recipe refresh: enabled"
|
||||
REPO_OFFLINE=0 COOKBOOK_OFFLINE=false make live CONFIG_NAME="${CONFIG_NAME}" ARCH="${ARCH}"
|
||||
|
||||
Reference in New Issue
Block a user