高通平台使用CDT(Configure Data Table)来存储平台信息和内存参数,CDT默认以数组方式存放在boot_images的源文件中,并最终编译到sbl1中;CDT也可以保存到emmc或eeprom中,在启动过程中加载;
下面是CDT常用的几个方法:
boot_config_data_table_init():初始化CDT;
boot_get_config_data_block():获取CDT block数据:;
boot_update_config_data_table():从emmc或eeprom加载CDT;
1. 初始化CDT
CDT的初始化操作就是为config_data_table_info变量赋值,这是一个cdt_info结构的变量;
首先从CDT数组中加载默认设置,如果emmc中有cdt的话,再更新config_data_table_info变量;
struct cdt_info {
uint32 size;
uint8 *cdt_ptr;
};
struct cdt_infoconfig_data_table_info;
boot_config_data_table_init()
-> config_data_table_info.size= config_data_table_size; //使用CDT数组初始化CDT Table,CDT数组
-> config_data_table_info.cdt_ptr= config_data_table; //数组保存在boot_cdt_array.c
-> boot_update_config_data_table(&config_data_table_info); //从emmc或eeprom加载cdt
2. 从CDT中取得平台信息
这里有两个地方要取得平台信息,分别是sbl1_hw_platform_pre_ddr()和sbl1_hw_platform_smem()方法,从cdt中取得指定的数据块,需要使用boot_get_config_data_block()方法,其中的index参数,指示要取得哪一个数据块,通常一个cdt中包含平台信息和内存参数两个数据块,block_index定义如下:
typedef enum
{
CONFIG_DATA_BLOCK_INDEX_V1_PLATFORM_ID = 0,
CONFIG_DATA_BLOCK_INDEX_V1_DDR = 1,
CONFIG_DATA_BLOCK_INDEX_TYPE_MAX_SIZE =0x7FFFFFFF
}config_data_block_index_type;
获取平台数据方法如下:
platform_id_cdb_ptr =boot_get_config_data_block(cdt_info_ptr->cdt_ptr,
CONFIG_DATA_BLOCK_INDEX_V1_PLATFORM_ID,
&platform_id_len);
CDT数据结构我们将会在下面介绍,这里只要知道通过Meta data的offset和size,我们可以找到平台数据存block放的位置和大小,platform_id_cdb_ptr指向block的起始地址;
上面提到的两个方法的区别在于取得platform id信息后的处理方法,一个是CDTConfigPreDDR,另一个是CDTConfigPostDDR,这里以DAL方式调用接口,实际是在调用platforminfor.c里面的PlatformInfo_CDTConfigPreDDR()和PlatformInfo_CDTConfigPostDDR(),这两个方法都会解析平台数据,差别在于PlatformInfo_CDTConfigPreDDR()方法解析出来的平台信息是在sbl1中用的,好像也会传给RPM用;而PlatformInfo_CDTConfigPostDDR()方法解析出来的数据会保存到smem中,可以给lk等使用;
平台数据的结构如下,一般CDT应该只有前5项:
typedef PACKED struct
{
uint8 nVersion;
uint8 nPlatform;
uint8 nHWVersionMajor;
uint8 nHWVersionMinor;
uint8 nSubtype;
uint8 nNumKVPS;
PlatformInfoKVPSCDTType aKVPS[];
} PlatformInfoCDTType;
3. 从CDT中取得DDR参数信息
在使用sbl1_ddr_set_params()方法设置DDR参数时,会先从CDT中取得使用的参数信息,如下:
sbl1_ddr_set_params()
-> ddr_cdt_params_ptr= boot_get_config_data_block(config_data_table_info->cdt_ptr,
CONFIG_DATA_BLOCK_INDEX_V1_DDR,
&ddr_cdt_params_size);
4. CDT数据结构
一个完整的CDT包括Header,Meta data和Block data三部分:
Header结构定义如下:
#defineCONFIG_DATA_MAGIC 0x00544443
__packed structcdt_header
{
uint32 magic; /*Magic Number */
uint16 version; /*Version number 8/
uint32 reserved1;
uint32 reserved2;
};
Meta data结构定义如下:
__packed struct cdb_meta
{
uint16 offset;
uint16 size;
};
5. CDT结构解析
/* Header */
0x43, 0x44, 0x54, 0x00, //Magic number
0x01, 0x00, 0x00, 0x00, //Version number
0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
/* Meta data */
0x16, 0x00, 0x05, 0x00, //meta info for platform id
0x1B, 0x00, 0x88, 0x01, //meta info for ddr parameter
/* Block data */
0x02, 0x08, 0x01, 0x00,
0x00, 0x01, 0x00, 0x00,
0x00, 0x00, 0x52, 0x44,
… …
Platform id信息解析:
0x02, 0x08, 0x01, 0x00,
Byte 0: platform_idVersion
Byte 1: platform_id ID:
0x01: Target is aSURF device
0x08: Target is aMTP device
0x0B: Target is aQRD device
Byte 2: platform_id Hardware version
6. 生成CDT image文件和boot_cdt_array.c
cdboot_images\core\boot\secboot3\scripts
modify <jedec_lpddr2_single_channel.xml>
python cdt_generator.pyjedec_lpddr2_single_channel.xml <cdt image>.bin