64K page size
PATCH 1/1 64K page size
Hello,
Attached is the rest of the 64K page patch. It's been tested uniprocessor on Malta 20KC and 25KF. It also runs on a 6-way SMP functional simulator containing 5KF's. Ran tests with 16K and 64K page size.
Question: Is there an SMP malta board?
There are 2 areas which could use improvement:
(1) Because 64K is larger than a 15 bit immediate operand, I could not get the asm-offsets mechanism to produce the correct constants. So I enlisted a fairly gruesome hack of using #define's for _PAGE_SIZE and _THREAD_SIZE, for that page size. Hopefully someone has a better idea.
(2) In tlbex.c:build_adjust_context(), I suspect the change for shift = PAGE_SHIFT - 12 should be more generally true, rather than just for the CPU's mentioned in the case statement. I was conservative there because I'm not familiar with the CPU_VR41* machines. Hopefully someone more intimate with that code can comment.
arch/mips/kernel/asm-offsets.c +6 -0
@@ -99,7 +99,10 @@ void output_thread_info_defines(void) offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); offset("#define TI_TP_VALUE ", struct thread_info, tp_value);constant ("#define _THREAD_SIZE_ORDER " ,THREAD_SIZE_ORDER ); +#ifndef CONFIG_PAGE_SIZE_64KB +/* See comment in page.h */ constant ("#define _THREAD_SIZE " ,THREAD_SIZE ); +#endif constant ("#define _THREAD_MASK " ,THREAD_MASK ); linefeed; }
@@ -219,7 +222,10 @@ void output_mm_defines(void) offset("#define MM_PGD ", struct mm_struct, pgd); offset("#define MM_CONTEXT ", struct mm_struct, context); linefeed; +#ifndef CONFIG_PAGE_SIZE_64KB +/* See comment in page.h */ constant ("#define _PAGE_SIZE " ,PAGE_SIZE ); +#endif constant ("#define _PAGE_SHIFT " ,PAGE_SHIFT ); linefeed;constant ("#define _PGD_T_SIZE " ,sizeof (pgd_t));
arch/mips/kernel/head.S +5 -0
@@ -190,7 +190,12 @@ #endif /* CONFIG_MIPS_MT_SMTC */ MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union +#ifdef CONFIG_PAGE_SIZE_64KB + PTR_ADDIU sp, $28, (_THREAD_SIZE - 32)/2 + PTR_ADDIU sp, sp, (_THREAD_SIZE - 32)/2 +#else PTR_ADDIU sp, $28, _THREAD_SIZE - 32 +#endif set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer
arch/mips/kernel/r4k_switch.S +5 -0
@@ -85,7 +85,12 @@ #endif move $28, a2 cpu_restore_nonscratch a1 +#ifdef CONFIG_PAGE_SIZE_64KB + PTR_ADDIU t0, $28, (_THREAD_SIZE - 32)/2 + PTR_ADDIU t0, t0, (_THREAD_SIZE - 32)/2 +#else PTR_ADDIU t0, $28, _THREAD_SIZE - 32 +#endif set_saved_sp t0, t1, t2 #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-writes of Status must be atomic on a VPE */
arch/mips/kernel/vmlinux.lds.S +5 -0
@@ -1,6 +1,10 @@ #include <asm/asm-offsets.h> #include <asm-generic/vmlinux.lds.h> +#ifdef CONFIG_PAGE_SIZE_64KB +#define _PAGE_SIZE 0x10000 +#endif + #undef mips #define mips mips OUTPUT_ARCH(mips)
@@ -50,6 +54,7 @@ #endif /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + . = ALIGN(_PAGE_SIZE); *(.data.init_task) *(.data)
arch/mips/lib-64/dump_tlb.c +1 -1
@@ -147,7 +147,7 @@ void dump_list_process(struct task_strucprintk ("Addr == %08lx\n" , addr);printk ("tasks->mm.pgd == %08lx\n" , (unsigned long ) t->mm->pgd); - page_dir =pgd_offset (t->mm,0 ); + page_dir =pgd_offset (t->mm,0UL );printk ("page_dir == %016lx\n" , (unsigned long ) page_dir); pgd =pgd_offset (t->mm, addr);
arch/mips/mips-boards/generic/memory.c +1 -1
@@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memoif (boot_mem_map.map[i].type !=BOOT_MEM_ROM_DATA )continue ; - addr = boot_mem_map.map[i].addr; + addr =PAGE_ALIGN (boot_mem_map.map[i].addr);while (addr < boot_mem_map.map[i].addr + boot_mem_map.map[i].size) {ClearPageReserved (virt_to_page (__va (addr)));
arch/mips/mm/pg-r4k.c +30 -2
@@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsemit_instruction (mi); } +static inline void build_addiu_a2 (unsigned long offset) +{ +union mips_instruction mi; + +BUG_ON (offset >0x7fff ); + + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; + mi.i_format.rs =6 ;/* $a2 */ + mi.i_format.rt =6 ;/* $a2 */ + mi.i_format.simmediate = offset; + +emit_instruction (mi); +} +static inline void build_addiu_a1 (unsigned long offset) {union mips_instruction mi;
@@ -369,7 +383,14 @@ void __init build_clear_page(void) } } -build_addiu_a2_a0 (PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear :0 )); +unsigned long off =PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear :0 ); +if (off >0x7fff ) { +build_addiu_a2_a0 (off>>1 ); +build_addiu_a2 (off>>1 ); + } +else { +build_addiu_a2_a0 (off); + }if (R4600_V2_HIT_CACHEOP_WAR &&cpu_is_r4600_v2_x ())build_insn_word (0x3c01a000 );/* lui $at, 0xa000 */
@@ -425,7 +446,14 @@ void __init build_copy_page(void) store_offset = load_offset =0 ; instruction_pending =0 ; -build_addiu_a2_a0 (PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy :0 )); +unsigned long off =PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy :0 ); +if (off >0x7fff ) { +build_addiu_a2_a0 (off>>1 ); +build_addiu_a2 (off>>1 ); + } +else { +build_addiu_a2_a0 (off); + }if (R4600_V2_HIT_CACHEOP_WAR &&cpu_is_r4600_v2_x ())build_insn_word (0x3c01a000 );/* lui $at, 0xa000 */
arch/mips/mm/tlbex.c +17 -2
@@ -97,6 +97,8 @@ #define FUNC_SH 0#define SET_MASK 0x7#define SET_SH 0 +#define OP_ERET 0x42000018 +enum opcode { insn_invalid, insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
@@ -631,6 +633,9 @@ static __init void copy_handler(struct rstatic __init int __attribute__((unused))insn_has_bdelay (struct reloc *rel,u32 *addr) { +if (*addr ==OP_ERET ) +return 1 ; +for (; rel->lab != label_invalid; rel++) { if (rel->addr == addr && (rel->type == R_MIPS_PC16
@@ -996,7 +1001,12 @@ #else#endif l_vmalloc_done (l, *p); -i_dsrl (p, tmp, tmp,PGDIR_SHIFT -3 );/* get pgd offset in bytes */ + +/* Want PGDIR_SHIFT-3 here, but break it into two ops so we don't +* exceed the max shift amount of 31 with large page sizes. */ +i_dsrl (p, tmp, tmp,PGDIR_SHIFT -16 );/* get pgd offset in bytes */ +i_dsrl (p, tmp, tmp,16 -3 );/* get pgd offset in bytes */ +i_andi (p, tmp, tmp, (PTRS_PER_PGD -1 )<<3 );i_daddu (p, ptr, ptr, tmp);/* add in pgd offset */ i_dmfc0 (p, tmp,C0_BADVADDR );/* get faulting address */
@@ -1087,6 +1097,11 @@ static __init void build_adjust_context(case CPU_VR4133 : shift +=2 ;break ; +case CPU_20KC : +case CPU_25KF : +case CPU_5KC : + shift =PAGE_SHIFT -12 ; +break ;default :break ;
@@ -1811,7 +1826,7 @@ void __init build_tlb_refill_handler(voidefault :build_r4000_tlb_refill_handler ();if (!run_once) { -build_r4000_tlb_load_handler (); +build_r4000_tlb_load_handler ();build_r4000_tlb_store_handler ();build_r4000_tlb_modify_handler (); run_once++;
include/asm-mips/page.h +8 -0
@@ -34,6 +34,14 @@ #endif#define PAGE_SIZE (1UL << PAGE_SHIFT)#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +/* +* Since asm-offsets.c does not work for more than 15 bit values, +* we defines these here. +*/ +#ifdef CONFIG_PAGE_SIZE_64KB +#define _PAGE_SIZE 0x10000 +#define _THREAD_SIZE 0x10000 +#endif #ifdef __KERNEL__#ifndef __ASSEMBLY__
include/asm-mips/pgalloc.h +1 -1
@@ -48,7 +48,7 @@ static inline pgd_t *pgd_alloc(struct mm ret = (pgd_t *)__get_free_pages (GFP_KERNEL ,PGD_ORDER );if (ret) { - init =pgd_offset (&init_mm,0 ); + init =pgd_offset (&init_mm,0UL );pgd_init ((unsigned long )ret);memcpy (ret +USER_PTRS_PER_PGD , init +USER_PTRS_PER_PGD , (PTRS_PER_PGD -USER_PTRS_PER_PGD ) *sizeof (pgd_t));
include/asm-mips/pgtable-64.h +1 -1
@@ -174,7 +174,7 @@ #define __pud_offset(address) (((address#define __pmd_offset (address) pmd_index(address)/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k (address) pgd_offset(&init_mm, 0) +#define pgd_offset_k (address) pgd_offset(&init_mm, 0UL)#define pgd_index (address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))#define pmd_index (address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
Quoted 1 line · Peter Watkins
Question: Is there an SMP malta board?
A CoreFPGA 2 or 3 card with a 34K bitfile is as close as you can get. The 34K would run either run a VSMP kernel which is a hyperthreading-like dual-processor kernel or an SMTC kernel which is uses the 34K's fancier multithreading features to implement upto 5 processors.
Of course the CoreFPGA cards being an FPGA CPU card allows you to roll your own stuff ;-)
Ralf
Quoted 8 lines · Peter Watkins
Hello,
Attached is the rest of the 64K page patch. It's been tested uniprocessor on Malta 20KC and 25KF. It also runs on a 6-way SMP functional simulator containing 5KF's. Ran tests with 16K and 64K page size.
Question: Is there an SMP malta board?
You mean a SMP core card? None I heard of.
Quoted 10 lines
There are 2 areas which could use improvement:
(1) Because 64K is larger than a 15 bit immediate operand, I could not get the asm-offsets mechanism to produce the correct constants. So I enlisted a fairly gruesome hack of using #define's for
_PAGE_SIZEand_THREAD_SIZE, for that page size. Hopefully someone has a better idea.(2) In tlbex.c:build_adjust_context(), I suspect the change for shift =
PAGE_SHIFT- 12 should be more generally true, rather than just for the CPU's mentioned in the case statement.
It should be added to the initial shift calculation instead, i suspect it will break 32bit kernels elsewise. It should be generally the same for all CPUs with r4k-style TLBs.
Quoted 3 lines
I was conservative there because
I'm not familiar with the CPU_VR41* machines. Hopefully someone more intimate with that code can comment.
The vr41xx has a different/broken page mask in order to support 1k pages (which aren't used by linux). The shift += 2 fixes this up.
[snip]
arch/mips/kernel/head.S #endif /* CONFIG_MIPS_MT_SMTC */ · line 198
Quoted 13 lines
index c06f63e..c9de17c 100644
arch/mips/kernel/head.S +5
-0@@ -190,7 +190,12 @@ #endif /* CONFIG_MIPS_MT_SMTC */ MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union +#ifdef CONFIG_PAGE_SIZE_64KB + PTR_ADDIU sp, $28, (_THREAD_SIZE - 32)/2 + PTR_ADDIU sp, sp, (_THREAD_SIZE - 32)/2 +#else PTR_ADDIU sp, $28, _THREAD_SIZE - 32 +#endif
A PTR_LI ... ; PTR_ADDU sequence would be better, without an #ifdef. This isn't a critical path of execution, and one day we might go for even bigger pagesizes. Likewise for the other doubled addiu in this patch.
[snip]
Quoted 14 lines
arch/mips/mm/tlbex.c +2
-0@@ -97,6 +97,8 @@ #define FUNC_SH 0#define SET_MASK 0x7#define SET_SH 0 +#define OP_ERET 0x42000018 +enum opcode { insn_invalid, insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
arch/mips/mm/tlbex.c static __init void copy_handler(struct r · line 638
Quoted 6 lines
arch/mips/mm/tlbex.c +3
-0@@ -631,6 +633,9 @@ static __init void copy_handler(struct rstatic __init int __attribute__((unused))insn_has_bdelay (struct reloc *rel,u32 *addr) { +if (*addr ==OP_ERET ) +return 1 ; +
Why? Eret has no BD slot.
arch/mips/mm/tlbex.c #else · line 1008
Quoted 13 lines
arch/mips/mm/tlbex.c +5
-1for (; rel->lab != label_invalid; rel++) { if (rel->addr == addr && (rel->type == R_MIPS_PC16@@ -996,7 +1001,12 @@ #else#endif l_vmalloc_done (l, *p); -i_dsrl (p, tmp, tmp,PGDIR_SHIFT -3 );/* get pgd offset in bytes */ + +/* Want PGDIR_SHIFT-3 here, but break it into two ops so we don't +* exceed the max shift amount of 31 with large page sizes. */ +i_dsrl (p, tmp, tmp,PGDIR_SHIFT -16 );/* get pgd offset in bytes */ +i_dsrl (p, tmp, tmp,16 -3 );/* get pgd offset in bytes */
This cries for a single i_dsrl32 for the large page case.
arch/mips/mm/tlbex.c static __init void build_adjust_context( · line 1104
Quoted 13 lines
arch/mips/mm/tlbex.c +6
-0+i_andi (p, tmp, tmp, (PTRS_PER_PGD -1 )<<3 );i_daddu (p, ptr, ptr, tmp);/* add in pgd offset */ i_dmfc0 (p, tmp,C0_BADVADDR );/* get faulting address */ @@ -1087,6 +1097,11 @@ static __init void build_adjust_context(case CPU_VR4133 : shift +=2 ;break ; +case CPU_20KC : +case CPU_25KF : +case CPU_5KC : + shift =PAGE_SHIFT -12 ; +break ;
As said, should be done for all CPUs. (This will also fix the vr41xx case, just in case somebody is crazy enough to go for large pages on his PDA. :-)
Thiemo
Hello again,
This patch incorporates all of Thiemo's suggestions.
Basic retesting with 4K, 16K, and 64K pages on Malta 20KC and 25KF, and an SMP simulator.
FWIW, some of these changes are required to get 16K pages working.
- Peter
arch/mips/kernel/asm-offsets.c +6 -0
@@ -99,7 +99,10 @@ void output_thread_info_defines(void) offset("#define TI_RESTART_BLOCK ", struct thread_info, restart_block); offset("#define TI_TP_VALUE ", struct thread_info, tp_value);constant ("#define _THREAD_SIZE_ORDER " ,THREAD_SIZE_ORDER ); +#ifndef CONFIG_PAGE_SIZE_64KB +/* See comment in page.h */ constant ("#define _THREAD_SIZE " ,THREAD_SIZE ); +#endif constant ("#define _THREAD_MASK " ,THREAD_MASK ); linefeed; }
@@ -219,7 +222,10 @@ void output_mm_defines(void) offset("#define MM_PGD ", struct mm_struct, pgd); offset("#define MM_CONTEXT ", struct mm_struct, context); linefeed; +#ifndef CONFIG_PAGE_SIZE_64KB +/* See comment in page.h */ constant ("#define _PAGE_SIZE " ,PAGE_SIZE ); +#endif constant ("#define _PAGE_SHIFT " ,PAGE_SHIFT ); linefeed;constant ("#define _PGD_T_SIZE " ,sizeof (pgd_t));
arch/mips/kernel/head.S +2 -1
@@ -190,7 +190,8 @@ #endif /* CONFIG_MIPS_MT_SMTC */ MTC0 zero, CP0_CONTEXT # clear context register PTR_LA $28, init_thread_union - PTR_ADDIU sp, $28, _THREAD_SIZE - 32 + PTR_LI sp, _THREAD_SIZE - 32 + PTR_ADDU sp, $28 set_saved_sp sp, t0, t1 PTR_SUBU sp, 4 * SZREG # init stack pointer
arch/mips/kernel/r4k_switch.S +2 -1
@@ -85,7 +85,8 @@ #endif move $28, a2 cpu_restore_nonscratch a1 - PTR_ADDIU t0, $28, _THREAD_SIZE - 32 + PTR_LI t0, _THREAD_SIZE - 32 + PTR_ADDU t0, $28 set_saved_sp t0, t1, t2 #ifdef CONFIG_MIPS_MT_SMTC /* Read-modify-writes of Status must be atomic on a VPE */
arch/mips/kernel/vmlinux.lds.S +5 -0
@@ -1,6 +1,10 @@ #include <asm/asm-offsets.h> #include <asm-generic/vmlinux.lds.h> +#ifdef CONFIG_PAGE_SIZE_64KB +#define _PAGE_SIZE 0x10000 +#endif + #undef mips #define mips mips OUTPUT_ARCH(mips)
@@ -50,6 +54,7 @@ #endif /* writeable */ .data : { /* Data */ . = . + DATAOFFSET; /* for CONFIG_MAPPED_KERNEL */ + . = ALIGN(_PAGE_SIZE); *(.data.init_task) *(.data)
arch/mips/lib-64/dump_tlb.c +1 -1
@@ -147,7 +147,7 @@ void dump_list_process(struct task_strucprintk ("Addr == %08lx\n" , addr);printk ("tasks->mm.pgd == %08lx\n" , (unsigned long ) t->mm->pgd); - page_dir =pgd_offset (t->mm,0 ); + page_dir =pgd_offset (t->mm,0UL );printk ("page_dir == %016lx\n" , (unsigned long ) page_dir); pgd =pgd_offset (t->mm, addr);
arch/mips/mips-boards/generic/memory.c +1 -1
@@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memoif (boot_mem_map.map[i].type !=BOOT_MEM_ROM_DATA )continue ; - addr = boot_mem_map.map[i].addr; + addr =PAGE_ALIGN (boot_mem_map.map[i].addr);while (addr < boot_mem_map.map[i].addr + boot_mem_map.map[i].size) {ClearPageReserved (virt_to_page (__va (addr)));
arch/mips/mm/pg-r4k.c +30 -2
@@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(unsemit_instruction (mi); } +static inline void build_addiu_a2 (unsigned long offset) +{ +union mips_instruction mi; + +BUG_ON (offset >0x7fff ); + + mi.i_format.opcode = cpu_has_64bit_gp_regs ? daddiu_op : addiu_op; + mi.i_format.rs =6 ;/* $a2 */ + mi.i_format.rt =6 ;/* $a2 */ + mi.i_format.simmediate = offset; + +emit_instruction (mi); +} +static inline void build_addiu_a1 (unsigned long offset) {union mips_instruction mi;
@@ -369,7 +383,14 @@ void __init build_clear_page(void) } } -build_addiu_a2_a0 (PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear :0 )); +unsigned long off =PAGE_SIZE - (cpu_has_prefetch ? pref_offset_clear :0 ); +if (off >0x7fff ) { +build_addiu_a2_a0 (off>>1 ); +build_addiu_a2 (off>>1 ); + } +else { +build_addiu_a2_a0 (off); + }if (R4600_V2_HIT_CACHEOP_WAR &&cpu_is_r4600_v2_x ())build_insn_word (0x3c01a000 );/* lui $at, 0xa000 */
@@ -425,7 +446,14 @@ void __init build_copy_page(void) store_offset = load_offset =0 ; instruction_pending =0 ; -build_addiu_a2_a0 (PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy :0 )); +unsigned long off =PAGE_SIZE - (cpu_has_prefetch ? pref_offset_copy :0 ); +if (off >0x7fff ) { +build_addiu_a2_a0 (off>>1 ); +build_addiu_a2 (off>>1 ); + } +else { +build_addiu_a2_a0 (off); + }if (R4600_V2_HIT_CACHEOP_WAR &&cpu_is_r4600_v2_x ())build_insn_word (0x3c01a000 );/* lui $at, 0xa000 */
arch/mips/mm/tlbex.c +14 -4
@@ -102,7 +102,7 @@ enum opcode { insn_addu, insn_addiu, insn_and, insn_andi, insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl, insn_bne, insn_daddu, insn_daddiu, insn_dmfc0, insn_dmtc0, - insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, + insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_ori, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
@@ -145,6 +145,7 @@ static __initdata struct insn insn_table { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, { insn_dsrl, M(spec_op,0,0,0,0,dsrl_op), RT | RD | RE }, + { insn_dsrl32, M(spec_op,0,0,0,0,dsrl32_op), RT | RD | RE }, { insn_dsubu, M(spec_op,0,0,0,0,dsubu_op), RS | RT | RD }, { insn_eret, M(cop0_op,cop_op,0,0,0,eret_op), 0 }, { insn_j, M(j_op,0,0,0,0,0), JIMM },
@@ -385,6 +386,7 @@ I_u2u1u3(_dsll);I_u2u1u3 (_dsll32);I_u2u1u3 (_dsra);I_u2u1u3 (_dsrl); +I_u2u1u3 (_dsrl32);I_u3u1u2 (_dsubu);I_0 (_eret);I_u1 (_j);
@@ -996,7 +998,15 @@ #else#endif l_vmalloc_done (l, *p); -i_dsrl (p, tmp, tmp,PGDIR_SHIFT -3 );/* get pgd offset in bytes */ + +/* Want PGDIR_SHIFT-3 here, but handle shifts greater than 32 +* bits for large page sizes. */ +#ifdef CONFIG_PAGE_SIZE_4KB +i_dsrl (p, tmp, tmp,PGDIR_SHIFT -3 );/* get pgd offset in bytes */ +#else +i_dsrl32 (p, tmp, tmp,PGDIR_SHIFT -3 -32 );/* get pgd offset in bytes */ +#endif +i_andi (p, tmp, tmp, (PTRS_PER_PGD -1 )<<3 );i_daddu (p, ptr, ptr, tmp);/* add in pgd offset */ i_dmfc0 (p, tmp,C0_BADVADDR );/* get faulting address */
@@ -1073,7 +1083,7 @@ #endif /* !CONFIG_64BIT */static __init void build_adjust_context (u32 **p,unsigned int ctx) { -unsigned int shift =4 - (PTE_T_LOG2 +1 ); +unsigned int shift =4 - (PTE_T_LOG2 +1 ) +PAGE_SHIFT -12 ;unsigned int mask = (PTRS_PER_PTE /2 -1 ) << (PTE_T_LOG2 +1 );switch (current_cpu_data.cputype) {
@@ -1811,7 +1821,7 @@ void __init build_tlb_refill_handler(voidefault :build_r4000_tlb_refill_handler ();if (!run_once) { -build_r4000_tlb_load_handler (); +build_r4000_tlb_load_handler ();build_r4000_tlb_store_handler ();build_r4000_tlb_modify_handler (); run_once++;
include/asm-mips/asm.h +2 -0
@@ -344,6 +344,7 @@ #define PTR_SUBU subu#define PTR_L lw#define PTR_S sw#define PTR_LA la +#define PTR_LI li#define PTR_SLL sll#define PTR_SLLV sllv#define PTR_SRL srl
@@ -368,6 +369,7 @@ #define PTR_SUBU dsubu#define PTR_L ld#define PTR_S sd#define PTR_LA dla +#define PTR_LI dli#define PTR_SLL dsll#define PTR_SLLV dsllv#define PTR_SRL dsrl
include/asm-mips/page.h +8 -0
@@ -34,6 +34,14 @@ #endif#define PAGE_SIZE (1UL << PAGE_SHIFT)#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +/* +* Since asm-offsets.c does not work for more than 15 bit values, +* we define these here. +*/ +#ifdef CONFIG_PAGE_SIZE_64KB +#define _PAGE_SIZE 0x10000 +#define _THREAD_SIZE 0x10000 +#endif #ifdef __KERNEL__#ifndef __ASSEMBLY__
include/asm-mips/pgalloc.h +1 -1
@@ -48,7 +48,7 @@ static inline pgd_t *pgd_alloc(struct mm ret = (pgd_t *)__get_free_pages (GFP_KERNEL ,PGD_ORDER );if (ret) { - init =pgd_offset (&init_mm,0 ); + init =pgd_offset (&init_mm,0UL );pgd_init ((unsigned long )ret);memcpy (ret +USER_PTRS_PER_PGD , init +USER_PTRS_PER_PGD , (PTRS_PER_PGD -USER_PTRS_PER_PGD ) *sizeof (pgd_t));
include/asm-mips/pgtable-64.h +1 -1
@@ -174,7 +174,7 @@ #define __pud_offset(address) (((address#define __pmd_offset (address) pmd_index(address)/* to find an entry in a kernel page-table-directory */ -#define pgd_offset_k (address) pgd_offset(&init_mm, 0) +#define pgd_offset_k (address) pgd_offset(&init_mm, 0UL)#define pgd_index (address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))#define pmd_index (address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))