xref: /openbmc/qemu/hw/sd/pl181.c (revision d2d08975fc01e4898ab43eae0d03d53e689048cd)
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