|
|
1.1 root 1: /*
2: * Intel XScale PXA255/270 PC Card and CompactFlash Interface.
3: *
4: * Copyright (c) 2006 Openedhand Ltd.
5: * Written by Andrzej Zaborowski <[email protected]>
6: *
7: * This code is licensed under the GPLv2.
8: */
9:
10: #include "hw.h"
11: #include "pcmcia.h"
12: #include "pxa.h"
13:
1.1.1.3 root 14: struct PXA2xxPCMCIAState {
15: PCMCIASocket slot;
16: PCMCIACardState *card;
1.1 root 17:
18: qemu_irq irq;
19: qemu_irq cd_irq;
20: };
21:
22: static uint32_t pxa2xx_pcmcia_common_read(void *opaque,
23: target_phys_addr_t offset)
24: {
1.1.1.3 root 25: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 26:
27: if (s->slot.attached) {
28: return s->card->common_read(s->card->state, offset);
29: }
30:
31: return 0;
32: }
33:
34: static void pxa2xx_pcmcia_common_write(void *opaque,
35: target_phys_addr_t offset, uint32_t value)
36: {
1.1.1.3 root 37: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 38:
39: if (s->slot.attached) {
40: s->card->common_write(s->card->state, offset, value);
41: }
42: }
43:
44: static uint32_t pxa2xx_pcmcia_attr_read(void *opaque,
45: target_phys_addr_t offset)
46: {
1.1.1.3 root 47: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 48:
49: if (s->slot.attached) {
50: return s->card->attr_read(s->card->state, offset);
51: }
52:
53: return 0;
54: }
55:
56: static void pxa2xx_pcmcia_attr_write(void *opaque,
57: target_phys_addr_t offset, uint32_t value)
58: {
1.1.1.3 root 59: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 60:
61: if (s->slot.attached) {
62: s->card->attr_write(s->card->state, offset, value);
63: }
64: }
65:
66: static uint32_t pxa2xx_pcmcia_io_read(void *opaque,
67: target_phys_addr_t offset)
68: {
1.1.1.3 root 69: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 70:
71: if (s->slot.attached) {
72: return s->card->io_read(s->card->state, offset);
73: }
74:
75: return 0;
76: }
77:
78: static void pxa2xx_pcmcia_io_write(void *opaque,
79: target_phys_addr_t offset, uint32_t value)
80: {
1.1.1.3 root 81: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 82:
83: if (s->slot.attached) {
84: s->card->io_write(s->card->state, offset, value);
85: }
86: }
87:
1.1.1.4 root 88: static CPUReadMemoryFunc * const pxa2xx_pcmcia_common_readfn[] = {
1.1 root 89: pxa2xx_pcmcia_common_read,
90: pxa2xx_pcmcia_common_read,
91: pxa2xx_pcmcia_common_read,
92: };
93:
1.1.1.4 root 94: static CPUWriteMemoryFunc * const pxa2xx_pcmcia_common_writefn[] = {
1.1 root 95: pxa2xx_pcmcia_common_write,
96: pxa2xx_pcmcia_common_write,
97: pxa2xx_pcmcia_common_write,
98: };
99:
1.1.1.4 root 100: static CPUReadMemoryFunc * const pxa2xx_pcmcia_attr_readfn[] = {
1.1 root 101: pxa2xx_pcmcia_attr_read,
102: pxa2xx_pcmcia_attr_read,
103: pxa2xx_pcmcia_attr_read,
104: };
105:
1.1.1.4 root 106: static CPUWriteMemoryFunc * const pxa2xx_pcmcia_attr_writefn[] = {
1.1 root 107: pxa2xx_pcmcia_attr_write,
108: pxa2xx_pcmcia_attr_write,
109: pxa2xx_pcmcia_attr_write,
110: };
111:
1.1.1.4 root 112: static CPUReadMemoryFunc * const pxa2xx_pcmcia_io_readfn[] = {
1.1 root 113: pxa2xx_pcmcia_io_read,
114: pxa2xx_pcmcia_io_read,
115: pxa2xx_pcmcia_io_read,
116: };
117:
1.1.1.4 root 118: static CPUWriteMemoryFunc * const pxa2xx_pcmcia_io_writefn[] = {
1.1 root 119: pxa2xx_pcmcia_io_write,
120: pxa2xx_pcmcia_io_write,
121: pxa2xx_pcmcia_io_write,
122: };
123:
124: static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
125: {
1.1.1.3 root 126: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 127: if (!s->irq)
128: return;
129:
130: qemu_set_irq(s->irq, level);
131: }
132:
1.1.1.3 root 133: PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base)
1.1 root 134: {
135: int iomemtype;
1.1.1.3 root 136: PXA2xxPCMCIAState *s;
1.1 root 137:
1.1.1.3 root 138: s = (PXA2xxPCMCIAState *)
1.1.1.6 ! root 139: g_malloc0(sizeof(PXA2xxPCMCIAState));
1.1 root 140:
141: /* Socket I/O Memory Space */
1.1.1.3 root 142: iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
1.1.1.5 root 143: pxa2xx_pcmcia_io_writefn, s, DEVICE_NATIVE_ENDIAN);
1.1.1.2 root 144: cpu_register_physical_memory(base | 0x00000000, 0x04000000, iomemtype);
1.1 root 145:
146: /* Then next 64 MB is reserved */
147:
148: /* Socket Attribute Memory Space */
1.1.1.3 root 149: iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_attr_readfn,
1.1.1.5 root 150: pxa2xx_pcmcia_attr_writefn, s, DEVICE_NATIVE_ENDIAN);
1.1.1.2 root 151: cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
1.1 root 152:
153: /* Socket Common Memory Space */
1.1.1.3 root 154: iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_common_readfn,
1.1.1.5 root 155: pxa2xx_pcmcia_common_writefn, s, DEVICE_NATIVE_ENDIAN);
1.1.1.2 root 156: cpu_register_physical_memory(base | 0x0c000000, 0x04000000, iomemtype);
1.1 root 157:
158: if (base == 0x30000000)
159: s->slot.slot_string = "PXA PC Card Socket 1";
160: else
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);
164:
165: return s;
166: }
167:
168: /* Insert a new card into a slot */
1.1.1.3 root 169: int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card)
1.1 root 170: {
1.1.1.3 root 171: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 172: if (s->slot.attached)
173: return -EEXIST;
174:
175: if (s->cd_irq) {
176: qemu_irq_raise(s->cd_irq);
177: }
178:
179: s->card = card;
180:
181: s->slot.attached = 1;
182: s->card->slot = &s->slot;
183: s->card->attach(s->card->state);
184:
185: return 0;
186: }
187:
188: /* Eject card from the slot */
189: int pxa2xx_pcmcia_dettach(void *opaque)
190: {
1.1.1.3 root 191: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 192: if (!s->slot.attached)
193: return -ENOENT;
194:
195: s->card->detach(s->card->state);
1.1.1.4 root 196: s->card->slot = NULL;
197: s->card = NULL;
1.1 root 198:
199: s->slot.attached = 0;
200:
201: if (s->irq)
202: qemu_irq_lower(s->irq);
203: if (s->cd_irq)
204: qemu_irq_lower(s->cd_irq);
205:
206: return 0;
207: }
208:
209: /* Who to notify on card events */
210: void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq)
211: {
1.1.1.3 root 212: PXA2xxPCMCIAState *s = (PXA2xxPCMCIAState *) opaque;
1.1 root 213: s->irq = irq;
214: s->cd_irq = cd_irq;
215: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.