Commit e5c9a13e2670b1cf23faa4b7793b3eae4ad428a5

Authored by balrog
1 parent ca9cc28c

PCI AC97 emulation by malc.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3918 c046a42c-6fe2-441c-8c8c-71466251a162
configure
... ... @@ -85,6 +85,7 @@ EXESUF=""
85 85 gdbstub="yes"
86 86 slirp="yes"
87 87 adlib="no"
  88 +ac97="no"
88 89 oss="no"
89 90 dsound="no"
90 91 coreaudio="no"
... ... @@ -280,6 +281,8 @@ for opt do
280 281 ;;
281 282 --enable-adlib) adlib="yes"
282 283 ;;
  284 + --enable-ac97) ac97="yes"
  285 + ;;
283 286 --disable-kqemu) kqemu="no"
284 287 ;;
285 288 --enable-profiler) profiler="yes"
... ... @@ -406,6 +409,7 @@ echo " --disable-sdl disable SDL"
406 409 echo " --enable-cocoa enable COCOA (Mac OS X only)"
407 410 echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
408 411 echo " --enable-adlib enable Adlib emulation"
  412 +echo " --enable-ac97 enable AC97 emulation"
409 413 echo " --enable-coreaudio enable Coreaudio audio driver"
410 414 echo " --enable-alsa enable ALSA audio driver"
411 415 echo " --enable-esd enable EsoundD audio driver"
... ... @@ -719,6 +723,7 @@ if test "$sdl" != "no" ; then
719 723 fi
720 724 echo "mingw32 support $mingw32"
721 725 echo "Adlib support $adlib"
  726 +echo "AC97 support $ac97"
722 727 echo "CoreAudio support $coreaudio"
723 728 echo "ALSA support $alsa"
724 729 echo "EsounD support $esd"
... ... @@ -895,6 +900,10 @@ if test "$adlib" = "yes" ; then
895 900 echo "CONFIG_ADLIB=yes" >> $config_mak
896 901 echo "#define CONFIG_ADLIB 1" >> $config_h
897 902 fi
  903 +if test "$ac97" = "yes" ; then
  904 + echo "CONFIG_AC97=yes" >> $config_mak
  905 + echo "#define CONFIG_AC97 1" >> $config_h
  906 +fi
