kboot_mmu.c revision ae115bc77f6fcde83175c75b4206dc2e50747966
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/archsystm.h>
#include <sys/bootconf.h>
#include <sys/bootsvcs.h>
#include <sys/bootinfo.h>
#include <sys/machparam.h>
#include <sys/machsystm.h>
#include <vm/kboot_mmu.h>
#include <vm/seg_kmem.h>
#if 0
/*
* Joe's debug printing
*/
#define DBG(x) \
#else
#define DBG(x) /* naught */
#endif
/*
* Page table and memory stuff.
*/
static caddr_t pte_to_window;
/*
* this are needed by mmu_init()
*/
int kbm_nx_support = 0; /* NX bit in PTEs is in use */
int kbm_pae_support = 0; /* PAE is 64 bit Page table entries */
int kbm_pge_support = 0; /* PGE is Page table global bit enabled */
int kbm_largepage_support = 0;
uint_t kbm_nucleus_size = 0;
#define BOOT_SHIFT(l) (shift_amt[l])
#define BOOT_MASK(l) (~BOOT_OFFSET(l))
/*
* Initialize memory management parameters for boot time page table management
*/
void
{
/*
* configure mmu information
*/
if (kbm_pae_support) {
ptes_per_table = 512;
pte_size = 8;
#ifdef __amd64
top_level = 3;
#else
top_level = 2;
#endif
} else {
ptes_per_table = 1024;
pte_size = 4;
top_level = 1;
}
}
/*
* Change the addressible page table window to point at a given page
*/
/*ARGSUSED*/
void *
{
if (kbm_pae_support)
else
return (window);
}
/*
* Add a mapping for the physical page at the given virtual address.
*/
void
{
if (khat_running)
panic("kbm_map() called too late");
if (level == 1)
pteval |= PT_PAGESIZE;
if (kbm_pge_support && is_kernel)
/*
* Find the pte that will map this address. This creates any
* missing intermediate level page tables.
*/
bop_panic("kbm_map: find_pte returned NULL");
if (kbm_pae_support)
else
}
/*
* Probe the boot time page tables to find the first mapping
* including va (or higher) and return non-zero if one is found.
* va is updated to the starting address and len to the pagesize.
* pp will be set to point to the 1st page_t of the mapped page(s).
*
* Note that if va is in the middle of a large page, the returned va
* will be less than what was asked for.
*/
int
{
level_t l;
if (khat_running)
panic("kbm_probe() called too late");
*len = 0;
*pfn = PFN_INVALID;
*prot = 0;
l = top_level;
for (;;) {
if (IN_VA_HOLE(probe_va))
if (IN_HYPERVISOR_VA(probe_va))
return (0);
/*
* then we can bump VA by this level's pagesize and try again.
* When the probe_va wraps around, we are done.
*/
bop_panic("kbm_probe: find_pte returned NULL");
if (kbm_pae_support)
else
if (!PTE_ISVALID(pte_val)) {
return (0);
goto restart_new_va;
}
/*
* If this entry is a pointer to a lower level page table
* go down to it.
*/
if (!PTE_ISPAGE(pte_val, l)) {
ASSERT(l > 0);
--l;
continue;
}
/*
* We found a boot level page table entry
*/
*prot |= PROT_WRITE;
/*
* pt_nx is cleared if processor doesn't support NX bit
*/
return (1);
}
}
/*
* Destroy a boot loader page table 4K mapping.
*/
void
{
if (khat_running)
panic("kbm_unmap() called too late");
else {
return;
if (kbm_pae_support)
*ptep = 0;
else
*((x86pte32_t *)ptep) = 0;
}
}
/*
* Change a boot loader page table 4K mapping.
* Returns the pfn of the old mapping.
*/
{
if (khat_running)
panic("kbm_remap() called too late");
bop_panic("kbm_remap: find_pte returned NULL");
if (kbm_pae_support)
else
if (kbm_pae_support)
else
return (PFN_INVALID);
}
/*
* Change a boot loader page table 4K mapping to read only.
*/
void
{
bop_panic("kbm_read_only: find_pte returned NULL");
if (kbm_pae_support)
else
}
/*
* interfaces for kernel debugger to access physical memory
*/
void *
{
static int first_time = 1;
if (first_time) {
first_time = 0;
return (window);
}
if (kbm_pae_support)
else
return (kbm_remap_window(pa, 0));
}
void
kbm_pop(void)
{
if (kbm_pae_support)
else
}
{
if (kbm_pae_support)
}
void
{
if (kbm_pae_support)
else
reload_cr3();
}
{
void *table_ptr;
else
return (new_table);
}
x86pte_t *
{
}