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