Revision 9f6f0423

b/hw/pci_host.c
79 79
    return val;
80 80
}
81 81

  
82
static void pci_host_config_writel(void *opaque, target_phys_addr_t addr,
83
                                   uint32_t val)
82
static void pci_host_config_write(ReadWriteHandler *handler,
83
                                  pcibus_t addr, uint32_t val, int len)
84 84
{
85
    PCIHostState *s = opaque;
85
    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
86 86

  
87
    PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n",
88
                __func__, addr, len, val);
87 89
#ifdef TARGET_WORDS_BIGENDIAN
88
    val = bswap32(val);
90
    val = qemu_bswap_len(val, len);
89 91
#endif
90
    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
91
                __func__, addr, val);
92 92
    s->config_reg = val;
93 93
}
94 94

  
95
static uint32_t pci_host_config_readl(void *opaque, target_phys_addr_t addr)
95
static uint32_t pci_host_config_read(ReadWriteHandler *handler,
96
                                            pcibus_t addr, int len)
96 97
{
97
    PCIHostState *s = opaque;
98
    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
98 99
    uint32_t val = s->config_reg;
99

  
100 100
#ifdef TARGET_WORDS_BIGENDIAN
101
    val = bswap32(val);
101
    val = qemu_bswap_len(val, len);
102 102
#endif
103
    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
104
                __func__, addr, val);
103
    PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n",
104
                __func__, addr, len, val);
105 105
    return val;
106 106
}
107 107

  
108
static CPUWriteMemoryFunc * const pci_host_config_write[] = {
109
    &pci_host_config_writel,
110
    &pci_host_config_writel,
111
    &pci_host_config_writel,
112
};
113

  
114
static CPUReadMemoryFunc * const pci_host_config_read[] = {
115
    &pci_host_config_readl,
116
    &pci_host_config_readl,
117
    &pci_host_config_readl,
118
};
119

  
120
int pci_host_conf_register_mmio(PCIHostState *s)
121
{
122
    return cpu_register_io_memory(pci_host_config_read,
123
                                  pci_host_config_write, s);
124
}
125

  
126
static void pci_host_config_writel_noswap(void *opaque,
127
                                          target_phys_addr_t addr,
128
                                          uint32_t val)
108
static void pci_host_config_write_noswap(ReadWriteHandler *handler,
109
                                         pcibus_t addr, uint32_t val, int len)
129 110
{
130
    PCIHostState *s = opaque;
111
    PCIHostState *s = container_of(handler, PCIHostState, conf_noswap_handler);
131 112

  
132
    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
133
                __func__, addr, val);
113
    PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n",
114
                __func__, addr, len, val);
134 115
    s->config_reg = val;
135 116
}
136 117

  
137
static uint32_t pci_host_config_readl_noswap(void *opaque,
138
                                             target_phys_addr_t addr)
118
static uint32_t pci_host_config_read_noswap(ReadWriteHandler *handler,
119
                                            pcibus_t addr, int len)
139 120
{
140
    PCIHostState *s = opaque;
121
    PCIHostState *s = container_of(handler, PCIHostState, conf_noswap_handler);
141 122
    uint32_t val = s->config_reg;
142 123

  
143
    PCI_DPRINTF("%s addr " TARGET_FMT_plx " val %"PRIx32"\n",
144
                __func__, addr, val);
124
    PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n",
125
                __func__, addr, len, val);
145 126
    return val;
146 127
}
147 128

  
148
static CPUWriteMemoryFunc * const pci_host_config_write_noswap[] = {
149
    &pci_host_config_writel_noswap,
150
    &pci_host_config_writel_noswap,
151
    &pci_host_config_writel_noswap,
152
};
153

  
154
static CPUReadMemoryFunc * const pci_host_config_read_noswap[] = {
155
    &pci_host_config_readl_noswap,
156
    &pci_host_config_readl_noswap,
157
    &pci_host_config_readl_noswap,
158
};
159

  
160
int pci_host_conf_register_mmio_noswap(PCIHostState *s)
129
static void pci_host_data_write(ReadWriteHandler *handler,
130
                                pcibus_t addr, uint32_t val, int len)
161 131
{
162
    return cpu_register_io_memory(pci_host_config_read_noswap,
163
                                  pci_host_config_write_noswap, s);
132
    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
133
#ifdef TARGET_WORDS_BIGENDIAN
134
    val = qemu_bswap_len(val, len);
135
#endif
136
    PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n",
137
                addr, len, val);
138
    if (s->config_reg & (1u << 31))
139
        pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
