📄 arm_map.c
字号:
/* * $QNXLicenseC: * Copyright 2007, QNX Software Systems. * * Licensed under the Apache License, Version 2.0 (the "License"). You * may not reproduce, modify or distribute this software except in * compliance with the License. You may obtain a copy of the License * at: http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OF ANY KIND, either express or implied. * * This file may contain contributions from others, either as * contributors under the License or as licensors under other terms. * Please review this entire file for other proprietary rights or license * notices, as well as the QNX Development Suite License Guide at * http://licensing.qnx.com/license-guide/ for other information. * $ */ #include "startup.h"/* * Map a 4K page table into both the L1 table and the "page directory" */voidarm_ptmap(paddr_t pt, uintptr_t vaddr){ int i; pte_t *pte = (pte_t *)L2_paddr + (vaddr >> 22); ptp_t *ptp = (ptp_t *)L1_paddr + ((vaddr >> 20) & ~3); /* * Map the page table into the "page directory" page table */ *pte = (pt | arm_pte_info->kpte_rw) & ~arm_pte_info->mask_nc; /* * Map the page table into the L1 table */ for (i = 0; i < 4; i++, pt += ARM_L2_SIZE) { *ptp++ = pt | ARM_PTP_L2; }}/* * Map a 1MB section into the L1 table. * This should be used with care, since the "page directory" knows * nothing about these mappings. Currently this is used only to map * the startup code itself to switch the MMU translation on. */voidarm_scmap(uintptr_t vaddr, paddr_t paddr, int flags){ ptp_t *ptp = (ptp_t *)L1_paddr + (vaddr >> 20); flags = (flags & ARM_PTE_CB) | ((flags & ARM_PTE_AP_MASK) << 10); *ptp = paddr | flags | ARM_PTP_SC;}/* * Map [paddr, paddr+size) with ARM specific attributes in flags. * If vaddr is ~0, we assign the address, otherwise, the mapping * will be made at the specified virtual address. */paddr_tarm_map(uintptr_t vaddr, paddr_t paddr, size_t size, int flags){ static uintptr_t next_addr = ARM_STARTUP_BASE; ptp_t *ptp; paddr_t off = paddr & PGMASK; if (!(shdr->flags1 & STARTUP_HDR_FLAGS1_VIRTUAL)) { return paddr; } paddr &= ~PGMASK; size = ROUNDPG(size + off); if (vaddr == ~(uintptr_t)0) { vaddr = next_addr; next_addr += size; } if (flags & ARM_PTE_U) { paddr |= (flags & ARM_PTE_RW) ? arm_pte_info->upte_rw : arm_pte_info->upte_ro; } else { paddr |= (flags & ARM_PTE_RW) ? arm_pte_info->kpte_rw : arm_pte_info->kpte_ro; } if ((flags & ARM_PTE_CB) == 0) { paddr &= ~arm_pte_info->mask_nc; } ptp = (ptp_t *)L1_paddr + ((vaddr >> 20) & ~3); while (size) { int i; pte_t *pte = (pte_t *)(*ptp & ~PGMASK); if ((*ptp & ARM_PTP_VALID) == 0) { /* * Need to allocate a page table */ pte = (pte_t *)calloc_ram(__PAGESIZE, __PAGESIZE); arm_ptmap((paddr_t)pte, vaddr); } pte += (vaddr >> 12) & 1023; for (i = (vaddr >> 12) & 1023; size && i < 1024; i++) { *pte++ = paddr; paddr += __PAGESIZE; size -= __PAGESIZE; } } return vaddr + off;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -