1#![forbid(unsafe_code)]
23
24use anyhow::Context;
25use chipset_device::ChipsetDevice;
26use guestmem::GuestMemory;
27use guestmem::MappableGuestMemory;
28use guestmem::MemoryMapper;
29use inspect::Inspect;
30use inspect::InspectMut;
31use memory_range::MemoryRange;
32use mesh::MeshPayload;
33use mesh::payload::Protobuf;
34use parking_lot::Mutex;
35use sparse_mmap::Mappable;
36use sparse_mmap::SparseMapping;
37use std::convert::Infallible;
38use std::io;
39use std::sync::Arc;
40use video_core::FramebufferControl;
41use video_core::FramebufferFormat;
42use video_core::ResolvedFramebuffer;
43use video_core::SharedFramebufferHandle;
44use vm_resource::ResolveResource;
45use vm_resource::kind::FramebufferHandleKind;
46use vmcore::device_state::ChangeDeviceState;
47use vmcore::save_restore::RestoreError;
48use vmcore::save_restore::SaveError;
49use vmcore::save_restore::SaveRestore;
50use vmcore::save_restore::SavedStateRoot;
51
52fn default_framebuffer_format() -> FramebufferFormat {
53 FramebufferFormat {
54 width: 1024,
55 height: 768,
56 bytes_per_line: 1024 * 4,
57 offset: 0,
58 }
59}
60
61pub const FRAMEBUFFER_SIZE: usize = 8 * 1024 * 1024; pub fn framebuffer(
78 vram: Mappable,
79 len: usize,
80 offset: u64,
81) -> io::Result<(Framebuffer, FramebufferAccess)> {
82 assert_eq!(
83 len, FRAMEBUFFER_SIZE,
84 "no framebuffer size flexibility for now"
85 );
86
87 let (send, recv) = mesh::channel();
88
89 let fb = Framebuffer {
90 vram: vram.try_clone()?,
91 len,
92 format_send: send,
93 };
94 let access = FramebufferAccess {
95 vram,
96 len,
97 format_recv: recv,
98 offset,
99 };
100 Ok((fb, access))
101}
102
103#[derive(Debug, MeshPayload)]
105pub struct Framebuffer {
106 vram: Mappable,
107 len: usize,
108 format_send: mesh::Sender<FramebufferFormat>,
109}
110
111impl Framebuffer {
112 pub fn len(&self) -> usize {
114 self.len
115 }
116
117 pub fn format_send(self) -> mesh::Sender<FramebufferFormat> {
119 self.format_send
120 }
121}
122
123#[derive(Debug, MeshPayload)]
125pub struct FramebufferAccess {
126 vram: Mappable,
127 len: usize,
128 format_recv: mesh::Receiver<FramebufferFormat>,
129 offset: u64,
130}
131
132impl FramebufferAccess {
133 pub fn view(self) -> io::Result<View> {
135 let mapping = SparseMapping::new(self.len)?;
136 mapping.map_file(0, self.len, &self.vram, self.offset, false)?;
137 Ok(View {
138 mapping,
139 format_recv: self.format_recv,
140 format: None,
141 vram: self.vram,
142 len: self.len,
143 offset: self.offset,
144 })
145 }
146}
147
148#[derive(Debug)]
150pub struct View {
151 mapping: SparseMapping,
152 format_recv: mesh::Receiver<FramebufferFormat>,
153 format: Option<FramebufferFormat>,
154 vram: Mappable,
155 len: usize,
156 offset: u64,
157}
158
159impl View {
160 pub fn read_line(&mut self, line: u16, data: &mut [u8]) {
162 if let Some(format) = &self.format {
163 if let Some(offset) = (line as usize)
164 .checked_mul(format.bytes_per_line)
165 .and_then(|x| x.checked_add(format.offset))
166 {
167 let len = std::cmp::min(data.len(), format.width * 4);
168 let _ = self.mapping.read_at(offset, &mut data[..len]);
169 return;
170 }
171 }
172 data.fill(0);
173 }
174
175 pub fn resolution(&mut self) -> (u16, u16) {
177 while let Ok(format) = self.format_recv.try_recv() {
182 self.format = Some(format);
183 }
184 if let Some(format) = &self.format {
185 (format.width as u16, format.height as u16)
186 } else {
187 (1, 1)
188 }
189 }
190
191 pub fn access(self) -> FramebufferAccess {
193 let (send, recv) = mesh::channel();
195 if let Some(format) = self.format {
196 send.send(format);
197 }
198 send.bridge(self.format_recv);
199 FramebufferAccess {
200 vram: self.vram,
201 len: self.len,
202 format_recv: recv,
203 offset: self.offset,
204 }
205 }
206}
207
208#[derive(InspectMut)]
210pub struct FramebufferDevice {
211 #[inspect(flatten)]
212 inner: Arc<Mutex<FramebufferInner>>,
213 #[inspect(hex)]
214 len: usize,
215}
216
217#[derive(Clone)]
219pub struct FramebufferLocalControl {
220 inner: Arc<Mutex<FramebufferInner>>,
221 len: usize,
222}
223
224#[derive(Inspect)]
225struct FramebufferInner {
226 #[inspect(skip)]
227 _mem_fixed: Option<Box<dyn MappableGuestMemory>>,
228 #[inspect(skip)]
229 framebuffer: Option<Framebuffer>,
230 mapping_state: Option<MappingState>,
231 format: FramebufferFormat,
232 #[inspect(skip)]
233 mapper: Box<dyn MemoryMapper>,
234}
235
236#[derive(Inspect)]
237struct MappingState {
238 gpa: u64,
239 subrange: MemoryRange,
240 #[inspect(skip)]
241 mem: Box<dyn MappableGuestMemory>,
242}
243
244#[derive(Debug, Clone, Protobuf, SavedStateRoot)]
246#[mesh(package = "framebuffer")]
247pub struct SavedState {
248 #[mesh(1)]
249 mapping: Option<SavedMappingState>,
250 #[mesh(2)]
251 format: FramebufferFormat,
252}
253
254#[derive(Debug, Clone, Protobuf)]
255#[mesh(package = "framebuffer")]
256struct SavedMappingState {
257 #[mesh(1)]
258 gpa: u64,
259 #[mesh(2)]
260 subrange: MemoryRange,
261}
262
263impl FramebufferDevice {
264 pub fn new(
268 mapper: Box<dyn MemoryMapper>,
269 framebuffer: Framebuffer,
270 framebuffer_gpa_base_fixed: Option<u64>,
271 ) -> anyhow::Result<Self> {
272 let len = framebuffer.len;
273
274 let mem_fixed = if let Some(gpa) = framebuffer_gpa_base_fixed {
278 let (mut mem, region) = mapper
279 .new_region(len, "framebuffer-vtl2".to_owned())
280 .context("failed to create vtl2 framebuffer memory region")?;
281
282 region
283 .map(0, &framebuffer.vram, 0, len, true)
284 .context("failed to map vtl2 framebuffer memory region")?;
285
286 mem.map_to_guest(gpa, true)?;
287 Some(mem)
288 } else {
289 None
290 };
291
292 let format = default_framebuffer_format();
294 framebuffer.format_send.send(format);
295
296 Ok(Self {
297 inner: Arc::new(Mutex::new(FramebufferInner {
298 _mem_fixed: mem_fixed,
299 mapping_state: None,
300 format,
301 framebuffer: Some(framebuffer),
302 mapper,
303 })),
304 len,
305 })
306 }
307
308 pub fn into_framebuffer(self) -> Framebuffer {
310 self.inner.lock().framebuffer.take().unwrap()
311 }
312
313 pub fn control(&self) -> FramebufferLocalControl {
315 FramebufferLocalControl {
316 inner: self.inner.clone(),
317 len: self.len,
318 }
319 }
320}
321
322impl ChangeDeviceState for FramebufferDevice {
323 fn start(&mut self) {}
324
325 async fn stop(&mut self) {}
326
327 async fn reset(&mut self) {
328 let mut inner = self.inner.lock();
329 inner.mapping_state = Default::default();
330 if let Some(mut state) = inner.mapping_state.take() {
331 state.mem.unmap_from_guest();
332 }
333
334 }
336}
337
338impl ChipsetDevice for FramebufferDevice {}
339
340impl SaveRestore for FramebufferDevice {
341 type SavedState = SavedState;
342
343 fn save(&mut self) -> Result<Self::SavedState, SaveError> {
344 let inner = self.inner.lock();
345 let mapping = inner.mapping_state.as_ref().map(
346 |MappingState {
347 gpa,
348 subrange,
349 mem: _,
350 }| SavedMappingState {
351 gpa: *gpa,
352 subrange: *subrange,
353 },
354 );
355 Ok(SavedState {
356 format: inner.format,
357 mapping,
358 })
359 }
360
361 fn restore(&mut self, state: Self::SavedState) -> Result<(), RestoreError> {
362 let SavedState { mapping, format } = state;
363 let mut inner = self.inner.lock();
364 let inner = &mut *inner;
365 inner.format = format;
366 if let Some(mapping) = mapping {
367 inner
368 .map(mapping.gpa, Some(mapping.subrange))
369 .context("failed to map VRAM to guest")
370 .map_err(RestoreError::Other)?;
371 }
372
373 inner
374 .framebuffer
375 .as_mut()
376 .unwrap()
377 .format_send
378 .send(inner.format);
379 Ok(())
380 }
381}
382
383impl FramebufferInner {
384 fn map(&mut self, gpa: u64, framebuffer_range: Option<MemoryRange>) -> anyhow::Result<()> {
385 if let Some(mut state) = self.mapping_state.take() {
386 state.mem.unmap_from_guest();
387 }
388
389 let Some(framebuffer) = &self.framebuffer else {
390 return Ok(());
391 };
392
393 let framebuffer_range =
394 framebuffer_range.unwrap_or_else(|| MemoryRange::new(0..framebuffer.len as u64));
395
396 let (mut mem, region) = self
397 .mapper
398 .new_region(framebuffer_range.len() as usize, "framebuffer".to_owned())
399 .context("failed to create framebuffer region")?;
400
401 region
402 .map(
403 0,
404 &framebuffer.vram,
405 framebuffer_range.start(),
406 framebuffer_range.len() as usize,
407 true,
408 )
409 .context("failed to map framebuffer memory")?;
410
411 mem.map_to_guest(gpa, true)
412 .context("failed to map VRAM to guest")?;
413 self.mapping_state = Some(MappingState {
414 gpa,
415 subrange: framebuffer_range,
416 mem,
417 });
418
419 tracing::debug!("Mapped VRAM to guest at address {:#x}", gpa);
420
421 Ok(())
422 }
423}
424
425impl FramebufferLocalControl {
426 pub fn map(&mut self, gpa: u64, framebuffer_range: Option<MemoryRange>) {
430 if let Err(err) = self.inner.lock().map(gpa, framebuffer_range) {
431 tracing::error!(
432 gpa,
433 error = err.as_ref() as &dyn std::error::Error,
434 "failed to map framebuffer to guest"
435 );
436 }
437 }
438
439 pub fn unmap(&mut self) {
441 let mut inner = self.inner.lock();
442 if let Some(mut state) = inner.mapping_state.take() {
443 state.mem.unmap_from_guest();
444 }
445 }
446
447 pub fn len(&self) -> usize {
449 self.len
450 }
451
452 pub fn set_format(&mut self, format: FramebufferFormat) {
454 let mut inner = self.inner.lock();
455 let inner = &mut *inner;
456
457 if inner.format != format {
458 inner.format = format;
459 if let Some(framebuffer) = &mut inner.framebuffer {
460 framebuffer.format_send.send(inner.format);
461 }
462 }
463 }
464
465 pub fn memory(&self) -> io::Result<GuestMemory> {
468 let inner = self.inner.lock();
469 let framebuffer = inner
470 .framebuffer
471 .as_ref()
472 .expect("framebuffer is still active");
473 let mapping = SparseMapping::new(framebuffer.len())?;
474 mapping.map_file(0, framebuffer.len(), &framebuffer.vram, 0, true)?;
475 Ok(GuestMemory::new("framebuffer", mapping))
476 }
477}
478
479#[async_trait::async_trait]
482impl FramebufferControl for FramebufferLocalControl {
483 async fn map(&mut self, gpa: u64) {
484 self.map(gpa, None);
485 }
486 async fn unmap(&mut self) {
487 self.unmap();
488 }
489 async fn set_format(&mut self, format: FramebufferFormat) {
490 self.set_format(format);
491 }
492}
493
494impl ResolveResource<FramebufferHandleKind, SharedFramebufferHandle> for FramebufferLocalControl {
495 type Output = ResolvedFramebuffer;
496 type Error = Infallible;
497
498 fn resolve(
499 &self,
500 _resource: SharedFramebufferHandle,
501 _input: (),
502 ) -> Result<Self::Output, Self::Error> {
503 Ok(self.clone().into())
504 }
505}