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