From: Peter Watkins <treestem@gmail.com>
To: linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>,
Jonathan Day <imipak@yahoo.com>
Subject: [PATCH 2] 64K page size
Date: Fri, 25 Aug 2006 10:42:41 -0400 [thread overview]
Message-ID: <44EF0C61.7090008@gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 970 bytes --]
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.
Signed-off-by: Peter Watkins <treestem@gmail.com>
[-- Attachment #2: patch-pagesize-2.6.18-rc1.txt --]
[-- Type: text/plain, Size: 8839 bytes --]
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index ec28077..07b6566 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -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));
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
index c06f63e..c9de17c 100644
--- a/arch/mips/kernel/head.S
+++ b/arch/mips/kernel/head.S
@@ -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
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index d5c8b82..fe534c7 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -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 */
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 0bb9cd8..ad7d6ff 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -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)
diff --git a/arch/mips/lib-64/dump_tlb.c b/arch/mips/lib-64/dump_tlb.c
index 6db44c7..cc6fd23 100644
--- a/arch/mips/lib-64/dump_tlb.c
+++ b/arch/mips/lib-64/dump_tlb.c
@@ -147,7 +147,7 @@ void dump_list_process(struct task_struc
printk("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);
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c
index be80c5d..eeed944 100644
--- a/arch/mips/mips-boards/generic/memory.c
+++ b/arch/mips/mips-boards/generic/memory.c
@@ -176,7 +176,7 @@ unsigned long __init prom_free_prom_memo
if (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)));
diff --git a/arch/mips/mm/pg-r4k.c b/arch/mips/mm/pg-r4k.c
index b7c7492..b173a8d 100644
--- a/arch/mips/mm/pg-r4k.c
+++ b/arch/mips/mm/pg-r4k.c
@@ -270,6 +270,20 @@ static inline void build_addiu_a2_a0(uns
emit_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 */
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 375e099..bf093aa 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -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 r
static __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(voi
default:
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++;
diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h
index 6ed1151..64cc068 100644
--- a/include/asm-mips/page.h
+++ b/include/asm-mips/page.h
@@ -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__
diff --git a/include/asm-mips/pgalloc.h b/include/asm-mips/pgalloc.h
index 582c1fe..af121c6 100644
--- a/include/asm-mips/pgalloc.h
+++ b/include/asm-mips/pgalloc.h
@@ -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));
diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h
index 9ce72bd..05a0e66 100644
--- a/include/asm-mips/pgtable-64.h
+++ b/include/asm-mips/pgtable-64.h
@@ -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))
next reply other threads:[~2006-08-25 14:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-25 14:42 Peter Watkins [this message]
2006-08-25 15:04 ` [PATCH 2] 64K page size Ralf Baechle
2006-08-25 15:21 ` Thiemo Seufer
2006-08-29 17:27 ` [PATCH 3] " Peter Watkins
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44EF0C61.7090008@gmail.com \
--to=treestem@gmail.com \
--cc=imipak@yahoo.com \
--cc=linux-mips@linux-mips.org \
--cc=ralf@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.