164 140
}
165 141

  
166
static void pci_host_config_writel_ioport(void *opaque,
167
                                          uint32_t addr, uint32_t val)
142
static uint32_t pci_host_data_read(ReadWriteHandler *handler,
143
                                   pcibus_t addr, int len)
168 144
{
169
    PCIHostState *s = opaque;
145
    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
146
    uint32_t val;
147
    if (!(s->config_reg & (1 << 31)))
148
        return 0xffffffff;
149
    val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
150
    PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n",
151
                addr, len, val);
152
#ifdef TARGET_WORDS_BIGENDIAN
153
    val = qemu_bswap_len(val, len);
154
#endif
155
    return val;
156
}
170 157

  
171
    PCI_DPRINTF("%s addr %"PRIx32 " val %"PRIx32"\n", __func__, addr, val);
172
    s->config_reg = val;
158
static void pci_host_init(PCIHostState *s)
159
{
160
    s->conf_handler.write = pci_host_config_write;
161
    s->conf_handler.read = pci_host_config_read;
162
    s->conf_noswap_handler.write = pci_host_config_write_noswap;
163
    s->conf_noswap_handler.read = pci_host_config_read_noswap;
164
    s->data_handler.write = pci_host_data_write;
165
    s->data_handler.read = pci_host_data_read;
173 166
}
174 167

  
175
static uint32_t pci_host_config_readl_ioport(void *opaque, uint32_t addr)
168
int pci_host_conf_register_mmio(PCIHostState *s)
176 169
{
177
    PCIHostState *s = opaque;
178
    uint32_t val = s->config_reg;
170
    pci_host_init(s);
171
    return cpu_register_io_memory_simple(&s->conf_handler);
172
}
179 173

  
180
    PCI_DPRINTF("%s addr %"PRIx32" val %"PRIx32"\n", __func__, addr, val);
181
    return val;
174
int pci_host_conf_register_mmio_noswap(PCIHostState *s)
175
{
176
    pci_host_init(s);
177
    return cpu_register_io_memory_simple(&s->conf_noswap_handler);
182 178
}
183 179

  
184 180
void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
185 181
{
186
    register_ioport_write(ioport, 4, 4, pci_host_config_writel_ioport, s);
187
    register_ioport_read(ioport, 4, 4, pci_host_config_readl_ioport, s);
182
    pci_host_init(s);
183
    register_ioport_simple(&s->conf_noswap_handler, ioport, 4, 4);
188 184
}
189 185

  
190
#define PCI_ADDR_T      target_phys_addr_t
191
#define PCI_HOST_SUFFIX _mmio
192

  
193
#include "pci_host_template.h"
194

  
195
static CPUWriteMemoryFunc * const pci_host_data_write_mmio[] = {
196
    pci_host_data_writeb_mmio,
197
    pci_host_data_writew_mmio,
198
    pci_host_data_writel_mmio,
199
};
200

  
201
static CPUReadMemoryFunc * const pci_host_data_read_mmio[] = {
202
    pci_host_data_readb_mmio,
203
    pci_host_data_readw_mmio,
204
    pci_host_data_readl_mmio,
205
};
206

  
207 186
int pci_host_data_register_mmio(PCIHostState *s)
208 187
{
209
    return cpu_register_io_memory(pci_host_data_read_mmio,
210
                                  pci_host_data_write_mmio,
211
                                  s);
188
    pci_host_init(s);
189
    return cpu_register_io_memory_simple(&s->data_handler);
212 190
}
213 191

  
214
#undef PCI_ADDR_T
215
#undef PCI_HOST_SUFFIX
216

  
217
#define PCI_ADDR_T      uint32_t
218
#define PCI_HOST_SUFFIX _ioport
219

  
220
#include "pci_host_template.h"
221

  
222 192
void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
223 193
{
224
    register_ioport_write(ioport, 4, 1, pci_host_data_writeb_ioport, s);
225
    register_ioport_write(ioport, 4, 2, pci_host_data_writew_ioport, s);
226
    register_ioport_write(ioport, 4, 4, pci_host_data_writel_ioport, s);
227
    register_ioport_read(ioport, 4, 1, pci_host_data_readb_ioport, s);
228
    register_ioport_read(ioport, 4, 2, pci_host_data_readw_ioport, s);
229
    register_ioport_read(ioport, 4, 4, pci_host_data_readl_ioport, s);
194
    pci_host_init(s);
195
    register_ioport_simple(&s->data_handler, ioport, 4, 1);
196
    register_ioport_simple(&s->data_handler, ioport, 4, 2);
197
    register_ioport_simple(&s->data_handler, ioport, 4, 4);
230 198
}
b/hw/pci_host.h
29 29
#define PCI_HOST_H
30 30

  
31 31
#include "sysbus.h"
32
#include "rwhandler.h"
32 33

  
33 34
struct PCIHostState {
34 35
    SysBusDevice busdev;
36
    ReadWriteHandler conf_noswap_handler;
37
    ReadWriteHandler conf_handler;
38
    ReadWriteHandler data_handler;
35 39
    uint32_t config_reg;
36 40
    PCIBus *bus;
37 41
};
/dev/null
1
/*
2
 * QEMU Common PCI Host bridge configuration data space access routines.
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
/* Worker routines for a PCI host controller that uses an {address,data}
26
   register pair to access PCI configuration space.  */
