Commit 775616c3ae8c9bdd43d57274f259b09ae87217b0

Authored by pbrook
1 parent f3b9f954

Partial SD card SPI mode support.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3731 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -57,6 +57,7 @@ OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o @@ -57,6 +57,7 @@ OBJS+=i2c.o smbus.o smbus_eeprom.o max7310.o max111x.o wm8750.o
57 OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o 57 OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o
58 OBJS+=scsi-disk.o cdrom.o 58 OBJS+=scsi-disk.o cdrom.o
59 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o 59 OBJS+=usb.o usb-hub.o usb-linux.o usb-hid.o usb-msd.o usb-wacom.o
  60 +OBJS+=sd.o ssi-sd.o
60 61
61 ifdef CONFIG_WIN32 62 ifdef CONFIG_WIN32
62 OBJS+=tap-win32.o 63 OBJS+=tap-win32.o
Makefile.target
@@ -488,7 +488,7 @@ endif @@ -488,7 +488,7 @@ endif
488 ifeq ($(TARGET_BASE_ARCH), arm) 488 ifeq ($(TARGET_BASE_ARCH), arm)
489 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o 489 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
490 VL_OBJS+= arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o 490 VL_OBJS+= arm_boot.o pl011.o pl031.o pl050.o pl080.o pl110.o pl181.o pl190.o
491 -VL_OBJS+= versatile_pci.o sd.o ptimer.o 491 +VL_OBJS+= versatile_pci.o ptimer.o
492 VL_OBJS+= realview_gic.o realview.o arm_sysctl.o mpcore.o 492 VL_OBJS+= realview_gic.o realview.o arm_sysctl.o mpcore.o
493 VL_OBJS+= armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o 493 VL_OBJS+= armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
494 VL_OBJS+= pl061.o 494 VL_OBJS+= pl061.o
hw/omap_mmc.c
@@ -525,7 +525,7 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base, @@ -525,7 +525,7 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
525 cpu_register_physical_memory(s->base, 0x800, iomemtype); 525 cpu_register_physical_memory(s->base, 0x800, iomemtype);
526 526
527 /* Instantiate the storage */ 527 /* Instantiate the storage */
528 - s->card = sd_init(bd); 528 + s->card = sd_init(bd, 0);
529 529
530 return s; 530 return s;
531 } 531 }
hw/pl061.c
@@ -48,6 +48,7 @@ typedef struct { @@ -48,6 +48,7 @@ typedef struct {
48 uint8_t slr; 48 uint8_t slr;
49 uint8_t den; 49 uint8_t den;
50 uint8_t cr; 50 uint8_t cr;
  51 + uint8_t float_high;
51 qemu_irq irq; 52 qemu_irq irq;
52 qemu_irq out[8]; 53 qemu_irq out[8];
53 } pl061_state; 54 } pl061_state;
@@ -56,18 +57,22 @@ static void pl061_update(pl061_state *s) @@ -56,18 +57,22 @@ static void pl061_update(pl061_state *s)
56 { 57 {
57 uint8_t changed; 58 uint8_t changed;
58 uint8_t mask; 59 uint8_t mask;
  60 + uint8_t out;
59 int i; 61 int i;
60 62
61 - changed = s->old_data ^ s->data; 63 + /* Outputs float high. */
  64 + /* FIXME: This is board dependent. */
  65 + out = (s->data & s->dir) | ~s->dir;
  66 + changed = s->old_data ^ out;
62 if (!changed) 67 if (!changed)
63 return; 68 return;
64 69
65 - s->old_data = s->data; 70 + s->old_data = out;
66 for (i = 0; i < 8; i++) { 71 for (i = 0; i < 8; i++) {
67 mask = 1 << i; 72 mask = 1 << i;
68 - if ((changed & mask & s->dir) && s->out) {  
69 - DPRINTF("Set output %d = %d\n", i, (s->data & mask) != 0);  
70 - qemu_set_irq(s->out[i], (s->data & mask) != 0); 73 + if ((changed & mask) && s->out) {
  74 + DPRINTF("Set output %d = %d\n", i, (out & mask) != 0);
  75 + qemu_set_irq(s->out[i], (out & mask) != 0);
71 } 76 }
72 } 77 }
73 78
hw/pl181.c
@@ -458,7 +458,7 @@ void pl181_init(uint32_t base, BlockDriverState *bd, @@ -458,7 +458,7 @@ void pl181_init(uint32_t base, BlockDriverState *bd,
458 pl181_writefn, s); 458 pl181_writefn, s);
459 cpu_register_physical_memory(base, 0x00001000, iomemtype); 459 cpu_register_physical_memory(base, 0x00001000, iomemtype);
460 s->base = base; 460 s->base = base;
461 - s->card = sd_init(bd); 461 + s->card = sd_init(bd, 0);
462 s->irq[0] = irq0; 462 s->irq[0] = irq0;
463 s->irq[1] = irq1; 463 s->irq[1] = irq1;
464 qemu_register_reset(pl181_reset, s); 464 qemu_register_reset(pl181_reset, s);
hw/primecell.h
@@ -21,13 +21,15 @@ void pl011_init(uint32_t base, qemu_irq irq, CharDriverState *chr, @@ -21,13 +21,15 @@ void pl011_init(uint32_t base, qemu_irq irq, CharDriverState *chr,
21 enum pl011_type type); 21 enum pl011_type type);
22 22
23 /* pl022.c */ 23 /* pl022.c */
24 -void pl022_init(uint32_t base, qemu_irq irq, int (*xfer_cb)(void *, int), 24 +typedef int (*ssi_xfer_cb)(void *, int);
  25 +void pl022_init(uint32_t base, qemu_irq irq, ssi_xfer_cb xfer_cb,
25 void *opaque); 26 void *opaque);
26 27
27 /* pl050.c */ 28 /* pl050.c */
28 void pl050_init(uint32_t base, qemu_irq irq, int is_mouse); 29 void pl050_init(uint32_t base, qemu_irq irq, int is_mouse);
29 30
30 /* pl061.c */ 31 /* pl061.c */
  32 +void pl061_float_high(void *opaque, uint8_t mask);
31 qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out); 33 qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out);
32 34
33 /* pl080.c */ 35 /* pl080.c */
hw/pxa2xx_mmci.c
@@ -538,7 +538,7 @@ struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base, @@ -538,7 +538,7 @@ struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base,
538 cpu_register_physical_memory(base, 0x00100000, iomemtype); 538 cpu_register_physical_memory(base, 0x00100000, iomemtype);
539 539
540 /* Instantiate the actual storage */ 540 /* Instantiate the actual storage */
541 - s->card = sd_init(bd); 541 + s->card = sd_init(bd, 1);
542 542
543 register_savevm("pxa2xx_mmci", 0, 0, 543 register_savevm("pxa2xx_mmci", 0, 0,
544 pxa2xx_mmci_save, pxa2xx_mmci_load, s); 544 pxa2xx_mmci_save, pxa2xx_mmci_load, s);
@@ -87,6 +87,7 @@ struct SDState { @@ -87,6 +87,7 @@ struct SDState {
87 int pwd_len; 87 int pwd_len;
88 int function_group[6]; 88 int function_group[6];
89 89
  90 + int spi;
90 int current_cmd; 91 int current_cmd;
91 int blk_written; 92 int blk_written;
92 uint32_t data_start; 93 uint32_t data_start;
@@ -395,11 +396,16 @@ static void sd_cardchange(void *opaque) @@ -395,11 +396,16 @@ static void sd_cardchange(void *opaque)
395 } 396 }
396 } 397 }
397 398
398 -SDState *sd_init(BlockDriverState *bs) 399 +/* We do not model the chip select pin, so allow the board to select
  400 + whether card should be in SSI ot MMC/SD mode. It is also up to the
  401 + board to ensure that ssi transfers only occur when the chip select
  402 + is asserted. */
  403 +SDState *sd_init(BlockDriverState *bs, int is_spi)
