void _optimsoc_set_itlb(uint32_t vaddr, optimsoc_pte_t pte) { // Extract the index uint32_t index = OR1K_ADDR_L2_INDEX_GET(vaddr) & 0x3f; // Extract PPN from pte uint32_t ppn = OR1K_PTE_PPN_GET(pte); // Assemble translation register // Set PPN uint32_t tr = OR1K_SPR_IMMU_ITLBW_TR_PPN_SET(0, ppn); // Set access rights if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_EXEC_BIT)) { tr = OR1K_SPR_IMMU_ITLBW_TR_SXE_SET(tr, 1); // Allow user access if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_USER_BIT)) { tr = OR1K_SPR_IMMU_ITLBW_TR_UXE_SET(tr, 1); } } // Write translate register or1k_mtspr (OR1K_SPR_IMMU_ITLBW_TR_ADDR(0, index), tr); // Set page match register // - valid // - level 2 (8kB) // - VPN from vaddr uint32_t mr = OR1K_SPR_IMMU_ITLBW_MR_V_SET(0, 1); mr = OR1K_SPR_IMMU_ITLBW_MR_VPN_SET(mr, OR1K_ADDR_PN_GET(vaddr)); // Write match register or1k_mtspr (OR1K_SPR_IMMU_ITLBW_MR_ADDR(0, index), mr); }
void arch_set_itlb(void* vaddr, void* paddr) { // Extract the index (shift by 13 and mask) uint32_t index = OR1K_SPR_IMMU_ITLBW_MR_VPN_GET((uint32_t) vaddr) & 0x3f; // Extract VPN (properly shift and mask) uint32_t vpn = OR1K_SPR_IMMU_ITLBW_MR_VPN_GET((uint32_t) vaddr); // Set page match register // - valid // - level 2 (8kB) // - VPN from vaddr uint32_t mr = OR1K_SPR_IMMU_ITLBW_MR_V_SET(0, 1); mr = OR1K_SPR_IMMU_ITLBW_MR_VPN_SET(mr, vpn); or1k_mtspr (OR1K_SPR_IMMU_ITLBW_MR_ADDR(0, index), mr); // Extract PPN (properly shift and mask) uint32_t ppn = OR1K_SPR_IMMU_ITLBW_TR_PPN_GET((uint32_t) paddr); // Set page translation register // - allow all accesses uint32_t tr = OR1K_SPR_IMMU_ITLBW_TR_UXE_SET(0, 1); tr = OR1K_SPR_IMMU_ITLBW_TR_SXE_SET(tr, 1); tr = OR1K_SPR_IMMU_ITLBW_TR_PPN_SET(tr, ppn); or1k_mtspr (OR1K_SPR_IMMU_ITLBW_TR_ADDR(0, index), tr); }