Re-arrange code to flush physically indexed caches:
* replace `flush by line' function with a `flush by page' funtion, which also takes an argument to indicate that write-back caches need not validate its backing memory. * use this function when allocating page table memory to flush the cache before mapping it into kernel virtual space. * also use it in pmap_{zero,copy}_page(), so we can safely use non-cacheable access in there.
This commit is contained in:
parent
95c4357e1b
commit
862a955e34
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cache.c,v 1.50 2000/05/22 22:03:32 pk Exp $ */
|
||||
/* $NetBSD: cache.c,v 1.51 2000/06/05 20:38:24 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -82,7 +82,7 @@ int cache_alias_bits;
|
|||
void
|
||||
sun4_cache_enable()
|
||||
{
|
||||
register u_int i, lim, ls, ts;
|
||||
u_int i, lim, ls, ts;
|
||||
|
||||
cache_alias_bits = CPU_ISSUN4
|
||||
? CACHE_ALIAS_BITS_SUN4
|
||||
|
@ -335,8 +335,8 @@ turbosparc_cache_enable()
|
|||
void
|
||||
sun4_vcache_flush_context()
|
||||
{
|
||||
register char *p;
|
||||
register int i, ls;
|
||||
char *p;
|
||||
int i, ls;
|
||||
|
||||
cachestats.cs_ncxflush++;
|
||||
p = (char *)0; /* addresses 0..cacheinfo.c_totalsize will do fine */
|
||||
|
@ -365,10 +365,10 @@ sun4_vcache_flush_context()
|
|||
*/
|
||||
void
|
||||
sun4_vcache_flush_region(vreg)
|
||||
register int vreg;
|
||||
int vreg;
|
||||
{
|
||||
register int i, ls;
|
||||
register char *p;
|
||||
int i, ls;
|
||||
char *p;
|
||||
|
||||
cachestats.cs_nrgflush++;
|
||||
p = (char *)VRTOVA(vreg); /* reg..reg+sz rather than 0..sz */
|
||||
|
@ -389,10 +389,10 @@ sun4_vcache_flush_region(vreg)
|
|||
*/
|
||||
void
|
||||
sun4_vcache_flush_segment(vreg, vseg)
|
||||
register int vreg, vseg;
|
||||
int vreg, vseg;
|
||||
{
|
||||
register int i, ls;
|
||||
register char *p;
|
||||
int i, ls;
|
||||
char *p;
|
||||
|
||||
cachestats.cs_nsgflush++;
|
||||
p = (char *)VSTOVA(vreg, vseg); /* seg..seg+sz rather than 0..sz */
|
||||
|
@ -418,8 +418,8 @@ void
|
|||
sun4_vcache_flush_page(va)
|
||||
int va;
|
||||
{
|
||||
register int i, ls;
|
||||
register char *p;
|
||||
int i, ls;
|
||||
char *p;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (va & PGOFSET)
|
||||
|
@ -451,10 +451,10 @@ sun4_vcache_flush_page(va)
|
|||
void
|
||||
sun4_cache_flush(base, len)
|
||||
caddr_t base;
|
||||
register u_int len;
|
||||
u_int len;
|
||||
{
|
||||
register int i, ls, baseoff;
|
||||
register char *p;
|
||||
int i, ls, baseoff;
|
||||
char *p;
|
||||
|
||||
if (CACHEINFO.c_vactype == VAC_NONE)
|
||||
return;
|
||||
|
@ -528,8 +528,8 @@ sun4_cache_flush(base, len)
|
|||
void
|
||||
srmmu_vcache_flush_context()
|
||||
{
|
||||
register char *p;
|
||||
register int i, ls;
|
||||
char *p;
|
||||
int i, ls;
|
||||
|
||||
cachestats.cs_ncxflush++;
|
||||
p = (char *)0; /* addresses 0..cacheinfo.c_totalsize will do fine */
|
||||
|
@ -548,10 +548,10 @@ srmmu_vcache_flush_context()
|
|||
*/
|
||||
void
|
||||
srmmu_vcache_flush_region(vreg)
|
||||
register int vreg;
|
||||
int vreg;
|
||||
{
|
||||
register int i, ls;
|
||||
register char *p;
|
||||
int i, ls;
|
||||
char *p;
|
||||
|
||||
cachestats.cs_nrgflush++;
|
||||
p = (char *)VRTOVA(vreg); /* reg..reg+sz rather than 0..sz */
|
||||
|
@ -572,10 +572,10 @@ srmmu_vcache_flush_region(vreg)
|
|||
*/
|
||||
void
|
||||
srmmu_vcache_flush_segment(vreg, vseg)
|
||||
register int vreg, vseg;
|
||||
int vreg, vseg;
|
||||
{
|
||||
register int i, ls;
|
||||
register char *p;
|
||||
int i, ls;
|
||||
char *p;
|
||||
|
||||
cachestats.cs_nsgflush++;
|
||||
p = (char *)VSTOVA(vreg, vseg); /* seg..seg+sz rather than 0..sz */
|
||||
|
@ -594,8 +594,8 @@ void
|
|||
srmmu_vcache_flush_page(va)
|
||||
int va;
|
||||
{
|
||||
register int i, ls;
|
||||
register char *p;
|
||||
int i, ls;
|
||||
char *p;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (va & PGOFSET)
|
||||
|
@ -726,6 +726,17 @@ ms1_cache_flush(base, len)
|
|||
*
|
||||
* Note: we don't bother to compare the actual tags
|
||||
* since that would require looking up physical addresses.
|
||||
*
|
||||
* The format of the tags we read from ASI_DCACHE control
|
||||
* space is:
|
||||
*
|
||||
* 31 27 26 11 10 1 0
|
||||
* +--------+----------------+------------+-+
|
||||
* | xxx | PA[26-11] | xxx |V|
|
||||
* +--------+----------------+------------+-+
|
||||
*
|
||||
* PA: bits 11-26 of the physical address
|
||||
* V: line valid bit
|
||||
*/
|
||||
int tagaddr = ((u_int)base & 0x7f0);
|
||||
|
||||
|
@ -786,7 +797,7 @@ cypress_cache_flush_all()
|
|||
void
|
||||
viking_cache_flush(base, len)
|
||||
caddr_t base;
|
||||
register u_int len;
|
||||
u_int len;
|
||||
{
|
||||
/*
|
||||
* Although physically tagged, we still need to flush the
|
||||
|
@ -797,73 +808,102 @@ viking_cache_flush(base, len)
|
|||
}
|
||||
|
||||
void
|
||||
viking_pcache_flush_line(va, pa)
|
||||
int va;
|
||||
int pa;
|
||||
viking_pcache_flush_page(pa, invalidate_only)
|
||||
paddr_t pa;
|
||||
int invalidate_only;
|
||||
{
|
||||
/*
|
||||
* Flush cache line corresponding to virtual address `va'
|
||||
* which is mapped at physical address `pa'.
|
||||
*/
|
||||
extern char etext[];
|
||||
static char *base;
|
||||
int i;
|
||||
char *v;
|
||||
int set, i;
|
||||
|
||||
/*
|
||||
* Construct a virtual address that hits the same cache line
|
||||
* as PA, then read from 2*ASSOCIATIVITY-1 different physical
|
||||
* locations (all different from PA).
|
||||
* The viking's on-chip data cache is 4-way set associative,
|
||||
* consisting of 128 sets, each holding 4 lines of 32 bytes.
|
||||
* Note that one 4096 byte page exactly covers all 128 sets
|
||||
* in the cache.
|
||||
*/
|
||||
if (invalidate_only) {
|
||||
u_int pa_tag = (pa >> 12);
|
||||
u_int tagaddr;
|
||||
u_int64_t tag;
|
||||
|
||||
/*
|
||||
* Loop over all sets and invalidate all entries tagged
|
||||
* with the given physical address by resetting the cache
|
||||
* tag in ASI_DCACHETAG control space.
|
||||
*
|
||||
* The address format for accessing a tag is:
|
||||
*
|
||||
* 31 30 27 26 11 5 4 3 2 0
|
||||
* +------+-----+------+-------//--------+--------+----+-----+
|
||||
* | type | xxx | line | xxx | set | xx | 0 |
|
||||
* +------+-----+------+-------//--------+--------+----+-----+
|
||||
*
|
||||
* set: the cache set tag to be read (0-127)
|
||||
* line: the line within the set (0-3)
|
||||
* type: 1: read set tag; 2: read physical tag
|
||||
*
|
||||
* The (type 2) tag read from this address is a 64-bit word
|
||||
* formatted as follows:
|
||||
*
|
||||
* 5 4 4
|
||||
* 63 6 8 0 23 0
|
||||
* +-------+-+-------+-+-------+-+-----------+----------------+
|
||||
* | xxx |V| xxx |D| xxx |S| xxx | PA[35-12] |
|
||||
* +-------+-+-------+-+-------+-+-----------+----------------+
|
||||
*
|
||||
* PA: bits 12-35 of the physical address
|
||||
* S: line shared bit
|
||||
* D: line dirty bit
|
||||
* V: line valid bit
|
||||
*/
|
||||
|
||||
#if 0
|
||||
if (base == 0) {
|
||||
cshift = CACHEINFO.ic_l2linesize;
|
||||
csize = CACHEINFO.ic_nlines << cshift;
|
||||
cmask = csize - 1;
|
||||
base = (char *)roundup((int)etext, csize);
|
||||
#define VIKING_DCACHETAG_S 0000010000000000UL /* line valid bit */
|
||||
#define VIKING_DCACHETAG_D 0001000000000000UL /* line dirty bit */
|
||||
#define VIKING_DCACHETAG_V 0100000000000000UL /* line shared bit */
|
||||
|
||||
for (set = 0; set < 128; set++) {
|
||||
/* Set set number and access type */
|
||||
tagaddr = (set << 5) | (2 << 30);
|
||||
|
||||
/* Examine the tag for each line in the set */
|
||||
for (i = 0 ; i < 4; i++) {
|
||||
tag = ldda(tagaddr | (i << 26), ASI_DCACHETAG);
|
||||
/*
|
||||
* If this is a valid tag and the PA field
|
||||
* matches clear the tag.
|
||||
*/
|
||||
if ((tag & 0x000fffff) == pa_tag &&
|
||||
(tag & VIKING_DCACHETAG_V) != 0)
|
||||
stda(tagaddr | (i << 26),
|
||||
ASI_DCACHETAG, 0);
|
||||
}
|
||||
}
|
||||
|
||||
v = base + (((va & cmask) >> cshift) << cshift);
|
||||
i = CACHEINFO.dc_associativity * 2 - 1;
|
||||
} else {
|
||||
extern char kernel_text[];
|
||||
|
||||
/*
|
||||
* Force the cache to validate its backing memory
|
||||
* by displacing all cache lines with known read-only
|
||||
* content from the start of kernel text.
|
||||
*
|
||||
* Note that this thrashes the entire cache. However,
|
||||
* we currently only need to call upon this code
|
||||
* once at boot time.
|
||||
*/
|
||||
for (set = 0; set < 128; set++) {
|
||||
int *v = (int *)(kernel_text + (set << 5));
|
||||
|
||||
/*
|
||||
* We need to read (2*associativity-1) different
|
||||
* locations to be sure to displace the entire set.
|
||||
*/
|
||||
i = 2 * 4 - 1;
|
||||
while (i--) {
|
||||
(*(volatile int *)v);
|
||||
v += csize;
|
||||
v += 4096;
|
||||
}
|
||||
#else
|
||||
#define cshift 5 /* CACHEINFO.ic_l2linesize */
|
||||
#define csize (128 << cshift) /* CACHEINFO.ic_nlines << cshift */
|
||||
#define cmask (csize - 1)
|
||||
#define cass 4 /* CACHEINFO.dc_associativity */
|
||||
|
||||
if (base == 0)
|
||||
base = (char *)roundup((unsigned int)etext, csize);
|
||||
|
||||
v = base + (((pa & cmask) >> cshift) << cshift);
|
||||
i = 2 * cass - 1;
|
||||
|
||||
while (i--) {
|
||||
(*(volatile int *)v);
|
||||
v += csize;
|
||||
}
|
||||
#undef cass
|
||||
#undef cmask
|
||||
#undef csize
|
||||
#undef cshift
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
srmmu_pcache_flush_line(va, pa)
|
||||
int va;
|
||||
int pa;
|
||||
{
|
||||
/*
|
||||
* Flush cache line corresponding to virtual address `va'
|
||||
* which is mapped at physical address `pa'.
|
||||
*/
|
||||
sta(va, ASI_IDCACHELFP, 0);
|
||||
}
|
||||
#endif /* SUN4M */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cache.h,v 1.20 1998/10/09 10:48:14 pk Exp $ */
|
||||
/* $NetBSD: cache.h,v 1.21 2000/06/05 20:38:24 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -171,7 +171,7 @@ void srmmu_cache_flush __P((caddr_t, u_int));/* flush region */
|
|||
|
||||
void ms1_cache_flush __P((caddr_t, u_int));
|
||||
void viking_cache_flush __P((caddr_t, u_int));
|
||||
void viking_pcache_flush_line __P((int, int));
|
||||
void viking_pcache_flush_page __P((paddr_t, int));
|
||||
void srmmu_pcache_flush_line __P((int, int));
|
||||
void hypersparc_pure_vcache_flush __P((void));
|
||||
|
||||
|
@ -192,7 +192,7 @@ extern void sparc_noop __P((void));
|
|||
(void (*)__P((int))) sparc_noop
|
||||
#define noop_cache_flush \
|
||||
(void (*)__P((caddr_t, u_int))) sparc_noop
|
||||
#define noop_pcache_flush_line \
|
||||
#define noop_pcache_flush_page \
|
||||
(void (*)__P((int, int))) sparc_noop
|
||||
#define noop_pure_vcache_flush \
|
||||
(void (*)__P((void))) sparc_noop
|
||||
|
@ -215,6 +215,8 @@ void smp_cache_flush __P((caddr_t, u_int)); /* flush region */
|
|||
#define cache_flush_region(vr) cpuinfo.vcache_flush_region(vr)
|
||||
#define cache_flush_context() cpuinfo.vcache_flush_context()
|
||||
|
||||
#define pcache_flush_page(pa,flag) cpuinfo.pcache_flush_page(pa,flag)
|
||||
|
||||
/*
|
||||
* Cache control information.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.c,v 1.103 2000/06/03 09:56:35 pk Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.104 2000/06/05 20:38:25 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -671,7 +671,7 @@ struct module_info module_sun4 = {
|
|||
sun4_vcache_flush_segment,
|
||||
sun4_vcache_flush_region,
|
||||
sun4_vcache_flush_context,
|
||||
noop_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
noop_cache_flush_all,
|
||||
0,
|
||||
|
@ -799,7 +799,7 @@ struct module_info module_sun4c = {
|
|||
sun4_vcache_flush_segment,
|
||||
sun4_vcache_flush_region,
|
||||
sun4_vcache_flush_context,
|
||||
noop_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
noop_cache_flush_all,
|
||||
0,
|
||||
|
@ -999,7 +999,7 @@ struct module_info module_ms1 = {
|
|||
noop_vcache_flush_segment,
|
||||
noop_vcache_flush_region,
|
||||
noop_vcache_flush_context,
|
||||
noop_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
ms1_cache_flush_all,
|
||||
memerr4m,
|
||||
|
@ -1029,7 +1029,7 @@ struct module_info module_ms2 = { /* UNTESTED */
|
|||
srmmu_vcache_flush_segment,
|
||||
srmmu_vcache_flush_region,
|
||||
srmmu_vcache_flush_context,
|
||||
noop_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
srmmu_cache_flush_all,
|
||||
memerr4m,
|
||||
|
@ -1054,7 +1054,7 @@ struct module_info module_swift = {
|
|||
srmmu_vcache_flush_segment,
|
||||
srmmu_vcache_flush_region,
|
||||
srmmu_vcache_flush_context,
|
||||
srmmu_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
srmmu_cache_flush_all,
|
||||
memerr4m,
|
||||
|
@ -1095,7 +1095,7 @@ struct module_info module_viking = {
|
|||
noop_vcache_flush_segment,
|
||||
noop_vcache_flush_region,
|
||||
noop_vcache_flush_context,
|
||||
viking_pcache_flush_line,
|
||||
viking_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
noop_cache_flush_all,
|
||||
viking_memerr,
|
||||
|
@ -1180,7 +1180,7 @@ struct module_info module_hypersparc = {
|
|||
srmmu_vcache_flush_segment,
|
||||
srmmu_vcache_flush_region,
|
||||
srmmu_vcache_flush_context,
|
||||
srmmu_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
hypersparc_pure_vcache_flush,
|
||||
hypersparc_cache_flush_all,
|
||||
hypersparc_memerr,
|
||||
|
@ -1230,7 +1230,7 @@ struct module_info module_cypress = {
|
|||
srmmu_vcache_flush_segment,
|
||||
srmmu_vcache_flush_region,
|
||||
srmmu_vcache_flush_context,
|
||||
srmmu_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
cypress_cache_flush_all,
|
||||
memerr4m,
|
||||
|
@ -1255,7 +1255,7 @@ struct module_info module_turbosparc = {
|
|||
srmmu_vcache_flush_segment,
|
||||
srmmu_vcache_flush_region,
|
||||
srmmu_vcache_flush_context,
|
||||
srmmu_pcache_flush_line,
|
||||
noop_pcache_flush_page,
|
||||
noop_pure_vcache_flush,
|
||||
srmmu_cache_flush_all,
|
||||
memerr4m,
|
||||
|
@ -1295,7 +1295,7 @@ cpumatch_turbosparc(sc, mp, node)
|
|||
sc->sp_vcache_flush_segment = 0;
|
||||
sc->sp_vcache_flush_region = 0;
|
||||
sc->sp_vcache_flush_context = 0;
|
||||
sc->pcache_flush_line = 0;
|
||||
sc->pcache_flush_page = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1480,7 +1480,7 @@ getcpuinfo(sc, node)
|
|||
MPCOPY(sp_vcache_flush_segment);
|
||||
MPCOPY(sp_vcache_flush_region);
|
||||
MPCOPY(sp_vcache_flush_context);
|
||||
MPCOPY(pcache_flush_line);
|
||||
MPCOPY(pcache_flush_page);
|
||||
MPCOPY(pure_vcache_flush);
|
||||
MPCOPY(cache_flush_all);
|
||||
MPCOPY(memerr);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpuvar.h,v 1.26 2000/05/31 05:28:28 thorpej Exp $ */
|
||||
/* $NetBSD: cpuvar.h,v 1.27 2000/06/05 20:38:25 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 The NetBSD Foundation, Inc.
|
||||
|
@ -78,7 +78,7 @@ struct module_info {
|
|||
void (*sp_vcache_flush_segment)__P((int, int));
|
||||
void (*sp_vcache_flush_region)__P((int));
|
||||
void (*sp_vcache_flush_context)__P((void));
|
||||
void (*pcache_flush_line)__P((int, int));
|
||||
void (*pcache_flush_page)__P((int, int));
|
||||
void (*pure_vcache_flush)__P((void));
|
||||
void (*cache_flush_all)__P((void));
|
||||
void (*memerr)__P((unsigned, u_int, u_int, struct trapframe *));
|
||||
|
@ -280,7 +280,7 @@ struct cpu_info {
|
|||
void (*vcache_flush_context)__P((void));
|
||||
void (*sp_vcache_flush_context)__P((void));
|
||||
|
||||
void (*pcache_flush_line)__P((int, int));
|
||||
void (*pcache_flush_page)__P((int, int));
|
||||
void (*pure_vcache_flush)__P((void));
|
||||
void (*cache_flush_all)__P((void));
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.c,v 1.166 2000/06/02 10:43:59 pk Exp $ */
|
||||
/* $NetBSD: pmap.c,v 1.167 2000/06/05 20:38:26 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -570,11 +570,6 @@ setpgt4m(ptep, pte)
|
|||
int pte;
|
||||
{
|
||||
swap(ptep, pte);
|
||||
#if 0
|
||||
/* XXX - uncaching in pgt_page_alloc() below is not yet quite Okay */
|
||||
if (cpuinfo.cpu_type == CPUTYP_SS1_MBUS_NOMXCC)
|
||||
cpuinfo.pcache_flush_line((int)ptep, VA2PA((caddr_t)ptep));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set the page table entry for va to pte. */
|
||||
|
@ -613,18 +608,6 @@ setpte4m(va, pte)
|
|||
setpgt4m(sm->sg_pte + VA_SUN4M_VPG(va), pte);
|
||||
}
|
||||
|
||||
void pcache_flush __P((caddr_t, caddr_t, int));
|
||||
void
|
||||
pcache_flush(va, pa, n)
|
||||
caddr_t va, pa;
|
||||
int n;
|
||||
{
|
||||
void (*f)__P((int,int)) = cpuinfo.pcache_flush_line;
|
||||
|
||||
while ((n -= 4) >= 0)
|
||||
(*f)((u_int)va+n, (u_int)pa+n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Page table pool back-end.
|
||||
*/
|
||||
|
@ -634,16 +617,38 @@ pgt_page_alloc(sz, flags, mtype)
|
|||
int flags;
|
||||
int mtype;
|
||||
{
|
||||
caddr_t p;
|
||||
int cacheit = (cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0;
|
||||
struct vm_page *pg;
|
||||
vaddr_t va;
|
||||
paddr_t pa;
|
||||
|
||||
p = (caddr_t)uvm_km_kmemalloc(kernel_map, uvm.kernel_object,
|
||||
(vsize_t)sz, UVM_KMF_NOWAIT);
|
||||
/* Allocate a page of physical memory */
|
||||
if ((pg = uvm_pagealloc(NULL, 0, NULL, 0)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0) {
|
||||
pcache_flush(p, (caddr_t)VA2PA(p), sz);
|
||||
kvm_uncache(p, sz/NBPG);
|
||||
/* Allocate virtual memory */
|
||||
va = uvm_km_valloc(kernel_map, PAGE_SIZE);
|
||||
if (va == 0) {
|
||||
uvm_pagefree(pg);
|
||||
return (NULL);
|
||||
}
|
||||
return (p);
|
||||
|
||||
/*
|
||||
* On systems with a physical data cache we need to flush this page
|
||||
* from the cache if the pagetables cannot be cached.
|
||||
* On systems with a virtually indexed data cache, we only need
|
||||
* to map it non-cacheable, since the page is not currently mapped.
|
||||
*/
|
||||
pa = VM_PAGE_TO_PHYS(pg);
|
||||
if (cacheit == 0)
|
||||
pcache_flush_page(pa, 1);
|
||||
|
||||
/* Map the page */
|
||||
pmap_enter(pmap_kernel(), va, pa | (cacheit ? 0 : PMAP_NC),
|
||||
VM_PROT_READ|VM_PROT_WRITE,
|
||||
VM_PROT_READ|VM_PROT_WRITE|PMAP_WIRED);
|
||||
|
||||
return ((void *)va);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3066,6 +3071,7 @@ pmap_bootstrap4m(void)
|
|||
int reg, seg;
|
||||
unsigned int ctxtblsize;
|
||||
caddr_t pagetables_start, pagetables_end;
|
||||
paddr_t pagetables_start_pa;
|
||||
extern char end[];
|
||||
extern char etext[];
|
||||
extern caddr_t reserve_dumppages(caddr_t);
|
||||
|
@ -3153,7 +3159,7 @@ pmap_bootstrap4m(void)
|
|||
get_phys_mem();
|
||||
|
||||
/* Allocate physical memory for pv_table[] */
|
||||
p += pv_table_map((paddr_t)p - KERNBASE, 0);
|
||||
p += pv_table_map((paddr_t)(p - KERNBASE), 0);
|
||||
|
||||
/*
|
||||
* Reserve memory for MMU pagetables. Some of these have severe
|
||||
|
@ -3162,6 +3168,7 @@ pmap_bootstrap4m(void)
|
|||
*/
|
||||
|
||||
pagetables_start = p;
|
||||
pagetables_start_pa = (paddr_t)(p - KERNBASE);
|
||||
|
||||
/*
|
||||
* Allocate context table.
|
||||
|
@ -3169,7 +3176,7 @@ pmap_bootstrap4m(void)
|
|||
*/
|
||||
ctxtblsize = max(ncontext,1024) * sizeof(int);
|
||||
cpuinfo.ctx_tbl = (int *)roundup((u_int)p, ctxtblsize);
|
||||
cpuinfo.ctx_tbl_pa = (paddr_t)cpuinfo.ctx_tbl - KERNBASE;
|
||||
cpuinfo.ctx_tbl_pa = (paddr_t)(cpuinfo.ctx_tbl - KERNBASE);
|
||||
p = (caddr_t)((u_int)cpuinfo.ctx_tbl + ctxtblsize);
|
||||
|
||||
/*
|
||||
|
@ -3197,7 +3204,7 @@ pmap_bootstrap4m(void)
|
|||
/* Round to next page and mark end of pre-wired kernel space */
|
||||
p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
|
||||
pagetables_end = p;
|
||||
avail_start = (paddr_t)p - KERNBASE;
|
||||
avail_start = (paddr_t)(p - KERNBASE);
|
||||
|
||||
/*
|
||||
* Now wire the region and segment tables of the kernel map.
|
||||
|
@ -3342,8 +3349,22 @@ pmap_bootstrap4m(void)
|
|||
* Flush it now, and don't touch it again until we
|
||||
* switch to our own tables (will be done immediately below).
|
||||
*/
|
||||
pcache_flush(pagetables_start, (caddr_t)VA2PA(pagetables_start),
|
||||
pagetables_end - pagetables_start);
|
||||
int size = pagetables_end - pagetables_start;
|
||||
if (CACHEINFO.c_vactype != VAC_NONE) {
|
||||
int va = (vaddr_t)pagetables_start;
|
||||
while (size != 0) {
|
||||
cache_flush_page(va);
|
||||
va += NBPG;
|
||||
size -= NBPG;
|
||||
}
|
||||
} else if (cpuinfo.pcache_flush_page != NULL) {
|
||||
int pa = pagetables_start_pa;
|
||||
while (size != 0) {
|
||||
pcache_flush_page(pa, 0);
|
||||
pa += NBPG;
|
||||
size -= NBPG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -6396,12 +6417,17 @@ pmap_zero_page4m(pa)
|
|||
|
||||
if (((pa & (PMAP_TNC_SRMMU & ~PMAP_NC)) == 0) && managed(pa)) {
|
||||
/*
|
||||
* The following might not be necessary since the page
|
||||
* is being cleared because it is about to be allocated,
|
||||
* The following VAC flush might not be necessary since the
|
||||
* page is being cleared because it is about to be allocated,
|
||||
* i.e., is in use by no one.
|
||||
* In the case of a physical cache, a flush (or just an
|
||||
* invalidate, if possible) is usually necessary when using
|
||||
* uncached access to clear it.
|
||||
*/
|
||||
if (CACHEINFO.c_vactype != VAC_NONE)
|
||||
pv_flushcache(pvhead(pa));
|
||||
else
|
||||
pcache_flush_page(pa, 1);
|
||||
}
|
||||
pte = SRMMU_TEPTE | PPROT_N_RWX | (atop(pa) << SRMMU_PPNSHIFT);
|
||||
if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY)
|
||||
|
@ -6507,6 +6533,8 @@ pmap_copy_page4m(src, dst)
|
|||
/* similar `might not be necessary' comment applies */
|
||||
if (CACHEINFO.c_vactype != VAC_NONE)
|
||||
pv_flushcache(pvhead(dst));
|
||||
else
|
||||
pcache_flush_page(dst, 1);
|
||||
}
|
||||
|
||||
dpte = SRMMU_TEPTE | PPROT_N_RWX | (atop(dst) << SRMMU_PPNSHIFT);
|
||||
|
|
Loading…
Reference in New Issue