version 1.322, 2008/01/02 11:48:29 |
version 1.322.20.2, 2009/11/15 05:58:38 |
Line 964 void pm_check_u(char *, struct pmap *); |
|
Line 964 void pm_check_u(char *, struct pmap *); |
|
|
|
static u_long va2pa_offset; |
static u_long va2pa_offset; |
#define PMAP_BOOTSTRAP_VA2PA(v) ((paddr_t)((u_long)(v) - va2pa_offset)) |
#define PMAP_BOOTSTRAP_VA2PA(v) ((paddr_t)((u_long)(v) - va2pa_offset)) |
|
#define PMAP_BOOTSTRAP_PA2VA(p) ((vaddr_t)((u_long)(p) + va2pa_offset)) |
|
|
/* |
/* |
* Grab physical memory list. |
* Grab physical memory list. |
Line 1115 pmap_page_upload(void) |
|
Line 1116 pmap_page_upload(void) |
|
if (end < chop) |
if (end < chop) |
chop = end; |
chop = end; |
#ifdef DEBUG |
#ifdef DEBUG |
printf("bootstrap gap: start %lx, chop %lx, end %lx\n", |
prom_printf("bootstrap gap: start %lx, chop %lx, end %lx\n", |
start, chop, end); |
start, chop, end); |
#endif |
#endif |
uvm_page_physload( |
uvm_page_physload( |
Line 1389 mmu_setup4m_L1(int regtblptd, struct pma |
|
Line 1390 mmu_setup4m_L1(int regtblptd, struct pma |
|
|
|
case SRMMU_TEPTE: |
case SRMMU_TEPTE: |
#ifdef DEBUG |
#ifdef DEBUG |
printf("mmu_setup4m_L1: " |
prom_printf("mmu_setup4m_L1: " |
"converting region 0x%x from L1->L3\n", i); |
"converting region 0x%x from L1->L3\n", i); |
#endif |
#endif |
/* |
/* |
Line 1444 mmu_setup4m_L2(int segtblptd, struct reg |
|
Line 1445 mmu_setup4m_L2(int segtblptd, struct reg |
|
|
|
case SRMMU_TEPTE: |
case SRMMU_TEPTE: |
#ifdef DEBUG |
#ifdef DEBUG |
printf("mmu_setup4m_L2: converting L2 entry at segment 0x%x to L3\n",i); |
prom_printf("mmu_setup4m_L2: converting L2 entry at segment 0x%x to L3\n",i); |
#endif |
#endif |
/* |
/* |
* This segment entry covers 256KB of memory -- or |
* This segment entry covers 256KB of memory -- or |
|
|
ctx_alloc(struct pmap *pm) |
ctx_alloc(struct pmap *pm) |
{ |
{ |
union ctxinfo *c; |
union ctxinfo *c; |
int cnum, i, doflush; |
int cnum, i = 0, doflush; |
struct regmap *rp; |
struct regmap *rp; |
int gap_start, gap_end; |
int gap_start, gap_end; |
vaddr_t va; |
vaddr_t va; |
|
#if defined(SUN4M) || defined(SUN4D) |
|
struct cpu_info *cpi; |
|
#endif |
|
|
/*XXX-GCC!*/gap_start=gap_end=0; |
/*XXX-GCC!*/gap_start=gap_end=0; |
#ifdef DEBUG |
#ifdef DEBUG |
Line 2205 ctx_alloc(struct pmap *pm) |
|
Line 2209 ctx_alloc(struct pmap *pm) |
|
* Note on multi-threaded processes: a context must remain |
* Note on multi-threaded processes: a context must remain |
* valid as long as any thread is still running on a CPU. |
* valid as long as any thread is still running on a CPU. |
*/ |
*/ |
#if defined(MULTIPROCESSOR) |
for (CPU_INFO_FOREACH(i, cpi)) { |
for (i = 0; i < sparc_ncpus; i++) |
|
#else |
|
i = 0; |
|
#endif |
|
{ |
|
struct cpu_info *cpi = cpus[i]; |
|
#if defined(MULTIPROCESSOR) |
|
if (cpi == NULL) |
|
continue; |
|
#endif |
|
setpgt4m(&cpi->ctx_tbl[cnum], |
setpgt4m(&cpi->ctx_tbl[cnum], |
(pm->pm_reg_ptps_pa[i] >> SRMMU_PPNPASHIFT) | |
(pm->pm_reg_ptps_pa[i] >> SRMMU_PPNPASHIFT) | |
SRMMU_TEPTD); |
SRMMU_TEPTD); |
Line 2237 ctx_free(struct pmap *pm) |
|
Line 2231 ctx_free(struct pmap *pm) |
|
{ |
{ |
union ctxinfo *c; |
union ctxinfo *c; |
int ctx; |
int ctx; |
|
#if defined(SUN4M) || defined(SUN4D) |
|
struct cpu_info *cpi; |
|
#endif |
|
|
c = pm->pm_ctx; |
c = pm->pm_ctx; |
ctx = pm->pm_ctxnum; |
ctx = pm->pm_ctxnum; |
Line 2259 ctx_free(struct pmap *pm) |
|
Line 2256 ctx_free(struct pmap *pm) |
|
|
|
cache_flush_context(ctx); |
cache_flush_context(ctx); |
tlb_flush_context(ctx, PMAP_CPUSET(pm)); |
tlb_flush_context(ctx, PMAP_CPUSET(pm)); |
#if defined(MULTIPROCESSOR) |
for (CPU_INFO_FOREACH(i, cpi)) { |
for (i = 0; i < sparc_ncpus; i++) |
|
#else |
|
i = 0; |
|
#endif |
|
{ |
|
struct cpu_info *cpi = cpus[i]; |
|
#if defined(MULTIPROCESSOR) |
|
if (cpi == NULL) |
|
continue; |
|
#endif |
|
setpgt4m(&cpi->ctx_tbl[ctx], SRMMU_TEINVALID); |
setpgt4m(&cpi->ctx_tbl[ctx], SRMMU_TEINVALID); |
} |
} |
} |
} |
Line 3014 pmap_bootstrap(int nctx, int nregion, in |
|
Line 3001 pmap_bootstrap(int nctx, int nregion, in |
|
} |
} |
|
|
pmap_page_upload(); |
pmap_page_upload(); |
curlwp = &lwp0; |
mutex_init(&demap_lock, MUTEX_DEFAULT, IPL_VM); |
|
mutex_init(&ctx_lock, MUTEX_DEFAULT, IPL_SCHED); |
} |
} |
|
|
#if defined(SUN4) || defined(SUN4C) |
#if defined(SUN4) || defined(SUN4C) |
Line 3209 pmap_bootstrap4_4c(void *top, int nctx, |
|
Line 3197 pmap_bootstrap4_4c(void *top, int nctx, |
|
|
|
p = i; /* retract to first free phys */ |
p = i; /* retract to first free phys */ |
|
|
mutex_init(&demap_lock, MUTEX_DEFAULT, IPL_VM); |
|
|
|
/* |
/* |
* All contexts are free except the kernel's. |
* All contexts are free except the kernel's. |
* |
* |
* XXX sun4c could use context 0 for users? |
* XXX sun4c could use context 0 for users? |
*/ |
*/ |
mutex_init(&ctx_lock, MUTEX_DEFAULT, IPL_SCHED); |
|
ci->c_pmap = pmap_kernel(); |
ci->c_pmap = pmap_kernel(); |
ctx_freelist = ci + 1; |
ctx_freelist = ci + 1; |
for (i = 1; i < ncontext; i++) { |
for (i = 1; i < ncontext; i++) { |
Line 3481 pmap_bootstrap4m(void *top) |
|
Line 3467 pmap_bootstrap4m(void *top) |
|
paddr_t pagetables_start_pa; |
paddr_t pagetables_start_pa; |
extern char etext[]; |
extern char etext[]; |
extern char kernel_text[]; |
extern char kernel_text[]; |
|
vaddr_t va; |
|
#ifdef MULTIPROCESSOR |
|
vsize_t off; |
|
struct vm_page *pg; |
|
#endif |
|
|
/* |
/* |
* Compute `va2pa_offset'. |
* Compute `va2pa_offset'. |
Line 3550 pmap_bootstrap4m(void *top) |
|
Line 3541 pmap_bootstrap4m(void *top) |
|
p += ncontext * sizeof *ci; |
p += ncontext * sizeof *ci; |
bzero((void *)ci, (u_int)p - (u_int)ci); |
bzero((void *)ci, (u_int)p - (u_int)ci); |
|
|
|
|
/* |
/* |
* Set up the `constants' for the call to vm_init() |
* Set up the `constants' for the call to vm_init() |
* in main(). All pages beginning at p (rounded up to |
* in main(). All pages beginning at p (rounded up to |
Line 3699 pmap_bootstrap4m(void *top) |
|
Line 3689 pmap_bootstrap4m(void *top) |
|
|
|
p = q; /* retract to first free phys */ |
p = q; /* retract to first free phys */ |
|
|
mutex_init(&demap_lock, MUTEX_DEFAULT, IPL_VM); |
|
|
|
/* |
/* |
* Set up the ctxinfo structures (freelist of contexts) |
* Set up the ctxinfo structures (freelist of contexts) |
*/ |
*/ |
mutex_init(&ctx_lock, MUTEX_DEFAULT, IPL_SCHED); |
|
ci->c_pmap = pmap_kernel(); |
ci->c_pmap = pmap_kernel(); |
ctx_freelist = ci + 1; |
ctx_freelist = ci + 1; |
for (i = 1; i < ncontext; i++) { |
for (i = 1; i < ncontext; i++) { |
Line 3775 pmap_bootstrap4m(void *top) |
|
Line 3762 pmap_bootstrap4m(void *top) |
|
*/ |
*/ |
int size = pagetables_end - pagetables_start; |
int size = pagetables_end - pagetables_start; |
if (CACHEINFO.c_vactype != VAC_NONE) { |
if (CACHEINFO.c_vactype != VAC_NONE) { |
vaddr_t va = (vaddr_t)pagetables_start; |
va = (vaddr_t)pagetables_start; |
while (size > 0) { |
while (size > 0) { |
cache_flush_page(va, 0); |
cache_flush_page(va, 0); |
va += NBPG; |
va += NBPG; |
Line 3795 pmap_bootstrap4m(void *top) |
|
Line 3782 pmap_bootstrap4m(void *top) |
|
* Now switch to kernel pagetables (finally!) |
* Now switch to kernel pagetables (finally!) |
*/ |
*/ |
mmu_install_tables(&cpuinfo); |
mmu_install_tables(&cpuinfo); |
|
|
|
#ifdef MULTIPROCESSOR |
|
/* Allocate VA for all the cpu_info structurs */ |
|
cpus = (union cpu_info_pg*)uvm_km_alloc(kernel_map, |
|
sizeof cpus[sparc_ncpus], 32*1024, UVM_KMF_VAONLY); |
|
/* |
|
* Add an alias mapping for the CPUINFO_VA allocation created |
|
* early during bootstrap for the first CPU |
|
*/ |
|
off = 0; |
|
for (va = (vaddr_t)&cpus[0].ci; |
|
off < sizeof(struct cpu_info); |
|
va += NBPG, off += NBPG) { |
|
paddr_t pa = PMAP_BOOTSTRAP_VA2PA(CPUINFO_VA + off); |
|
pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); |
|
} |
|
/* |
|
* Now allocate memory for all other CPUs cpu_info and map |
|
* it into the coresponding space in the cpus array. We will |
|
* later duplicate the mapping into CPUINFO_VA. |
|
*/ |
|
for (i = 1; i < sparc_ncpus; i++) { |
|
off = 0; |
|
for (va = (vaddr_t)&cpus[i].ci; |
|
off < sizeof(struct cpu_info); |
|
va += NBPG, off += NBPG) { |
|
pg = uvm_pagealloc(NULL, 0, NULL, 0); |
|
paddr_t pa = VM_PAGE_TO_PHYS(pg); |
|
pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); |
|
} |
|
} |
|
|
|
/* clear new cpu infos */ |
|
prom_printf("clearing other cpus cpu info\n"); |
|
memset(&cpus[1].ci, 0, (sparc_ncpus-1)*sizeof(union cpu_info_pg)); |
|
|
|
/* setup self refernces, and cpu "cpuinfo" */ |
|
prom_printf("setting cpus self reference and mapping\n"); |
|
for (i = 0; i < sparc_ncpus; i++) { |
|
|
|
prom_printf("going to set cpu%d ci_self address: %p\n", i, &cpus[i].ci); |
|
cpus[i].ci.ci_self = &cpus[i].ci; |
|
|
|
/* mapped above. */ |
|
if (i == 0) |
|
continue; |
|
|
|
off = 0; |
|
for (va = (vaddr_t)&cpus[i].ci; |
|
off < sizeof(struct cpu_info); |
|
va += NBPG, off += NBPG) { |
|
paddr_t pa = PMAP_BOOTSTRAP_VA2PA(va + off); |
|
prom_printf("going to pmap_kenter_pa(va=%p, pa=%p)\n", va, pa); |
|
pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); |
|
} |
|
} |
|
#endif |
|
pmap_update(pmap_kernel()); |
} |
} |
|
|
static u_long prom_ctxreg; |
static u_long prom_ctxreg; |
Line 3804 mmu_install_tables(struct cpu_info *sc) |
|
Line 3849 mmu_install_tables(struct cpu_info *sc) |
|
{ |
{ |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
printf("pmap_bootstrap: installing kernel page tables..."); |
prom_printf("pmap_bootstrap: installing kernel page tables..."); |
#endif |
#endif |
setcontext4m(0); /* paranoia? %%%: Make 0x3 a define! below */ |
setcontext4m(0); /* paranoia? %%%: Make 0x3 a define! below */ |
|
|
Line 3821 mmu_install_tables(struct cpu_info *sc) |
|
Line 3866 mmu_install_tables(struct cpu_info *sc) |
|
tlb_flush_all_real(); |
tlb_flush_all_real(); |
|
|
#ifdef DEBUG |
#ifdef DEBUG |
printf("done.\n"); |
prom_printf("done.\n"); |
#endif |
#endif |
} |
} |
|
|
Line 3839 srmmu_restore_prom_ctx(void) |
|
Line 3884 srmmu_restore_prom_ctx(void) |
|
|
|
#if defined(MULTIPROCESSOR) |
#if defined(MULTIPROCESSOR) |
/* |
/* |
* Globalize the boot CPU's cpu_info structure. |
|
*/ |
|
void |
|
pmap_globalize_boot_cpuinfo(struct cpu_info *cpi) |
|
{ |
|
vaddr_t va; |
|
vsize_t off; |
|
|
|
off = 0; |
|
for (va = (vaddr_t)cpi; off < sizeof(*cpi); va += NBPG, off += NBPG) { |
|
paddr_t pa = PMAP_BOOTSTRAP_VA2PA(CPUINFO_VA + off); |
|
pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE); |
|
} |
|
pmap_update(pmap_kernel()); |
|
} |
|
|
|
/* |
|
* Allocate per-CPU page tables. One region, segment and page table |
* Allocate per-CPU page tables. One region, segment and page table |
* is needed to map CPUINFO_VA to different physical addresses on |
* is needed to map CPUINFO_VA to different physical addresses on |
* each CPU. Since the kernel region and segment tables are all |
* each CPU. Since the kernel region and segment tables are all |
Line 4085 pmap_quiet_check(struct pmap *pm) |
|
Line 4113 pmap_quiet_check(struct pmap *pm) |
|
n = 0; |
n = 0; |
#endif |
#endif |
{ |
{ |
#if defined(MULTIPROCESSOR) |
|
if (cpus[n] == NULL) |
|
continue; |
|
#endif |
|
if (pm->pm_reg_ptps[n][vr] != SRMMU_TEINVALID) |
if (pm->pm_reg_ptps[n][vr] != SRMMU_TEINVALID) |
printf("pmap_chk: spurious PTP in user " |
printf("pmap_chk: spurious PTP in user " |
"region %d on CPU %d\n", vr, n); |
"region %d on CPU %d\n", vr, n); |
Line 4202 pmap_pmap_pool_ctor(void *arg, void *obj |
|
Line 4226 pmap_pmap_pool_ctor(void *arg, void *obj |
|
{ |
{ |
int *upt, *kpt; |
int *upt, *kpt; |
|
|
#if defined(MULTIPROCESSOR) |
|
if (cpus[n] == NULL) |
|
continue; |
|
#endif |
|
upt = pool_get(&L1_pool, flags); |
upt = pool_get(&L1_pool, flags); |
pm->pm_reg_ptps[n] = upt; |
pm->pm_reg_ptps[n] = upt; |
pm->pm_reg_ptps_pa[n] = VA2PA((char *)upt); |
pm->pm_reg_ptps_pa[n] = VA2PA((char *)upt); |
Line 4256 pmap_pmap_pool_dtor(void *arg, void *obj |
|
Line 4276 pmap_pmap_pool_dtor(void *arg, void *obj |
|
n = 0; |
n = 0; |
#endif |
#endif |
{ |
{ |
#if defined(MULTIPROCESSOR) |
|
if (cpus[n] == NULL) |
|
continue; |
|
#endif |
|
int *pt = pm->pm_reg_ptps[n]; |
int *pt = pm->pm_reg_ptps[n]; |
pm->pm_reg_ptps[n] = NULL; |
pm->pm_reg_ptps[n] = NULL; |
pm->pm_reg_ptps_pa[n] = 0; |
pm->pm_reg_ptps_pa[n] = 0; |
Line 4435 pgt_lvl23_remove4m(struct pmap *pm, stru |
|
Line 4451 pgt_lvl23_remove4m(struct pmap *pm, stru |
|
#ifdef MULTIPROCESSOR |
#ifdef MULTIPROCESSOR |
/* Invalidate level 1 PTP entries on all CPUs */ |
/* Invalidate level 1 PTP entries on all CPUs */ |
for (; n < sparc_ncpus; n++) { |
for (; n < sparc_ncpus; n++) { |
if (cpus[n] == NULL) |
if ((cpus[n].ci.flags & CPUFLG_HATCHED) == 0) |
continue; |
continue; |
#endif |
#endif |
setpgt4m(&pm->pm_reg_ptps[n][vr], SRMMU_TEINVALID); |
setpgt4m(&pm->pm_reg_ptps[n][vr], SRMMU_TEINVALID); |
Line 6272 pmap_enu4m(struct pmap *pm, vaddr_t va, |
|
Line 6288 pmap_enu4m(struct pmap *pm, vaddr_t va, |
|
#endif |
#endif |
{ |
{ |
#if defined(MULTIPROCESSOR) |
#if defined(MULTIPROCESSOR) |
if (cpus[i] == NULL) |
if ((cpus[i].ci.flags & CPUFLG_HATCHED) == 0) |
continue; |
continue; |
#endif |
#endif |
setpgt4m(&pm->pm_reg_ptps[i][vr], |
setpgt4m(&pm->pm_reg_ptps[i][vr], |