2 * SSI to SD card adapter.
4 * Copyright (c) 2007-2009 CodeSourcery.
5 * Written by Paul Brook
7 * This code is licensed under the GNU GPL v2.
9 * Contributions after 2012-01-13 are licensed under the terms of the
10 * GNU GPL, version 2 or (at your option) any later version.
13 #include "qemu/osdep.h"
14 #include "sysemu/blockdev.h"
15 #include "hw/ssi/ssi.h"
16 #include "migration/vmstate.h"
17 #include "hw/qdev-properties.h"
19 #include "qapi/error.h"
20 #include "qemu/crc-ccitt.h"
21 #include "qemu/module.h"
22 #include "qom/object.h"
24 //#define DEBUG_SSI_SD 1
27 #define DPRINTF(fmt, ...) \
28 do { printf("ssi_sd: " fmt , ## __VA_ARGS__); } while (0)
29 #define BADF(fmt, ...) \
30 do { fprintf(stderr, "ssi_sd: error: " fmt , ## __VA_ARGS__); exit(1);} while (0)
32 #define DPRINTF(fmt, ...) do {} while(0)
33 #define BADF(fmt, ...) \
34 do { fprintf(stderr, "ssi_sd: error: " fmt , ## __VA_ARGS__);} while (0)
62 #define TYPE_SSI_SD "ssi-sd"
63 OBJECT_DECLARE_SIMPLE_TYPE(ssi_sd_state
, SSI_SD
)
65 /* State word bits. */
66 #define SSI_SDR_LOCKED 0x0001
67 #define SSI_SDR_WP_ERASE 0x0002
68 #define SSI_SDR_ERROR 0x0004
69 #define SSI_SDR_CC_ERROR 0x0008
70 #define SSI_SDR_ECC_FAILED 0x0010
71 #define SSI_SDR_WP_VIOLATION 0x0020
72 #define SSI_SDR_ERASE_PARAM 0x0040
73 #define SSI_SDR_OUT_OF_RANGE 0x0080
74 #define SSI_SDR_IDLE 0x0100
75 #define SSI_SDR_ERASE_RESET 0x0200
76 #define SSI_SDR_ILLEGAL_COMMAND 0x0400
77 #define SSI_SDR_COM_CRC_ERROR 0x0800
78 #define SSI_SDR_ERASE_SEQ_ERROR 0x1000
79 #define SSI_SDR_ADDRESS_ERROR 0x2000
80 #define SSI_SDR_PARAMETER_ERROR 0x4000
82 /* single block read/write, multiple block read */
83 #define SSI_TOKEN_SINGLE 0xfe
85 /* dummy value - don't care */
86 #define SSI_DUMMY 0xff
88 static uint32_t ssi_sd_transfer(SSIPeripheral
*dev
, uint32_t val
)
90 ssi_sd_state
*s
= SSI_SD(dev
);
93 * Special case: allow CMD12 (STOP TRANSMISSION) while reading data.
95 * See "Physical Layer Specification Version 8.00" chapter 7.5.2.2,
96 * to avoid conflict between CMD12 response and next data block,
97 * timing of CMD12 should be controlled as follows:
99 * - CMD12 issued at the timing that end bit of CMD12 and end bit of
100 * data block is overlapped
101 * - CMD12 issued after one clock cycle after host receives a token
102 * (either Start Block token or Data Error token)
104 * We need to catch CMD12 in all of the data read states.
106 if (s
->mode
>= SSI_SD_PREP_DATA
&& s
->mode
<= SSI_SD_DATA_CRC16
) {
108 s
->mode
= SSI_SD_CMD
;
109 /* There must be at least one byte delay before the card responds */
116 if (val
== SSI_DUMMY
) {
117 DPRINTF("NULL command\n");
121 s
->mode
= SSI_SD_CMDARG
;
125 if (s
->arglen
== 4) {
127 uint8_t longresp
[16];
128 /* FIXME: Check CRC. */
129 request
.cmd
= s
->cmd
;
130 request
.arg
= ldl_be_p(s
->cmdarg
);
131 DPRINTF("CMD%d arg 0x%08x\n", s
->cmd
, request
.arg
);
132 s
->arglen
= sdbus_do_command(&s
->sdbus
, &request
, longresp
);
133 if (s
->arglen
<= 0) {
136 DPRINTF("SD command failed\n");
137 } else if (s
->cmd
== 58) {
138 /* CMD58 returns R3 response (OCR) */
139 DPRINTF("Returned OCR\n");
142 memcpy(&s
->response
[1], longresp
, 4);
143 } else if (s
->arglen
!= 4) {
144 BADF("Unexpected response to cmd %d\n", s
->cmd
);
145 /* Illegal command is about as near as we can get. */
149 /* All other commands return status. */
152 /* CMD13 returns a 2-byte statuse work. Other commands
153 only return the first byte. */
154 s
->arglen
= (s
->cmd
== 13) ? 2 : 1;
155 cardstatus
= ldl_be_p(longresp
);
157 if (((cardstatus
>> 9) & 0xf) < 4)
158 status
|= SSI_SDR_IDLE
;
159 if (cardstatus
& ERASE_RESET
)
160 status
|= SSI_SDR_ERASE_RESET
;
161 if (cardstatus
& ILLEGAL_COMMAND
)
162 status
|= SSI_SDR_ILLEGAL_COMMAND
;
163 if (cardstatus
& COM_CRC_ERROR
)
164 status
|= SSI_SDR_COM_CRC_ERROR
;
165 if (cardstatus
& ERASE_SEQ_ERROR
)
166 status
|= SSI_SDR_ERASE_SEQ_ERROR
;
167 if (cardstatus
& ADDRESS_ERROR
)
168 status
|= SSI_SDR_ADDRESS_ERROR
;
169 if (cardstatus
& CARD_IS_LOCKED
)
170 status
|= SSI_SDR_LOCKED
;
171 if (cardstatus
& (LOCK_UNLOCK_FAILED
| WP_ERASE_SKIP
))
172 status
|= SSI_SDR_WP_ERASE
;
173 if (cardstatus
& SD_ERROR
)
174 status
|= SSI_SDR_ERROR
;
175 if (cardstatus
& CC_ERROR
)
176 status
|= SSI_SDR_CC_ERROR
;
177 if (cardstatus
& CARD_ECC_FAILED
)
178 status
|= SSI_SDR_ECC_FAILED
;
179 if (cardstatus
& WP_VIOLATION
)
180 status
|= SSI_SDR_WP_VIOLATION
;
181 if (cardstatus
& ERASE_PARAM
)
182 status
|= SSI_SDR_ERASE_PARAM
;
183 if (cardstatus
& (OUT_OF_RANGE
| CID_CSD_OVERWRITE
))
184 status
|= SSI_SDR_OUT_OF_RANGE
;
185 /* ??? Don't know what Parameter Error really means, so
186 assume it's set if the second byte is nonzero. */
188 status
|= SSI_SDR_PARAMETER_ERROR
;
189 s
->response
[0] = status
>> 8;
190 s
->response
[1] = status
;
191 DPRINTF("Card status 0x%02x\n", status
);
193 s
->mode
= SSI_SD_PREP_RESP
;
196 s
->cmdarg
[s
->arglen
++] = val
;
199 case SSI_SD_PREP_RESP
:
200 DPRINTF("Prepare card response (Ncr)\n");
201 s
->mode
= SSI_SD_RESPONSE
;
203 case SSI_SD_RESPONSE
:
208 if (s
->response_pos
< s
->arglen
) {
209 DPRINTF("Response 0x%02x\n", s
->response
[s
->response_pos
]);
210 return s
->response
[s
->response_pos
++];
212 if (sdbus_data_ready(&s
->sdbus
)) {
213 DPRINTF("Data read\n");
214 s
->mode
= SSI_SD_DATA_START
;
216 DPRINTF("End of command\n");
217 s
->mode
= SSI_SD_CMD
;
220 case SSI_SD_PREP_DATA
:
221 DPRINTF("Prepare data block (Nac)\n");
222 s
->mode
= SSI_SD_DATA_START
;
224 case SSI_SD_DATA_START
:
225 DPRINTF("Start read block\n");
226 s
->mode
= SSI_SD_DATA_READ
;
228 return SSI_TOKEN_SINGLE
;
229 case SSI_SD_DATA_READ
:
230 val
= sdbus_read_byte(&s
->sdbus
);
232 s
->crc16
= crc_ccitt_false(s
->crc16
, (uint8_t *)&val
, 1);
233 if (!sdbus_data_ready(&s
->sdbus
) || s
->read_bytes
== 512) {
234 DPRINTF("Data read end\n");
235 s
->mode
= SSI_SD_DATA_CRC16
;
238 case SSI_SD_DATA_CRC16
:
239 val
= (s
->crc16
& 0xff00) >> 8;
242 if (s
->response_pos
== 2) {
243 DPRINTF("CRC16 read end\n");
244 if (s
->read_bytes
== 512 && s
->cmd
!= 17) {
245 s
->mode
= SSI_SD_PREP_DATA
;
247 s
->mode
= SSI_SD_CMD
;
254 /* Should never happen. */
258 static int ssi_sd_post_load(void *opaque
, int version_id
)
260 ssi_sd_state
*s
= (ssi_sd_state
*)opaque
;
262 if (s
->mode
> SSI_SD_DATA_CRC16
) {
265 if (s
->mode
== SSI_SD_CMDARG
&&
266 (s
->arglen
< 0 || s
->arglen
>= ARRAY_SIZE(s
->cmdarg
))) {
269 if (s
->mode
== SSI_SD_RESPONSE
&&
270 (s
->response_pos
< 0 || s
->response_pos
>= ARRAY_SIZE(s
->response
) ||
271 (!s
->stopping
&& s
->arglen
> ARRAY_SIZE(s
->response
)))) {
278 static const VMStateDescription vmstate_ssi_sd
= {
281 .minimum_version_id
= 6,
282 .post_load
= ssi_sd_post_load
,
283 .fields
= (VMStateField
[]) {
284 VMSTATE_UINT32(mode
, ssi_sd_state
),
285 VMSTATE_INT32(cmd
, ssi_sd_state
),
286 VMSTATE_UINT8_ARRAY(cmdarg
, ssi_sd_state
, 4),
287 VMSTATE_UINT8_ARRAY(response
, ssi_sd_state
, 5),
288 VMSTATE_UINT16(crc16
, ssi_sd_state
),
289 VMSTATE_INT32(read_bytes
, ssi_sd_state
),
290 VMSTATE_INT32(arglen
, ssi_sd_state
),
291 VMSTATE_INT32(response_pos
, ssi_sd_state
),
292 VMSTATE_INT32(stopping
, ssi_sd_state
),
293 VMSTATE_SSI_PERIPHERAL(ssidev
, ssi_sd_state
),
294 VMSTATE_END_OF_LIST()
298 static void ssi_sd_realize(SSIPeripheral
*d
, Error
**errp
)
301 ssi_sd_state
*s
= SSI_SD(d
);
302 DeviceState
*carddev
;
305 qbus_create_inplace(&s
->sdbus
, sizeof(s
->sdbus
), TYPE_SD_BUS
,
306 DEVICE(d
), "sd-bus");
308 /* Create and plug in the sd card */
309 /* FIXME use a qdev drive property instead of drive_get_next() */
310 dinfo
= drive_get_next(IF_SD
);
311 carddev
= qdev_new(TYPE_SD_CARD
);
313 if (!qdev_prop_set_drive_err(carddev
, "drive",
314 blk_by_legacy_dinfo(dinfo
), errp
)) {
319 if (!object_property_set_bool(OBJECT(carddev
), "spi", true, errp
)) {
323 if (!qdev_realize_and_unref(carddev
, BUS(&s
->sdbus
), errp
)) {
330 error_prepend(errp
, "failed to init SD card: ");
333 static void ssi_sd_reset(DeviceState
*dev
)
335 ssi_sd_state
*s
= SSI_SD(dev
);
337 s
->mode
= SSI_SD_CMD
;
339 memset(s
->cmdarg
, 0, sizeof(s
->cmdarg
));
340 memset(s
->response
, 0, sizeof(s
->response
));
348 static void ssi_sd_class_init(ObjectClass
*klass
, void *data
)
350 DeviceClass
*dc
= DEVICE_CLASS(klass
);
351 SSIPeripheralClass
*k
= SSI_PERIPHERAL_CLASS(klass
);
353 k
->realize
= ssi_sd_realize
;
354 k
->transfer
= ssi_sd_transfer
;
355 k
->cs_polarity
= SSI_CS_LOW
;
356 dc
->vmsd
= &vmstate_ssi_sd
;
357 dc
->reset
= ssi_sd_reset
;
358 /* Reason: init() method uses drive_get_next() */
359 dc
->user_creatable
= false;
362 static const TypeInfo ssi_sd_info
= {
364 .parent
= TYPE_SSI_PERIPHERAL
,
365 .instance_size
= sizeof(ssi_sd_state
),
366 .class_init
= ssi_sd_class_init
,
369 static void ssi_sd_register_types(void)
371 type_register_static(&ssi_sd_info
);
374 type_init(ssi_sd_register_types
)