summaryrefslogtreecommitdiffstats
path: root/arch/mips/mm/init.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /arch/mips/mm/init.c
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff)
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'arch/mips/mm/init.c')
-rw-r--r--arch/mips/mm/init.c123
1 files changed, 35 insertions, 88 deletions
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8bdbffaf8..f7fa99a37 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.8 1998/09/04 21:21:34 ralf Exp $
+/* $Id: init.c,v 1.9 1998/09/19 19:16:18 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -33,13 +33,8 @@
#ifdef CONFIG_SGI
#include <asm/sgialib.h>
#endif
+#include <asm/mmu_context.h>
-/*
- * Define this to effectivly disable the userpage colouring shit.
- */
-#define CONF_GIVE_A_SHIT_ABOUT_COLOURS
-
-extern void deskstation_tyne_dma_init(void);
extern void show_net_buffers(void);
void __bad_pte_kernel(pmd_t *pmd)
@@ -58,7 +53,7 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
{
pte_t *page;
- page = (pte_t *) __get_free_page(GFP_KERNEL);
+ page = (pte_t *) __get_free_page(GFP_USER);
if (pmd_none(*pmd)) {
if (page) {
clear_page((unsigned long)page);
@@ -243,83 +238,6 @@ pte_t __bad_page(void)
return pte_mkdirty(mk_pte(page, PAGE_SHARED));
}
-#ifdef __SMP__
-spinlock_t user_page_lock = SPIN_LOCK_UNLOCKED;
-#endif
-struct upcache user_page_cache[8] __attribute__((aligned(32)));
-static unsigned long user_page_order;
-unsigned long user_page_colours;
-
-unsigned long get_user_page_slow(int which)
-{
- unsigned long chunk;
- struct upcache *up = &user_page_cache[0];
- struct page *p, *res;
- int i;
-
- do {
- chunk = __get_free_pages(GFP_KERNEL, user_page_order);
- } while(chunk==0);
-
- p = mem_map + MAP_NR(chunk);
- res = p + which;
- spin_lock(&user_page_lock);
- for (i=user_page_colours; i>=0; i--,p++,up++,chunk+=PAGE_SIZE) {
- atomic_set(&p->count, 1);
- p->age = PAGE_INITIAL_AGE;
-
- if (p != res) {
- if(up->count < USER_PAGE_WATER) {
- p->next = up->list;
- up->list = p;
- up->count++;
- } else
- free_pages(chunk, 0);
- }
- }
- spin_unlock(&user_page_lock);
-
- return page_address(res);
-}
-
-static inline void user_page_setup(void)
-{
- unsigned long assoc = 0;
- unsigned long dcache_log, icache_log, cache_log;
- unsigned long config = read_32bit_cp0_register(CP0_CONFIG);
-
- switch(mips_cputype) {
- case CPU_R4000SC:
- case CPU_R4000MC:
- case CPU_R4400SC:
- case CPU_R4400MC:
- cache_log = 3; /* => 32k, sucks */
- break;
-
- case CPU_R4600: /* two way set associative caches? */
- case CPU_R4700:
- case CPU_R5000:
- case CPU_NEVADA:
- assoc = 1;
- /* fall through */
- default:
- /* use bigger cache */
- icache_log = (config >> 9) & 7;
- dcache_log = (config >> 6) & 7;
- if (dcache_log > icache_log)
- cache_log = dcache_log;
- else
- cache_log = icache_log;
- }
-
-#ifdef CONF_GIVE_A_SHIT_ABOUT_COLOURS
- cache_log = assoc = 0;
-#endif
-
- user_page_order = cache_log - assoc;
- user_page_colours = (1 << (cache_log - assoc)) - 1;
-}
-
void show_mem(void)
{
int i, free = 0, total = 0, reserved = 0;
@@ -423,9 +341,6 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
max_mapnr << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10));
-
- /* Initialize allocator for colour matched mapped pages. */
- user_page_setup();
}
extern char __init_begin, __init_end;
@@ -465,3 +380,35 @@ void si_meminfo(struct sysinfo *val)
val->sharedram <<= PAGE_SHIFT;
return;
}
+
+/* Fixup an immediate instruction */
+__initfunc(static void __i_insn_fixup(unsigned int **start, unsigned int **stop,
+ unsigned int i_const))
+{
+ unsigned int **p, *ip;
+
+ for (p = start;p < stop; p++) {
+ ip = *p;
+ *ip = (*ip & 0xffff0000) | i_const;
+ }
+}
+
+#define i_insn_fixup(section, const) \
+do { \
+ extern unsigned int *__start_ ## section; \
+ extern unsigned int *__stop_ ## section; \
+ __i_insn_fixup(&__start_ ## section, &__stop_ ## section, const); \
+} while(0)
+
+/* Caller is assumed to flush the caches before the first context switch. */
+__initfunc(void __asid_setup(unsigned int inc, unsigned int mask,
+ unsigned int version_mask,
+ unsigned int first_version))
+{
+ i_insn_fixup(__asid_inc, inc);
+ i_insn_fixup(__asid_mask, mask);
+ i_insn_fixup(__asid_version_mask, version_mask);
+ i_insn_fixup(__asid_first_version, first_version);
+
+ asid_cache = first_version;
+}