113 lines
3.2 KiB
C
113 lines
3.2 KiB
C
|
|
#include <common.h>
|
|
#include <sys_partition.h>
|
|
#include <sunxi_board.h>
|
|
#include <sys_config.h>
|
|
#include <asm/io.h>
|
|
#include <smc.h>
|
|
#include <asm/arch/platform.h>
|
|
|
|
int get_serial_num_from_file(char* serial)
|
|
{
|
|
int ret = 0;
|
|
int partno = -1;
|
|
char filename[32] = {0};
|
|
char part_info[16] = {0}; // format is "partno:0"
|
|
char addr_info[32] = {0}; //"00000000"
|
|
char file_info[64] = {0};
|
|
char * bmp_argv[6] = { "fatload", "sunxi_flash", part_info, addr_info, file_info, NULL };
|
|
|
|
//check serial_feature config info
|
|
ret = script_parser_fetch("serial_feature", "sn_filename", (int*)filename, sizeof(filename)/4);
|
|
if((ret != 0) || (strlen(filename)== 0) )
|
|
{
|
|
printf("sunxi_serial: sn_filename is not exist\n");
|
|
return -1;
|
|
}
|
|
//check private partition info
|
|
partno = sunxi_partition_get_partno_byname("private");
|
|
if(partno < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
//get data from file
|
|
sprintf(part_info,"%d:0", partno);
|
|
sprintf(addr_info,"%lx", (ulong)serial);
|
|
sprintf(file_info,"%s", filename);
|
|
if(do_fat_fsload(0, 0, 5, bmp_argv))
|
|
{
|
|
printf("load file(%s) error \n", bmp_argv[4]);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int get_serial_num_from_chipid(char* serial)
|
|
{
|
|
u32 sunxi_soc_chipid[4];
|
|
u32 sunxi_serial[3];
|
|
|
|
memset((void *)sunxi_serial, 0, sizeof(sunxi_serial));
|
|
|
|
#if defined (CONFIG_ARCH_SUN8IW1P1) || defined (CONFIG_ARCH_SUN8IW3P1)
|
|
memset((void *)sunxi_soc_chipid, 0, sizeof(sunxi_soc_chipid));
|
|
|
|
#elif defined (CONFIG_ARCH_SUN8IW5P1)
|
|
|
|
sunxi_soc_chipid[0] = readl(SUNXI_SID_VBASE);
|
|
sunxi_soc_chipid[1] = readl(SUNXI_SID_VBASE + 0x4);
|
|
sunxi_soc_chipid[2] = readl(SUNXI_SID_VBASE + 0x8);
|
|
sunxi_soc_chipid[3] = readl(SUNXI_SID_VBASE + 0xc);
|
|
|
|
sunxi_serial[0] = sunxi_soc_chipid[3] | 0xFFFFC000; /*bit14-bit31-->bit14-bit31*/
|
|
sunxi_serial[0] |= (sunxi_soc_chipid[2] >> 31) << 13; /*bit31 -->bit13 */
|
|
sunxi_serial[0] |= ((sunxi_soc_chipid[2] & 0x01FFF000) >> 12); /*bit12-bit24-->bit0-bit12*/
|
|
sunxi_serial[1] = sunxi_soc_chipid[1];
|
|
sunxi_serial[2] = (sunxi_soc_chipid[2] & 0xFFF); /*bit0-bit11-->bit0-bit11*/
|
|
sunxi_serial[2] |= (sunxi_soc_chipid[0] & 0x3) << 12; /*bit0-bit1-->bit12-bit13*/
|
|
|
|
#elif (defined CONFIG_ARCH_SUN8IW6P1) \
|
|
|| (defined CONFIG_ARCH_SUN8IW9P1) \
|
|
|| (defined CONFIG_ARCH_SUN8IW7) \
|
|
|| (defined CONFIG_ARCH_SUN9IW1P1)
|
|
|
|
sunxi_soc_chipid[0] = smc_readl(SID_BASE + 0x200);
|
|
sunxi_soc_chipid[1] = smc_readl(SID_BASE + 0x200 + 0x4);
|
|
sunxi_soc_chipid[2] = smc_readl(SID_BASE + 0x200 + 0x8);
|
|
sunxi_soc_chipid[3] = smc_readl(SID_BASE + 0x200 + 0xc);
|
|
|
|
sunxi_serial[0] = sunxi_soc_chipid[3];
|
|
sunxi_serial[1] = sunxi_soc_chipid[2];
|
|
sunxi_serial[2] = (sunxi_soc_chipid[1] >> 16) & 0xFFFF;
|
|
|
|
#endif
|
|
|
|
sprintf(serial , "%04x%08x%08x",sunxi_serial[2], sunxi_serial[1], sunxi_serial[0]);
|
|
return 0;
|
|
}
|
|
|
|
int sunxi_set_serial_num(void)
|
|
{
|
|
char serial[128] = {0};
|
|
if(uboot_spare_head.boot_data.work_mode != WORK_MODE_BOOT)
|
|
{
|
|
return 0;
|
|
}
|
|
if(get_serial_num_from_file(serial))
|
|
{
|
|
get_serial_num_from_chipid(serial);
|
|
}
|
|
printf("serial is: %s\n",serial);
|
|
if(setenv("sunxi_serial", serial))
|
|
{
|
|
printf("error:set variable [sunxi_serial] fail\n");
|
|
}
|
|
|
|
#if (defined CONFIG_ARCH_SUN8IW5P1) || (defined CONFIG_ARCH_SUN8IW6P1)
|
|
setenv("sunxi_hardware", "sun8i");
|
|
#elif defined CONFIG_ARCH_SUN9IW1P1
|
|
setenv("sunxi_hardware", "sun9i");
|
|
#endif
|
|
return 0;
|
|
} |