898 907 if test "$oss" = "yes" ; then
899 908 echo "CONFIG_OSS=yes" >> $config_mak
900 909 echo "#define CONFIG_OSS 1" >> $config_h
... ...
hw/ac97.c 0 → 100644
  1 +/*
  2 + * Copyright (C) 2006 InnoTek Systemberatung GmbH
  3 + *
  4 + * This file is part of VirtualBox Open Source Edition (OSE), as
  5 + * available from http://www.virtualbox.org. This file is free software;
  6 + * you can redistribute it and/or modify it under the terms of the GNU
  7 + * General Public License as published by the Free Software Foundation,
  8 + * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
  9 + * distribution. VirtualBox OSE is distributed in the hope that it will
  10 + * be useful, but WITHOUT ANY WARRANTY of any kind.
  11 + *
  12 + * If you received this file as part of a commercial VirtualBox
  13 + * distribution, then only the terms of your commercial VirtualBox
  14 + * license agreement apply instead of the previous paragraph.
  15 + */
  16 +
  17 +#include "hw.h"
  18 +#include "audiodev.h"
  19 +#include "audio/audio.h"
  20 +#include "pci.h"
  21 +
  22 +enum {
  23 + AC97_Reset = 0x00,
  24 + AC97_Master_Volume_Mute = 0x02,
  25 + AC97_Headphone_Volume_Mute = 0x04,
  26 + AC97_Master_Volume_Mono_Mute = 0x06,
  27 + AC97_Master_Tone_RL = 0x08,
  28 + AC97_PC_BEEP_Volume_Mute = 0x0A,
  29 + AC97_Phone_Volume_Mute = 0x0C,
  30 + AC97_Mic_Volume_Mute = 0x0E,
  31 + AC97_Line_In_Volume_Mute = 0x10,
  32 + AC97_CD_Volume_Mute = 0x12,
  33 + AC97_Video_Volume_Mute = 0x14,
  34 + AC97_Aux_Volume_Mute = 0x16,
  35 + AC97_PCM_Out_Volume_Mute = 0x18,
  36 + AC97_Record_Select = 0x1A,
  37 + AC97_Record_Gain_Mute = 0x1C,
  38 + AC97_Record_Gain_Mic_Mute = 0x1E,
  39 + AC97_General_Purpose = 0x20,
  40 + AC97_3D_Control = 0x22,
  41 + AC97_AC_97_RESERVED = 0x24,
  42 + AC97_Powerdown_Ctrl_Stat = 0x26,
  43 + AC97_Extended_Audio_ID = 0x28,
  44 + AC97_Extended_Audio_Ctrl_Stat = 0x2A,
  45 + AC97_PCM_Front_DAC_Rate = 0x2C,
  46 + AC97_PCM_Surround_DAC_Rate = 0x2E,
  47 + AC97_PCM_LFE_DAC_Rate = 0x30,
  48 + AC97_PCM_LR_ADC_Rate = 0x32,
  49 + AC97_MIC_ADC_Rate = 0x34,
  50 + AC97_6Ch_Vol_C_LFE_Mute = 0x36,
  51 + AC97_6Ch_Vol_L_R_Surround_Mute = 0x38,
  52 + AC97_Vendor_Reserved = 0x58,
  53 + AC97_Vendor_ID1 = 0x7c,
  54 + AC97_Vendor_ID2 = 0x7e
  55 +};
  56 +
  57 +#define SOFT_VOLUME
  58 +#define SR_FIFOE 16 /* rwc */
  59 +#define SR_BCIS 8 /* rwc */
  60 +#define SR_LVBCI 4 /* rwc */
  61 +#define SR_CELV 2 /* ro */
  62 +#define SR_DCH 1 /* ro */
  63 +#define SR_VALID_MASK ((1 << 5) - 1)
  64 +#define SR_WCLEAR_MASK (SR_FIFOE | SR_BCIS | SR_LVBCI)
  65 +#define SR_RO_MASK (SR_DCH | SR_CELV)
  66 +#define SR_INT_MASK (SR_FIFOE | SR_BCIS | SR_LVBCI)
  67 +
  68 +#define CR_IOCE 16 /* rw */
  69 +#define CR_FEIE 8 /* rw */
  70 +#define CR_LVBIE 4 /* rw */
  71 +#define CR_RR 2 /* rw */
  72 +#define CR_RPBM 1 /* rw */
  73 +#define CR_VALID_MASK ((1 << 5) - 1)
  74 +#define CR_DONT_CLEAR_MASK (CR_IOCE | CR_FEIE | CR_LVBIE)
  75 +
  76 +#define GC_WR 4 /* rw */
  77 +#define GC_CR 2 /* rw */
  78 +#define GC_VALID_MASK ((1 << 6) - 1)
  79 +
  80 +#define GS_MD3 (1<<17) /* rw */
  81 +#define GS_AD3 (1<<16) /* rw */
  82 +#define GS_RCS (1<<15) /* rwc */
  83 +#define GS_B3S12 (1<<14) /* ro */
  84 +#define GS_B2S12 (1<<13) /* ro */
  85 +#define GS_B1S12 (1<<12) /* ro */
  86 +#define GS_S1R1 (1<<11) /* rwc */
  87 +#define GS_S0R1 (1<<10) /* rwc */
  88 +#define GS_S1CR (1<<9) /* ro */
  89 +#define GS_S0CR (1<<8) /* ro */
  90 +#define GS_MINT (1<<7) /* ro */
  91 +#define GS_POINT (1<<6) /* ro */
  92 +#define GS_PIINT (1<<5) /* ro */
  93 +#define GS_RSRVD ((1<<4)|(1<<3))
  94 +#define GS_MOINT (1<<2) /* ro */
  95 +#define GS_MIINT (1<<1) /* ro */
  96 +#define GS_GSCI 1 /* rwc */
  97 +#define GS_RO_MASK (GS_B3S12| \
  98 + GS_B2S12| \
  99 + GS_B1S12| \
  100 + GS_S1CR| \
  101 + GS_S0CR| \
  102 + GS_MINT| \
  103 + GS_POINT| \
  104 + GS_PIINT| \
  105 + GS_RSRVD| \
  106 + GS_MOINT| \
  107 + GS_MIINT)
  108 +#define GS_VALID_MASK ((1 << 18) - 1)
  109 +#define GS_WCLEAR_MASK (GS_RCS|GS_S1R1|GS_S0R1|GS_GSCI)
  110 +
  111 +#define BD_IOC (1<<31)
  112 +#define BD_BUP (1<<30)
  113 +
  114 +#define EACS_VRA 1
  115 +#define EACS_VRM 8
  116 +
  117 +#define VOL_MASK 0x1f
  118 +#define MUTE_SHIFT 15
  119 +
  120 +#define REC_MASK 7
  121 +enum {
  122 + REC_MIC = 0,
  123 + REC_CD,
  124 + REC_VIDEO,
  125 + REC_AUX,
  126 + REC_LINE_IN,
  127 + REC_STEREO_MIX,
  128 + REC_MONO_MIX,
  129 + REC_PHONE
  130 +};
  131 +
  132 +typedef struct BD {
  133 + uint32_t addr;
  134 + uint32_t ctl_len;
  135 +} BD;
  136 +
  137 +typedef struct AC97BusMasterRegs {
  138 + uint32_t bdbar; /* rw 0 */
  139 + uint8_t civ; /* ro 0 */
  140 + uint8_t lvi; /* rw 0 */
  141 + uint16_t sr; /* rw 1 */
  142 + uint16_t picb; /* ro 0 */
  143 + uint8_t piv; /* ro 0 */
  144 + uint8_t cr; /* rw 0 */
  145 + unsigned int bd_valid;
  146 + BD bd;
  147 +} AC97BusMasterRegs;
  148 +
  149 +typedef struct AC97LinkState {
  150 + PCIDevice *pci_dev;
  151 + QEMUSoundCard card;
  152 + uint32_t glob_cnt;
  153 + uint32_t glob_sta;
  154 + uint32_t cas;
  155 + uint32_t last_samp;
  156 + AC97BusMasterRegs bm_regs[3];
  157 + uint8_t mixer_data[256];
  158 + SWVoiceIn *voice_pi;
  159 + SWVoiceOut *voice_po;
  160 + SWVoiceIn *voice_mc;
  161 + uint8_t silence[128];
  162 + uint32_t base[2];
  163 + int bup_flag;
  164 +} AC97LinkState;
  165 +
  166 +enum {
  167 + BUP_SET = 1,
  168 + BUP_LAST = 2
  169 +};
  170 +
  171 +#ifdef DEBUG_AC97
  172 +#define dolog(...) AUD_log ("ac97", __VA_ARGS__)
  173 +#else
  174 +#define dolog(...)
  175 +#endif
  176 +
  177 +typedef struct PCIAC97LinkState {
  178 + PCIDevice dev;
  179 + AC97LinkState ac97;
  180 +} PCIAC97LinkState;
  181 +
  182 +#define MKREGS(prefix, start) \
  183 +enum { \
  184 + prefix ## _BDBAR = start, \
  185 + prefix ## _CIV = start + 4, \
  186 + prefix ## _LVI = start + 5, \
  187 + prefix ## _SR = start + 6, \
  188 + prefix ## _PICB = start + 8, \
  189 + prefix ## _PIV = start + 10, \
  190 + prefix ## _CR = start + 11 \
  191 +}
  192 +
  193 +enum {
  194 + PI_INDEX = 0,
  195 + PO_INDEX,
  196 + MC_INDEX,
  197 + LAST_INDEX
  198 +};
  199 +
  200 +MKREGS (PI, PI_INDEX * 16);
  201 +MKREGS (PO, PO_INDEX * 16);
  202 +MKREGS (MC, MC_INDEX * 16);
  203 +
  204 +enum {
  205 + GLOB_CNT = 0x2c,
  206 + GLOB_STA = 0x30,
  207 + CAS = 0x34
  208 +};
  209 +
  210 +#define GET_BM(index) (((index) >> 4) & 3)
  211 +
  212 +static void po_callback (void *opaque, int free);
  213 +static void pi_callback (void *opaque, int avail);
  214 +static void mc_callback (void *opaque, int avail);
  215 +
  216 +static void warm_reset (AC97LinkState *s)
  217 +{
  218 + (void) s;
  219 +}
  220 +
  221 +static void cold_reset (AC97LinkState * s)
  222 +{
  223 + (void) s;
  224 +}
  225 +
  226 +static void fetch_bd (AC97LinkState *s, AC97BusMasterRegs *r)
  227 +{
  228 + uint8_t b[8];
  229 +
  230 + cpu_physical_memory_read (r->bdbar + r->civ * 8, b, 8);
  231 + r->bd_valid = 1;
  232 + r->bd.addr = le32_to_cpu (*(uint32_t *) &b[0]) & ~3;
  233 + r->bd.ctl_len = le32_to_cpu (*(uint32_t *) &b[4]);
  234 + r->picb = r->bd.ctl_len & 0xffff;
  235 + dolog ("bd %2d addr=%#x ctl=%#06x len=%#x(%d bytes)\n",
  236 + r->civ, r->bd.addr, r->bd.ctl_len >> 16,
  237 + r->bd.ctl_len & 0xffff,
  238 + (r->bd.ctl_len & 0xffff) << 1);
  239 +}
  240 +
  241 +static void update_sr (AC97LinkState *s, AC97BusMasterRegs *r, uint32_t new_sr)
  242 +{
  243 + int event = 0;
  244 + int level = 0;
  245 + uint32_t new_mask = new_sr & SR_INT_MASK;
  246 + uint32_t old_mask = r->sr & SR_INT_MASK;
  247 + uint32_t masks[] = {GS_PIINT, GS_POINT, GS_MINT};
  248 +
  249 + if (new_mask ^ old_mask) {
  250 + /** @todo is IRQ deasserted when only one of status bits is cleared? */
  251 + if (!new_mask) {
  252 + event = 1;
  253 + level = 0;
  254 + }
  255 + else {
  256 + if ((new_mask & SR_LVBCI) && (r->cr & CR_LVBIE)) {
  257 + event = 1;
  258 + level = 1;
  259 + }
  260 + if ((new_mask & SR_BCIS) && (r->cr & CR_IOCE)) {
  261 + event = 1;
  262 + level = 1;
  263 + }
  264 + }
  265 + }
  266 +
  267 + r->sr = new_sr;
  268 +
  269 + dolog ("IOC%d LVB%d sr=%#x event=%d level=%d\n",
  270 + r->sr & SR_BCIS, r->sr & SR_LVBCI,
  271 + r->sr,
  272 + event, level);
  273 +
  274 + if (!event)
  275 + return;
  276 +
  277 + if (level) {
  278 + s->glob_sta |= masks[r - s->bm_regs];
  279 + dolog ("set irq level=1\n");
  280 + qemu_set_irq(s->pci_dev->irq[0], 1);
  281 + }
  282 + else {
  283 + s->glob_sta &= ~masks[r - s->bm_regs];
  284 + dolog ("set irq level=0\n");
  285 + qemu_set_irq(s->pci_dev->irq[0], 0);
  286 + }
  287 +}
  288 +
  289 +static void voice_set_active (AC97LinkState *s, int bm_index, int on)
  290 +{
  291 + switch (bm_index) {
  292 + case PI_INDEX:
  293 + AUD_set_active_in (s->voice_pi, on);
  294 + break;
  295 +
  296 + case PO_INDEX:
  297 + AUD_set_active_out (s->voice_po, on);
  298 + break;
  299 +
  300 + case MC_INDEX:
  301 + AUD_set_active_in (s->voice_mc, on);
  302 + break;
  303 +
  304 + default:
  305 + AUD_log ("ac97", "invalid bm_index(%d) in voice_set_active", bm_index);
  306 + break;
  307 + }
  308 +}
  309 +
  310 +static void reset_bm_regs (AC97LinkState *s, AC97BusMasterRegs *r)
  311 +{
  312 + dolog ("reset_bm_regs\n");
  313 + r->bdbar = 0;
  314 + r->civ = 0;
  315 + r->lvi = 0;
  316 + /** todo do we need to do that? */
  317 + update_sr (s, r, SR_DCH);
  318 + r->picb = 0;
  319 + r->piv = 0;
  320 + r->cr = r->cr & CR_DONT_CLEAR_MASK;
  321 + r->bd_valid = 0;
  322 +
  323 + voice_set_active (s, r - s->bm_regs, 0);
  324 + memset (s->silence, 0, sizeof (s->silence));
  325 +}
  326 +
  327 +static void mixer_store (AC97LinkState *s, uint32_t i, uint16_t v)
  328 +{
  329 + if (i + 2 > sizeof (s->mixer_data)) {
  330 + dolog ("mixer_store: index %d out of bounds %d\n",
  331 + i, sizeof (s->mixer_data));
  332 + return;
  333 + }
  334 +
  335 + s->mixer_data[i + 0] = v & 0xff;
  336 + s->mixer_data[i + 1] = v >> 8;
  337 +}
  338 +
  339 +static uint16_t mixer_load (AC97LinkState *s, uint32_t i)
  340 +{
  341 + uint16_t val = 0xffff;
  342 +
  343 + if (i + 2 > sizeof (s->mixer_data)) {
  344 + dolog ("mixer_store: index %d out of bounds %d\n",
  345 + i, sizeof (s->mixer_data));
  346 + }
  347 + else {
  348 + val = s->mixer_data[i + 0] | (s->mixer_data[i + 1] << 8);
  349 + }
  350 +
  351 + return val;
  352 +}
  353 +
  354 +static void open_voice (AC97LinkState *s, int index, int freq)
  355 +{
  356 + audsettings_t as;
  357 +
  358 + as.freq = freq;
  359 + as.nchannels = 2;
  360 + as.fmt = AUD_FMT_S16;
  361 + as.endianness = 0;
  362 +
  363 + switch (index) {
  364 + case PI_INDEX:
  365 + s->voice_pi = AUD_open_in (
  366 + &s->card,
  367 + s->voice_pi,
  368 + "ac97.pi",
  369 + s,
  370 + pi_callback,
  371 + &as
  372 + );
  373 + break;
  374 +
  375 + case PO_INDEX:
  376 + s->voice_po = AUD_open_out (
  377 + &s->card,
  378 + s->voice_po,
  379 + "ac97.po",
  380 + s,
  381 + po_callback,
  382 + &as
  383 + );
  384 + break;
  385 +
  386 + case MC_INDEX:
  387 + s->voice_mc = AUD_open_in (
  388 + &s->card,
  389 + s->voice_mc,
  390 + "ac97.mc",
  391 + s,
  392 + mc_callback,
  393 + &as
  394 + );
  395 + break;
  396 + }
  397 +}
  398 +
  399 +static void reset_voices (AC97LinkState *s, uint8_t active[LAST_INDEX])
  400 +{
  401 + uint16_t freq;
  402 +
  403 + freq = mixer_load (s, AC97_PCM_LR_ADC_Rate);
  404 + open_voice (s, PI_INDEX, freq);
  405 + AUD_set_active_in (s->voice_pi, active[PI_INDEX]);
  406 +
  407 + freq = mixer_load (s, AC97_PCM_Front_DAC_Rate);
  408 + open_voice (s, PO_INDEX, freq);
  409 + AUD_set_active_out (s->voice_po, active[PO_INDEX]);
  410 +
  411 + freq = mixer_load (s, AC97_MIC_ADC_Rate);
  412 + open_voice (s, MC_INDEX, freq);
  413 + AUD_set_active_in (s->voice_mc, active[MC_INDEX]);
  414 +}
  415 +
  416 +#ifdef USE_MIXER
  417 +static void set_volume (AC97LinkState *s, int index,
  418 + audmixerctl_t mt, uint32_t val)
  419 +{
  420 + int mute = (val >> MUTE_SHIFT) & 1;
  421 + uint8_t rvol = VOL_MASK - (val & VOL_MASK);
  422 + uint8_t lvol = VOL_MASK - ((val >> 8) & VOL_MASK);
  423 + rvol = 255 * rvol / VOL_MASK;
  424 + lvol = 255 * lvol / VOL_MASK;
  425 +
  426 +#ifdef SOFT_VOLUME
  427 + if (index == AC97_Master_Volume_Mute) {
  428 + AUD_set_volume_out (s->voice_po, mute, lvol, rvol);
  429 + }
  430 + else {
  431 + AUD_set_volume (mt, &mute, &lvol, &rvol);
  432 + }
  433 +#else
  434 + AUD_set_volume (mt, &mute, &lvol, &rvol);
  435 +#endif
  436 +
  437 + rvol = VOL_MASK - ((VOL_MASK * rvol) / 255);
  438 + lvol = VOL_MASK - ((VOL_MASK * lvol) / 255);
  439 + mixer_store (s, index, val);
  440 +}
  441 +
  442 +static audrecsource_t ac97_to_aud_record_source (uint8_t i)
  443 +{
  444 + switch (i) {
  445 + case REC_MIC:
  446 + return AUD_REC_MIC;
  447 +
  448 + case REC_CD:
  449 + return AUD_REC_CD;
  450 +
  451 + case REC_VIDEO:
  452 + return AUD_REC_VIDEO;
  453 +
  454 + case REC_AUX:
  455 + return AUD_REC_AUX;
  456 +
  457 + case REC_LINE_IN:
  458 + return AUD_REC_LINE_IN;
  459 +
  460 + case REC_PHONE:
  461 + return AUD_REC_PHONE;
  462 +
  463 + default:
  464 + dolog ("Unknown record source %d, using MIC\n", i);
  465 + return AUD_REC_MIC;
  466 + }
  467 +}
  468 +
  469 +static uint8_t aud_to_ac97_record_source (audrecsource_t rs)
  470 +{
  471 + switch (rs) {
  472 + case AUD_REC_MIC:
  473 + return REC_MIC;
  474 +
  475 + case AUD_REC_CD:
  476 + return REC_CD;
  477 +
  478 + case AUD_REC_VIDEO:
  479 + return REC_VIDEO;
  480 +
  481 + case AUD_REC_AUX:
  482 + return REC_AUX;
  483 +
  484 + case AUD_REC_LINE_IN:
  485 + return REC_LINE_IN;
  486 +
  487 + case AUD_REC_PHONE:
  488 + return REC_PHONE;
  489 +
  490 + default:
  491 + dolog ("Unknown audio recording source %d using MIC\n", rs);
  492 + return REC_MIC;
  493 + }
  494 +}
  495 +
  496 +static void record_select (AC97LinkState *s, uint32_t val)
  497 +{
  498 + uint8_t rs = val & REC_MASK;
  499 + uint8_t ls = (val >> 8) & REC_MASK;
  500 + audrecsource_t ars = ac97_to_aud_record_source (rs);
  501 + audrecsource_t als = ac97_to_aud_record_source (ls);
  502 + AUD_set_record_source (&als, &ars);
  503 + rs = aud_to_ac97_record_source (ars);
  504 + ls = aud_to_ac97_record_source (als);
  505 + mixer_store (s, AC97_Record_Select, rs | (ls << 8));
  506 +}
  507 +#endif
  508 +
  509 +static void mixer_reset (AC97LinkState *s)
  510 +{
  511 + uint8_t active[LAST_INDEX];
  512 +
  513 + dolog ("mixer_reset\n");
  514 + memset (s->mixer_data, 0, sizeof (s->mixer_data));
  515 + memset (active, 0, sizeof (active));
  516 + mixer_store (s, AC97_Reset , 0x0000); /* 6940 */
  517 + mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x8000);
  518 + mixer_store (s, AC97_PC_BEEP_Volume_Mute , 0x0000);
  519 +
  520 + mixer_store (s, AC97_Phone_Volume_Mute , 0x8008);
  521 + mixer_store (s, AC97_Mic_Volume_Mute , 0x8008);
  522 + mixer_store (s, AC97_CD_Volume_Mute , 0x8808);
  523 + mixer_store (s, AC97_Aux_Volume_Mute , 0x8808);
  524 + mixer_store (s, AC97_Record_Gain_Mic_Mute , 0x8000);
  525 + mixer_store (s, AC97_General_Purpose , 0x0000);
  526 + mixer_store (s, AC97_3D_Control , 0x0000);
  527 + mixer_store (s, AC97_Powerdown_Ctrl_Stat , 0x000f);
  528 +
  529 + /*
  530 + * Sigmatel 9700 (STAC9700)
  531 + */
  532 + mixer_store (s, AC97_Vendor_ID1 , 0x8384);
  533 + mixer_store (s, AC97_Vendor_ID2 , 0x7600); /* 7608 */
  534 +
  535 + mixer_store (s, AC97_Extended_Audio_ID , 0x0809);
  536 + mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, 0x0009);
  537 + mixer_store (s, AC97_PCM_Front_DAC_Rate , 0xbb80);
  538 + mixer_store (s, AC97_PCM_Surround_DAC_Rate , 0xbb80);
  539 + mixer_store (s, AC97_PCM_LFE_DAC_Rate , 0xbb80);
  540 + mixer_store (s, AC97_PCM_LR_ADC_Rate , 0xbb80);
  541 + mixer_store (s, AC97_MIC_ADC_Rate , 0xbb80);
  542 +
  543 +#ifdef USE_MIXER
  544 + record_select (s, 0);
  545 + set_volume (s, AC97_Master_Volume_Mute, AUD_MIXER_VOLUME , 0x8000);
  546 + set_volume (s, AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM , 0x8808);
  547 + set_volume (s, AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN, 0x8808);
  548 +#endif
  549 + reset_voices (s, active);
  550 +}
  551 +
  552 +/**
  553 + * Native audio mixer
  554 + * I/O Reads
  555 + */
  556 +static uint32_t nam_readb (void *opaque, uint32_t addr)
  557 +{
  558 + PCIAC97LinkState *d = opaque;
  559 + AC97LinkState *s = &d->ac97;
  560 + dolog ("U nam readb %#x\n", addr);
  561 + s->cas = 0;
  562 + return ~0U;
  563 +}
  564 +
  565 +static uint32_t nam_readw (void *opaque, uint32_t addr)
  566 +{
  567 + PCIAC97LinkState *d = opaque;
  568 + AC97LinkState *s = &d->ac97;
  569 + uint32_t val = ~0U;
  570 + uint32_t index = addr - s->base[0];
  571 + s->cas = 0;
  572 + val = mixer_load (s, index);
  573 + return val;
  574 +}
  575 +
  576 +static uint32_t nam_readl (void *opaque, uint32_t addr)
  577 +{
  578 + PCIAC97LinkState *d = opaque;
  579 + AC97LinkState *s = &d->ac97;
  580 + dolog ("U nam readl %#x\n", addr);
  581 + s->cas = 0;
  582 + return ~0U;
  583 +}
  584 +
  585 +/**
  586 + * Native audio mixer
  587 + * I/O Writes
  588 + */
  589 +static void nam_writeb (void *opaque, uint32_t addr, uint32_t val)
  590 +{
  591 + PCIAC97LinkState *d = opaque;
  592 + AC97LinkState *s = &d->ac97;
  593 + dolog ("U nam writeb %#x <- %#x\n", addr, val);
  594 + s->cas = 0;
  595 +}
  596 +
  597 +static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
  598 +{
  599 + PCIAC97LinkState *d = opaque;
  600 + AC97LinkState *s = &d->ac97;
  601 + uint32_t index = addr - s->base[0];
  602 + s->cas = 0;
  603 + switch (index) {
  604 + case AC97_Reset:
  605 + mixer_reset (s);
  606 + break;
  607 + case AC97_Powerdown_Ctrl_Stat:
  608 + val &= ~0xf;
  609 + val |= mixer_load (s, index) & 0xf;
  610 + mixer_store (s, index, val);
  611 + break;
  612 +#ifdef USE_MIXER
  613 + case AC97_Master_Volume_Mute:
  614 + set_volume (s, index, AUD_MIXER_VOLUME, val);
  615 + break;
  616 + case AC97_PCM_Out_Volume_Mute:
  617 + set_volume (s, index, AUD_MIXER_PCM, val);
  618 + break;
  619 + case AC97_Line_In_Volume_Mute:
  620 + set_volume (s, index, AUD_MIXER_LINE_IN, val);
  621 + break;
  622 + case AC97_Record_Select:
  623 + record_select (s, val);
  624 + break;
  625 +#endif
  626 + case AC97_Vendor_ID1:
  627 + case AC97_Vendor_ID2:
  628 + dolog ("Attempt to write vendor ID to %#x\n", val);
  629 + break;
  630 + case AC97_Extended_Audio_ID:
  631 + dolog ("Attempt to write extended audio ID to %#x\n", val);
  632 + break;
  633 + case AC97_Extended_Audio_Ctrl_Stat:
  634 + if (!(val & EACS_VRA)) {
  635 + mixer_store (s, AC97_PCM_Front_DAC_Rate, 0xbb80);
  636 + mixer_store (s, AC97_PCM_LR_ADC_Rate, 0xbb80);
  637 + open_voice (s, PI_INDEX, 48000);
  638 + open_voice (s, PO_INDEX, 48000);
  639 + }
  640 + if (!(val & EACS_VRM)) {
  641 + mixer_store (s, AC97_MIC_ADC_Rate, 0xbb80);
  642 + open_voice (s, MC_INDEX, 48000);
  643 + }
  644 + dolog ("Setting extended audio control to %#x\n", val);
  645 + mixer_store (s, AC97_Extended_Audio_Ctrl_Stat, val);
  646 + break;
  647 + case AC97_PCM_Front_DAC_Rate:
  648 + if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) {
  649 + mixer_store (s, index, val);
  650 + dolog ("Set front DAC rate to %d\n", val);
  651 + open_voice (s, PO_INDEX, val);
  652 + }
  653 + else {
  654 + dolog ("Attempt to set front DAC rate to %d, "
  655 + "but VRA is not set\n",
  656 + val);
  657 + }
  658 + break;
  659 + case AC97_MIC_ADC_Rate:
  660 + if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRM) {
  661 + mixer_store (s, index, val);
  662 + dolog ("Set MIC ADC rate to %d\n", val);
  663 + open_voice (s, MC_INDEX, val);
  664 + }
  665 + else {
  666 + dolog ("Attempt to set MIC ADC rate to %d, "
  667 + "but VRM is not set\n",
  668 + val);
  669 + }
  670 + break;
  671 + case AC97_PCM_LR_ADC_Rate:
  672 + if (mixer_load (s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) {
  673 + mixer_store (s, index, val);
  674 + dolog ("Set front LR ADC rate to %d\n", val);
  675 + open_voice (s, PI_INDEX, val);
  676 + }
  677 + else {
  678 + dolog ("Attempt to set LR ADC rate to %d, but VRA is not set\n",
  679 + val);
  680 + }
  681 + break;
  682 + default:
  683 + dolog ("U nam writew %#x <- %#x\n", addr, val);
  684 + mixer_store (s, index, val);
  685 + break;
  686 + }
  687 +}
  688 +
  689 +static void nam_writel (void *opaque, uint32_t addr, uint32_t val)
  690 +{
  691 + PCIAC97LinkState *d = opaque;
  692 + AC97LinkState *s = &d->ac97;
  693 + dolog ("U nam writel %#x <- %#x\n", addr, val);
  694 + s->cas = 0;
  695 +}
  696 +
  697 +/**
  698 + * Native audio bus master
  699 + * I/O Reads
  700 + */
  701 +static uint32_t nabm_readb (void *opaque, uint32_t addr)
  702 +{
  703 + PCIAC97LinkState *d = opaque;
  704 + AC97LinkState *s = &d->ac97;
  705 + AC97BusMasterRegs *r = NULL;
  706 + uint32_t index = addr - s->base[1];
  707 + uint32_t val = ~0U;
  708 +
  709 + switch (index) {
  710 + case CAS:
  711 + dolog ("CAS %d\n", s->cas);
  712 + val = s->cas;
  713 + s->cas = 1;
  714 + break;
  715 + case PI_CIV:
  716 + case PO_CIV:
  717 + case MC_CIV:
  718 + r = &s->bm_regs[GET_BM (index)];
  719 + val = r->civ;
  720 + dolog ("CIV[%d] -> %#x\n", GET_BM (index), val);
  721 + break;
  722 + case PI_LVI:
  723 + case PO_LVI:
  724 + case MC_LVI:
  725 + r = &s->bm_regs[GET_BM (index)];
  726 + val = r->lvi;
  727 + dolog ("LVI[%d] -> %#x\n", GET_BM (index), val);
  728 + break;
  729 + case PI_PIV:
  730 + case PO_PIV:
  731 + case MC_PIV:
  732 + r = &s->bm_regs[GET_BM (index)];
  733 + val = r->piv;
  734 + dolog ("PIV[%d] -> %#x\n", GET_BM (index), val);
  735 + break;
  736 + case PI_CR:
  737 + case PO_CR:
  738 + case MC_CR:
  739 + r = &s->bm_regs[GET_BM (index)];
  740 + val = r->cr;
  741 + dolog ("CR[%d] -> %#x\n", GET_BM (index), val);
  742 + break;
  743 + case PI_SR:
  744 + case PO_SR:
  745 + case MC_SR:
  746 + r = &s->bm_regs[GET_BM (index)];
  747 + val = r->sr & 0xff;
  748 + dolog ("SRb[%d] -> %#x\n", GET_BM (index), val);
  749 + break;
  750 + default:
  751 + dolog ("U nabm readb %#x -> %#x\n", addr, val);
  752 + break;
  753 + }
  754 + return val;
  755 +}
  756 +
  757 +static uint32_t nabm_readw (void *opaque, uint32_t addr)
  758 +{
  759 + PCIAC97LinkState *d = opaque;
  760 + AC97LinkState *s = &d->ac97;
  761 + AC97BusMasterRegs *r = NULL;
  762 + uint32_t index = addr - s->base[1];
  763 + uint32_t val = ~0U;
  764 +
  765 + switch (index) {
  766 + case PI_SR:
  767 + case PO_SR:
  768 + case MC_SR:
  769 + r = &s->bm_regs[GET_BM (index)];
  770 + val = r->sr;
  771 + dolog ("SR[%d] -> %#x\n", GET_BM (index), val);
  772 + break;
  773 + case PI_PICB:
  774 + case PO_PICB:
  775 + case MC_PICB:
  776 + r = &s->bm_regs[GET_BM (index)];
  777 + val = r->picb;
  778 + dolog ("PICB[%d] -> %#x\n", GET_BM (index), val);
  779 + break;
  780 + default:
  781 + dolog ("U nabm readw %#x -> %#x\n", addr, val);
  782 + break;
  783 + }
  784 + return val;
  785 +}
  786 +
  787 +static uint32_t nabm_readl (void *opaque, uint32_t addr)
  788 +{
  789 + PCIAC97LinkState *d = opaque;
  790 + AC97LinkState *s = &d->ac97;
  791 + AC97BusMasterRegs *r = NULL;
  792 + uint32_t index = addr - s->base[1];
  793 + uint32_t val = ~0U;
  794 +
  795 + switch (index) {
  796 + case PI_BDBAR:
  797 + case PO_BDBAR:
  798 + case MC_BDBAR:
  799 + r = &s->bm_regs[GET_BM (index)];
  800 + val = r->bdbar;
  801 + dolog ("BMADDR[%d] -> %#x\n", GET_BM (index), val);
  802 + break;
  803 + case PI_CIV:
  804 + case PO_CIV:
  805 + case MC_CIV:
  806 + r = &s->bm_regs[GET_BM (index)];
  807 + val = r->civ | (r->lvi << 8) | (r->sr << 16);
  808 + dolog ("CIV LVI SR[%d] -> %#x, %#x, %#x\n", GET_BM (index),
  809 + r->civ, r->lvi, r->sr);
  810 + break;
  811 + case PI_PICB:
  812 + case PO_PICB:
  813 + case MC_PICB:
  814 + r = &s->bm_regs[GET_BM (index)];
  815 + val = r->picb | (r->piv << 16) | (r->cr << 24);
  816 + dolog ("PICB PIV CR[%d] -> %#x %#x %#x %#x\n", GET_BM (index),
  817 + val, r->picb, r->piv, r->cr);
  818 + break;
  819 + case GLOB_CNT:
  820 + val = s->glob_cnt;
  821 + dolog ("glob_cnt -> %#x\n", val);
  822 + break;
  823 + case GLOB_STA:
  824 + val = s->glob_sta | GS_S0CR;
  825 + dolog ("glob_sta -> %#x\n", val);
  826 + break;
  827 + default:
  828 + dolog ("U nabm readl %#x -> %#x\n", addr, val);
  829 + break;
  830 + }
  831 + return val;
  832 +}
  833 +
  834 +/**
  835 + * Native audio bus master
  836 + * I/O Writes
  837 + */
  838 +static void nabm_writeb (void *opaque, uint32_t addr, uint32_t val)
  839 +{
  840 + PCIAC97LinkState *d = opaque;
  841 + AC97LinkState *s = &d->ac97;
  842 + AC97BusMasterRegs *r = NULL;
  843 + uint32_t index = addr - s->base[1];
  844 + switch (index) {
  845 + case PI_LVI:
  846 + case PO_LVI:
  847 + case MC_LVI:
  848 + r = &s->bm_regs[GET_BM (index)];
  849 + if ((r->cr & CR_RPBM) && (r->sr & SR_DCH)) {
  850 + r->sr &= ~(SR_DCH | SR_CELV);
  851 + r->civ = r->piv;
  852 + r->piv = (r->piv + 1) % 32;
  853 + fetch_bd (s, r);
  854 + }
  855 + r->lvi = val % 32;
  856 + dolog ("LVI[%d] <- %#x\n", GET_BM (index), val);
  857 + break;
  858 + case PI_CR:
  859 + case PO_CR:
  860 + case MC_CR:
  861 + r = &s->bm_regs[GET_BM (index)];
  862 + if (val & CR_RR) {
  863 + reset_bm_regs (s, r);
  864 + }
  865 + else {
  866 + r->cr = val & CR_VALID_MASK;
  867 + if (!(r->cr & CR_RPBM)) {
  868 + voice_set_active (s, r - s->bm_regs, 0);
  869 + r->sr |= SR_DCH;
  870 + }
  871 + else {
  872 + r->civ = r->piv;
  873 + r->piv = (r->piv + 1) % 32;
  874 + fetch_bd (s, r);
  875 + r->sr &= ~SR_DCH;
  876 + voice_set_active (s, r - s->bm_regs, 1);
  877 + }
  878 + }
  879 + dolog ("CR[%d] <- %#x (cr %#x)\n", GET_BM (index), val, r->cr);
  880 + break;
  881 + case PI_SR:
  882 + case PO_SR:
  883 + case MC_SR:
  884 + r = &s->bm_regs[GET_BM (index)];
  885 + r->sr |= val & ~(SR_RO_MASK | SR_WCLEAR_MASK);
  886 + update_sr (s, r, r->sr & ~(val & SR_WCLEAR_MASK));
  887 + dolog ("SR[%d] <- %#x (sr %#x)\n", GET_BM (index), val, r->sr);
  888 + break;
  889 + default:
  890 + dolog ("U nabm writeb %#x <- %#x\n", addr, val);
  891 + break;
  892 + }
  893 +}
  894 +
  895 +static void nabm_writew (void *opaque, uint32_t addr, uint32_t val)
  896 +{
  897 + PCIAC97LinkState *d = opaque;
  898 + AC97LinkState *s = &d->ac97;
  899 + AC97BusMasterRegs *r = NULL;
  900 + uint32_t index = addr - s->base[1];
  901 + switch (index) {
  902 + case PI_SR:
  903 + case PO_SR:
  904 + case MC_SR:
  905 + r = &s->bm_regs[GET_BM (index)];
  906 + r->sr |= val & ~(SR_RO_MASK | SR_WCLEAR_MASK);
  907 + update_sr (s, r, r->sr & ~(val & SR_WCLEAR_MASK));
  908 + dolog ("SR[%d] <- %#x (sr %#x)\n", GET_BM (index), val, r->sr);
  909 + break;
  910 + default:
  911 + dolog ("U nabm writew %#x <- %#x\n", addr, val);
  912 + break;
  913 + }
  914 +}
  915 +
  916 +static void nabm_writel (void *opaque, uint32_t addr, uint32_t val)
  917 +{
  918 + PCIAC97LinkState *d = opaque;
  919 + AC97LinkState *s = &d->ac97;
  920 + AC97BusMasterRegs *r = NULL;
  921 + uint32_t index = addr - s->base[1];
  922 + switch (index) {
  923 + case PI_BDBAR:
  924 + case PO_BDBAR:
  925 + case MC_BDBAR:
  926 + r = &s->bm_regs[GET_BM (index)];
  927 + r->bdbar = val & ~3;
  928 + dolog ("BDBAR[%d] <- %#x (bdbar %#x)\n",
  929 + GET_BM (index), val, r->bdbar);
  930 + break;
  931 + case GLOB_CNT:
  932 + if (val & GC_WR)
  933 + warm_reset (s);
  934 + if (val & GC_CR)
  935 + cold_reset (s);
  936 + if (!(val & (GC_WR | GC_CR)))
  937 + s->glob_cnt = val & GC_VALID_MASK;
  938 + dolog ("glob_cnt <- %#x (glob_cnt %#x)\n", val, s->glob_cnt);
  939 + break;
  940 + case GLOB_STA:
  941 + s->glob_sta &= ~(val & GS_WCLEAR_MASK);
  942 + s->glob_sta |= (val & ~(GS_WCLEAR_MASK | GS_RO_MASK)) & GS_VALID_MASK;
  943 + dolog ("glob_sta <- %#x (glob_sta %#x)\n", val, s->glob_sta);
  944 + break;
  945 + default:
  946 + dolog ("U nabm writel %#x <- %#x\n", addr, val);
  947 + break;
  948 + }
  949 +}
  950 +
  951 +static int write_audio (AC97LinkState *s, AC97BusMasterRegs *r,
  952 + int max, int *stop)
  953 +{
  954 + uint8_t tmpbuf[4096];
  955 + uint32_t addr = r->bd.addr;
  956 + uint32_t temp = r->picb << 1;
  957 + uint32_t written = 0;
  958 + int to_copy = 0;
  959 + temp = audio_MIN (temp, max);
  960 +
  961 + if (!temp) {
  962 + *stop = 1;
  963 + return 0;
  964 + }
  965 +
  966 + while (temp) {
  967 + int copied;
  968 + to_copy = audio_MIN (temp, sizeof (tmpbuf));
  969 + cpu_physical_memory_read (addr, tmpbuf, to_copy);
  970 + copied = AUD_write (s->voice_po, tmpbuf, to_copy);
  971 + dolog ("write_audio max=%x to_copy=%x copied=%x\n",
  972 + max, to_copy, copied);
  973 + if (!copied) {
  974 + *stop = 1;
  975 + break;
  976 + }
  977 + temp -= copied;
  978 + addr += copied;
  979 + written += copied;
  980 + }
  981 +
  982 + if (!temp) {
  983 + if (to_copy < 4) {
  984 + dolog ("whoops\n");
  985 + s->last_samp = 0;
  986 + }
  987 + else {
  988 + s->last_samp = *(uint32_t *) &tmpbuf[to_copy - 4];
  989 + }
  990 + }
  991 +
  992 + r->bd.addr = addr;
  993 + return written;
  994 +}
  995 +
  996 +static void write_bup (AC97LinkState *s, int elapsed)
  997 +{
  998 + int written = 0;
  999 +
  1000 + dolog ("write_bup\n");
  1001 + if (!(s->bup_flag & BUP_SET)) {
  1002 + if (s->bup_flag & BUP_LAST) {
  1003 + int i;
  1004 + uint8_t *p = s->silence;
  1005 + for (i = 0; i < sizeof (s->silence) / 4; i++, p += 4) {
  1006 + *(uint32_t *) p = s->last_samp;
  1007 + }
  1008 + }
  1009 + else {
  1010 + memset (s->silence, 0, sizeof (s->silence));
  1011 + }
  1012 + s->bup_flag |= BUP_SET;
  1013 + }
  1014 +
  1015 + while (elapsed) {
  1016 + int temp = audio_MIN (elapsed, sizeof (s->silence));
  1017 + while (temp) {
  1018 + int copied = AUD_write (s->voice_po, s->silence, temp);
  1019 + if (!copied)
  1020 + return;
  1021 + temp -= copied;
  1022 + elapsed -= copied;
  1023 + written += copied;
  1024 + }
  1025 + }
  1026 +}
  1027 +
  1028 +static int read_audio (AC97LinkState *s, AC97BusMasterRegs *r,
  1029 + int max, int *stop)
  1030 +{
  1031 + uint8_t tmpbuf[4096];
  1032 + uint32_t addr = r->bd.addr;
  1033 + uint32_t temp = r->picb << 1;
  1034 + uint32_t nread = 0;
  1035 + int to_copy = 0;
  1036 + SWVoiceIn *voice = (r - s->bm_regs) == MC_INDEX ? s->voice_mc : s->voice_pi;
  1037 +
  1038 + temp = audio_MIN (temp, max);
  1039 +
  1040 + if (!temp) {
  1041 + *stop = 1;
  1042 + return 0;
  1043 + }
  1044 +
  1045 + while (temp) {
  1046 + int acquired;
  1047 + to_copy = audio_MIN (temp, sizeof (tmpbuf));
  1048 + acquired = AUD_read (voice, tmpbuf, to_copy);
  1049 + if (!acquired) {
  1050 + *stop = 1;
  1051 + break;
  1052 + }
  1053 + cpu_physical_memory_write (addr, tmpbuf, acquired);
  1054 + temp -= acquired;
  1055 + addr += acquired;
  1056 + nread += acquired;
  1057 + }
  1058 +
  1059 + r->bd.addr = addr;
  1060 + return nread;
  1061 +}
  1062 +
  1063 +static void transfer_audio (AC97LinkState *s, int index, int elapsed)
  1064 +{
  1065 + AC97BusMasterRegs *r = &s->bm_regs[index];
  1066 + int written = 0, stop = 0;
  1067 +
  1068 + if (r->sr & SR_DCH) {
  1069 + if (r->cr & CR_RPBM) {
  1070 + switch (index) {
  1071 + case PO_INDEX:
  1072 + write_bup (s, elapsed);
  1073 + break;
  1074 + }
  1075 + }
  1076 + return;
  1077 + }
  1078 +
  1079 + while ((elapsed >> 1) && !stop) {
  1080 + int temp;
  1081 +
  1082 + if (!r->bd_valid) {
  1083 + dolog ("invalid bd\n");
  1084 + fetch_bd (s, r);
  1085 + }
  1086 +
  1087 + if (!r->picb) {
  1088 + dolog ("fresh bd %d is empty %#x %#x\n",
  1089 + r->civ, r->bd.addr, r->bd.ctl_len);
  1090 + if (r->civ == r->lvi) {
  1091 + r->sr |= SR_DCH; /* CELV? */
  1092 + s->bup_flag = 0;
  1093 + break;
  1094 + }
  1095 + r->sr &= ~SR_CELV;
  1096 + r->civ = r->piv;
  1097 + r->piv = (r->piv + 1) % 32;
  1098 + fetch_bd (s, r);
  1099 + return;
  1100 + }
  1101 +
  1102 + switch (index) {
  1103 + case PO_INDEX:
  1104 + temp = write_audio (s, r, elapsed, &stop);
  1105 + written += temp;
  1106 + elapsed -= temp;
  1107 + r->picb -= (temp >> 1);
  1108 + break;
  1109 +
  1110 + case PI_INDEX:
  1111 + case MC_INDEX:
  1112 + temp = read_audio (s, r, elapsed, &stop);
  1113 + elapsed -= temp;
  1114 + r->picb -= (temp >> 1);
  1115 + break;
  1116 + }
  1117 +
  1118 + if (!r->picb) {
  1119 + uint32_t new_sr = r->sr & ~SR_CELV;
  1120 +
  1121 + if (r->bd.ctl_len & BD_IOC) {
  1122 + new_sr |= SR_BCIS;
  1123 + }
  1124 +
  1125 + if (r->civ == r->lvi) {
  1126 + dolog ("Underrun civ (%d) == lvi (%d)\n", r->civ, r->lvi);
  1127 +
  1128 + new_sr |= SR_LVBCI | SR_DCH | SR_CELV;
  1129 + stop = 1;
  1130 + s->bup_flag = (r->bd.ctl_len & BD_BUP) ? BUP_LAST : 0;
  1131 + }
  1132 + else {
  1133 + r->civ = r->piv;
  1134 + r->piv = (r->piv + 1) % 32;
  1135 + fetch_bd (s, r);
  1136 + }
  1137 +
  1138 + update_sr (s, r, new_sr);
  1139 + }
  1140 + }
  1141 +}
  1142 +
  1143 +static void pi_callback (void *opaque, int avail)
  1144 +{
  1145 + transfer_audio (opaque, PI_INDEX, avail);
  1146 +}
  1147 +
  1148 +static void mc_callback (void *opaque, int avail)
  1149 +{
  1150 + transfer_audio (opaque, MC_INDEX, avail);
  1151 +}
  1152 +
  1153 +static void po_callback (void *opaque, int free)
  1154 +{
  1155 + transfer_audio (opaque, PO_INDEX, free);
  1156 +}
  1157 +
  1158 +static void ac97_save (QEMUFile *f, void *opaque)
  1159 +{
  1160 + size_t i;
  1161 + uint8_t active[LAST_INDEX];
  1162 + AC97LinkState *s = opaque;
  1163 +
  1164 + qemu_put_be32s (f, &s->glob_cnt);
  1165 + qemu_put_be32s (f, &s->glob_sta);
  1166 + qemu_put_be32s (f, &s->cas);
  1167 +
  1168 + for (i = 0; i < sizeof (s->bm_regs) / sizeof (s->bm_regs[0]); ++i) {
  1169 + AC97BusMasterRegs *r = &s->bm_regs[i];
  1170 + qemu_put_be32s (f, &r->bdbar);
  1171 + qemu_put_8s (f, &r->civ);
  1172 + qemu_put_8s (f, &r->lvi);
  1173 + qemu_put_be16s (f, &r->sr);
  1174 + qemu_put_be16s (f, &r->picb);
  1175 + qemu_put_8s (f, &r->piv);
  1176 + qemu_put_8s (f, &r->cr);
  1177 + qemu_put_be32s (f, &r->bd_valid);
  1178 + qemu_put_be32s (f, &r->bd.addr);
  1179 + qemu_put_be32s (f, &r->bd.ctl_len);
  1180 + }
  1181 + qemu_put_buffer (f, s->mixer_data, sizeof (s->mixer_data));
  1182 +
  1183 + active[PI_INDEX] = AUD_is_active_in (s->voice_pi) ? 1 : 0;
  1184 + active[PO_INDEX] = AUD_is_active_out (s->voice_po) ? 1 : 0;
  1185 + active[MC_INDEX] = AUD_is_active_in (s->voice_mc) ? 1 : 0;
  1186 + qemu_put_buffer (f, active, sizeof (active));
  1187 +}
  1188 +
  1189 +static int ac97_load (QEMUFile *f, void *opaque, int version_id)
  1190 +{
  1191 + size_t i;
  1192 + uint8_t active[LAST_INDEX];
  1193 + AC97LinkState *s = opaque;
  1194 +
  1195 + if (version_id != 1)
  1196 + return -EINVAL;
  1197 +
  1198 + qemu_get_be32s (f, &s->glob_cnt);
  1199 + qemu_get_be32s (f, &s->glob_sta);
  1200 + qemu_get_be32s (f, &s->cas);
  1201 +
  1202 + for (i = 0; i < sizeof (s->bm_regs) / sizeof (s->bm_regs[0]); ++i) {
  1203 + AC97BusMasterRegs *r = &s->bm_regs[i];
  1204 + qemu_get_be32s (f, &r->bdbar);
  1205 + qemu_get_8s (f, &r->civ);
  1206 + qemu_get_8s (f, &r->lvi);
  1207 + qemu_get_be16s (f, &r->sr);
  1208 + qemu_get_be16s (f, &r->picb);
  1209 + qemu_get_8s (f, &r->piv);
  1210 + qemu_get_8s (f, &r->cr);
  1211 + qemu_get_be32s (f, &r->bd_valid);
  1212 + qemu_get_be32s (f, &r->bd.addr);
  1213 + qemu_get_be32s (f, &r->bd.ctl_len);
  1214 + }
  1215 + qemu_get_buffer (f, s->mixer_data, sizeof (s->mixer_data));
  1216 + qemu_get_buffer (f, active, sizeof (active));
  1217 +
  1218 +#ifdef USE_MIXER
  1219 + record_select (s, mixer_load (s, AC97_Record_Select));
  1220 +#define V_(a, b) set_volume (s, a, b, mixer_load (s, a))
  1221 + V_ (AC97_Master_Volume_Mute, AUD_MIXER_VOLUME);
  1222 + V_ (AC97_PCM_Out_Volume_Mute, AUD_MIXER_PCM);
  1223 + V_ (AC97_Line_In_Volume_Mute, AUD_MIXER_LINE_IN);
  1224 +#undef V_
  1225 +#endif
  1226 + reset_voices (s, active);
  1227 +
  1228 + s->bup_flag = 0;
  1229 + s->last_samp = 0;
  1230 + return 0;
  1231 +}
  1232 +
  1233 +static void ac97_map (PCIDevice *pci_dev, int region_num,
  1234 + uint32_t addr, uint32_t size, int type)
  1235 +{
  1236 + PCIAC97LinkState *d = (PCIAC97LinkState *) pci_dev;
  1237 + AC97LinkState *s = &d->ac97;
  1238 +
  1239 + if (!region_num) {
  1240 + s->base[0] = addr;
  1241 + register_ioport_read (addr, 256 * 1, 1, nam_readb, d);
  1242 + register_ioport_read (addr, 256 * 2, 2, nam_readw, d);
  1243 + register_ioport_read (addr, 256 * 4, 4, nam_readl, d);
  1244 + register_ioport_write (addr, 256 * 1, 1, nam_writeb, d);
  1245 + register_ioport_write (addr, 256 * 2, 2, nam_writew, d);
  1246 + register_ioport_write (addr, 256 * 4, 4, nam_writel, d);
  1247 + }
  1248 + else {
  1249 + s->base[1] = addr;
  1250 + register_ioport_read (addr, 64 * 1, 1, nabm_readb, d);
  1251 + register_ioport_read (addr, 64 * 2, 2, nabm_readw, d);
  1252 + register_ioport_read (addr, 64 * 4, 4, nabm_readl, d);
  1253 + register_ioport_write (addr, 64 * 1, 1, nabm_writeb, d);
  1254 + register_ioport_write (addr, 64 * 2, 2, nabm_writew, d);
  1255 + register_ioport_write (addr, 64 * 4, 4, nabm_writel, d);
  1256 + }
  1257 +}
  1258 +
  1259 +static void ac97_on_reset (void *opaque)
  1260 +{
  1261 + AC97LinkState *s = opaque;
  1262 +
  1263 + reset_bm_regs (s, &s->bm_regs[0]);
  1264 + reset_bm_regs (s, &s->bm_regs[1]);
  1265 + reset_bm_regs (s, &s->bm_regs[2]);
  1266 +
  1267 + /*
  1268 + * Reset the mixer too. The Windows XP driver seems to rely on
  1269 + * this. At least it wants to read the vendor id before it resets
  1270 + * the codec manually.
  1271 + */
  1272 + mixer_reset (s);
  1273 +}
  1274 +
  1275 +int ac97_init (PCIBus *bus, AudioState *audio)
  1276 +{
  1277 + PCIAC97LinkState *d;
  1278 + AC97LinkState *s;
  1279 + uint8_t *c;
  1280 +
  1281 + if (!bus) {
  1282 + AUD_log ("ac97", "No PCI bus\n");
  1283 + return -1;
  1284 + }
  1285 +
  1286 + if (!audio) {
  1287 + AUD_log ("ac97", "No audio state\n");
  1288 + return -1;
  1289 + }
  1290 +
  1291 + d = (PCIAC97LinkState *) pci_register_device (bus, "AC97",
  1292 + sizeof (PCIAC97LinkState),
  1293 + -1, NULL, NULL);
  1294 +
  1295 + if (!d) {
  1296 + AUD_log ("ac97", "Failed to register PCI device\n");
  1297 + return -1;
  1298 + }
  1299 +
  1300 + s = &d->ac97;
  1301 + s->pci_dev = &d->dev;
  1302 + c = d->dev.config;
  1303 + c[0x00] = 0x86; /* vid vendor id intel ro */
  1304 + c[0x01] = 0x80; /* intel */
  1305 +
  1306 + c[0x02] = 0x15; /* did device id 82801 ro */
  1307 + c[0x03] = 0x24; /* 82801aa */
  1308 +
  1309 + c[0x04] = 0x00; /* pcicmd pci command rw, ro */
  1310 + c[0x05] = 0x00;
  1311 +
  1312 + c[0x06] = 0x80; /* pcists pci status rwc, ro */
  1313 + c[0x07] = 0x02;
  1314 +
  1315 + c[0x08] = 0x01; /* rid revision ro */
  1316 + c[0x09] = 0x00; /* pi programming interface ro */
  1317 + c[0x0a] = 0x01; /* scc sub class code ro */
  1318 + c[0x0b] = 0x04; /* bcc base class code ro */
  1319 + c[0x0e] = 0x00; /* headtyp header type ro */
  1320 +
  1321 + c[0x10] = 0x01; /* nabmar native audio mixer base
  1322 + address rw */
  1323 + c[0x11] = 0x00;
  1324 + c[0x12] = 0x00;
  1325 + c[0x13] = 0x00;
  1326 +
  1327 + c[0x14] = 0x01; /* nabmbar native audio bus mastering
  1328 + base address rw */
  1329 + c[0x15] = 0x00;
  1330 + c[0x16] = 0x00;
  1331 + c[0x17] = 0x00;
  1332 +
  1333 + c[0x2c] = 0x86; /* svid subsystem vendor id rwo */
  1334 + c[0x2d] = 0x80;
  1335 +
  1336 + c[0x2e] = 0x00; /* sid subsystem id rwo */
  1337 + c[0x2f] = 0x00;
  1338 +
  1339 + c[0x3c] = 0x00; /* intr_ln interrupt line rw */
  1340 + c[0x3d] = 0x01; /* intr_pn interrupt pin ro */
  1341 +
  1342 + pci_register_io_region (&d->dev, 0, 256 * 4, PCI_ADDRESS_SPACE_IO, ac97_map);
  1343 + pci_register_io_region (&d->dev, 1, 64 * 4, PCI_ADDRESS_SPACE_IO, ac97_map);
  1344 + register_savevm ("ac97", 0, 1, ac97_save, ac97_load, s);
  1345 + qemu_register_reset (ac97_on_reset, s);
  1346 + AUD_register_card (audio, "ac97", &s->card);
  1347 + ac97_on_reset (s);
  1348 + return 0;
  1349 +}
