1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "hw/hw.h"
27#include "sysemu/block-backend.h"
28#include "sysemu/blockdev.h"
29#include "sysemu/dma.h"
30#include "qemu/timer.h"
31#include "qemu/bitops.h"
32#include "sdhci-internal.h"
33#include "qapi/error.h"
34#include "qemu/log.h"
35
36
37#ifndef SDHC_DEBUG
38#define SDHC_DEBUG 0
39#endif
40
41#define DPRINT_L1(fmt, args...) \
42 do { \
43 if (SDHC_DEBUG) { \
44 fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
45 } \
46 } while (0)
47#define DPRINT_L2(fmt, args...) \
48 do { \
49 if (SDHC_DEBUG > 1) { \
50 fprintf(stderr, "QEMU SDHC: " fmt, ## args); \
51 } \
52 } while (0)
53#define ERRPRINT(fmt, args...) \
54 do { \
55 if (SDHC_DEBUG) { \
56 fprintf(stderr, "QEMU SDHC ERROR: " fmt, ## args); \
57 } \
58 } while (0)
59
60#define TYPE_SDHCI_BUS "sdhci-bus"
61#define SDHCI_BUS(obj) OBJECT_CHECK(SDBus, (obj), TYPE_SDHCI_BUS)
62
63#define MASKED_WRITE(reg, mask, val) (reg = (reg & (mask)) | (val))
64
65static uint8_t sdhci_slotint(SDHCIState *s)
66{
67 return (s->norintsts & s->norintsigen) || (s->errintsts & s->errintsigen) ||
68 ((s->norintsts & SDHC_NIS_INSERT) && (s->wakcon & SDHC_WKUP_ON_INS)) ||
69 ((s->norintsts & SDHC_NIS_REMOVE) && (s->wakcon & SDHC_WKUP_ON_RMV));
70}
71
72static inline void sdhci_update_irq(SDHCIState *s)
73{
74 qemu_set_irq(s->irq, sdhci_slotint(s));
75}
76
77static void sdhci_raise_insertion_irq(void *opaque)
78{
79 SDHCIState *s = (SDHCIState *)opaque;
80
81 if (s->norintsts & SDHC_NIS_REMOVE) {
82 timer_mod(s->insert_timer,
83 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
84 } else {
85 s->prnsts = 0x1ff0000;
86 if (s->norintstsen & SDHC_NISEN_INSERT) {
87 s->norintsts |= SDHC_NIS_INSERT;
88 }
89 sdhci_update_irq(s);
90 }
91}
92
93static void sdhci_set_inserted(DeviceState *dev, bool level)
94{
95 SDHCIState *s = (SDHCIState *)dev;
96 DPRINT_L1("Card state changed: %s!\n", level ? "insert" : "eject");
97
98 if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
99
100 timer_mod(s->insert_timer,
101 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
102 } else {
103 if (level) {
104 s->prnsts = 0x1ff0000;
105 if (s->norintstsen & SDHC_NISEN_INSERT) {
106 s->norintsts |= SDHC_NIS_INSERT;
107 }
108 } else {
109 s->prnsts = 0x1fa0000;
110 s->pwrcon &= ~SDHC_POWER_ON;
111 s->clkcon &= ~SDHC_CLOCK_SDCLK_EN;
112 if (s->norintstsen & SDHC_NISEN_REMOVE) {
113 s->norintsts |= SDHC_NIS_REMOVE;
114 }
115 }
116 sdhci_update_irq(s);
117 }
118}
119
120static void sdhci_set_readonly(DeviceState *dev, bool level)
121{
122 SDHCIState *s = (SDHCIState *)dev;
123
124 if (level) {
125 s->prnsts &= ~SDHC_WRITE_PROTECT;
126 } else {
127
128 s->prnsts |= SDHC_WRITE_PROTECT;
129 }
130}
131
132static void sdhci_reset(SDHCIState *s)
133{
134 DeviceState *dev = DEVICE(s);
135
136 timer_del(s->insert_timer);
137 timer_del(s->transfer_timer);
138
139
140
141 memset(&s->sdmasysad, 0, (uintptr_t)&s->capareg - (uintptr_t)&s->sdmasysad);
142
143
144 sdhci_set_inserted(dev, sdbus_get_inserted(&s->sdbus));
145 sdhci_set_readonly(dev, sdbus_get_readonly(&s->sdbus));
146
147 s->data_count = 0;
148 s->stopped_state = sdhc_not_stopped;
149 s->pending_insert_state = false;
150}
151
152static void sdhci_poweron_reset(DeviceState *dev)
153{
154
155
156
157
158 SDHCIState *s = (SDHCIState *)dev;
159
160 sdhci_reset(s);
161
162 if (s->pending_insert_quirk) {
163 s->pending_insert_state = true;
164 }
165}
166
167static void sdhci_data_transfer(void *opaque);
168
169static void sdhci_send_command(SDHCIState *s)
170{
171 SDRequest request;
172 uint8_t response[16];
173 int rlen;
174
175 s->errintsts = 0;
176 s->acmd12errsts = 0;
177 request.cmd = s->cmdreg >> 8;
178 request.arg = s->argument;
179 DPRINT_L1("sending CMD%u ARG[0x%08x]\n", request.cmd, request.arg);
180 rlen = sdbus_do_command(&s->sdbus, &request, response);
181
182 if (s->cmdreg & SDHC_CMD_RESPONSE) {
183 if (rlen == 4) {
184 s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
185 (response[2] << 8) | response[3];
186 s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
187 DPRINT_L1("Response: RSPREG[31..0]=0x%08x\n", s->rspreg[0]);
188 } else if (rlen == 16) {
189 s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
190 (response[13] << 8) | response[14];
191 s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |
192 (response[9] << 8) | response[10];
193 s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
194 (response[5] << 8) | response[6];
195 s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
196 response[2];
197 DPRINT_L1("Response received:\n RSPREG[127..96]=0x%08x, RSPREG[95.."
198 "64]=0x%08x,\n RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x\n",
199 s->rspreg[3], s->rspreg[2], s->rspreg[1], s->rspreg[0]);
200 } else {
201 ERRPRINT("Timeout waiting for command response\n");
202 if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {
203 s->errintsts |= SDHC_EIS_CMDTIMEOUT;
204 s->norintsts |= SDHC_NIS_ERR;
205 }
206 }
207
208 if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&
209 (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {
210 s->norintsts |= SDHC_NIS_TRSCMP;
211 }
212 }
213
214 if (s->norintstsen & SDHC_NISEN_CMDCMP) {
215 s->norintsts |= SDHC_NIS_CMDCMP;
216 }
217
218 sdhci_update_irq(s);
219
220 if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {
221 s->data_count = 0;
222 sdhci_data_transfer(s);
223 }
224}
225
226static void sdhci_end_transfer(SDHCIState *s)
227{
228
229 if ((s->trnmod & SDHC_TRNS_ACMD12) != 0) {
230 SDRequest request;
231 uint8_t response[16];
232
233 request.cmd = 0x0C;
234 request.arg = 0;
235 DPRINT_L1("Automatically issue CMD%d %08x\n", request.cmd, request.arg);
236 sdbus_do_command(&s->sdbus, &request, response);
237
238 s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
239 (response[2] << 8) | response[3];
240 }
241
242 s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
243 SDHC_DAT_LINE_ACTIVE | SDHC_DATA_INHIBIT |
244 SDHC_SPACE_AVAILABLE | SDHC_DATA_AVAILABLE);
245
246 if (s->norintstsen & SDHC_NISEN_TRSCMP) {
247 s->norintsts |= SDHC_NIS_TRSCMP;
248 }
249
250 sdhci_update_irq(s);
251}
252
253
254
255
256
257
258static void sdhci_read_block_from_card(SDHCIState *s)
259{
260 int index = 0;
261 uint8_t data;
262 uint16_t blk_size;
263
264 blk_size = s->blksize & 0x0fff;
265
266 if ((s->trnmod & SDHC_TRNS_MULTI) &&
267 (s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) {
268 return;
269 }
270
271 for (index = 0; index < blk_size; index++) {
272 data = sdbus_read_data(&s->sdbus);
273 if (!(s->hostctl2 & (SDHC_CTRL2_EXECUTE_TUNING >> 16))) {
274
275 s->fifo_buffer[index] = data;
276 }
277 }
278
279 if (s->hostctl2 & (SDHC_CTRL2_EXECUTE_TUNING >> 16)) {
280
281 s->hostctl2 &= ~(SDHC_CTRL2_EXECUTE_TUNING >> 16);
282 s->hostctl2 |= (SDHC_CTRL2_SAMPLING_CLKSEL >> 16);
283 s->prnsts &= ~(SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ |
284 SDHC_DATA_INHIBIT);
285 goto read_done;
286 }
287
288
289 s->prnsts |= SDHC_DATA_AVAILABLE;
290 if (s->norintstsen & SDHC_NISEN_RBUFRDY) {
291 s->norintsts |= SDHC_NIS_RBUFRDY;
292 }
293
294
295 if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
296 ((s->trnmod & SDHC_TRNS_MULTI) && s->blkcnt == 1)) {
297 s->prnsts &= ~SDHC_DAT_LINE_ACTIVE;
298 }
299
300
301
302 if (s->stopped_state == sdhc_gap_read && (s->trnmod & SDHC_TRNS_MULTI) &&
303 s->blkcnt != 1) {
304 s->prnsts &= ~SDHC_DAT_LINE_ACTIVE;
305 if (s->norintstsen & SDHC_EISEN_BLKGAP) {
306 s->norintsts |= SDHC_EIS_BLKGAP;
307 }
308 }
309
310read_done:
311 sdhci_update_irq(s);
312}
313
314
315static uint32_t sdhci_read_dataport(SDHCIState *s, unsigned size)
316{
317 uint32_t value = 0;
318 int i;
319
320
321 if ((s->prnsts & SDHC_DATA_AVAILABLE) == 0) {
322 ERRPRINT("Trying to read from empty buffer\n");
323 return 0;
324 }
325
326 for (i = 0; i < size; i++) {
327 value |= s->fifo_buffer[s->data_count] << i * 8;
328 s->data_count++;
329
330 if ((s->data_count) >= (s->blksize & 0x0fff)) {
331 DPRINT_L2("All %u bytes of data have been read from input buffer\n",
332 s->data_count);
333 s->prnsts &= ~SDHC_DATA_AVAILABLE;
334 s->data_count = 0;
335
336 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
337 s->blkcnt--;
338 }
339
340
341 if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
342 ((s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0)) ||
343
344 (s->stopped_state == sdhc_gap_read &&
345 !(s->prnsts & SDHC_DAT_LINE_ACTIVE))) {
346 sdhci_end_transfer(s);
347 } else {
348 sdhci_read_block_from_card(s);
349 }
350 break;
351 }
352 }
353
354 return value;
355}
356
357
358static void sdhci_write_block_to_card(SDHCIState *s)
359{
360 int index = 0;
361
362 if (s->prnsts & SDHC_SPACE_AVAILABLE) {
363 if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
364 s->norintsts |= SDHC_NIS_WBUFRDY;
365 }
366 sdhci_update_irq(s);
367 return;
368 }
369
370 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
371 if (s->blkcnt == 0) {
372 return;
373 } else {
374 s->blkcnt--;
375 }
376 }
377
378 for (index = 0; index < (s->blksize & 0x0fff); index++) {
379 sdbus_write_data(&s->sdbus, s->fifo_buffer[index]);
380 }
381
382
383 s->prnsts |= SDHC_SPACE_AVAILABLE;
384
385
386 if ((s->trnmod & SDHC_TRNS_MULTI) == 0 ||
387 ((s->trnmod & SDHC_TRNS_MULTI) &&
388 (s->trnmod & SDHC_TRNS_BLK_CNT_EN) && (s->blkcnt == 0))) {
389 sdhci_end_transfer(s);
390 } else if (s->norintstsen & SDHC_NISEN_WBUFRDY) {
391 s->norintsts |= SDHC_NIS_WBUFRDY;
392 }
393
394
395 if (s->stopped_state == sdhc_gap_write && (s->trnmod & SDHC_TRNS_MULTI) &&
396 s->blkcnt > 0) {
397 s->prnsts &= ~SDHC_DOING_WRITE;
398 if (s->norintstsen & SDHC_EISEN_BLKGAP) {
399 s->norintsts |= SDHC_EIS_BLKGAP;
400 }
401 sdhci_end_transfer(s);
402 }
403
404 sdhci_update_irq(s);
405}
406
407
408
409static void sdhci_write_dataport(SDHCIState *s, uint32_t value, unsigned size)
410{
411 unsigned i;
412
413
414 if (!(s->prnsts & SDHC_SPACE_AVAILABLE)) {
415 ERRPRINT("Can't write to data buffer: buffer full\n");
416 return;
417 }
418
419 for (i = 0; i < size; i++) {
420 s->fifo_buffer[s->data_count] = value & 0xFF;
421 s->data_count++;
422 value >>= 8;
423 if (s->data_count >= (s->blksize & 0x0fff)) {
424 DPRINT_L2("write buffer filled with %u bytes of data\n",
425 s->data_count);
426 s->data_count = 0;
427 s->prnsts &= ~SDHC_SPACE_AVAILABLE;
428 if (s->prnsts & SDHC_DOING_WRITE) {
429 sdhci_write_block_to_card(s);
430 }
431 }
432 }
433}
434
435
436
437
438
439
440static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
441{
442 bool page_aligned = false;
443 unsigned int n, begin;
444 const uint16_t block_size = s->blksize & 0x0fff;
445 uint32_t boundary_chk = 1 << (((s->blksize & 0xf000) >> 12) + 12);
446 uint32_t boundary_count = boundary_chk - (s->sdmasysad % boundary_chk);
447
448
449
450
451 if ((s->sdmasysad % boundary_chk) == 0) {
452 page_aligned = true;
453 }
454
455 if (s->trnmod & SDHC_TRNS_READ) {
456 s->prnsts |= SDHC_DOING_READ | SDHC_DATA_INHIBIT |
457 SDHC_DAT_LINE_ACTIVE;
458 while (s->blkcnt) {
459 if (s->data_count == 0) {
460 for (n = 0; n < block_size; n++) {
461 s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
462 }
463 }
464 begin = s->data_count;
465 if (((boundary_count + begin) < block_size) && page_aligned) {
466 s->data_count = boundary_count + begin;
467 boundary_count = 0;
468 } else {
469 s->data_count = block_size;
470 boundary_count -= block_size - begin;
471 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
472 s->blkcnt--;
473 }
474 }
475 dma_memory_write(s->dma_as, s->sdmasysad,
476 &s->fifo_buffer[begin], s->data_count - begin);
477 s->sdmasysad += s->data_count - begin;
478 if (s->data_count == block_size) {
479 s->data_count = 0;
480 }
481 if (page_aligned && boundary_count == 0) {
482 break;
483 }
484 }
485 } else {
486 s->prnsts |= SDHC_DOING_WRITE | SDHC_DATA_INHIBIT |
487 SDHC_DAT_LINE_ACTIVE;
488 while (s->blkcnt) {
489 begin = s->data_count;
490 if (((boundary_count + begin) < block_size) && page_aligned) {
491 s->data_count = boundary_count + begin;
492 boundary_count = 0;
493 } else {
494 s->data_count = block_size;
495 boundary_count -= block_size - begin;
496 }
497 dma_memory_read(s->dma_as, s->sdmasysad,
498 &s->fifo_buffer[begin], s->data_count - begin);
499 s->sdmasysad += s->data_count - begin;
500 if (s->data_count == block_size) {
501 for (n = 0; n < block_size; n++) {
502 sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
503 }
504 s->data_count = 0;
505 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
506 s->blkcnt--;
507 }
508 }
509 if (page_aligned && boundary_count == 0) {
510 break;
511 }
512 }
513 }
514
515 if (s->blkcnt == 0) {
516 sdhci_end_transfer(s);
517 } else {
518 if (s->norintstsen & SDHC_NISEN_DMA) {
519 s->norintsts |= SDHC_NIS_DMA;
520 }
521 sdhci_update_irq(s);
522 }
523}
524
525
526
527static void sdhci_sdma_transfer_single_block(SDHCIState *s)
528{
529 int n;
530 uint32_t datacnt = s->blksize & 0x0fff;
531
532 if (s->trnmod & SDHC_TRNS_READ) {
533 for (n = 0; n < datacnt; n++) {
534 s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
535 }
536 dma_memory_write(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
537 } else {
538 dma_memory_read(s->dma_as, s->sdmasysad, s->fifo_buffer, datacnt);
539 for (n = 0; n < datacnt; n++) {
540 sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
541 }
542 }
543
544 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
545 s->blkcnt--;
546 }
547
548 sdhci_end_transfer(s);
549}
550
551typedef struct ADMADescr {
552 hwaddr addr;
553 uint16_t length;
554 uint8_t attr;
555 uint8_t incr;
556} ADMADescr;
557
558static void get_adma_description(SDHCIState *s, ADMADescr *dscr)
559{
560 uint32_t adma1 = 0;
561 uint64_t adma2 = 0;
562 hwaddr entry_addr = (hwaddr)s->admasysaddr;
563 switch (SDHC_DMA_TYPE(s->hostctl)) {
564 case SDHC_CTRL_ADMA2_32:
565 dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma2,
566 sizeof(adma2));
567 adma2 = le64_to_cpu(adma2);
568
569
570
571 dscr->addr = (hwaddr)extract64(adma2, 32, 32) & ~0x3ull;
572 dscr->length = (uint16_t)extract64(adma2, 16, 16);
573 dscr->attr = (uint8_t)extract64(adma2, 0, 7);
574 dscr->incr = 8;
575 break;
576 case SDHC_CTRL_ADMA1_32:
577 dma_memory_read(s->dma_as, entry_addr, (uint8_t *)&adma1,
578 sizeof(adma1));
579 adma1 = le32_to_cpu(adma1);
580 dscr->addr = (hwaddr)(adma1 & 0xFFFFF000);
581 dscr->attr = (uint8_t)extract32(adma1, 0, 7);
582 dscr->incr = 4;
583 if ((dscr->attr & SDHC_ADMA_ATTR_ACT_MASK) == SDHC_ADMA_ATTR_SET_LEN) {
584 dscr->length = (uint16_t)extract32(adma1, 12, 16);
585 } else {
586 dscr->length = 4096;
587 }
588 break;
589 case SDHC_CTRL_ADMA2_64:
590 dma_memory_read(s->dma_as, entry_addr, (uint8_t *)(&dscr->attr), 1);
591 dma_memory_read(s->dma_as, entry_addr + 2,
592 (uint8_t *)(&dscr->length), 2);
593 dscr->length = le16_to_cpu(dscr->length);
594 dma_memory_read(s->dma_as, entry_addr + 4,
595 (uint8_t *)(&dscr->addr), 8);
596 dscr->addr = le64_to_cpu(dscr->addr);
597 dscr->attr &= (uint8_t) ~0xC0;
598 dscr->incr = 12;
599 break;
600 }
601}
602
603
604
605static void sdhci_do_adma(SDHCIState *s)
606{
607 unsigned int n, begin, length;
608 const uint16_t block_size = s->blksize & 0x0fff;
609 ADMADescr dscr;
610 int i;
611
612 for (i = 0; i < SDHC_ADMA_DESCS_PER_DELAY; ++i) {
613 s->admaerr &= ~SDHC_ADMAERR_LENGTH_MISMATCH;
614
615 get_adma_description(s, &dscr);
616 DPRINT_L2("ADMA loop: addr=" TARGET_FMT_plx ", len=%d, attr=%x\n",
617 dscr.addr, dscr.length, dscr.attr);
618
619 if ((dscr.attr & SDHC_ADMA_ATTR_VALID) == 0) {
620
621 s->admaerr &= ~SDHC_ADMAERR_STATE_MASK;
622 s->admaerr |= SDHC_ADMAERR_STATE_ST_FDS;
623
624
625 if (s->errintstsen & SDHC_EISEN_ADMAERR) {
626 s->errintsts |= SDHC_EIS_ADMAERR;
627 s->norintsts |= SDHC_NIS_ERR;
628 }
629
630 sdhci_update_irq(s);
631 return;
632 }
633
634 length = dscr.length ? dscr.length : 65536;
635
636 switch (dscr.attr & SDHC_ADMA_ATTR_ACT_MASK) {
637 case SDHC_ADMA_ATTR_ACT_TRAN:
638
639 if (s->trnmod & SDHC_TRNS_READ) {
640 while (length) {
641 if (s->data_count == 0) {
642 for (n = 0; n < block_size; n++) {
643 s->fifo_buffer[n] = sdbus_read_data(&s->sdbus);
644 }
645 }
646 begin = s->data_count;
647 if ((length + begin) < block_size) {
648 s->data_count = length + begin;
649 length = 0;
650 } else {
651 s->data_count = block_size;
652 length -= block_size - begin;
653 }
654 dma_memory_write(s->dma_as, dscr.addr,
655 &s->fifo_buffer[begin],
656 s->data_count - begin);
657 dscr.addr += s->data_count - begin;
658 if (s->data_count == block_size) {
659 s->data_count = 0;
660 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
661 s->blkcnt--;
662 if (s->blkcnt == 0) {
663 break;
664 }
665 }
666 }
667 }
668 } else {
669 while (length) {
670 begin = s->data_count;
671 if ((length + begin) < block_size) {
672 s->data_count = length + begin;
673 length = 0;
674 } else {
675 s->data_count = block_size;
676 length -= block_size - begin;
677 }
678 dma_memory_read(s->dma_as, dscr.addr,
679 &s->fifo_buffer[begin],
680 s->data_count - begin);
681 dscr.addr += s->data_count - begin;
682 if (s->data_count == block_size) {
683 for (n = 0; n < block_size; n++) {
684 sdbus_write_data(&s->sdbus, s->fifo_buffer[n]);
685 }
686 s->data_count = 0;
687 if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
688 s->blkcnt--;
689 if (s->blkcnt == 0) {
690 break;
691 }
692 }
693 }
694 }
695 }
696 s->admasysaddr += dscr.incr;
697 break;
698 case SDHC_ADMA_ATTR_ACT_LINK:
699 s->admasysaddr = dscr.addr;
700 DPRINT_L1("ADMA link: admasysaddr=0x%" PRIx64 "\n",
701 s->admasysaddr);
702 break;
703 default:
704 s->admasysaddr += dscr.incr;
705 break;
706 }
707
708 if (dscr.attr & SDHC_ADMA_ATTR_INT) {
709 DPRINT_L1("ADMA interrupt: admasysaddr=0x%" PRIx64 "\n",
710 s->admasysaddr);
711 if (s->norintstsen & SDHC_NISEN_DMA) {
712 s->norintsts |= SDHC_NIS_DMA;
713 }
714
715 sdhci_update_irq(s);
716 }
717
718
719 if (((s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
720 (s->blkcnt == 0)) || (dscr.attr & SDHC_ADMA_ATTR_END)) {
721 DPRINT_L2("ADMA transfer completed\n");
722 if (length || ((dscr.attr & SDHC_ADMA_ATTR_END) &&
723 (s->trnmod & SDHC_TRNS_BLK_CNT_EN) &&
724 s->blkcnt != 0)) {
725 ERRPRINT("SD/MMC host ADMA length mismatch\n");
726 s->admaerr |= SDHC_ADMAERR_LENGTH_MISMATCH |
727 SDHC_ADMAERR_STATE_ST_TFR;
728 if (s->errintstsen & SDHC_EISEN_ADMAERR) {
729 ERRPRINT("Set ADMA error flag\n");
730 s->errintsts |= SDHC_EIS_ADMAERR;
731 s->norintsts |= SDHC_NIS_ERR;
732 }
733
734 sdhci_update_irq(s);
735 }
736 sdhci_end_transfer(s);
737 return;
738 }
739
740 }
741
742
743 timer_mod(s->transfer_timer,
744 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_TRANSFER_DELAY);
745}
746
747
748
749static void sdhci_data_transfer(void *opaque)
750{
751 SDHCIState *s = (SDHCIState *)opaque;
752
753 if (s->trnmod & SDHC_TRNS_DMA) {
754 switch (SDHC_DMA_TYPE(s->hostctl)) {
755 case SDHC_CTRL_SDMA:
756 if ((s->trnmod & SDHC_TRNS_MULTI) &&
757 (!(s->trnmod & SDHC_TRNS_BLK_CNT_EN) || s->blkcnt == 0)) {
758 break;
759 }
760
761 if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {
762 sdhci_sdma_transfer_single_block(s);
763 } else {
764 sdhci_sdma_transfer_multi_blocks(s);
765 }
766
767 break;
768 case SDHC_CTRL_ADMA1_32:
769 if (!(s->capareg & SDHC_CAN_DO_ADMA1)) {
770 ERRPRINT("ADMA1 not supported\n");
771 break;
772 }
773
774 sdhci_do_adma(s);
775 break;
776 case SDHC_CTRL_ADMA2_32:
777 if (!(s->capareg & SDHC_CAN_DO_ADMA2)) {
778 ERRPRINT("ADMA2 not supported\n");
779 break;
780 }
781
782 sdhci_do_adma(s);
783 break;
784 case SDHC_CTRL_ADMA2_64:
785 if (!(s->capareg & SDHC_CAN_DO_ADMA2) ||
786 !(s->capareg & SDHC_64_BIT_BUS_SUPPORT)) {
787 ERRPRINT("64 bit ADMA not supported\n");
788 break;
789 }
790
791 sdhci_do_adma(s);
792 break;
793 default:
794 ERRPRINT("Unsupported DMA type\n");
795 break;
796 }
797 } else {
798 if ((s->trnmod & SDHC_TRNS_READ) && sdbus_data_ready(&s->sdbus)) {
799 s->prnsts |= SDHC_DOING_READ | SDHC_DATA_INHIBIT |
800 SDHC_DAT_LINE_ACTIVE;
801 sdhci_read_block_from_card(s);
802 } else {
803 s->prnsts |= SDHC_DOING_WRITE | SDHC_DAT_LINE_ACTIVE |
804 SDHC_SPACE_AVAILABLE | SDHC_DATA_INHIBIT;
805 sdhci_write_block_to_card(s);
806 }
807 }
808}
809
810static bool sdhci_can_issue_command(SDHCIState *s)
811{
812 if (!SDHC_CLOCK_IS_ON(s->clkcon) ||
813 (((s->prnsts & SDHC_DATA_INHIBIT) || s->stopped_state) &&
814 ((s->cmdreg & SDHC_CMD_DATA_PRESENT) ||
815 ((s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY &&
816 !(SDHC_COMMAND_TYPE(s->cmdreg) == SDHC_CMD_ABORT))))) {
817 return false;
818 }
819
820 return true;
821}
822
823
824
825static inline bool
826sdhci_buff_access_is_sequential(SDHCIState *s, unsigned byte_num)
827{
828 if ((s->data_count & 0x3) != byte_num) {
829 ERRPRINT("Non-sequential access to Buffer Data Port register"
830 "is prohibited\n");
831 return false;
832 }
833 return true;
834}
835
836static uint64_t sdhci_read(void *opaque, hwaddr offset, unsigned size)
837{
838 SDHCIState *s = (SDHCIState *)opaque;
839 uint32_t ret = 0;
840
841 switch (offset & ~0x3) {
842 case SDHC_SYSAD:
843 ret = s->sdmasysad;
844 break;
845 case SDHC_BLKSIZE:
846 ret = s->blksize | (s->blkcnt << 16);
847 break;
848 case SDHC_ARGUMENT:
849 ret = s->argument;
850 break;
851 case SDHC_TRNMOD:
852 ret = s->trnmod | (s->cmdreg << 16);
853 break;
854 case SDHC_RSPREG0 ... SDHC_RSPREG3:
855 ret = s->rspreg[((offset & ~0x3) - SDHC_RSPREG0) >> 2];
856 break;
857 case SDHC_BDATA:
858 if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
859 ret = sdhci_read_dataport(s, size);
860 DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset,
861 ret, ret);
862 return ret;
863 }
864 break;
865 case SDHC_PRNSTS:
866 ret = s->prnsts;
867 ret = deposit32(ret, SDHC_DAT_LVL_SHIFT, SDHC_DAT_LVL_LENGTH,
868 sdbus_get_dat_lines(&s->sdbus));
869 ret = deposit32(ret, SDHC_CMD_LVL_SHIFT, 1, sdbus_get_cmd_line(&s->sdbus));
870 break;
871 case SDHC_HOSTCTL:
872 ret = s->hostctl | (s->pwrcon << 8) | (s->blkgap << 16) |
873 (s->wakcon << 24);
874 break;
875 case SDHC_CLKCON:
876 ret = s->clkcon | (s->timeoutcon << 16);
877 break;
878 case SDHC_NORINTSTS:
879 ret = s->norintsts | (s->errintsts << 16);
880 break;
881 case SDHC_NORINTSTSEN:
882 ret = s->norintstsen | (s->errintstsen << 16);
883 break;
884 case SDHC_NORINTSIGEN:
885 ret = s->norintsigen | (s->errintsigen << 16);
886 break;
887 case SDHC_ACMD12ERRSTS:
888 ret = s->acmd12errsts | (s->hostctl2 << 16);
889 break;
890 case SDHC_CAPAREG_HI:
891 ret = extract64(s->capareg, 32, 32);
892 break;
893 case SDHC_CAPAREG:
894 ret = extract64(s->capareg, 0, 32);
895 break;
896 case SDHC_MAXCURR:
897 ret = s->maxcurr;
898 break;
899 case SDHC_ADMAERR:
900 ret = s->admaerr;
901 break;
902 case SDHC_ADMASYSADDR:
903 ret = (uint32_t)s->admasysaddr;
904 break;
905 case SDHC_ADMASYSADDR + 4:
906 ret = (uint32_t)(s->admasysaddr >> 32);
907 break;
908 case SDHC_SLOT_INT_STATUS:
909 ret = (SD_HOST_SPECv2_VERS << 16) | sdhci_slotint(s);
910 break;
911 default:
912 ERRPRINT("bad %ub read: addr[0x%04x]\n", size, (int)offset);
913 break;
914 }
915
916 ret >>= (offset & 0x3) * 8;
917 ret &= (1ULL << (size * 8)) - 1;
918 DPRINT_L2("read %ub: addr[0x%04x] -> %u(0x%x)\n", size, (int)offset, ret, ret);
919 return ret;
920}
921
922static inline void sdhci_blkgap_write(SDHCIState *s, uint8_t value)
923{
924 if ((value & SDHC_STOP_AT_GAP_REQ) && (s->blkgap & SDHC_STOP_AT_GAP_REQ)) {
925 return;
926 }
927 s->blkgap = value & SDHC_STOP_AT_GAP_REQ;
928
929 if ((value & SDHC_CONTINUE_REQ) && s->stopped_state &&
930 (s->blkgap & SDHC_STOP_AT_GAP_REQ) == 0) {
931 if (s->stopped_state == sdhc_gap_read) {
932 s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ;
933 sdhci_read_block_from_card(s);
934 } else {
935 s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_WRITE;
936 sdhci_write_block_to_card(s);
937 }
938 s->stopped_state = sdhc_not_stopped;
939 } else if (!s->stopped_state && (value & SDHC_STOP_AT_GAP_REQ)) {
940 if (s->prnsts & SDHC_DOING_READ) {
941 s->stopped_state = sdhc_gap_read;
942 } else if (s->prnsts & SDHC_DOING_WRITE) {
943 s->stopped_state = sdhc_gap_write;
944 }
945 }
946}
947
948static inline void sdhci_reset_write(SDHCIState *s, uint8_t value)
949{
950 switch (value) {
951 case SDHC_RESET_ALL:
952 sdhci_reset(s);
953 break;
954 case SDHC_RESET_CMD:
955 s->prnsts &= ~SDHC_CMD_INHIBIT;
956 s->norintsts &= ~SDHC_NIS_CMDCMP;
957 break;
958 case SDHC_RESET_DATA:
959 s->data_count = 0;
960 s->prnsts &= ~(SDHC_SPACE_AVAILABLE | SDHC_DATA_AVAILABLE |
961 SDHC_DOING_READ | SDHC_DOING_WRITE |
962 SDHC_DATA_INHIBIT | SDHC_DAT_LINE_ACTIVE);
963 s->blkgap &= ~(SDHC_STOP_AT_GAP_REQ | SDHC_CONTINUE_REQ);
964 s->stopped_state = sdhc_not_stopped;
965 s->norintsts &= ~(SDHC_NIS_WBUFRDY | SDHC_NIS_RBUFRDY |
966 SDHC_NIS_DMA | SDHC_NIS_TRSCMP | SDHC_NIS_BLKGAP);
967 break;
968 }
969}
970
971static void
972sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
973{
974 SDHCIState *s = (SDHCIState *)opaque;
975 unsigned shift = 8 * (offset & 0x3);
976 uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift);
977 uint32_t value = val;
978 value <<= shift;
979
980 switch (offset & ~0x3) {
981 case SDHC_SYSAD:
982 s->sdmasysad = (s->sdmasysad & mask) | value;
983 MASKED_WRITE(s->sdmasysad, mask, value);
984
985 if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&
986 s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) {
987 sdhci_sdma_transfer_multi_blocks(s);
988 }
989 break;
990 case SDHC_BLKSIZE:
991 if (!TRANSFERRING_DATA(s->prnsts)) {
992 MASKED_WRITE(s->blksize, mask, value);
993 MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16);
994 }
995
996
997 if (extract32(s->blksize, 0, 12) > s->buf_maxsz) {
998 qemu_log_mask(LOG_GUEST_ERROR, "%s: Size 0x%x is larger than " \
999 "the maximum buffer 0x%x", __func__, s->blksize,
1000 s->buf_maxsz);
1001
1002 s->blksize = deposit32(s->blksize, 0, 12, s->buf_maxsz);
1003 }
1004
1005 break;
1006 case SDHC_ARGUMENT:
1007 MASKED_WRITE(s->argument, mask, value);
1008 break;
1009 case SDHC_TRNMOD:
1010
1011
1012 if (!(s->capareg & SDHC_CAN_DO_DMA)) {
1013 value &= ~SDHC_TRNS_DMA;
1014 }
1015 MASKED_WRITE(s->trnmod, mask, value);
1016 MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
1017
1018
1019 if ((mask & 0xFF000000) || !sdhci_can_issue_command(s)) {
1020 break;
1021 }
1022
1023 sdhci_send_command(s);
1024 break;
1025 case SDHC_BDATA:
1026 if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) {
1027 sdhci_write_dataport(s, value >> shift, size);
1028 }
1029 break;
1030 case SDHC_HOSTCTL:
1031 if (!(mask & 0xFF0000)) {
1032 sdhci_blkgap_write(s, value >> 16);
1033 }
1034 MASKED_WRITE(s->hostctl, mask, value);
1035 MASKED_WRITE(s->pwrcon, mask >> 8, value >> 8);
1036 MASKED_WRITE(s->wakcon, mask >> 24, value >> 24);
1037 if (!(s->prnsts & SDHC_CARD_PRESENT) || ((s->pwrcon >> 1) & 0x7) < 5 ||
1038 !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7))))) {
1039 s->pwrcon &= ~SDHC_POWER_ON;
1040 }
1041 break;
1042 case SDHC_ACMD12ERRSTS:
1043 s->acmd12errsts = value;
1044 MASKED_WRITE(s->hostctl2, mask >> 16, value >> 16);
1045 sdbus_set_voltage(&s->sdbus, s->hostctl2 & SDHC_CTRL2_VOLTAGE_SWITCH ?
1046 SD_VOLTAGE_18 : SD_VOLTAGE_33);
1047 break;
1048 case SDHC_CLKCON:
1049 if (!(mask & 0xFF000000)) {
1050 sdhci_reset_write(s, value >> 24);
1051 }
1052 MASKED_WRITE(s->clkcon, mask, value);
1053 MASKED_WRITE(s->timeoutcon, mask >> 16, value >> 16);
1054 if (s->clkcon & SDHC_CLOCK_INT_EN) {
1055 s->clkcon |= SDHC_CLOCK_INT_STABLE;
1056 } else {
1057 s->clkcon &= ~SDHC_CLOCK_INT_STABLE;
1058 }
1059 break;
1060 case SDHC_NORINTSTS:
1061 if (s->norintstsen & SDHC_NISEN_CARDINT) {
1062 value &= ~SDHC_NIS_CARDINT;
1063 }
1064 s->norintsts &= mask | ~value;
1065 s->errintsts &= (mask >> 16) | ~(value >> 16);
1066 if (s->errintsts) {
1067 s->norintsts |= SDHC_NIS_ERR;
1068 } else {
1069 s->norintsts &= ~SDHC_NIS_ERR;
1070 }
1071 sdhci_update_irq(s);
1072 break;
1073 case SDHC_NORINTSTSEN:
1074 MASKED_WRITE(s->norintstsen, mask, value);
1075 MASKED_WRITE(s->errintstsen, mask >> 16, value >> 16);
1076 s->norintsts &= s->norintstsen;
1077 s->errintsts &= s->errintstsen;
1078 if (s->errintsts) {
1079 s->norintsts |= SDHC_NIS_ERR;
1080 } else {
1081 s->norintsts &= ~SDHC_NIS_ERR;
1082 }
1083
1084
1085 if ((s->norintstsen & SDHC_NISEN_INSERT) && s->pending_insert_state) {
1086 assert(s->pending_insert_quirk);
1087 s->norintsts |= SDHC_NIS_INSERT;
1088 s->pending_insert_state = false;
1089 }
1090 sdhci_update_irq(s);
1091 break;
1092 case SDHC_NORINTSIGEN:
1093 MASKED_WRITE(s->norintsigen, mask, value);
1094 MASKED_WRITE(s->errintsigen, mask >> 16, value >> 16);
1095 sdhci_update_irq(s);
1096 break;
1097 case SDHC_ADMAERR:
1098 MASKED_WRITE(s->admaerr, mask, value);
1099 break;
1100 case SDHC_ADMASYSADDR:
1101 s->admasysaddr = (s->admasysaddr & (0xFFFFFFFF00000000ULL |
1102 (uint64_t)mask)) | (uint64_t)value;
1103 break;
1104 case SDHC_ADMASYSADDR + 4:
1105 s->admasysaddr = (s->admasysaddr & (0x00000000FFFFFFFFULL |
1106 ((uint64_t)mask << 32))) | ((uint64_t)value << 32);
1107 break;
1108 case SDHC_FEAER:
1109 s->acmd12errsts |= value;
1110 s->errintsts |= (value >> 16) & s->errintstsen;
1111 if (s->acmd12errsts) {
1112 s->errintsts |= SDHC_EIS_CMD12ERR;
1113 }
1114 if (s->errintsts) {
1115 s->norintsts |= SDHC_NIS_ERR;
1116 }
1117 sdhci_update_irq(s);
1118 break;
1119 default:
1120 ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n",
1121 size, (int)offset, value >> shift, value >> shift);
1122 break;
1123 }
1124 DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n",
1125 size, (int)offset, value >> shift, value >> shift);
1126}
1127
1128static const MemoryRegionOps sdhci_mmio_ops = {
1129 .read = sdhci_read,
1130 .write = sdhci_write,
1131 .valid = {
1132 .min_access_size = 1,
1133 .max_access_size = 4,
1134 .unaligned = false
1135 },
1136 .endianness = DEVICE_LITTLE_ENDIAN,
1137};
1138
1139static inline unsigned int sdhci_get_fifolen(SDHCIState *s)
1140{
1141 switch (SDHC_CAPAB_BLOCKSIZE(s->capareg)) {
1142 case 0:
1143 return 512;
1144 case 1:
1145 return 1024;
1146 case 2:
1147 return 2048;
1148 default:
1149 hw_error("SDHC: unsupported value for maximum block size\n");
1150 return 0;
1151 }
1152}
1153
1154static void sdhci_initfn(SDHCIState *s)
1155{
1156 qbus_create_inplace(&s->sdbus, sizeof(s->sdbus),
1157 TYPE_SDHCI_BUS, DEVICE(s), "sd-bus");
1158
1159 s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
1160 s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_data_transfer, s);
1161
1162 object_property_add_link(OBJECT(s), "dma", TYPE_MEMORY_REGION,
1163 (Object **)&s->dma_mr,
1164 qdev_prop_allow_set_link_before_realize,
1165 OBJ_PROP_LINK_UNREF_ON_RELEASE,
1166 &error_abort);
1167}
1168
1169static void sdhci_uninitfn(SDHCIState *s)
1170{
1171 timer_del(s->insert_timer);
1172 timer_free(s->insert_timer);
1173 timer_del(s->transfer_timer);
1174 timer_free(s->transfer_timer);
1175 qemu_free_irq(s->eject_cb);
1176 qemu_free_irq(s->ro_cb);
1177
1178 g_free(s->fifo_buffer);
1179 s->fifo_buffer = NULL;
1180}
1181
1182static bool sdhci_pending_insert_vmstate_needed(void *opaque)
1183{
1184 SDHCIState *s = opaque;
1185
1186 return s->pending_insert_state;
1187}
1188
1189static const VMStateDescription sdhci_pending_insert_vmstate = {
1190 .name = "sdhci/pending-insert",
1191 .version_id = 1,
1192 .minimum_version_id = 1,
1193 .needed = sdhci_pending_insert_vmstate_needed,
1194 .fields = (VMStateField[]) {
1195 VMSTATE_BOOL(pending_insert_state, SDHCIState),
1196 VMSTATE_END_OF_LIST()
1197 },
1198};
1199
1200const VMStateDescription sdhci_vmstate = {
1201 .name = "sdhci",
1202 .version_id = 1,
1203 .minimum_version_id = 1,
1204 .fields = (VMStateField[]) {
1205 VMSTATE_UINT32(sdmasysad, SDHCIState),
1206 VMSTATE_UINT16(blksize, SDHCIState),
1207 VMSTATE_UINT16(blkcnt, SDHCIState),
1208 VMSTATE_UINT32(argument, SDHCIState),
1209 VMSTATE_UINT16(trnmod, SDHCIState),
1210 VMSTATE_UINT16(cmdreg, SDHCIState),
1211 VMSTATE_UINT32_ARRAY(rspreg, SDHCIState, 4),
1212 VMSTATE_UINT32(prnsts, SDHCIState),
1213 VMSTATE_UINT8(hostctl, SDHCIState),
1214 VMSTATE_UINT8(pwrcon, SDHCIState),
1215 VMSTATE_UINT8(blkgap, SDHCIState),
1216 VMSTATE_UINT8(wakcon, SDHCIState),
1217 VMSTATE_UINT16(clkcon, SDHCIState),
1218 VMSTATE_UINT8(timeoutcon, SDHCIState),
1219 VMSTATE_UINT8(admaerr, SDHCIState),
1220 VMSTATE_UINT16(norintsts, SDHCIState),
1221 VMSTATE_UINT16(errintsts, SDHCIState),
1222 VMSTATE_UINT16(norintstsen, SDHCIState),
1223 VMSTATE_UINT16(errintstsen, SDHCIState),
1224 VMSTATE_UINT16(norintsigen, SDHCIState),
1225 VMSTATE_UINT16(errintsigen, SDHCIState),
1226 VMSTATE_UINT16(acmd12errsts, SDHCIState),
1227 VMSTATE_UINT16(data_count, SDHCIState),
1228 VMSTATE_UINT64(admasysaddr, SDHCIState),
1229 VMSTATE_UINT8(stopped_state, SDHCIState),
1230 VMSTATE_VBUFFER_UINT32(fifo_buffer, SDHCIState, 1, NULL, 0, buf_maxsz),
1231 VMSTATE_TIMER_PTR(insert_timer, SDHCIState),
1232 VMSTATE_TIMER_PTR(transfer_timer, SDHCIState),
1233 VMSTATE_END_OF_LIST()
1234 },
1235 .subsections = (const VMStateDescription*[]) {
1236 &sdhci_pending_insert_vmstate,
1237 NULL
1238 },
1239};
1240
1241
1242
1243static Property sdhci_pci_properties[] = {
1244 DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
1245 SDHC_CAPAB_REG_DEFAULT),
1246 DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
1247 DEFINE_PROP_END_OF_LIST(),
1248};
1249
1250static void sdhci_pci_realize(PCIDevice *dev, Error **errp)
1251{
1252 SDHCIState *s = PCI_SDHCI(dev);
1253 dev->config[PCI_CLASS_PROG] = 0x01;
1254 dev->config[PCI_INTERRUPT_PIN] = 0x01;
1255 sdhci_initfn(s);
1256 s->buf_maxsz = sdhci_get_fifolen(s);
1257 s->fifo_buffer = g_malloc0(s->buf_maxsz);
1258 s->irq = pci_allocate_irq(dev);
1259 memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
1260 SDHC_REGISTERS_MAP_SIZE);
1261 pci_register_bar(dev, 0, 0, &s->iomem);
1262}
1263
1264static void sdhci_pci_exit(PCIDevice *dev)
1265{
1266 SDHCIState *s = PCI_SDHCI(dev);
1267 sdhci_uninitfn(s);
1268}
1269
1270static void sdhci_pci_class_init(ObjectClass *klass, void *data)
1271{
1272 DeviceClass *dc = DEVICE_CLASS(klass);
1273 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1274
1275 k->realize = sdhci_pci_realize;
1276 k->exit = sdhci_pci_exit;
1277 k->vendor_id = PCI_VENDOR_ID_REDHAT;
1278 k->device_id = PCI_DEVICE_ID_REDHAT_SDHCI;
1279 k->class_id = PCI_CLASS_SYSTEM_SDHCI;
1280 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1281 dc->vmsd = &sdhci_vmstate;
1282 dc->props = sdhci_pci_properties;
1283 dc->reset = sdhci_poweron_reset;
1284}
1285
1286static const TypeInfo sdhci_pci_info = {
1287 .name = TYPE_PCI_SDHCI,
1288 .parent = TYPE_PCI_DEVICE,
1289 .instance_size = sizeof(SDHCIState),
1290 .class_init = sdhci_pci_class_init,
1291};
1292
1293static Property sdhci_sysbus_properties[] = {
1294 DEFINE_PROP_UINT32("capareg", SDHCIState, capareg,
1295 SDHC_CAPAB_REG_DEFAULT),
1296 DEFINE_PROP_UINT32("maxcurr", SDHCIState, maxcurr, 0),
1297 DEFINE_PROP_BOOL("pending-insert-quirk", SDHCIState, pending_insert_quirk,
1298 false),
1299 DEFINE_PROP_END_OF_LIST(),
1300};
1301
1302static void sdhci_sysbus_init(Object *obj)
1303{
1304 SDHCIState *s = SYSBUS_SDHCI(obj);
1305
1306 sdhci_initfn(s);
1307}
1308
1309static void sdhci_sysbus_finalize(Object *obj)
1310{
1311 SDHCIState *s = SYSBUS_SDHCI(obj);
1312 sdhci_uninitfn(s);
1313}
1314
1315static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
1316{
1317 SDHCIState *s = SYSBUS_SDHCI(dev);
1318 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1319
1320 s->buf_maxsz = sdhci_get_fifolen(s);
1321 s->fifo_buffer = g_malloc0(s->buf_maxsz);
1322 sysbus_init_irq(sbd, &s->irq);
1323 memory_region_init_io(&s->iomem, OBJECT(s), &sdhci_mmio_ops, s, "sdhci",
1324 SDHC_REGISTERS_MAP_SIZE);
1325 sysbus_init_mmio(sbd, &s->iomem);
1326 s->dma_as = s->dma_mr ? address_space_init_shareable(s->dma_mr, NULL)
1327 : &address_space_memory;
1328}
1329
1330static void sdhci_sysbus_class_init(ObjectClass *klass, void *data)
1331{
1332 DeviceClass *dc = DEVICE_CLASS(klass);
1333
1334 dc->vmsd = &sdhci_vmstate;
1335 dc->props = sdhci_sysbus_properties;
1336 dc->realize = sdhci_sysbus_realize;
1337 dc->reset = sdhci_poweron_reset;
1338}
1339
1340static const TypeInfo sdhci_sysbus_info = {
1341 .name = TYPE_SYSBUS_SDHCI,
1342 .parent = TYPE_SYS_BUS_DEVICE,
1343 .instance_size = sizeof(SDHCIState),
1344 .instance_init = sdhci_sysbus_init,
1345 .instance_finalize = sdhci_sysbus_finalize,
1346 .class_init = sdhci_sysbus_class_init,
1347};
1348
1349static void sdhci_bus_class_init(ObjectClass *klass, void *data)
1350{
1351 SDBusClass *sbc = SD_BUS_CLASS(klass);
1352
1353 sbc->set_inserted = sdhci_set_inserted;
1354 sbc->set_readonly = sdhci_set_readonly;
1355}
1356
1357static const TypeInfo sdhci_bus_info = {
1358 .name = TYPE_SDHCI_BUS,
1359 .parent = TYPE_SD_BUS,
1360 .instance_size = sizeof(SDBus),
1361 .class_init = sdhci_bus_class_init,
1362};
1363
1364static void sdhci_register_types(void)
1365{
1366 type_register_static(&sdhci_pci_info);
1367 type_register_static(&sdhci_sysbus_info);
1368 type_register_static(&sdhci_bus_info);
1369}
1370
1371type_init(sdhci_register_types)
1372