VirtualBox

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

Last change on this file since 1 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.1 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 return VINF_SUCCESS;
1668}
1669
1670/**
1671 * The device registration structure.
1672 */
1673const PDMDEVREG g_DeviceICHAC97 =
1674{
1675 /* u32Version */
1676 PDM_DEVREG_VERSION,
1677 /* szDeviceName */
1678 "ichac97",
1679 /* szGCMod */
1680 "",
1681 /* szR0Mod */
1682 "",
1683 /* pszDescription */
1684 "ICH AC'97 Audio Controller",
1685 /* fFlags */
1686 PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT | PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT,
1687 /* fClass */
1688 PDM_DEVREG_CLASS_AUDIO,
1689 /* cMaxInstances */
1690 1,
1691 /* cbInstance */
1692 sizeof(PCIAC97LinkState),
1693 /* pfnConstruct */
1694 ichac97Construct,
1695 /* pfnDestruct */
1696 NULL,
1697 /* pfnRelocate */
1698 NULL,
1699 /* pfnIOCtl */
1700 NULL,
1701 /* pfnPowerOn */
1702 NULL,
1703 /* pfnReset */
1704 ac97Reset,
1705 /* pfnSuspend */
1706 NULL,
1707 /* pfnResume */
1708 NULL,
1709 /* pfnAttach */
1710 NULL,
1711 /* pfnDetach */
1712 NULL,
1713 /* pfnQueryInterface. */
1714 NULL
1715};
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