mcu_hi3321_watch/middleware/utils/cpu_load/private/cpu_load.c
2025-05-26 20:15:20 +08:00

198 lines
7.3 KiB
C

/*
* Copyright (c) CompanyNameMagicTag 2021-2021. All rights reserved.
* Description: CPU load
* Author:
* Create: 2021-04-06
*/
#include "cpu_load.h"
#include <stdint.h>
#include "debug_print.h"
#include "chip_io.h"
#include "memory_config_common.h"
#ifdef BUILD_APPLICATION_STANDARD
#include "log_oam_logger.h"
#include "log_def.h"
#include "log_printf.h"
#endif
#define IMAGE_COPY_LEN 4
#define ADDR_TRANS 4
#define STACK_DEFAULT_VALUE 0xdeadbeef
#define BSS_DEFAULT_VALUE 0x0
#define RESEVED_VALUE 0xffffffff
#define MASTER_XIP_ADDR_MASK 0x1fffffff
#ifdef MASTER_LOAD_SLAVE
//lint -esym(752,*)
extern uint32_t g_system_stack_begin;
extern uint32_t g_system_stack_end;
extern uint32_t __ramtext_begin__;
extern uint32_t __ramtext_end__;
extern uint32_t __ramtext_load__;
extern uint32_t __data_begin__;
extern uint32_t __data_end__;
extern uint32_t __data_load__;
extern uint32_t __bss_begin__;
extern uint32_t __bss_end__;
extern uint32_t __rom_data_begin__;
extern uint32_t __rom_data_end__;
extern uint32_t __rom_data_load__;
extern uint32_t __rom_bss_begin__;
extern uint32_t __rom_bss_end__;
extern uint32_t __patch_data_begin__;
extern uint32_t __patch_data_end__;
extern uint32_t __patch_data_load__;
#ifdef AUTO_GEN_ROM
extern uint32_t __rom_ram_begin__;
extern uint32_t __rom_ram_end__;
extern uint32_t __rom_ram_load__;
#endif
#if CORE == BT
#define SECTION_NUMBER 9
extern uint32_t __btc_text_begin__;
extern uint32_t __btc_text_end__;
extern uint32_t __btc_text_load__;
static const section_head_t g_section_information __attribute__((section(".build_info"))) = {
SECTION_NUMBER,
0,
{{SECTION_TYPE_INIT, &g_system_stack_begin, &g_system_stack_end, NULL, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__rom_data_begin__, &__rom_data_end__, &__rom_data_load__, RESEVED_VALUE},
{SECTION_TYPE_CLEAR, &__rom_bss_begin__, &__rom_bss_end__, NULL, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__patch_data_begin__, &__patch_data_end__, &__patch_data_load__, RESEVED_VALUE},
#ifdef AUTO_GEN_ROM
{SECTION_TYPE_RELOAD, &__rom_ram_begin__, &__rom_ram_end__, &__rom_ram_load__, RESEVED_VALUE},
#endif
{SECTION_TYPE_RELOAD, NULL, (void *)(uintptr_t)BT_VECTORS_LENGTH,
(void *)(uintptr_t)BT_VECTORS_LOAD_ORIGIN, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__btc_text_begin__, &__btc_text_end__, &__btc_text_load__, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__ramtext_begin__, &__ramtext_end__, &__ramtext_load__, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__data_begin__, &__data_end__, &__data_load__, RESEVED_VALUE},
{SECTION_TYPE_CLEAR, &__bss_begin__, &__bss_end__, NULL, RESEVED_VALUE}}
};
#elif CORE == GNSS
#define SECTION_NUMBER 5
static const section_head_t g_section_information __attribute__((section(".build_info"))) = {
SECTION_NUMBER,
0,
{{SECTION_TYPE_INIT, &g_system_stack_begin, &g_system_stack_end, NULL, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, NULL, (void *)(uintptr_t)GNSS_VECTORS_LENGTH,
(void *)(uintptr_t)GNSS_VECTORS_LOAD_ORIGIN, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__ramtext_begin__, &__ramtext_end__, &__ramtext_load__, RESEVED_VALUE},
{SECTION_TYPE_RELOAD, &__data_begin__, &__data_end__, &__data_load__, RESEVED_VALUE},
{SECTION_TYPE_CLEAR, &__bss_begin__, &__bss_end__, NULL, RESEVED_VALUE}}
};
#else
static const section_head_t g_section_information __attribute__((section(".build_info"))) = {
0,
0,
{{0}}
};
#endif
//lint -esym(752,*)
#endif
void cpu_load_image_process(uint32_t type, uint32_t *src, uint32_t *des, uint32_t size)
{
if (((type == SECTION_TYPE_RELOAD) && (src == NULL)) || (des == NULL) || (size & 0x3) || (size == 0)) {
PRINT("img download size:0x%x is not 4 byte aligned, type:%d\r\n", size, type);
#ifdef BUILD_APPLICATION_STANDARD
oml_pf_log_print2(LOG_BCORE_PLT_LPM_DSP_POWER, LOG_NUM_LPM_DSP_POWER, LOG_LEVEL_INFO, \
"[LOW_POWER]img download size:0x%x is not 4 byte aligned, type:%d\r\n", size, type);
#endif
return;
}
switch (type) {
case SECTION_TYPE_INIT:
for (uint32_t offset = 0; offset < size; offset += IMAGE_COPY_LEN) {
writel((uintptr_t)des + offset, STACK_DEFAULT_VALUE);
}
break;
case SECTION_TYPE_CLEAR:
for (uint32_t offset = 0; offset < size; offset += IMAGE_COPY_LEN) {
writel((uintptr_t)des + offset, BSS_DEFAULT_VALUE);
}
break;
case SECTION_TYPE_RELOAD:
for (uint32_t offset = 0; offset < size; offset += IMAGE_COPY_LEN) {
writel((uintptr_t)des + offset, readl((uintptr_t)src + offset));
}
break;
default:
break;
}
}
const section_head_t *cpu_load_get_section_info(core_images_e image)
{
UNUSED(image);
#if defined(MASTER_LOAD_SLAVE)
return (section_head_t *)&g_section_information;
#else
return NULL;
#endif
}
static uint32_t cpu_load_caculate_offset(uint32_t section_run_begin, core_images_e image)
{
UNUSED(section_run_begin);
if (image == CORE_IMAGES_BT) {
return 0x29800000; //!< M3 REMAP_ADDR_OFFSET = 0xa6000000 / 4
}
if (image == CORE_IMAGES_EXTERN0) {
#if CHIP_LIBRA
return (section_run_begin >= GNSS_DTCM_ORIGIN) ? 0x22800000 : 0x2A000000;
#endif
}
return 0;
}
#if CHIP_BRANDY
uint32_t* cpu_load_translate_into_mcu_xip_addr(uint32_t *addr, core_images_e image)
{
// loadaddr must be non-zero for translate
if (image == CORE_IMAGES_BT && addr) {
return (uint32_t*)((uint32_t)addr - BCPU_XIP_FLASH_ADDR + MCU_XIP_FLASH_ADDR);
} else {
#ifdef BUILD_APPLICATION_STANDARD
oml_pf_log_print2(LOG_BCORE_PLT_LPM_DSP_POWER, LOG_NUM_LPM_DSP_POWER, LOG_LEVEL_INFO, \
"[%d]core flash address[0x%x] translate int mcu flash.\r\n", image, addr);
#endif
return NULL;
}
}
#endif
void cpu_load_image(const section_head_t *load_info, core_images_e image)
{
section_head_t *head = NULL;
uint32_t type;
uint32_t *run_addr_begin = NULL;
uint32_t *run_addr_end = NULL;
uint32_t *load_addr = NULL;
uint32_t section_size;
head = (section_head_t *)load_info;
if ((head == NULL) || (head->section_num == 0xFFFFFFFF)) {
PRINT("img head is null\n");
return;
}
for (uint32_t i = 0; i < head->section_num; i++) {
type = head->section_info[i].section_type;
run_addr_begin = (uint32_t *)((char *)head->section_info[i].section_run_begin);
run_addr_end = (uint32_t *)((char *)head->section_info[i].section_run_end);
#if CHIP_BRANDY
load_addr = cpu_load_translate_into_mcu_xip_addr((uint32_t*)head->section_info[i].section_load_addr, image);
#else
load_addr = (uint32_t *)((char *)((uint32_t)head->section_info[i].section_load_addr & MASTER_XIP_ADDR_MASK));
#endif
section_size = (uint32_t)((run_addr_end - run_addr_begin) * ADDR_TRANS);
run_addr_begin += cpu_load_caculate_offset((uint32_t)run_addr_begin, image);
#ifdef CPU_LOAD_DEBUG
PRINT("copy sections num = %x\r\n", i);
PRINT("type = %x\r\n", type);
PRINT("size = %x\r\n", section_size);
#endif
cpu_load_image_process(type, load_addr, run_addr_begin, section_size);
}
}