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