[PATCH] ppc44x: support for 256K PAGE_SIZE
Yuri Tikhonov
yur at emcraft.com
Thu Oct 18 21:00:32 EST 2007
It has turned out that my mailer had corrupted my previous message (thanks
Wolfgang Denk for pointing this). So if you'd like to apply the patch without the
conflicts please use the version of the patch in this mail.
The following patch adds support for 256KB PAGE_SIZE on ppc44x-based boards.
The applications to be run on the kernel with 256KB PAGE_SIZE have to be
built using the modified version of binutils, where the MAXPAGESIZE
definition is set to 0x40000 (as opposite to standard 0x10000).
Signed-off-by: Pavel Kolesnikov <concord at emcraft.com>
Acked-by: Yuri Tikhonov <yur at emcraft.com>
--
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index c590b18..0ee372d 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -1223,6 +1223,9 @@ config PPC_PAGE_16K
config PPC_PAGE_64K
bool "64 KB" if 44x
+
+config PPC_PAGE_256K
+ bool "256 KB" if 44x
endchoice
endmenu
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index fba7ca1..2140341 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -200,7 +200,7 @@ _GLOBAL(DoSyscall)
#ifdef SHOW_SYSCALLS
bl do_show_syscall
#endif /* SHOW_SYSCALLS */
- rlwinm r10,r1,0,0,18 /* current_thread_info() */
+ rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
lwz r11,TI_FLAGS(r10)
andi. r11,r11,_TIF_SYSCALL_T_OR_A
bne- syscall_dotrace
@@ -221,7 +221,7 @@ ret_from_syscall:
bl do_show_syscall_exit
#endif
mr r6,r3
- rlwinm r12,r1,0,0,18 /* current_thread_info() */
+ rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
/* disable interrupts so current_thread_info()->flags can't change */
LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */
SYNC
@@ -639,7 +639,7 @@ ret_from_except:
user_exc_return: /* r10 contains MSR_KERNEL here */
/* Check current_thread_info()->flags */
- rlwinm r9,r1,0,0,18
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r9,TI_FLAGS(r9)
andi. r0,r9,(_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NEED_RESCHED)
bne do_work
@@ -659,7 +659,7 @@ restore_user:
/* N.B. the only way to get here is from the beq following ret_from_except. */
resume_kernel:
/* check current_thread_info->preempt_count */
- rlwinm r9,r1,0,0,18
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r0,TI_PREEMPT(r9)
cmpwi 0,r0,0 /* if non-zero, just restore regs and return */
bne restore
@@ -669,7 +669,7 @@ resume_kernel:
andi. r0,r3,MSR_EE /* interrupts off? */
beq restore /* don't schedule if so */
1: bl preempt_schedule_irq
- rlwinm r9,r1,0,0,18
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r3,TI_FLAGS(r9)
andi. r0,r3,_TIF_NEED_RESCHED
bne- 1b
@@ -875,7 +875,7 @@ recheck:
LOAD_MSR_KERNEL(r10,MSR_KERNEL)
SYNC
MTMSRD(r10) /* disable interrupts */
- rlwinm r9,r1,0,0,18
+ rlwinm r9,r1,0,0,(31-THREAD_SHIFT)
lwz r9,TI_FLAGS(r9)
andi. r0,r9,_TIF_NEED_RESCHED
bne- do_resched
diff --git a/arch/ppc/kernel/head_booke.h b/arch/ppc/kernel/head_booke.h
index f3d274c..db4eeee 100644
--- a/arch/ppc/kernel/head_booke.h
+++ b/arch/ppc/kernel/head_booke.h
@@ -20,7 +20,9 @@
beq 1f; \
mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
- addi r1,r1,THREAD_SIZE; \
+ lis r11,THREAD_SIZE at h; \
+ ori r11,r11,THREAD_SIZE at l; \
+ add r1,r1,r11; \
1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
mr r11,r1; \
stw r10,_CCR(r11); /* save various registers */\
@@ -106,7 +108,9 @@
/* COMING FROM USER MODE */ \
mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
- addi r11,r11,THREAD_SIZE; \
+ lis r11,THREAD_SIZE at h; \
+ ori r11,r11,THREAD_SIZE at l; \
+ add r1,r1,r11; \
1: subi r11,r11,INT_FRAME_SIZE; /* Allocate an exception frame */\
stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index 3f32ca8..0a564ce 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -15,7 +15,11 @@
#ifdef CONFIG_PPC64
#define THREAD_SHIFT 14
#else
-#define THREAD_SHIFT 13
+#if defined(CONFIG_PPC_PAGE_256K)
+#define THREAD_SHIFT 15
+#else
+#define THREAD_SHIFT 13
+#endif
#endif
#define THREAD_SIZE (1 << THREAD_SHIFT)
@@ -81,11 +85,26 @@ struct thread_info {
#else /* THREAD_SHIFT < PAGE_SHIFT */
#ifdef CONFIG_DEBUG_STACK_USAGE
-#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
+#if defined(CONFIG_PPC_PAGE_256K)
+#define alloc_thread_info(tsk) \
+ ((struct thread_info *)__get_free_pages(GFP_KERNEL | \
+ __GFP_ZERO, 0))
#else
-#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#define alloc_thread_info(tsk) kzalloc(THREAD_SIZE, GFP_KERNEL)
#endif
+#else /* CONFIG_DEBUG_STACK_USAGE */
+#if defined(CONFIG_PPC_PAGE_256K)
+#define alloc_thread_info(tsk) \
+ ((struct thread_info *)__get_free_pages(GFP_KERNEL, 0))
+#else
+#define alloc_thread_info(tsk) kmalloc(THREAD_SIZE, GFP_KERNEL)
+#endif
+#endif /* CONFIG_DEBUG_STACK_USAGE */
+#if defined(CONFIG_PPC_PAGE_256K)
+#define free_thread_info(ti) free_pages((unsigned long)ti, 0)
+#else
#define free_thread_info(ti) kfree(ti)
+#endif
#endif /* THREAD_SHIFT < PAGE_SHIFT */
diff --git a/include/asm-ppc/page.h b/include/asm-ppc/page.h
index cb4a484..726823b 100644
--- a/include/asm-ppc/page.h
+++ b/include/asm-ppc/page.h
@@ -10,6 +10,8 @@
#define PAGE_SHIFT 14
#elif defined(CONFIG_PPC_PAGE_64K)
#define PAGE_SHIFT 16
+#elif defined(CONFIG_PPC_PAGE_256K)
+#define PAGE_SHIFT 18
#endif
#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
@@ -34,7 +36,11 @@
*/
#ifdef CONFIG_PTE_64BIT
typedef unsigned long long pte_basic_t;
+#if defined(CONFIG_PPC_PAGE_256K)
+#define PTE_SHIFT (PAGE_SHIFT - 7)
+#else
#define PTE_SHIFT (PAGE_SHIFT - 3) /* PAGE_SIZE/8 ptes per page */
+#endif
#define PTE_FMT "%16Lx"
#else
typedef unsigned long pte_basic_t;
diff --git a/include/asm-ppc/ppc_page_asm.h b/include/asm-ppc/ppc_page_asm.h
index 1dbfd3b..924463c 100644
--- a/include/asm-ppc/ppc_page_asm.h
+++ b/include/asm-ppc/ppc_page_asm.h
@@ -55,6 +55,19 @@
#define PPC44x_PTE_ADD_SH 19 /*32 - PMD_SHIFT + PTE_SHIFT + 3*/
#define PPC44x_PTE_ADD_M1 16 /*32 - 3 - PTE_SHIFT*/
#define PPC44x_RPN_M2 15 /*31 - PAGE_SHIFT*/
+#elif (PAGE_SHIFT == 18)
+/*
+ * PAGE_SIZE 256K
+ * PAGE_SHIFT 18
+ * PTE_SHIFT 11
+ * PMD_SHIFT 29
+ */
+#define PPC44x_TLB_SIZE PPC44x_TLB_256K
+#define PPC44x_PGD_OFF_SH 5 /*(32 - PMD_SHIFT + 2)*/
+#define PPC44x_PGD_OFF_M1 27 /*(PMD_SHIFT - 2)*/
+#define PPC44x_PTE_ADD_SH 17 /*32 - PMD_SHIFT + PTE_SHIFT + 3*/
+#define PPC44x_PTE_ADD_M1 18 /*32 - 3 - PTE_SHIFT*/
+#define PPC44x_RPN_M2 13 /*31 - PAGE_SHIFT*/
#else
#error "Unsupported PAGE_SIZE"
#endif
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S
index 930fe30..3ba570b 100644
--- a/arch/ppc/kernel/vmlinux.lds.S
+++ b/arch/ppc/kernel/vmlinux.lds.S
@@ -3,6 +3,11 @@
OUTPUT_ARCH(powerpc:common)
jiffies = jiffies_64 + 4;
+PHDRS
+{
+ text PT_LOAD FILEHDR PHDRS FLAGS (7);
+ data PT_LOAD FLAGS (7);
+}
SECTIONS
{
/* Read-only sections, merged into text segment: */
@@ -30,6 +35,7 @@ SECTIONS
.rela.plt : { *(.rela.plt) }
/* .init : { *(.init) } =0*/
.plt : { *(.plt) }
+ . = ALIGN(PAGE_SIZE);
.text :
{
_text = .;
@@ -41,7 +47,7 @@ SECTIONS
__got2_start = .;
*(.got2)
__got2_end = .;
- }
+ } :text
_etext = .;
PROVIDE (etext = .);
@@ -75,7 +81,7 @@ SECTIONS
*(.got.plt) *(.got)
*(.dynamic)
CONSTRUCTORS
- }
+ } :data
. = ALIGN(PAGE_SIZE);
__nosave_begin = .;
@@ -89,7 +95,7 @@ SECTIONS
_edata = .;
PROVIDE (edata = .);
- . = ALIGN(8192);
+ . = ALIGN(PAGE_SIZE << 1);
.data.init_task : { *(.data.init_task) }
. = ALIGN(PAGE_SIZE);
--
Yuri Tikhonov, Senior Software Engineer
Emcraft Systems, www.emcraft.com
More information about the Linuxppc-dev
mailing list