2 * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
4 * Copyright (c) 2006 Openedhand Ltd.
7 * This code is licensed under the GPLv2.
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.
18 struct PXA2xxPCMCIAState {
20 PCMCIACardState *card;
21 MemoryRegion common_iomem;
22 MemoryRegion attr_iomem;
29 static uint64_t pxa2xx_pcmcia_common_read(void *opaque,
30 target_phys_addr_t offset, unsigned size)
32 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
34 if (s->slot.attached) {
35 return s->card->common_read(s->card->state, offset);
41 static void pxa2xx_pcmcia_common_write(void *opaque, target_phys_addr_t offset,
42 uint64_t value, unsigned size)
44 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
46 if (s->slot.attached) {
47 s->card->common_write(s->card->state, offset, value);
51 static uint64_t pxa2xx_pcmcia_attr_read(void *opaque,
52 target_phys_addr_t offset, unsigned size)
54 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
56 if (s->slot.attached) {
57 return s->card->attr_read(s->card->state, offset);
63 static void pxa2xx_pcmcia_attr_write(void *opaque, target_phys_addr_t offset,
64 uint64_t value, unsigned size)
66 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
68 if (s->slot.attached) {
69 s->card->attr_write(s->card->state, offset, value);
73 static uint64_t pxa2xx_pcmcia_io_read(void *opaque,
74 target_phys_addr_t offset, unsigned size)
76 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
78 if (s->slot.attached) {
79 return s->card->io_read(s->card->state, offset);
85 static void pxa2xx_pcmcia_io_write(void *opaque, target_phys_addr_t offset,
86 uint64_t value, unsigned size)
88 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
90 if (s->slot.attached) {
91 s->card->io_write(s->card->state, offset, value);
95 static const MemoryRegionOps pxa2xx_pcmcia_common_ops = {
96 .read = pxa2xx_pcmcia_common_read,
97 .write = pxa2xx_pcmcia_common_write,
98 .endianness = DEVICE_NATIVE_ENDIAN
101 static const MemoryRegionOps pxa2xx_pcmcia_attr_ops = {
102 .read = pxa2xx_pcmcia_attr_read,
103 .write = pxa2xx_pcmcia_attr_write,
104 .endianness = DEVICE_NATIVE_ENDIAN
107 static const MemoryRegionOps pxa2xx_pcmcia_io_ops = {
108 .read = pxa2xx_pcmcia_io_read,
109 .write = pxa2xx_pcmcia_io_write,
110 .endianness = DEVICE_NATIVE_ENDIAN
113 static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
115 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
119 qemu_set_irq(s->irq, level);
122 PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
123 target_phys_addr_t base)
125 PXA2xxPCMCIAState *s;
127 s = (PXA2xxPCMCIAState *)
128 g_malloc0(sizeof(PXA2xxPCMCIAState));
130 /* Socket I/O Memory Space */
131 memory_region_init_io(&s->iomem, &pxa2xx_pcmcia_io_ops, s,
132 "pxa2xx-pcmcia-io", 0x04000000);
133 memory_region_add_subregion(sysmem, base | 0x00000000,
136 /* Then next 64 MB is reserved */
138 /* Socket Attribute Memory Space */
139 memory_region_init_io(&s->attr_iomem, &pxa2xx_pcmcia_attr_ops, s,
140 "pxa2xx-pcmcia-attribute", 0x04000000);
141 memory_region_add_subregion(sysmem, base | 0x08000000,
144 /* Socket Common Memory Space */
145 memory_region_init_io(&s->common_iomem, &pxa2xx_pcmcia_common_ops, s,
146 "pxa2xx-pcmcia-common", 0x04000000);
147 memory_region_add_subregion(sysmem, base | 0x0c000000,
150 if (base == 0x30000000)
151 s->slot.slot_string = "PXA PC Card Socket 1";
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);
160 /* Insert a new card into a slot */
161 int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
163 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
164 if (s->slot.attached)
168 qemu_irq_raise(s->cd_irq);
173 s->slot.attached = 1;
174 s->card->slot = &s->slot;
175 s->card->attach(s->card->state);
180 /* Eject card from the slot */
181 int pxa2xx_pcmcia_dettach(void *opaque)
183 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
184 if (!s->slot.attached)
187 s->card->detach(s->card->state);
188 s->card->slot = NULL;
191 s->slot.attached = 0;
194 qemu_irq_lower(s->irq);
196 qemu_irq_lower(s->cd_irq);
201 /* Who to notify on card events */
202 void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
204 PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;