VirtualBox

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

Last change on this file since 34828 was 33676, checked in by vboxsync, 14 years ago

scm cleanup run.

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