patch-2.1.127 linux/arch/sparc64/mm/init.c
Next file: linux/arch/sparc64/mm/ultra.S
Previous file: linux/arch/sparc64/mm/fault.c
Back to the patch index
Back to the overall index
- Lines: 278
- Date:
Tue Oct 27 09:52:21 1998
- Orig file:
v2.1.126/linux/arch/sparc64/mm/init.c
- Orig date:
Mon Oct 5 13:13:38 1998
diff -u --recursive --new-file v2.1.126/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.98 1998/09/28 06:18:39 davem Exp $
+/* $Id: init.c,v 1.103 1998/10/20 03:09:12 jj Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -45,7 +45,6 @@
int do_check_pgt_cache(int low, int high)
{
- struct page *page, *page2;
int freed = 0;
if(pgtable_cache_size > high) {
@@ -60,6 +59,7 @@
}
#ifndef __SMP__
if (pgd_cache_size > high / 4) {
+ struct page *page, *page2;
for (page2 = NULL, page = (struct page *)pgd_quicklist; page;) {
if ((unsigned long)page->pprev_hash == 3) {
if (page2)
@@ -537,7 +537,7 @@
if (pgd_none(*pgdp)) {
pmdp = sparc_init_alloc(&mempool,
PMD_TABLE_SIZE);
- clear_page(pmdp);
+ memset(pmdp, 0, PAGE_SIZE);
pgd_set(pgdp, pmdp);
}
pmdp = pmd_offset(pgdp, vaddr);
@@ -591,12 +591,17 @@
}
static int prom_ditlb_set = 0;
-int prom_itlb_ent, prom_dtlb_ent;
-unsigned long prom_itlb_tag, prom_itlb_data;
-unsigned long prom_dtlb_tag, prom_dtlb_data;
+struct prom_tlb_entry {
+ int tlb_ent;
+ unsigned long tlb_tag;
+ unsigned long tlb_data;
+};
+struct prom_tlb_entry prom_itlb[8], prom_dtlb[8];
void prom_world(int enter)
{
+ int i;
+
if (!prom_ditlb_set)
return;
if (enter) {
@@ -604,29 +609,44 @@
__flush_nucleus_vptes();
/* Install PROM world. */
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (prom_dtlb_tag), "r" (TLB_TAG_ACCESS),
+ for (i = 0; i < 8; i++) {
+ if (prom_dtlb[i].tlb_ent != -1) {
+ __asm__ __volatile__("stxa %0, [%1] %2"
+ : : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
"i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(62, prom_dtlb_data);
- membar("#Sync");
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (prom_itlb_tag), "r" (TLB_TAG_ACCESS),
+ membar("#Sync");
+ spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
+ prom_dtlb[i].tlb_data);
+ membar("#Sync");
+ }
+
+ if (prom_itlb[i].tlb_ent != -1) {
+ __asm__ __volatile__("stxa %0, [%1] %2"
+ : : "r" (prom_itlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
"i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(62, prom_itlb_data);
- membar("#Sync");
+ membar("#Sync");
+ spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
+ prom_itlb[i].tlb_data);
+ membar("#Sync");
+ }
+ }
} else {
- __asm__ __volatile__("stxa %%g0, [%0] %1"
+ for (i = 0; i < 8; i++) {
+ if (prom_dtlb[i].tlb_ent != -1) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1"
: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(62, 0x0UL);
- membar("#Sync");
- __asm__ __volatile__("stxa %%g0, [%0] %1"
+ membar("#Sync");
+ spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent, 0x0UL);
+ membar("#Sync");
+ }
+ if (prom_itlb[i].tlb_ent != -1) {
+ __asm__ __volatile__("stxa %%g0, [%0] %1"
: : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(62, 0x0UL);
- membar("#Sync");
+ membar("#Sync");
+ spitfire_put_itlb_data(prom_itlb[i].tlb_ent, 0x0UL);
+ membar("#Sync");
+ }
+ }
}
}
@@ -640,8 +660,8 @@
* it (conveniently) fails to mention any of these in the
* translations property. The only ones that matter are
* the locked PROM tlb entries, so we impose the following
- * irrecovable rule on the PROM, it is allowed 1 locked
- * entry in the ITLB and 1 in the DTLB.
+ * irrecovable rule on the PROM, it is allowed 8 locked
+ * entries in the ITLB and 8 in the DTLB.
*
* Supposedly the upper 16GB of the address space is
* reserved for OBP, BUT I WISH THIS WAS DOCUMENTED
@@ -650,17 +670,23 @@
* systems to coordinate mmu mappings is also COMPLETELY
* UNDOCUMENTED!!!!!! Thanks S(t)un!
*/
+ if (save_p) {
+ for(i = 0; i < 8; i++) {
+ prom_dtlb[i].tlb_ent = -1;
+ prom_itlb[i].tlb_ent = -1;
+ }
+ }
for(i = 0; i < 63; i++) {
unsigned long data;
data = spitfire_get_dtlb_data(i);
- if(!dtlb_seen && (data & _PAGE_L)) {
+ if(data & _PAGE_L) {
unsigned long tag = spitfire_get_dtlb_tag(i);
if(save_p) {
- prom_dtlb_ent = i;
- prom_dtlb_tag = tag;
- prom_dtlb_data = data;
+ prom_dtlb[dtlb_seen].tlb_ent = i;
+ prom_dtlb[dtlb_seen].tlb_tag = tag;
+ prom_dtlb[dtlb_seen].tlb_data = data;
}
__asm__ __volatile__("stxa %%g0, [%0] %1"
: : "r" (TLB_TAG_ACCESS), "i" (ASI_DMMU));
@@ -668,18 +694,22 @@
spitfire_put_dtlb_data(i, 0x0UL);
membar("#Sync");
- dtlb_seen = 1;
- if(itlb_seen)
+ dtlb_seen++;
+ if(dtlb_seen > 7)
break;
}
+ }
+ for(i = 0; i < 63; i++) {
+ unsigned long data;
+
data = spitfire_get_itlb_data(i);
- if(!itlb_seen && (data & _PAGE_L)) {
+ if(data & _PAGE_L) {
unsigned long tag = spitfire_get_itlb_tag(i);
if(save_p) {
- prom_itlb_ent = i;
- prom_itlb_tag = tag;
- prom_itlb_data = data;
+ prom_itlb[itlb_seen].tlb_ent = i;
+ prom_itlb[itlb_seen].tlb_tag = tag;
+ prom_itlb[itlb_seen].tlb_data = data;
}
__asm__ __volatile__("stxa %%g0, [%0] %1"
: : "r" (TLB_TAG_ACCESS), "i" (ASI_IMMU));
@@ -687,15 +717,8 @@
spitfire_put_itlb_data(i, 0x0UL);
membar("#Sync");
- /* Re-install it. */
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (tag), "r" (TLB_TAG_ACCESS),
- "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(62, data);
- membar("#Sync");
- itlb_seen = 1;
- if(dtlb_seen)
+ itlb_seen++;
+ if(itlb_seen > 7)
break;
}
}
@@ -706,19 +729,29 @@
/* Give PROM back his world, done during reboots... */
void prom_reload_locked(void)
{
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (prom_dtlb_tag), "r" (TLB_TAG_ACCESS),
- "i" (ASI_DMMU));
- membar("#Sync");
- spitfire_put_dtlb_data(prom_dtlb_ent, prom_dtlb_data);
- membar("#Sync");
-
- __asm__ __volatile__("stxa %0, [%1] %2"
- : : "r" (prom_itlb_tag), "r" (TLB_TAG_ACCESS),
- "i" (ASI_IMMU));
- membar("#Sync");
- spitfire_put_itlb_data(prom_itlb_ent, prom_itlb_data);
- membar("#Sync");
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (prom_dtlb[i].tlb_ent != -1) {
+ __asm__ __volatile__("stxa %0, [%1] %2"
+ : : "r" (prom_dtlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
+ "i" (ASI_DMMU));
+ membar("#Sync");
+ spitfire_put_dtlb_data(prom_dtlb[i].tlb_ent,
+ prom_dtlb[i].tlb_data);
+ membar("#Sync");
+ }
+
+ if (prom_itlb[i].tlb_ent != -1) {
+ __asm__ __volatile__("stxa %0, [%1] %2"
+ : : "r" (prom_itlb[i].tlb_tag), "r" (TLB_TAG_ACCESS),
+ "i" (ASI_IMMU));
+ membar("#Sync");
+ spitfire_put_itlb_data(prom_itlb[i].tlb_ent,
+ prom_itlb[i].tlb_data);
+ membar("#Sync");
+ }
+ }
}
void __flush_dcache_range(unsigned long start, unsigned long end)
@@ -844,7 +877,7 @@
pmd = (pmd_t *) __get_free_page(GFP_DMA|GFP_KERNEL);
if(pmd) {
- clear_page(pmd);
+ memset(pmd, 0, PAGE_SIZE);
pgd_set(pgd, pmd);
return pmd + offset;
}
@@ -857,7 +890,7 @@
pte = (pte_t *) __get_free_page(GFP_DMA|GFP_KERNEL);
if(pte) {
- clear_page(pte);
+ memset(pte, 0, PAGE_SIZE);
pmd_set(pmd, pte);
return pte + offset;
}
@@ -875,13 +908,13 @@
pgdp = pgd_offset(init_task.mm, start);
if (pgd_none(*pgdp)) {
pmdp = sparc_init_alloc(&mempool, PAGE_SIZE);
- clear_page(pmdp);
+ memset(pmdp, 0, PAGE_SIZE);
pgd_set(pgdp, pmdp);
}
pmdp = pmd_offset(pgdp, start);
if (pmd_none(*pmdp)) {
ptep = sparc_init_alloc(&mempool, PAGE_SIZE);
- clear_page(ptep);
+ memset(ptep, 0, PAGE_SIZE);
pmd_set(pmdp, ptep);
}
start = (start + PMD_SIZE) & PMD_MASK;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov