Skip to content

Commit c2b9089

Browse files
committed
[NUC472] Fix buffer overflow in BSP SD driver
1 parent c629eba commit c2b9089

File tree

2 files changed

+86
-39
lines changed

2 files changed

+86
-39
lines changed

targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_sd.c

Lines changed: 83 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**************************************************************************//**
22
* @file SD.c
33
* @version V1.00
4-
* $Revision: 13 $
5-
* $Date: 14/10/08 9:02a $
4+
* $Revision: 16 $
5+
* $Date: 15/11/26 10:45a $
66
* @brief NUC472/NUC442 SD driver source file
77
*
88
* @note
@@ -41,12 +41,12 @@ uint8_t *_sd_pSDHCBuffer;
4141
uint32_t _sd_ReferenceClock;
4242

4343
#if defined (__CC_ARM)
44-
__align(4096) uint8_t _sd_ucSDHCBuffer[64];
44+
__align(4096) uint8_t _sd_ucSDHCBuffer[512];
4545
#elif defined ( __ICCARM__ ) /*!< IAR Compiler */
4646
#pragma data_alignment = 4096
47-
uint8_t _sd_ucSDHCBuffer[64];
47+
uint8_t _sd_ucSDHCBuffer[512];
4848
#elif defined ( __GNUC__ )
49-
uint8_t _sd_ucSDHCBuffer[64] __attribute__((aligned (4096)));
49+
uint8_t _sd_ucSDHCBuffer[512] __attribute__((aligned (4096)));
5050
#endif
5151

5252
int sd0_ok = 0;
@@ -371,14 +371,20 @@ int SD_Init(SD_INFO_T *pSD)
371371
for (i=0x100; i>0; i--);
372372

373373
_sd_uR3_CMD = 1;
374-
if (SD_SDCmdAndRsp(pSD, 1, 0x80ff8000, u32CmdTimeOut) != 2) { // MMC memory
374+
375+
if (SD_SDCmdAndRsp(pSD, 1, 0x40ff8000, u32CmdTimeOut) != 2) { // eMMC memory
375376
resp = SD->RESP0;
376377
while (!(resp & 0x00800000)) { // check if card is ready
377378
_sd_uR3_CMD = 1;
378-
SD_SDCmdAndRsp(pSD, 1, 0x80ff8000, u32CmdTimeOut); // high voltage
379+
380+
SD_SDCmdAndRsp(pSD, 1, 0x40ff8000, u32CmdTimeOut); // high voltage
379381
resp = SD->RESP0;
380382
}
381-
pSD->CardType = SD_TYPE_MMC;
383+
384+
if(resp & 0x00400000)
385+
pSD->CardType = SD_TYPE_EMMC;
386+
else
387+
pSD->CardType = SD_TYPE_MMC;
382388
} else {
383389
pSD->CardType = SD_TYPE_UNKNOWN;
384390
return SD_ERR_DEVICE;
@@ -403,7 +409,7 @@ int SD_Init(SD_INFO_T *pSD)
403409
// CMD2, CMD3
404410
if (pSD->CardType != SD_TYPE_UNKNOWN) {
405411
SD_SDCmdAndRsp2(pSD, 2, 0x00, CIDBuffer);
406-
if (pSD->CardType == SD_TYPE_MMC) {
412+
if ((pSD->CardType == SD_TYPE_MMC) || (pSD->CardType == SD_TYPE_EMMC)) {
407413
if ((status = SD_SDCmdAndRsp(pSD, 3, 0x10000, 0)) != Successful) // set RCA
408414
return status;
409415
pSD->RCA = 0x10000;
@@ -460,6 +466,7 @@ int SD_SwitchToHighSpeed(SD_INFO_T *pSD)
460466
int SD_SelectCardType(SD_INFO_T *pSD)
461467
{
462468
int volatile status=0;
469+
unsigned int arg;
463470

464471
if ((status = SD_SDCmdAndRsp(pSD, 7, pSD->RCA, 0)) != Successful)
465472
return status;
@@ -509,59 +516,94 @@ int SD_SelectCardType(SD_INFO_T *pSD)
509516
return status;
510517

511518
SD->CTL |= SDH_CTL_DBW_Msk;
512-
} else if (pSD->CardType == SD_TYPE_MMC) {
513-
SD->CTL &= ~SDH_CTL_DBW_Msk;
519+
} else if ((pSD->CardType == SD_TYPE_MMC) ||(pSD->CardType == SD_TYPE_EMMC)) {
520+
521+
if(pSD->CardType == SD_TYPE_MMC)
522+
SD->CTL &= ~SDH_CTL_DBW_Msk;
523+
524+
//--- sent CMD6 to MMC card to set bus width to 4 bits mode
525+
// set CMD6 argument Access field to 3, Index to 183, Value to 1 (4-bit mode)
526+
arg = (3 << 24) | (183 << 16) | (1 << 8);
527+
if ((status = SD_SDCmdAndRsp(pSD, 6, arg, 0)) != Successful)
528+
return status;
529+
SD_CheckRB();
530+
531+
SD->CTL |= SDH_CTL_DBW_Msk;; // set bus width to 4-bit mode for SD host controller
532+
514533
}
515534

516535
if ((status = SD_SDCmdAndRsp(pSD, 16, SD_BLOCK_SIZE, 0)) != Successful) // set block length
517536
return status;
518537
SD->BLEN = SD_BLOCK_SIZE - 1; // set the block size
519538

520539
SD_SDCommand(pSD, 7, 0);
540+
SD->CTL |= SDH_CTL_CLK8OEN_Msk;
541+
while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
521542

522543
#ifdef _SD_USE_INT_
523-
SD->INTEN |= SDH_INTEN_BLKD_IE_Msk;
544+
SD->INTEN |= SDH_INTEN_BLKDIEN_Msk;
524545
#endif //_SD_USE_INT_
525546

526547
return Successful;
527548
}
528549

529550
void SD_Get_SD_info(SD_INFO_T *pSD, DISK_DATA_T *_info)
530551
{
531-
unsigned int i;
532552
unsigned int R_LEN, C_Size, MULT, size;
533553
unsigned int Buffer[4];
534554
unsigned char *ptr;
535555

536556
SD_SDCmdAndRsp2(pSD, 9, pSD->RCA, Buffer);
537557

538-
if ((Buffer[0] & 0xc0000000) && (pSD->CardType != SD_TYPE_MMC)) {
539-
C_Size = ((Buffer[1] & 0x0000003f) << 16) | ((Buffer[2] & 0xffff0000) >> 16);
540-
size = (C_Size+1) * 512; // Kbytes
558+
if ((pSD->CardType == SD_TYPE_MMC) || (pSD->CardType == SD_TYPE_EMMC)) {
559+
// for MMC/eMMC card
560+
if ((Buffer[0] & 0xc0000000) == 0xc0000000) {
561+
// CSD_STRUCTURE [127:126] is 3
562+
// CSD version depend on EXT_CSD register in eMMC v4.4 for card size > 2GB
563+
SD_SDCmdAndRsp(pSD, 7, pSD->RCA, 0);
564+
565+
ptr = (uint8_t *)((uint32_t)_sd_ucSDHCBuffer );
566+
SD->DMASA = (uint32_t)ptr; // set DMA transfer starting address
567+
SD->BLEN = 511; // read 512 bytes for EXT_CSD
568+
569+
if (SD_SDCmdAndRspDataIn(pSD, 8, 0x00) != Successful)
570+
return;
541571

542-
_info->diskSize = size;
543-
_info->totalSectorN = size << 1;
572+
SD_SDCommand(pSD, 7, 0);
573+
SD->CTL |= SDH_CTL_CLK8OEN_Msk;
574+
while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
575+
576+
_info->totalSectorN = (*(uint32_t *)(ptr+212));
577+
_info->diskSize = _info->totalSectorN / 2;
578+
} else {
579+
// CSD version v1.0/1.1/1.2 in eMMC v4.4 spec for card size <= 2GB
580+
R_LEN = (Buffer[1] & 0x000f0000) >> 16;
581+
C_Size = ((Buffer[1] & 0x000003ff) << 2) | ((Buffer[2] & 0xc0000000) >> 30);
582+
MULT = (Buffer[2] & 0x00038000) >> 15;
583+
size = (C_Size+1) * (1<<(MULT+2)) * (1<<R_LEN);
584+
585+
_info->diskSize = size / 1024;
586+
_info->totalSectorN = size / 512;
587+
}
544588
} else {
545-
R_LEN = (Buffer[1] & 0x000f0000) >> 16;
546-
C_Size = ((Buffer[1] & 0x000003ff) << 2) | ((Buffer[2] & 0xc0000000) >> 30);
547-
MULT = (Buffer[2] & 0x00038000) >> 15;
548-
size = (C_Size+1) * (1<<(MULT+2)) * (1<<R_LEN);
589+
if (Buffer[0] & 0xc0000000) {
590+
C_Size = ((Buffer[1] & 0x0000003f) << 16) | ((Buffer[2] & 0xffff0000) >> 16);
591+
size = (C_Size+1) * 512; // Kbytes
549592

550-
_info->diskSize = size / 1024;
551-
_info->totalSectorN = size / 512;
552-
}
553-
_info->sectorSize = 512;
593+
_info->diskSize = size;
594+
_info->totalSectorN = size << 1;
595+
} else {
596+
R_LEN = (Buffer[1] & 0x000f0000) >> 16;
597+
C_Size = ((Buffer[1] & 0x000003ff) << 2) | ((Buffer[2] & 0xc0000000) >> 30);
598+
MULT = (Buffer[2] & 0x00038000) >> 15;
599+
size = (C_Size+1) * (1<<(MULT+2)) * (1<<R_LEN);
554600

555-
SD_SDCmdAndRsp2(pSD, 10, pSD->RCA, Buffer);
601+
_info->diskSize = size / 1024;
602+
_info->totalSectorN = size / 512;
603+
}
604+
}
556605

557-
_info->vendor[0] = (Buffer[0] & 0xff000000) >> 24;
558-
ptr = (unsigned char *)Buffer;
559-
ptr = ptr + 4;
560-
for (i=0; i<5; i++)
561-
_info->product[i] = *ptr++;
562-
ptr = ptr + 10;
563-
for (i=0; i<4; i++)
564-
_info->serial[i] = *ptr++;
606+
_info->sectorSize = 512;
565607
}
566608

567609
int SD_ChipErase(SD_INFO_T *pSD, DISK_DATA_T *_info)
@@ -743,7 +785,7 @@ uint32_t SD_Read(uint32_t u32CardNum, uint8_t *pu8BufAddr, uint32_t u32StartSec,
743785

744786
SD->BLEN = blksize - 1; // the actual byte count is equal to (SDBLEN+1)
745787

746-
if (pSD->CardType == SD_TYPE_SD_HIGH)
788+
if ( (pSD->CardType == SD_TYPE_SD_HIGH) || (pSD->CardType == SD_TYPE_EMMC) )
747789
SD->CMDARG = u32StartSec;
748790
else
749791
SD->CMDARG = u32StartSec * blksize;
@@ -845,6 +887,8 @@ uint32_t SD_Read(uint32_t u32CardNum, uint8_t *pu8BufAddr, uint32_t u32StartSec,
845887
SD_CheckRB();
846888

847889
SD_SDCommand(pSD, 7, 0);
890+
SD->CTL |= SDH_CTL_CLK8OEN_Msk;
891+
while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
848892

849893
return Successful;
850894
}
@@ -891,7 +935,7 @@ uint32_t SD_Write(uint32_t u32CardNum, uint8_t *pu8BufAddr, uint32_t u32StartSec
891935
// According to SD Spec v2.0, the write CMD block size MUST be 512, and the start address MUST be 512*n.
892936
SD->BLEN = SD_BLOCK_SIZE - 1; // set the block size
893937

894-
if (pSD->CardType == SD_TYPE_SD_HIGH)
938+
if ((pSD->CardType == SD_TYPE_SD_HIGH) || (pSD->CardType == SD_TYPE_EMMC))
895939
SD->CMDARG = u32StartSec;
896940
else
897941
SD->CMDARG = u32StartSec * SD_BLOCK_SIZE; // set start address for SD CMD
@@ -975,6 +1019,8 @@ uint32_t SD_Write(uint32_t u32CardNum, uint8_t *pu8BufAddr, uint32_t u32StartSec
9751019
SD_CheckRB();
9761020

9771021
SD_SDCommand(pSD, 7, 0);
1022+
SD->CTL |= SDH_CTL_CLK8OEN_Msk;
1023+
while(SD->CTL & SDH_CTL_CLK8OEN_Msk);
9781024

9791025
return Successful;
9801026
}

targets/TARGET_NUVOTON/TARGET_NUC472/device/StdDriver/nuc472_sd.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**************************************************************************//**
22
* @file sd.h
33
* @version V1.00
4-
* $Revision: 11 $
5-
* $Date: 14/10/03 2:25p $
4+
* $Revision: 12 $
5+
* $Date: 14/11/04 10:10a $
66
* @brief NUC472/NUC442 SD driver header file
77
*
88
* @note
@@ -41,6 +41,7 @@
4141
#define SD_TYPE_SD_HIGH 1
4242
#define SD_TYPE_SD_LOW 2
4343
#define SD_TYPE_MMC 3
44+
#define SD_TYPE_EMMC 4
4445

4546
/* SD error */
4647
#define SD_NO_SD_CARD (SD_ERR_ID|0x10)

0 commit comments

Comments
 (0)