VirtualBox

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

Last change on this file since 239 was 239, checked in by vboxsync, 18 years ago

use the new runtime error report mechanism to warn the user if the audio device does not respond

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