Esempio n. 1
0
void arch_set_dtlb(void *vaddr, void *paddr) {
    // Extract the index (shift by 13 and mask)
    uint32_t index = OR1K_SPR_DMMU_DTLBW_MR_VPN_GET((uint32_t) vaddr) & 0x3f;

    // Extract VPN (properly shift and mask)
    uint32_t vpn = OR1K_SPR_DMMU_DTLBW_MR_VPN_GET((uint32_t) vaddr);

    // Set page match register
    //  - valid
    //  - level 2 (8kB)
    //  - VPN from vaddr
    uint32_t mr = OR1K_SPR_DMMU_DTLBW_MR_V_SET(0, 1);
    mr = OR1K_SPR_DMMU_DTLBW_MR_VPN_SET(mr, vpn);

    or1k_mtspr (OR1K_SPR_DMMU_DTLBW_MR_ADDR(0, index), mr);

    // Extract PPN (properly shift and mask)
    uint32_t ppn = OR1K_SPR_DMMU_DTLBW_TR_PPN_GET((uint32_t) paddr);

    // Set page translation register
    //  - allow all accesses
    uint32_t tr = OR1K_SPR_DMMU_DTLBW_TR_URE_SET(0, 1);
    tr = OR1K_SPR_DMMU_DTLBW_TR_UWE_SET(tr, 1);
    tr = OR1K_SPR_DMMU_DTLBW_TR_SRE_SET(tr, 1);
    tr = OR1K_SPR_DMMU_DTLBW_TR_SWE_SET(tr, 1);
    tr = OR1K_SPR_DMMU_DTLBW_TR_PPN_SET(tr, ppn);

    or1k_mtspr (OR1K_SPR_DMMU_DTLBW_TR_ADDR(0, index), tr);
}
Esempio n. 2
0
File: vmm.c Progetto: imphil/sources
void _optimsoc_set_dtlb(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_DMMU_DTLBW_TR_PPN_SET(0, ppn);

    // Set read rights
    if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_USER_BIT)) {
        // Allow user access
        tr = OR1K_SPR_DMMU_DTLBW_TR_URE_SET(tr, 1);
    }
    tr = OR1K_SPR_DMMU_DTLBW_TR_SRE_SET(tr, 1);

    // Set write rights
    if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_WRITE_BIT)) {
        tr = OR1K_SPR_DMMU_DTLBW_TR_SWE_SET(tr, 1);
        if (OR1K_PTE_PPI_GET(pte) & (1 << OR1K_PTE_PPI_USER_BIT)) {
            // Allow user access
            tr = OR1K_SPR_DMMU_DTLBW_TR_UWE_SET(tr, 1);
        }
    }

    // Write translate register
    or1k_mtspr (OR1K_SPR_DMMU_DTLBW_TR_ADDR(0, index), tr);

    // Set page match register
    //  - valid
    //  - level 2 (8kB)
    //  - VPN from vaddr
    uint32_t mr = OR1K_SPR_DMMU_DTLBW_MR_V_SET(0, 1);
    mr = OR1K_SPR_DMMU_DTLBW_MR_VPN_SET(mr, OR1K_ADDR_PN_GET(vaddr));

    // Write match register
    or1k_mtspr (OR1K_SPR_DMMU_DTLBW_MR_ADDR(0, index), mr);
}