1 // Copyright 2018 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 use std::collections::VecDeque;
6 use std::convert::TryInto;
7 use std::sync::atomic::{AtomicBool, Ordering};
8 use std::sync::Arc;
9 use std::thread;
10 use std::time::{Duration, Instant};
11
12 use audio_streams::{
13 shm_streams::{ShmStream, ShmStreamSource},
14 BoxError, NoopStreamControl, SampleFormat, StreamControl, StreamDirection, StreamEffect,
15 };
16 use base::{
17 self, error, set_rt_prio_limit, set_rt_round_robin, warn, AsRawDescriptor, AsRawDescriptors,
18 FromRawDescriptor, RawDescriptor, SharedMemoryUnix,
19 };
20 use remain::sorted;
21 use sync::{Condvar, Mutex};
22 use thiserror::Error;
23 use vm_memory::{GuestAddress, GuestMemory};
24
25 use crate::pci::ac97_mixer::Ac97Mixer;
26 use crate::pci::ac97_regs::*;
27 use crate::IrqLevelEvent;
28
29 const INPUT_SAMPLE_RATE: u32 = 48000;
30 const DEVICE_INPUT_CHANNEL_COUNT: usize = 2;
31
32 // Bus Master registers. Keeps the state of the bus master register values. Used to share the state
33 // between the main and audio threads.
34 struct Ac97BusMasterRegs {
35 pi_regs: Ac97FunctionRegs, // Input
36 po_regs: Ac97FunctionRegs, // Output
37 po_pointer_update_time: Instant, // Time the picb and civ regs were last updated.
38 mc_regs: Ac97FunctionRegs, // Microphone
39 glob_cnt: u32,
40 glob_sta: u32,
41
42 // IRQ event - driven by the glob_sta register.
43 irq_evt: Option<IrqLevelEvent>,
44 }
45
46 impl Ac97BusMasterRegs {
new() -> Ac97BusMasterRegs47 fn new() -> Ac97BusMasterRegs {
48 Ac97BusMasterRegs {
49 pi_regs: Ac97FunctionRegs::new(),
50 po_regs: Ac97FunctionRegs::new(),
51 po_pointer_update_time: Instant::now(),
52 mc_regs: Ac97FunctionRegs::new(),
53 glob_cnt: 0,
54 glob_sta: GLOB_STA_RESET_VAL,
55 irq_evt: None,
56 }
57 }
58
func_regs(&self, func: Ac97Function) -> &Ac97FunctionRegs59 fn func_regs(&self, func: Ac97Function) -> &Ac97FunctionRegs {
60 match func {
61 Ac97Function::Input => &self.pi_regs,
62 Ac97Function::Output => &self.po_regs,
63 Ac97Function::Microphone => &self.mc_regs,
64 }
65 }
66
func_regs_mut(&mut self, func: Ac97Function) -> &mut Ac97FunctionRegs67 fn func_regs_mut(&mut self, func: Ac97Function) -> &mut Ac97FunctionRegs {
68 match func {
69 Ac97Function::Input => &mut self.pi_regs,
70 Ac97Function::Output => &mut self.po_regs,
71 Ac97Function::Microphone => &mut self.mc_regs,
72 }
73 }
74
tube_count(&self, func: Ac97Function) -> usize75 fn tube_count(&self, func: Ac97Function) -> usize {
76 fn output_tube_count(glob_cnt: u32) -> usize {
77 let val = (glob_cnt & GLOB_CNT_PCM_246_MASK) >> 20;
78 match val {
79 0 => 2,
80 1 => 4,
81 2 => 6,
82 _ => {
83 warn!("unknown tube_count: 0x{:x}", val);
84 2
85 }
86 }
87 }
88
89 match func {
90 Ac97Function::Output => output_tube_count(self.glob_cnt),
91 _ => DEVICE_INPUT_CHANNEL_COUNT,
92 }
93 }
94
95 /// Returns whether the irq is set for any one of the bus master function registers.
has_irq(&self) -> bool96 pub fn has_irq(&self) -> bool {
97 self.pi_regs.has_irq() || self.po_regs.has_irq() || self.mc_regs.has_irq()
98 }
99 }
100
101 // Internal error type used for reporting errors from guest memory reading.
102 #[sorted]
103 #[derive(Error, Debug)]
104 enum GuestMemoryError {
105 // Failure getting the address of the audio buffer.
106 #[error("Failed to get the address of the audio buffer: {0}.")]
107 ReadingGuestBufferAddress(vm_memory::GuestMemoryError),
108 }
109
110 impl From<GuestMemoryError> for AudioError {
from(err: GuestMemoryError) -> Self111 fn from(err: GuestMemoryError) -> Self {
112 AudioError::ReadingGuestError(err)
113 }
114 }
115
116 type GuestMemoryResult<T> = std::result::Result<T, GuestMemoryError>;
117
118 // Internal error type used for reporting errors from the audio thread.
119 #[sorted]
120 #[derive(Error, Debug)]
121 enum AudioError {
122 // Failed to clone a descriptor.
123 #[error("Failed to clone a descriptor: {0}")]
124 CloneDescriptor(base::Error),
125 // Failed to create a shared memory.
126 #[error("Failed to create a shared memory: {0}.")]
127 CreateSharedMemory(base::Error),
128 // Failed to create a new stream.
129 #[error("Failed to create audio stream: {0}.")]
130 CreateStream(BoxError),
131 // Failure to get regions from guest memory.
132 #[error("Failed to get guest memory region: {0}.")]
133 GuestRegion(GuestMemoryError),
134 // Invalid buffer offset received from the audio server.
135 #[error("Offset > max usize")]
136 InvalidBufferOffset,
137 // Guest did not provide a buffer when needed.
138 #[error("No buffer was available from the Guest")]
139 NoBufferAvailable,
140 // Failure to read guest memory.
141 #[error("Failed to read guest memory: {0}.")]
142 ReadingGuestError(GuestMemoryError),
143 // Failure to respond to the ServerRequest.
144 #[error("Failed to respond to the ServerRequest: {0}")]
145 RespondRequest(BoxError),
146 // Failure to wait for a request from the stream.
147 #[error("Failed to wait for a message from the stream: {0}")]
148 WaitForAction(BoxError),
149 }
150
151 type AudioResult<T> = std::result::Result<T, AudioError>;
152
153 // Audio thread book-keeping data
154 struct AudioThreadInfo {
155 thread: Option<thread::JoinHandle<()>>,
156 thread_run: Arc<AtomicBool>,
157 thread_semaphore: Arc<Condvar>,
158 stream_control: Option<Box<dyn StreamControl>>,
159 }
160
161 impl AudioThreadInfo {
new() -> Self162 fn new() -> Self {
163 Self {
164 thread: None,
165 thread_run: Arc::new(AtomicBool::new(false)),
166 thread_semaphore: Arc::new(Condvar::new()),
167 stream_control: None,
168 }
169 }
170
is_running(&self) -> bool171 fn is_running(&self) -> bool {
172 self.thread_run.load(Ordering::Relaxed)
173 }
174
start(&mut self, mut worker: AudioWorker)175 fn start(&mut self, mut worker: AudioWorker) {
176 const AUDIO_THREAD_RTPRIO: u16 = 10; // Matches other cros audio clients.
177 self.thread_run.store(true, Ordering::Relaxed);
178 self.thread = Some(thread::spawn(move || {
179 if let Err(e) = set_rt_prio_limit(u64::from(AUDIO_THREAD_RTPRIO))
180 .and_then(|_| set_rt_round_robin(i32::from(AUDIO_THREAD_RTPRIO)))
181 {
182 warn!("Failed to set audio thread to real time: {}", e);
183 }
184
185 if let Err(e) = worker.run() {
186 error!("{:?} error: {}", worker.func, e);
187 }
188
189 worker.thread_run.store(false, Ordering::Relaxed);
190 }));
191
192 self.stream_control = Some(Box::new(NoopStreamControl::new()));
193 }
194
stop(&mut self)195 fn stop(&mut self) {
196 self.thread_run.store(false, Ordering::Relaxed);
197 self.thread_semaphore.notify_one();
198 if let Some(thread) = self.thread.take() {
199 if let Err(e) = thread.join() {
200 error!("Failed to join thread: {:?}.", e);
201 }
202 }
203 }
204 }
205
206 /// `Ac97BusMaster` emulates the bus master portion of AC97. It exposes a register read/write
207 /// interface compliant with the ICH bus master.
208 pub struct Ac97BusMaster {
209 // Keep guest memory as each function will use it for buffer descriptors.
210 mem: GuestMemory,
211 regs: Arc<Mutex<Ac97BusMasterRegs>>,
212 acc_sema: u8,
213
214 // Bookkeeping info for playback and capture stream.
215 po_info: AudioThreadInfo,
216 pi_info: AudioThreadInfo,
217 pmic_info: AudioThreadInfo,
218
219 // Audio server used to create playback or capture streams.
220 audio_server: Box<dyn ShmStreamSource<base::Error>>,
221
222 // Thread for hadlind IRQ resample events from the guest.
223 irq_resample_thread: Option<thread::JoinHandle<()>>,
224 }
225
226 impl Ac97BusMaster {
227 /// Creates an Ac97BusMaster` object that plays audio from `mem` to streams provided by
228 /// `audio_server`.
new(mem: GuestMemory, audio_server: Box<dyn ShmStreamSource<base::Error>>) -> Self229 pub fn new(mem: GuestMemory, audio_server: Box<dyn ShmStreamSource<base::Error>>) -> Self {
230 Ac97BusMaster {
231 mem,
232 regs: Arc::new(Mutex::new(Ac97BusMasterRegs::new())),
233 acc_sema: 0,
234
235 po_info: AudioThreadInfo::new(),
236 pi_info: AudioThreadInfo::new(),
237 pmic_info: AudioThreadInfo::new(),
238 audio_server,
239
240 irq_resample_thread: None,
241 }
242 }
243
244 /// Returns any file descriptors that need to be kept open when entering a jail.
keep_rds(&self) -> Option<Vec<RawDescriptor>>245 pub fn keep_rds(&self) -> Option<Vec<RawDescriptor>> {
246 let mut rds = self.audio_server.keep_fds();
247 rds.append(&mut self.mem.as_raw_descriptors());
248 Some(rds)
249 }
250
251 /// Provides the events needed to raise interrupts in the guest.
set_irq_event(&mut self, irq_evt: IrqLevelEvent)252 pub fn set_irq_event(&mut self, irq_evt: IrqLevelEvent) {
253 let thread_regs = self.regs.clone();
254 self.regs.lock().irq_evt = Some(irq_evt.try_clone().expect("cloning irq_evt failed"));
255 self.irq_resample_thread = Some(thread::spawn(move || {
256 loop {
257 if let Err(e) = irq_evt.get_resample().read() {
258 error!(
259 "Failed to read the irq event from the resample thread: {}.",
260 e,
261 );
262 break;
263 }
264 {
265 // Scope for the lock on thread_regs.
266 let regs = thread_regs.lock();
267 if regs.has_irq() {
268 if let Err(e) = irq_evt.trigger() {
269 error!("Failed to set the irq from the resample thread: {}.", e);
270 break;
271 }
272 }
273 }
274 }
275 }));
276 }
277
278 /// Called when `mixer` has been changed and the new values should be applied to currently
279 /// active streams.
update_mixer_settings(&mut self, mixer: &Ac97Mixer)280 pub fn update_mixer_settings(&mut self, mixer: &Ac97Mixer) {
281 if let Some(control) = self.po_info.stream_control.as_mut() {
282 // The audio server only supports one volume, not separate left and right.
283 let (muted, left_volume, _right_volume) = mixer.get_master_volume();
284 control.set_volume(left_volume);
285 control.set_mute(muted);
286 }
287 }
288
289 /// Checks if the bus master is in the cold reset state.
is_cold_reset(&self) -> bool290 pub fn is_cold_reset(&self) -> bool {
291 self.regs.lock().glob_cnt & GLOB_CNT_COLD_RESET == 0
292 }
293
294 /// Reads a byte from the given `offset`.
readb(&mut self, offset: u64) -> u8295 pub fn readb(&mut self, offset: u64) -> u8 {
296 fn readb_func_regs(func_regs: &Ac97FunctionRegs, offset: u64) -> u8 {
297 match offset {
298 CIV_OFFSET => func_regs.civ,
299 LVI_OFFSET => func_regs.lvi,
300 SR_OFFSET => func_regs.sr as u8,
301 PIV_OFFSET => func_regs.piv,
302 CR_OFFSET => func_regs.cr,
303 _ => 0,
304 }
305 }
306
307 let regs = self.regs.lock();
308 match offset {
309 PI_BASE_00..=PI_CR_0B => readb_func_regs(®s.pi_regs, offset - PI_BASE_00),
310 PO_BASE_10..=PO_CR_1B => readb_func_regs(®s.po_regs, offset - PO_BASE_10),
311 MC_BASE_20..=MC_CR_2B => readb_func_regs(®s.mc_regs, offset - MC_BASE_20),
312 ACC_SEMA_34 => self.acc_sema,
313 _ => 0,
314 }
315 }
316
317 /// Reads a word from the given `offset`.
readw(&mut self, offset: u64, mixer: &Ac97Mixer) -> u16318 pub fn readw(&mut self, offset: u64, mixer: &Ac97Mixer) -> u16 {
319 let regs = self.regs.lock();
320 match offset {
321 PI_SR_06 => regs.pi_regs.sr,
322 PI_PICB_08 => regs.pi_regs.picb,
323 PO_SR_16 => regs.po_regs.sr,
324 PO_PICB_18 => {
325 // PO PICB
326 if !self.thread_info(Ac97Function::Output).is_running() {
327 // Not running, no need to estimate what has been consumed.
328 regs.po_regs.picb
329 } else {
330 // Estimate how many samples have been played since the last audio callback.
331 let num_channels = regs.tube_count(Ac97Function::Output) as u64;
332 let micros = regs.po_pointer_update_time.elapsed().subsec_micros();
333 // Round down to the next 10 millisecond boundary. The linux driver often
334 // assumes that two rapid reads from picb will return the same value.
335 let millis = micros / 1000 / 10 * 10;
336 let sample_rate = self.current_sample_rate(Ac97Function::Output, mixer);
337 let frames_consumed = sample_rate as u64 * u64::from(millis) / 1000;
338
339 regs.po_regs
340 .picb
341 .saturating_sub((num_channels * frames_consumed) as u16)
342 }
343 }
344 MC_SR_26 => regs.mc_regs.sr,
345 MC_PICB_28 => regs.mc_regs.picb,
346 _ => 0,
347 }
348 }
349
350 /// Reads a 32-bit word from the given `offset`.
readl(&mut self, offset: u64) -> u32351 pub fn readl(&mut self, offset: u64) -> u32 {
352 let regs = self.regs.lock();
353 match offset {
354 PI_BDBAR_00 => regs.pi_regs.bdbar,
355 PI_CIV_04 => regs.pi_regs.atomic_status_regs(),
356 PO_BDBAR_10 => regs.po_regs.bdbar,
357 PO_CIV_14 => regs.po_regs.atomic_status_regs(),
358 MC_BDBAR_20 => regs.mc_regs.bdbar,
359 MC_CIV_24 => regs.mc_regs.atomic_status_regs(),
360 GLOB_CNT_2C => regs.glob_cnt,
361 GLOB_STA_30 => regs.glob_sta,
362 _ => 0,
363 }
364 }
365
366 /// Writes the byte `val` to the register specified by `offset`.
writeb(&mut self, offset: u64, val: u8, mixer: &Ac97Mixer)367 pub fn writeb(&mut self, offset: u64, val: u8, mixer: &Ac97Mixer) {
368 // Only process writes to the control register when cold reset is set.
369 if self.is_cold_reset() {
370 return;
371 }
372
373 match offset {
374 PI_CIV_04 => (), // RO
375 PI_LVI_05 => self.set_lvi(Ac97Function::Input, val),
376 PI_SR_06 => self.set_sr(Ac97Function::Input, u16::from(val)),
377 PI_PIV_0A => (), // RO
378 PI_CR_0B => self.set_cr(Ac97Function::Input, val, mixer),
379 PO_CIV_14 => (), // RO
380 PO_LVI_15 => self.set_lvi(Ac97Function::Output, val),
381 PO_SR_16 => self.set_sr(Ac97Function::Output, u16::from(val)),
382 PO_PIV_1A => (), // RO
383 PO_CR_1B => self.set_cr(Ac97Function::Output, val, mixer),
384 MC_CIV_24 => (), // RO
385 MC_LVI_25 => self.set_lvi(Ac97Function::Microphone, val),
386 MC_SR_26 => self.set_sr(Ac97Function::Microphone, u16::from(val)),
387 MC_PIV_2A => (), // RO
388 MC_CR_2B => self.set_cr(Ac97Function::Microphone, val, mixer),
389 ACC_SEMA_34 => self.acc_sema = val,
390 o => warn!("write byte to 0x{:x}", o),
391 }
392 }
393
394 /// Writes the word `val` to the register specified by `offset`.
writew(&mut self, offset: u64, val: u16)395 pub fn writew(&mut self, offset: u64, val: u16) {
396 // Only process writes to the control register when cold reset is set.
397 if self.is_cold_reset() {
398 return;
399 }
400 match offset {
401 PI_SR_06 => self.set_sr(Ac97Function::Input, val),
402 PI_PICB_08 => (), // RO
403 PO_SR_16 => self.set_sr(Ac97Function::Output, val),
404 PO_PICB_18 => (), // RO
405 MC_SR_26 => self.set_sr(Ac97Function::Microphone, val),
406 MC_PICB_28 => (), // RO
407 o => warn!("write word to 0x{:x}", o),
408 }
409 }
410
411 /// Writes the 32-bit `val` to the register specified by `offset`.
writel(&mut self, offset: u64, val: u32, mixer: &mut Ac97Mixer)412 pub fn writel(&mut self, offset: u64, val: u32, mixer: &mut Ac97Mixer) {
413 // Only process writes to the control register when cold reset is set.
414 if self.is_cold_reset() && offset != 0x2c {
415 return;
416 }
417 match offset {
418 PI_BDBAR_00 => self.set_bdbar(Ac97Function::Input, val),
419 PO_BDBAR_10 => self.set_bdbar(Ac97Function::Output, val),
420 MC_BDBAR_20 => self.set_bdbar(Ac97Function::Microphone, val),
421 GLOB_CNT_2C => self.set_glob_cnt(val, mixer),
422 GLOB_STA_30 => (), // RO
423 o => warn!("write long to 0x{:x}", o),
424 }
425 }
426
set_bdbar(&mut self, func: Ac97Function, val: u32)427 fn set_bdbar(&mut self, func: Ac97Function, val: u32) {
428 self.regs.lock().func_regs_mut(func).bdbar = val & !0x07;
429 }
430
set_lvi(&mut self, func: Ac97Function, val: u8)431 fn set_lvi(&mut self, func: Ac97Function, val: u8) {
432 let mut regs = self.regs.lock();
433 let func_regs = regs.func_regs_mut(func);
434 func_regs.lvi = val % 32; // LVI wraps at 32.
435
436 // If running and stalled waiting for more valid buffers, restart by clearing the "DMA
437 // stopped" bit.
438 if func_regs.cr & CR_RPBM == CR_RPBM
439 && func_regs.sr & SR_DCH == SR_DCH
440 && func_regs.civ != func_regs.lvi
441 {
442 if func_regs.sr & SR_CELV != 0 {
443 // CELV means we'd already processed the buffer at CIV.
444 // Move CIV to the next buffer now that LVI has moved.
445 func_regs.move_to_next_buffer();
446 }
447 func_regs.sr &= !(SR_DCH | SR_CELV);
448
449 match func {
450 Ac97Function::Input => self.pi_info.thread_semaphore.notify_one(),
451 Ac97Function::Output => self.po_info.thread_semaphore.notify_one(),
452 Ac97Function::Microphone => self.pmic_info.thread_semaphore.notify_one(),
453 }
454 }
455 }
456
set_sr(&mut self, func: Ac97Function, val: u16)457 fn set_sr(&mut self, func: Ac97Function, val: u16) {
458 let mut sr = self.regs.lock().func_regs(func).sr;
459 if val & SR_FIFOE != 0 {
460 sr &= !SR_FIFOE;
461 }
462 if val & SR_LVBCI != 0 {
463 sr &= !SR_LVBCI;
464 }
465 if val & SR_BCIS != 0 {
466 sr &= !SR_BCIS;
467 }
468 update_sr(&mut self.regs.lock(), func, sr);
469 }
470
set_cr(&mut self, func: Ac97Function, val: u8, mixer: &Ac97Mixer)471 fn set_cr(&mut self, func: Ac97Function, val: u8, mixer: &Ac97Mixer) {
472 if val & CR_RR != 0 {
473 let mut regs = self.regs.lock();
474 Self::reset_func_regs(&mut regs, func);
475 } else {
476 let cr = self.regs.lock().func_regs(func).cr;
477 if val & CR_RPBM == 0 {
478 // Run/Pause set to pause.
479 self.thread_info_mut(func).stop();
480 let mut regs = self.regs.lock();
481 regs.func_regs_mut(func).sr |= SR_DCH;
482 } else if cr & CR_RPBM == 0 {
483 // Not already running.
484 // Run/Pause set to run.
485 {
486 let mut regs = self.regs.lock();
487 let func_regs = regs.func_regs_mut(func);
488 func_regs.piv = 1;
489 func_regs.civ = 0;
490 func_regs.sr &= !SR_DCH;
491 }
492 if let Err(e) = self.start_audio(func, mixer) {
493 warn!("Failed to start audio: {}", e);
494 }
495 }
496 let mut regs = self.regs.lock();
497 regs.func_regs_mut(func).cr = val & CR_VALID_MASK;
498 }
499 }
500
set_glob_cnt(&mut self, new_glob_cnt: u32, mixer: &mut Ac97Mixer)501 fn set_glob_cnt(&mut self, new_glob_cnt: u32, mixer: &mut Ac97Mixer) {
502 // Only the reset bits are emulated, the GPI and PCM formatting are not supported.
503 if new_glob_cnt & GLOB_CNT_COLD_RESET == 0 {
504 self.reset_audio_regs();
505 mixer.reset();
506 let mut regs = self.regs.lock();
507 regs.glob_cnt = new_glob_cnt & GLOB_CNT_STABLE_BITS;
508 self.acc_sema = 0;
509 return;
510 }
511 if new_glob_cnt & GLOB_CNT_WARM_RESET != 0 {
512 // Check if running and if so, ignore. Warm reset is specified to no-op when the device
513 // is playing or recording audio.
514 if !self.is_audio_running() {
515 self.stop_all_audio();
516 let mut regs = self.regs.lock();
517 regs.glob_cnt = new_glob_cnt & !GLOB_CNT_WARM_RESET; // Auto-cleared reset bit.
518 return;
519 }
520 }
521 self.regs.lock().glob_cnt = new_glob_cnt;
522 }
523
stream_effects(func: Ac97Function) -> Vec<StreamEffect>524 fn stream_effects(func: Ac97Function) -> Vec<StreamEffect> {
525 match func {
526 Ac97Function::Microphone => vec![StreamEffect::EchoCancellation],
527 _ => vec![StreamEffect::NoEffect],
528 }
529 }
530
current_sample_rate(&self, func: Ac97Function, mixer: &Ac97Mixer) -> u32531 fn current_sample_rate(&self, func: Ac97Function, mixer: &Ac97Mixer) -> u32 {
532 match func {
533 Ac97Function::Output => mixer.get_sample_rate().into(),
534 _ => INPUT_SAMPLE_RATE,
535 }
536 }
537
create_audio_worker( &mut self, mixer: &Ac97Mixer, func: Ac97Function, ) -> AudioResult<AudioWorker>538 fn create_audio_worker(
539 &mut self,
540 mixer: &Ac97Mixer,
541 func: Ac97Function,
542 ) -> AudioResult<AudioWorker> {
543 let direction = match func {
544 Ac97Function::Microphone => StreamDirection::Capture,
545 Ac97Function::Input => StreamDirection::Capture,
546 Ac97Function::Output => StreamDirection::Playback,
547 };
548
549 let locked_regs = self.regs.lock();
550 let sample_rate = self.current_sample_rate(func, mixer);
551 let buffer_samples = current_buffer_size(locked_regs.func_regs(func), &self.mem)?;
552 let num_channels = locked_regs.tube_count(func);
553 let buffer_frames = buffer_samples / num_channels;
554
555 let mut pending_buffers = VecDeque::with_capacity(2);
556 let starting_offsets = match direction {
557 StreamDirection::Capture => {
558 let mut offsets = [0, 0];
559 for offset in &mut offsets {
560 let buffer = next_guest_buffer(&locked_regs, &self.mem, func, 0)?
561 .ok_or(AudioError::NoBufferAvailable)?;
562 *offset = buffer.offset as u64;
563 pending_buffers.push_back(Some(buffer));
564 }
565 offsets
566 }
567 StreamDirection::Playback => [0, 0],
568 };
569
570 // Create a `base::SharedMemory` object from a descriptor backing `self.mem`.
571 // This creation is expected to succeed because we can assume that `self.mem` was created
572 // from a `SharedMemory` object and its type was generalized to `dyn AsRawDescriptor`.
573 let desc: &dyn AsRawDescriptor = self
574 .mem
575 .offset_region(starting_offsets[0])
576 .map_err(|e| AudioError::GuestRegion(GuestMemoryError::ReadingGuestBufferAddress(e)))?;
577 let shm = {
578 let rd = base::clone_descriptor(desc).map_err(AudioError::CloneDescriptor)?;
579 // Safe because the fd is owned.
580 let sd = unsafe { base::SafeDescriptor::from_raw_descriptor(rd) };
581 base::SharedMemory::from_safe_descriptor(sd).map_err(AudioError::CreateSharedMemory)?
582 };
583
584 let stream = self
585 .audio_server
586 .new_stream(
587 direction,
588 num_channels,
589 SampleFormat::S16LE,
590 sample_rate,
591 buffer_frames,
592 &Self::stream_effects(func),
593 &shm,
594 starting_offsets,
595 )
596 .map_err(AudioError::CreateStream)?;
597
598 let params = AudioWorkerParams {
599 func,
600 stream,
601 pending_buffers,
602 message_interval: Duration::from_secs_f64(buffer_frames as f64 / sample_rate as f64),
603 };
604 Ok(AudioWorker::new(self, params))
605 }
606
thread_info(&self, func: Ac97Function) -> &AudioThreadInfo607 fn thread_info(&self, func: Ac97Function) -> &AudioThreadInfo {
608 match func {
609 Ac97Function::Microphone => &self.pmic_info,
610 Ac97Function::Input => &self.pi_info,
611 Ac97Function::Output => &self.po_info,
612 }
613 }
614
thread_info_mut(&mut self, func: Ac97Function) -> &mut AudioThreadInfo615 fn thread_info_mut(&mut self, func: Ac97Function) -> &mut AudioThreadInfo {
616 match func {
617 Ac97Function::Microphone => &mut self.pmic_info,
618 Ac97Function::Input => &mut self.pi_info,
619 Ac97Function::Output => &mut self.po_info,
620 }
621 }
622
is_audio_running(&self) -> bool623 fn is_audio_running(&self) -> bool {
624 self.thread_info(Ac97Function::Output).is_running()
625 || self.thread_info(Ac97Function::Input).is_running()
626 || self.thread_info(Ac97Function::Microphone).is_running()
627 }
628
start_audio(&mut self, func: Ac97Function, mixer: &Ac97Mixer) -> AudioResult<()>629 fn start_audio(&mut self, func: Ac97Function, mixer: &Ac97Mixer) -> AudioResult<()> {
630 let audio_worker = self.create_audio_worker(mixer, func)?;
631 self.thread_info_mut(func).start(audio_worker);
632 self.update_mixer_settings(mixer);
633 Ok(())
634 }
635
stop_all_audio(&mut self)636 fn stop_all_audio(&mut self) {
637 self.thread_info_mut(Ac97Function::Input).stop();
638 self.thread_info_mut(Ac97Function::Output).stop();
639 self.thread_info_mut(Ac97Function::Microphone).stop();
640 }
641
642 // Helper function for resetting function registers.
reset_func_regs(regs: &mut Ac97BusMasterRegs, func: Ac97Function)643 fn reset_func_regs(regs: &mut Ac97BusMasterRegs, func: Ac97Function) {
644 regs.func_regs_mut(func).do_reset();
645 update_sr(regs, func, SR_DCH);
646 }
647
reset_audio_regs(&mut self)648 fn reset_audio_regs(&mut self) {
649 self.stop_all_audio();
650 let mut regs = self.regs.lock();
651 Self::reset_func_regs(&mut regs, Ac97Function::Input);
652 Self::reset_func_regs(&mut regs, Ac97Function::Output);
653 Self::reset_func_regs(&mut regs, Ac97Function::Microphone);
654 }
655 }
656
657 #[derive(Debug)]
658 struct GuestBuffer {
659 offset: usize,
660 frames: usize,
661 }
662
get_buffer_offset( func_regs: &Ac97FunctionRegs, mem: &GuestMemory, index: u8, ) -> GuestMemoryResult<u64>663 fn get_buffer_offset(
664 func_regs: &Ac97FunctionRegs,
665 mem: &GuestMemory,
666 index: u8,
667 ) -> GuestMemoryResult<u64> {
668 let descriptor_addr = func_regs.bdbar + u32::from(index) * DESCRIPTOR_LENGTH as u32;
669 let buffer_addr_reg: u32 = mem
670 .read_obj_from_addr(GuestAddress(u64::from(descriptor_addr)))
671 .map_err(GuestMemoryError::ReadingGuestBufferAddress)?;
672 let buffer_addr = GuestAddress((buffer_addr_reg & !0x03u32) as u64); // The address must be aligned to four bytes.
673
674 mem.offset_from_base(buffer_addr)
675 .map_err(GuestMemoryError::ReadingGuestBufferAddress)
676 }
677
get_buffer_samples( func_regs: &Ac97FunctionRegs, mem: &GuestMemory, index: u8, ) -> GuestMemoryResult<usize>678 fn get_buffer_samples(
679 func_regs: &Ac97FunctionRegs,
680 mem: &GuestMemory,
681 index: u8,
682 ) -> GuestMemoryResult<usize> {
683 let descriptor_addr = func_regs.bdbar + u32::from(index) * DESCRIPTOR_LENGTH as u32;
684 let control_reg: u32 = mem
685 .read_obj_from_addr(GuestAddress(u64::from(descriptor_addr) + 4))
686 .map_err(GuestMemoryError::ReadingGuestBufferAddress)?;
687 let buffer_samples = control_reg as usize & 0x0000_ffff;
688 Ok(buffer_samples)
689 }
690
691 // Gets the start address and length of the buffer at `civ + offset` from the
692 // guest.
693 // This will return `None` if `civ + offset` is past LVI; if the DMA controlled
694 // stopped bit is set, such as after an underrun where CIV hits LVI; or if
695 // `civ + offset == LVI and the CELV flag is set.
next_guest_buffer( regs: &Ac97BusMasterRegs, mem: &GuestMemory, func: Ac97Function, offset: usize, ) -> AudioResult<Option<GuestBuffer>>696 fn next_guest_buffer(
697 regs: &Ac97BusMasterRegs,
698 mem: &GuestMemory,
699 func: Ac97Function,
700 offset: usize,
701 ) -> AudioResult<Option<GuestBuffer>> {
702 let func_regs = regs.func_regs(func);
703 let offset = (offset % 32) as u8;
704 let index = (func_regs.civ + offset) % 32;
705
706 // Check that value is between `low` and `high` modulo some `n`.
707 fn check_between(low: u8, high: u8, value: u8) -> bool {
708 // If low <= high, value must be in the interval between them:
709 // 0 l h n
710 // ......+++++++......
711 (low <= high && (low <= value && value <= high)) ||
712 // If low > high, value must not be in the interval between them:
713 // 0 h l n
714 // +++++++++......++++
715 (low > high && (low <= value || value <= high))
716 }
717
718 // Check if
719 // * we're halted
720 // * `index` is not between CIV and LVI (mod 32)
721 // * `index is LVI and we've already processed LVI (SR_CELV is set)
722 // if any of these are true `index` isn't valid.
723 if func_regs.sr & SR_DCH != 0
724 || !check_between(func_regs.civ, func_regs.lvi, index)
725 || func_regs.sr & SR_CELV != 0
726 {
727 return Ok(None);
728 }
729
730 let offset = get_buffer_offset(func_regs, mem, index)?
731 .try_into()
732 .map_err(|_| AudioError::InvalidBufferOffset)?;
733 let frames = get_buffer_samples(func_regs, mem, index)? / regs.tube_count(func);
734
735 Ok(Some(GuestBuffer { offset, frames }))
736 }
737
738 // Marks the current buffer completed and moves to the next buffer for the given
739 // function and registers.
buffer_completed( regs: &mut Ac97BusMasterRegs, mem: &GuestMemory, func: Ac97Function, ) -> AudioResult<()>740 fn buffer_completed(
741 regs: &mut Ac97BusMasterRegs,
742 mem: &GuestMemory,
743 func: Ac97Function,
744 ) -> AudioResult<()> {
745 // check if the completed descriptor wanted an interrupt on completion.
746 let civ = regs.func_regs(func).civ;
747 let descriptor_addr = regs.func_regs(func).bdbar + u32::from(civ) * DESCRIPTOR_LENGTH as u32;
748 let control_reg: u32 = mem
749 .read_obj_from_addr(GuestAddress(u64::from(descriptor_addr) + 4))
750 .map_err(GuestMemoryError::ReadingGuestBufferAddress)?;
751
752 let mut new_sr = regs.func_regs(func).sr & !SR_CELV;
753 if control_reg & BD_IOC != 0 {
754 new_sr |= SR_BCIS;
755 }
756
757 let lvi = regs.func_regs(func).lvi;
758 // if the current buffer was the last valid buffer, then update the status register to
759 // indicate that the end of audio was hit and possibly raise an interrupt.
760 if civ == lvi {
761 new_sr |= SR_DCH | SR_CELV | SR_LVBCI;
762 } else {
763 regs.func_regs_mut(func).move_to_next_buffer();
764 }
765
766 update_sr(regs, func, new_sr);
767
768 regs.func_regs_mut(func).picb = current_buffer_size(regs.func_regs(func), mem)? as u16;
769 if func == Ac97Function::Output {
770 regs.po_pointer_update_time = Instant::now();
771 }
772
773 Ok(())
774 }
775
776 struct AudioWorker {
777 func: Ac97Function,
778 regs: Arc<Mutex<Ac97BusMasterRegs>>,
779 mem: GuestMemory,
780 thread_run: Arc<AtomicBool>,
781 lvi_semaphore: Arc<Condvar>,
782 message_interval: Duration,
783 stream: Box<dyn ShmStream>,
784 pending_buffers: VecDeque<Option<GuestBuffer>>,
785 }
786
787 struct AudioWorkerParams {
788 func: Ac97Function,
789 stream: Box<dyn ShmStream>,
790 pending_buffers: VecDeque<Option<GuestBuffer>>,
791 message_interval: Duration,
792 }
793
794 impl AudioWorker {
new(bus_master: &Ac97BusMaster, args: AudioWorkerParams) -> Self795 fn new(bus_master: &Ac97BusMaster, args: AudioWorkerParams) -> Self {
796 Self {
797 func: args.func,
798 regs: bus_master.regs.clone(),
799 mem: bus_master.mem.clone(),
800 thread_run: bus_master.thread_info(args.func).thread_run.clone(),
801 lvi_semaphore: bus_master.thread_info(args.func).thread_semaphore.clone(),
802 message_interval: args.message_interval,
803 stream: args.stream,
804 pending_buffers: args.pending_buffers,
805 }
806 }
807
808 // Runs and updates the offset within the stream shm where samples can be
809 // found/placed for shm playback/capture streams, respectively
run(&mut self) -> AudioResult<()>810 fn run(&mut self) -> AudioResult<()> {
811 let func = self.func;
812 let message_interval = self.message_interval;
813 // Set up picb.
814 {
815 let mut locked_regs = self.regs.lock();
816 locked_regs.func_regs_mut(func).picb =
817 current_buffer_size(locked_regs.func_regs(func), &self.mem)? as u16;
818 }
819
820 'audio_loop: while self.thread_run.load(Ordering::Relaxed) {
821 {
822 let mut locked_regs = self.regs.lock();
823 while locked_regs.func_regs(func).sr & SR_DCH != 0 {
824 locked_regs = self.lvi_semaphore.wait(locked_regs);
825 if !self.thread_run.load(Ordering::Relaxed) {
826 break 'audio_loop;
827 }
828 }
829 }
830
831 let timeout = Duration::from_secs(1);
832 let action = self
833 .stream
834 .wait_for_next_action_with_timeout(timeout)
835 .map_err(AudioError::WaitForAction)?;
836
837 let request = match action {
838 None => {
839 warn!("No audio message received within timeout of {:?}", timeout);
840 continue;
841 }
842 Some(request) => request,
843 };
844 let start = Instant::now();
845
846 let next_buffer = {
847 let mut locked_regs = self.regs.lock();
848 if self.pending_buffers.len() == 2 {
849 // When we have two pending buffers and receive a request for
850 // another, we know that oldest buffer has been completed.
851 // However, if that old buffer was an empty buffer we sent
852 // because the guest driver had no available buffers, we don't
853 // want to mark a buffer complete.
854 if let Some(Some(_)) = self.pending_buffers.pop_front() {
855 buffer_completed(&mut locked_regs, &self.mem, self.func)?;
856 }
857 }
858
859 // We count the number of pending, real buffers at the server, and
860 // then use that as our offset from CIV.
861 let offset = self.pending_buffers.iter().filter(|e| e.is_some()).count();
862
863 // Get a buffer to respond to our request. If there's no buffer
864 // available, we'll wait one buffer interval and check again.
865 loop {
866 if let Some(buffer) = next_guest_buffer(&locked_regs, &self.mem, func, offset)?
867 {
868 break Some(buffer);
869 }
870 let elapsed = start.elapsed();
871 if elapsed > message_interval {
872 break None;
873 }
874 locked_regs = self
875 .lvi_semaphore
876 .wait_timeout(locked_regs, message_interval - elapsed)
877 .0;
878 }
879 };
880
881 match next_buffer {
882 Some(ref buffer) => {
883 let requested_frames = request.requested_frames();
884 if requested_frames != buffer.frames {
885 // We should be able to handle when the number of frames in
886 // the buffer doesn't match the number of frames requested,
887 // but we don't yet.
888 warn!(
889 "Stream requested {} frames but buffer had {} frames: {:?}",
890 requested_frames, buffer.frames, buffer
891 );
892 }
893
894 request
895 .set_buffer_offset_and_frames(
896 buffer.offset,
897 std::cmp::min(requested_frames, buffer.frames),
898 )
899 .map_err(AudioError::RespondRequest)?;
900 }
901 None => {
902 request
903 .ignore_request()
904 .map_err(AudioError::RespondRequest)?;
905 }
906 }
907 self.pending_buffers.push_back(next_buffer);
908 }
909 Ok(())
910 }
911 }
912
913 // Update the status register and if any interrupts need to fire, raise them.
update_sr(regs: &mut Ac97BusMasterRegs, func: Ac97Function, val: u16)914 fn update_sr(regs: &mut Ac97BusMasterRegs, func: Ac97Function, val: u16) {
915 let int_mask = match func {
916 Ac97Function::Input => GS_PIINT,
917 Ac97Function::Output => GS_POINT,
918 Ac97Function::Microphone => GS_MINT,
919 };
920
921 let mut interrupt_high = false;
922
923 {
924 let func_regs = regs.func_regs_mut(func);
925 let old_sr = func_regs.sr;
926 func_regs.sr = val;
927 if (old_sr ^ val) & SR_INT_MASK != 0 {
928 if (val & SR_LVBCI) != 0 && (func_regs.cr & CR_LVBIE) != 0 {
929 interrupt_high = true;
930 }
931 if (val & SR_BCIS) != 0 && (func_regs.cr & CR_IOCE) != 0 {
932 interrupt_high = true;
933 }
934 } else {
935 return;
936 }
937 }
938
939 if interrupt_high {
940 regs.glob_sta |= int_mask;
941 if let Some(ref irq_evt) = regs.irq_evt {
942 // Ignore write failure, nothing can be done about it from here.
943 let _ = irq_evt.trigger();
944 }
945 } else {
946 regs.glob_sta &= !int_mask;
947 }
948 }
949
950 // Returns the size in samples of the buffer pointed to by the CIV register.
current_buffer_size( func_regs: &Ac97FunctionRegs, mem: &GuestMemory, ) -> GuestMemoryResult<usize>951 fn current_buffer_size(
952 func_regs: &Ac97FunctionRegs,
953 mem: &GuestMemory,
954 ) -> GuestMemoryResult<usize> {
955 let civ = func_regs.civ;
956 get_buffer_samples(func_regs, mem, civ)
957 }
958
959 #[cfg(test)]
960 mod test {
961 use super::*;
962
963 use audio_streams::shm_streams::MockShmStreamSource;
964
965 #[test]
bm_bdbar()966 fn bm_bdbar() {
967 let mut bm = Ac97BusMaster::new(
968 GuestMemory::new(&[]).expect("Creating guest memory failed."),
969 Box::new(MockShmStreamSource::new()),
970 );
971 let mut mixer = Ac97Mixer::new();
972
973 let bdbars = [0x00u64, 0x10, 0x20];
974
975 // Make sure writes have no affect during cold reset.
976 bm.writel(0x00, 0x5555_555f, &mut mixer);
977 assert_eq!(bm.readl(0x00), 0x0000_0000);
978
979 // Relesase cold reset.
980 bm.writel(GLOB_CNT_2C, 0x0000_0002, &mut mixer);
981
982 // Tests that the base address is writable and that the bottom three bits are read only.
983 for bdbar in &bdbars {
984 assert_eq!(bm.readl(*bdbar), 0x0000_0000);
985 bm.writel(*bdbar, 0x5555_555f, &mut mixer);
986 assert_eq!(bm.readl(*bdbar), 0x5555_5558);
987 }
988 }
989
990 #[test]
bm_status_reg()991 fn bm_status_reg() {
992 let mut bm = Ac97BusMaster::new(
993 GuestMemory::new(&[]).expect("Creating guest memory failed."),
994 Box::new(MockShmStreamSource::new()),
995 );
996 let mixer = Ac97Mixer::new();
997
998 let sr_addrs = [0x06u64, 0x16, 0x26];
999
1000 for sr in &sr_addrs {
1001 assert_eq!(bm.readw(*sr, &mixer), 0x0001);
1002 bm.writew(*sr, 0xffff);
1003 assert_eq!(bm.readw(*sr, &mixer), 0x0001);
1004 }
1005 }
1006
1007 #[test]
bm_global_control()1008 fn bm_global_control() {
1009 let mut bm = Ac97BusMaster::new(
1010 GuestMemory::new(&[]).expect("Creating guest memory failed."),
1011 Box::new(MockShmStreamSource::new()),
1012 );
1013 let mut mixer = Ac97Mixer::new();
1014
1015 assert_eq!(bm.readl(GLOB_CNT_2C), 0x0000_0000);
1016
1017 // Relesase cold reset.
1018 bm.writel(GLOB_CNT_2C, 0x0000_0002, &mut mixer);
1019
1020 // Check interrupt enable bits are writable.
1021 bm.writel(GLOB_CNT_2C, 0x0000_0072, &mut mixer);
1022 assert_eq!(bm.readl(GLOB_CNT_2C), 0x0000_0072);
1023
1024 // A Warm reset should doesn't affect register state and is auto cleared.
1025 bm.writel(0x00, 0x5555_5558, &mut mixer);
1026 bm.writel(GLOB_CNT_2C, 0x0000_0076, &mut mixer);
1027 assert_eq!(bm.readl(GLOB_CNT_2C), 0x0000_0072);
1028 assert_eq!(bm.readl(0x00), 0x5555_5558);
1029 // Check that a cold reset works, but setting bdbar and checking it is zeroed.
1030 bm.writel(0x00, 0x5555_555f, &mut mixer);
1031 bm.writel(GLOB_CNT_2C, 0x000_0070, &mut mixer);
1032 assert_eq!(bm.readl(GLOB_CNT_2C), 0x0000_0070);
1033 assert_eq!(bm.readl(0x00), 0x0000_0000);
1034 }
1035
1036 #[test]
run_multi_tube_playback()1037 fn run_multi_tube_playback() {
1038 start_playback(2, 48000);
1039 start_playback(4, 48000);
1040 start_playback(6, 48000);
1041 }
1042
1043 #[test]
run_multi_rate_playback()1044 fn run_multi_rate_playback() {
1045 start_playback(2, 32000);
1046 start_playback(2, 44100);
1047 start_playback(2, 48000);
1048 }
1049
start_playback(num_channels: usize, rate: u16)1050 fn start_playback(num_channels: usize, rate: u16) {
1051 const TIMEOUT: Duration = Duration::from_millis(500);
1052 const LVI_MASK: u8 = 0x1f; // Five bits for 32 total entries.
1053 const IOC_MASK: u32 = 0x8000_0000; // Interrupt on completion.
1054 let num_buffers = LVI_MASK as usize + 1;
1055 const BUFFER_SIZE: usize = 32768;
1056 const FRAGMENT_SIZE: usize = BUFFER_SIZE / 2;
1057
1058 const GUEST_ADDR_BASE: u32 = 0x100_0000;
1059 let mem = GuestMemory::new(&[(GuestAddress(GUEST_ADDR_BASE as u64), 1024 * 1024 * 1024)])
1060 .expect("Creating guest memory failed.");
1061 let stream_source = MockShmStreamSource::new();
1062 let mut bm = Ac97BusMaster::new(mem.clone(), Box::new(stream_source.clone()));
1063 let mut mixer = Ac97Mixer::new();
1064
1065 // Release cold reset.
1066 bm.writel(GLOB_CNT_2C, 0x0000_0002, &mut mixer);
1067
1068 // Setup ping-pong buffers. A and B repeating for every possible index.
1069 bm.writel(PO_BDBAR_10, GUEST_ADDR_BASE, &mut mixer);
1070 for i in 0..num_buffers {
1071 let pointer_addr = GuestAddress(GUEST_ADDR_BASE as u64 + i as u64 * 8);
1072 let control_addr = GuestAddress(GUEST_ADDR_BASE as u64 + i as u64 * 8 + 4);
1073 if i % 2 == 0 {
1074 mem.write_obj_at_addr(GUEST_ADDR_BASE, pointer_addr)
1075 .expect("Writing guest memory failed.");
1076 } else {
1077 mem.write_obj_at_addr(GUEST_ADDR_BASE + FRAGMENT_SIZE as u32, pointer_addr)
1078 .expect("Writing guest memory failed.");
1079 };
1080 mem.write_obj_at_addr(IOC_MASK | ((FRAGMENT_SIZE as u32) / 2), control_addr)
1081 .expect("Writing guest memory failed.");
1082 }
1083
1084 bm.writeb(PO_LVI_15, LVI_MASK, &mixer);
1085 assert_eq!(bm.readb(PO_CIV_14), 0);
1086
1087 // Set tube count and sample rate.
1088 let mut cnt = bm.readl(GLOB_CNT_2C);
1089 cnt &= !GLOB_CNT_PCM_246_MASK;
1090 mixer.writew(MIXER_PCM_FRONT_DAC_RATE_2C, rate);
1091 if num_channels == 4 {
1092 cnt |= GLOB_CNT_PCM_4;
1093 mixer.writew(MIXER_PCM_SURR_DAC_RATE_2E, rate);
1094 } else if num_channels == 6 {
1095 cnt |= GLOB_CNT_PCM_6;
1096 mixer.writew(MIXER_PCM_LFE_DAC_RATE_30, rate);
1097 }
1098 bm.writel(GLOB_CNT_2C, cnt, &mut mixer);
1099
1100 // Start.
1101 bm.writeb(PO_CR_1B, CR_IOCE | CR_RPBM, &mixer);
1102 // TODO(crbug.com/1058881): The test is flaky in builder.
1103 // assert_eq!(bm.readw(PO_PICB_18), 0);
1104
1105 let mut stream = stream_source.get_last_stream();
1106 // Trigger callback and see that CIV has not changed, since only 1
1107 // buffer has been sent.
1108 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1109
1110 assert_eq!(stream.num_channels(), num_channels);
1111 assert_eq!(stream.frame_rate(), rate as u32);
1112
1113 let mut civ = bm.readb(PO_CIV_14);
1114 assert_eq!(civ, 0);
1115
1116 // After two more callbacks, CIV should now be 1 since we know that the
1117 // first buffer must have been played.
1118 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1119 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1120 civ = bm.readb(PO_CIV_14);
1121 assert_eq!(civ, 1);
1122
1123 // Buffer complete should be set as the IOC bit was set in the descriptor.
1124 assert!(bm.readw(PO_SR_16, &mixer) & SR_BCIS != 0);
1125 // Clear the BCIS bit
1126 bm.writew(PO_SR_16, SR_BCIS);
1127 assert!(bm.readw(PO_SR_16, &mixer) & SR_BCIS == 0);
1128
1129 std::thread::sleep(Duration::from_millis(50));
1130 let picb = bm.readw(PO_PICB_18, &mixer);
1131 let pos = (FRAGMENT_SIZE - (picb as usize * 2)) / 4;
1132
1133 // Check that frames are consumed at least at a reasonable rate.
1134 // This can't be exact as during unit tests the thread scheduling is highly variable, so the
1135 // test only checks that some samples are consumed.
1136 assert!(pos > 0);
1137 assert!(bm.readw(PO_SR_16, &mixer) & SR_DCH == 0); // DMA is running.
1138
1139 // Set last valid to next buffer to be sent and trigger callback so we hit it.
1140 bm.writeb(PO_LVI_15, civ + 2, &mixer);
1141 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1142 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1143 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1144 assert!(bm.readw(PO_SR_16, &mixer) & SR_LVBCI != 0); // Hit last buffer
1145 assert!(bm.readw(PO_SR_16, &mixer) & SR_DCH == SR_DCH); // DMA stopped because of lack of buffers.
1146 assert!(bm.readw(PO_SR_16, &mixer) & SR_CELV == SR_CELV); // Processed the last buffer
1147 assert_eq!(bm.readb(PO_LVI_15), bm.readb(PO_CIV_14));
1148 assert!(
1149 bm.readl(GLOB_STA_30) & GS_POINT != 0,
1150 "POINT bit should be set."
1151 );
1152
1153 // Clear the LVB bit
1154 bm.writeb(PO_SR_16, SR_LVBCI as u8, &mixer);
1155 assert!(bm.readw(PO_SR_16, &mixer) & SR_LVBCI == 0);
1156 // Reset the LVI to the last buffer and check that playback resumes
1157 bm.writeb(PO_LVI_15, LVI_MASK, &mixer);
1158 assert!(bm.readw(PO_SR_16, &mixer) & SR_DCH == 0); // DMA restarts.
1159 assert_eq!(bm.readw(PO_SR_16, &mixer) & SR_CELV, 0);
1160
1161 let restart_civ = bm.readb(PO_CIV_14);
1162 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1163 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1164 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1165 assert!(bm.readb(PO_CIV_14) != restart_civ);
1166
1167 // Stop.
1168 bm.writeb(PO_CR_1B, 0, &mixer);
1169 assert!(bm.readw(PO_SR_16, &mixer) & 0x01 != 0); // DMA is not running.
1170 bm.writeb(PO_CR_1B, CR_RR, &mixer);
1171 assert!(
1172 bm.readl(GLOB_STA_30) & GS_POINT == 0,
1173 "POINT bit should be disabled."
1174 );
1175 }
1176
1177 #[test]
run_capture()1178 fn run_capture() {
1179 start_capture(Ac97Function::Input);
1180 start_capture(Ac97Function::Microphone);
1181 }
1182
start_capture(func: Ac97Function)1183 fn start_capture(func: Ac97Function) {
1184 const TIMEOUT: Duration = Duration::from_millis(500);
1185 const LVI_MASK: u8 = 0x1f; // Five bits for 32 total entries.
1186 const IOC_MASK: u32 = 0x8000_0000; // Interrupt on completion.
1187 let num_buffers = LVI_MASK as usize + 1;
1188 const BUFFER_SIZE: usize = 32768;
1189 const FRAGMENT_SIZE: usize = BUFFER_SIZE / 2;
1190
1191 const GUEST_ADDR_BASE: u32 = 0x100_0000;
1192 let mem = GuestMemory::new(&[(GuestAddress(GUEST_ADDR_BASE as u64), 1024 * 1024 * 1024)])
1193 .expect("Creating guest memory failed.");
1194 let stream_source = MockShmStreamSource::new();
1195 let mut bm = Ac97BusMaster::new(mem.clone(), Box::new(stream_source.clone()));
1196 let mut mixer = Ac97Mixer::new();
1197
1198 let (bdbar_addr, lvi_addr, cr_addr, civ_addr, pcib_addr, sr_addr, int_mask) = match func {
1199 Ac97Function::Input => (
1200 PI_BDBAR_00,
1201 PI_LVI_05,
1202 PI_CR_0B,
1203 PI_CIV_04,
1204 PI_PICB_08,
1205 PI_SR_06,
1206 GS_PIINT,
1207 ),
1208 Ac97Function::Microphone => (
1209 MC_BDBAR_20,
1210 MC_LVI_25,
1211 MC_CR_2B,
1212 MC_CIV_24,
1213 MC_PICB_28,
1214 MC_SR_26,
1215 GS_MINT,
1216 ),
1217 _ => {
1218 panic!("Invalid Ac97Function.");
1219 }
1220 };
1221
1222 // Release cold reset.
1223 bm.writel(GLOB_CNT_2C, 0x0000_0002, &mut mixer);
1224
1225 // Setup ping-pong buffers.
1226 bm.writel(bdbar_addr, GUEST_ADDR_BASE, &mut mixer);
1227 for i in 0..num_buffers {
1228 let pointer_addr = GuestAddress(GUEST_ADDR_BASE as u64 + i as u64 * 8);
1229 let control_addr = GuestAddress(GUEST_ADDR_BASE as u64 + i as u64 * 8 + 4);
1230 mem.write_obj_at_addr(GUEST_ADDR_BASE + FRAGMENT_SIZE as u32, pointer_addr)
1231 .expect("Writing guest memory failed.");
1232 mem.write_obj_at_addr(IOC_MASK | ((FRAGMENT_SIZE as u32) / 2), control_addr)
1233 .expect("Writing guest memory failed.");
1234 }
1235
1236 bm.writeb(lvi_addr, LVI_MASK, &mixer);
1237
1238 // Start.
1239 bm.writeb(cr_addr, CR_IOCE | CR_RPBM, &mixer);
1240 // TODO(crbug.com/1086337): Test flakiness in build time.
1241 // assert_eq!(bm.readw(PI_PICB_08), 0);
1242
1243 let mut stream = stream_source.get_last_stream();
1244 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1245
1246 // CIV is 1 here since we preemptively sent two buffer indices to the
1247 // server before creating the stream. When we triggered the callback
1248 // above, that means the first of those buffers was filled, so CIV
1249 // increments to 1.
1250 let civ = bm.readb(civ_addr);
1251 assert_eq!(civ, 1);
1252 std::thread::sleep(Duration::from_millis(20));
1253 let picb = bm.readw(pcib_addr, &mixer);
1254 assert!(picb > 0);
1255 assert!(bm.readw(sr_addr, &mixer) & SR_DCH == 0); // DMA is running.
1256
1257 // Trigger 2 callbacks so that we'll move to buffer 3 since at that
1258 // point we can be certain that buffers 1 and 2 have been captured to.
1259 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1260 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1261 assert_eq!(bm.readb(civ_addr), 3);
1262
1263 let civ = bm.readb(civ_addr);
1264 // Sets LVI to CIV + 2 to trigger last buffer hit
1265 bm.writeb(lvi_addr, civ + 2, &mixer);
1266 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1267 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1268 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1269 assert_ne!(bm.readw(sr_addr, &mixer) & SR_LVBCI, 0); // Hit last buffer
1270 assert_eq!(bm.readw(sr_addr, &mixer) & SR_DCH, SR_DCH); // DMA stopped because of lack of buffers.
1271 assert_eq!(bm.readw(sr_addr, &mixer) & SR_CELV, SR_CELV);
1272 assert_eq!(bm.readb(lvi_addr), bm.readb(civ_addr));
1273 assert!(
1274 bm.readl(GLOB_STA_30) & int_mask != 0,
1275 "int_mask bit should be set."
1276 );
1277
1278 // Clear the LVB bit
1279 bm.writeb(sr_addr, SR_LVBCI as u8, &mixer);
1280 assert!(bm.readw(sr_addr, &mixer) & SR_LVBCI == 0);
1281 // Reset the LVI to the last buffer and check that playback resumes
1282 bm.writeb(lvi_addr, LVI_MASK, &mixer);
1283 assert!(bm.readw(sr_addr, &mixer) & SR_DCH == 0); // DMA restarts.
1284 assert_eq!(bm.readw(sr_addr, &mixer) & SR_CELV, 0);
1285
1286 let restart_civ = bm.readb(civ_addr);
1287 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1288 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1289 assert!(stream.trigger_callback_with_timeout(TIMEOUT));
1290 assert_ne!(bm.readb(civ_addr), restart_civ);
1291
1292 // Stop.
1293 bm.writeb(cr_addr, 0, &mixer);
1294 assert!(bm.readw(sr_addr, &mixer) & 0x01 != 0); // DMA is not running.
1295 bm.writeb(cr_addr, CR_RR, &mixer);
1296 assert!(
1297 bm.readl(GLOB_STA_30) & int_mask == 0,
1298 "int_mask bit should be disabled."
1299 );
1300 }
1301 }
1302