if the D-cache is enabled, make sure the buffer used by DMA is aligned to 32 bytes

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1945 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
dzzxzz@gmail.com 2012-02-13 11:12:57 +00:00
parent 3fca6b062a
commit 70463829c5
3 changed files with 57 additions and 32 deletions

View File

@ -21,11 +21,12 @@
static rt_list_t blk_devices; static rt_list_t blk_devices;
struct mmcsd_blk_device { struct mmcsd_blk_device
{
struct rt_mmcsd_card *card; struct rt_mmcsd_card *card;
rt_list_t list; rt_list_t list;
struct rt_device dev; struct rt_device dev;
struct dfs_partition part; struct dfs_partition part;
struct rt_device_blk_geometry geometry; struct rt_device_blk_geometry geometry;
}; };
@ -96,6 +97,8 @@ static rt_int32_t mmcsd_num_wr_blocks(struct rt_mmcsd_card *card)
static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector, void *buf, rt_size_t blks, rt_uint8_t dir) static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector, void *buf, rt_size_t blks, rt_uint8_t dir)
{ {
void *aligned_buf;
struct rt_mmcsd_cmd cmd, stop; struct rt_mmcsd_cmd cmd, stop;
struct rt_mmcsd_data data; struct rt_mmcsd_data data;
struct rt_mmcsd_req req; struct rt_mmcsd_req req;
@ -152,7 +155,23 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
mmcsd_set_data_timeout(&data, card); mmcsd_set_data_timeout(&data, card);
data.buf = buf; if (((rt_uint32_t)buf & (32 - 1)) != 0) /* the buf address is not aligned to 32 */
{
aligned_buf = rt_malloc_align(data.blks * data.blksize, 32);
if (aligned_buf == RT_NULL)
{
rt_kprintf("allocate memory failed\n");
return -RT_ENOMEM;
}
if (dir)//write
rt_memcpy(aligned_buf, buf, data.blks*data.blksize);
data.buf = aligned_buf;
}
else
data.buf = buf;
mmcsd_send_request(host, &req); mmcsd_send_request(host, &req);
@ -178,7 +197,6 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
*/ */
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) || } while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
(R1_CURRENT_STATE(cmd.resp[0]) == 7)); (R1_CURRENT_STATE(cmd.resp[0]) == 7));
} }
mmcsd_host_unlock(host); mmcsd_host_unlock(host);
@ -187,9 +205,20 @@ static rt_err_t rt_mmcsd_req_blk(struct rt_mmcsd_card *card, rt_uint32_t sector,
{ {
rt_kprintf("mmcsd request blocks error\n"); rt_kprintf("mmcsd request blocks error\n");
rt_kprintf("%d,%d,%d, 0x%08x,0x%08x\n", cmd.err, data.err, stop.err, data.flags, sector); rt_kprintf("%d,%d,%d, 0x%08x,0x%08x\n", cmd.err, data.err, stop.err, data.flags, sector);
if (((rt_uint32_t)buf & (32 - 1)) != 0)
rt_free_align(aligned_buf);
return -RT_ERROR; return -RT_ERROR;
} }
if (((rt_uint32_t)buf & (32 - 1)) != 0)
{
if (!dir)//read
rt_memcpy(buf, data.buf, data.blks*data.blksize);
rt_free_align(aligned_buf);
}
return RT_EOK; return RT_EOK;
} }
@ -213,15 +242,16 @@ static rt_err_t rt_mmcsd_control(rt_device_t dev, rt_uint8_t cmd, void *args)
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data; struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
switch (cmd) switch (cmd)
{ {
case RT_DEVICE_CTRL_BLK_GETGEOME: case RT_DEVICE_CTRL_BLK_GETGEOME:
rt_memcpy(args, &blk_dev->geometry, sizeof(struct rt_device_blk_geometry)); rt_memcpy(args, &blk_dev->geometry, sizeof(struct rt_device_blk_geometry));
break; break;
default: break; default:
break;
} }
return RT_EOK; return RT_EOK;
} }
static rt_size_t rt_mmcsd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) static rt_size_t rt_mmcsd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{ {
rt_err_t err; rt_err_t err;
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data; struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
@ -246,13 +276,13 @@ static rt_size_t rt_mmcsd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_s
return size; return size;
} }
static rt_size_t rt_mmcsd_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) static rt_size_t rt_mmcsd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{ {
rt_err_t err; rt_err_t err;
struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data; struct mmcsd_blk_device *blk_dev = (struct mmcsd_blk_device *)dev->user_data;
struct dfs_partition *part = &blk_dev->part; struct dfs_partition *part = &blk_dev->part;
if ( dev == RT_NULL ) if (dev == RT_NULL)
{ {
rt_set_errno(-DFS_STATUS_EINVAL); rt_set_errno(-DFS_STATUS_EINVAL);
return 0; return 0;
@ -289,8 +319,7 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
if (err) if (err)
{ {
rt_kprintf("MMCSD: unable to set block size to %d: %d\n", rt_kprintf("MMCSD: unable to set block size to %d: %d\n", cmd.arg, err);
cmd.arg, err);
return -RT_ERROR; return -RT_ERROR;
} }
@ -299,7 +328,7 @@ static rt_int32_t mmcsd_set_blksize(struct rt_mmcsd_card *card)
rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card) rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
{ {
rt_int32_t err = 0; rt_int32_t err = 0;
rt_uint8_t i, status; rt_uint8_t i, status;
rt_uint8_t *sector; rt_uint8_t *sector;
char dname[4]; char dname[4];
@ -313,7 +342,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
} }
/* get the first sector to read partition table */ /* get the first sector to read partition table */
sector = (rt_uint8_t*) rt_malloc (SECTOR_SIZE); sector = (rt_uint8_t *)rt_malloc_align(SECTOR_SIZE, 32);
if (sector == RT_NULL) if (sector == RT_NULL)
{ {
rt_kprintf("allocate partition sector buffer failed\n"); rt_kprintf("allocate partition sector buffer failed\n");
@ -341,7 +370,7 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO); blk_dev->part.lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
/* register mmcsd device */ /* register mmcsd device */
blk_dev->dev.type = RT_Device_Class_Block; blk_dev->dev.type = RT_Device_Class_Block;
blk_dev->dev.init = rt_mmcsd_init; blk_dev->dev.init = rt_mmcsd_init;
blk_dev->dev.open = rt_mmcsd_open; blk_dev->dev.open = rt_mmcsd_open;
blk_dev->dev.close = rt_mmcsd_close; blk_dev->dev.close = rt_mmcsd_close;
@ -415,11 +444,9 @@ rt_int32_t rt_mmcsd_blk_probe(struct rt_mmcsd_card *card)
} }
/* release sector buffer */ /* release sector buffer */
rt_free(sector); rt_free_align(sector);
return err; return err;
} }
void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card) void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
@ -439,8 +466,6 @@ void rt_mmcsd_blk_remove(struct rt_mmcsd_card *card)
} }
} }
void rt_mmcsd_blk_init(void) void rt_mmcsd_blk_init(void)
{ {
list_init(&blk_devices); list_init(&blk_devices);

View File

@ -175,7 +175,7 @@ rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid)
return 0; return 0;
} }
buf = rt_malloc(16); buf = rt_malloc_align(16, 32);
if (!buf) if (!buf)
{ {
rt_kprintf("malloc mem failed\n"); rt_kprintf("malloc mem failed\n");
@ -214,13 +214,13 @@ rt_int32_t mmcsd_get_cid(struct rt_mmcsd_host *host, rt_uint32_t *cid)
if (cmd.err || data.err) if (cmd.err || data.err)
{ {
rt_free(buf); rt_free_align(buf);
return -RT_ERROR; return -RT_ERROR;
} }
for (i = 0;i < 4;i++) for (i = 0;i < 4;i++)
cid[i] = buf[i]; cid[i] = buf[i];
rt_free(buf); rt_free_align(buf);
return 0; return 0;
} }
@ -248,7 +248,7 @@ rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd)
return 0; return 0;
} }
buf = rt_malloc(16); buf = rt_malloc_align(16, 32);
if (!buf) if (!buf)
{ {
rt_kprintf("malloc mem failed\n"); rt_kprintf("malloc mem failed\n");
@ -288,13 +288,13 @@ rt_int32_t mmcsd_get_csd(struct rt_mmcsd_card *card, rt_uint32_t *csd)
if (cmd.err || data.err) if (cmd.err || data.err)
{ {
rt_free(buf); rt_free_align(buf);
return -RT_ERROR; return -RT_ERROR;
} }
for (i = 0;i < 4;i++) for (i = 0;i < 4;i++)
csd[i] = buf[i]; csd[i] = buf[i];
rt_free(buf); rt_free_align(buf);
return 0; return 0;
} }

View File

@ -179,7 +179,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card)
struct rt_mmcsd_data data; struct rt_mmcsd_data data;
rt_uint8_t *buf; rt_uint8_t *buf;
buf = rt_malloc(64); buf = rt_malloc_align(64, 32);
if (!buf) if (!buf)
{ {
rt_kprintf("alloc memory failed\n"); rt_kprintf("alloc memory failed\n");
@ -258,7 +258,7 @@ static rt_int32_t mmcsd_switch(struct rt_mmcsd_card *card)
card->flags |= CARD_MODE_HIGHSPEED; card->flags |= CARD_MODE_HIGHSPEED;
err: err:
rt_free(buf); rt_free_align(buf);
return 0; return 0;
err1: err1:
@ -272,7 +272,7 @@ err1:
err = data.err; err = data.err;
} }
return err; return err;
} }