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 57 OBJS+=ssd0303.o ssd0323.o ads7846.o stellaris_input.o
58 58 OBJS+=scsi-disk.o cdrom.o
59 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 62 ifdef CONFIG_WIN32
62 63 OBJS+=tap-win32.o
... ...
Makefile.target
... ... @@ -488,7 +488,7 @@ endif
488 488 ifeq ($(TARGET_BASE_ARCH), arm)
489 489 VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
490 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 492 VL_OBJS+= realview_gic.o realview.o arm_sysctl.o mpcore.o
493 493 VL_OBJS+= armv7m.o armv7m_nvic.o stellaris.o pl022.o stellaris_enet.o
494 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 525 cpu_register_physical_memory(s->base, 0x800, iomemtype);
526 526  
527 527 /* Instantiate the storage */
528   - s->card = sd_init(bd);
  528 + s->card = sd_init(bd, 0);
529 529  
530 530 return s;
531 531 }
... ...
hw/pl061.c
... ... @@ -48,6 +48,7 @@ typedef struct {
48 48 uint8_t slr;
49 49 uint8_t den;
50 50 uint8_t cr;
  51 + uint8_t float_high;
51 52 qemu_irq irq;
52 53 qemu_irq out[8];
53 54 } pl061_state;
... ... @@ -56,18 +57,22 @@ static void pl061_update(pl061_state *s)
56 57 {
57 58 uint8_t changed;
58 59 uint8_t mask;
  60 + uint8_t out;
59 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 67 if (!changed)
63 68 return;
64 69  
65   - s->old_data = s->data;
  70 + s->old_data = out;
66 71 for (i = 0; i < 8; i++) {
67 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 458 pl181_writefn, s);
459 459 cpu_register_physical_memory(base, 0x00001000, iomemtype);
460 460 s->base = base;
461   - s->card = sd_init(bd);
  461 + s->card = sd_init(bd, 0);
462 462 s->irq[0] = irq0;
463 463 s->irq[1] = irq1;
464 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 21 enum pl011_type type);
22 22  
23 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 26 void *opaque);
26 27  
27 28 /* pl050.c */
28 29 void pl050_init(uint32_t base, qemu_irq irq, int is_mouse);
29 30  
30 31 /* pl061.c */
  32 +void pl061_float_high(void *opaque, uint8_t mask);
