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(®s.pi_regs, offset - PI_BASE_00),
326 PO_BASE_10..=PO_CR_1B => readb_func_regs(®s.po_regs, offset - PO_BASE_10),
327 MC_BASE_20..=MC_CR_2B => readb_func_regs(®s.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