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.
15 struct PXA2xxPCMCIAState
{
17 PCMCIACardState
*card
;
18 MemoryRegion common_iomem
;
19 MemoryRegion attr_iomem
;
26 static uint64_t pxa2xx_pcmcia_common_read(void *opaque
,
27 target_phys_addr_t offset
, unsigned size
)
29 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
31 if (s
->slot
.attached
) {
32 return s
->card
->common_read(s
->card
->state
, offset
);
38 static void pxa2xx_pcmcia_common_write(void *opaque
, target_phys_addr_t offset
,
39 uint64_t value
, unsigned size
)
41 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
43 if (s
->slot
.attached
) {
44 s
->card
->common_write(s
->card
->state
, offset
, value
);
48 static uint64_t pxa2xx_pcmcia_attr_read(void *opaque
,
49 target_phys_addr_t offset
, unsigned size
)
51 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
53 if (s
->slot
.attached
) {
54 return s
->card
->attr_read(s
->card
->state
, offset
);
60 static void pxa2xx_pcmcia_attr_write(void *opaque
, target_phys_addr_t offset
,
61 uint64_t value
, unsigned size
)
63 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
65 if (s
->slot
.attached
) {
66 s
->card
->attr_write(s
->card
->state
, offset
, value
);
70 static uint64_t pxa2xx_pcmcia_io_read(void *opaque
,
71 target_phys_addr_t offset
, unsigned size
)
73 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
75 if (s
->slot
.attached
) {
76 return s
->card
->io_read(s
->card
->state
, offset
);
82 static void pxa2xx_pcmcia_io_write(void *opaque
, target_phys_addr_t offset
,
83 uint64_t value
, unsigned size
)
85 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
87 if (s
->slot
.attached
) {
88 s
->card
->io_write(s
->card
->state
, offset
, value
);
92 static const MemoryRegionOps pxa2xx_pcmcia_common_ops
= {
93 .read
= pxa2xx_pcmcia_common_read
,
94 .write
= pxa2xx_pcmcia_common_write
,
95 .endianness
= DEVICE_NATIVE_ENDIAN
98 static const MemoryRegionOps pxa2xx_pcmcia_attr_ops
= {
99 .read
= pxa2xx_pcmcia_attr_read
,
100 .write
= pxa2xx_pcmcia_attr_write
,
101 .endianness
= DEVICE_NATIVE_ENDIAN
104 static const MemoryRegionOps pxa2xx_pcmcia_io_ops
= {
105 .read
= pxa2xx_pcmcia_io_read
,
106 .write
= pxa2xx_pcmcia_io_write
,
107 .endianness
= DEVICE_NATIVE_ENDIAN
110 static void pxa2xx_pcmcia_set_irq(void *opaque
, int line
, int level
)
112 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
116 qemu_set_irq(s
->irq
, level
);
119 PXA2xxPCMCIAState
*pxa2xx_pcmcia_init(MemoryRegion
*sysmem
,
120 target_phys_addr_t base
)
122 PXA2xxPCMCIAState
*s
;
124 s
= (PXA2xxPCMCIAState
*)
125 g_malloc0(sizeof(PXA2xxPCMCIAState
));
127 /* Socket I/O Memory Space */
128 memory_region_init_io(&s
->iomem
, &pxa2xx_pcmcia_io_ops
, s
,
129 "pxa2xx-pcmcia-io", 0x04000000);
130 memory_region_add_subregion(sysmem
, base
| 0x00000000,
133 /* Then next 64 MB is reserved */
135 /* Socket Attribute Memory Space */
136 memory_region_init_io(&s
->attr_iomem
, &pxa2xx_pcmcia_attr_ops
, s
,
137 "pxa2xx-pcmcia-attribute", 0x04000000);
138 memory_region_add_subregion(sysmem
, base
| 0x08000000,
141 /* Socket Common Memory Space */
142 memory_region_init_io(&s
->common_iomem
, &pxa2xx_pcmcia_common_ops
, s
,
143 "pxa2xx-pcmcia-common", 0x04000000);
144 memory_region_add_subregion(sysmem
, base
| 0x0c000000,
147 if (base
== 0x30000000)
148 s
->slot
.slot_string
= "PXA PC Card Socket 1";
150 s
->slot
.slot_string
= "PXA PC Card Socket 0";
151 s
->slot
.irq
= qemu_allocate_irqs(pxa2xx_pcmcia_set_irq
, s
, 1)[0];
152 pcmcia_socket_register(&s
->slot
);
157 /* Insert a new card into a slot */
158 int pxa2xx_pcmcia_attach(void *opaque
, PCMCIACardState
*card
)
160 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
161 if (s
->slot
.attached
)
165 qemu_irq_raise(s
->cd_irq
);
170 s
->slot
.attached
= 1;
171 s
->card
->slot
= &s
->slot
;
172 s
->card
->attach(s
->card
->state
);
177 /* Eject card from the slot */
178 int pxa2xx_pcmcia_dettach(void *opaque
)
180 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;
181 if (!s
->slot
.attached
)
184 s
->card
->detach(s
->card
->state
);
185 s
->card
->slot
= NULL
;
188 s
->slot
.attached
= 0;
191 qemu_irq_lower(s
->irq
);
193 qemu_irq_lower(s
->cd_irq
);
198 /* Who to notify on card events */
199 void pxa2xx_pcmcia_set_irq_cb(void *opaque
, qemu_irq irq
, qemu_irq cd_irq
)
201 PXA2xxPCMCIAState
*s
= (PXA2xxPCMCIAState
*) opaque
;