/*
* 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 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/vm_machparam.h>
#include <vm/seg_kmem.h>
#include <sys/x86_archext.h>
#include <sys/archsystm.h>
#include <sys/ddidmareq.h>
#include <sys/controlregs.h>
#include <sys/bootconf.h>
#include <sys/bootsvcs.h>
#include <sys/bootinfo.h>
#include <vm/kboot_mmu.h>
#ifdef __xpv
#include <sys/hypervisor.h>
#endif
{
} else {
}
}
return (addr1);
}
/*
* This routine is like page_numtopp, but accepts only free pages, which
* it allocates (unfrees) and returns with the exclusive lock held.
*
* XXX this and some others should probably be in vm_machdep.c
*/
page_t *
{
return (NULL);
}
return (NULL);
}
goto retry;
}
return (NULL);
}
goto retry;
}
/* If associated with a vnode, destroy mappings */
return (NULL);
}
goto retry;
}
}
return (NULL);
}
return (NULL);
return (pp);
}
/*
* Flag is not set early in boot. Once it is set we are no longer
* using boot's page tables.
*/
/*
* This procedure is callable only while the boot loader is in charge of the
* MMU. It assumes that PA == VA for page table pointers. It doesn't live in
* kboot_mmu.c since it's used from common code.
*/
{
if (khat_running)
panic("va_to_pfn(): called too late\n");
return (PFN_INVALID);
return (PFN_INVALID);
return (pfn);
}
/*
* Initialize a special area in the kernel that always holds some PTEs for
* faster performance. This always holds segmap's PTEs.
* In the 32 bit kernel this maps the kernel heap too.
*/
void
{
ulong_t i;
/*
* We have to map in an area that matches an entire page table.
* The PTEs are large page aligned to avoid spurious pagefaults
* on the hypervisor.
*/
/*
* allocate vmem for the kmap_ptes
*/
/*
* Map the page tables that cover kmap into the allocated range.
* Note we don't ever htable_release() the kmap page tables - they
* can't ever be stolen, freed, etc.
*/
panic("hat_kmap_init: ht == NULL");
#ifdef __xpv
#else
#endif
}
/*
* set information in mmu to activate handling of kmap
*/
}
#ifdef __xpv
/*
* Create the initial segkpm mappings for the hypervisor. To avoid having
* to deal with page tables being read only, we make all mappings
* read only at first.
*/
static void
{
}
}
/*
* Try to make all kpm mappings writable. Failures are ok, as those
* are just pagetable, GDT, etc. pages.
*/
static void
xen_kpm_finish_init(void)
{
/*
* skip gdt
*/
continue;
/*
* p_index is a hint that this is a pagetable
*/
continue;
}
}
}
#endif
/*
* Routine to pre-allocate data structures for hat_kern_setup(). It computes
* how many pagetables it needs by walking the boot loader's page tables.
*/
/*ARGSUSED*/
void
{
level_t l;
int nwindows;
if (kpm_size > 0) {
/*
* Create the kpm page tables. When running on the
* Later we'll add write permission where possible.
*/
while (psize >= MMU_PAGESIZE) {
/* find the largest page size */
for (l = lpagel; l > 0; l--) {
if ((paddr & LEVEL_OFFSET(l)) == 0 &&
psize > LEVEL_SIZE(l))
break;
}
#if defined(__xpv)
/*
* conflicting with pagetable usage
*/
xen_kpm_create(paddr, l);
#else
l, 1);
#endif
paddr += LEVEL_SIZE(l);
psize -= LEVEL_SIZE(l);
}
}
}
/*
* If this machine doesn't have a kpm segment, we need to allocate
* a small number of 'windows' which can be used to map pagetables.
*/
#if defined(__xpv)
/*
* On a hypervisor, these windows are also used by the xpv_panic
* code, where we need one window for each level of the pagetable
* hierarchy.
*/
#endif
if (nwindows != 0) {
/*
* Create the page windows and 1 page of VA in
* which we map the PTEs of those windows.
*/
/*
*/
paddr = 0;
#ifdef __xpv
#else
#endif
}
/*
* Walk the boot loader's page tables and figure out
* how many tables and page mappings there will be.
*/
/*
* At each level, if the last_va falls into a new htable,
* increment table_cnt. We can stop at the 1st level where
* they are in the same htable.
*/
start_level = 0;
break;
start_level++;
}
break;
++table_cnt;
}
}
/*
* Besides the boot loader mappings, we're going to fill in
* the entire top level page table for the kernel. Make sure there's
* enough reserve for that too.
*/
#if defined(__i386)
/*
* The 32 bit PAE hat allocates tables one level below the top when
* kernelbase isn't 1 Gig aligned. We'll just be sloppy and allocate
* a bunch more to the reserve. Any unused will be returned later.
* Note we've already counted these mappings, just not the extra
* pagetables.
*/
#endif
/*
* Add 1/4 more into table_cnt for extra slop. The unused
* slop is freed back when we htable_adjust_reserve() later.
*/
/*
* We only need mapping entries (hments) for shared pages.
* This should be far, far fewer than the total possible,
* We'll allocate enough for 1/16 of all possible PTEs.
*/
/*
*/
}
/*
* This routine handles the work of creating the kernel's initial mappings
* by deciphering the mappings in the page tables created by the boot program.
*
* We maintain large page mappings, but only to a level 1 pagesize.
* The boot loader can only add new mappings once this function starts.
* In particular it can not change the pagesize used for any existing
* mappings or this code breaks!
*/
void
hat_kern_setup(void)
{
/*
* Attach htables to the existing pagetables
*/
/* BEGIN CSTYLED */
#ifdef __xpv
#else
#endif
/* END CSTYLED */
#endif /* __i386 */
/*
* Try to make the kpm mappings r/w. Failures here are OK, as
* it's probably just a pagetable
*/
#endif
/*
* The kernel HAT is now officially open for business.
*/
khat_running = 1;
}