27

  
28
static void glue(pci_host_data_writeb, PCI_HOST_SUFFIX)(
29
    void* opaque, PCI_ADDR_T addr, uint32_t val)
30
{
31
    PCIHostState *s = opaque;
32

  
33
    PCI_DPRINTF("writeb addr " TARGET_FMT_plx " val %x\n",
34
                (target_phys_addr_t)addr, val);
35
    if (s->config_reg & (1u << 31))
36
        pci_data_write(s->bus, s->config_reg | (addr & 3), val, 1);
37
}
38

  
39
static void glue(pci_host_data_writew, PCI_HOST_SUFFIX)(
40
    void* opaque, PCI_ADDR_T addr, uint32_t val)
41
{
42
    PCIHostState *s = opaque;
43
#ifdef TARGET_WORDS_BIGENDIAN
44
    val = bswap16(val);
45
#endif
46
    PCI_DPRINTF("writew addr " TARGET_FMT_plx " val %x\n",
47
                (target_phys_addr_t)addr, val);
48
    if (s->config_reg & (1u << 31))
49
        pci_data_write(s->bus, s->config_reg | (addr & 3), val, 2);
50
}
51

  
52
static void glue(pci_host_data_writel, PCI_HOST_SUFFIX)(
53
    void* opaque, PCI_ADDR_T addr, uint32_t val)
54
{
55
    PCIHostState *s = opaque;
56
#ifdef TARGET_WORDS_BIGENDIAN
57
    val = bswap32(val);
58
#endif
59
    PCI_DPRINTF("writel addr " TARGET_FMT_plx " val %x\n",
60
                (target_phys_addr_t)addr, val);
61
    if (s->config_reg & (1u << 31))
62
        pci_data_write(s->bus, s->config_reg, val, 4);
63
}
64

  
65
static uint32_t glue(pci_host_data_readb, PCI_HOST_SUFFIX)(
66
    void* opaque, PCI_ADDR_T addr)
67
{
68
    PCIHostState *s = opaque;
69
    uint32_t val;
70

  
71
    if (!(s->config_reg & (1 << 31)))
72
        return 0xff;
73
    val = pci_data_read(s->bus, s->config_reg | (addr & 3), 1);
74
    PCI_DPRINTF("readb addr " TARGET_FMT_plx " val %x\n",
75
                (target_phys_addr_t)addr, val);
76
    return val;
77
}
78

  
79
static uint32_t glue(pci_host_data_readw, PCI_HOST_SUFFIX)(
80
    void* opaque, PCI_ADDR_T addr)
81
{
82
    PCIHostState *s = opaque;
83
    uint32_t val;
84
    if (!(s->config_reg & (1 << 31)))
85
        return 0xffff;
86
    val = pci_data_read(s->bus, s->config_reg | (addr & 3), 2);
87
    PCI_DPRINTF("readw addr " TARGET_FMT_plx " val %x\n",
88
                (target_phys_addr_t)addr, val);
89
#ifdef TARGET_WORDS_BIGENDIAN
90
    val = bswap16(val);
91
#endif
92
    return val;
93
}
94

  
95
static uint32_t glue(pci_host_data_readl, PCI_HOST_SUFFIX)(
96
    void* opaque, PCI_ADDR_T addr)
97
{
98
    PCIHostState *s = opaque;
99
    uint32_t val;
100
    if (!(s->config_reg & (1 << 31)))
101
        return 0xffffffff;
102
    val = pci_data_read(s->bus, s->config_reg | (addr & 3), 4);
103
    PCI_DPRINTF("readl addr " TARGET_FMT_plx " val %x\n",
104
                (target_phys_addr_t)addr, val);
105
#ifdef TARGET_WORDS_BIGENDIAN
106
    val = bswap32(val);
107
#endif
108
    return val;
109
}

Also available in: Unified diff