31 33 qemu_irq *pl061_init(uint32_t base, qemu_irq irq, qemu_irq **out);
32 34  
33 35 /* pl080.c */
... ...
hw/pxa2xx_mmci.c
... ... @@ -538,7 +538,7 @@ struct pxa2xx_mmci_s *pxa2xx_mmci_init(target_phys_addr_t base,
538 538 cpu_register_physical_memory(base, 0x00100000, iomemtype);
539 539  
540 540 /* Instantiate the actual storage */
541   - s->card = sd_init(bd);
  541 + s->card = sd_init(bd, 1);
542 542  
543 543 register_savevm("pxa2xx_mmci", 0, 0,
544 544 pxa2xx_mmci_save, pxa2xx_mmci_load, s);
... ...
... ... @@ -87,6 +87,7 @@ struct SDState {
87 87 int pwd_len;
88 88 int function_group[6];
89 89  
  90 + int spi;
90 91 int current_cmd;
91 92 int blk_written;
92 93 uint32_t data_start;
... ... @@ -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 405 SDState *sd;
401 406  
402 407 sd = (SDState *) qemu_mallocz(sizeof(SDState));
  408 + sd->spi = is_spi;
403 409 sd_reset(sd, bs);
404 410 bdrv_set_change_cb(sd->bdrv, sd_cardchange, sd);
405 411 return sd;
... ... @@ -567,16 +573,25 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
567 573 case 0: /* CMD0: GO_IDLE_STATE */
568 574 switch (sd->state) {
569 575 case sd_inactive_state:
570   - return sd_r0;
  576 + return sd->spi ? sd_r1 : sd_r0;
571 577  
572 578 default:
573 579 sd->state = sd_idle_state;
574 580 sd_reset(sd, sd->bdrv);
575   - return sd_r0;
  581 + return sd->spi ? sd_r1 : sd_r0;
576 582 }
577 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 592 case 2: /* CMD2: ALL_SEND_CID */
  593 + if (sd->spi)
  594 + goto bad_cmd;
580 595 switch (sd->state) {
581 596 case sd_ready_state:
582 597 sd->state = sd_identification_state;
... ... @@ -588,6 +603,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
588 603 break;
589 604  
590 605 case 3: /* CMD3: SEND_RELATIVE_ADDR */
  606 + if (sd->spi)
  607 + goto bad_cmd;
591 608 switch (sd->state) {
592 609 case sd_identification_state:
593 610 case sd_standby_state:
... ... @@ -601,6 +618,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
601 618 break;
602 619  
603 620 case 4: /* CMD4: SEND_DSR */
  621 + if (sd->spi)
  622 + goto bad_cmd;
604 623 switch (sd->state) {
605 624 case sd_standby_state:
606 625 break;
... ... @@ -611,6 +630,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
611 630 break;
612 631  
613 632 case 6: /* CMD6: SWITCH_FUNCTION */
  633 + if (sd->spi)
  634 + goto bad_cmd;
614 635 switch (sd->mode) {
615 636 case sd_data_transfer_mode:
616 637 sd_function_switch(sd, req.arg);
... ... @@ -625,6 +646,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
625 646 break;
626 647  
627 648 case 7: /* CMD7: SELECT/DESELECT_CARD */
  649 + if (sd->spi)
  650 + goto bad_cmd;
628 651 switch (sd->state) {
629 652 case sd_standby_state:
630 653 if (sd->rca != rca)
... ... @@ -668,6 +691,15 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
668 691  
669 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 703 default:
672 704 break;
673 705 }
... ... @@ -681,12 +713,23 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
681 713  
682 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 725 default:
685 726 break;
686 727 }
687 728 break;
688 729  
689 730 case 11: /* CMD11: READ_DAT_UNTIL_STOP */
  731 + if (sd->spi)
  732 + goto bad_cmd;
690 733 switch (sd->state) {
691 734 case sd_transfer_state:
692 735 sd->state = sd_sendingdata_state;
... ... @@ -733,6 +776,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
733 776 break;
734 777  
735 778 case 15: /* CMD15: GO_INACTIVE_STATE */
  779 + if (sd->spi)
  780 + goto bad_cmd;
736 781 switch (sd->mode) {
737 782 case sd_data_transfer_mode:
738 783 if (sd->rca != rca)
... ... @@ -796,8 +841,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
796 841  
797 842 /* Block write commands (Class 4) */
798 843 case 24: /* CMD24: WRITE_SINGLE_BLOCK */
  844 + if (sd->spi)
  845 + goto unimplemented_cmd;
799 846 switch (sd->state) {
800 847 case sd_transfer_state:
  848 + /* Writing in SPI mode not implemented. */
  849 + if (sd->spi)
  850 + break;
801 851 sd->state = sd_receivingdata_state;
802 852 sd->data_start = req.arg;
803 853 sd->data_offset = 0;
... ... @@ -817,8 +867,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
817 867 break;
818 868  
819 869 case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
  870 + if (sd->spi)
  871 + goto unimplemented_cmd;
820 872 switch (sd->state) {
821 873 case sd_transfer_state:
  874 + /* Writing in SPI mode not implemented. */
  875 + if (sd->spi)
  876 + break;
822 877 sd->state = sd_receivingdata_state;
823 878 sd->data_start = req.arg;
824 879 sd->data_offset = 0;
... ... @@ -838,6 +893,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
838 893 break;
839 894  
840 895 case 26: /* CMD26: PROGRAM_CID */
  896 + if (sd->spi)
  897 + goto bad_cmd;
841 898 switch (sd->state) {
842 899 case sd_transfer_state:
843 900 sd->state = sd_receivingdata_state;
... ... @@ -851,6 +908,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
851 908 break;
852 909  
853 910 case 27: /* CMD27: PROGRAM_CSD */
  911 + if (sd->spi)
  912 + goto unimplemented_cmd;
854 913 switch (sd->state) {
855 914 case sd_transfer_state:
856 915 sd->state = sd_receivingdata_state;
... ... @@ -962,6 +1021,8 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
962 1021  
963 1022 /* Lock card commands (Class 7) */
964 1023 case 42: /* CMD42: LOCK_UNLOCK */
  1024 + if (sd->spi)
  1025 + goto unimplemented_cmd;
965 1026 switch (sd->state) {
966 1027 case sd_transfer_state:
967 1028 sd->state = sd_receivingdata_state;
... ... @@ -1000,10 +1061,17 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
1000 1061 break;
1001 1062  
1002 1063 default:
  1064 + bad_cmd:
1003 1065 sd->card_status |= ILLEGAL_COMMAND;
1004 1066  
1005 1067 printf("SD: Unknown CMD%i\n", req.cmd);
1006 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 1077 sd->card_status |= ILLEGAL_COMMAND;
... ... @@ -1069,6 +1137,11 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
1069 1137 break;
1070 1138  
1071 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 1145 switch (sd->state) {
1073 1146 case sd_idle_state:
1074 1147 /* We accept any voltage. 10000 V is nothing. */
... ... @@ -1414,6 +1487,14 @@ uint8_t sd_read_data(SDState *sd)
1414 1487 sd->state = sd_transfer_state;
1415 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 1498 case 11: /* CMD11: READ_DAT_UNTIL_STOP */
1418 1499 if (sd->data_offset == 0)
1419 1500 BLK_READ_BLOCK(sd->data_start, sd->blk_len);
... ...
... ... @@ -67,7 +67,7 @@ struct sd_request_s {
67 67  
68 68 typedef struct SDState SDState;
69 69  
70   -SDState *sd_init(BlockDriverState *bs);
  70 +SDState *sd_init(BlockDriverState *bs, int is_spi);
71 71 int sd_do_command(SDState *sd, struct sd_request_s *req,
72 72 uint8_t *response);
73 73 void sd_write_data(SDState *sd, uint8_t value);
... ... @@ -75,4 +75,8 @@ uint8_t sd_read_data(SDState *sd);
75 75 void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
76 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 82 #endif /* __hw_sd_h */
... ...
hw/ssd0323.c
... ... @@ -157,6 +157,9 @@ int ssd0323_xfer_ssi(void *opaque, int data)
157 157 case 0xe3: /* NOP. */
158 158 DATA(0);
159 159 break;
  160 + case 0xff: /* Nasty hack because we don't handle chip selects
  161 + properly. */
  162 + break;
160 163 default:
161 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 14 #include "qemu-timer.h"
15 15 #include "i2c.h"
16 16 #include "net.h"
  17 +#include "sd.h"
17 18 #include "sysemu.h"
18 19 #include "boards.h"
19 20  
... ... @@ -1000,6 +1001,51 @@ static qemu_irq stellaris_adc_init(uint32_t base, qemu_irq irq)
1000 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 1049 /* Board init. */
1004 1050 static stellaris_board_info stellaris_boards[] = {
1005 1051 { "LM3S811EVB",
... ... @@ -1085,9 +1131,19 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
1085 1131 if (board->dc2 & (1 << 4)) {
1086 1132 if (board->peripherals & BP_OLED_SSI) {
1087 1133 void * oled;
1088   - /* FIXME: Implement chip select for OLED/MMC. */
  1134 + void * sd;
  1135 + void *ssi_bus;
  1136 +
1089 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 1147 } else {
1092 1148 pl022_init(0x40008000, pic[7], NULL, NULL);
1093 1149 }
... ...