2
* Intel XScale PXA255/270 PC Card and CompactFlash Interface.
4
* Copyright (c) 2006 Openedhand Ltd.
5
* Written by Andrzej Zaborowski <balrog@zabor.org>
7
* This code is licensed under the GPLv2.
14
struct PXA2xxPCMCIAState {
16
PCMCIACardState *card;
22
static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
23
target_phys_addr_t offset)
25
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
27
if (s->slot.attached) {
28
return s->card->common_read(s->card->state, offset);
34
static void pxa2xx_pcmcia_common_write(void *opaque,
35
target_phys_addr_t offset, uint32_t value)
37
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
39
if (s->slot.attached) {
40
s->card->common_write(s->card->state, offset, value);
44
static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
45
target_phys_addr_t offset)
47
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
49
if (s->slot.attached) {
50
return s->card->attr_read(s->card->state, offset);
56
static void pxa2xx_pcmcia_attr_write(void *opaque,
57
target_phys_addr_t offset, uint32_t value)
59
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
61
if (s->slot.attached) {
62
s->card->attr_write(s->card->state, offset, value);
66
static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
67
target_phys_addr_t offset)
69
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
71
if (s->slot.attached) {
72
return s->card->io_read(s->card->state, offset);
78
static void pxa2xx_pcmcia_io_write(void *opaque,
79
target_phys_addr_t offset, uint32_t value)
81
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
83
if (s->slot.attached) {
84
s->card->io_write(s->card->state, offset, value);
88
static CPUReadMemoryFunc * const pxa2xx_pcmcia_common_readfn[] = {
89
pxa2xx_pcmcia_common_read,
90
pxa2xx_pcmcia_common_read,
91
pxa2xx_pcmcia_common_read,
94
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_common_writefn[] = {
95
pxa2xx_pcmcia_common_write,
96
pxa2xx_pcmcia_common_write,
97
pxa2xx_pcmcia_common_write,
100
static CPUReadMemoryFunc * const pxa2xx_pcmcia_attr_readfn[] = {
101
pxa2xx_pcmcia_attr_read,
102
pxa2xx_pcmcia_attr_read,
103
pxa2xx_pcmcia_attr_read,
106
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_attr_writefn[] = {
107
pxa2xx_pcmcia_attr_write,
108
pxa2xx_pcmcia_attr_write,
109
pxa2xx_pcmcia_attr_write,
112
static CPUReadMemoryFunc * const pxa2xx_pcmcia_io_readfn[] = {
113
pxa2xx_pcmcia_io_read,
114
pxa2xx_pcmcia_io_read,
115
pxa2xx_pcmcia_io_read,
118
static CPUWriteMemoryFunc * const pxa2xx_pcmcia_io_writefn[] = {
119
pxa2xx_pcmcia_io_write,
120
pxa2xx_pcmcia_io_write,
121
pxa2xx_pcmcia_io_write,
124
static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
126
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
130
qemu_set_irq(s->irq, level);
133
PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base)
136
PXA2xxPCMCIAState *s;
138
s = (PXA2xxPCMCIAState *)
139
g_malloc0(sizeof(PXA2xxPCMCIAState));
141
/* Socket I/O Memory Space */
142
iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
143
pxa2xx_pcmcia_io_writefn, s, DEVICE_NATIVE_ENDIAN);
144
cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);
146
/* Then next 64 MB is reserved */
148
/* Socket Attribute Memory Space */
149
iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_attr_readfn,
150
pxa2xx_pcmcia_attr_writefn, s, DEVICE_NATIVE_ENDIAN);
151
cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
153
/* Socket Common Memory Space */
154
iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_common_readfn,
155
pxa2xx_pcmcia_common_writefn, s, DEVICE_NATIVE_ENDIAN);
156
cpu_register_physical_memory(base | 0x0c000000, 0x04000000, iomemtype);
158
if (base == 0x30000000)
159
s->slot.slot_string = "PXA PC Card Socket 1";
161
s->slot.slot_string = "PXA PC Card Socket 0";
162
s->slot.irq = qemu_allocate_irqs(pxa2xx_pcmcia_set_irq, s, 1)[0];
163
pcmcia_socket_register(&s->slot);
168
/* Insert a new card into a slot */
169
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
171
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
172
if (s->slot.attached)
176
qemu_irq_raise(s->cd_irq);
181
s->slot.attached = 1;
182
s->card->slot = &s->slot;
183
s->card->attach(s->card->state);
188
/* Eject card from the slot */
189
int pxa2xx_pcmcia_dettach(void *opaque)
191
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
192
if (!s->slot.attached)
195
s->card->detach(s->card->state);
196
s->card->slot = NULL;
199
s->slot.attached = 0;
202
qemu_irq_lower(s->irq);
204
qemu_irq_lower(s->cd_irq);
209
/* Who to notify on card events */
210
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
212
PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;