VirtualBox

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

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

introduced PDMDevHlpGetVM()

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