MCPcopy Create free account
hub / github.com/RT-Thread/rt-thread / rt_hw_mem_setup_early

Function rt_hw_mem_setup_early

libcpu/risc-v/common64/mmu.c:665–722  ·  view source on GitHub ↗

* @brief Early memory setup function for hardware initialization. * * This function performs early memory setup tasks, including: * - Calculating the physical-to-virtual (PV) offset. * - Setting up initial page tables for identity mapping and text region relocation. * - Applying new memory mappings by updating the SATP register. * * @note This function is typically called during the early s

Source from the content-addressed store, hash-verified

663 * Here the identity mapping is implemented by a 1-stage page table, whose page size is 1GB.
664 */
665void rt_hw_mem_setup_early(void)
666{
667 rt_ubase_t pv_off;
668 rt_ubase_t ps = 0x0;
669 rt_ubase_t vs = 0x0;
670 rt_ubase_t *early_pgtbl = (rt_ubase_t *)(((size_t)&__bss_end + 4095) & ~0xfff);
671
672 /* calculate pv_offset */
673 void *symb_pc;
674 void *symb_linker;
675 __asm__ volatile("la %0, _start\n" : "=r"(symb_pc));
676 __asm__ volatile("la %0, _start_link_addr\n" : "=r"(symb_linker));
677 symb_linker = *(void **)symb_linker;
678 pv_off = symb_pc - symb_linker;
679 rt_kmem_pvoff_set(pv_off);
680
681 if (pv_off)
682 {
683 if (pv_off & ((1ul << (ARCH_INDEX_WIDTH * 2 + ARCH_PAGE_SHIFT)) - 1))
684 {
685 LOG_E("%s: not aligned virtual address. pv_offset %p", __func__,
686 pv_off);
687 RT_ASSERT(0);
688 }
689
690 /**
691 * identical mapping,
692 * PC are still at lower region before relocating to high memory
693 */
694 rt_ubase_t pg_idx ;
695 /* Round down symb_pc to L1_PAGE_SIZE boundary to ensure proper page alignment.
696 * This is necessary because MMU operations work with page-aligned addresses, and
697 * make sure all the text region is mapped.*/
698 ps = (rt_ubase_t)symb_pc & (~(L1_PAGE_SIZE - 1));
699 pg_idx = GET_L1(ps);
700 early_pgtbl[pg_idx] = COMBINEPTE(ps, MMU_MAP_EARLY);
701
702 /* relocate text region */
703 __asm__ volatile("la %0, _start\n" : "=r"(ps));
704 ps &= ~(L1_PAGE_SIZE - 1);
705 vs = ps - pv_off;
706
707 /* relocate region */
708 rt_ubase_t vs_idx = GET_L1(vs);
709 rt_ubase_t ve_idx = GET_L1(vs + 0x80000000);
710 for (size_t i = vs_idx; i < ve_idx; i++)
711 {
712 early_pgtbl[i] = COMBINEPTE(ps, MMU_MAP_EARLY);
713 ps += L1_PAGE_SIZE;
714 }
715
716 /* apply new mapping */
717 asm volatile("sfence.vma x0, x0");
718 write_csr(satp, SATP_BASE | ((size_t)early_pgtbl >> PAGE_OFFSET_BIT));
719 asm volatile("sfence.vma x0, x0");
720 }
721 /* return to lower text section */
722}

Callers

nothing calls this directly

Calls 1

rt_kmem_pvoff_setFunction · 0.85

Tested by

no test coverage detected