/* * Copyright (c) 2017 Actions Semiconductor Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ /** * @file * @brief link memory address overlay helper */ #include #include #include #include LOG_MODULE_REGISTER(overlay, LOG_LEVEL_DBG); struct overlay_info { u32_t idcode; u32_t code_vma; u32_t code_size; u32_t code_lma; u32_t data_vma; u32_t data_size; u32_t data_lma; u32_t bss_vma; u32_t bss_size; }; struct overlay_table { u32_t magic; u32_t count; const struct overlay_info items[7]; }; #ifndef __UVISION_VERSION /* overlay table is dynamic generated by linker */ extern const struct overlay_table __overlay_table; #else extern char __mp3_p_overlay_bss_start[]; extern char __mp3_p_overlay_bss_size[]; extern char __mp3_p_overlay_data_start[]; extern char __mp3_p_overlay_data_size[]; extern char __mp3_p_overlay_data_image_start[]; extern char __aac_p_overlay_bss_start[]; extern char __aac_p_overlay_bss_size[]; extern char __aac_p_overlay_data_start[]; extern char __aac_p_overlay_data_size[]; extern char __aac_p_overlay_data_image_start[]; extern char __ape_p_overlay_bss_start[]; extern int __ape_p_overlay_bss_size[]; extern char __ape_p_overlay_data_start[]; extern char __ape_p_overlay_data_size[]; extern char __ape_p_overlay_data_image_start[]; extern char __wav_p_overlay_bss_start[]; extern char __wav_p_overlay_bss_size[]; extern char __wav_p_overlay_data_start[]; extern char __wav_p_overlay_data_size[]; extern char __wav_p_overlay_data_image_start[]; extern char __wma_p_overlay_bss_start[]; extern char __wma_p_overlay_bss_size[]; extern char __wma_p_overlay_data_start[]; extern char __wma_p_overlay_data_size[]; extern char __wma_p_overlay_data_image_start[]; extern char __flac_p_overlay_bss_start[]; extern char __flac_p_overlay_bss_size[]; extern char __flac_p_overlay_data_start[]; extern char __flac_p_overlay_data_size[]; extern char __flac_p_overlay_data_image_start[]; const struct overlay_table __overlay_table = { .magic = OVERLAY_TABLE_MAGIC, .count = 7, { { .idcode = OVERLAY_ID_LIBAPMP3, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__mp3_p_overlay_data_start, .data_size = 0, .data_lma = (int)__mp3_p_overlay_data_image_start, .bss_vma = (int)__mp3_p_overlay_bss_start, .bss_size = (int)__mp3_p_overlay_bss_size, }, { .idcode = OVERLAY_ID_LIBAPFLA, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__flac_p_overlay_data_start, .data_size = (int)__flac_p_overlay_data_size, .data_lma = (int)__flac_p_overlay_data_image_start, .bss_vma = (int)__flac_p_overlay_bss_start, .bss_size = (int)__flac_p_overlay_bss_size, }, { .idcode = OVERLAY_ID_LIBAPAPE, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__ape_p_overlay_data_start, .data_size = (int)__ape_p_overlay_data_size, .data_lma = (int)__ape_p_overlay_data_image_start, .bss_vma = (int)__ape_p_overlay_bss_start, .bss_size = (int)__ape_p_overlay_bss_size, }, { .idcode = OVERLAY_ID_LIBAPWAV, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__wav_p_overlay_data_start, .data_size = (int)__wav_p_overlay_data_size, .data_lma = (int)__wav_p_overlay_data_image_start, .bss_vma = (int)__wav_p_overlay_bss_start, .bss_size = (int)__wav_p_overlay_bss_size, }, { .idcode = OVERLAY_ID_LIBAPMP3, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__mp3_p_overlay_data_start, .data_size =(int)__mp3_p_overlay_data_size, .data_lma = (int)__mp3_p_overlay_data_image_start, .bss_vma = (int)__mp3_p_overlay_bss_start, .bss_size = (int)__mp3_p_overlay_bss_size, }, { .idcode = OVERLAY_ID_LIBAPWMA, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__wma_p_overlay_data_start, .data_size = (int)__wma_p_overlay_data_size, .data_lma = (int)__wma_p_overlay_data_image_start, .bss_vma = (int)__wma_p_overlay_bss_start, .bss_size = (int)__wma_p_overlay_bss_size, }, { .idcode = OVERLAY_ID_LIBAPAAC, .code_vma = 0, .code_size = 0, .code_lma = 0, .data_vma = (int)__aac_p_overlay_data_start, .data_size = (int)__aac_p_overlay_data_size, .data_lma = (int)__aac_p_overlay_data_image_start, .bss_vma = (int)__aac_p_overlay_bss_start, .bss_size = (int)__aac_p_overlay_bss_size, }, }, }; #endif static int check_overlay_table(const struct overlay_table *tbl) { if (!tbl || tbl->magic != OVERLAY_TABLE_MAGIC || !tbl->count) return -1; return 0; } void overlay_dump(void) { const struct overlay_info *ovl; int i, cnt; if (check_overlay_table(&__overlay_table)) { printk("invalid overlay table\n"); return; } cnt = __overlay_table.count; printk("section overlay, total count %d\n", cnt); for (i = 0; i < cnt; i++) { ovl = &__overlay_table.items[i]; printk(" -- item %d --\n", i); printk(" idcode: %d\n", ovl->idcode); printk(" code_vma: 0x%08x\n", ovl->code_vma); printk(" code_size: 0x%08x\n", ovl->code_size); printk(" code_lma: 0x%08x\n", ovl->code_lma); printk(" data_vma: 0x%08x\n", ovl->data_vma); printk(" data_size: 0x%08x\n", ovl->data_size); printk(" data_lma: 0x%08x\n", ovl->data_lma); printk(" bss_vma: 0x%08x\n", ovl->bss_vma); printk(" bss_size: 0x%08x\n", ovl->bss_size); } } int overlay_section_init(u32_t idcode) { const struct overlay_info *ovl = NULL; int i, cnt; LOG_DBG("init overlay 0x%x", idcode); if (check_overlay_table(&__overlay_table)) { LOG_WRN("invalid overlay table\n"); return -1; } cnt = __overlay_table.count; for (i = 0; i < cnt; i++) { ovl = &__overlay_table.items[i]; if (idcode == ovl->idcode) break; } if (cnt == i) { LOG_WRN("cannot found overlay for idcode 0x%x\n", idcode); return -1; } if (ovl->code_size) { LOG_DBG("overlay id:0x%x: copy code from 0x%x to 0x%x, size 0x%x\n", idcode, ovl->code_lma, ovl->code_vma, ovl->code_size); memcpy((char *)ovl->code_vma, (char *)ovl->code_lma, ovl->code_size); } if (ovl->data_size) { LOG_DBG("overlay id:0x%x: copy data from 0x%x to 0x%x, size 0x%x\n", idcode, ovl->data_lma, ovl->data_vma, ovl->data_size); memcpy((char *)ovl->data_vma, (char *)ovl->data_lma, ovl->data_size); } if (ovl->bss_size) { LOG_DBG("overlay id:0x%x: init bss from 0x%x, size 0x%x\n", idcode, ovl->bss_vma, ovl->bss_size); memset((char *)ovl->bss_vma, 0x0, ovl->bss_size); } LOG_DBG("init overlay 0x%x ok", idcode); return 0; }