399 { 404 {
400 SDState *sd; 405 SDState *sd;
401 406
402 sd = (SDState *) qemu_mallocz(sizeof(SDState)); 407 sd = (SDState *) qemu_mallocz(sizeof(SDState));
  408 + sd->spi = is_spi;
403 sd_reset(sd, bs); 409 sd_reset(sd, bs);
404 bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd); 410 bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd);
405 return sd; 411 return sd;
@@ -567,16 +573,25 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -567,16 +573,25 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
567 case 0: /* CMD0: GO_IDLE_STATE */ 573 case 0: /* CMD0: GO_IDLE_STATE */
568 switch (sd->state) { 574 switch (sd->state) {
569 case sd_inactive_state: 575 case sd_inactive_state:
570 - return sd_r0; 576 + return sd->spi ? sd_r1 : sd_r0;
571 577
572 default: 578 default:
573 sd->state = sd_idle_state; 579 sd->state = sd_idle_state;
574 sd_reset(sd, sd->bdrv); 580 sd_reset(sd, sd->bdrv);
575 - return sd_r0; 581 + return sd->spi ? sd_r1 : sd_r0;
576 } 582 }
577 break; 583 break;
578 584
  585 + case 1: /* CMD1: SEND_OP_CMD */
  586 + if (!sd->spi)
  587 + goto bad_cmd;
  588 +
  589 + sd->state = sd_transfer_state;
  590 + return sd_r1;
  591 +
