/*
 * Copyright 2020-2025 Yuntu Microelectronics Co., Ltd.
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 * 
 * @file RamInit1.c
 * @brief 
 * 
 */

#include "stdint.h"








#define WORD_ALIGN_MASK (3U)
#define WORD_SHIFT      (2U)

typedef struct
{
    uint32_t *RamStart;   /*!< Start address of section in RAM */
    uint32_t *RomStart;   /*!< Start address of section in ROM */
    uint32_t *RomEnd;     /*!< End address of section in ROM */
} RamCopyLayoutType;


typedef struct
{
    uint32_t *RamStart;   /*!< Start address of section in RAM */
    uint32_t *RamEnd;     /*!< End address of section in RAM */
} RamZeroLayoutType;

extern uint32_t CODE_RAM_ram_start[];
extern uint32_t CODE_RAM_rom_start[];
extern uint32_t CODE_RAM_rom_end[];
extern uint32_t DATA_RAM_ram_start[];
extern uint32_t DATA_RAM_rom_start[];
extern uint32_t DATA_RAM_rom_end[];

extern uint32_t BSS_start[];
extern uint32_t BSS_end[];

const RamCopyLayoutType CopyLayout[2]={
    {
        .RamStart=CODE_RAM_ram_start,
        .RomStart=CODE_RAM_rom_start,
        .RomEnd=CODE_RAM_rom_end,
    },
    {
        .RamStart=DATA_RAM_ram_start,
        .RomStart=DATA_RAM_rom_start,
        .RomEnd=DATA_RAM_rom_end,
    },
};

const RamZeroLayoutType ZeroLayout[1]={
    {
        .RamStart=BSS_start,
        .RamEnd=BSS_end,
    },
};
/**
 * @brief RamInit1 for copying initialized data and zeroing uninitialized data
 */
void RamInit1(){
    const uint32_t *Rom32;
    const uint8_t *Rom8;
    uint32_t *Ram32;
    uint8_t *Ram8;
    volatile uint8_t DataPad;
    volatile uint32_t Len = 0U;
    uint32_t Size = 0U;
    uint32_t MajorLoopCnt = 0U;
    uint32_t MinorLoopCnt = 0U;

    /* Copy initialized table */
    Len = 2;
    for (MajorLoopCnt = 0U; MajorLoopCnt < Len; ++MajorLoopCnt)
    {
        Rom32 = (const uint32_t *)CopyLayout[MajorLoopCnt].RomStart;
        Ram32 = (uint32_t *)CopyLayout[MajorLoopCnt].RamStart;
        Size = (uint32_t)CopyLayout[MajorLoopCnt].RomEnd - (uint32_t)CopyLayout[MajorLoopCnt].RomStart;
        /* Make sure the data area to be copied must be aligned with 4. Then, copy 4 bytes at per one read */
        DataPad = Size & WORD_ALIGN_MASK;
        Size = (Size - DataPad) >> WORD_SHIFT;
        for (MinorLoopCnt = 0U; MinorLoopCnt < Size; ++MinorLoopCnt)
        {
            Ram32[MinorLoopCnt] = Rom32[MinorLoopCnt];
        }
        /* For the rest of data, copy 1 bytes at per one read */
        Rom8 = (uint8_t *) & (Rom32[MinorLoopCnt]);
        Ram8 = (uint8_t *) & (Ram32[MinorLoopCnt]);
        for (MinorLoopCnt = 0U; MinorLoopCnt < DataPad; ++MinorLoopCnt)
        {
            Ram8[MinorLoopCnt] = Rom8[MinorLoopCnt];
        }
    }

    /* Clear zero table */
    Len = 1;
    for (MajorLoopCnt = 0U; MajorLoopCnt < Len; ++MajorLoopCnt)
    {
        Ram32 = (uint32_t *)ZeroLayout[MajorLoopCnt].RamStart;
        Size = (uint32_t)ZeroLayout[MajorLoopCnt].RamEnd - (uint32_t)ZeroLayout[MajorLoopCnt].RamStart;
        /* Make sure the data area to be zeroed must be aligned with 4. Then, zero 4 bytes at per one read */
        DataPad = Size & WORD_ALIGN_MASK;
        Size = (Size - DataPad) >> WORD_SHIFT;        
        for (MinorLoopCnt = 0U; MinorLoopCnt < Size; ++MinorLoopCnt)
        {
            Ram32[MinorLoopCnt] = 0U;
        }
        /* For the rest of data, zero 1 bytes at per one read */
        Ram8 = (uint8_t *) & (Ram32[MinorLoopCnt]);
        for (MinorLoopCnt = 0U; MinorLoopCnt < DataPad; ++MinorLoopCnt)
        {
            Ram8[MinorLoopCnt] = 0U;
        }
    }
}


