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 qemu_mallocz(sizeof(PXA2xxPCMCIAState
));
141 /* Socket I/O Memory Space */
142 iomemtype
= cpu_register_io_memory(pxa2xx_pcmcia_io_readfn
,
143 pxa2xx_pcmcia_io_writefn
, s
);
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
);
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
);
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
;