1 /*
2 * Arm PrimeCell PL181 MultiMedia Card Interface
3 *
4 * Copyright (c) 2007 CodeSourcery.
5 * Written by Paul Brook
6 *
7 * This code is licensed under the GPL.
8 */
9
10 #include "qemu/osdep.h"
11 #include "system/blockdev.h"
12 #include "hw/sysbus.h"
13 #include "migration/vmstate.h"
14 #include "hw/irq.h"
15 #include "hw/sd/sd.h"
16 #include "qemu/log.h"
17 #include "qemu/module.h"
18 #include "qemu/error-report.h"
19 #include "qapi/error.h"
20 #include "trace.h"
21 #include "qom/object.h"
22
23 #define PL181_FIFO_LEN 16
24
25 #define TYPE_PL181 "pl181"
26 OBJECT_DECLARE_SIMPLE_TYPE(PL181State, PL181)
27
28 #define TYPE_PL181_BUS "pl181-bus"
29
30 struct PL181State {
31 SysBusDevice parent_obj;
32
33 MemoryRegion iomem;
34 SDBus sdbus;
35 uint32_t clock;
36 uint32_t power;
37 uint32_t cmdarg;
38 uint32_t cmd;
39 uint32_t datatimer;
40 uint32_t datalength;
41 uint32_t respcmd;
42 uint32_t response[4];
43 uint32_t datactrl;
44 uint32_t datacnt;
45 uint32_t status;
46 uint32_t mask[2];
47 int32_t fifo_pos;
48 int32_t fifo_len;
49 /* The linux 2.6.21 driver is buggy, and misbehaves if new data arrives
50 while it is reading the FIFO. We hack around this by deferring
51 subsequent transfers until after the driver polls the status word.
52 http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=4446/1
53 */
54 int32_t linux_hack;
55 uint32_t fifo[PL181_FIFO_LEN]; /* TODO use Fifo32 */
56 qemu_irq irq[2];
57 /* GPIO outputs for 'card is readonly' and 'card inserted' */
58 qemu_irq card_readonly;
59 qemu_irq card_inserted;
60 };
61
62 static const VMStateDescription vmstate_pl181 = {
63 .name = "pl181",
64 .version_id = 1,
65 .minimum_version_id = 1,
66 .fields = (const VMStateField[]) {
67 VMSTATE_UINT32(clock, PL181State),
68 VMSTATE_UINT32(power, PL181State),
69 VMSTATE_UINT32(cmdarg, PL181State),
70 VMSTATE_UINT32(cmd, PL181State),
71 VMSTATE_UINT32(datatimer, PL181State),
72 VMSTATE_UINT32(datalength, PL181State),
73 VMSTATE_UINT32(respcmd, PL181State),
74 VMSTATE_UINT32_ARRAY(response, PL181State, 4),
75 VMSTATE_UINT32(datactrl, PL181State),
76 VMSTATE_UINT32(datacnt, PL181State),
77 VMSTATE_UINT32(status, PL181State),
78 VMSTATE_UINT32_ARRAY(mask, PL181State, 2),
79 VMSTATE_INT32(fifo_pos, PL181State),
80 VMSTATE_INT32(fifo_len, PL181State),
81 VMSTATE_INT32(linux_hack, PL181State),
82 VMSTATE_UINT32_ARRAY(fifo, PL181State, PL181_FIFO_LEN),
83 VMSTATE_END_OF_LIST()
84 }
85 };
86
87 #define PL181_CMD_INDEX 0x3f
88 #define PL181_CMD_RESPONSE (1 << 6)
89 #define PL181_CMD_LONGRESP (1 << 7)
90 #define PL181_CMD_INTERRUPT (1 << 8)
91 #define PL181_CMD_PENDING (1 << 9)
92 #define PL181_CMD_ENABLE (1 << 10)
93
94 #define PL181_DATA_ENABLE (1 << 0)
95 #define PL181_DATA_DIRECTION (1 << 1)
96 #define PL181_DATA_MODE (1 << 2)
97 #define PL181_DATA_DMAENABLE (1 << 3)
98
99 #define PL181_STATUS_CMDCRCFAIL (1 << 0)
100 #define PL181_STATUS_DATACRCFAIL (1 << 1)
101 #define PL181_STATUS_CMDTIMEOUT (1 << 2)
102 #define PL181_STATUS_DATATIMEOUT (1 << 3)
103 #define PL181_STATUS_TXUNDERRUN (1 << 4)
104 #define PL181_STATUS_RXOVERRUN (1 << 5)
105 #define PL181_STATUS_CMDRESPEND (1 << 6)
106 #define PL181_STATUS_CMDSENT (1 << 7)
107 #define PL181_STATUS_DATAEND (1 << 8)
108 #define PL181_STATUS_DATABLOCKEND (1 << 10)
109 #define PL181_STATUS_CMDACTIVE (1 << 11)
110 #define PL181_STATUS_TXACTIVE (1 << 12)
111 #define PL181_STATUS_RXACTIVE (1 << 13)
112 #define PL181_STATUS_TXFIFOHALFEMPTY (1 << 14)
113 #define PL181_STATUS_RXFIFOHALFFULL (1 << 15)
114 #define PL181_STATUS_TXFIFOFULL (1 << 16)
115 #define PL181_STATUS_RXFIFOFULL (1 << 17)
116 #define PL181_STATUS_TXFIFOEMPTY (1 << 18)
117 #define PL181_STATUS_RXFIFOEMPTY (1 << 19)
118 #define PL181_STATUS_TXDATAAVLBL (1 << 20)
119 #define PL181_STATUS_RXDATAAVLBL (1 << 21)
120
121 #define PL181_STATUS_TX_FIFO (PL181_STATUS_TXACTIVE \
122 |PL181_STATUS_TXFIFOHALFEMPTY \
123 |PL181_STATUS_TXFIFOFULL \
124 |PL181_STATUS_TXFIFOEMPTY \
125 |PL181_STATUS_TXDATAAVLBL)
126 #define PL181_STATUS_RX_FIFO (PL181_STATUS_RXACTIVE \
127 |PL181_STATUS_RXFIFOHALFFULL \
128 |PL181_STATUS_RXFIFOFULL \
129 |PL181_STATUS_RXFIFOEMPTY \
130 |PL181_STATUS_RXDATAAVLBL)
131
132 static const unsigned char pl181_id[] =
133 { 0x81, 0x11, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };
134
pl181_update(PL181State * s)135 static void pl181_update(PL181State *s)
136 {
137 int i;
138 for (i = 0; i < 2; i++) {
139 qemu_set_irq(s->irq[i], (s->status & s->mask[i]) != 0);
140 }
141 }
142
pl181_fifo_push(PL181State * s,uint32_t value)143 static void pl181_fifo_push(PL181State *s, uint32_t value)
144 {
145 int n;
146
147 if (s->fifo_len == PL181_FIFO_LEN) {
148 error_report("%s: FIFO overflow", __func__);
149 return;
150 }
151 n = (s->fifo_pos + s->fifo_len) & (PL181_FIFO_LEN - 1);
152 s->fifo_len++;
153 s->fifo[n] = value;
154 trace_pl181_fifo_push(value);
155 }
156
pl181_fifo_pop(PL181State * s)157 static uint32_t pl181_fifo_pop(PL181State *s)
158 {
159 uint32_t value;
160
161 if (s->fifo_len == 0) {
162 error_report("%s: FIFO underflow", __func__);
163 return 0;
164 }
165 value = s->fifo[s->fifo_pos];
166 s->fifo_len--;
167 s->fifo_pos = (s->fifo_pos + 1) & (PL181_FIFO_LEN - 1);
168 trace_pl181_fifo_pop(value);
169 return value;
170 }
171
pl181_do_command(PL181State * s)172 static void pl181_do_command(PL181State *s)
173 {
174 SDRequest request;
175 uint8_t response[16];
176 size_t rlen;
177
178 request.cmd = s->cmd & PL181_CMD_INDEX;
179 request.arg = s->cmdarg;
180 trace_pl181_command_send(request.cmd, request.arg);
181 rlen = sdbus_do_command(&s->sdbus, &request, response, sizeof(response));
182 if (s->cmd & PL181_CMD_RESPONSE) {
183 if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
184 goto error;
185 if (rlen != 4 && rlen != 16)
186 goto error;
187 s->response[0] = ldl_be_p(&response[0]);
188 if (rlen == 4) {
189 s->response[1] = s->response[2] = s->response[3] = 0;
190 } else {
191 s->response[1] = ldl_be_p(&response[4]);
192 s->response[2] = ldl_be_p(&response[8]);
193 s->response[3] = ldl_be_p(&response[12]) & ~1;
194 }
195 trace_pl181_command_response_pending();
196 s->status |= PL181_STATUS_CMDRESPEND;
197 } else {
198 trace_pl181_command_sent();
199 s->status |= PL181_STATUS_CMDSENT;
200 }
201 return;
202
203 error:
204 trace_pl181_command_timeout();
205 s->status |= PL181_STATUS_CMDTIMEOUT;
206 }
207
208 /* Transfer data between the card and the FIFO. This is complicated by
209 the FIFO holding 32-bit words and the card taking data in single byte
210 chunks. FIFO bytes are transferred in little-endian order. */
211
pl181_fifo_run(PL181State * s)212 static void pl181_fifo_run(PL181State *s)
213 {
214 uint32_t bits;
215 uint32_t value = 0;
216 int n;
217 int is_read;
218
219 is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
220 if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus))
221 && !s->linux_hack) {
222 if (is_read) {
223 n = 0;
224 while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
225 value |= (uint32_t)sdbus_read_byte(&s->sdbus) << (n * 8);
226 s->datacnt--;
227 n++;
228 if (n == 4) {
229 pl181_fifo_push(s, value);
230 n = 0;
231 value = 0;
232 }
233 }
234 if (n != 0) {
235 pl181_fifo_push(s, value);
236 }
237 } else { /* write */
238 n = 0;
239 while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
240 if (n == 0) {
241 value = pl181_fifo_pop(s);
242 n = 4;
243 }
244 n--;
245 s->datacnt--;
246 sdbus_write_byte(&s->sdbus, value & 0xff);
247 value >>= 8;
248 }
249 }
250 }
251 s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO);
252 if (s->datacnt == 0) {
253 s->status |= PL181_STATUS_DATAEND;
254 /* HACK: */
255 s->status |= PL181_STATUS_DATABLOCKEND;
256 trace_pl181_fifo_transfer_complete();
257 }
258 if (s->datacnt == 0 && s->fifo_len == 0) {
259 s->datactrl &= ~PL181_DATA_ENABLE;
260 trace_pl181_data_engine_idle();
261 } else {
262 /* Update FIFO bits. */
263 bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE;
264 if (s->fifo_len == 0) {
265 bits |= PL181_STATUS_TXFIFOEMPTY;
266 bits |= PL181_STATUS_RXFIFOEMPTY;
267 } else {
268 bits |= PL181_STATUS_TXDATAAVLBL;
269 bits |= PL181_STATUS_RXDATAAVLBL;
270 }
271 if (s->fifo_len == 16) {
272 bits |= PL181_STATUS_TXFIFOFULL;
273 bits |= PL181_STATUS_RXFIFOFULL;
274 }
275 if (s->fifo_len <= 8) {
276 bits |= PL181_STATUS_TXFIFOHALFEMPTY;
277 }
278 if (s->fifo_len >= 8) {
279 bits |= PL181_STATUS_RXFIFOHALFFULL;
280 }
281 if (s->datactrl & PL181_DATA_DIRECTION) {
282 bits &= PL181_STATUS_RX_FIFO;
283 } else {
284 bits &= PL181_STATUS_TX_FIFO;
285 }
286 s->status |= bits;
287 }
288 }
289
pl181_read(void * opaque,hwaddr offset,unsigned size)290 static uint64_t pl181_read(void *opaque, hwaddr offset,
291 unsigned size)
292 {
293 PL181State *s = (PL181State *)opaque;
294 uint32_t tmp;
295
296 if (offset >= 0xfe0 && offset < 0x1000) {
297 return pl181_id[(offset - 0xfe0) >> 2];
298 }
299 switch (offset) {
300 case 0x00: /* Power */
301 return s->power;
302 case 0x04: /* Clock */
303 return s->clock;
304 case 0x08: /* Argument */
305 return s->cmdarg;
306 case 0x0c: /* Command */
307 return s->cmd;
308 case 0x10: /* RespCmd */
309 return s->respcmd;
310 case 0x14: /* Response0 */
311 return s->response[0];
312 case 0x18: /* Response1 */
313 return s->response[1];
314 case 0x1c: /* Response2 */
315 return s->response[2];
316 case 0x20: /* Response3 */
317 return s->response[3];
318 case 0x24: /* DataTimer */
319 return s->datatimer;
320 case 0x28: /* DataLength */
321 return s->datalength;
322 case 0x2c: /* DataCtrl */
323 return s->datactrl;
324 case 0x30: /* DataCnt */
325 return s->datacnt;
326 case 0x34: /* Status */
327 tmp = s->status;
328 if (s->linux_hack) {
329 s->linux_hack = 0;
330 pl181_fifo_run(s);
331 pl181_update(s);
332 }
333 return tmp;
334 case 0x3c: /* Mask0 */
335 return s->mask[0];
336 case 0x40: /* Mask1 */
337 return s->mask[1];
338 case 0x48: /* FifoCnt */
339 /* The documentation is somewhat vague about exactly what FifoCnt
340 does. On real hardware it appears to be when decrememnted
341 when a word is transferred between the FIFO and the serial
342 data engine. DataCnt is decremented after each byte is
343 transferred between the serial engine and the card.
344 We don't emulate this level of detail, so both can be the same. */
345 tmp = (s->datacnt + 3) >> 2;
346 if (s->linux_hack) {
347 s->linux_hack = 0;
348 pl181_fifo_run(s);
349 pl181_update(s);
350 }
351 return tmp;
352 case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
353 case 0x90: case 0x94: case 0x98: case 0x9c:
354 case 0xa0: case 0xa4: case 0xa8: case 0xac:
355 case 0xb0: case 0xb4: case 0xb8: case 0xbc:
356 if (s->fifo_len == 0) {
357 qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO read\n");
358 return 0;
359 } else {
360 uint32_t value;
361 value = pl181_fifo_pop(s);
362 s->linux_hack = 1;
363 pl181_fifo_run(s);
364 pl181_update(s);
365 return value;
366 }
367 default:
368 qemu_log_mask(LOG_GUEST_ERROR,
369 "pl181_read: Bad offset %x\n", (int)offset);
370 return 0;
371 }
372 }
373
pl181_write(void * opaque,hwaddr offset,uint64_t value,unsigned size)374 static void pl181_write(void *opaque, hwaddr offset,
375 uint64_t value, unsigned size)
376 {
377 PL181State *s = (PL181State *)opaque;
378
379 switch (offset) {
380 case 0x00: /* Power */
381 s->power = value & 0xff;
382 break;
383 case 0x04: /* Clock */
384 s->clock = value & 0xff;
385 break;
386 case 0x08: /* Argument */
387 s->cmdarg = value;
388 break;
389 case 0x0c: /* Command */
390 s->cmd = value;
391 if (s->cmd & PL181_CMD_ENABLE) {
392 if (s->cmd & PL181_CMD_INTERRUPT) {
393 qemu_log_mask(LOG_UNIMP,
394 "pl181: Interrupt mode not implemented\n");
395 } if (s->cmd & PL181_CMD_PENDING) {
396 qemu_log_mask(LOG_UNIMP,
397 "pl181: Pending commands not implemented\n");
398 } else {
399 pl181_do_command(s);
400 pl181_fifo_run(s);
401 }
402 /* The command has completed one way or the other. */
403 s->cmd &= ~PL181_CMD_ENABLE;
404 }
405 break;
406 case 0x24: /* DataTimer */
407 s->datatimer = value;
408 break;
409 case 0x28: /* DataLength */
410 s->datalength = value & 0xffff;
411 break;
412 case 0x2c: /* DataCtrl */
413 s->datactrl = value & 0xff;
414 if (value & PL181_DATA_ENABLE) {
415 s->datacnt = s->datalength;
416 pl181_fifo_run(s);
417 }
418 break;
419 case 0x38: /* Clear */
420 s->status &= ~(value & 0x7ff);
421 break;
422 case 0x3c: /* Mask0 */
423 s->mask[0] = value;
424 break;
425 case 0x40: /* Mask1 */
426 s->mask[1] = value;
427 break;
428 case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
429 case 0x90: case 0x94: case 0x98: case 0x9c:
430 case 0xa0: case 0xa4: case 0xa8: case 0xac:
431 case 0xb0: case 0xb4: case 0xb8: case 0xbc:
432 if (s->datacnt == 0) {
433 qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO write\n");
434 } else {
435 pl181_fifo_push(s, value);
436 pl181_fifo_run(s);
437 }
438 break;
439 default:
440 qemu_log_mask(LOG_GUEST_ERROR,
441 "pl181_write: Bad offset %x\n", (int)offset);
442 }
443 pl181_update(s);
444 }
445
446 static const MemoryRegionOps pl181_ops = {
447 .read = pl181_read,
448 .write = pl181_write,
449 .endianness = DEVICE_NATIVE_ENDIAN,
450 };
451
pl181_set_readonly(DeviceState * dev,bool level)452 static void pl181_set_readonly(DeviceState *dev, bool level)
453 {
454 PL181State *s = (PL181State *)dev;
455
456 qemu_set_irq(s->card_readonly, level);
457 }
458
pl181_set_inserted(DeviceState * dev,bool level)459 static void pl181_set_inserted(DeviceState *dev, bool level)
460 {
461 PL181State *s = (PL181State *)dev;
462
463 qemu_set_irq(s->card_inserted, level);
464 }
465
pl181_reset(DeviceState * d)466 static void pl181_reset(DeviceState *d)
467 {
468 PL181State *s = PL181(d);
469
470 s->power = 0;
471 s->cmdarg = 0;
472 s->cmd = 0;
473 s->datatimer = 0;
474 s->datalength = 0;
475 s->respcmd = 0;
476 s->response[0] = 0;
477 s->response[1] = 0;
478 s->response[2] = 0;
479 s->response[3] = 0;
480 s->datatimer = 0;
481 s->datalength = 0;
482 s->datactrl = 0;
483 s->datacnt = 0;
484 s->status = 0;
485 s->linux_hack = 0;
486 s->mask[0] = 0;
487 s->mask[1] = 0;
488
489 /* Reset other state based on current card insertion/readonly status */
490 pl181_set_inserted(DEVICE(s), sdbus_get_inserted(&s->sdbus));
491 pl181_set_readonly(DEVICE(s), sdbus_get_readonly(&s->sdbus));
492 }
493
pl181_init(Object * obj)494 static void pl181_init(Object *obj)
495 {
496 DeviceState *dev = DEVICE(obj);
497 PL181State *s = PL181(obj);
498 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
499
500 memory_region_init_io(&s->iomem, obj, &pl181_ops, s, "pl181", 0x1000);
501 sysbus_init_mmio(sbd, &s->iomem);
502 sysbus_init_irq(sbd, &s->irq[0]);
503 sysbus_init_irq(sbd, &s->irq[1]);
504 qdev_init_gpio_out_named(dev, &s->card_readonly, "card-read-only", 1);
505 qdev_init_gpio_out_named(dev, &s->card_inserted, "card-inserted", 1);
506
507 qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_PL181_BUS, dev, "sd-bus");
508 }
509
pl181_class_init(ObjectClass * klass,const void * data)510 static void pl181_class_init(ObjectClass *klass, const void *data)
511 {
512 DeviceClass *k = DEVICE_CLASS(klass);
513
514 k->vmsd = &vmstate_pl181;
515 device_class_set_legacy_reset(k, pl181_reset);
516 /* Reason: output IRQs should be wired up */
517 k->user_creatable = false;
518 }
519
pl181_bus_class_init(ObjectClass * klass,const void * data)520 static void pl181_bus_class_init(ObjectClass *klass, const void *data)
521 {
522 SDBusClass *sbc = SD_BUS_CLASS(klass);
523
524 sbc->set_inserted = pl181_set_inserted;
525 sbc->set_readonly = pl181_set_readonly;
526 }
527
528 static const TypeInfo pl181_info[] = {
529 {
530 .name = TYPE_PL181,
531 .parent = TYPE_SYS_BUS_DEVICE,
532 .instance_size = sizeof(PL181State),
533 .instance_init = pl181_init,
534 .class_init = pl181_class_init,
535 },
536 {
537 .name = TYPE_PL181_BUS,
538 .parent = TYPE_SD_BUS,
539 .instance_size = sizeof(SDBus),
540 .class_init = pl181_bus_class_init,
541 },
542 };
543
544 DEFINE_TYPES(pl181_info)
545