VirtualBox

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

Last change on this file since 4672 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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