unstick r302391

Revision 302391

Date:
2016/05/08 20:29:20
Author:
iateaca
Revision Log:
design the layout of registers, implement the read and write access to the registers
Files:

Legend:

 
Added
 
Removed
 
Modified
  • soc2015/iateaca/bhyve-ne2000-head/usr.sbin/bhyve/pci_hda.c

     
    1 1
    2 2 #include <stdio.h>
    3 3 #include <stdlib.h>
    4 #include <string.h>
    4 5
    5 6 #include "pci_emul.h"
    6 7
     
    23 24 #define INTEL_VENDORID 0x8086
    24 25 #define HDA_INTEL_82801G 0x27d8
    25 26
    27 #define HDA_OSS_NO 0x04
    28 #define HDA_ISS_NO 0x04
    29 #define HDA_LAST_OFFSET (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20))
    30
    26 31 /*
    27 32 * HDA Controller Register Offsets
    28 33 */
     
    94 99 #define _HDAC_OSDBDPL(n, iss, oss) (0x18 + _HDAC_OSDOFFSET(n, iss, oss))
    95 100 #define _HDAC_OSDBDPU(n, iss, oss) (0x1c + _HDAC_OSDOFFSET(n, iss, oss))
    96 101
    97
    98 102 /*
    99 103 * HDA data structures
    100 104 */
    101 105
    106 struct hda_softc;
    107
    108 typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t old);
    109
    110 struct hda_softc {
    111 uint32_t regs[HDA_LAST_OFFSET];
    112 };
    113
    102 114 /*
    103 115 * HDA module function declarations
    104 116 */
    117 static void
    118 hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value);
    119 static uint32_t
    120 hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset);
    121 static void
    122 hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t mask, uint32_t value);
    105 123
    124 static struct hda_softc *hda_init(const char *opts);
    125 static void hda_reset_regs(struct hda_softc *sc);
    126 static uint32_t
    127 hda_read(struct hda_softc *sc, uint32_t offset);
    128 static int
    129 hda_write(struct hda_softc *sc, uint32_t offset, uint32_t value);
    130
    106 131 /*
    107 132 * PCI HDA function declarations
    108 133 */
     
    118 143 * HDA global data
    119 144 */
    120 145
    146 static const hda_set_reg_handler hda_set_reg_table[] = {
    147 [HDA_LAST_OFFSET] = NULL,
    148 };
    149
    121 150 struct pci_devemu pci_de_hda = {
    122 151 .pe_emu = "hda",
    123 152 .pe_init = pci_hda_init,
     
    131 160 * HDA module function definitions
    132 161 */
    133 162
    163 static void
    164 hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value)
    165 {
    166 assert(offset < HDA_LAST_OFFSET);
    167 sc->regs[offset] = value;
    168
    169 return;
    170 }
    171
    172 static uint32_t
    173 hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset)
    174 {
    175 assert(offset < HDA_LAST_OFFSET);
    176 return sc->regs[offset];
    177 }
    178
    179 static void
    180 hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t mask, uint32_t value)
    181 {
    182 uint32_t reg_value = 0;
    183
    184 reg_value = hda_get_reg_by_offset(sc, offset);
    185
    186 reg_value &= ~mask;
    187 reg_value |= value;
    188
    189 hda_set_reg_by_offset(sc, offset, reg_value);
    190
    191 return;
    192 }
    193
    194 static struct hda_softc *hda_init(const char *opts)
    195 {
    196 struct hda_softc *sc = NULL;
    197
    198 #if DEBUG_HDA == 1
    199 dbg = fopen("/tmp/bhyve_hda.log", "w+");
    200 #endif
    201
    202 DPRINTF("opts: %s\n", opts);
    203
    204 sc = calloc(1, sizeof(*sc));
    205 if (!sc)
    206 return NULL;
    207
    208 hda_reset_regs(sc);
    209
    210 return sc;
    211 }
    212
    213 static void hda_reset_regs(struct hda_softc *sc)
    214 {
    215 memset(sc->regs, 0, sizeof(sc->regs));
    216
    217 hda_set_reg_by_offset(sc, HDAC_GCAP, 0x4401);
    218 hda_set_reg_by_offset(sc, HDAC_CORBSIZE, 0x42);
    219 hda_set_reg_by_offset(sc, HDAC_RIRBSIZE, 0x42);
    220
    221 return;
    222 }
    223
    224 static uint32_t
    225 hda_read(struct hda_softc *sc, uint32_t offset)
    226 {
    227 return hda_get_reg_by_offset(sc, offset);
    228 }
    229
    230 static int
    231 hda_write(struct hda_softc *sc, uint32_t offset, uint32_t value)
    232 {
    233 uint32_t old = hda_get_reg_by_offset(sc, offset);
    234 hda_set_reg_handler set_reg_handler = hda_set_reg_table[offset];
    235
    236 hda_set_reg_by_offset(sc, offset, value);
    237
    238 if (set_reg_handler)
    239 set_reg_handler(sc, old);
    240
    241 return 0;
    242 }
    243
    134 244 /*
    135 245 * PCI HDA function definitions
    136 246 */
    137 247 static int
    138 248 pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts)
    139 249 {
    250 struct hda_softc *sc = NULL;
    251
    140 252 assert(ctx != NULL);
    141 253 assert(pi != NULL);
    142 254
    143 #if DEBUG_HDA == 1
    144 dbg = fopen("/tmp/bhyve_hda.log", "w+");
    145 #endif
    146
    147 DPRINTF("PCI HDA\n");
    148
    149 255 pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID);
    150 256 pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G);
    151 257
     
    154 260
    155 261 /* TODO check the right size */
    156 262 /* allocate one BAR register for the Memory address offsets */
    157 pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, 0x0fff);
    263 pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, 0x1000);
    158 264
    159 265 /* allocate an IRQ pin for our slot */
    160 266 pci_lintr_request(pi);
    161 267
    268 sc = hda_init(opts);
    269 if (!sc)
    270 return -1;
    271
    272 pi->pi_arg = sc;
    273
    162 274 return 0;
    163 275 }
    164 276
     
    166 278 pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
    167 279 int baridx, uint64_t offset, int size, uint64_t value)
    168 280 {
    281 struct hda_softc *sc = pi->pi_arg;
    282 int err;
    283
    284 assert(sc);
    169 285 assert(baridx == 0);
    286 assert(size <= 4);
    170 287
    171 DPRINTF("offset: 0x%lx size: %d\n", offset, size);
    288 DPRINTF("offset: 0x%lx value: 0x%lx\n", offset, value);
    172 289
    290 err = hda_write(sc, offset, value);
    291 assert(!err);
    292
    173 293 return;
    174 294 }
    175 295
     
    177 297 pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi,
    178 298 int baridx, uint64_t offset, int size)
    179 299 {
    300 struct hda_softc *sc = pi->pi_arg;
    301 uint64_t value = 0;
    302
    303 assert(sc);
    180 304 assert(baridx == 0);
    305 assert(size <= 4);
    181 306
    182 DPRINTF("offset: 0x%lx size: %d\n", offset, size);
    307 value = hda_read(sc, offset);
    183 308
    184 return 0;
    309 DPRINTF("offset: 0x%lx value: 0x%lx\n", offset, value);
    310
    311 return value;
    185 312 }
    186 313
    187 314