pagedirectory.cc
来自「Murphy 大俠 GPL 的 C++/x86 RTOS, 支持 MMU, 用戶」· CC 代码 · 共 155 行
CC
155 行
// File: PageDirectory.cc
/*
* Copyright (c) 1998-1999 Murphy Cheng-Che Chen <murphychen@mail2000.com.tw>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
1998/12/09: Created by Murphy Cheng-Che Chen
*/
#include "PageDirectory.h"
#include "MemoryManager\MemoryManager.h"
#include "Initialize\Globals.h"
#include "LibC\assert\assert.h"
#include "LibC\stdio\stdio.h"
#include "LibC\string\string.h"
void PageDirectory::Allocate()
{
m_pdeTable=(PageDirectoryEntry*)g_MemoryManager.AllocPage(0);
#ifdef DEBUG
// printf("Allocate Page Directory Base Address = %x\n",
// m_pdeTable);
#endif
memset(m_pdeTable, 0, 1024*4);
m_ptTables=new PageTable[1024];
}
void PageDirectory::Deallocate()
{
g_MemoryManager.FreePage(m_pdeTable);
delete [] m_ptTables;
}
void PageDirectory::MapPage(vm_offset_t linear_address, vm_offset_t physical_address, DWORD mapping_bits)
{
assert(mapping_bits & PDE_PRESENT);
assert(!(mapping_bits & PDE_BASEADDRESS));
WORD pdtIndex=LinearToPageDirectoryTableIndex(linear_address);
// Find the page table, creating one if necessary.
if (!(m_pdeTable[pdtIndex].Present))
{
m_ptTables[pdtIndex].Allocate();
// Set the pde to point to it.
m_pdeTable[pdtIndex] =
(DWORD)m_ptTables[pdtIndex].GetBase()
| PDE_PRESENT | PDE_USER | PDE_WRITE;
}
m_ptTables[pdtIndex].MapPage(linear_address, physical_address, mapping_bits);
}
void PageDirectory::MapRange(vm_offset_t linear_address, vm_offset_t physical_address,
vm_size_t size, DWORD mapping_bits)
{
assert(mapping_bits & PDE_PRESENT);
assert(!(mapping_bits & PDE_BASEADDRESS));
// Make size round to mutiples of 4K.
size=(size+PAGE_SIZE-1)&~(PAGE_SIZE-1);
// printf("PageDirectory::MapRange %08x -> %08x, size=%08x\n", linear_address, physical_address, size);
while (size > 0)
{
WORD pdtIndex=LinearToPageDirectoryTableIndex(linear_address);
#if 0
// Use a 4MB page if we can.
if (superpage_aligned(linear_address)
&& superpage_aligned(physical_address)
&& (size >= SUPERPAGE_SIZE)
&& ( g_Processor.CPUFeatureVerify(CPUF_4MB_PAGES)) )
{
// printf("Size left for mapping : %x\n", size);
assert(m_pdeTable[pdtIndex].Present==0);
/* XXX what if an empty page table exists
from previous finer-granularity mappings? */
m_pdeTable[pdtIndex] = physical_address | mapping_bits | PDE_SUPERPAGE;
linear_address += SUPERPAGE_SIZE;
physical_address += SUPERPAGE_SIZE;
size -= SUPERPAGE_SIZE;
}
else
#endif
{
PageTableEntry *pte;
// Find the page table, creating one if necessary.
if (!(m_pdeTable[pdtIndex].Present))
{
m_ptTables[pdtIndex].Allocate();
// Set the pde to point to it.
m_pdeTable[pdtIndex] = (DWORD)m_ptTables[pdtIndex].GetBase()
| PDE_PRESENT | PDE_USER | PDE_WRITE;
}
// printf("Page Directory Entry %x =%x\n", pdtIndex, m_pdeTable[pdtIndex]);
// printf("Page Directory Entry Present = %d\n", m_pdeTable[pdtIndex].Present);
// printf("Page Directory Entry Write = %d\n", m_pdeTable[pdtIndex].Write);
// printf("Page Directory Entry User = %d\n", m_pdeTable[pdtIndex].User);
// printf("Page Directory Entry WriteThrough = %d\n", m_pdeTable[pdtIndex].WriteThrough);
// printf("Page Directory Entry CacheDisable = %d\n", m_pdeTable[pdtIndex].CacheDisable);
// printf("Page Directory Entry Accessed = %d\n", m_pdeTable[pdtIndex].Accessed);
// printf("Page Directory Entry SuperPage = %d\n", m_pdeTable[pdtIndex].SuperPage);
// printf("Page Directory Entry Avail = %d\n", m_pdeTable[pdtIndex].Avail);
// printf("Page Directory Entry PageTableBaseAddress = %d\n", m_pdeTable[pdtIndex].PageTableBaseAddress);
assert(m_pdeTable[pdtIndex].SuperPage==0);
// Use normal 4KB page mappings.
do
{
// printf("Size left for mapping : %x\n", size);
m_ptTables[pdtIndex].MapPage(linear_address, physical_address, mapping_bits);
// Advance to the next page.
linear_address += PAGE_SIZE;
physical_address += PAGE_SIZE;
size -= PAGE_SIZE;
}
while ((size > 0) && !superpage_aligned(linear_address));
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?