VirtualBox

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

Last change on this file since 5085 was 5003, checked in by vboxsync, 17 years ago

Clear interrupt flag in global status register when the engine status register is updated

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 56.3 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 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
485static void set_volume (AC97LinkState *s, int index,
486 audmixerctl_t mt, uint32_t val)
487{
488 int mute = (val >> MUTE_SHIFT) & 1;
489 uint8_t rvol = VOL_MASK - (val & VOL_MASK);
490 uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK);
491 rvol = 255 * rvol / VOL_MASK;
492 lvol = 255 * lvol / VOL_MASK;
493
494#ifdef SOFT_VOLUME
495 if (index == AC97_Master_Volume_Mute)
496 AUD_set_volume_out (s->voice_po, mute, lvol, rvol);
497 else
498 AUD_set_volume (mt, &mute, &lvol, &rvol);
499#else
500 AUD_set_volume (mt, &mute, &lvol, &rvol);
501#endif
502
503 rvol = VOL_MASK - ((VOL_MASK * rvol) / 255);
504 lvol = VOL_MASK - ((VOL_MASK * lvol) / 255);
505
506#ifdef VBOX
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 & BIT(5))
516 val |= BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0);
517 if (val & BIT(13))
518 val |= BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8);
519#endif
520
521 mixer_store (s, index, val);
522}
523
524static audrecsource_t ac97_to_aud_record_source (uint8_t i)
525{
526 switch (i)
527 {
528 case REC_MIC: return AUD_REC_MIC;
529 case REC_CD: return AUD_REC_CD;
530 case REC_VIDEO: return AUD_REC_VIDEO;
531 case REC_AUX: return AUD_REC_AUX;
532 case REC_LINE_IN: return AUD_REC_LINE_IN;
533 case REC_PHONE: return AUD_REC_PHONE;
534 default: Log (("ac97: Unknown record source %d, using MIC\n", i));
535 return AUD_REC_MIC;
536 }
537}
538
539static uint8_t aud_to_ac97_record_source (audrecsource_t rs)
540{
541 switch (rs)
542 {
543 case AUD_REC_MIC: return REC_MIC;
544 case AUD_REC_CD: return REC_CD;
545 case AUD_REC_VIDEO: return REC_VIDEO;
546 case AUD_REC_AUX: return REC_AUX;
547 case AUD_REC_LINE_IN: return REC_LINE_IN;
548 case AUD_REC_PHONE: return REC_PHONE;
549 default: Log (("ac97: Unknown audio recording source %d using MIC\n", rs));
550 return REC_MIC;
551 }
552}
553
554static void record_select (AC97LinkState *s, uint32_t val)
555{
556 uint8_t rs = val & REC_MASK;
557 uint8_t ls = (val >> 8) & REC_MASK;
558 audrecsource_t ars = ac97_to_aud_record_source (rs);
559 audrecsource_t als = ac97_to_aud_record_source (ls);
560 AUD_set_record_source (&als, &ars);
561 rs = aud_to_ac97_record_source (ars);
562 ls = aud_to_ac97_record_source (als);
563 mixer_store (s, AC97_Record_Select, rs | (ls << 8));
564}
565#endif
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\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 return;
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 r->picb -= (temp >> 1);
792 break;
793
794 case PI_INDEX:
795 case MC_INDEX:
796 temp = read_audio (s, r, elapsed, &stop);
797 elapsed -= temp;
798 r->picb -= (temp >> 1);
799 break;
800 }
801
802 Log(("r->picb = %d\n", r->picb));
803
804 if (!r->picb)
805 {
806 uint32_t new_sr = r->sr & ~SR_CELV;
807
808 if (r->bd.ctl_len & BD_IOC)
809 new_sr |= SR_BCIS;
810
811 if (r->civ == r->lvi)
812 {
813 Log (("ac97: Underrun civ (%d) == lvi (%d)\n", r->civ, r->lvi));
814 new_sr |= SR_LVBCI | SR_DCH | SR_CELV;
815 stop = 1;
816 s->bup_flag = (r->bd.ctl_len & BD_BUP) ? BUP_LAST : 0;
817 }
818 else
819 {
820 r->civ = r->piv;
821 r->piv = (r->piv + 1) % 32;
822 fetch_bd (s, r);
823 }
824 update_sr (s, r, new_sr);
825 }
826 }
827}
828
829static void pi_callback (void *opaque, int avail)
830{
831 transfer_audio ((AC97LinkState*)opaque, PI_INDEX, avail);
832}
833
834static void mc_callback (void *opaque, int avail)
835{
836 transfer_audio ((AC97LinkState*)opaque, MC_INDEX, avail);
837}
838
839static void po_callback (void *opaque, int free)
840{
841 transfer_audio ((AC97LinkState*)opaque, PO_INDEX, free);
842}
843
844/**
845 * Port I/O Handler for IN operations.
846 *
847 * @returns VBox status code.
848 *
849 * @param pDevIns The device instance.
850 * @param pvUser User argument.
851 * @param uPort Port number used for the IN operation.
852 * @param pu32 Where to store the result.
853 * @param cb Number of bytes read.
854 */
855static DECLCALLBACK(int) ichac97IOPortNABMRead (PPDMDEVINS pDevIns, void *pvUser,
856 RTIOPORT Port, uint32_t *pu32, unsigned cb)
857{
858 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
859 AC97LinkState *s = &d->ac97;
860
861 switch (cb)
862 {
863 case 1:
864 {
865 AC97BusMasterRegs *r = NULL;
866 uint32_t index = Port - d->ac97.IOPortBase[1];
867 *pu32 = ~0U;
868
869 switch (index)
870 {
871 case CAS:
872 /* Codec Access Semaphore Register */
873 Log (("ac97: CAS %d\n", s->cas));
874 *pu32 = s->cas;
875 s->cas = 1;
876 break;
877 case PI_CIV:
878 case PO_CIV:
879 case MC_CIV:
880 /* Current Index Value Register */
881 r = &s->bm_regs[GET_BM (index)];
882 *pu32 = r->civ;
883 Log (("ac97: CIV[%d] -> %#x\n", GET_BM (index), *pu32));
884 break;
885 case PI_LVI:
886 case PO_LVI:
887 case MC_LVI:
888 /* Last Valid Index Register */
889 r = &s->bm_regs[GET_BM (index)];
890 *pu32 = r->lvi;
891 Log (("ac97: LVI[%d] -> %#x\n", GET_BM (index), *pu32));
892 break;
893 case PI_PIV:
894 case PO_PIV:
895 case MC_PIV:
896 /* Prefetched Index Value Register */
897 r = &s->bm_regs[GET_BM (index)];
898 *pu32 = r->piv;
899 Log (("ac97: PIV[%d] -> %#x\n", GET_BM (index), *pu32));
900 break;
901 case PI_CR:
902 case PO_CR:
903 case MC_CR:
904 /* Control Register */
905 r = &s->bm_regs[GET_BM (index)];
906 *pu32 = r->cr;
907 Log (("ac97: CR[%d] -> %#x\n", GET_BM (index), *pu32));
908 break;
909 case PI_SR:
910 case PO_SR:
911 case MC_SR:
912 /* Status Register (lower part) */
913 r = &s->bm_regs[GET_BM (index)];
914 *pu32 = r->sr & 0xff;
915 Log (("ac97: SRb[%d] -> %#x\n", GET_BM (index), *pu32));
916 break;
917 default:
918 Log (("ac97: U nabm readb %#x -> %#x\n", Port, *pu32));
919 break;
920 }
921 break;
922 }
923
924 case 2:
925 {
926 AC97BusMasterRegs *r = NULL;
927 uint32_t index = Port - d->ac97.IOPortBase[1];
928 *pu32 = ~0U;
929
930 switch (index)
931 {
932 case PI_SR:
933 case PO_SR:
934 case MC_SR:
935 /* Status Register */
936 r = &s->bm_regs[GET_BM (index)];
937 *pu32 = r->sr;
938 Log (("ac97: SR[%d] -> %#x\n", GET_BM (index), *pu32));
939 break;
940 case PI_PICB:
941 case PO_PICB:
942 case MC_PICB:
943 /* Position in Current Buffer Register */
944 r = &s->bm_regs[GET_BM (index)];
945 *pu32 = r->picb;
946 Log (("ac97: PICB[%d] -> %#x\n", GET_BM (index), *pu32));
947 break;
948 default:
949 Log (("ac97: U nabm readw %#x -> %#x\n", Port, *pu32));
950 break;
951 }
952 break;
953 }
954
955 case 4:
956 {
957 AC97BusMasterRegs *r = NULL;
958 uint32_t index = Port - d->ac97.IOPortBase[1];
959 *pu32 = ~0U;
960
961 switch (index)
962 {
963 case PI_BDBAR:
964 case PO_BDBAR:
965 case MC_BDBAR:
966 /* Buffer Descriptor Base Address Register */
967 r = &s->bm_regs[GET_BM (index)];
968 *pu32 = r->bdbar;
969 Log (("ac97: BMADDR[%d] -> %#x\n", GET_BM (index), *pu32));
970 break;
971 case PI_CIV:
972 case PO_CIV:
973 case MC_CIV:
974 /* 32-bit access: Current Index Value Register +
975 * Last Valid Index Register +
976 * Status Register */
977 r = &s->bm_regs[GET_BM (index)];
978 *pu32 = r->civ | (r->lvi << 8) | (r->sr << 16);
979 Log (("ac97: CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM (index),
980 r->civ, r->lvi, r->sr));
981 break;
982 case PI_PICB:
983 case PO_PICB:
984 case MC_PICB:
985 /* 32-bit access: Position in Current Buffer Register +
986 * Prefetched Index Value Register +
987 * Control Register */
988 r = &s->bm_regs[GET_BM (index)];
989 *pu32 = r->picb | (r->piv << 16) | (r->cr << 24);
990 Log (("ac97: PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM (index),
991 *pu32, r->picb, r->piv, r->cr));
992 break;
993 case GLOB_CNT:
994 /* Global Control */
995 *pu32 = s->glob_cnt;
996 Log (("ac97: glob_cnt -> %#x\n", *pu32));
997 break;
998 case GLOB_STA:
999 /* Global Status */
1000 *pu32 = s->glob_sta | GS_S0CR;
1001 Log (("ac97: glob_sta -> %#x\n", *pu32));
1002 break;
1003 default:
1004 Log (("ac97: U nabm readl %#x -> %#x\n", Port, *pu32));
1005 break;
1006 }
1007 break;
1008 }
1009
1010 default:
1011 return VERR_IOM_IOPORT_UNUSED;
1012 }
1013 return VINF_SUCCESS;
1014}
1015
1016/**
1017 * Port I/O Handler for OUT operations.
1018 *
1019 * @returns VBox status code.
1020 *
1021 * @param pDevIns The device instance.
1022 * @param pvUser User argument.
1023 * @param uPort Port number used for the IN operation.
1024 * @param u32 The value to output.
1025 * @param cb The value size in bytes.
1026 */
1027static DECLCALLBACK(int) ichac97IOPortNABMWrite (PPDMDEVINS pDevIns, void *pvUser,
1028 RTIOPORT Port, uint32_t u32, unsigned cb)
1029{
1030 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
1031 AC97LinkState *s = &d->ac97;
1032
1033 switch (cb)
1034 {
1035 case 1:
1036 {
1037 AC97BusMasterRegs *r = NULL;
1038 uint32_t index = Port - d->ac97.IOPortBase[1];
1039 switch (index)
1040 {
1041 case PI_LVI:
1042 case PO_LVI:
1043 case MC_LVI:
1044 /* Last Valid Index */
1045 r = &s->bm_regs[GET_BM (index)];
1046 if ((r->cr & CR_RPBM) && (r->sr & SR_DCH)) {
1047 r->sr &= ~(SR_DCH | SR_CELV);
1048 r->civ = r->piv;
1049 r->piv = (r->piv + 1) % 32;
1050 fetch_bd (s, r);
1051 }
1052 r->lvi = u32 % 32;
1053 Log (("ac97: LVI[%d] <- %#x\n", GET_BM (index), u32));
1054 break;
1055 case PI_CR:
1056 case PO_CR:
1057 case MC_CR:
1058 /* Control Register */
1059 r = &s->bm_regs[GET_BM (index)];
1060 if (u32 & CR_RR)
1061 reset_bm_regs (s, r);
1062 else
1063 {
1064 r->cr = u32 & CR_VALID_MASK;
1065 if (!(r->cr & CR_RPBM))
1066 {
1067 voice_set_active (s, r - s->bm_regs, 0);
1068 r->sr |= SR_DCH;
1069 }
1070 else
1071 {
1072 r->civ = r->piv;
1073 r->piv = (r->piv + 1) % 32;
1074 fetch_bd (s, r);
1075 r->sr &= ~SR_DCH;
1076 voice_set_active (s, r - s->bm_regs, 1);
1077 }
1078 }
1079 Log (("ac97: CR[%d] <- %#x (cr %#x)\n", GET_BM (index), u32, r->cr));
1080 break;
1081 case PI_SR:
1082 case PO_SR:
1083 case MC_SR:
1084 /* Status Register */
1085 r = &s->bm_regs[GET_BM (index)];
1086 r->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK);
1087 update_sr (s, r, r->sr & ~(u32 & SR_WCLEAR_MASK));
1088 Log (("ac97: SR[%d] <- %#x (sr %#x)\n", GET_BM (index), u32, r->sr));
1089 break;
1090 default:
1091 Log (("ac97: U nabm writeb %#x <- %#x\n", Port, u32));
1092 break;
1093 }
1094 break;
1095 }
1096
1097 case 2:
1098 {
1099 AC97BusMasterRegs *r = NULL;
1100 uint32_t index = Port - d->ac97.IOPortBase[1];
1101 switch (index)
1102 {
1103 case PI_SR:
1104 case PO_SR:
1105 case MC_SR:
1106 /* Status Register */
1107 r = &s->bm_regs[GET_BM (index)];
1108 r->sr |= u32 & ~(SR_RO_MASK | SR_WCLEAR_MASK);
1109 update_sr (s, r, r->sr & ~(u32 & SR_WCLEAR_MASK));
1110 Log (("ac97: SR[%d] <- %#x (sr %#x)\n", GET_BM (index), u32, r->sr));
1111 break;
1112 default:
1113 Log (("ac97: U nabm writew %#x <- %#x\n", Port, u32));
1114 break;
1115 }
1116 break;
1117 }
1118
1119 case 4:
1120 {
1121 AC97BusMasterRegs *r = NULL;
1122 uint32_t index = Port - d->ac97.IOPortBase[1];
1123 switch (index)
1124 {
1125 case PI_BDBAR:
1126 case PO_BDBAR:
1127 case MC_BDBAR:
1128 /* Buffer Descriptor list Base Address Register */
1129 r = &s->bm_regs[GET_BM (index)];
1130 r->bdbar = u32 & ~3;
1131 Log (("ac97: BDBAR[%d] <- %#x (bdbar %#x)\n",
1132 GET_BM (index), u32, r->bdbar));
1133 break;
1134 case GLOB_CNT:
1135 /* Global Control */
1136 if (u32 & GC_WR)
1137 warm_reset (s);
1138 if (u32 & GC_CR)
1139 cold_reset (s);
1140 if (!(u32 & (GC_WR | GC_CR)))
1141 s->glob_cnt = u32 & GC_VALID_MASK;
1142 Log (("ac97: glob_cnt <- %#x (glob_cnt %#x)\n", u32, s->glob_cnt));
1143 break;
1144 case GLOB_STA:
1145 /* Global Status */
1146 s->glob_sta &= ~(u32 & GS_WCLEAR_MASK);
1147 s->glob_sta |= (u32 & ~(GS_WCLEAR_MASK | GS_RO_MASK)) & GS_VALID_MASK;
1148 Log (("ac97: glob_sta <- %#x (glob_sta %#x)\n", u32, s->glob_sta));
1149 break;
1150 default:
1151 Log (("ac97: U nabm writel %#x <- %#x\n", Port, u32));
1152 break;
1153 }
1154 break;
1155 }
1156
1157 default:
1158 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
1159 break;
1160 }
1161 return VINF_SUCCESS;
1162}
1163
1164/**
1165 * Port I/O Handler for IN operations.
1166 *
1167 * @returns VBox status code.
1168 *
1169 * @param pDevIns The device instance.
1170 * @param pvUser User argument.
1171 * @param uPort Port number used for the IN operation.
1172 * @param pu32 Where to store the result.
1173 * @param cb Number of bytes read.
1174 */
1175static DECLCALLBACK(int) ichac97IOPortNAMRead (PPDMDEVINS pDevIns, void *pvUser,
1176 RTIOPORT Port, uint32_t *pu32, unsigned cb)
1177{
1178 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
1179 AC97LinkState *s = &d->ac97;
1180
1181 switch (cb)
1182 {
1183 case 1:
1184 {
1185 Log (("ac97: U nam readb %#x\n", Port));
1186 s->cas = 0;
1187 *pu32 = ~0U;
1188 break;
1189 }
1190
1191 case 2:
1192 {
1193 uint32_t index = Port - d->ac97.IOPortBase[0];
1194 *pu32 = ~0U;
1195 s->cas = 0;
1196 switch (index)
1197 {
1198 default:
1199 *pu32 = mixer_load (s, index);
1200 Log (("ac97: nam readw %#x -> %#x\n", Port, *pu32));
1201 break;
1202 }
1203 break;
1204 }
1205
1206 case 4:
1207 {
1208 Log (("ac97: U nam readl %#x\n", Port));
1209 s->cas = 0;
1210 *pu32 = ~0U;
1211 break;
1212 }
1213
1214 default:
1215 return VERR_IOM_IOPORT_UNUSED;
1216 }
1217 return VINF_SUCCESS;
1218}
1219
1220/**
1221 * Port I/O Handler for OUT operations.
1222 *
1223 * @returns VBox status code.
1224 *
1225 * @param pDevIns The device instance.
1226 * @param pvUser User argument.
1227 * @param uPort Port number used for the IN operation.
1228 * @param u32 The value to output.
1229 * @param cb The value size in bytes.
1230 */
1231static DECLCALLBACK(int) ichac97IOPortNAMWrite (PPDMDEVINS pDevIns, void *pvUser,
1232 RTIOPORT Port, uint32_t u32, unsigned cb)
1233{
1234 PCIAC97LinkState *d = (PCIAC97LinkState*)pvUser;
1235 AC97LinkState *s = &d->ac97;
1236
1237 switch (cb)
1238 {
1239 case 1:
1240 {
1241 Log (("ac97: U nam writeb %#x <- %#x\n", Port, u32));
1242 s->cas = 0;
1243 break;
1244 }
1245
1246 case 2:
1247 {
1248 uint32_t index = Port - d->ac97.IOPortBase[0];
1249 s->cas = 0;
1250 switch (index)
1251 {
1252 case AC97_Reset:
1253 mixer_reset (s);
1254 break;
1255 case AC97_Powerdown_Ctrl_Stat:
1256 u32 &= ~0xf;
1257 u32 |= mixer_load (s, index) & 0xf;
1258 mixer_store (s, index, u32);
1259 break;
1260#ifdef USE_MIXER
1261 case AC97_Master_Volume_Mute:
1262 set_volume (s, index, AUD_MIXER_VOLUME, u32);
1263 break;
1264 case AC97_PCM_Out_Volume_Mute:
1265 set_volume (s, index, AUD_MIXER_PCM, u32);
1266 break;
1267 case AC97_Line_In_Volume_Mute:
1268 set_volume (s, index, AUD_MIXER_LINE_IN, u32);
1269 break;
1270 case AC97_Record_Select:
1271 record_select (s, u32);
1272 break;
1273#else
1274 case AC97_Master_Volume_Mute:
1275 case AC97_PCM_Out_Volume_Mute:
1276 case AC97_Line_In_Volume_Mute:
1277 case AC97_Record_Select:
1278 mixer_store (s, index, u32);
1279 break;
1280#endif
1281 case AC97_Vendor_ID1:
1282 case AC97_Vendor_ID2:
1283 Log (("ac97: Attempt to write vendor ID to %#x\n", u32));
1284 break;
1285 case AC97_Extended_Audio_ID:
1286 Log (("ac97: Attempt to write extended audio ID to %#x\n", u32));
1287 break;
1288 case AC97_Extended_Audio_Ctrl_Stat:
1289 if (!(u32 & EACS_VRA))
1290 {
1291 mixer_store (s, AC97_PCM_Front_DAC_Rate, 0xbb80);
1292 mixer_store (s, AC97_PCM_LR_ADC_Rate, 0xbb80);
1293 open_voice (s, PI_INDEX, 48000);
1294 open_voice (s, PO_INDEX, 48000);
1295 }
1296 if (!(u32 & EACS_VRM))
1297 {
1298 mixer_store (s, AC97_MIC_ADC_Rate, 0xbb80);
1299 open_voice (s, MC_INDEX, 48000);
1300 }
1301 Log (("ac97: Setting extended audio control to %#x\n", u32));
1302 mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, u32);
1303 break;
1304 case AC97_PCM_Front_DAC_Rate:
1305 if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
1306 {
1307 mixer_store (s, index, u32);
1308 Log(("ac97: Set front DAC rate to %d\n", u32));
1309 open_voice (s, PO_INDEX, u32);
1310 }
1311 else
1312 {
1313 Log (("ac97: Attempt to set front DAC rate to %d, "
1314 "but VRA is not set\n",
1315 u32));
1316 }
1317 break;
1318 case AC97_MIC_ADC_Rate:
1319 if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM)
1320 {
1321 mixer_store (s, index, u32);
1322 Log (("ac97: Set MIC ADC rate to %d\n", u32));
1323 open_voice (s, MC_INDEX, u32);
1324 }
1325 else
1326 {
1327 Log (("ac97: Attempt to set MIC ADC rate to %d, "
1328 "but VRM is not set\n",
1329 u32));
1330 }
1331 break;
1332 case AC97_PCM_LR_ADC_Rate:
1333 if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA)
1334 {
1335 mixer_store (s, index, u32);
1336 Log (("ac97: Set front LR ADC rate to %d\n", u32));
1337 open_voice (s, PI_INDEX, u32);
1338 }
1339 else
1340 {
1341 Log (("ac97: Attempt to set LR ADC rate to %d, but VRA is not set\n",
1342 u32));
1343 }
1344 break;
1345 default:
1346 Log (("ac97: U nam writew %#x <- %#x\n", Port, u32));
1347 mixer_store (s, index, u32);
1348 break;
1349 }
1350 break;
1351 }
1352
1353 case 4:
1354 {
1355 Log (("ac97: U nam writel %#x <- %#x\n", Port, u32));
1356 s->cas = 0;
1357 break;
1358 }
1359
1360 default:
1361 AssertMsgFailed(("Port=%#x cb=%d u32=%#x\n", Port, cb, u32));
1362 break;
1363 }
1364 return VINF_SUCCESS;
1365}
1366
1367/**
1368 * Callback function for mapping a PCI I/O region.
1369 *
1370 * @return VBox status code.
1371 * @param pPciDev Pointer to PCI device.
1372 * Use pPciDev->pDevIns to get the device instance.
1373 * @param iRegion The region number.
1374 * @param GCPhysAddress Physical address of the region.
1375 * If iType is PCI_ADDRESS_SPACE_IO, this is an
1376 * I/O port, else it's a physical address.
1377 * This address is *NOT* relative
1378 * to pci_mem_base like earlier!
1379 * @param enmType One of the PCI_ADDRESS_SPACE_* values.
1380 */
1381static DECLCALLBACK(int) ichac97IOPortMap (PPCIDEVICE pPciDev, int iRegion,
1382 RTGCPHYS GCPhysAddress, uint32_t cb,
1383 PCIADDRESSSPACE enmType)
1384{
1385 int rc;
1386 PPDMDEVINS pDevIns = pPciDev->pDevIns;
1387 RTIOPORT Port = (RTIOPORT)GCPhysAddress;
1388 PCIAC97LinkState *pData = PCIDEV_2_ICHAC97STATE(pPciDev);
1389
1390 Assert(enmType == PCI_ADDRESS_SPACE_IO);
1391 Assert(cb >= 0x20);
1392
1393 if (iRegion == 0)
1394 rc = PDMDevHlpIOPortRegister (pDevIns, Port, 256, pData,
1395 ichac97IOPortNAMWrite, ichac97IOPortNAMRead,
1396 NULL, NULL, "ICHAC97 NAM");
1397 else
1398 rc = PDMDevHlpIOPortRegister (pDevIns, Port, 64, pData,
1399 ichac97IOPortNABMWrite, ichac97IOPortNABMRead,
1400 NULL, NULL, "ICHAC97 NABM");
1401 if (VBOX_FAILURE(rc))
1402 return rc;
1403
1404 pData->ac97.IOPortBase[iRegion] = Port;
1405 return VINF_SUCCESS;
1406}
1407
1408/**
1409 * Saves a state of the AC'97 device.
1410 *
1411 * @returns VBox status code.
1412 * @param pDevIns The device instance.
1413 * @param pSSMHandle The handle to save the state to.
1414 */
1415static DECLCALLBACK(int) ichac97SaveExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
1416{
1417 PCIAC97LinkState *pData = PDMINS2DATA(pDevIns, PCIAC97LinkState *);
1418 size_t i;
1419 uint8_t active[LAST_INDEX];
1420 AC97LinkState *s = &pData->ac97;
1421
1422 SSMR3PutU32 (pSSMHandle, s->glob_cnt);
1423 SSMR3PutU32 (pSSMHandle, s->glob_sta);
1424 SSMR3PutU32 (pSSMHandle, s->cas);
1425
1426 for (i = 0; i < sizeof (s->bm_regs) / sizeof (s->bm_regs[0]); ++i)
1427 {
1428 AC97BusMasterRegs *r = &s->bm_regs[i];
1429 SSMR3PutU32 (pSSMHandle, r->bdbar);
1430 SSMR3PutU8 (pSSMHandle, r->civ);
1431 SSMR3PutU8 (pSSMHandle, r->lvi);
1432 SSMR3PutU16 (pSSMHandle, r->sr);
1433 SSMR3PutU16 (pSSMHandle, r->picb);
1434 SSMR3PutU8 (pSSMHandle, r->piv);
1435 SSMR3PutU8 (pSSMHandle, r->cr);
1436 SSMR3PutS32 (pSSMHandle, r->bd_valid);
1437 SSMR3PutU32 (pSSMHandle, r->bd.addr);
1438 SSMR3PutU32 (pSSMHandle, r->bd.ctl_len);
1439 }
1440 SSMR3PutMem (pSSMHandle, s->mixer_data, sizeof (s->mixer_data));
1441
1442 active[PI_INDEX] = AUD_is_active_in (s->voice_pi) ? 1 : 0;
1443 active[PO_INDEX] = AUD_is_active_out (s->voice_po) ? 1 : 0;
1444 active[MC_INDEX] = AUD_is_active_in (s->voice_mc) ? 1 : 0;
1445 SSMR3PutMem (pSSMHandle, active, sizeof (active));
1446
1447 return VINF_SUCCESS;
1448}
1449
1450/**
1451 * Loads a saved AC'97 device state.
1452 *
1453 * @returns VBox status code.
1454 * @param pDevIns The device instance.
1455 * @param pSSMHandle The handle to the saved state.
1456 * @param u32Version The data unit version number.
1457 */
1458static DECLCALLBACK(int) ichac97LoadExec (PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle,
1459 uint32_t u32Version)
1460{
1461 PCIAC97LinkState *pData = PDMINS2DATA(pDevIns, PCIAC97LinkState *);
1462 size_t i;
1463 uint8_t active[LAST_INDEX];
1464 AC97LinkState *s = &pData->ac97;
1465
1466 if (u32Version != AC97_SSM_VERSION)
1467 {
1468 AssertFailed();
1469 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
1470 }
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
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 *pData = PDMINS2DATA(pDevIns, PCIAC97LinkState *);
1521
1522 /*
1523 * Reset the device state (will need pDrv later).
1524 */
1525 reset_bm_regs (&pData->ac97, &pData->ac97.bm_regs[0]);
1526 reset_bm_regs (&pData->ac97, &pData->ac97.bm_regs[1]);
1527 reset_bm_regs (&pData->ac97, &pData->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(&pData->ac97);
1535}
1536
1537/**
1538 * Queries an interface to the driver.
1539 *
1540 * @returns Pointer to interface.
1541 * @returns NULL if the interface was not supported by the driver.
1542 * @param pInterface Pointer to this interface structure.
1543 * @param enmInterface The requested interface identification.
1544 * @thread Any thread.
1545 */
1546static DECLCALLBACK(void *) ichac97QueryInterface (struct PDMIBASE *pInterface,
1547 PDMINTERFACE enmInterface)
1548{
1549 PCIAC97LinkState *pData =
1550 (PCIAC97LinkState *)((uintptr_t)pInterface
1551 - RT_OFFSETOF(PCIAC97LinkState, ac97.IBase));
1552 Assert(&pData->ac97.IBase == pInterface);
1553 switch (enmInterface)
1554 {
1555 case PDMINTERFACE_BASE:
1556 return &pData->ac97.IBase;
1557 default:
1558 return NULL;
1559 }
1560}
1561
1562/**
1563 * Construct a device instance for a VM.
1564 *
1565 * @returns VBox status.
1566 * @param pDevIns The device instance data.
1567 * If the registration structure is needed,
1568 * pDevIns->pDevReg points to it.
1569 * @param iInstance Instance number. Use this to figure out which
1570 * registers and such to use.
1571 * The device number is also found in pDevIns->iInstance,
1572 * but since it's likely to be freqently used PDM passes
1573 * it as parameter.
1574 * @param pCfgHandle Configuration node handle for the device.
1575 * Use this to obtain the configuration
1576 * of the device instance. It's also found in
1577 * pDevIns->pCfgHandle, but like iInstance it's expected
1578 * to be used a bit in this function.
1579 */
1580static DECLCALLBACK(int) ichac97Construct (PPDMDEVINS pDevIns, int iInstance,
1581 PCFGMNODE pCfgHandle)
1582{
1583 PCIAC97LinkState *pData = PDMINS2DATA(pDevIns, PCIAC97LinkState *);
1584 AC97LinkState *s = &pData->ac97;
1585 int rc;
1586
1587 Assert(iInstance == 0);
1588
1589 /*
1590 * Initialize data (most of it anyway).
1591 */
1592 s->pDevIns = pDevIns;
1593 /* IBase */
1594 s->IBase.pfnQueryInterface = ichac97QueryInterface;
1595
1596 /* PCI Device */
1597 pData->dev.config[0x00] = 0x86; /* vid vendor id intel ro */
1598 pData->dev.config[0x01] = 0x80; /* intel */
1599
1600 pData->dev.config[0x02] = 0x15; /* did device id 82801 ro */
1601 pData->dev.config[0x03] = 0x24; /* 82801aa */
1602
1603 pData->dev.config[0x04] = 0x00; /* pcicmd pci command rw, ro */
1604 pData->dev.config[0x05] = 0x00;
1605
1606 pData->dev.config[0x06] = 0x80; /* pcists pci status rwc, ro */
1607 pData->dev.config[0x07] = 0x02;
1608
1609 pData->dev.config[0x08] = 0x01; /* rid revision ro */
1610 pData->dev.config[0x09] = 0x00; /* pi programming interface ro */
1611 pData->dev.config[0x0a] = 0x01; /* scc sub class code ro */
1612 pData->dev.config[0x0b] = 0x04; /* bcc base class code ro */
1613 pData->dev.config[0x0e] = 0x00; /* headtyp header type ro */
1614
1615 pData->dev.config[0x10] = 0x01; /* nambar native audio mixer base
1616 * address rw */
1617 pData->dev.config[0x11] = 0x00;
1618 pData->dev.config[0x12] = 0x00;
1619 pData->dev.config[0x13] = 0x00;
1620
1621 pData->dev.config[0x14] = 0x01; /* nabmbar native audio bus mastering
1622 * base address rw */
1623 pData->dev.config[0x15] = 0x00;
1624 pData->dev.config[0x16] = 0x00;
1625 pData->dev.config[0x17] = 0x00;
1626
1627 pData->dev.config[0x2c] = 0x86; /* svid subsystem vendor id rwo */
1628 pData->dev.config[0x2d] = 0x80;
1629
1630 pData->dev.config[0x2e] = 0x00; /* sid subsystem id rwo */
1631 pData->dev.config[0x2f] = 0x00;
1632
1633 pData->dev.config[0x3c] = 0x00; /* intr_ln interrupt line rw */
1634 pData->dev.config[0x3d] = 0x01; /* intr_pn interrupt pin ro */
1635
1636 /*
1637 * Register the PCI device, it's I/O regions, the timer and the
1638 * saved state item.
1639 */
1640 rc = PDMDevHlpPCIRegister (pDevIns, &pData->dev);
1641 if (VBOX_FAILURE(rc))
1642 return rc;
1643
1644 rc = PDMDevHlpPCIIORegionRegister (pDevIns, 0, 256, PCI_ADDRESS_SPACE_IO,
1645 ichac97IOPortMap);
1646 if (VBOX_FAILURE(rc))
1647 return rc;
1648
1649 rc = PDMDevHlpPCIIORegionRegister (pDevIns, 1, 64, PCI_ADDRESS_SPACE_IO,
1650 ichac97IOPortMap);
1651 if (VBOX_FAILURE(rc))
1652 return rc;
1653
1654 rc = PDMDevHlpSSMRegister (pDevIns, pDevIns->pDevReg->szDeviceName,
1655 iInstance, AC97_SSM_VERSION, sizeof(*pData),
1656 NULL, ichac97SaveExec, NULL,
1657 NULL, ichac97LoadExec, NULL);
1658 if (VBOX_FAILURE(rc))
1659 return rc;
1660
1661 /*
1662 * Attach driver.
1663 */
1664 rc = PDMDevHlpDriverAttach (pDevIns, 0, &s->IBase,
1665 &s->pDrvBase, "Audio Driver Port");
1666 if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
1667 Log (("ac97: No attached driver!\n"));
1668 else if (VBOX_FAILURE(rc))
1669 {
1670 AssertMsgFailed(("Failed to attach AC97 LUN #0! rc=%Vrc\n", rc));
1671 return rc;
1672 }
1673
1674 AUD_register_card ("ICH0", &s->card);
1675
1676 ac97Reset(pDevIns);
1677
1678#ifndef RT_OS_DARWIN /* coreaudio doesn't supply these. */
1679 if (!s->voice_pi)
1680 LogRel(("AC97: WARNING: Unable to open PCM IN!\n"));
1681 if (!s->voice_mc)
1682 LogRel(("AC97: WARNING: Unable to open PCM MC!\n"));
1683#endif
1684 if (!s->voice_po)
1685 LogRel(("AC97: WARNING: Unable to open PCM OUT!\n"));
1686
1687 if (!s->voice_pi && !s->voice_po && !s->voice_mc)
1688 {
1689 /* Was not able initialize *any* voice. Select the NULL audio driver instead */
1690 AUD_close_in (&s->card, s->voice_pi);
1691 AUD_close_out (&s->card, s->voice_po);
1692 AUD_close_in (&s->card, s->voice_mc);
1693 s->voice_po = NULL;
1694 s->voice_pi = NULL;
1695 s->voice_mc = NULL;
1696 AUD_init_null();
1697 ac97Reset(pDevIns);
1698
1699 PDMDevHlpVMSetRuntimeError(pDevIns, false, "HostAudioNotResponding",
1700 N_("No audio devices could not be opened. Selecting the NULL audio backend "
1701 "with the consequence that no sound is audible."));
1702 }
1703#ifndef RT_OS_DARWIN
1704 else if (!s->voice_pi || !s->voice_po || !s->voice_mc)
1705 {
1706 char szMissingVoices[128];
1707 size_t len = 0;
1708 bool fComma = false;
1709 if (!s->voice_pi)
1710 {
1711 len = RTStrPrintf(szMissingVoices, sizeof(szMissingVoices), "PCM_in");
1712 fComma = true;
1713 }
1714 if (!s->voice_po)
1715 {
1716 len = RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices)-len, "%sPCM_out",
1717 fComma ? ", " : "");
1718 fComma = true;
1719 }
1720 if (!s->voice_mc)
1721 {
1722 len = RTStrPrintf(szMissingVoices + len, sizeof(szMissingVoices)-len, "%sPCM_mic",
1723 fComma ? ", " : "");
1724 }
1725
1726 PDMDevHlpVMSetRuntimeError(pDevIns, false, "HostAudioNotResponding",
1727 N_("Some audio devices (%s) could not be opened. Guest applications generating audio "
1728 "output or depending on audio input may hang. Make sure your host audio device "
1729 "is working properly. Check the logfile for error messages of the audio "
1730 "subsystem."), szMissingVoices);
1731 }
1732#endif
1733
1734 return VINF_SUCCESS;
1735}
1736
1737/**
1738 * The device registration structure.
1739 */
1740const PDMDEVREG g_DeviceICHAC97 =
1741{
1742 /* u32Version */
1743 PDM_DEVREG_VERSION,
1744 /* szDeviceName */
1745 "ichac97",
1746 /* szGCMod */
1747 "",
1748 /* szR0Mod */
1749 "",
1750 /* pszDescription */
1751 "ICH AC'97 Audio Controller",
1752 /* fFlags */
1753 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
1754 /* fClass */
1755 PDM_DEVREG_CLASS_AUDIO,
1756 /* cMaxInstances */
1757 1,
1758 /* cbInstance */
1759 sizeof(PCIAC97LinkState),
1760 /* pfnConstruct */
1761 ichac97Construct,
1762 /* pfnDestruct */
1763 NULL,
1764 /* pfnRelocate */
1765 NULL,
1766 /* pfnIOCtl */
1767 NULL,
1768 /* pfnPowerOn */
1769 NULL,
1770 /* pfnReset */
1771 ac97Reset,
1772 /* pfnSuspend */
1773 NULL,
1774 /* pfnResume */
1775 NULL,
1776 /* pfnAttach */
1777 NULL,
1778 /* pfnDetach */
1779 NULL,
1780 /* pfnQueryInterface. */
1781 NULL
1782};
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