]> git.proxmox.com Git - qemu.git/blame - hw/pxa2xx_pcmcia.c
pxa2xx_pcmcia.c: convert common memory space to memory API
[qemu.git] / hw / pxa2xx_pcmcia.c
CommitLineData
a171fe39
AZ
1/*
2 * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
3 *
4 * Copyright (c) 2006 Openedhand Ltd.
5 * Written by Andrzej Zaborowski <balrog@zabor.org>
6 *
7 * This code is licensed under the GPLv2.
8 */
9
87ecb68b
PB
10#include "hw.h"
11#include "pcmcia.h"
9596ebb7 12#include "pxa.h"
a171fe39 13
bc24a225
PB
14struct PXA2xxPCMCIAState {
15 PCMCIASocket slot;
16 PCMCIACardState *card;
354a8c06 17 MemoryRegion common_iomem;
a171fe39
AZ
18
19 qemu_irq irq;
20 qemu_irq cd_irq;
21};
22
354a8c06
BC
23static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
24 target_phys_addr_t offset, unsigned size)
a171fe39 25{
bc24a225 26 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
27
28 if (s->slot.attached) {
a171fe39
AZ
29 return s->card->common_read(s->card->state, offset);
30 }
31
32 return 0;
33}
34
354a8c06
BC
35static void pxa2xx_pcmcia_common_write(void *opaque, target_phys_addr_t offset,
36 uint64_t value, unsigned size)
a171fe39 37{
bc24a225 38 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
39
40 if (s->slot.attached) {
a171fe39
AZ
41 s->card->common_write(s->card->state, offset, value);
42 }
43}
44
45static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
c227f099 46 target_phys_addr_t offset)
a171fe39 47{
bc24a225 48 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
49
50 if (s->slot.attached) {
a171fe39
AZ
51 return s->card->attr_read(s->card->state, offset);
52 }
53
54 return 0;
55}
56
57static void pxa2xx_pcmcia_attr_write(void *opaque,
c227f099 58 target_phys_addr_t offset, uint32_t value)
a171fe39 59{
bc24a225 60 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
61
62 if (s->slot.attached) {
a171fe39
AZ
63 s->card->attr_write(s->card->state, offset, value);
64 }
65}
66
67static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
c227f099 68 target_phys_addr_t offset)
a171fe39 69{
bc24a225 70 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
71
72 if (s->slot.attached) {
a171fe39
AZ
73 return s->card->io_read(s->card->state, offset);
74 }
75
76 return 0;
77}
78
79static void pxa2xx_pcmcia_io_write(void *opaque,
c227f099 80 target_phys_addr_t offset, uint32_t value)
a171fe39 81{
bc24a225 82 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
83
84 if (s->slot.attached) {
a171fe39
AZ
85 s->card->io_write(s->card->state, offset, value);
86 }
87}
88
354a8c06
BC
89static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
90 .read = pxa2xx_pcmcia_common_read,
91 .write = pxa2xx_pcmcia_common_write,
92 .endianness = DEVICE_NATIVE_ENDIAN
a171fe39
AZ
93};
94
d60efc6b 95static CPUReadMemoryFunc * const pxa2xx_pcmcia_attr_readfn[] = {
a171fe39
AZ
96 pxa2xx_pcmcia_attr_read,
97 pxa2xx_pcmcia_attr_read,
98 pxa2xx_pcmcia_attr_read,
99};
100
d60efc6b 101static CPUWriteMemoryFunc * const pxa2xx_pcmcia_attr_writefn[] = {
a171fe39
AZ
102 pxa2xx_pcmcia_attr_write,
103 pxa2xx_pcmcia_attr_write,
104 pxa2xx_pcmcia_attr_write,
105};
106
d60efc6b 107static CPUReadMemoryFunc * const pxa2xx_pcmcia_io_readfn[] = {
a171fe39
AZ
108 pxa2xx_pcmcia_io_read,
109 pxa2xx_pcmcia_io_read,
110 pxa2xx_pcmcia_io_read,
111};
112
d60efc6b 113static CPUWriteMemoryFunc * const pxa2xx_pcmcia_io_writefn[] = {
a171fe39
AZ
114 pxa2xx_pcmcia_io_write,
115 pxa2xx_pcmcia_io_write,
116 pxa2xx_pcmcia_io_write,
117};
118
119static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
120{
bc24a225 121 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
122 if (!s->irq)
123 return;
124
125 qemu_set_irq(s->irq, level);
126}
127
354a8c06
BC
128PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
129 target_phys_addr_t base)
a171fe39
AZ
130{
131 int iomemtype;
bc24a225 132 PXA2xxPCMCIAState *s;
a171fe39 133
bc24a225 134 s = (PXA2xxPCMCIAState *)
7267c094 135 g_malloc0(sizeof(PXA2xxPCMCIAState));
a171fe39
AZ
136
137 /* Socket I/O Memory Space */
1eed09cb 138 iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
2507c12a 139 pxa2xx_pcmcia_io_writefn, s, DEVICE_NATIVE_ENDIAN);
8da3ff18 140 cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);
a171fe39
AZ
141
142 /* Then next 64 MB is reserved */
143
144 /* Socket Attribute Memory Space */
1eed09cb 145 iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_attr_readfn,
2507c12a 146 pxa2xx_pcmcia_attr_writefn, s, DEVICE_NATIVE_ENDIAN);
8da3ff18 147 cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
a171fe39
AZ
148
149 /* Socket Common Memory Space */
354a8c06
BC
150 memory_region_init_io(&s->common_iomem, &pxa2xx_pcmcia_common_ops, s,
151 "pxa2xx-pcmcia-common", 0x04000000);
152 memory_region_add_subregion(sysmem, base | 0x0c000000,
153 &s->common_iomem);
a171fe39
AZ
154
155 if (base == 0x30000000)
156 s->slot.slot_string = "PXA PC Card Socket 1";
157 else
158 s->slot.slot_string = "PXA PC Card Socket 0";
159 s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
160 pcmcia_socket_register(&s->slot);
3f582262 161
a171fe39
AZ
162 return s;
163}
164
165/* Insert a new card into a slot */
bc24a225 166int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
a171fe39 167{
bc24a225 168 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
169 if (s->slot.attached)
170 return -EEXIST;
171
172 if (s->cd_irq) {
173 qemu_irq_raise(s->cd_irq);
174 }
175
176 s->card = card;
177
178 s->slot.attached = 1;
179 s->card->slot = &s->slot;
180 s->card->attach(s->card->state);
181
182 return 0;
183}
184
185/* Eject card from the slot */
186int pxa2xx_pcmcia_dettach(void *opaque)
187{
bc24a225 188 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
189 if (!s->slot.attached)
190 return -ENOENT;
191
192 s->card->detach(s->card->state);
b9d38e95
BS
193 s->card->slot = NULL;
194 s->card = NULL;
a171fe39
AZ
195
196 s->slot.attached = 0;
197
198 if (s->irq)
199 qemu_irq_lower(s->irq);
200 if (s->cd_irq)
201 qemu_irq_lower(s->cd_irq);
202
203 return 0;
204}
205
206/* Who to notify on card events */
207void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
208{
bc24a225 209 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
210 s->irq = irq;
211 s->cd_irq = cd_irq;
212}