static int check_md_header(int md_id, void *parse_addr, struct ccci_image_info *image)
{
	int ret;
	bool md_type_check = false;
	bool md_plat_check = false;
	bool md_sys_match = false;
	bool md_size_check = false;
	unsigned int md_size;
	unsigned int header_size;
	int idx;
	unsigned char *start, *ptr;
	struct md_check_header *head = &md_img_header[md_id];
	get_md_resv_mem_info(md_id, NULL, &md_size, NULL, NULL);

	header_size = *(((unsigned int *)parse_addr) - 1);
	CCCI_UTIL_DBG_MSG_WITH_ID(md_id, "MD image header size = %d\n", header_size);
	if (header_size == sizeof(struct md_check_header_v3))
		return check_md_header_v3(md_id, parse_addr, image);

	/*memcpy(head, (void*)(parse_addr - sizeof(struct md_check_header)), sizeof(struct md_check_header)); */
	start = (unsigned char *)(head);
	ptr = (unsigned char *)(parse_addr - sizeof(struct md_check_header));
	for (idx = 0; idx < sizeof(struct md_check_header); idx++)
		*start++ = *ptr++;

	CCCI_UTIL_INF_MSG_WITH_ID(md_id, "**********************MD image check %d***************************\n",
				  (int)sizeof(struct md_check_header));
	ret = strncmp(head->check_header, MD_HEADER_MAGIC_NO, 12);
	if (ret) {
		CCCI_UTIL_ERR_MSG_WITH_ID(md_id, "md check header not exist!\n");
		ret = 0;
	} else {
		if (head->header_verno > 2) {
			CCCI_UTIL_ERR_MSG_WITH_ID(md_id, "[Error]md check header version mis-match to AP:[%d]!\n",
						  head->header_verno);
		} else {
#ifdef ENABLE_2G_3G_CHECK
			if ((head->image_type != 0) && (head->image_type == md->config.load_type))
				md_type_check = true;
#else
			md_type_check = true;
#endif

#ifdef ENABLE_CHIP_VER_CHECK
			if (!strncmp(head->platform, ccci_get_ap_platform(), AP_PLATFORM_LEN))
				md_plat_check = true;
#else
			md_plat_check = true;
#endif

			if (head->bind_sys_id == (md_id + 1))
				md_sys_match = true;
#ifdef ENABLE_MEM_SIZE_CHECK
			if (head->header_verno == 2) {
				/*md_size = md->mem_layout.md_region_size; */
				if (head->mem_size == md_size) {
					md_size_check = true;
				} else if (head->mem_size < md_size) {
					md_size_check = true;
					CCCI_UTIL_INF_MSG_WITH_ID(md_id,
								  "[Warning]md size in md header isn't sync to DFO setting: (%08x, %08x)\n",
								  head->mem_size, md_size);
				}
				image->img_info.mem_size = head->mem_size;
				image->ap_info.mem_size = md_size;
			} else {
				md_size_check = true;
			}
#else
			md_size_check = true;
#endif

			image->ap_info.image_type = type_str[head->image_type];
			image->ap_info.platform = ccci_get_ap_platform();
			image->img_info.image_type = type_str[head->image_type];
			image->img_info.platform = head->platform;
			image->img_info.build_time = head->build_time;
			image->img_info.build_ver = head->build_ver;
			image->img_info.product_ver = product_str[head->product_ver];
			image->img_info.version = head->product_ver;

			if (md_type_check && md_plat_check && md_sys_match && md_size_check) {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "Modem header check OK!\n");
			} else {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Error]Modem header check fail!\n");
				if (!md_type_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD type(2G/3G) mis-match to AP!\n");

				if (!md_plat_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD platform mis-match to AP!\n");

				if (!md_sys_match)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD image is not for MD SYS%d!\n",
								  md_id + 1);

				if (!md_size_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id,
								  "[Reason]MD mem size mis-match to AP setting!\n");

				ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
			}

			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[type]=%s, (AP)[type]=%s\n", image->img_info.image_type,
						  image->ap_info.image_type);
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[plat]=%s, (AP)[plat]=%s\n", image->img_info.platform,
						  image->ap_info.platform);
			if (head->header_verno >= 2) {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[size]=%x, (AP)[size]=%x\n",
							  image->img_info.mem_size, image->ap_info.mem_size);
				if (head->md_img_size) {
					if (image->size >= head->md_img_size)
						image->size = head->md_img_size;
					else {
						CCCI_UTIL_INF_MSG_WITH_ID(md_id,
									  "[Reason]MD image size mis-match to AP!\n");
						ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
					}
					image->ap_info.md_img_size = image->size;
					image->img_info.md_img_size = head->md_img_size;
				}
				/* else {image->size -= 0x1A0;}  workaround for md not check in check header */
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[img_size]=%x, (AP)[img_size]=%x\n",
							  head->md_img_size, image->size);
			}
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[build_ver]=%s, [build_time]=%s\n",
						  image->img_info.build_ver, image->img_info.build_time);
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[product_ver]=%s\n", image->img_info.product_ver);
		}
	}
	CCCI_UTIL_INF_MSG_WITH_ID(md_id, "**********************MD image check***************************\n");

	return ret;
}
Example #2
0
static int check_md_header_v3(int md_id, void *parse_addr, struct ccci_image_info *image)
{
	int ret;
	bool md_type_check = false;
	bool md_plat_check = false;
	bool md_sys_match  = false;
	bool md_size_check = false;
	unsigned int md_size;

	struct md_check_header_v3 *head = &md_img_header_v3[md_id];
	get_md_resv_mem_info(md_id, NULL, &md_size, NULL, NULL);

	memcpy(head, (void*)(parse_addr - sizeof(struct md_check_header_v3)), sizeof(struct md_check_header_v3));

	CCCI_UTIL_INF_MSG_WITH_ID(md_id, "**********************MD image check V3 %d***************************\n", sizeof(struct md_check_header_v3));
	ret = strncmp(head->check_header, MD_HEADER_MAGIC_NO, 12);
	if(ret) {
		CCCI_UTIL_ERR_MSG_WITH_ID(md_id, "md check header not exist!\n");
		ret = 0;
	}
	else {
		if(head->header_verno > MD_HEADER_VER_NO) {
			CCCI_UTIL_ERR_MSG_WITH_ID(md_id, "[Error]md check header version mis-match to AP:[%d]!\n", 
				head->header_verno);
		} else {
#ifdef ENABLE_2G_3G_CHECK
			if((head->image_type != 0) && (head->image_type == md->config.load_type)) {
				md_type_check = true;
			}
#else
			md_type_check = true;
#endif

#ifdef ENABLE_CHIP_VER_CHECK
			if(!strncmp(head->platform, ap_platform, AP_PLATFORM_LEN)) {
				md_plat_check = true;
			}
#else
			md_plat_check = true;
#endif

			if(head->bind_sys_id == (md_id+1)) {
				md_sys_match = true;
			}

#ifdef ENABLE_MEM_SIZE_CHECK
			if(head->header_verno >= 2) {
				//md_size = md->mem_layout.md_region_size;
				if (head->mem_size == md_size) {
					md_size_check = true;
				} else if(head->mem_size < md_size) {
					md_size_check = true;
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Warning]md size in md header isn't sync to DFO setting: (%08x, %08x)\n",
						head->mem_size, md_size);
				}
				image->img_info.mem_size = head->mem_size;
				image->ap_info.mem_size = md_size;
			} else {
				md_size_check = true;
			}
#else
			md_size_check = true;
#endif

			image->ap_info.image_type = type_str[head->image_type];
			image->ap_info.platform = ap_platform;
			image->img_info.image_type = type_str[head->image_type];
			image->img_info.platform = head->platform;
			image->img_info.build_time = head->build_time;
			image->img_info.build_ver = head->build_ver;
			image->img_info.product_ver = product_str[head->product_ver];
			image->img_info.version = head->product_ver;

			if(md_type_check && md_plat_check && md_sys_match && md_size_check) {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "Modem header check OK!\n");
			} else {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Error]Modem header check fail!\n");
				if(!md_type_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD type(2G/3G) mis-match to AP!\n");

				if(!md_plat_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD platform mis-match to AP!\n");

				if(!md_sys_match)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD image is not for MD SYS%d!\n", md_id+1);

				if(!md_size_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD mem size mis-match to AP setting!\n");

				ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
			}

			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[type]=%s, (AP)[type]=%s\n", image->img_info.image_type, image->ap_info.image_type);
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[plat]=%s, (AP)[plat]=%s\n", image->img_info.platform, image->ap_info.platform);
			if(head->header_verno >= 2) {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[size]=%x, (AP)[size]=%x\n",image->img_info.mem_size, image->ap_info.mem_size);
				if (head->md_img_size) {
					if (image->size >= head->md_img_size)
						image->size = head->md_img_size;
					else {
						CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD image size mis-match to AP!\n");
						ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
					}
					image->ap_info.md_img_size = image->size;
					image->img_info.md_img_size = head->md_img_size;
				}
				// else {image->size -= 0x1A0;} //workaround for md not check in check header
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[img_size]=%x, (AP)[img_size]=%x\n", head->md_img_size, image->size);
			}
			if(head->header_verno >= 3) {
				image->dsp_offset = head->dsp_img_offset;
				image->dsp_size = head->dsp_img_size;
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP image offset=%x size=%x\n", image->dsp_offset, image->dsp_size);
				if(image->dsp_offset == 0xCDCDCDAA) {
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP on EMI disabled\n");
				} else if(image->dsp_offset&0xFFFF != 0) {
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP image offset not 64KB align\n");
					ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
				} else if(image->dsp_offset+image->dsp_size > md_size) {
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP image size too large %x\n", md_size);
					ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
				}
			} else {
				image->dsp_offset = 0;
			}
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[build_ver]=%s, [build_time]=%s\n",image->img_info.build_ver, image->img_info.build_time);
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[product_ver]=%s\n",image->img_info.product_ver);
		}
	}
	CCCI_UTIL_INF_MSG_WITH_ID(md_id, "**********************MD image check V3***************************\n");

	return ret;
}
static int check_md_header_v3(int md_id, void *parse_addr, struct ccci_image_info *image)
{
	int ret;
	bool md_type_check = false;
	bool md_plat_check = false;
	bool md_sys_match = false;
	bool md_size_check = false;
	int idx;
	unsigned int md_size;
	unsigned char *start, *ptr;

	struct md_check_header_v3 *head = &md_img_header_v3[md_id];
	get_md_resv_mem_info(md_id, NULL, &md_size, NULL, NULL);

	/*memcpy(head, (void*)(parse_addr - sizeof(struct md_check_header_v3)), sizeof(struct md_check_header_v3)); */
	start = (unsigned char *)(head);
	ptr = (unsigned char *)(parse_addr - sizeof(struct md_check_header_v3));
	for (idx = 0; idx < sizeof(struct md_check_header_v3); idx++)
		*start++ = *ptr++;

	CCCI_UTIL_INF_MSG_WITH_ID(md_id, "**********************MD image check V3 %d***************************\n",
				  (int)sizeof(struct md_check_header_v3));
	ret = strncmp(head->check_header, MD_HEADER_MAGIC_NO, 12);
	if (ret) {
		CCCI_UTIL_ERR_MSG_WITH_ID(md_id, "md check header not exist!\n");
		ret = 0;
	} else {
		if (head->header_verno < 3) {
			CCCI_UTIL_ERR_MSG_WITH_ID(md_id, "[Error]md check header version mis-match to AP:[%d]!\n",
						  head->header_verno);
		} else {
#ifdef ENABLE_2G_3G_CHECK
			if ((head->image_type != 0) && (head->image_type == md->config.load_type))
				md_type_check = true;
#else
			md_type_check = true;
#endif

#ifdef ENABLE_CHIP_VER_CHECK
			if (!strncmp(head->platform, ccci_get_ap_platform(), AP_PLATFORM_LEN))
				md_plat_check = true;
#else
			md_plat_check = true;
#endif

			if (head->bind_sys_id == (md_id + 1))
				md_sys_match = true;
#ifdef ENABLE_MEM_SIZE_CHECK
			if (head->header_verno >= 2) {
				/*md_size = md->mem_layout.md_region_size; */
				if (head->mem_size == md_size) {
					md_size_check = true;
				} else if (head->mem_size < md_size) {
					md_size_check = true;
					CCCI_UTIL_INF_MSG_WITH_ID(md_id,
								  "[Warning]md size in md header isn't sync to DFO setting: (%08x, %08x)\n",
								  head->mem_size, md_size);
				}
				image->img_info.mem_size = head->mem_size;
				image->ap_info.mem_size = md_size;
			} else {
				md_size_check = true;
			}
#else
			md_size_check = true;
#endif

			image->ap_info.image_type = type_str[head->image_type];
			image->ap_info.platform = ccci_get_ap_platform();
			image->img_info.image_type = type_str[head->image_type];
			image->img_info.platform = head->platform;
			image->img_info.build_time = head->build_time;
			image->img_info.build_ver = head->build_ver;
			image->img_info.product_ver = product_str[head->product_ver];
			image->img_info.version = head->product_ver;

			if (md_type_check && md_plat_check && md_sys_match && md_size_check) {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "Modem header check OK!\n");
			} else {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Error]Modem header check fail!\n");
				if (!md_type_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD type(2G/3G) mis-match to AP!\n");

				if (!md_plat_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD platform mis-match to AP!\n");

				if (!md_sys_match)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "[Reason]MD image is not for MD SYS%d!\n",
								  md_id + 1);

				if (!md_size_check)
					CCCI_UTIL_INF_MSG_WITH_ID(md_id,
								  "[Reason]MD mem size mis-match to AP setting!\n");

				ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
			}

			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[type]=%s, (AP)[type]=%s\n", image->img_info.image_type,
						  image->ap_info.image_type);
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[plat]=%s, (AP)[plat]=%s\n", image->img_info.platform,
						  image->ap_info.platform);
			if (head->header_verno >= 2) {
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[size]=%x, (AP)[size]=%x\n",
							  image->img_info.mem_size, image->ap_info.mem_size);
				if (head->md_img_size) {
					if (image->size >= head->md_img_size)
						image->size = head->md_img_size;
					else {
						char title[50];
						char info[100];
						snprintf(title, sizeof(title),
							 "MD%d mem size smaller than image header setting", md_id + 1);
						snprintf(info, sizeof(info),
							 "MD%d mem cfg size(0x%x)<header size(0x%x),please check memory config in <chip>.dtsi",
							 md_id + 1, image->size, head->md_img_size);
#if defined(CONFIG_MTK_AEE_FEATURE)
						aed_md_exception_api(NULL, 0, (const int *)info, sizeof(info), (const char *)title,
								     DB_OPT_DEFAULT);
#endif
						CCCI_UTIL_INF_MSG_WITH_ID(md_id,
									  "[Reason]MD image size mis-match to AP!\n");
						ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
					}
					image->ap_info.md_img_size = image->size;
					image->img_info.md_img_size = head->md_img_size;
				}
				/* else {image->size -= 0x1A0;} workaround for md not check in check header */
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[img_size]=%x, (AP)[img_size]=%x\n",
							  head->md_img_size, image->size);
			}
			if (head->header_verno >= 3) {
				image->dsp_offset = head->dsp_img_offset;
				image->dsp_size = head->dsp_img_size;
				CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP image offset=%x size=%x\n", image->dsp_offset,
							  image->dsp_size);
				if (image->dsp_offset == 0xCDCDCDAA) {
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP on EMI disabled\n");
				} else if ((image->dsp_offset & 0xFFFF) != 0) {
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP image offset not 64KB align\n");
					ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
				} else if (image->dsp_offset + image->dsp_size > md_size) {
					CCCI_UTIL_INF_MSG_WITH_ID(md_id, "DSP image size too large %x\n", md_size);
					ret = -CCCI_ERR_LOAD_IMG_MD_CHECK;
				}
			} else {
				image->dsp_offset = 0;
			}
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[build_ver]=%s, [build_time]=%s\n",
						  image->img_info.build_ver, image->img_info.build_time);
			CCCI_UTIL_INF_MSG_WITH_ID(md_id, "(MD)[product_ver]=%s\n", image->img_info.product_ver);
		}
	}
	CCCI_UTIL_INF_MSG_WITH_ID(md_id, "**********************MD image check V3***************************\n");

	return ret;
}