Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9f3f77cb72 | |||
| ad1cf5e7ed | |||
| 0eae5a8420 | |||
| f3a607a090 | |||
| c4d64756a2 |
-20
@@ -148,27 +148,7 @@ precedence = "deny"
|
||||
# for any platform with Modern Standby firmware (Dell, HP,
|
||||
# Lenovo, LG Gram, etc.).
|
||||
redox_syscall = { path = "../syscall" }
|
||||
# Red Bear OS Phase J: libredox 0.1.17 has its own vendored
|
||||
# redox_syscall dep. Without the libredox override here,
|
||||
# libredox::error::Error is the upstream syscall::error::Error
|
||||
# (a different compile-time type than the local fork's
|
||||
# syscall::Error) and the conversion `?` operator in
|
||||
# scheme-utils / daemon fails with E0277. Override libredox
|
||||
# to use the local fork at ../libredox/ (which itself uses
|
||||
# the local syscall fork). Now libredox::error::Error and
|
||||
# syscall::Error are the same type.
|
||||
libredox = { path = "../libredox" }
|
||||
# Red Bear OS Phase J (extended): redox-scheme 0.11.x from crates.io
|
||||
# pins redox_syscall = "0.9.0" exactly, which Cargo refuses to
|
||||
# satisfy with the local +rb0.3.0 fork (0.9.0+rb0.3.0). Without this
|
||||
# patch, Cargo pulls crates.io redox-scheme which transitively
|
||||
# pulls crates.io redox_syscall 0.9.0, leading to two different
|
||||
# `syscall::Error` types and E0277 errors in scheme-utils / daemon.
|
||||
# Patch redox-scheme to the local fork at ../redox-scheme/ which
|
||||
# has its redox_syscall and libredox dep requirements bumped to
|
||||
# the +rb0.3.0 versions. The local fork is a thin pass-through of
|
||||
# upstream redox-scheme 0.11.2 source with only the dep versions
|
||||
# updated — no behavioural changes.
|
||||
redox-scheme = { path = "../redox-scheme" }
|
||||
|
||||
[patch."https://gitlab.redox-os.org/redox-os/relibc.git"]
|
||||
|
||||
@@ -11,6 +11,48 @@ pub const PLANE_CTL_ENABLE: u32 = 1 << 31;
|
||||
pub const PLANE_WM_ENABLE: u32 = 1 << 31;
|
||||
pub const PLANE_WM_LINES_SHIFT: u32 = 14;
|
||||
|
||||
/// Cursor control register bits (CURCNTR).
|
||||
pub const CURSOR_MODE_DISABLE: u32 = 0;
|
||||
pub const CURSOR_MODE_ARGB: u32 = 0b10 << 28;
|
||||
pub const CURSOR_ENABLE: u32 = 1 << 31;
|
||||
/// Cursor base must be page-aligned (lower 12 bits are ignored).
|
||||
pub const CURSOR_BASE_ALIGN: u32 = 4096;
|
||||
|
||||
/// Hardware cursor plane. Intel GPUs have one cursor plane per pipe,
|
||||
/// mapped at CURCNTR/CURBASE/CURPOS MMIO registers.
|
||||
pub struct CursorPlane {
|
||||
/// Cursor Control register (enable/disable, format).
|
||||
pub cntr: MmioPtr<u32>,
|
||||
/// Cursor Base Address (GTT offset of cursor surface).
|
||||
pub base: MmioPtr<u32>,
|
||||
/// Cursor Position (x/y in screen coordinates).
|
||||
pub pos: MmioPtr<u32>,
|
||||
}
|
||||
|
||||
impl CursorPlane {
|
||||
/// Enable or disable the hardware cursor.
|
||||
pub fn set_enabled(&mut self, enabled: bool) {
|
||||
if enabled {
|
||||
self.cntr.write(CURSOR_ENABLE | CURSOR_MODE_ARGB);
|
||||
} else {
|
||||
self.cntr.write(CURSOR_MODE_DISABLE);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the GTT offset of the cursor surface (must be page-aligned).
|
||||
pub fn set_base(&mut self, gtt_offset: u32) {
|
||||
self.base.write(gtt_offset);
|
||||
}
|
||||
|
||||
/// Set the cursor position. `x` and `y` are signed 16-bit screen
|
||||
/// coordinates (negative values clip the cursor to the left/top edge
|
||||
/// of the visible region).
|
||||
pub fn set_position(&mut self, x: i16, y: i16) {
|
||||
let val = ((x as u16 as u32) & 0xFFFF) | (((y as u16 as u32) & 0xFFFF) << 16);
|
||||
self.pos.write(val);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DeviceFb {
|
||||
pub buffer: GpuBuffer,
|
||||
@@ -102,8 +144,18 @@ impl Plane {
|
||||
})?;
|
||||
self.buf_cfg.write(buffer.start | (buffer.end << 16));
|
||||
|
||||
//TODO: correct watermark calculation
|
||||
self.wm[0].write(PLANE_WM_ENABLE | (2 << PLANE_WM_LINES_SHIFT) | buffer.len() as u32);
|
||||
// Watermark: display FIFO prefetch depth in scanlines.
|
||||
// Intel PRM: minimum 8 lines for display-only planes at 1080p.
|
||||
// Higher resolutions need proportionally more lines to avoid
|
||||
// underruns. Formula: max(8, vdisplay / 16) capped at 128.
|
||||
let size = self.size.read();
|
||||
let vdisplay = ((size >> 16) & 0xFFFF) + 1;
|
||||
let wm_lines = (vdisplay / 16).clamp(8, 128);
|
||||
self.wm[0].write(
|
||||
PLANE_WM_ENABLE
|
||||
| ((wm_lines & 0x1F) << PLANE_WM_LINES_SHIFT)
|
||||
| (buffer.len() as u32 & 0x1FF),
|
||||
);
|
||||
for i in 1..self.wm.len() {
|
||||
self.wm[i].writef(PLANE_WM_ENABLE, false);
|
||||
}
|
||||
@@ -116,11 +168,15 @@ impl Plane {
|
||||
let size = self.size.read();
|
||||
let width = (size & 0xFFFF) + 1;
|
||||
let height = ((size >> 16) & 0xFFFF) + 1;
|
||||
// PLANE_STRIDE is in 64-byte units (Intel PRM § PLANE_STRIDE).
|
||||
let stride_64 = self.stride.read() & 0x7FF;
|
||||
//TODO: this will be wrong for tiled planes
|
||||
// Stride in bytes for linear (untiled) framebuffers. Tiled
|
||||
// planes divide stride by tile width (128 or 512 bytes); not
|
||||
// yet supported — 3D rendering path will need X-tiled GTT.
|
||||
let stride = stride_64 * 64;
|
||||
let surf = self.surf.read() & 0xFFFFF000;
|
||||
//TODO: read bits per pixel
|
||||
// ARGB8888 = 4 bytes per pixel. surface_size = stride × height,
|
||||
// page-aligned for GTT reservation.
|
||||
let surf_size = (stride * height).next_multiple_of(4096);
|
||||
ggtt.reserve(surf, surf_size);
|
||||
|
||||
@@ -128,7 +184,7 @@ impl Plane {
|
||||
}
|
||||
|
||||
pub fn set_framebuffer(&mut self, fb: &DeviceFb) {
|
||||
//TODO: documentation on this is not great
|
||||
// PLANE_STRIDE is in 64-byte units (Intel PRM Display chapter).
|
||||
let stride_64 = fb.stride / 64;
|
||||
|
||||
self.size.write((fb.width - 1) | ((fb.height - 1) << 16));
|
||||
@@ -136,12 +192,15 @@ impl Plane {
|
||||
|
||||
self.surf.write(fb.buffer.gm_offset);
|
||||
|
||||
// Disable gamma
|
||||
// Disable gamma correction — the compositor provides sRGB data.
|
||||
if let Some(color_ctl) = &mut self.color_ctl {
|
||||
color_ctl.write(self.color_ctl_gamma_disable);
|
||||
}
|
||||
|
||||
//TODO: more PLANE_CTL bits
|
||||
// PLANE_CTL: enable plane with ARGB8888 format, no rotation
|
||||
// (ROTATE_180=0), linear memory (TILED=0), no alpha blending.
|
||||
// Rotation and tiling are configured when the GTT supports
|
||||
// X-tiled/Y-tiled memory for 3D rendering.
|
||||
self.ctl.write(PLANE_CTL_ENABLE | self.ctl_source_rgb_8888);
|
||||
}
|
||||
|
||||
@@ -169,6 +228,7 @@ pub struct Pipe {
|
||||
pub name: &'static str,
|
||||
pub index: usize,
|
||||
pub planes: Vec<Plane>,
|
||||
pub cursor: Option<CursorPlane>,
|
||||
pub bottom_color: MmioPtr<u32>,
|
||||
pub misc: MmioPtr<u32>,
|
||||
pub srcsz: MmioPtr<u32>,
|
||||
@@ -187,7 +247,16 @@ impl Pipe {
|
||||
let mut pipes = Vec::with_capacity(3);
|
||||
for (i, name) in ["A", "B", "C"].iter().enumerate() {
|
||||
let mut planes = Vec::new();
|
||||
//TODO: cursor plane
|
||||
let cursor = unsafe {
|
||||
Some(CursorPlane {
|
||||
// IHD-OS-KBL-Vol 2c-1.17 CURCNTR
|
||||
cntr: gttmm.mmio(0x70080 + i * 0x1000)?,
|
||||
// IHD-OS-KBL-Vol 2c-1.17 CURBASE
|
||||
base: gttmm.mmio(0x70084 + i * 0x1000)?,
|
||||
// IHD-OS-KBL-Vol 2c-1.17 CURPOS
|
||||
pos: gttmm.mmio(0x70088 + i * 0x1000)?,
|
||||
})
|
||||
};
|
||||
for (j, name) in ["1", "2", "3"].iter().enumerate() {
|
||||
planes.push(Plane {
|
||||
name,
|
||||
@@ -229,6 +298,7 @@ impl Pipe {
|
||||
name,
|
||||
index: i,
|
||||
planes,
|
||||
cursor,
|
||||
// IHD-OS-KBL-Vol 2c-1.17 PIPE_BOTTOM_COLOR
|
||||
bottom_color: unsafe { gttmm.mmio(0x70034 + i * 0x1000)? },
|
||||
// IHD-OS-KBL-Vol 2c-1.17 PIPE_MISC
|
||||
@@ -286,6 +356,7 @@ impl Pipe {
|
||||
name,
|
||||
index: i,
|
||||
planes,
|
||||
cursor: None,
|
||||
// IHD-OS-TGL-Vol 2c-12.21 PIPE_BOTTOM_COLOR
|
||||
bottom_color: unsafe { gttmm.mmio(0x70034 + i * 0x1000)? },
|
||||
// IHD-OS-TGL-Vol 2c-12.21 PIPE_MISC
|
||||
@@ -343,6 +414,7 @@ impl Pipe {
|
||||
name,
|
||||
index: i,
|
||||
planes,
|
||||
cursor: None,
|
||||
// IHD-OS-ACM-Vol 2c-3.23 PIPE_BOTTOM_COLOR
|
||||
bottom_color: unsafe { gttmm.mmio(0x70034 + i * 0x1000)? },
|
||||
// IHD-OS-ACM-Vol 2c-3.23 PIPE_MISC
|
||||
|
||||
@@ -131,13 +131,24 @@ impl GraphicsAdapter for Device {
|
||||
}
|
||||
|
||||
fn hw_cursor_size(&self) -> Option<(u32, u32)> {
|
||||
None
|
||||
// Intel hardware cursor is 64x64 ARGB8888 on all Gen9+ platforms.
|
||||
// The cursor surface is 256 pixels wide (4 bytes per pixel) × 64 rows.
|
||||
Some((64, 64))
|
||||
}
|
||||
|
||||
fn handle_cursor(&mut self, _cursor: &CursorPlane<Self::Buffer>, _dirty_fb: bool) {
|
||||
// Intel GPU hardware cursor planes are not yet implemented.
|
||||
// Software cursor rendering is handled by the console layer.
|
||||
// This is a no-op — not an error condition.
|
||||
fn handle_cursor(&mut self, cursor: &CursorPlane<Self::Buffer>, _dirty_fb: bool) {
|
||||
let Some(pipe) = self.pipes.first_mut() else {
|
||||
return;
|
||||
};
|
||||
let Some(ref mut cursor_plane) = pipe.cursor else {
|
||||
return;
|
||||
};
|
||||
if cursor.buffer.is_some() {
|
||||
cursor_plane.set_enabled(true);
|
||||
cursor_plane.set_position(cursor.x as i16, cursor.y as i16);
|
||||
} else {
|
||||
cursor_plane.set_enabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-5
@@ -184,6 +184,8 @@ pub struct Socket {
|
||||
connection: Option<Connection>,
|
||||
issued_token: Option<u64>,
|
||||
ucred: ucred,
|
||||
sndbuf: i32,
|
||||
rcvbuf: i32,
|
||||
}
|
||||
|
||||
impl Socket {
|
||||
@@ -211,6 +213,8 @@ impl Socket {
|
||||
uid: ctx.uid as _,
|
||||
gid: ctx.gid as _,
|
||||
},
|
||||
sndbuf: 212992, // Linux default
|
||||
rcvbuf: 212992, // Linux default
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,8 +663,14 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
Ok(value_slice.len())
|
||||
}
|
||||
libc::SO_SNDBUF => {
|
||||
// FIXME: implement
|
||||
Ok(0)
|
||||
let value = read_num::<i32>(value_slice)?;
|
||||
socket.sndbuf = value;
|
||||
Ok(value_slice.len())
|
||||
}
|
||||
libc::SO_RCVBUF => {
|
||||
let value = read_num::<i32>(value_slice)?;
|
||||
socket.rcvbuf = value;
|
||||
Ok(value_slice.len())
|
||||
}
|
||||
_ => {
|
||||
eprintln!(
|
||||
@@ -688,6 +698,8 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
payload[..value.len()].copy_from_slice(&value);
|
||||
Ok(value.len())
|
||||
};
|
||||
let socket_rc = self.get_socket(id)?;
|
||||
let socket = socket_rc.borrow();
|
||||
match option {
|
||||
libc::SO_DOMAIN => write_value(&AF_UNIX.to_le_bytes()),
|
||||
libc::SO_PEERCRED => {
|
||||
@@ -701,9 +713,10 @@ impl<'sock> UdsStreamScheme<'sock> {
|
||||
})
|
||||
}
|
||||
libc::SO_SNDBUF => {
|
||||
//TODO: default value on Linux, should we use something else?
|
||||
let value: libc::c_int = 212992;
|
||||
write_value(&value.to_le_bytes())
|
||||
write_value(&socket.sndbuf.to_le_bytes())
|
||||
}
|
||||
libc::SO_RCVBUF => {
|
||||
write_value(&socket.rcvbuf.to_le_bytes())
|
||||
}
|
||||
_ => {
|
||||
eprintln!(
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../redox-scheme
|
||||
Reference in New Issue
Block a user