579 case 2: /* CMD2: ALL_SEND_CID */ 592 case 2: /* CMD2: ALL_SEND_CID */
  593 + if (sd->spi)
  594 + goto bad_cmd;
580 switch (sd->state) { 595 switch (sd->state) {
581 case sd_ready_state: 596 case sd_ready_state:
582 sd->state = sd_identification_state; 597 sd->state = sd_identification_state;
@@ -588,6 +603,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -588,6 +603,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
588 break; 603 break;
589 604
590 case 3: /* CMD3: SEND_RELATIVE_ADDR */ 605 case 3: /* CMD3: SEND_RELATIVE_ADDR */
  606 + if (sd->spi)
  607 + goto bad_cmd;
591 switch (sd->state) { 608 switch (sd->state) {
592 case sd_identification_state: 609 case sd_identification_state:
593 case sd_standby_state: 610 case sd_standby_state:
@@ -601,6 +618,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -601,6 +618,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
601 break; 618 break;
602 619
603 case 4: /* CMD4: SEND_DSR */ 620 case 4: /* CMD4: SEND_DSR */
  621 + if (sd->spi)
  622 + goto bad_cmd;
604 switch (sd->state) { 623 switch (sd->state) {
605 case sd_standby_state: 624 case sd_standby_state:
606 break; 625 break;
@@ -611,6 +630,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -611,6 +630,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
611 break; 630 break;
612 631
613 case 6: /* CMD6: SWITCH_FUNCTION */ 632 case 6: /* CMD6: SWITCH_FUNCTION */
  633 + if (sd->spi)
  634 + goto bad_cmd;
614 switch (sd->mode) { 635 switch (sd->mode) {
615 case sd_data_transfer_mode: 636 case sd_data_transfer_mode:
616 sd_function_switch(sd, req.arg); 637 sd_function_switch(sd, req.arg);
@@ -625,6 +646,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -625,6 +646,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
625 break; 646 break;
626 647
627 case 7: /* CMD7: SELECT/DESELECT_CARD */ 648 case 7: /* CMD7: SELECT/DESELECT_CARD */
  649 + if (sd->spi)
  650 + goto bad_cmd;
628 switch (sd->state) { 651 switch (sd->state) {
629 case sd_standby_state: 652 case sd_standby_state:
630 if (sd->rca != rca) 653 if (sd->rca != rca)
@@ -668,6 +691,15 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -668,6 +691,15 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
668 691
669 return sd_r2_s; 692 return sd_r2_s;
670 693
  694 + case sd_transfer_state:
  695 + if (!sd->spi)
  696 + break;
  697 + sd->state = sd_sendingdata_state;
  698 + memcpy(sd->data, sd->csd, 16);
  699 + sd->data_start = req.arg;
  700 + sd->data_offset = 0;
  701 + return sd_r1;
  702 +
671 default: 703 default:
672 break; 704 break;
673 } 705 }
@@ -681,12 +713,23 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -681,12 +713,23 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
681 713
682 return sd_r2_i; 714 return sd_r2_i;
683 715
  716 + case sd_transfer_state:
  717 + if (!sd->spi)
  718 + break;
  719 + sd->state = sd_sendingdata_state;
  720 + memcpy(sd->data, sd->cid, 16);
  721 + sd->data_start = req.arg;
  722 + sd->data_offset = 0;
  723 + return sd_r1;
  724 +
684 default: 725 default:
685 break; 726 break;
686 } 727 }
687 break; 728 break;
688 729
689 case 11: /* CMD11: READ_DAT_UNTIL_STOP */ 730 case 11: /* CMD11: READ_DAT_UNTIL_STOP */
  731 + if (sd->spi)
  732 + goto bad_cmd;
690 switch (sd->state) { 733 switch (sd->state) {
691 case sd_transfer_state: 734 case sd_transfer_state:
692 sd->state = sd_sendingdata_state; 735 sd->state = sd_sendingdata_state;
@@ -733,6 +776,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -733,6 +776,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
733 break; 776 break;
734 777
735 case 15: /* CMD15: GO_INACTIVE_STATE */ 778 case 15: /* CMD15: GO_INACTIVE_STATE */
  779 + if (sd->spi)
  780 + goto bad_cmd;
736 switch (sd->mode) { 781 switch (sd->mode) {
737 case sd_data_transfer_mode: 782 case sd_data_transfer_mode:
738 if (sd->rca != rca) 783 if (sd->rca != rca)
@@ -796,8 +841,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -796,8 +841,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
796 841
797 /* Block write commands (Class 4) */ 842 /* Block write commands (Class 4) */
798 case 24: /* CMD24: WRITE_SINGLE_BLOCK */ 843 case 24: /* CMD24: WRITE_SINGLE_BLOCK */
  844 + if (sd->spi)
  845 + goto unimplemented_cmd;
799 switch (sd->state) { 846 switch (sd->state) {
800 case sd_transfer_state: 847 case sd_transfer_state:
  848 + /* Writing in SPI mode not implemented. */
  849 + if (sd->spi)
  850 + break;
801 sd->state = sd_receivingdata_state; 851 sd->state = sd_receivingdata_state;
802 sd->data_start = req.arg; 852 sd->data_start = req.arg;
803 sd->data_offset = 0; 853 sd->data_offset = 0;
@@ -817,8 +867,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -817,8 +867,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
817 break; 867 break;
818 868
819 case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */ 869 case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
  870 + if (sd->spi)
  871 + goto unimplemented_cmd;
820 switch (sd->state) { 872 switch (sd->state) {
821 case sd_transfer_state: 873 case sd_transfer_state:
  874 + /* Writing in SPI mode not implemented. */
  875 + if (sd->spi)
  876 + break;
822 sd->state = sd_receivingdata_state; 877 sd->state = sd_receivingdata_state;
823 sd->data_start = req.arg; 878 sd->data_start = req.arg;
824 sd->data_offset = 0; 879 sd->data_offset = 0;
@@ -838,6 +893,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -838,6 +893,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
838 break; 893 break;
839 894
840 case 26: /* CMD26: PROGRAM_CID */ 895 case 26: /* CMD26: PROGRAM_CID */
  896 + if (sd->spi)
  897 + goto bad_cmd;
841 switch (sd->state) { 898 switch (sd->state) {
842 case sd_transfer_state: 899 case sd_transfer_state:
843 sd->state = sd_receivingdata_state; 900 sd->state = sd_receivingdata_state;
@@ -851,6 +908,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -851,6 +908,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
851 break; 908 break;
852 909
853 case 27: /* CMD27: PROGRAM_CSD */ 910 case 27: /* CMD27: PROGRAM_CSD */
  911 + if (sd->spi)
  912 + goto unimplemented_cmd;
854 switch (sd->state) { 913 switch (sd->state) {
855 case sd_transfer_state: 914 case sd_transfer_state:
856 sd->state = sd_receivingdata_state; 915 sd->state = sd_receivingdata_state;
@@ -962,6 +1021,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -962,6 +1021,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
962 1021
963 /* Lock card commands (Class 7) */ 1022 /* Lock card commands (Class 7) */
964 case 42: /* CMD42: LOCK_UNLOCK */ 1023 case 42: /* CMD42: LOCK_UNLOCK */
  1024 + if (sd->spi)
  1025 + goto unimplemented_cmd;
965 switch (sd->state) { 1026 switch (sd->state) {
966 case sd_transfer_state: 1027 case sd_transfer_state:
967 sd->state = sd_receivingdata_state; 1028 sd->state = sd_receivingdata_state;
@@ -1000,10 +1061,17 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, @@ -1000,10 +1061,17 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
1000 break; 1061 break;
1001 1062
1002 default: 1063 default:
  1064 + bad_cmd:
1003 sd->card_status |= ILLEGAL_COMMAND; 1065 sd->card_status |= ILLEGAL_COMMAND;
1004 1066
1005 printf("SD: Unknown CMD%i\n", req.cmd); 1067 printf("SD: Unknown CMD%i\n", req.cmd);
1006 return sd_r0; 1068 return sd_r0;
  1069 +
  1070 + unimplemented_cmd:
  1071 + /* Commands that are recognised but not yet implemented in SPI mode. */
  1072 + sd->card_status |= ILLEGAL_COMMAND;
  1073 + printf ("SD: CMD%i not implemented in SPI mode\n", req.cmd);
  1074 + return sd_r0;
1007 } 1075 }
1008 1076
1009 sd->card_status |= ILLEGAL_COMMAND; 1077 sd->card_status |= ILLEGAL_COMMAND;
@@ -1069,6 +1137,11 @@ static sd_rsp_type_t sd_app_command(SDState *sd, @@ -1069,6 +1137,11 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
1069 break; 1137 break;
1070 1138
1071 case 41: /* ACMD41: SD_APP_OP_COND */ 1139 case 41: /* ACMD41: SD_APP_OP_COND */
  1140 + if (sd->spi) {
  1141 + /* SEND_OP_CMD */
  1142 + sd->state = sd_transfer_state;
  1143 + return sd_r1;
  1144 + }
1072 switch (sd->state) { 1145 switch (sd->state) {
1073 case sd_idle_state: 1146 case sd_idle_state:
1074 /* We accept any voltage. 10000 V is nothing. */ 1147 /* We accept any voltage. 10000 V is nothing. */
@@ -1414,6 +1487,14 @@ uint8_t sd_read_data(SDState *sd) @@ -1414,6 +1487,14 @@ uint8_t sd_read_data(SDState *sd)
1414 sd->state = sd_transfer_state; 1487 sd->state = sd_transfer_state;
1415 break; 1488 break;
1416 1489
  1490 + case 9: /* CMD9: SEND_CSD */
  1491 + case 10: /* CMD10: SEND_CID */
  1492 + ret = sd->data[sd->data_offset ++];
  1493 +
  1494 + if (sd->data_offset >= 16)
  1495 + sd->state = sd_transfer_state;
  1496 + break;
  1497 +
1417 case 11: /* CMD11: READ_DAT_UNTIL_STOP */ 1498 case 11: /* CMD11: READ_DAT_UNTIL_STOP */
1418 if (sd->data_offset == 0) 1499 if (sd->data_offset == 0)
1419 BLK_READ_BLOCK(sd->data_start, sd->blk_len); 1500 BLK_READ_BLOCK(sd->data_start, sd->blk_len);
@@ -67,7 +67,7 @@ struct sd_request_s { @@ -67,7 +67,7 @@ struct sd_request_s {
67 67
68 typedef struct SDState SDState; 68 typedef struct SDState SDState;
69 69
70 -SDState *sd_init(BlockDriverState *bs); 70 +SDState *sd_init(BlockDriverState *bs, int is_spi);
71 int sd_do_command(SDState *sd, struct sd_request_s *req, 71 int sd_do_command(SDState *sd, struct sd_request_s *req,
72 uint8_t *response); 72 uint8_t *response);
73 void sd_write_data(SDState *sd, uint8_t value); 73 void sd_write_data(SDState *sd, uint8_t value);
@@ -75,4 +75,8 @@ uint8_t sd_read_data(SDState *sd); @@ -75,4 +75,8 @@ uint8_t sd_read_data(SDState *sd);
75 void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert); 75 void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
76 int sd_data_ready(SDState *sd); 76 int sd_data_ready(SDState *sd);
77 77
  78 +/* ssi-sd.c */
  79 +int ssi_sd_xfer(void *opaque, int val);
  80 +void *ssi_sd_init(BlockDriverState *bs);
  81 +
78 #endif /* __hw_sd_h */ 82 #endif /* __hw_sd_h */
hw/ssd0323.c
@@ -157,6 +157,9 @@ int ssd0323_xfer_ssi(void *opaque, int data) @@ -157,6 +157,9 @@ int ssd0323_xfer_ssi(void *opaque, int data)
157 case 0xe3: /* NOP. */ 157 case 0xe3: /* NOP. */
158 DATA(0); 158 DATA(0);
159 break; 159 break;
  160 + case 0xff: /* Nasty hack because we don't handle chip selects
  161 + properly. */
  162 + break;
160 default: 163 default:
161 BADF("Unknown command: 0x%x\n", data); 164 BADF("Unknown command: 0x%x\n", data);
162 } 165 }
hw/ssi-sd.c 0 โ†’ 100644
  1 +/*
  2 + * SSI to SD card adapter.
  3 + *
  4 + * Copyright (c) 2007 CodeSourcery.
  5 + * Written by Paul Brook
  6 + *
  7 + * This code is licenced under the GPL.
  8 + */
  9 +
  10 +#include "hw.h"
  11 +#include "sd.h"
  12 +
  13 +//#define DEBUG_SSI_SD 1
  14 +
  15 +#ifdef DEBUG_SSI_SD
  16 +#define DPRINTF(fmt, args...) \
  17 +do { printf("ssi_sd: " fmt , ##args); } while (0)
  18 +#define BADF(fmt, args...) \
  19 +do { fprintf(stderr, "ssi_sd: error: " fmt , ##args); exit(1);} while (0)
  20 +#else
  21 +#define DPRINTF(fmt, args...) do {} while(0)
  22 +#define BADF(fmt, args...) \
  23 +do { fprintf(stderr, "ssi_sd: error: " fmt , ##args);} while (0)
  24 +#endif
  25 +
  26 +typedef enum {
  27 + SSI_SD_CMD,
  28 + SSI_SD_CMDARG,
  29 + SSI_SD_RESPONSE,
  30 + SSI_SD_DATA_START,
  31 + SSI_SD_DATA_READ,
  32 +} ssi_sd_mode;
  33 +
  34 +typedef struct {
  35 + ssi_sd_mode mode;
  36 + int cmd;
  37 + uint8_t cmdarg[4];
  38 + uint8_t response[5];
  39 + int arglen;
  40 + int response_pos;
  41 + int stopping;
  42 + SDState *sd;
  43 +} ssi_sd_state;
  44 +
  45 +/* State word bits. */
  46 +#define SSI_SDR_LOCKED 0x0001
  47 +#define SSI_SDR_WP_ERASE 0x0002
  48 +#define SSI_SDR_ERROR 0x0004
  49 +#define SSI_SDR_CC_ERROR 0x0008
  50 +#define SSI_SDR_ECC_FAILED 0x0010
  51 +#define SSI_SDR_WP_VIOLATION 0x0020
  52 +#define SSI_SDR_ERASE_PARAM 0x0040
  53 +#define SSI_SDR_OUT_OF_RANGE 0x0080
  54 +#define SSI_SDR_IDLE 0x0100
  55 +#define SSI_SDR_ERASE_RESET 0x0200
  56 +#define SSI_SDR_ILLEGAL_COMMAND 0x0400
  57 +#define SSI_SDR_COM_CRC_ERROR 0x0800
  58 +#define SSI_SDR_ERASE_SEQ_ERROR 0x1000
  59 +#define SSI_SDR_ADDRESS_ERROR 0x2000
  60 +#define SSI_SDR_PARAMETER_ERROR 0x4000
  61 +
  62 +int ssi_sd_xfer(void *opaque, int val)
  63 +{
  64 + ssi_sd_state *s = (ssi_sd_state *)opaque;
  65 +
  66 + /* Special case: allow CMD12 (STOP TRANSMISSION) while reading data. */
  67 + if (s->mode == SSI_SD_DATA_READ && val == 0x4d) {
  68 + s->mode = SSI_SD_CMD;
  69 + /* There must be at least one byte delay before the card responds. */
  70 + s->stopping = 1;
  71 + }
  72 +
  73 + switch (s->mode) {
  74 + case SSI_SD_CMD:
  75 + if (val == 0xff) {
  76 + DPRINTF("NULL command\n");
  77 + return 0xff;
  78 + }
  79 + s->cmd = val & 0x3f;
  80 + s->mode = SSI_SD_CMDARG;
  81 + s->arglen = 0;
  82 + return 0xff;
  83 + case SSI_SD_CMDARG:
  84 + if (s->arglen == 4) {
  85 + struct sd_request_s request;
  86 + uint8_t longresp[16];
  87 + /* FIXME: Check CRC. */
  88 + request.cmd = s->cmd;
  89 + request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16)
  90 + | (s->cmdarg[2] << 8) | s->cmdarg[3];
  91 + DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
  92 + s->arglen = sd_do_command(s->sd, &request, longresp);
  93 + if (s->arglen <= 0) {
  94 + s->arglen = 1;
  95 + s->response[0] = 4;
  96 + DPRINTF("SD command failed\n");
  97 + } else if (s->cmd == 58) {
  98 + /* CMD58 returns R3 response (OCR) */
  99 + DPRINTF("Returned OCR\n");
  100 + s->arglen = 5;
  101 + s->response[0] = 1;
  102 + memcpy(&s->response[1], longresp, 4);
  103 + } else if (s->arglen != 4) {
  104 + BADF("Unexpected response to cmd %d\n", s->cmd);
  105 + /* Illegal command is about as near as we can get. */
  106 + s->arglen = 1;
  107 + s->response[0] = 4;
  108 + } else {
  109 + /* All other commands return status. */
  110 + uint32_t cardstatus;
  111 + uint16_t status;
  112 + /* CMD13 returns a 2-byte statuse work. Other commands
  113 + only return the first byte. */
  114 + s->arglen = (s->cmd == 13) ? 2 : 1;
  115 + cardstatus = (longresp[0] << 24) | (longresp[1] << 16)
  116 + | (longresp[2] << 8) | longresp[3];
  117 + status = 0;
  118 + if (((cardstatus >> 9) & 0xf) < 4)
  119 + status |= SSI_SDR_IDLE;
  120 + if (cardstatus & ERASE_RESET)
  121 + status |= SSI_SDR_ERASE_RESET;
  122 + if (cardstatus & ILLEGAL_COMMAND)
  123 + status |= SSI_SDR_ILLEGAL_COMMAND;
  124 + if (cardstatus & COM_CRC_ERROR)
  125 + status |= SSI_SDR_COM_CRC_ERROR;
  126 + if (cardstatus & ERASE_SEQ_ERROR)
  127 + status |= SSI_SDR_ERASE_SEQ_ERROR;
  128 + if (cardstatus & ADDRESS_ERROR)
  129 + status |= SSI_SDR_ADDRESS_ERROR;
  130 + if (cardstatus & CARD_IS_LOCKED)
  131 + status |= SSI_SDR_LOCKED;
  132 + if (cardstatus & (LOCK_UNLOCK_FAILED | WP_ERASE_SKIP))
  133 + status |= SSI_SDR_WP_ERASE;
  134 + if (cardstatus & SD_ERROR)
  135 + status |= SSI_SDR_ERROR;
  136 + if (cardstatus & CC_ERROR)
  137 + status |= SSI_SDR_CC_ERROR;
  138 + if (cardstatus & CARD_ECC_FAILED)
  139 + status |= SSI_SDR_ECC_FAILED;
  140 + if (cardstatus & WP_VIOLATION)
  141 + status |= SSI_SDR_WP_VIOLATION;
  142 + if (cardstatus & ERASE_PARAM)
  143 + status |= SSI_SDR_ERASE_PARAM;
  144 + if (cardstatus & (OUT_OF_RANGE | CID_CSD_OVERWRITE))
  145 + status |= SSI_SDR_OUT_OF_RANGE;
  146 + /* ??? Don't know what Parameter Error really means, so
  147 + assume it's set if the second byte is nonzero. */
  148 + if (status & 0xff)
  149 + status |= SSI_SDR_PARAMETER_ERROR;
  150 + s->response[0] = status >> 8;
  151 + s->response[1] = status;
  152 + DPRINTF("Card status 0x%02x\n", status);
  153 + }
  154 + s->mode = SSI_SD_RESPONSE;
  155 + s->response_pos = 0;
  156 + } else {
  157 + s->cmdarg[s->arglen++] = val;
  158 + }
  159 + return 0xff;
  160 + case SSI_SD_RESPONSE:
  161 + if (s->stopping) {
  162 + s->stopping = 0;
  163 + return 0xff;
  164 + }
  165 + if (s->response_pos < s->arglen) {
  166 + DPRINTF("Response 0x%02x\n", s->response[s->response_pos]);
  167 + return s->response[s->response_pos++];
  168 + }
  169 + if (sd_data_ready(s->sd)) {
  170 + DPRINTF("Data read\n");
  171 + s->mode = SSI_SD_DATA_START;
  172 + } else {
  173 + DPRINTF("End of command\n");
  174 + s->mode = SSI_SD_CMD;
  175 + }
  176 + return 0xff;
  177 + case SSI_SD_DATA_START:
  178 + DPRINTF("Start read block\n");
  179 + s->mode = SSI_SD_DATA_READ;
  180 + return 0xfe;
  181 + case SSI_SD_DATA_READ:
  182 + val = sd_read_data(s->sd);
  183 + if (!sd_data_ready(s->sd)) {
  184 + DPRINTF("Data read end\n");
  185 + s->mode = SSI_SD_CMD;
  186 + }
  187 + return val;
  188 + }
  189 + /* Should never happen. */
  190 + return 0xff;
  191 +}
  192 +
  193 +void *ssi_sd_init(BlockDriverState *bs)
  194 +{
  195 + ssi_sd_state *s;
  196 +
  197 + s = (ssi_sd_state *)qemu_mallocz(sizeof(ssi_sd_state));
  198 + s->mode = SSI_SD_CMD;
  199 + s->sd = sd_init(bs, 1);
  200 + return s;
  201 +}
  202 +
hw/stellaris.c
@@ -14,6 +14,7 @@ @@ -14,6 +14,7 @@
14 #include "qemu-timer.h" 14 #include "qemu-timer.h"
15 #include "i2c.h" 15 #include "i2c.h"
16 #include "net.h" 16 #include "net.h"
  17 +#include "sd.h"
17 #include "sysemu.h" 18 #include "sysemu.h"
18 #include "boards.h" 19 #include "boards.h"
19 20
@@ -1000,6 +1001,51 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq) @@ -1000,6 +1001,51 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
1000 return qi[0]; 1001 return qi[0];
1001 } 1002 }
1002 1003
  1004 +/* Some boards have both an OLED controller and SD card connected to
  1005 + the same SSI port, with the SD card chip select connected to a
  1006 + GPIO pin. Technically the OLED chip select is connected to the SSI
  1007 + Fss pin. We do not bother emulating that as both devices should
  1008 + never be selected simultaneously, and our OLED controller ignores stray
  1009 + 0xff commands that occur when deselecting the SD card. */
  1010 +
  1011 +typedef struct {
  1012 + ssi_xfer_cb xfer_cb[2];
  1013 + void *opaque[2];
  1014 + qemu_irq irq;
  1015 + int current_dev;
  1016 +} stellaris_ssi_bus_state;
  1017 +
  1018 +static void stellaris_ssi_bus_select(void *opaque, int irq, int level)
  1019 +{
  1020 + stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
  1021 +
  1022 + s->current_dev = level;
  1023 +}
  1024 +
  1025 +static int stellaris_ssi_bus_xfer(void *opaque, int val)
  1026 +{
  1027 + stellaris_ssi_bus_state *s = (stellaris_ssi_bus_state *)opaque;
  1028 +
  1029 + return s->xfer_cb[s->current_dev](s->opaque[s->current_dev], val);
  1030 +}
  1031 +
  1032 +static void *stellaris_ssi_bus_init(qemu_irq *irqp,
  1033 + ssi_xfer_cb cb0, void *opaque0,
  1034 + ssi_xfer_cb cb1, void *opaque1)
  1035 +{
  1036 + qemu_irq *qi;
  1037 + stellaris_ssi_bus_state *s;
  1038 +
  1039 + s = (stellaris_ssi_bus_state *)qemu_mallocz(sizeof(stellaris_ssi_bus_state));
  1040 + s->xfer_cb[0] = cb0;
  1041 + s->opaque[0] = opaque0;
  1042 + s->xfer_cb[1] = cb1;
  1043 + s->opaque[1] = opaque1;
  1044 + qi = qemu_allocate_irqs(stellaris_ssi_bus_select, s, 1);
  1045 + *irqp = *qi;
  1046 + return s;
  1047 +}
  1048 +
1003 /* Board init. */ 1049 /* Board init. */
1004 static stellaris_board_info stellaris_boards[] = { 1050 static stellaris_board_info stellaris_boards[] = {
1005 { "LM3S811EVB", 1051 { "LM3S811EVB",
@@ -1085,9 +1131,19 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model, @@ -1085,9 +1131,19 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1085 if (board->dc2 & (1 << 4)) { 1131 if (board->dc2 & (1 << 4)) {
1086 if (board->peripherals & BP_OLED_SSI) { 1132 if (board->peripherals & BP_OLED_SSI) {
1087 void * oled; 1133 void * oled;
1088 - /* FIXME: Implement chip select for OLED/MMC. */ 1134 + void * sd;
  1135 + void *ssi_bus;
  1136 +
1089 oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]); 1137 oled = ssd0323_init(ds, &gpio_out[GPIO_C][7]);
1090 - pl022_init(0x40008000, pic[7], ssd0323_xfer_ssi, oled); 1138 + sd = ssi_sd_init(sd_bdrv);
  1139 +
  1140 + ssi_bus = stellaris_ssi_bus_init(&gpio_out[GPIO_D][0],
  1141 + ssi_sd_xfer, sd,
  1142 + ssd0323_xfer_ssi, oled);
  1143 +
  1144 + pl022_init(0x40008000, pic[7], stellaris_ssi_bus_xfer, ssi_bus);
  1145 + /* Make sure the select pin is high. */
  1146 + qemu_irq_raise(gpio_out[GPIO_D][0]);
1091 } else { 1147 } else {
1092 pl022_init(0x40008000, pic[7], NULL, NULL); 1148 pl022_init(0x40008000, pic[7], NULL, NULL);
1093 } 1149 }