VirtualBox

source: vbox/trunk/src/VBox/Devices/Audio/DevIchAc97.cpp@ 22432

Last change on this file since 22432 was 18645, checked in by vboxsync, 16 years ago

VMSetRuntimeError[V] refactoring: fFatal -> fFlags, may return informational status codes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 57.7 KB
Line 
1/* $Id: DevIchAc97.cpp 18645 2009-04-02 15:38:31Z vboxsync $ */
2/** @file
3 * DevIchAc97 - VBox ICH AC97 Audio Controller.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22/*******************************************************************************
23* Header Files *
24*******************************************************************************/
25#define LOG_GROUP LOG_GROUP_DEV_AUDIO
26#include <VBox/pdmdev.h>
27#include <iprt/assert.h>
28#include <iprt/uuid.h>
29#include <iprt/string.h>
30
31#include "../Builtins.h"
32
33extern "C" {
34#include "audio.h"
35}
36
37#undef LOG_VOICES
38#ifndef VBOX
39//#define USE_MIXER
40#else
41#define USE_MIXER
42#endif
43
44#define AC97_SSM_VERSION 1
45
46enum {
47 AC97_Reset = 0x00,
48 AC97_Master_Volume_Mute = 0x02,
49 AC97_Headphone_Volume_Mute = 0x04,
50 AC97_Master_Volume_Mono_Mute = 0x06,
51 AC97_Master_Tone_RL = 0x08,
52 AC97_PC_BEEP_Volume_Mute = 0x0A,
53 AC97_Phone_Volume_Mute = 0x0C,
54 AC97_Mic_Volume_Mute = 0x0E,
55 AC97_Line_In_Volume_Mute = 0x10,
56 AC97_CD_Volume_Mute = 0x12,
57 AC97_Video_Volume_Mute = 0x14,
58 AC97_Aux_Volume_Mute = 0x16,
59 AC97_PCM_Out_Volume_Mute = 0x18,
60 AC97_Record_Select = 0x1A,
61 AC97_Record_Gain_Mute = 0x1C,
62 AC97_Record_Gain_Mic_Mute = 0x1E,
63 AC97_General_Purpose = 0x20,
64 AC97_3D_Control = 0x22,
65 AC97_AC_97_RESERVED = 0x24,
66 AC97_Powerdown_Ctrl_Stat = 0x26,
67 AC97_Extended_Audio_ID = 0x28,
68 AC97_Extended_Audio_Ctrl_Stat = 0x2A,
69 AC97_PCM_Front_DAC_Rate = 0x2C,
70 AC97_PCM_Surround_DAC_Rate = 0x2E,
71 AC97_PCM_LFE_DAC_Rate = 0x30,
72 AC97_PCM_LR_ADC_Rate = 0x32,
73 AC97_MIC_ADC_Rate = 0x34,
74 AC97_6Ch_Vol_C_LFE_Mute = 0x36,
75 AC97_6Ch_Vol_L_R_Surround_Mute = 0x38,
76 AC97_Vendor_Reserved = 0x58,
77 AC97_Vendor_ID1 = 0x7c,
78 AC97_Vendor_ID2 = 0x7e
79};
80
81#ifndef VBOX
82# define SOFT_VOLUME
83#else
84# undef SOFT_VOLUME
85#endif
86#define SR_FIFOE RT_BIT(4) /* rwc, fifo error */
87#define SR_BCIS RT_BIT(3) /* rwc, buffer completion interrupt status */
88#define SR_LVBCI RT_BIT(2) /* rwc, last valid buffer completion interrupt */
89#define SR_CELV RT_BIT(1) /* ro, current equals last valid */
90#define SR_DCH RT_BIT(0) /* ro, controller halted */
91#define SR_VALID_MASK (RT_BIT(5) - 1)
92#define SR_WCLEAR_MASK (SR_FIFOE | SR_BCIS | SR_LVBCI)
93#define SR_RO_MASK (SR_DCH | SR_CELV)
94#define SR_INT_MASK (SR_FIFOE | SR_BCIS | SR_LVBCI)
95
96#define CR_IOCE RT_BIT(4) /* rw */
97#define CR_FEIE RT_BIT(3) /* rw */
98#define CR_LVBIE RT_BIT(2) /* rw */
99#define CR_RR RT_BIT(1) /* rw */
100#define CR_RPBM RT_BIT(0) /* rw */
101#define CR_VALID_MASK (RT_BIT(5) - 1)
102#define CR_DONT_CLEAR_MASK (CR_IOCE | CR_FEIE | CR_LVBIE)
103
104#define GC_WR 4 /* rw */
105#define GC_CR 2 /* rw */
106#define GC_VALID_MASK (RT_BIT(6) - 1)
107
108#define GS_MD3 RT_BIT(17) /* rw */
109#define GS_AD3 RT_BIT(16) /* rw */
110#define GS_RCS RT_BIT(15) /* rwc */
111#define GS_B3S12 RT_BIT(14) /* ro */
112#define GS_B2S12 RT_BIT(13) /* ro */
113#define GS_B1S12 RT_BIT(12) /* ro */
114#define GS_S1R1 RT_BIT(11) /* rwc */
115#define GS_S0R1 RT_BIT(10) /* rwc */
116#define GS_S1CR RT_BIT(9) /* ro */
117#define GS_S0CR RT_BIT(8) /* ro */
118#define GS_MINT RT_BIT(7) /* ro */
119#define GS_POINT RT_BIT(6) /* ro */
120#define GS_PIINT RT_BIT(5) /* ro */
121#define GS_RSRVD (RT_BIT(4)|RT_BIT(3))
122#define GS_MOINT RT_BIT(2) /* ro */
123#define GS_MIINT RT_BIT(1) /* ro */
124#define GS_GSCI RT_BIT(0) /* rwc */
125#define GS_RO_MASK (GS_B3S12| \
126 GS_B2S12| \
127 GS_B1S12| \
128 GS_S1CR| \
129 GS_S0CR| \
130 GS_MINT| \
131 GS_POINT| \
132 GS_PIINT| \
133 GS_RSRVD| \
134 GS_MOINT| \
135 GS_MIINT)
136#define GS_VALID_MASK (RT_BIT(18) - 1)
137#define GS_WCLEAR_MASK (GS_RCS|GS_S1R1|GS_S0R1|GS_GSCI)
138
139/** Buffer Descriptor */
140#define BD_IOC RT_BIT(31) /* Interrupt on Completion */
141#define BD_BUP RT_BIT(30) /* Buffer Underrun Policy */
142
143#define EACS_VRA 1
144#define EACS_VRM 8
145
146#define VOL_MASK 0x1f
147#define MUTE_SHIFT 15
148
149#define REC_MASK 7
150enum
151{
152 REC_MIC = 0,
153 REC_CD,
154 REC_VIDEO,
155 REC_AUX,
156 REC_LINE_IN,
157 REC_STEREO_MIX,
158 REC_MONO_MIX,
159 REC_PHONE
160};
161
162typedef struct BD
163{
164 uint32_t addr;
165 uint32_t ctl_len;
166} BD;
167
168typedef struct AC97BusMasterRegs
169{
170 uint32_t bdbar; /* rw 0, buffer descriptor list base address register */
171 uint8_t civ; /* ro 0, current index value */
172 uint8_t lvi; /* rw 0, last valid index */
173 uint16_t sr; /* rw 1, status register */
174 uint16_t picb; /* ro 0, position in current buffer */
175 uint8_t piv; /* ro 0, prefetched index value */
176 uint8_t cr; /* rw 0, control register */
177 int bd_valid; /* initialized? */
178 BD bd;
179} AC97BusMasterRegs;
180
181typedef struct AC97LinkState
182{
183 QEMUSoundCard card;
184 /** Global Control (Bus Master Control Register) */
185 uint32_t glob_cnt;
186 /** Global Status (Bus Master Control Register) */
187 uint32_t glob_sta;
188 /** Codec Access Semaphore Register (Bus Master Control Register) */
189 uint32_t cas;
190 uint32_t last_samp;
191 /** Bus Master Control Registers for PCM in, PCM out, and Mic in */
192 AC97BusMasterRegs bm_regs[3];
193 uint8_t mixer_data[256];
194 /** PCM in */
195 SWVoiceIn *voice_pi;
196 /** PCM out */
197 SWVoiceOut *voice_po;
198 /** Mic in */
199 SWVoiceIn *voice_mc;
200 uint8_t silence[128];
201 int bup_flag;
202 /** Pointer to the device instance. */
203 PPDMDEVINSR3 pDevIns;
204 /** Pointer to the connector of the attached audio driver. */
205 PPDMIAUDIOCONNECTOR pDrv;
206 /** Pointer to the attached audio driver. */
207 PPDMIBASE pDrvBase;
208 /** The base interface. */
209 PDMIBASE IBase;
210 /** Base port of the I/O space region. */
211 RTIOPORT IOPortBase[2];
212} AC97LinkState;
213
214#define ICHAC97STATE_2_DEVINS(pAC97) ((pAC97)->pDevIns)
215#define PCIDEV_2_ICHAC97STATE(pPciDev) ((PCIAC97LinkState *)(pPciDev))
216
217enum
218{
219 BUP_SET = RT_BIT(0),
220 BUP_LAST = RT_BIT(1)
221};
222
223typedef struct PCIAC97LinkState
224{
225 PCIDevice dev;
226 AC97LinkState ac97;
227} PCIAC97LinkState;
228
229#define MKREGS(prefix, start) \
230 enum { \
231 prefix ## _BDBAR = start, \
232 prefix ## _CIV = start + 4, \
233 prefix ## _LVI = start + 5, \
234 prefix ## _SR = start + 6, \
235 prefix ## _PICB = start + 8, \
236 prefix ## _PIV = start + 10, \
237 prefix ## _CR = start + 11 \
238 }
239
240enum
241{
242 PI_INDEX = 0, /* PCM in */
243 PO_INDEX, /* PCM out */
244 MC_INDEX, /* Mic in */
245 LAST_INDEX
246};
247
248MKREGS (PI, PI_INDEX * 16);
249MKREGS (PO, PO_INDEX * 16);
250MKREGS (MC, MC_INDEX * 16);
251
252enum
253{
254 GLOB_CNT = 0x2c,
255 GLOB_STA = 0x30,
256 CAS = 0x34
257};
258
259#define GET_BM(index) (((index) >> 4) & 3)
260
261static void po_callback (void *opaque, int free);
262static void pi_callback (void *opaque, int avail);
263static void mc_callback (void *opaque, int avail);
264
265static void warm_reset (AC97LinkState *s)
266{
267 (void) s;
268}
269
270static void cold_reset (AC97LinkState * s)
271{
272 (void) s;
273}
274
275/** Fetch Buffer Descriptor at _CIV */
276static void fetch_bd (AC97LinkState *s, AC97BusMasterRegs *r)
277{
278 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(s);
279 uint8_t b[8];
280
281 PDMDevHlpPhysRead (pDevIns, r->bdbar + r->civ * 8, b, sizeof(b));
282 r->bd_valid = 1;
283#if !defined(RT_ARCH_X86) && !defined(RT_ARCH_AMD64)
284# error Please adapt the code (audio buffers are little endian)!
285#else
286 r->bd.addr = (*(uint32_t *) &b[0]) & ~3;
287 r->bd.ctl_len = (*(uint32_t *) &b[4]);
288#endif
289 r->picb = r->bd.ctl_len & 0xffff;
290 Log (("ac97: bd %2d addr=%#x ctl=%#06x len=%#x(%d bytes)\n",
291 r->civ, r->bd.addr, r->bd.ctl_len >> 16,
292 r->bd.ctl_len & 0xffff, (r->bd.ctl_len & 0xffff) << 1));
293}
294
295/**
296 * Update the BM status register
297 */
298static void update_sr (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr)
299{
300 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(s);
301 int event = 0;
302 int level = 0;
303 uint32_t new_mask = new_sr & SR_INT_MASK;
304 uint32_t old_mask = r->sr & SR_INT_MASK;
305 uint32_t masks[] = {GS_PIINT, GS_POINT, GS_MINT};
306
307 if (new_mask ^ old_mask)
308 {
309 /** @todo is IRQ deasserted when only one of status bits is cleared? */
310 if (!new_mask)
311 {
312 event = 1;
313 level = 0;
314 }
315 else if ((new_mask & SR_LVBCI) && (r->cr & CR_LVBIE))
316 {
317 event = 1;
318 level = 1;
319 }
320 else if ((new_mask & SR_BCIS) && (r->cr & CR_IOCE))
321 {
322 event = 1;
323 level = 1;
324 }
325 }
326
327 r->sr = new_sr;
328
329 Log (("ac97: IOC%d LVB%d sr=%#x event=%d level=%d\n",
330 r->sr & SR_BCIS, r->sr & SR_LVBCI, r->sr, event, level));
331
332 if (event)
333 {
334 if (level)
335 s->glob_sta |= masks[r - s->bm_regs];
336 else
337 s->glob_sta &= ~masks[r - s->bm_regs];
338
339 Log (("ac97: set irq level=%d\n", !!level));
340 PDMDevHlpPCISetIrq (pDevIns, 0, !!level);
341 }
342}
343
344static void voice_set_active (AC97LinkState *s, int bm_index, int on)
345{
346 switch (bm_index)
347 {
348 case PI_INDEX: AUD_set_active_in (s->voice_pi, on); break;
349 case PO_INDEX: AUD_set_active_out(s->voice_po, on); break;
350 case MC_INDEX: AUD_set_active_in (s->voice_mc, on); break;
351 default: AssertFailed ();
352 break;
353 }
354}
355
356static void reset_bm_regs (AC97LinkState *s, AC97BusMasterRegs *r)
357{
358 Log (("ac97: reset_bm_regs\n"));
359 r->bdbar = 0;
360 r->civ = 0;
361 r->lvi = 0;
362 /** @todo do we need to do that? */
363 update_sr (s, r, SR_DCH);
364 r->picb = 0;
365 r->piv = 0;
366 r->cr = r->cr & CR_DONT_CLEAR_MASK;
367 r->bd_valid = 0;
368
369 voice_set_active (s, r - s->bm_regs, 0);
370 memset (s->silence, 0, sizeof (s->silence));
371}
372
373static void mixer_store (AC97LinkState *s, uint32_t i, uint16_t v)
374{
375 if (i + 2 > sizeof (s->mixer_data))
376 {
377 Log (("ac97: mixer_store: index %d out of bounds %d\n",
378 i, sizeof (s->mixer_data)));
379 return;
380 }
381
382 s->mixer_data[i + 0] = v & 0xff;
383 s->mixer_data[i + 1] = v >> 8;
384}
385
386static uint16_t mixer_load (AC97LinkState *s, uint32_t i)
387{
388 uint16_t val;
389
390 if (i + 2 > sizeof (s->mixer_data))
391 {
392 Log (("ac97: mixer_store: index %d out of bounds %d\n",
393 i, sizeof (s->mixer_data)));
394 val = 0xffff;
395 }
396 else
397 val = s->mixer_data[i + 0] | (s->mixer_data[i + 1] << 8);
398
399 return val;
400}
401
402static void open_voice (AC97LinkState *s, int index, int freq)
403{
404 audsettings_t as;
405
406 if (freq)
407 {
408 as.freq = freq;
409 as.nchannels = 2;
410 as.fmt = AUD_FMT_S16;
411 as.endianness = 0;
412
413 switch (index)
414 {
415 case PI_INDEX: /* PCM in */
416 s->voice_pi = AUD_open_in (&s->card, s->voice_pi, "ac97.pi",
417 s, pi_callback, &as);
418#ifdef LOG_VOICES
419 LogRel (("AC97: open PI freq=%d (%s)\n", freq, s->voice_pi ? "ok" : "FAIL"));
420#endif
421 break;
422
423 case PO_INDEX: /* PCM out */
424 s->voice_po = AUD_open_out (&s->card, s->voice_po, "ac97.po",
425 s, po_callback, &as);
426#ifdef LOG_VOICES
427 LogRel (("AC97: open PO freq=%d (%s)\n", freq, s->voice_po ? "ok" : "FAIL"));
428#endif
429 break;
430
431 case MC_INDEX: /* Mic in */
432 s->voice_mc = AUD_open_in (&s->card, s->voice_mc, "ac97.mc",
433 s, mc_callback, &as);
434#ifdef LOG_VOICES
435 LogRel (("AC97: open MC freq=%d (%s)\n", freq, s->voice_mc ? "ok" : "FAIL"));
436#endif
437 break;
438 }
439 }
440 else
441 {
442 switch (index)
443 {
444 case PI_INDEX:
445 AUD_close_in (&s->card, s->voice_pi);
446#ifdef LOG_VOICES
447 LogRel (("AC97: Closing PCM IN\n"));
448#endif
449 s->voice_pi = NULL;
450 break;
451
452 case PO_INDEX:
453 AUD_close_out (&s->card, s->voice_po);
454#ifdef LOG_VOICES
455 LogRel (("AC97: Closing PCM OUT\n"));
456#endif
457 s->voice_po = NULL;
458 break;
459
460 case MC_INDEX:
461 AUD_close_in (&s->card, s->voice_mc);
462#ifdef LOG_VOICES
463 LogRel (("AC97: Closing MIC IN\n"));
464#endif
465 s->voice_mc = NULL;
466 break;
467 }
468 }
469}
470
471static void reset_voices (AC97LinkState *s, uint8_t active[LAST_INDEX])
472{
473 uint16_t freq;
474
475 freq = mixer_load (s, AC97_PCM_LR_ADC_Rate);
476 open_voice (s, PI_INDEX, freq);
477 AUD_set_active_in (s->voice_pi, active[PI_INDEX]);
478
479 freq = mixer_load (s, AC97_PCM_Front_DAC_Rate);
480 open_voice (s, PO_INDEX, freq);
481 AUD_set_active_out (s->voice_po, active[PO_INDEX]);
482
483 freq = mixer_load (s, AC97_MIC_ADC_Rate);
484 open_voice (s, MC_INDEX, freq);
485 AUD_set_active_in (s->voice_mc, active[MC_INDEX]);
486}
487
488#ifdef USE_MIXER
489
490static void set_volume (AC97LinkState *s, int index,
491 audmixerctl_t mt, uint32_t val)
492{
493 int mute = (val >> MUTE_SHIFT) & 1;
494 uint8_t rvol = VOL_MASK - (val & VOL_MASK);
495 uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK);
496 rvol = 255 * rvol / VOL_MASK;
497 lvol = 255 * lvol / VOL_MASK;
498
499# ifdef SOFT_VOLUME
500 if (index == AC97_Master_Volume_Mute)
501 AUD_set_volume_out (s->voice_po, mute, lvol, rvol);
502 else
503 AUD_set_volume (mt, &mute, &lvol, &rvol);
504# else
505 AUD_set_volume (mt, &mute, &lvol, &rvol);
506# endif
507
508 rvol = VOL_MASK - ((VOL_MASK * rvol) / 255);
509 lvol = VOL_MASK - ((VOL_MASK * lvol) / 255);
510
511 /*
512 * From AC'97 SoundMax Codec AD1981A: "Because AC '97 defines 6-bit volume registers, to
513 * maintain compatibility whenever the D5 or D13 bits are set to `1,' their respective
514 * lower five volume bits are automatically set to `1' by the Codec logic. On readback,
515 * all lower 5 bits will read ones whenever these bits are set to `1.'"
516 *
517 * Linux ALSA depends on this behavior.
518 */
519 if (val & RT_BIT(5))
520 val |= RT_BIT(4) | RT_BIT(3) | RT_BIT(2) | RT_BIT(1) | RT_BIT(0);
521 if (val & RT_BIT(13))
522 val |= RT_BIT(12) | RT_BIT(11) | RT_BIT(10) | RT_BIT(9) | RT_BIT(8);
523
524 mixer_store (s, index, val);
525}
526
527static audrecsource_t ac97_to_aud_record_source (uint8_t i)
528{
529 switch (i)
530 {
531 case REC_MIC: return AUD_REC_MIC;
532 case REC_CD: return AUD_REC_CD;
533 case REC_VIDEO: return AUD_REC_VIDEO;
534 case REC_AUX: return AUD_REC_AUX;
535 case REC_LINE_IN: return AUD_REC_LINE_IN;
536 case REC_PHONE: return AUD_REC_PHONE;
537 default: Log (("ac97: Unknown record source %d, using MIC\n", i));
538 return AUD_REC_MIC;
539 }
540}
541
542static uint8_t aud_to_ac97_record_source (audrecsource_t rs)
543{
544 switch (rs)
545 {
546 case AUD_REC_MIC: return REC_MIC;
547 case AUD_REC_CD: return REC_CD;
548 case AUD_REC_VIDEO: return REC_VIDEO;
549 case AUD_REC_AUX: return REC_AUX;
550 case AUD_REC_LINE_IN: return REC_LINE_IN;
551 case AUD_REC_PHONE: return REC_PHONE;
552 default: Log (("ac97: Unknown audio recording source %d using MIC\n", rs));
553 return REC_MIC;
554 }
555}
556
557static void record_select (AC97LinkState *s, uint32_t val)
558{
559 uint8_t rs = val & REC_MASK;
560 uint8_t ls = (val >> 8) & REC_MASK;
561 audrecsource_t ars = ac97_to_aud_record_source (rs);
562 audrecsource_t als = ac97_to_aud_record_source (ls);
563 AUD_set_record_source (&als, &ars);
564 rs = aud_to_ac97_record_source (ars);
565 ls = aud_to_ac97_record_source (als);
566 mixer_store (s, AC97_Record_Select, rs | (ls << 8));
567}
568
569#endif /* USE_MIXER */
570
571static void mixer_reset (AC97LinkState *s)
572{
573 uint8_t active[LAST_INDEX];
574
575 Log (("ac97: mixer_reset\n"));
576 memset (s->mixer_data, 0, sizeof (s->mixer_data));
577 memset (active, 0, sizeof (active));
578 mixer_store (s, AC97_Reset , 0x0000); /* 6940 */
579 mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x8000);
580 mixer_store (s, AC97_PC_BEEP_Volume_Mute , 0x0000);
581
582 mixer_store (s, AC97_Phone_Volume_Mute , 0x8008);
583 mixer_store (s, AC97_Mic_Volume_Mute , 0x8008);
584 mixer_store (s, AC97_CD_Volume_Mute , 0x8808);
585 mixer_store (s, AC97_Aux_Volume_Mute , 0x8808);
586 mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x8000);
587 mixer_store (s, AC97_General_Purpose , 0x0000);
588 mixer_store (s, AC97_3D_Control , 0x0000);
589 mixer_store (s, AC97_Powerdown_Ctrl_Stat , 0x000f);
590
591 /*
592 * Sigmatel 9700 (STAC9700)
593 */
594 mixer_store (s, AC97_Vendor_ID1 , 0x8384);
595 mixer_store (s, AC97_Vendor_ID2 , 0x7600); /* 7608 */
596
597 mixer_store (s, AC97_Extended_Audio_ID , 0x0809);
598 mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, 0x0009);
599 mixer_store (s, AC97_PCM_Front_DAC_Rate , 0xbb80);
600 mixer_store (s, AC97_PCM_Surround_DAC_Rate , 0xbb80);
601 mixer_store (s, AC97_PCM_LFE_DAC_Rate , 0xbb80);
602 mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80);
603 mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80);
604
605#ifdef USE_MIXER
606 record_select (s, 0);
607 set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME, 0x8000);
608 set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM, 0x8808);
609 set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);
610#else
611 mixer_store (s, AC97_Record_Select, 0);
612 mixer_store (s, AC97_Master_Volume_Mute, 0x8000);
613 mixer_store (s, AC97_PCM_Out_Volume_Mute, 0x8808);
614 mixer_store (s, AC97_Line_In_Volume_Mute, 0x8808);
615#endif
616
617 reset_voices (s, active);
618}
619
620static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
621 int max, int *stop)
622{
623 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(s);
624 uint8_t tmpbuf[4096];
625 uint32_t addr = r->bd.addr;
626 uint32_t temp = r->picb << 1;
627 uint32_t written = 0;
628 int to_copy = 0;
629
630 temp = audio_MIN (temp, (uint32_t) max);
631 if (!temp)
632 {
633 *stop = 1;
634 return 0;
635 }
636
637 while (temp)
638 {
639 int copied;
640 to_copy = audio_MIN (temp, sizeof (tmpbuf));
641 PDMDevHlpPhysRead (pDevIns, addr, tmpbuf, to_copy);
642 copied = AUD_write (s->voice_po, tmpbuf, to_copy);
643 Log (("ac97: write_audio max=%x to_copy=%x copied=%x\n",
644 max, to_copy, copied));
645 if (!copied)
646 {
647 *stop = 1;
648 break;
649 }
650 temp -= copied;
651 addr += copied;
652 written += copied;
653 }
654
655 if (!temp)
656 {
657 if (to_copy < 4)
658 {
659 Log (("ac97: whoops\n"));
660 s->last_samp = 0;
661 }
662 else
663 s->last_samp = *(uint32_t *) &tmpbuf[to_copy - 4];
664 }
665
666 r->bd.addr = addr;
667 return written;
668}
669
670static void write_bup (AC97LinkState *s, int elapsed)
671{
672 int written = 0;
673
674 Log (("ac97: write_bup\n"));
675 if (!(s->bup_flag & BUP_SET))
676 {
677 if (s->bup_flag & BUP_LAST)
678 {
679 unsigned int i;
680 uint32_t *p = (uint32_t*)s->silence;
681 for (i = 0; i < sizeof (s->silence) / 4; i++)
682 *p++ = s->last_samp;
683 }
684 else
685 memset (s->silence, 0, sizeof (s->silence));
686
687 s->bup_flag |= BUP_SET;
688 }
689
690 while (elapsed)
691 {
692 unsigned int temp = audio_MIN ((unsigned int)elapsed, sizeof (s->silence));
693 while (temp)
694 {
695 int copied = AUD_write (s->voice_po, s->silence, temp);
696 if (!copied)
697 return;
698 temp -= copied;
699 elapsed -= copied;
700 written += copied;
701 }
702 }
703}
704
705static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,
706 int max, int *stop)
707{
708 PPDMDEVINS pDevIns = ICHAC97STATE_2_DEVINS(s);
709 uint8_t tmpbuf[4096];
710 uint32_t addr = r->bd.addr;
711 uint32_t temp = r->picb << 1;
712 uint32_t nread = 0;
713 int to_copy = 0;
714 SWVoiceIn *voice = (r - s->bm_regs) == MC_INDEX ? s->voice_mc : s->voice_pi;
715
716 temp = audio_MIN (temp, (uint32_t) max);
717 if (!temp)
718 {
719 *stop = 1;
720 return 0;
721 }
722
723 while (temp)
724 {
725 int acquired;
726 to_copy = audio_MIN (temp, sizeof (tmpbuf));
727 acquired = AUD_read (voice, tmpbuf, to_copy);
728 if (!acquired)
729 {
730 *stop = 1;
731 break;
732 }
733 PDMDevHlpPhysWrite (pDevIns, addr, tmpbuf, acquired);
734 temp -= acquired;
735 addr += acquired;
736 nread += acquired;
737 }
738
739 r->bd.addr = addr;
740 return nread;
741}
742
743static void transfer_audio (AC97LinkState *s, int index, int elapsed)
744{
745 AC97BusMasterRegs *r = &s->bm_regs[index];
746 int written = 0, stop = 0;
747
748 if (r->sr & SR_DCH)
749 {
750 if (r->cr & CR_RPBM)
751 {
752 switch (index)
753 {
754 case PO_INDEX:
755 write_bup (s, elapsed);
756 break;
757 }
758 }
759 return;
760 }
761
762 while ((elapsed >> 1) && !stop)
763 {
764 int temp;
765
766 if (!r->bd_valid)
767 {
768 Log (("ac97: invalid bd\n"));
769 fetch_bd (s, r);
770 }
771
772 if (!r->picb)
773 {
774 Log (("ac97: fresh bd %d is empty %#x %#x\n",
775 r->civ, r->bd.addr, r->bd.ctl_len));
776 if (r->civ == r->lvi)
777 {
778 r->sr |= SR_DCH; /* CELV? */
779 s->bup_flag = 0;
780 break;
781 }
782 r->sr &= ~SR_CELV;
783 r->civ = r->piv;
784 r->piv = (r->piv + 1) % 32;
785 fetch_bd (s, r);
786 return;
787 }
788
789 switch (index)
790 {
791 case PO_INDEX:
792 temp = write_audio (s, r, elapsed, &stop);
793 written += temp;
794 elapsed -= temp;
795 r->picb -= (temp >> 1);
796 break;
797
798 case PI_INDEX:
799 case MC_INDEX:
800 temp = read_audio (s, r, elapsed, &stop);
801 elapsed -= temp;
802 r->picb -= (temp >> 1);
803 break;
804 }
805
806 Log (("r->picb = %d\n", r->picb));
807
808 if (!r->picb)
809 {
810 uint32_t new_sr = r->sr & ~SR_CELV;
811
812 if (r->bd.ctl_len & BD_IOC)
813 new_sr |= SR_BCIS;
814
815 if (r->civ == r->lvi)
816 {
817 Log (("ac97: Underrun civ (%d) == lvi (%d)\n", r->civ, r->lvi));
818 new_sr |= SR_LVBCI | SR_DCH | SR_CELV;
819 stop = 1;
820 s->bup_flag = (r->bd.ctl_len & BD_BUP) ? BUP_LAST : 0;
821 }
822 else
823 {
824 r->civ = r->piv;
825 r->piv = (r->piv + 1) % 32;
826 fetch_bd (s, r);
827 }
828 update_sr (s, r, new_sr);
829 }
830 }
831}
832
833static void pi_callback (void *opaque, int avail)
834{
835 transfer_audio ((AC97LinkState*)opaque, PI_INDEX, avail);
836}
837
838static void mc_callback (void *opaque, int avail)
839{
840 transfer_audio ((AC97LinkState*)opaque, MC_INDEX, avail);
841}
842
843static void po_callback (void *opaque, int free)
844{
845 transfer_audio ((AC97LinkState*)opaque, PO_INDEX, free);
846}
847
848/**
849 * Port I/O Handler for IN operations.
850 *
851 * @returns VBox status code.
852 *
853 * @param pDevIns The device instance.
854 * @param pvUser User argument.
855 * @param uPort Port number used for the IN operation.
856 * @param pu32 Where to store the result.
857 * @param cb Number of bytes read.
858 */
859static DECLCALLBACK(int) ichac97IOPortNABMRead (PPDMDEVINS pDevIns, void *pvUser,
860 RTIOPORT Port, uint32_t *pu32, unsigned cb)
861{
862 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
863 AC97LinkState *s = &d->ac97;
864
865 switch (cb)
866 {
867 case 1:
868 {
869 AC97BusMasterRegs *r = NULL;
870 uint32_t index = Port - d->ac97.IOPortBase[1];
871 *pu32 = ~0U;
872
873 switch (index)
874 {
875 case CAS:
876 /* Codec Access Semaphore Register */
877 Log (("ac97: CAS %d\n", s->cas));
878 *pu32 = s->cas;
879 s->cas = 1;
880 break;
881 case PI_CIV:
882 case PO_CIV:
883 case MC_CIV:
884 /* Current Index Value Register */
885 r = &s->bm_regs[GET_BM (index)];
886 *pu32 = r->civ;
887 Log (("ac97: CIV[%d] -> %#x\n", GET_BM (index), *pu32));
888 break;
889 case PI_LVI:
890 case PO_LVI:
891 case MC_LVI:
892 /* Last Valid Index Register */
893 r = &s->bm_regs[GET_BM (index)];
894 *pu32 = r->lvi;
895 Log (("ac97: LVI[%d] -> %#x\n", GET_BM (index), *pu32));
896 break;
897 case PI_PIV:
898 case PO_PIV:
899 case MC_PIV:
900 /* Prefetched Index Value Register */
901 r = &s->bm_regs[GET_BM (index)];
902 *pu32 = r->piv;
903 Log (("ac97: PIV[%d] -> %#x\n", GET_BM (index), *pu32));
904 break;
905 case PI_CR:
906 case PO_CR:
907 case MC_CR:
908 /* Control Register */
909 r = &s->bm_regs[GET_BM (index)];
910 *pu32 = r->cr;
911 Log (("ac97: CR[%d] -> %#x\n", GET_BM (index), *pu32));
912 break;
913 case PI_SR:
914 case PO_SR:
915 case MC_SR:
916 /* Status Register (lower part) */
917 r = &s->bm_regs[GET_BM (index)];
918 *pu32 = r->sr & 0xff;
919 Log (("ac97: SRb[%d] -> %#x\n", GET_BM (index), *pu32));
920 break;
921 default:
922 Log (("ac97: U nabm readb %#x -> %#x\n", Port, *pu32));
923 break;
924 }
925 break;
926 }
927
928 case 2:
929 {
930 AC97BusMasterRegs *r = NULL;
931 uint32_t index = Port - d->ac97.IOPortBase[1];
932 *pu32 = ~0U;
933
934 switch (index)
935 {
936 case PI_SR:
937 case PO_SR:
938 case MC_SR:
939 /* Status Register */
940 r = &s->bm_regs[GET_BM (index)];
941 *pu32 = r->sr;
942 Log (("ac97: SR[%d] -> %#x\n", GET_BM (index), *pu32));
943 break;
944 case PI_PICB:
945 case PO_PICB:
946 case MC_PICB:
947 /* Position in Current Buffer Register */
948 r = &s->bm_regs[GET_BM (index)];
949 *pu32 = r->picb;
950 Log (("ac97: PICB[%d] -> %#x\n", GET_BM (index), *pu32));
951 break;
952 default:
953 Log (("ac97: U nabm readw %#x -> %#x\n", Port, *pu32));
954 break;
955 }
956 break;
957 }
958
959 case 4:
960 {
961 AC97BusMasterRegs *r = NULL;
962 uint32_t index = Port - d->ac97.IOPortBase[1];
963 *pu32 = ~0U;
964
965 switch (index)
966 {
967 case PI_BDBAR:
968 case PO_BDBAR:
969 case MC_BDBAR:
970 /* Buffer Descriptor Base Address Register */
971 r = &s->bm_regs[GET_BM (index)];
972 *pu32 = r->bdbar;
973 Log (("ac97: BMADDR[%d] -> %#x\n", GET_BM (index), *pu32));
974 break;
975 case PI_CIV:
976 case PO_CIV:
977 case MC_CIV:
978 /* 32-bit access: Current Index Value Register +
979 * Last Valid Index Register +
980 * Status Register */
981 r = &s->bm_regs[GET_BM (index)];
982 *pu32 = r->civ | (r->lvi << 8) | (r->sr << 16);
983 Log (("ac97: CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM (index),
984 r->civ, r->lvi, r->sr));
985 break;
986 case PI_PICB:
987 case PO_PICB:
988 case MC_PICB:
989 /* 32-bit access: Position in Current Buffer Register +
990 * Prefetched Index Value Register +
991 * Control Register */
992 r = &s->bm_regs[GET_BM (index)];
993 *pu32 = r->picb | (r->piv << 16) | (r->cr << 24);
994 Log (("ac97: PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM (index),
995 *pu32, r->picb, r->piv, r->cr));
996 break;
997 case GLOB_CNT:
998 /* Global Control */
999 *pu32 = s->glob_cnt;
1000 Log (("ac97: glob_cnt -> %#x\n", *pu32));
1001 break;
1002 case GLOB_STA:
1003 /* Global Status */
1004 *pu32 = s->glob_sta | GS_S0CR;
1005 Log (("ac97: glob_sta -> %#x\n", *pu32));
1006 break;
1007 default:
1008 Log (("ac97: U nabm readl %#x -> %#x\n", Port, *pu32));
1009 break;
1010 }
1011 break;
1012 }
1013
1014 default:
1015 return VERR_IOM_IOPORT_UNUSED;
1016 }
1017 return VINF_SUCCESS;
1018}
1019
1020/**
1021 * Port I/O Handler for OUT operations.
1022 *
1023 * @returns VBox status code.
1024 *
1025 * @param pDevIns The device instance.
1026 * @param pvUser User argument.
1027 * @param uPort Port number used for the IN operation.
1028 * @param u32 The value to output.
1029 * @param cb The value size in bytes.
1030 */
1031static DECLCALLBACK(int) ichac97IOPortNABMWrite (PPDMDEVINS pDevIns, void *pvUser,
1032 RTIOPORT Port, uint32_t u32, unsigned cb)
1033{
1034 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
1035 AC97LinkState *s = &d->ac97;
1036
1037 switch (cb)
1038 {
1039 case 1:
1040 {
1041 AC97BusMasterRegs *r = NULL;
1042 uint32_t index = Port - d->ac97.IOPortBase[1];
1043 switch (index)
1044 {
1045 case PI_LVI:
1046 case PO_LVI:
1047 case MC_LVI:
1048 /* Last Valid Index */
1049 r = &s->bm_regs[GET_BM (index)];
1050 if ((r->cr & CR_RPBM) && (r->sr & SR_DCH)) {
1051 r->sr &= ~(SR_DCH | SR_CELV);
1052 r->civ = r->piv;
1053 r->piv = (r->piv + 1) % 32;
1054 fetch_bd (s, r);
1055 }
1056 r->lvi = u32 % 32;
1057 Log (("ac97: LVI[%d] <- %#x\n", GET_BM (index), u32));
1058 break;
1059 case PI_CR:
1060 case PO_CR:
1061 case MC_CR:
1062 /* Control Register */
1063 r = &s->bm_regs[GET_BM (index)];
1064 if (u32 & CR_RR)
1065 reset_bm_regs (s, r);
1066 else
1067 {
1068 r->cr = u32 & CR_VALID_MASK;
1069 if (!(r->cr & CR_RPBM))
1070 {
1071 voice_set_active (s, r - s->bm_regs, 0);
1072 r->sr |= SR_DCH;
1073 }
1074 else
1075 {
1076 r->civ = r->piv;
1077 r->piv = (r->piv + 1) % 32;
1078 fetch_bd (s, r);
1079 r->sr &= ~SR_DCH;
1080 voice_set_active (s, r - s->bm_regs, 1);
1081 }
1082 }
1083 Log (("ac97: CR[%d] <- %#x (cr %#x)\n", GET_BM (index), u32, r->cr));
1084 break;
1085 case PI_SR:
1086 case PO_SR:
1087 case MC_SR:
1088 /* Status Register */
1089 r = &s->bm_regs[GET_BM (index)];
1090 r->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK);
1091 update_sr (s, r, r->sr & ~(u32 & SR_WCLEAR_MASK));
1092 Log (("ac97: SR[%d] <- %#x (sr %#x)\n", GET_BM (index), u32, r->sr));
1093 break;
1094 default:
1095 Log (("ac97: U nabm writeb %#x <- %#x\n", Port, u32));
1096 break;
1097 }
1098 break;
1099 }
1100
1101 case 2:
1102 {
1103 AC97BusMasterRegs *r = NULL;
1104 uint32_t index = Port - d->ac97.IOPortBase[1];
1105 switch (index)
1106 {
1107 case PI_SR:
1108 case PO_SR:
1109 case MC_SR:
1110 /* Status Register */
1111 r = &s->bm_regs[GET_BM (index)];
1112 r->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK);
1113 update_sr (s, r, r->sr & ~(u32 & SR_WCLEAR_MASK));
1114 Log (("ac97: SR[%d] <- %#x (sr %#x)\n", GET_BM (index), u32, r->sr));
1115 break;
1116 default:
1117 Log (("ac97: U nabm writew %#x <- %#x\n", Port, u32));
1118 break;
1119 }
1120 break;
1121 }
1122
1123 case 4:
1124 {
1125 AC97BusMasterRegs *r = NULL;
1126 uint32_t index = Port - d->ac97.IOPortBase[1];
1127 switch (index)
1128 {
1129 case PI_BDBAR:
1130 case PO_BDBAR:
1131 case MC_BDBAR:
1132 /* Buffer Descriptor list Base Address Register */
1133 r = &s->bm_regs[GET_BM (index)];
1134 r->bdbar = u32 & ~3;
1135 Log (("ac97: BDBAR[%d] <- %#x (bdbar %#x)\n",
1136 GET_BM (index), u32, r->bdbar));
1137 break;
1138 case GLOB_CNT:
1139 /* Global Control */
1140 if (u32 & GC_WR)
1141 warm_reset (s);
1142 if (u32 & GC_CR)
1143 cold_reset (s);
1144 if (!(u32 & (GC_WR | GC_CR)))
1145 s->glob_cnt = u32 & GC_VALID_MASK;
1146 Log (("ac97: glob_cnt <- %#x (glob_cnt %#x)\n", u32, s->glob_cnt));
1147 break;
1148 case GLOB_STA:
1149 /* Global Status */
1150 s->glob_sta &= ~(u32 & GS_WCLEAR_MASK);
1151 s->glob_sta |= (u32 & ~(GS_WCLEAR_MASK | GS_RO_MASK)) & GS_VALID_MASK;
1152 Log (("ac97: glob_sta <- %#x (glob_sta %#x)\n", u32, s->glob_sta));
1153 break;
1154 default:
1155 Log (("ac97: U nabm writel %#x <- %#x\n", Port, u32));
1156 break;
1157 }
1158 break;
1159 }
1160
1161 default:
1162 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
1163 break;
1164 }
1165 return VINF_SUCCESS;
1166}
1167
1168/**
1169 * Port I/O Handler for IN operations.
1170 *
1171 * @returns VBox status code.
1172 *
1173 * @param pDevIns The device instance.
1174 * @param pvUser User argument.
1175 * @param uPort Port number used for the IN operation.
1176 * @param pu32 Where to store the result.
1177 * @param cb Number of bytes read.
1178 */
1179static DECLCALLBACK(int) ichac97IOPortNAMRead (PPDMDEVINS pDevIns, void *pvUser,
1180 RTIOPORT Port, uint32_t *pu32, unsigned cb)
1181{
1182 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
1183 AC97LinkState *s = &d->ac97;
1184
1185 switch (cb)
1186 {
1187 case 1:
1188 {
1189 Log (("ac97: U nam readb %#x\n", Port));
1190 s->cas = 0;
1191 *pu32 = ~0U;
1192 break;
1193 }
1194
1195 case 2:
1196 {
1197 uint32_t index = Port - d->ac97.IOPortBase[0];
1198 *pu32 = ~0U;
1199 s->cas = 0;
1200 switch (index)
1201 {
1202 default:
1203 *pu32 = mixer_load (s, index);
1204 Log (("ac97: nam readw %#x -> %#x\n", Port, *pu32));
1205 break;
1206 }
1207 break;
1208 }
1209
1210 case 4:
1211 {
1212 Log (("ac97: U nam readl %#x\n", Port));
1213 s->cas = 0;
1214 *pu32 = ~0U;
1215 break;
1216 }
1217
1218 default:
1219 return VERR_IOM_IOPORT_UNUSED;
1220 }
1221 return VINF_SUCCESS;
1222}
1223
1224/**
1225 * Port I/O Handler for OUT operations.
1226 *
1227 * @returns VBox status code.
1228 *
1229 * @param pDevIns The device instance.
1230 * @param pvUser User argument.
1231 * @param uPort Port number used for the IN operation.
1232 * @param u32 The value to output.
1233 * @param cb The value size in bytes.
1234 */
1235static DECLCALLBACK(int) ichac97IOPortNAMWrite (PPDMDEVINS pDevIns, void *pvUser,
1236 RTIOPORT Port, uint32_t u32, unsigned cb)
1237{
1238 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
1239 AC97LinkState *s = &d->ac97;
1240
1241 switch (cb)
1242 {
1243 case 1:
1244 {
1245 Log (("ac97: U nam writeb %#x <- %#x\n", Port, u32));
1246 s->cas = 0;
1247 break;
1248 }
1249
1250 case 2:
1251 {
1252 uint32_t index = Port - d->ac97.IOPortBase[0];
1253 s->cas = 0;
1254 switch (index)
1255 {
1256 case AC97_Reset:
1257 mixer_reset (s);
1258 break;
1259 case AC97_Powerdown_Ctrl_Stat:
1260 u32 &= ~0xf;
1261 u32 |= mixer_load (s, index) & 0xf;
1262 mixer_store (s, index, u32);
1263 break;
1264#ifdef USE_MIXER
1265 case AC97_Master_Volume_Mute:
1266 set_volume (s, index, AUD_MIXER_VOLUME, u32);
1267 break;
1268 case AC97_PCM_Out_Volume_Mute:
1269 set_volume (s, index, AUD_MIXER_PCM, u32);
1270 break;
1271 case AC97_Line_In_Volume_Mute:
1272 set_volume (s, index, AUD_MIXER_LINE_IN, u32);
1273 break;
1274 case AC97_Record_Select:
1275 record_select (s, u32);
1276 break;
1277#else /* !USE_MIXER */
1278 case AC97_Master_Volume_Mute:
1279 case AC97_PCM_Out_Volume_Mute:
1280 case AC97_Line_In_Volume_Mute:
1281 case AC97_Record_Select:
1282 mixer_store (s, index, u32);
1283 break;
1284#endif /* !USE_MIXER */
1285 case AC97_Vendor_ID1:
1286 case AC97_Vendor_ID2:
1287 Log (("ac97: Attempt to write vendor ID to %#x\n", u32));
1288 break;
1289 case AC97_Extended_Audio_ID:
1290 Log (("ac97: Attempt to write extended audio ID to %#x\n", u32));
1291 break;
1292 case AC97_Extended_Audio_Ctrl_Stat:
1293 if (!(u32 & EACS_VRA))
1294 {
1295 mixer_store (s, AC97_PCM_Front_DAC_Rate, 0xbb80);
1296 mixer_store (s, AC97_PCM_LR_ADC_Rate, 0xbb80);
1297 open_voice (s, PI_INDEX, 48000);
1298 open_voice (s, PO_INDEX, 48000);
1299 }
1300 if (!(u32 & EACS_VRM))
1301 {
1302 mixer_store (s, AC97_MIC_ADC_Rate, 0xbb80);
1303 open_voice (s, MC_INDEX, 48000);
1304 }
1305 Log (("ac97: Setting extended audio control to %#x\n", u32));
1306 mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, u32);
1307 break;
1308 case AC97_PCM_Front_DAC_Rate:
1309 if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
1310 {
1311 mixer_store (s, index, u32);
1312 Log(("ac97: Set front DAC rate to %d\n", u32));
1313 open_voice (s, PO_INDEX, u32);
1314 }
1315 else
1316 {
1317 Log (("ac97: Attempt to set front DAC rate to %d, "
1318 "but VRA is not set\n",
1319 u32));
1320 }
1321 break;
1322 case AC97_MIC_ADC_Rate:
1323 if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM)
1324 {
1325 mixer_store (s, index, u32);
1326 Log (("ac97: Set MIC ADC rate to %d\n", u32));
1327 open_voice (s, MC_INDEX, u32);
1328 }
1329 else
1330 {
1331 Log (("ac97: Attempt to set MIC ADC rate to %d, "
1332 "but VRM is not set\n",
1333 u32));
1334 }
1335 break;
1336 case AC97_PCM_LR_ADC_Rate:
1337 if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
1338 {
1339 mixer_store (s, index, u32);
1340 Log (("ac97: Set front LR ADC rate to %d\n", u32));
1341 open_voice (s, PI_INDEX, u32);
1342 }
1343 else
1344 {
1345 Log (("ac97: Attempt to set LR ADC rate to %d, but VRA is not set\n",
1346 u32));
1347 }
1348 break;
1349 default:
1350 Log (("ac97: U nam writew %#x <- %#x\n", Port, u32));
1351 mixer_store (s, index, u32);
1352 break;
1353 }
1354 break;
1355 }
1356
1357 case 4:
1358 {
1359 Log (("ac97: U nam writel %#x <- %#x\n", Port, u32));
1360 s->cas = 0;
1361 break;
1362 }
1363
1364 default:
1365 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
1366 break;
1367 }
1368 return VINF_SUCCESS;
1369}
1370
1371/**
1372 * Callback function for mapping a PCI I/O region.
1373 *
1374 * @return VBox status code.
1375 * @param pPciDev Pointer to PCI device.
1376 * Use pPciDev->pDevIns to get the device instance.
1377 * @param iRegion The region number.
1378 * @param GCPhysAddress Physical address of the region.
1379 * If iType is PCI_ADDRESS_SPACE_IO, this is an
1380 * I/O port, else it's a physical address.
1381 * This address is *NOT* relative
1382 * to pci_mem_base like earlier!
1383 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
1384 */
1385static DECLCALLBACK(int) ichac97IOPortMap (PPCIDEVICE pPciDev, int iRegion,
1386 RTGCPHYS GCPhysAddress, uint32_t cb,
1387 PCIADDRESSSPACE enmType)
1388{
1389 int rc;
1390 PPDMDEVINS pDevIns = pPciDev->pDevIns;
1391 RTIOPORT Port = (RTIOPORT)GCPhysAddress;
1392 PCIAC97LinkState *pThis = PCIDEV_2_ICHAC97STATE(pPciDev);
1393
1394 Assert(enmType == PCI_ADDRESS_SPACE_IO);
1395 Assert(cb >= 0x20);
1396
1397 if (iRegion == 0)
1398 rc = PDMDevHlpIOPortRegister (pDevIns, Port, 256, pThis,
1399 ichac97IOPortNAMWrite, ichac97IOPortNAMRead,
1400 NULL, NULL, "ICHAC97 NAM");
1401 else
1402 rc = PDMDevHlpIOPortRegister (pDevIns, Port, 64, pThis,
1403 ichac97IOPortNABMWrite, ichac97IOPortNABMRead,
1404 NULL, NULL, "ICHAC97 NABM");
1405 if (RT_FAILURE(rc))
1406 return rc;
1407
1408 pThis->ac97.IOPortBase[iRegion] = Port;
1409 return VINF_SUCCESS;
1410}
1411
1412/**
1413 * Saves a state of the AC'97 device.
1414 *
1415 * @returns VBox status code.
1416 * @param pDevIns The device instance.
1417 * @param pSSMHandle The handle to save the state to.
1418 */
1419static DECLCALLBACK(int) ichac97SaveExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
1420{
1421 PCIAC97LinkState *pThis = PDMINS_2_DATA(pDevIns, PCIAC97LinkState *);
1422 size_t i;
1423 uint8_t active[LAST_INDEX];
1424 AC97LinkState *s = &pThis->ac97;
1425
1426 SSMR3PutU32 (pSSMHandle, s->glob_cnt);
1427 SSMR3PutU32 (pSSMHandle, s->glob_sta);
1428 SSMR3PutU32 (pSSMHandle, s->cas);
1429
1430 for (i = 0; i < sizeof (s->bm_regs) / sizeof (s->bm_regs[0]); ++i)
1431 {
1432 AC97BusMasterRegs *r = &s->bm_regs[i];
1433 SSMR3PutU32 (pSSMHandle, r->bdbar);
1434 SSMR3PutU8 (pSSMHandle, r->civ);
1435 SSMR3PutU8 (pSSMHandle, r->lvi);
1436 SSMR3PutU16 (pSSMHandle, r->sr);
1437 SSMR3PutU16 (pSSMHandle, r->picb);
1438 SSMR3PutU8 (pSSMHandle, r->piv);
1439 SSMR3PutU8 (pSSMHandle, r->cr);
1440 SSMR3PutS32 (pSSMHandle, r->bd_valid);
1441 SSMR3PutU32 (pSSMHandle, r->bd.addr);
1442 SSMR3PutU32 (pSSMHandle, r->bd.ctl_len);
1443 }
1444 SSMR3PutMem (pSSMHandle, s->mixer_data, sizeof (s->mixer_data));
1445
1446 active[PI_INDEX] = AUD_is_active_in (s->voice_pi) ? 1 : 0;
1447 active[PO_INDEX] = AUD_is_active_out (s->voice_po) ? 1 : 0;
1448 active[MC_INDEX] = AUD_is_active_in (s->voice_mc) ? 1 : 0;
1449 SSMR3PutMem (pSSMHandle, active, sizeof (active));
1450
1451 return VINF_SUCCESS;
1452}
1453
1454/**
1455 * Loads a saved AC'97 device state.
1456 *
1457 * @returns VBox status code.
1458 * @param pDevIns The device instance.
1459 * @param pSSMHandle The handle to the saved state.
1460 * @param u32Version The data unit version number.
1461 */
1462static DECLCALLBACK(int) ichac97LoadExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle,
1463 uint32_t u32Version)
1464{
1465 PCIAC97LinkState *pThis = PDMINS_2_DATA(pDevIns, PCIAC97LinkState *);
1466 size_t i;
1467 uint8_t active[LAST_INDEX];
1468 AC97LinkState *s = &pThis->ac97;
1469
1470 if (u32Version != AC97_SSM_VERSION)
1471 {
1472 AssertFailed();
1473 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
1474 }
1475
1476 SSMR3GetU32 (pSSMHandle, &s->glob_cnt);
1477 SSMR3GetU32 (pSSMHandle, &s->glob_sta);
1478 SSMR3GetU32 (pSSMHandle, &s->cas);
1479
1480 for (i = 0; i < sizeof (s->bm_regs) / sizeof (s->bm_regs[0]); ++i)
1481 {
1482 AC97BusMasterRegs *r = &s->bm_regs[i];
1483 SSMR3GetU32 (pSSMHandle, &r->bdbar);
1484 SSMR3GetU8 (pSSMHandle, &r->civ);
1485 SSMR3GetU8 (pSSMHandle, &r->lvi);
1486 SSMR3GetU16 (pSSMHandle, &r->sr);
1487 SSMR3GetU16 (pSSMHandle, &r->picb);
1488 SSMR3GetU8 (pSSMHandle, &r->piv);
1489 SSMR3GetU8 (pSSMHandle, &r->cr);
1490 SSMR3GetS32 (pSSMHandle, &r->bd_valid);
1491 SSMR3GetU32 (pSSMHandle, &r->bd.addr);
1492 SSMR3GetU32 (pSSMHandle, &r->bd.ctl_len);
1493 }
1494 SSMR3GetMem (pSSMHandle, s->mixer_data, sizeof (s->mixer_data));
1495 SSMR3GetMem (pSSMHandle, active, sizeof (active));
1496
1497#ifdef USE_MIXER
1498 record_select (s, mixer_load (s, AC97_Record_Select));
1499# define V_(a, b) set_volume (s, a, b, mixer_load (s, a))
1500 V_ (AC97_Master_Volume_Mute, AUD_MIXER_VOLUME);
1501 V_ (AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM);
1502 V_ (AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN);
1503# undef V_
1504#endif /* USE_MIXER */
1505 reset_voices (s, active);
1506
1507 s->bup_flag = 0;
1508 s->last_samp = 0;
1509
1510 return VINF_SUCCESS;
1511}
1512
1513/**
1514 * Reset notification.
1515 *
1516 * @returns VBox status.
1517 * @param pDevIns The device instance data.
1518 *
1519 * @remark The original sources didn't install a reset handler, but it seems to
1520 * make sense to me so we'll do it.
1521 */
1522static DECLCALLBACK(void) ac97Reset (PPDMDEVINS pDevIns)
1523{
1524 PCIAC97LinkState *pThis = PDMINS_2_DATA(pDevIns, PCIAC97LinkState *);
1525
1526 /*
1527 * Reset the device state (will need pDrv later).
1528 */
1529 reset_bm_regs (&pThis->ac97, &pThis->ac97.bm_regs[0]);
1530 reset_bm_regs (&pThis->ac97, &pThis->ac97.bm_regs[1]);
1531 reset_bm_regs (&pThis->ac97, &pThis->ac97.bm_regs[2]);
1532
1533 /*
1534 * Reset the mixer too. The Windows XP driver seems to rely on
1535 * this. At least it wants to read the vendor id before it resets
1536 * the codec manually.
1537 */
1538 mixer_reset (&pThis->ac97);
1539}
1540
1541/**
1542 * Queries an interface to the driver.
1543 *
1544 * @returns Pointer to interface.
1545 * @returns NULL if the interface was not supported by the driver.
1546 * @param pInterface Pointer to this interface structure.
1547 * @param enmInterface The requested interface identification.
1548 * @thread Any thread.
1549 */
1550static DECLCALLBACK(void *) ichac97QueryInterface (struct PDMIBASE *pInterface,
1551 PDMINTERFACE enmInterface)
1552{
1553 PCIAC97LinkState *pThis =
1554 (PCIAC97LinkState *)((uintptr_t)pInterface
1555 - RT_OFFSETOF(PCIAC97LinkState, ac97.IBase));
1556 Assert(&pThis->ac97.IBase == pInterface);
1557 switch (enmInterface)
1558 {
1559 case PDMINTERFACE_BASE:
1560 return &pThis->ac97.IBase;
1561 default:
1562 return NULL;
1563 }
1564}
1565
1566/**
1567 * Construct a device instance for a VM.
1568 *
1569 * @returns VBox status.
1570 * @param pDevIns The device instance data.
1571 * If the registration structure is needed,
1572 * pDevIns->pDevReg points to it.
1573 * @param iInstance Instance number. Use this to figure out which
1574 * registers and such to use.
1575 * The device number is also found in pDevIns->iInstance,
1576 * but since it's likely to be freqently used PDM passes
1577 * it as parameter.
1578 * @param pCfgHandle Configuration node handle for the device.
1579 * Use this to obtain the configuration
1580 * of the device instance. It's also found in
1581 * pDevIns->pCfgHandle, but like iInstance it's expected
1582 * to be used a bit in this function.
1583 */
1584static DECLCALLBACK(int) ichac97Construct (PPDMDEVINS pDevIns, int iInstance,
1585 PCFGMNODE pCfgHandle)
1586{
1587 PCIAC97LinkState *pThis = PDMINS_2_DATA(pDevIns, PCIAC97LinkState *);
1588 AC97LinkState *s = &pThis->ac97;
1589 int rc;
1590
1591 Assert(iInstance == 0);
1592
1593 /*
1594 * Initialize data (most of it anyway).
1595 */
1596 s->pDevIns = pDevIns;
1597 /* IBase */
1598 s->IBase.pfnQueryInterface = ichac97QueryInterface;
1599
1600 /* PCI Device (the assertions will be removed later) */
1601 PCIDevSetVendorId (&pThis->dev, 0x8086); /* 00 ro - intel. */ Assert (pThis->dev.config[0x00] == 0x86); Assert (pThis->dev.config[0x01] == 0x80);
1602 PCIDevSetDeviceId (&pThis->dev, 0x2415); /* 02 ro - 82801 / 82801aa(?). */Assert (pThis->dev.config[0x02] == 0x15); Assert (pThis->dev.config[0x03] == 0x24);
1603 PCIDevSetCommand (&pThis->dev, 0x0000); /* 04 rw,ro - pcicmd. */ Assert (pThis->dev.config[0x04] == 0x00); Assert (pThis->dev.config[0x05] == 0x00);
1604 PCIDevSetStatus (&pThis->dev, 0x0280); /* 06 rwc?,ro? - pcists. */ Assert (pThis->dev.config[0x06] == 0x80); Assert (pThis->dev.config[0x07] == 0x02);
1605 PCIDevSetRevisionId (&pThis->dev, 0x01); /* 08 ro - rid. */ Assert (pThis->dev.config[0x08] == 0x01);
1606 PCIDevSetClassProg (&pThis->dev, 0x00); /* 09 ro - pi. */ Assert (pThis->dev.config[0x09] == 0x00);
1607 PCIDevSetClassSub (&pThis->dev, 0x01); /* 0a ro - scc; 01 == Audio. */ Assert (pThis->dev.config[0x0a] == 0x01);
1608 PCIDevSetClassBase (&pThis->dev, 0x04); /* 0b ro - bcc; 04 == multimedia. */ Assert (pThis->dev.config[0x0b] == 0x04);
1609 PCIDevSetHeaderType (&pThis->dev, 0x00); /* 0e ro - headtyp. */ Assert (pThis->dev.config[0x0e] == 0x00);
1610 PCIDevSetBaseAddress (&pThis->dev, 0, /* 10 rw - nambar - native audio mixer base. */
1611 true /* fIoSpace */, false /* fPrefetchable */, false /* f64Bit */, 0x00000000); Assert (pThis->dev.config[0x10] == 0x01); Assert (pThis->dev.config[0x11] == 0x00); Assert (pThis->dev.config[0x12] == 0x00); Assert (pThis->dev.config[0x13] == 0x00);
1612 PCIDevSetBaseAddress (&pThis->dev, 1, /* 14 rw - nabmbar - native audio bus mastering. */
1613 true /* fIoSpace */, false /* fPrefetchable */, false /* f64Bit */, 0x00000000); Assert (pThis->dev.config[0x14] == 0x01); Assert (pThis->dev.config[0x15] == 0x00); Assert (pThis->dev.config[0x16] == 0x00); Assert (pThis->dev.config[0x17] == 0x00);
1614 PCIDevSetSubSystemVendorId (&pThis->dev, 0x8086); /* 2c ro - intel.) */ Assert (pThis->dev.config[0x2c] == 0x86); Assert (pThis->dev.config[0x2d] == 0x80);
1615 PCIDevSetSubSystemId (&pThis->dev, 0x0000); /* 2e ro. */ Assert (pThis->dev.config[0x2e] == 0x00); Assert (pThis->dev.config[0x2f] == 0x00);
1616 PCIDevSetInterruptLine (&pThis->dev, 0x00); /* 3c rw. */ Assert (pThis->dev.config[0x3c] == 0x00);
1617 PCIDevSetInterruptPin (&pThis->dev, 0x01); /* 3d ro - INTA#. */ Assert (pThis->dev.config[0x3d] == 0x01);
1618
1619 /*
1620 * Register the PCI device, it's I/O regions, the timer and the
1621 * saved state item.
1622 */
1623 rc = PDMDevHlpPCIRegister (pDevIns, &pThis->dev);
1624 if (RT_FAILURE (rc))
1625 return rc;
1626
1627 rc = PDMDevHlpPCIIORegionRegister (pDevIns, 0, 256, PCI_ADDRESS_SPACE_IO,
1628 ichac97IOPortMap);
1629 if (RT_FAILURE (rc))
1630 return rc;
1631
1632 rc = PDMDevHlpPCIIORegionRegister (pDevIns, 1, 64, PCI_ADDRESS_SPACE_IO,
1633 ichac97IOPortMap);
1634 if (RT_FAILURE (rc))
1635 return rc;
1636
1637 rc = PDMDevHlpSSMRegister (pDevIns, pDevIns->pDevReg->szDeviceName,
1638 iInstance, AC97_SSM_VERSION, sizeof(*pThis),
1639 NULL, ichac97SaveExec, NULL,
1640 NULL, ichac97LoadExec, NULL);
1641 if (RT_FAILURE (rc))
1642 return rc;
1643
1644 /*
1645 * Attach driver.
1646 */
1647 rc = PDMDevHlpDriverAttach (pDevIns, 0, &s->IBase,
1648 &s->pDrvBase, "Audio Driver Port");
1649 if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
1650 Log (("ac97: No attached driver!\n"));
1651 else if (RT_FAILURE (rc))
1652 {
1653 AssertMsgFailed (("Failed to attach AC97 LUN #0! rc=%Rrc\n", rc));
1654 return rc;
1655 }
1656
1657 AUD_register_card ("ICH0", &s->card);
1658
1659 ac97Reset (pDevIns);
1660
1661#ifndef RT_OS_DARWIN /* coreaudio doesn't supply these. */
1662 if (!s->voice_pi)
1663 LogRel (("AC97: WARNING: Unable to open PCM IN!\n"));
1664 if (!s->voice_mc)
1665 LogRel (("AC97: WARNING: Unable to open PCM MC!\n"));
1666#endif
1667 if (!s->voice_po)
1668 LogRel (("AC97: WARNING: Unable to open PCM OUT!\n"));
1669
1670 if (!s->voice_pi && !s->voice_po && !s->voice_mc)
1671 {
1672 /* Was not able initialize *any* voice. Select the NULL audio driver instead */
1673 AUD_close_in (&s->card, s->voice_pi);
1674 AUD_close_out (&s->card, s->voice_po);
1675 AUD_close_in (&s->card, s->voice_mc);
1676 s->voice_po = NULL;
1677 s->voice_pi = NULL;
1678 s->voice_mc = NULL;
1679 AUD_init_null ();
1680 ac97Reset (pDevIns);
1681
1682 PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
1683 N_ ("No audio devices could be opened. Selecting the NULL audio backend "
1684 "with the consequence that no sound is audible"));
1685 }
1686#ifndef RT_OS_DARWIN
1687 else if (!s->voice_pi || !s->voice_po || !s->voice_mc)
1688 {
1689 char szMissingVoices[128];
1690 size_t len = 0;
1691 if (!s->voice_pi)
1692 len = RTStrPrintf (szMissingVoices, sizeof(szMissingVoices), "PCM_in");
1693 if (!s->voice_po)
1694 len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_out" : "PCM_out");
1695 if (!s->voice_mc)
1696 len += RTStrPrintf (szMissingVoices + len, sizeof(szMissingVoices) - len, len ? ", PCM_mic" : "PCM_mic");
1697
1698 PDMDevHlpVMSetRuntimeError (pDevIns, 0 /*fFlags*/, "HostAudioNotResponding",
1699 N_ ("Some audio devices (%s) could not be opened. Guest applications generating audio "
1700 "output or depending on audio input may hang. Make sure your host audio device "
1701 "is working properly. Check the logfile for error messages of the audio "
1702 "subsystem"), szMissingVoices);
1703 }
1704#endif
1705
1706 return VINF_SUCCESS;
1707}
1708
1709/**
1710 * The device registration structure.
1711 */
1712const PDMDEVREG g_DeviceICHAC97 =
1713{
1714 /* u32Version */
1715 PDM_DEVREG_VERSION,
1716 /* szDeviceName */
1717 "ichac97",
1718 /* szRCMod */
1719 "",
1720 /* szR0Mod */
1721 "",
1722 /* pszDescription */
1723 "ICH AC'97 Audio Controller",
1724 /* fFlags */
1725 PDM_DEVREG_FLAGS_DEFAULT_BITS,
1726 /* fClass */
1727 PDM_DEVREG_CLASS_AUDIO,
1728 /* cMaxInstances */
1729 1,
1730 /* cbInstance */
1731 sizeof(PCIAC97LinkState),
1732 /* pfnConstruct */
1733 ichac97Construct,
1734 /* pfnDestruct */
1735 NULL,
1736 /* pfnRelocate */
1737 NULL,
1738 /* pfnIOCtl */
1739 NULL,
1740 /* pfnPowerOn */
1741 NULL,
1742 /* pfnReset */
1743 ac97Reset,
1744 /* pfnSuspend */
1745 NULL,
1746 /* pfnResume */
1747 NULL,
1748 /* pfnAttach */
1749 NULL,
1750 /* pfnDetach */
1751 NULL,
1752 /* pfnQueryInterface. */
1753 NULL,
1754 /* pfnInitComplete */
1755 NULL,
1756 /* pfnPowerOff */
1757 NULL,
1758 /* pfnSoftReset */
1759 NULL,
1760 /* u32VersionEnd */
1761 PDM_DEVREG_VERSION
1762};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette