|
|
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:
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: {
25: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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: {
37: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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: {
47: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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: {
59: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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: {
69: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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: {
81: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
82:
83: if (s->slot.attached) {
84: s->card->io_write(s->card->state, offset, value);
85: }
86: }
87:
88: static CPUReadMemoryFunc *pxa2xx_pcmcia_common_readfn[] = {
89: pxa2xx_pcmcia_common_read,
90: pxa2xx_pcmcia_common_read,
91: pxa2xx_pcmcia_common_read,
92: };
93:
94: static CPUWriteMemoryFunc *pxa2xx_pcmcia_common_writefn[] = {
95: pxa2xx_pcmcia_common_write,
96: pxa2xx_pcmcia_common_write,
97: pxa2xx_pcmcia_common_write,
98: };
99:
100: static CPUReadMemoryFunc *pxa2xx_pcmcia_attr_readfn[] = {
101: pxa2xx_pcmcia_attr_read,
102: pxa2xx_pcmcia_attr_read,
103: pxa2xx_pcmcia_attr_read,
104: };
105:
106: static CPUWriteMemoryFunc *pxa2xx_pcmcia_attr_writefn[] = {
107: pxa2xx_pcmcia_attr_write,
108: pxa2xx_pcmcia_attr_write,
109: pxa2xx_pcmcia_attr_write,
110: };
111:
112: static CPUReadMemoryFunc *pxa2xx_pcmcia_io_readfn[] = {
113: pxa2xx_pcmcia_io_read,
114: pxa2xx_pcmcia_io_read,
115: pxa2xx_pcmcia_io_read,
116: };
117:
118: static CPUWriteMemoryFunc *pxa2xx_pcmcia_io_writefn[] = {
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: {
126: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
127: if (!s->irq)
128: return;
129:
130: qemu_set_irq(s->irq, level);
131: }
132:
133: struct pxa2xx_pcmcia_s *pxa2xx_pcmcia_init(target_phys_addr_t base)
134: {
135: int iomemtype;
136: struct pxa2xx_pcmcia_s *s;
137:
138: s = (struct pxa2xx_pcmcia_s *)
139: qemu_mallocz(sizeof(struct pxa2xx_pcmcia_s));
140:
141: /* Socket I/O Memory Space */
142: iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_io_readfn,
143: pxa2xx_pcmcia_io_writefn, s);
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 */
149: iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_attr_readfn,
150: pxa2xx_pcmcia_attr_writefn, s);
1.1.1.2 ! root 151: cpu_register_physical_memory(base | 0x08000000, 0x04000000, iomemtype);
1.1 root 152:
153: /* Socket Common Memory Space */
154: iomemtype = cpu_register_io_memory(0, pxa2xx_pcmcia_common_readfn,
155: pxa2xx_pcmcia_common_writefn, s);
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 */
169: int pxa2xx_pcmcia_attach(void *opaque, struct pcmcia_card_s *card)
170: {
171: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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: {
191: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
192: if (!s->slot.attached)
193: return -ENOENT;
194:
195: s->card->detach(s->card->state);
196: s->card->slot = 0;
197: s->card = 0;
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: {
212: struct pxa2xx_pcmcia_s *s = (struct pxa2xx_pcmcia_s *) opaque;
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.