xref: /openbmc/qemu/hw/sd/pl181.c (revision 5e37bc4997c32a1c9a6621a060462c84df9f1b8f)
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 "sysemu/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  
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  
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  
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  
172  static void pl181_do_command(PL181State *s)
173  {
174      SDRequest request;
175      uint8_t response[16];
176      int 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);
182      if (rlen < 0)
183          goto error;
184      if (s->cmd & PL181_CMD_RESPONSE) {
185          if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
186              goto error;
187          if (rlen != 4 && rlen != 16)
188              goto error;
189          s->response[0] = ldl_be_p(&response[0]);
190          if (rlen == 4) {
191              s->response[1] = s->response[2] = s->response[3] = 0;
192          } else {
193              s->response[1] = ldl_be_p(&response[4]);
194              s->response[2] = ldl_be_p(&response[8]);
195              s->response[3] = ldl_be_p(&response[12]) & ~1;
196          }
197          trace_pl181_command_response_pending();
198          s->status |= PL181_STATUS_CMDRESPEND;
199      } else {
200          trace_pl181_command_sent();
201          s->status |= PL181_STATUS_CMDSENT;
202      }
203      return;
204  
205  error:
206      trace_pl181_command_timeout();
207      s->status |= PL181_STATUS_CMDTIMEOUT;
208  }
209  
210  /* Transfer data between the card and the FIFO.  This is complicated by
211     the FIFO holding 32-bit words and the card taking data in single byte
212     chunks.  FIFO bytes are transferred in little-endian order.  */
213  
214  static void pl181_fifo_run(PL181State *s)
215  {
216      uint32_t bits;
217      uint32_t value = 0;
218      int n;
219      int is_read;
220  
221      is_read = (s->datactrl & PL181_DATA_DIRECTION) != 0;
222      if (s->datacnt != 0 && (!is_read || sdbus_data_ready(&s->sdbus))
223              && !s->linux_hack) {
224          if (is_read) {
225              n = 0;
226              while (s->datacnt && s->fifo_len < PL181_FIFO_LEN) {
227                  value |= (uint32_t)sdbus_read_byte(&s->sdbus) << (n * 8);
228                  s->datacnt--;
229                  n++;
230                  if (n == 4) {
231                      pl181_fifo_push(s, value);
232                      n = 0;
233                      value = 0;
234                  }
235              }
236              if (n != 0) {
237                  pl181_fifo_push(s, value);
238              }
239          } else { /* write */
240              n = 0;
241              while (s->datacnt > 0 && (s->fifo_len > 0 || n > 0)) {
242                  if (n == 0) {
243                      value = pl181_fifo_pop(s);
244                      n = 4;
245                  }
246                  n--;
247                  s->datacnt--;
248                  sdbus_write_byte(&s->sdbus, value & 0xff);
249                  value >>= 8;
250              }
251          }
252      }
253      s->status &= ~(PL181_STATUS_RX_FIFO | PL181_STATUS_TX_FIFO);
254      if (s->datacnt == 0) {
255          s->status |= PL181_STATUS_DATAEND;
256          /* HACK: */
257          s->status |= PL181_STATUS_DATABLOCKEND;
258          trace_pl181_fifo_transfer_complete();
259      }
260      if (s->datacnt == 0 && s->fifo_len == 0) {
261          s->datactrl &= ~PL181_DATA_ENABLE;
262          trace_pl181_data_engine_idle();
263      } else {
264          /* Update FIFO bits.  */
265          bits = PL181_STATUS_TXACTIVE | PL181_STATUS_RXACTIVE;
266          if (s->fifo_len == 0) {
267              bits |= PL181_STATUS_TXFIFOEMPTY;
268              bits |= PL181_STATUS_RXFIFOEMPTY;
269          } else {
270              bits |= PL181_STATUS_TXDATAAVLBL;
271              bits |= PL181_STATUS_RXDATAAVLBL;
272          }
273          if (s->fifo_len == 16) {
274              bits |= PL181_STATUS_TXFIFOFULL;
275              bits |= PL181_STATUS_RXFIFOFULL;
276          }
277          if (s->fifo_len <= 8) {
278              bits |= PL181_STATUS_TXFIFOHALFEMPTY;
279          }
280          if (s->fifo_len >= 8) {
281              bits |= PL181_STATUS_RXFIFOHALFFULL;
282          }
283          if (s->datactrl & PL181_DATA_DIRECTION) {
284              bits &= PL181_STATUS_RX_FIFO;
285          } else {
286              bits &= PL181_STATUS_TX_FIFO;
287          }
288          s->status |= bits;
289      }
290  }
291  
292  static uint64_t pl181_read(void *opaque, hwaddr offset,
293                             unsigned size)
294  {
295      PL181State *s = (PL181State *)opaque;
296      uint32_t tmp;
297  
298      if (offset >= 0xfe0 && offset < 0x1000) {
299          return pl181_id[(offset - 0xfe0) >> 2];
300      }
301      switch (offset) {
302      case 0x00: /* Power */
303          return s->power;
304      case 0x04: /* Clock */
305          return s->clock;
306      case 0x08: /* Argument */
307          return s->cmdarg;
308      case 0x0c: /* Command */
309          return s->cmd;
310      case 0x10: /* RespCmd */
311          return s->respcmd;
312      case 0x14: /* Response0 */
313          return s->response[0];
314      case 0x18: /* Response1 */
315          return s->response[1];
316      case 0x1c: /* Response2 */
317          return s->response[2];
318      case 0x20: /* Response3 */
319          return s->response[3];
320      case 0x24: /* DataTimer */
321          return s->datatimer;
322      case 0x28: /* DataLength */
323          return s->datalength;
324      case 0x2c: /* DataCtrl */
325          return s->datactrl;
326      case 0x30: /* DataCnt */
327          return s->datacnt;
328      case 0x34: /* Status */
329          tmp = s->status;
330          if (s->linux_hack) {
331              s->linux_hack = 0;
332              pl181_fifo_run(s);
333              pl181_update(s);
334          }
335          return tmp;
336      case 0x3c: /* Mask0 */
337          return s->mask[0];
338      case 0x40: /* Mask1 */
339          return s->mask[1];
340      case 0x48: /* FifoCnt */
341          /* The documentation is somewhat vague about exactly what FifoCnt
342             does.  On real hardware it appears to be when decrememnted
343             when a word is transferred between the FIFO and the serial
344             data engine.  DataCnt is decremented after each byte is
345             transferred between the serial engine and the card.
346             We don't emulate this level of detail, so both can be the same.  */
347          tmp = (s->datacnt + 3) >> 2;
348          if (s->linux_hack) {
349              s->linux_hack = 0;
350              pl181_fifo_run(s);
351              pl181_update(s);
352          }
353          return tmp;
354      case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
355      case 0x90: case 0x94: case 0x98: case 0x9c:
356      case 0xa0: case 0xa4: case 0xa8: case 0xac:
357      case 0xb0: case 0xb4: case 0xb8: case 0xbc:
358          if (s->fifo_len == 0) {
359              qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO read\n");
360              return 0;
361          } else {
362              uint32_t value;
363              value = pl181_fifo_pop(s);
364              s->linux_hack = 1;
365              pl181_fifo_run(s);
366              pl181_update(s);
367              return value;
368          }
369      default:
370          qemu_log_mask(LOG_GUEST_ERROR,
371                        "pl181_read: Bad offset %x\n", (int)offset);
372          return 0;
373      }
374  }
375  
376  static void pl181_write(void *opaque, hwaddr offset,
377                          uint64_t value, unsigned size)
378  {
379      PL181State *s = (PL181State *)opaque;
380  
381      switch (offset) {
382      case 0x00: /* Power */
383          s->power = value & 0xff;
384          break;
385      case 0x04: /* Clock */
386          s->clock = value & 0xff;
387          break;
388      case 0x08: /* Argument */
389          s->cmdarg = value;
390          break;
391      case 0x0c: /* Command */
392          s->cmd = value;
393          if (s->cmd & PL181_CMD_ENABLE) {
394              if (s->cmd & PL181_CMD_INTERRUPT) {
395                  qemu_log_mask(LOG_UNIMP,
396                                "pl181: Interrupt mode not implemented\n");
397              } if (s->cmd & PL181_CMD_PENDING) {
398                  qemu_log_mask(LOG_UNIMP,
399                                "pl181: Pending commands not implemented\n");
400              } else {
401                  pl181_do_command(s);
402                  pl181_fifo_run(s);
403              }
404              /* The command has completed one way or the other.  */
405              s->cmd &= ~PL181_CMD_ENABLE;
406          }
407          break;
408      case 0x24: /* DataTimer */
409          s->datatimer = value;
410          break;
411      case 0x28: /* DataLength */
412          s->datalength = value & 0xffff;
413          break;
414      case 0x2c: /* DataCtrl */
415          s->datactrl = value & 0xff;
416          if (value & PL181_DATA_ENABLE) {
417              s->datacnt = s->datalength;
418              pl181_fifo_run(s);
419          }
420          break;
421      case 0x38: /* Clear */
422          s->status &= ~(value & 0x7ff);
423          break;
424      case 0x3c: /* Mask0 */
425          s->mask[0] = value;
426          break;
427      case 0x40: /* Mask1 */
428          s->mask[1] = value;
429          break;
430      case 0x80: case 0x84: case 0x88: case 0x8c: /* FifoData */
431      case 0x90: case 0x94: case 0x98: case 0x9c:
432      case 0xa0: case 0xa4: case 0xa8: case 0xac:
433      case 0xb0: case 0xb4: case 0xb8: case 0xbc:
434          if (s->datacnt == 0) {
435              qemu_log_mask(LOG_GUEST_ERROR, "pl181: Unexpected FIFO write\n");
436          } else {
437              pl181_fifo_push(s, value);
438              pl181_fifo_run(s);
439          }
440          break;
441      default:
442          qemu_log_mask(LOG_GUEST_ERROR,
443                        "pl181_write: Bad offset %x\n", (int)offset);
444      }
445      pl181_update(s);
446  }
447  
448  static const MemoryRegionOps pl181_ops = {
449      .read = pl181_read,
450      .write = pl181_write,
451      .endianness = DEVICE_NATIVE_ENDIAN,
452  };
453  
454  static void pl181_set_readonly(DeviceState *dev, bool level)
455  {
456      PL181State *s = (PL181State *)dev;
457  
458      qemu_set_irq(s->card_readonly, level);
459  }
460  
461  static void pl181_set_inserted(DeviceState *dev, bool level)
462  {
463      PL181State *s = (PL181State *)dev;
464  
465      qemu_set_irq(s->card_inserted, level);
466  }
467  
468  static void pl181_reset(DeviceState *d)
469  {
470      PL181State *s = PL181(d);
471  
472      s->power = 0;
473      s->cmdarg = 0;
474      s->cmd = 0;
475      s->datatimer = 0;
476      s->datalength = 0;
477      s->respcmd = 0;
478      s->response[0] = 0;
479      s->response[1] = 0;
480      s->response[2] = 0;
481      s->response[3] = 0;
482      s->datatimer = 0;
483      s->datalength = 0;
484      s->datactrl = 0;
485      s->datacnt = 0;
486      s->status = 0;
487      s->linux_hack = 0;
488      s->mask[0] = 0;
489      s->mask[1] = 0;
490  
491      /* Reset other state based on current card insertion/readonly status */
492      pl181_set_inserted(DEVICE(s), sdbus_get_inserted(&s->sdbus));
493      pl181_set_readonly(DEVICE(s), sdbus_get_readonly(&s->sdbus));
494  }
495  
496  static void pl181_init(Object *obj)
497  {
498      DeviceState *dev = DEVICE(obj);
499      PL181State *s = PL181(obj);
500      SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
501  
502      memory_region_init_io(&s->iomem, obj, &pl181_ops, s, "pl181", 0x1000);
503      sysbus_init_mmio(sbd, &s->iomem);
504      sysbus_init_irq(sbd, &s->irq[0]);
505      sysbus_init_irq(sbd, &s->irq[1]);
506      qdev_init_gpio_out_named(dev, &s->card_readonly, "card-read-only", 1);
507      qdev_init_gpio_out_named(dev, &s->card_inserted, "card-inserted", 1);
508  
509      qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_PL181_BUS, dev, "sd-bus");
510  }
511  
512  static void pl181_class_init(ObjectClass *klass, void *data)
513  {
514      DeviceClass *k = DEVICE_CLASS(klass);
515  
516      k->vmsd = &vmstate_pl181;
517      k->reset = pl181_reset;
518      /* Reason: output IRQs should be wired up */
519      k->user_creatable = false;
520  }
521  
522  static void pl181_bus_class_init(ObjectClass *klass, void *data)
523  {
524      SDBusClass *sbc = SD_BUS_CLASS(klass);
525  
526      sbc->set_inserted = pl181_set_inserted;
527      sbc->set_readonly = pl181_set_readonly;
528  }
529  
530  static const TypeInfo pl181_info[] = {
531      {
532          .name           = TYPE_PL181,
533          .parent         = TYPE_SYS_BUS_DEVICE,
534          .instance_size  = sizeof(PL181State),
535          .instance_init  = pl181_init,
536          .class_init     = pl181_class_init,
537      },
538      {
539          .name           = TYPE_PL181_BUS,
540          .parent         = TYPE_SD_BUS,
541          .instance_size  = sizeof(SDBus),
542          .class_init     = pl181_bus_class_init,
543      },
544  };
545  
546  DEFINE_TYPES(pl181_info)
547