]> git.proxmox.com Git - qemu.git/blame - hw/misc/pxa2xx_pcmcia.c
Merge git://github.com/hw-claudio/qemu-aarch64-queue into tcg-next
[qemu.git] / hw / misc / 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.
6b620ca3
PB
8 *
9 * Contributions after 2012-01-13 are licensed under the terms of the
10 * GNU GPL, version 2 or (at your option) any later version.
a171fe39
AZ
11 */
12
83c9f4ca
PB
13#include "hw/hw.h"
14#include "hw/pcmcia.h"
0d09e41a 15#include "hw/arm/pxa.h"
a171fe39 16
4beeaa71 17
bc24a225
PB
18struct PXA2xxPCMCIAState {
19 PCMCIASocket slot;
20 PCMCIACardState *card;
354a8c06 21 MemoryRegion common_iomem;
4beeaa71 22 MemoryRegion attr_iomem;
59aee13c 23 MemoryRegion iomem;
a171fe39
AZ
24
25 qemu_irq irq;
26 qemu_irq cd_irq;
27};
28
354a8c06 29static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
a8170e5e 30 hwaddr offset, unsigned size)
a171fe39 31{
bc24a225 32 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
33
34 if (s->slot.attached) {
a171fe39
AZ
35 return s->card->common_read(s->card->state, offset);
36 }
37
38 return 0;
39}
40
a8170e5e 41static void pxa2xx_pcmcia_common_write(void *opaque, hwaddr offset,
354a8c06 42 uint64_t value, unsigned size)
a171fe39 43{
bc24a225 44 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
45
46 if (s->slot.attached) {
a171fe39
AZ
47 s->card->common_write(s->card->state, offset, value);
48 }
49}
50
4beeaa71 51static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
a8170e5e 52 hwaddr offset, unsigned size)
a171fe39 53{
bc24a225 54 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
55
56 if (s->slot.attached) {
a171fe39
AZ
57 return s->card->attr_read(s->card->state, offset);
58 }
59
60 return 0;
61}
62
a8170e5e 63static void pxa2xx_pcmcia_attr_write(void *opaque, hwaddr offset,
4beeaa71 64 uint64_t value, unsigned size)
a171fe39 65{
bc24a225 66 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
67
68 if (s->slot.attached) {
a171fe39
AZ
69 s->card->attr_write(s->card->state, offset, value);
70 }
71}
72
59aee13c 73static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
a8170e5e 74 hwaddr offset, unsigned size)
a171fe39 75{
bc24a225 76 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
77
78 if (s->slot.attached) {
a171fe39
AZ
79 return s->card->io_read(s->card->state, offset);
80 }
81
82 return 0;
83}
84
a8170e5e 85static void pxa2xx_pcmcia_io_write(void *opaque, hwaddr offset,
59aee13c 86 uint64_t value, unsigned size)
a171fe39 87{
bc24a225 88 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
89
90 if (s->slot.attached) {
a171fe39
AZ
91 s->card->io_write(s->card->state, offset, value);
92 }
93}
94
354a8c06
BC
95static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
96 .read = pxa2xx_pcmcia_common_read,
97 .write = pxa2xx_pcmcia_common_write,
98 .endianness = DEVICE_NATIVE_ENDIAN
a171fe39
AZ
99};
100
4beeaa71
BC
101static const MemoryRegionOps pxa2xx_pcmcia_attr_ops = {
102 .read = pxa2xx_pcmcia_attr_read,
103 .write = pxa2xx_pcmcia_attr_write,
104 .endianness = DEVICE_NATIVE_ENDIAN
a171fe39
AZ
105};
106
59aee13c
BC
107static const MemoryRegionOps pxa2xx_pcmcia_io_ops = {
108 .read = pxa2xx_pcmcia_io_read,
109 .write = pxa2xx_pcmcia_io_write,
110 .endianness = DEVICE_NATIVE_ENDIAN
a171fe39
AZ
111};
112
113static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
114{
bc24a225 115 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
116 if (!s->irq)
117 return;
118
119 qemu_set_irq(s->irq, level);
120}
121
354a8c06 122PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
a8170e5e 123 hwaddr base)
a171fe39 124{
bc24a225 125 PXA2xxPCMCIAState *s;
a171fe39 126
bc24a225 127 s = (PXA2xxPCMCIAState *)
7267c094 128 g_malloc0(sizeof(PXA2xxPCMCIAState));
a171fe39
AZ
129
130 /* Socket I/O Memory Space */
2c9b15ca 131 memory_region_init_io(&s->iomem, NULL, &pxa2xx_pcmcia_io_ops, s,
59aee13c
BC
132 "pxa2xx-pcmcia-io", 0x04000000);
133 memory_region_add_subregion(sysmem, base | 0x00000000,
134 &s->iomem);
a171fe39
AZ
135
136 /* Then next 64 MB is reserved */
137
138 /* Socket Attribute Memory Space */
2c9b15ca 139 memory_region_init_io(&s->attr_iomem, NULL, &pxa2xx_pcmcia_attr_ops, s,
4beeaa71
BC
140 "pxa2xx-pcmcia-attribute", 0x04000000);
141 memory_region_add_subregion(sysmem, base | 0x08000000,
142 &s->attr_iomem);
a171fe39
AZ
143
144 /* Socket Common Memory Space */
2c9b15ca 145 memory_region_init_io(&s->common_iomem, NULL, &pxa2xx_pcmcia_common_ops, s,
354a8c06
BC
146 "pxa2xx-pcmcia-common", 0x04000000);
147 memory_region_add_subregion(sysmem, base | 0x0c000000,
148 &s->common_iomem);
a171fe39
AZ
149
150 if (base == 0x30000000)
151 s->slot.slot_string = "PXA PC Card Socket 1";
152 else
153 s->slot.slot_string = "PXA PC Card Socket 0";
154 s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
155 pcmcia_socket_register(&s->slot);
3f582262 156
a171fe39
AZ
157 return s;
158}
159
160/* Insert a new card into a slot */
bc24a225 161int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
a171fe39 162{
bc24a225 163 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
164 if (s->slot.attached)
165 return -EEXIST;
166
167 if (s->cd_irq) {
168 qemu_irq_raise(s->cd_irq);
169 }
170
171 s->card = card;
172
173 s->slot.attached = 1;
174 s->card->slot = &s->slot;
175 s->card->attach(s->card->state);
176
177 return 0;
178}
179
180/* Eject card from the slot */
181int pxa2xx_pcmcia_dettach(void *opaque)
182{
bc24a225 183 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
184 if (!s->slot.attached)
185 return -ENOENT;
186
187 s->card->detach(s->card->state);
b9d38e95
BS
188 s->card->slot = NULL;
189 s->card = NULL;
a171fe39
AZ
190
191 s->slot.attached = 0;
192
193 if (s->irq)
194 qemu_irq_lower(s->irq);
195 if (s->cd_irq)
196 qemu_irq_lower(s->cd_irq);
197
198 return 0;
199}
200
201/* Who to notify on card events */
202void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
203{
bc24a225 204 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
a171fe39
AZ
205 s->irq = irq;
206 s->cd_irq = cd_irq;
207}