Merge branch 'master' of git://git.qemu.org/qemu
[qemu.git] / hw / pl181.c
blob46855f69ded85a5a2cc549b6f31de2f5827c28ab
1 /*
2 * Arm PrimeCell PL181 MultiMedia Card Interface
4 * Copyright (c) 2007 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licensed under the GPL.
8 */
10 #include "blockdev.h"
11 #include "sysbus.h"
12 #include "sd.h"
14 //#define DEBUG_PL181 1
16 #ifdef DEBUG_PL181
17 #define DPRINTF(fmt, ...) \
18 do { printf("pl181: " fmt , ## __VA_ARGS__); } while (0)
19 #else
20 #define DPRINTF(fmt, ...) do {} while(0)
21 #endif
23 #define PL181_FIFO_LEN 16
25 typedef struct {
26 SysBusDevice busdev;
27 MemoryRegion iomem;
28 SDState *card;
29 uint32_t clock;
30 uint32_t power;
31 uint32_t cmdarg;
32 uint32_t cmd;
33 uint32_t datatimer;
34 uint32_t datalength;
35 uint32_t respcmd;
36 uint32_t response[4];
37 uint32_t datactrl;
38 uint32_t datacnt;
39 uint32_t status;
40 uint32_t mask[2];
41 int fifo_pos;
42 int fifo_len;
43 /* The linux 2.6.21 driver is buggy, and misbehaves if new data arrives
44 while it is reading the FIFO. We hack around this be defering
45 subsequent transfers until after the driver polls the status word.
46 http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4446/1
48 int linux_hack;
49 uint32_t fifo[PL181_FIFO_LEN];
50 qemu_irq irq[2];
51 /* GPIO outputs for 'card is readonly' and 'card inserted' */
52 qemu_irq cardstatus[2];
53 } pl181_state;
55 #define PL181_CMD_INDEX 0x3f
56 #define PL181_CMD_RESPONSE (1 << 6)
57 #define PL181_CMD_LONGRESP (1 << 7)
58 #define PL181_CMD_INTERRUPT (1 << 8)
59 #define PL181_CMD_PENDING (1 << 9)
60 #define PL181_CMD_ENABLE (1 << 10)
62 #define PL181_DATA_ENABLE (1 << 0)
63 #define PL181_DATA_DIRECTION (1 << 1)
64 #define PL181_DATA_MODE (1 << 2)
65 #define PL181_DATA_DMAENABLE (1 << 3)
67 #define PL181_STATUS_CMDCRCFAIL (1 << 0)
68 #define PL181_STATUS_DATACRCFAIL (1 << 1)
69 #define PL181_STATUS_CMDTIMEOUT (1 << 2)
70 #define PL181_STATUS_DATATIMEOUT (1 << 3)
71 #define PL181_STATUS_TXUNDERRUN (1 << 4)
72 #define PL181_STATUS_RXOVERRUN (1 << 5)
73 #define PL181_STATUS_CMDRESPEND (1 << 6)
74 #define PL181_STATUS_CMDSENT (1 << 7)
75 #define PL181_STATUS_DATAEND (1 << 8)
76 #define PL181_STATUS_DATABLOCKEND (1 << 10)
77 #define PL181_STATUS_CMDACTIVE (1 << 11)
78 #define PL181_STATUS_TXACTIVE (1 << 12)
79 #define PL181_STATUS_RXACTIVE (1 << 13)
80 #define PL181_STATUS_TXFIFOHALFEMPTY (1 << 14)
81 #define PL181_STATUS_RXFIFOHALFFULL (1 << 15)
82 #define PL181_STATUS_TXFIFOFULL (1 << 16)
83 #define PL181_STATUS_RXFIFOFULL (1 << 17)
84 #define PL181_STATUS_TXFIFOEMPTY (1 << 18)
85 #define PL181_STATUS_RXFIFOEMPTY (1 << 19)
86 #define PL181_STATUS_TXDATAAVLBL (1 << 20)
87 #define PL181_STATUS_RXDATAAVLBL (1 << 21)
89 #define PL181_STATUS_TX_FIFO (PL181_STATUS_TXACTIVE \
90 |PL181_STATUS_TXFIFOHALFEMPTY \
91 |PL181_STATUS_TXFIFOFULL \
92 |PL181_STATUS_TXFIFOEMPTY \
93 |PL181_STATUS_TXDATAAVLBL)
94 #define PL181_STATUS_RX_FIFO (PL181_STATUS_RXACTIVE \
95 |PL181_STATUS_RXFIFOHALFFULL \
96 |PL181_STATUS_RXFIFOFULL \
97 |PL181_STATUS_RXFIFOEMPTY \
98 |PL181_STATUS_RXDATAAVLBL)
100 static const unsigned char pl181_id[] =
101 { 0x81, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
103 static void pl181_update(pl181_state *s)
105 int i;
106 for (i = 0; i < 2; i++) {
107 qemu_set_irq(s->irq[i], (s->status & s->mask[i]) != 0);
111 static void pl181_fifo_push(pl181_state *s, uint32_t value)
113 int n;
115 if (s->fifo_len == PL181_FIFO_LEN) {
116 fprintf(stderr, "pl181: FIFO overflow\n");
117 return;
119 n = (s->fifo_pos + s->fifo_len) & (PL181_FIFO_LEN - 1);
120 s->fifo_len++;
121 s->fifo[n] = value;
122 DPRINTF("FIFO push %08x\n", (int)value);
125 static uint32_t pl181_fifo_pop(pl181_state *s)
127 uint32_t value;
129 if (s->fifo_len == 0) {
130 fprintf(stderr, "pl181: FIFO underflow\n");
131 return 0;
133 value = s->fifo[s->fifo_pos];
134 s->fifo_len--;
135 s->fifo_pos = (s->fifo_pos + 1) & (PL181_FIFO_LEN - 1);
136 DPRINTF("FIFO pop %08x\n", (int)value);
137 return value;
140 static void pl181_send_command(pl181_state *s)
142 SDRequest request;
143 uint8_t response[16];
144 int rlen;
146 request.cmd = s->cmd & PL181_CMD_INDEX;
147 request.arg = s->cmdarg;
148 DPRINTF("Command %d %08x\n", request.cmd, request.arg);
149 rlen = sd_do_command(s->card, &request, response);
150 if (rlen < 0)
151 goto error;
152 if (s->cmd & PL181_CMD_RESPONSE) {
153 #define RWORD(n) ((response[n] << 24) | (response[n + 1] << 16) \
154 | (response[n + 2] << 8) | response[n + 3])
155 if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
156 goto error;
157 if (rlen != 4 && rlen != 16)
158 goto error;
159 s->response[0] = RWORD(0);
160 if (rlen == 4) {
161 s->response[1] = s->response[2] = s->response[3] = 0;
162 } else {
163 s->response[1] = RWORD(4);
164 s->response[2] = RWORD(8);
165 s->response[3] = RWORD(12) & ~1;
167 DPRINTF("Response received\n");
168 s->status |= PL181_STATUS_CMDRESPEND;
169 #undef RWORD
170 } else {
171 DPRINTF("Command sent\n");
172 s->status |= PL181_STATUS_CMDSENT;
174 return;
176 error:
177 DPRINTF("Timeout\n");
178 s->status |= PL181_STATUS_CMDTIMEOUT;
181 /* Transfer data between the card and the FIFO. This is complicated by
182 the FIFO holding 32-bit words and the card taking data in single byte
183 chunks. FIFO bytes are transferred in little-endian order. */
185 static void pl181_fifo_run(pl181_state *s)
187 uint32_t bits;
188 uint32_t value = 0;
189 int n;
190 int is_read;
192 is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
193 if (s->datacnt != 0 && (!is_read || sd_data_ready(s->card))
194 && !s->linux_hack) {
195 if (is_read) {
196 n = 0;
197 while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
198 value |= (uint32_t)sd_read_data(s->card) << (n * 8);
199 s->datacnt--;
200 n++;
201 if (n == 4) {
202 pl181_fifo_push(s, value);
203 n = 0;
204 value = 0;
207 if (n != 0) {
208 pl181_fifo_push(s, value);
210 } else { /* write */
211 n = 0;
212 while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
213 if (n == 0) {
214 value = pl181_fifo_pop(s);
215 n = 4;
217 n--;
218 s->datacnt--;
219 sd_write_data(s->card, value & 0xff);
220 value >>= 8;
224 s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO);
225 if (s->datacnt == 0) {
226 s->status |= PL181_STATUS_DATAEND;
227 /* HACK: */
228 s->status |= PL181_STATUS_DATABLOCKEND;
229 DPRINTF("Transfer Complete\n");
231 if (s->datacnt == 0 && s->fifo_len == 0) {
232 s->datactrl &= ~PL181_DATA_ENABLE;
233 DPRINTF("Data engine idle\n");
234 } else {
235 /* Update FIFO bits. */
236 bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE;
237 if (s->fifo_len == 0) {
238 bits |= PL181_STATUS_TXFIFOEMPTY;
239 bits |= PL181_STATUS_RXFIFOEMPTY;
240 } else {
241 bits |= PL181_STATUS_TXDATAAVLBL;
242 bits |= PL181_STATUS_RXDATAAVLBL;
244 if (s->fifo_len == 16) {
245 bits |= PL181_STATUS_TXFIFOFULL;
246 bits |= PL181_STATUS_RXFIFOFULL;
248 if (s->fifo_len <= 8) {
249 bits |= PL181_STATUS_TXFIFOHALFEMPTY;
251 if (s->fifo_len >= 8) {
252 bits |= PL181_STATUS_RXFIFOHALFFULL;
254 if (s->datactrl & PL181_DATA_DIRECTION) {
255 bits &= PL181_STATUS_RX_FIFO;
256 } else {
257 bits &= PL181_STATUS_TX_FIFO;
259 s->status |= bits;
263 static uint64_t pl181_read(void *opaque, target_phys_addr_t offset,
264 unsigned size)
266 pl181_state *s = (pl181_state *)opaque;
267 uint32_t tmp;
269 if (offset >= 0xfe0 && offset < 0x1000) {
270 return pl181_id[(offset - 0xfe0) >> 2];
272 switch (offset) {
273 case 0x00: /* Power */
274 return s->power;
275 case 0x04: /* Clock */
276 return s->clock;
277 case 0x08: /* Argument */
278 return s->cmdarg;
279 case 0x0c: /* Command */
280 return s->cmd;
281 case 0x10: /* RespCmd */
282 return s->respcmd;
283 case 0x14: /* Response0 */
284 return s->response[0];
285 case 0x18: /* Response1 */
286 return s->response[1];
287 case 0x1c: /* Response2 */
288 return s->response[2];
289 case 0x20: /* Response3 */
290 return s->response[3];
291 case 0x24: /* DataTimer */
292 return s->datatimer;
293 case 0x28: /* DataLength */
294 return s->datalength;
295 case 0x2c: /* DataCtrl */
296 return s->datactrl;
297 case 0x30: /* DataCnt */
298 return s->datacnt;
299 case 0x34: /* Status */
300 tmp = s->status;
301 if (s->linux_hack) {
302 s->linux_hack = 0;
303 pl181_fifo_run(s);
304 pl181_update(s);
306 return tmp;
307 case 0x3c: /* Mask0 */
308 return s->mask[0];
309 case 0x40: /* Mask1 */
310 return s->mask[1];
311 case 0x48: /* FifoCnt */
312 /* The documentation is somewhat vague about exactly what FifoCnt
313 does. On real hardware it appears to be when decrememnted
314 when a word is transfered between the FIFO and the serial
315 data engine. DataCnt is decremented after each byte is
316 transfered between the serial engine and the card.
317 We don't emulate this level of detail, so both can be the same. */
318 tmp = (s->datacnt + 3) >> 2;
319 if (s->linux_hack) {
320 s->linux_hack = 0;
321 pl181_fifo_run(s);
322 pl181_update(s);
324 return tmp;
325 case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
326 case 0x90: case 0x94: case 0x98: case 0x9c:
327 case 0xa0: case 0xa4: case 0xa8: case 0xac:
328 case 0xb0: case 0xb4: case 0xb8: case 0xbc:
329 if (s->fifo_len == 0) {
330 fprintf(stderr, "pl181: Unexpected FIFO read\n");
331 return 0;
332 } else {
333 uint32_t value;
334 value = pl181_fifo_pop(s);
335 s->linux_hack = 1;
336 pl181_fifo_run(s);
337 pl181_update(s);
338 return value;
340 default:
341 hw_error("pl181_read: Bad offset %x\n", (int)offset);
342 return 0;
346 static void pl181_write(void *opaque, target_phys_addr_t offset,
347 uint64_t value, unsigned size)
349 pl181_state *s = (pl181_state *)opaque;
351 switch (offset) {
352 case 0x00: /* Power */
353 s->power = value & 0xff;
354 break;
355 case 0x04: /* Clock */
356 s->clock = value & 0xff;
357 break;
358 case 0x08: /* Argument */
359 s->cmdarg = value;
360 break;
361 case 0x0c: /* Command */
362 s->cmd = value;
363 if (s->cmd & PL181_CMD_ENABLE) {
364 if (s->cmd & PL181_CMD_INTERRUPT) {
365 fprintf(stderr, "pl181: Interrupt mode not implemented\n");
366 abort();
367 } if (s->cmd & PL181_CMD_PENDING) {
368 fprintf(stderr, "pl181: Pending commands not implemented\n");
369 abort();
370 } else {
371 pl181_send_command(s);
372 pl181_fifo_run(s);
374 /* The command has completed one way or the other. */
375 s->cmd &= ~PL181_CMD_ENABLE;
377 break;
378 case 0x24: /* DataTimer */
379 s->datatimer = value;
380 break;
381 case 0x28: /* DataLength */
382 s->datalength = value & 0xffff;
383 break;
384 case 0x2c: /* DataCtrl */
385 s->datactrl = value & 0xff;
386 if (value & PL181_DATA_ENABLE) {
387 s->datacnt = s->datalength;
388 pl181_fifo_run(s);
390 break;
391 case 0x38: /* Clear */
392 s->status &= ~(value & 0x7ff);
393 break;
394 case 0x3c: /* Mask0 */
395 s->mask[0] = value;
396 break;
397 case 0x40: /* Mask1 */
398 s->mask[1] = value;
399 break;
400 case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
401 case 0x90: case 0x94: case 0x98: case 0x9c:
402 case 0xa0: case 0xa4: case 0xa8: case 0xac:
403 case 0xb0: case 0xb4: case 0xb8: case 0xbc:
404 if (s->datacnt == 0) {
405 fprintf(stderr, "pl181: Unexpected FIFO write\n");
406 } else {
407 pl181_fifo_push(s, value);
408 pl181_fifo_run(s);
410 break;
411 default:
412 hw_error("pl181_write: Bad offset %x\n", (int)offset);
414 pl181_update(s);
417 static const MemoryRegionOps pl181_ops = {
418 .read = pl181_read,
419 .write = pl181_write,
420 .endianness = DEVICE_NATIVE_ENDIAN,
423 static void pl181_reset(void *opaque)
425 pl181_state *s = (pl181_state *)opaque;
427 s->power = 0;
428 s->cmdarg = 0;
429 s->cmd = 0;
430 s->datatimer = 0;
431 s->datalength = 0;
432 s->respcmd = 0;
433 s->response[0] = 0;
434 s->response[1] = 0;
435 s->response[2] = 0;
436 s->response[3] = 0;
437 s->datatimer = 0;
438 s->datalength = 0;
439 s->datactrl = 0;
440 s->datacnt = 0;
441 s->status = 0;
442 s->linux_hack = 0;
443 s->mask[0] = 0;
444 s->mask[1] = 0;
446 /* We can assume our GPIO outputs have been wired up now */
447 sd_set_cb(s->card, s->cardstatus[0], s->cardstatus[1]);
450 static int pl181_init(SysBusDevice *dev)
452 pl181_state *s = FROM_SYSBUS(pl181_state, dev);
453 DriveInfo *dinfo;
455 memory_region_init_io(&s->iomem, &pl181_ops, s, "pl181", 0x1000);
456 sysbus_init_mmio(dev, &s->iomem);
457 sysbus_init_irq(dev, &s->irq[0]);
458 sysbus_init_irq(dev, &s->irq[1]);
459 qdev_init_gpio_out(&s->busdev.qdev, s->cardstatus, 2);
460 dinfo = drive_get_next(IF_SD);
461 s->card = sd_init(dinfo ? dinfo->bdrv : NULL, 0);
462 qemu_register_reset(pl181_reset, s);
463 pl181_reset(s);
464 /* ??? Save/restore. */
465 return 0;
468 static void pl181_register_devices(void)
470 sysbus_register_dev("pl181", sizeof(pl181_state), pl181_init);
473 device_init(pl181_register_devices)