From: jmcmullan@netronome.com (Jason McMullan)
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] (no subject)
Date: Fri, 30 Oct 2009 21:07:24 -0400 (EDT) [thread overview]
Message-ID: <20091031010724.DAC4E3C662@mcmullan-linux> (raw)
>From cc0481503722124f085d785637aeea9ea51fab9b Mon Sep 17 00:00:00 2001
From: Jason S. McMullan <jason.mcmullan@gmail.com>
Date: Wed, 28 Oct 2009 00:56:00 -0400
Subject: [PATCH] hw/sd: Support SDHC size cards
Signed-off-by: Jason S. McMullan <jason.mcmullan@gmail.com>
---
hw/sd.c | 153 ++++++++++++++++++++++++++++++++++++++-------------------------
1 files changed, 93 insertions(+), 60 deletions(-)
diff --git a/hw/sd.c b/hw/sd.c
index 9888547..4d306af 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -81,7 +81,7 @@ struct SDState {
uint32_t vhs;
int wp_switch;
int *wp_groups;
- uint32_t size;
+ uint64_t size;
int blk_len;
uint32_t erase_start;
uint32_t erase_end;
@@ -92,7 +92,7 @@ struct SDState {
int spi;
int current_cmd;
int blk_written;
- uint32_t data_start;
+ uint64_t data_start;
uint32_t data_offset;
uint8_t data[512];
qemu_irq readonly_cb;
@@ -249,37 +249,59 @@ static const uint8_t sd_csd_rw_mask[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe,
};
-static void sd_set_csd(SDState *sd, uint32_t size)
+static void sd_set_csd(SDState *sd, uint64_t size)
{
uint32_t csize = (size >> (CMULT_SHIFT + HWBLOCK_SHIFT)) - 1;
uint32_t sectsize = (1 << (SECTOR_SHIFT + 1)) - 1;
uint32_t wpsize = (1 << (WPGROUP_SHIFT + 1)) - 1;
- sd->csd[0] = 0x00; /* CSD structure */
- sd->csd[1] = 0x26; /* Data read access-time-1 */
- sd->csd[2] = 0x00; /* Data read access-time-2 */
- sd->csd[3] = 0x5a; /* Max. data transfer rate */
- sd->csd[4] = 0x5f; /* Card Command Classes */
- sd->csd[5] = 0x50 | /* Max. read data block length */
- HWBLOCK_SHIFT;
- sd->csd[6] = 0xe0 | /* Partial block for read allowed */
- ((csize >> 10) & 0x03);
- sd->csd[7] = 0x00 | /* Device size */
- ((csize >> 2) & 0xff);
- sd->csd[8] = 0x3f | /* Max. read current */
- ((csize << 6) & 0xc0);
- sd->csd[9] = 0xfc | /* Max. write current */
- ((CMULT_SHIFT - 2) >> 1);
- sd->csd[10] = 0x40 | /* Erase sector size */
- (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
- sd->csd[11] = 0x00 | /* Write protect group size */
- ((sectsize << 7) & 0x80) | wpsize;
- sd->csd[12] = 0x90 | /* Write speed factor */
- (HWBLOCK_SHIFT >> 2);
- sd->csd[13] = 0x20 | /* Max. write data block length */
- ((HWBLOCK_SHIFT << 6) & 0xc0);
- sd->csd[14] = 0x00; /* File format group */
- sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
+ if (size <= 0x40000000) {
+ sd->csd[0] = 0x00; /* CSD structure */
+ sd->csd[1] = 0x26; /* Data read access-time-1 */
+ sd->csd[2] = 0x00; /* Data read access-time-2 */
+ sd->csd[3] = 0x5a; /* Max. data transfer rate */
+ sd->csd[4] = 0x5f; /* Card Command Classes */
+ sd->csd[5] = 0x50 | /* Max. read data block length */
+ HWBLOCK_SHIFT;
+ sd->csd[6] = 0xe0 | /* Partial block for read allowed */
+ ((csize >> 10) & 0x03);
+ sd->csd[7] = 0x00 | /* Device size */
+ ((csize >> 2) & 0xff);
+ sd->csd[8] = 0x3f | /* Max. read current */
+ ((csize << 6) & 0xc0);
+ sd->csd[9] = 0xfc | /* Max. write current */
+ ((CMULT_SHIFT - 2) >> 1);
+ sd->csd[10] = 0x40 | /* Erase sector size */
+ (((CMULT_SHIFT - 2) << 7) & 0x80) | (sectsize >> 1);
+ sd->csd[11] = 0x00 | /* Write protect group size */
+ ((sectsize << 7) & 0x80) | wpsize;
+ sd->csd[12] = 0x90 | /* Write speed factor */
+ (HWBLOCK_SHIFT >> 2);
+ sd->csd[13] = 0x20 | /* Max. write data block length */
+ ((HWBLOCK_SHIFT << 6) & 0xc0);
+ sd->csd[14] = 0x00; /* File format group */
+ sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
+ } else {
+ size /= 512 * 1024;
+ size -= 1;
+ sd->csd[0] = 0x40;
+ sd->csd[1] = 0x0e;
+ sd->csd[2] = 0x00;
+ sd->csd[3] = 0x32;
+ sd->csd[4] = 0x5b;
+ sd->csd[5] = 0x59;
+ sd->csd[6] = 0x00;
+ sd->csd[7] = (size >> 16) & 0xff;
+ sd->csd[8] = (size >> 8) & 0xff;
+ sd->csd[9] = (size & 0xff);
+ sd->csd[10] = 0x7f;
+ sd->csd[11] = 0x80;
+ sd->csd[12] = 0x0a;
+ sd->csd[13] = 0x40;
+ sd->csd[14] = 0x00;
+ sd->csd[15] = 0x00;
+ sd->ocr |= (1 << 30);
+ }
}
static void sd_set_rca(SDState *sd)
@@ -362,7 +384,7 @@ static void sd_response_r7_make(SDState *sd, uint8_t *response)
static void sd_reset(SDState *sd, BlockDriverState *bdrv)
{
- uint32_t size;
+ uint64_t size;
uint64_t sect;
if (bdrv) {
@@ -372,10 +394,7 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
}
sect <<= 9;
- if (sect > 0x40000000)
- size = 0x40000000; /* 1 gig */
- else
- size = sect + 1;
+ size = sect + 1;
sect = (size >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT)) + 1;
@@ -460,7 +479,7 @@ static void sd_erase(SDState *sd)
sd->card_status |= WP_ERASE_SKIP;
}
-static uint32_t sd_wpbits(SDState *sd, uint32_t addr)
+static uint32_t sd_wpbits(SDState *sd, uint64_t addr)
{
uint32_t i, wpnum;
uint32_t ret = 0;
@@ -583,7 +602,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
SDRequest req)
{
uint32_t rca = 0x0000;
+ uint64_t addr;
+ if (sd->ocr & (1 << 30)) {
+ addr = (uint64_t)req.arg << 9;
+ } else {
+ addr = req.arg;
+ }
+
if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc)
rca = req.arg >> 16;
@@ -735,7 +761,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
break;
sd->state = sd_sendingdata_state;
memcpy(sd->data, sd->csd, 16);
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
return sd_r1;
@@ -757,7 +783,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
break;
sd->state = sd_sendingdata_state;
memcpy(sd->data, sd->cid, 16);
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
return sd_r1;
@@ -850,7 +876,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_sendingdata_state;
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
if (sd->data_start + sd->blk_len > sd->size)
@@ -866,7 +892,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
switch (sd->state) {
case sd_transfer_state:
sd->state = sd_sendingdata_state;
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
if (sd->data_start + sd->blk_len > sd->size)
@@ -888,7 +914,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
if (sd->spi)
break;
sd->state = sd_receivingdata_state;
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
sd->blk_written = 0;
@@ -914,7 +940,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
if (sd->spi)
break;
sd->state = sd_receivingdata_state;
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
sd->blk_written = 0;
@@ -965,13 +991,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
case 28: /* CMD28: SET_WRITE_PROT */
switch (sd->state) {
case sd_transfer_state:
- if (req.arg >= sd->size) {
+ if (addr >= sd->size) {
sd->card_status = ADDRESS_ERROR;
return sd_r1b;
}
sd->state = sd_programming_state;
- sd->wp_groups[req.arg >> (HWBLOCK_SHIFT +
+ sd->wp_groups[addr >> (HWBLOCK_SHIFT +
SECTOR_SHIFT + WPGROUP_SHIFT)] = 1;
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
@@ -985,13 +1011,13 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
case 29: /* CMD29: CLR_WRITE_PROT */
switch (sd->state) {
case sd_transfer_state:
- if (req.arg >= sd->size) {
+ if (addr >= sd->size) {
sd->card_status = ADDRESS_ERROR;
return sd_r1b;
}
sd->state = sd_programming_state;
- sd->wp_groups[req.arg >> (HWBLOCK_SHIFT +
+ sd->wp_groups[addr >> (HWBLOCK_SHIFT +
SECTOR_SHIFT + WPGROUP_SHIFT)] = 0;
/* Bzzzzzzztt .... Operation complete. */
sd->state = sd_transfer_state;
@@ -1007,7 +1033,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
case sd_transfer_state:
sd->state = sd_sendingdata_state;
*(uint32_t *) sd->data = sd_wpbits(sd, req.arg);
- sd->data_start = req.arg;
+ sd->data_start = addr;
sd->data_offset = 0;
return sd_r1b;
@@ -1322,11 +1348,11 @@ int sd_do_command(SDState *sd, SDRequest *req,
return rsplen;
}
-/* No real need for 64 bit addresses here */
-static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
+static void sd_blk_read(SDState *sd, uint64_t addr, uint32_t len)
{
- uint32_t end = addr + len;
+ uint64_t end = addr + len;
+ DPRINTF("sd_blk_read: addr = 0x%08llx, len = %d\n", (unsigned long long)addr, len);
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
fprintf(stderr, "sd_blk_read: read error on host side\n");
return;
@@ -1344,9 +1370,9 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
memcpy(sd->data, sd->buf + (addr & 511), len);
}
-static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len)
+static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)
{
- uint32_t end = addr + len;
+ uint64_t end = addr + len;
if ((addr & 511) || len < 512)
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
@@ -1505,6 +1531,7 @@ uint8_t sd_read_data(SDState *sd)
{
/* TODO: Append CRCs */
uint8_t ret;
+ int io_len;
if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
return 0x00;
@@ -1517,6 +1544,12 @@ uint8_t sd_read_data(SDState *sd)
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
return 0x00;
+ if (sd->ocr & (1 << 30)) {
+ io_len = 512;
+ } else {
+ io_len = sd->blk_len;
+ }
+
switch (sd->current_cmd) {
case 6: /* CMD6: SWITCH_FUNCTION */
ret = sd->data[sd->data_offset ++];
@@ -1535,13 +1568,13 @@ uint8_t sd_read_data(SDState *sd)
case 11: /* CMD11: READ_DAT_UNTIL_STOP */
if (sd->data_offset == 0)
- BLK_READ_BLOCK(sd->data_start, sd->blk_len);
+ BLK_READ_BLOCK(sd->data_start, io_len);
ret = sd->data[sd->data_offset ++];
- if (sd->data_offset >= sd->blk_len) {
- sd->data_start += sd->blk_len;
+ if (sd->data_offset >= io_len) {
+ sd->data_start += io_len;
sd->data_offset = 0;
- if (sd->data_start + sd->blk_len > sd->size) {
+ if (sd->data_start + io_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
break;
}
@@ -1557,22 +1590,22 @@ uint8_t sd_read_data(SDState *sd)
case 17: /* CMD17: READ_SINGLE_BLOCK */
if (sd->data_offset == 0)
- BLK_READ_BLOCK(sd->data_start, sd->blk_len);
+ BLK_READ_BLOCK(sd->data_start, io_len);
ret = sd->data[sd->data_offset ++];
- if (sd->data_offset >= sd->blk_len)
+ if (sd->data_offset >= io_len)
sd->state = sd_transfer_state;
break;
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
if (sd->data_offset == 0)
- BLK_READ_BLOCK(sd->data_start, sd->blk_len);
+ BLK_READ_BLOCK(sd->data_start, io_len);
ret = sd->data[sd->data_offset ++];
- if (sd->data_offset >= sd->blk_len) {
- sd->data_start += sd->blk_len;
+ if (sd->data_offset >= io_len) {
+ sd->data_start += io_len;
sd->data_offset = 0;
- if (sd->data_start + sd->blk_len > sd->size) {
+ if (sd->data_start + io_len > sd->size) {
sd->card_status |= ADDRESS_ERROR;
break;
}
--
1.6.3.3
next reply other threads:[~2009-10-31 1:07 UTC|newest]
Thread overview: 129+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-31 1:07 Jason McMullan [this message]
-- strict thread matches above, loose matches on Subject: below --
2019-02-25 13:18 [Qemu-devel] (no subject) Yang Weijiang
2019-01-02 2:02 Yaowei Bai
2018-12-13 10:10 Илья Резников
2018-11-28 1:08 John Arbuckle
2018-11-28 19:39 ` Peter Maydell
2018-11-29 0:21 ` Programmingkid
2018-11-29 2:11 ` berkus infinitus
2018-11-29 10:18 ` Peter Maydell
2018-07-22 9:13 Liujinsong (Paul)
2018-06-20 7:32 [Qemu-devel] [PATCH v5 0/7] monitor: enable OOB by default Peter Xu
2018-06-26 17:21 ` [Qemu-devel] (no subject) Markus Armbruster
2017-10-12 23:54 Anatol Pomozov
2017-08-07 16:34 Eduardo Otubo
2017-08-07 13:31 vaibhav shukla
2017-05-17 22:42 John Bradley
2017-05-17 22:42 ` John Bradley
2017-05-18 5:29 ` no-reply
2017-05-18 5:31 ` no-reply
[not found] <CAMj-D2DO_CfvD77izsGfggoKP45HSC9aD6auUPAYC9Yeq_aX7w@mail.gmail.com>
2017-05-04 16:44 ` gengdongjiu
2017-05-04 16:44 ` gengdongjiu
2017-03-21 14:03 [Qemu-devel] [PATCH] qemu-ga: add guest-get-osinfo command Vinzenz Feenstra
2017-03-16 14:50 ` [Qemu-devel] (no subject) Vinzenz 'evilissimo' Feenstra
2017-03-23 13:44 ` Eric Blake
2017-02-24 13:19 Eric Bischoff
2017-02-17 15:42 Pranith Kumar
2017-01-02 12:03 morgenlette madeBy
2017-01-03 16:36 ` Stefan Hajnoczi
2016-11-16 19:41 Christopher Oliver
2016-11-17 9:15 ` Thomas Huth
2016-10-30 15:30 Pradeep Jagadeesh
2016-10-20 6:59 Nicholas Piggin
2016-10-12 21:49 Neeraj Sharma
2016-10-02 6:47 Shreya Shrivastava
2016-09-12 21:23 Stephen Bates
2016-09-13 2:28 ` Fam Zheng
2016-09-19 15:54 ` Stephen Bates
2016-07-31 15:07 Kumud Bhat
2016-03-21 8:44 Yunqiang Gao
2016-03-21 18:00 ` John Snow
2016-03-21 21:09 ` Peter Maydell
2016-03-22 21:45 ` John Snow
2016-01-15 10:06 Liang Li
2015-11-17 13:08 Christoph Hellwig
2015-11-17 17:29 ` Paolo Bonzini
2015-07-14 7:33 Pankaj Gupta
2015-07-02 16:18 Denis V. Lunev
2015-06-30 4:49 Scott Feldman
2015-06-30 7:18 ` Fam Zheng
2015-06-30 14:22 ` Scott Feldman
2015-05-03 14:10 yhindin
2015-05-03 14:10 yhindin
2015-05-03 14:10 yhindin
2015-05-03 14:07 yhindin
2015-05-03 14:07 yhindin
2015-02-22 1:00 Sunil Kumar
2014-12-06 10:54 Jun Li
2014-11-10 3:14 xubin yan
2014-09-17 16:20 Priyanka Ranjan
2014-06-12 14:45 Puneet Bakshi
2014-02-04 14:18 Валентин Сайков
2013-11-21 19:33 [Qemu-devel] [PATCH for-1.7 0/5] acpi unit-test: added tests Marcel Apfelbaum
2013-11-21 19:33 ` [Qemu-devel] [PATCH for-1.7 2/5] acpi unit-test: adjust the test data structure for better handling Marcel Apfelbaum
2013-12-10 16:42 ` [Qemu-devel] (no subject) Michael S. Tsirkin
2013-08-18 18:19 Liu, Jinsong
2013-05-06 13:47 [Qemu-devel] [PATCH] Add 'maxqdepth' as an option to tty character devices Paolo Bonzini
2013-05-07 16:36 ` [Qemu-devel] (no subject) John Baboval
2013-04-02 16:02 Elizabeth Brown
2013-04-05 7:18 ` Stefan Hajnoczi
2012-11-19 20:39 Stefan Priebe
2012-07-23 10:59 Paulo Arcinas
2012-07-20 3:39 Guan Xuetao
2012-04-01 16:19 César
2012-03-08 3:26 suyi wang
[not found] <[0/4] RESEND: Outstanding bugfixes and cleanups>
2012-03-08 0:41 ` David Gibson
2012-02-29 12:43 Dmitry Fleytman
2011-12-29 21:17 Fred Oliveira
2011-12-13 2:50 Erik Lotspeich
2011-12-13 8:06 ` Stefan Hajnoczi
2011-12-13 12:55 ` Erik Lotspeich
2011-12-13 14:57 ` Stefan Hajnoczi
2011-12-13 15:22 ` Erik Lotspeich
2011-12-13 15:56 ` Paolo Bonzini
2011-12-08 12:06 wong
2011-11-11 21:46 Ronnie Sahlberg
2011-10-24 21:03 Benoît Canet
2011-10-24 10:25 王永博
2011-09-29 16:55 Ottavio
2011-09-14 14:38 王永博
2011-08-03 14:50 Michael Tokarev
2011-06-12 2:47 Ronnie Sahlberg
2011-05-31 4:56 coolman coolx
2011-03-08 9:59 Stefan Hajnoczi
2011-02-17 10:45 maheen butt
2011-01-04 15:15 Aurelien Jarno
2011-01-04 16:06 ` Peter Maydell
2011-01-04 16:12 ` Aurelien Jarno
2010-12-13 8:05 Ronnie Sahlberg
2010-12-06 0:39 Joao Francisco Medeiros Neto
2010-12-05 19:29 Joao Francisco Medeiros Neto
2010-12-02 18:21 Joao Francisco Medeiros Neto
2010-11-28 14:28 Joao Francisco Medeiros Neto
2010-11-27 16:37 Joao Francisco Medeiros Neto
2010-11-12 9:43 Stefan Hajnoczi
2010-11-11 1:30 Michael Roth
2010-10-31 11:17 Zamzit
2010-10-22 14:56 Stefan Hajnoczi
2010-05-18 7:31 Corentin Chary
2010-02-10 18:15 Stephen Isard
2009-07-01 21:26 G 3
2009-03-17 20:37 Uri Lublin
2009-01-29 19:54 Uri Lublin
2009-01-30 2:43 ` Paul Brook
2009-02-01 15:20 ` Uri Lublin
2008-12-13 21:18 froydnj
2008-12-13 19:31 froydnj
2008-12-11 22:12 Hollis Blanchard
2008-12-11 22:43 ` Aurelien Jarno
2008-11-14 15:38 sniper
2008-08-21 14:27 Paweł Tulik
2007-04-10 13:34 Stuart Anderson
2007-03-03 23:09 Ben Taylor
2007-03-02 16:10 jeremy fenelon
2006-11-21 16:08 Torbjörn Andersson
2006-10-07 5:51 av1474
2006-10-10 20:50 ` Blue Swirl
2005-12-20 19:47 Hoppers U. Moppet
2005-11-08 15:57 Shahar Livne
2005-11-03 13:16 Qemtz
2005-04-27 14:08 blackcrack
2005-04-27 16:04 ` Johannes Schindelin
2005-04-27 16:38 ` Alex Beregszaszi
2005-01-18 4:44 Cliff
2004-08-08 1:42 anthony hill
2004-02-19 17:16 Adrian C
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091031010724.DAC4E3C662@mcmullan-linux \
--to=jmcmullan@netronome.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.