~ahs3/+junk/cq-qemu

« back to all changes in this revision

Viewing changes to hw/cs4231.c

  • Committer: Al Stone
  • Date: 2012-02-09 01:17:20 UTC
  • Revision ID: albert.stone@canonical.com-20120209011720-tztl7ik3qayz80p4
first commit to bzr for qemu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * QEMU Crystal CS4231 audio chip emulation
 
3
 *
 
4
 * Copyright (c) 2006 Fabrice Bellard
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
7
 * of this software and associated documentation files (the "Software"), to deal
 
8
 * in the Software without restriction, including without limitation the rights
 
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
10
 * copies of the Software, and to permit persons to whom the Software is
 
11
 * furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included in
 
14
 * all copies or substantial portions of the Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
22
 * THE SOFTWARE.
 
23
 */
 
24
 
 
25
#include "sysbus.h"
 
26
#include "trace.h"
 
27
 
 
28
/*
 
29
 * In addition to Crystal CS4231 there is a DMA controller on Sparc.
 
30
 */
 
31
#define CS_SIZE 0x40
 
32
#define CS_REGS 16
 
33
#define CS_DREGS 32
 
34
#define CS_MAXDREG (CS_DREGS - 1)
 
35
 
 
36
typedef struct CSState {
 
37
    SysBusDevice busdev;
 
38
    qemu_irq irq;
 
39
    uint32_t regs[CS_REGS];
 
40
    uint8_t dregs[CS_DREGS];
 
41
} CSState;
 
42
 
 
43
#define CS_RAP(s) ((s)->regs[0] & CS_MAXDREG)
 
44
#define CS_VER 0xa0
 
45
#define CS_CDC_VER 0x8a
 
46
 
 
47
static void cs_reset(DeviceState *d)
 
48
{
 
49
    CSState *s = container_of(d, CSState, busdev.qdev);
 
50
 
 
51
    memset(s->regs, 0, CS_REGS * 4);
 
52
    memset(s->dregs, 0, CS_DREGS);
 
53
    s->dregs[12] = CS_CDC_VER;
 
54
    s->dregs[25] = CS_VER;
 
55
}
 
56
 
 
57
static uint32_t cs_mem_readl(void *opaque, target_phys_addr_t addr)
 
58
{
 
59
    CSState *s = opaque;
 
60
    uint32_t saddr, ret;
 
61
 
 
62
    saddr = addr >> 2;
 
63
    switch (saddr) {
 
64
    case 1:
 
65
        switch (CS_RAP(s)) {
 
66
        case 3: // Write only
 
67
            ret = 0;
 
68
            break;
 
69
        default:
 
70
            ret = s->dregs[CS_RAP(s)];
 
71
            break;
 
72
        }
 
73
        trace_cs4231_mem_readl_dreg(CS_RAP(s), ret);
 
74
        break;
 
75
    default:
 
76
        ret = s->regs[saddr];
 
77
        trace_cs4231_mem_readl_reg(saddr, ret);
 
78
        break;
 
79
    }
 
80
    return ret;
 
81
}
 
82
 
 
83
static void cs_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
 
84
{
 
85
    CSState *s = opaque;
 
86
    uint32_t saddr;
 
87
 
 
88
    saddr = addr >> 2;
 
89
    trace_cs4231_mem_writel_reg(saddr, s->regs[saddr], val);
 
90
    switch (saddr) {
 
91
    case 1:
 
92
        trace_cs4231_mem_writel_dreg(CS_RAP(s), s->dregs[CS_RAP(s)], val);
 
93
        switch(CS_RAP(s)) {
 
94
        case 11:
 
95
        case 25: // Read only
 
96
            break;
 
97
        case 12:
 
98
            val &= 0x40;
 
99
            val |= CS_CDC_VER; // Codec version
 
100
            s->dregs[CS_RAP(s)] = val;
 
101
            break;
 
102
        default:
 
103
            s->dregs[CS_RAP(s)] = val;
 
104
            break;
 
105
        }
 
106
        break;
 
107
    case 2: // Read only
 
108
        break;
 
109
    case 4:
 
110
        if (val & 1) {
 
111
            cs_reset(&s->busdev.qdev);
 
112
        }
 
113
        val &= 0x7f;
 
114
        s->regs[saddr] = val;
 
115
        break;
 
116
    default:
 
117
        s->regs[saddr] = val;
 
118
        break;
 
119
    }
 
120
}
 
121
 
 
122
static CPUReadMemoryFunc * const cs_mem_read[3] = {
 
123
    cs_mem_readl,
 
124
    cs_mem_readl,
 
125
    cs_mem_readl,
 
126
};
 
127
 
 
128
static CPUWriteMemoryFunc * const cs_mem_write[3] = {
 
129
    cs_mem_writel,
 
130
    cs_mem_writel,
 
131
    cs_mem_writel,
 
132
};
 
133
 
 
134
static const VMStateDescription vmstate_cs4231 = {
 
135
    .name ="cs4231",
 
136
    .version_id = 1,
 
137
    .minimum_version_id = 1,
 
138
    .minimum_version_id_old = 1,
 
139
    .fields      = (VMStateField []) {
 
140
        VMSTATE_UINT32_ARRAY(regs, CSState, CS_REGS),
 
141
        VMSTATE_UINT8_ARRAY(dregs, CSState, CS_DREGS),
 
142
        VMSTATE_END_OF_LIST()
 
143
    }
 
144
};
 
145
 
 
146
static int cs4231_init1(SysBusDevice *dev)
 
147
{
 
148
    int io;
 
149
    CSState *s = FROM_SYSBUS(CSState, dev);
 
150
 
 
151
    io = cpu_register_io_memory(cs_mem_read, cs_mem_write, s,
 
152
                                DEVICE_NATIVE_ENDIAN);
 
153
    sysbus_init_mmio(dev, CS_SIZE, io);
 
154
    sysbus_init_irq(dev, &s->irq);
 
155
 
 
156
    return 0;
 
157
}
 
158
 
 
159
static SysBusDeviceInfo cs4231_info = {
 
160
    .init = cs4231_init1,
 
161
    .qdev.name  = "SUNW,CS4231",
 
162
    .qdev.size  = sizeof(CSState),
 
163
    .qdev.vmsd  = &vmstate_cs4231,
 
164
    .qdev.reset = cs_reset,
 
165
    .qdev.props = (Property[]) {
 
166
        {.name = NULL}
 
167
    }
 
168
};
 
169
 
 
170
static void cs4231_register_devices(void)
 
171
{
 
172
    sysbus_register_withprop(&cs4231_info);
 
173
}
 
174
 
 
175
device_init(cs4231_register_devices)