... ...
hw/audiodev.h
... ... @@ -10,3 +10,5 @@ int Adlib_init (AudioState *s, qemu_irq *pic);
10 10 /* gus.c */
11 11 int GUS_init (AudioState *s, qemu_irq *pic);
12 12  
  13 +/* ac97.c */
  14 +int ac97_init (PCIBus *buf, AudioState *s);
... ...
qemu-doc.texi
... ... @@ -166,6 +166,8 @@ Creative SoundBlaster 16 sound card
166 166 @item
167 167 ENSONIQ AudioPCI ES1370 sound card
168 168 @item
  169 +Intel 82801AA AC97 Audio compatible sound card
  170 +@item
169 171 Adlib(OPL2) - Yamaha YM3812 compatible chip
170 172 @item
171 173 PCI UHCI USB controller and a virtual USB hub.
... ... @@ -173,8 +175,8 @@ PCI UHCI USB controller and a virtual USB hub.
173 175  
174 176 SMP is supported with up to 255 CPUs.
175 177  
176   -Note that adlib is only available when QEMU was configured with
177   --enable-adlib
  178 +Note that adlib and ac97 are only available when QEMU was configured
  179 +with --enable-adlib, --enable-ac97 respectively.
178 180  
179 181 QEMU uses the PC BIOS from the Bochs project and the Plex86/Bochs LGPL
180 182 VGA BIOS.
... ... @@ -334,10 +336,18 @@ available sound hardware.
334 336 @example
335 337 qemu -soundhw sb16,adlib hda
336 338 qemu -soundhw es1370 hda
  339 +qemu -soundhw ac97 hda
337 340 qemu -soundhw all hda
338 341 qemu -soundhw ?
339 342 @end example
340 343  
  344 +Note that Linux's i810_audio OSS kernel (for AC97) module might
  345 +require manually specifying clocking.
  346 +
  347 +@example
  348 +modprobe i810_audio clocking=48000
  349 +@end example
  350 +
341 351 @item -localtime
342 352 Set the real time clock to local time (the default is to UTC
343 353 time). This option is needed to have correct date in MS-DOS or
... ...
... ... @@ -7990,6 +7990,16 @@ struct soundhw soundhw[] = {
7990 7990 },
7991 7991 #endif
7992 7992  
  7993 +#ifdef CONFIG_AC97
  7994 + {
  7995 + "ac97",
  7996 + "Intel 82801AA AC97 Audio",
  7997 + 0,
  7998 + 0,
  7999 + { .init_pci = ac97_init }
  8000 + },
  8001 +#endif
  8002 +
7993 8003 {
7994 8004 "es1370",
7995 8005 "ENSONIQ AudioPCI ES1370",
... ...