From 8f5a0b9dffeb3cb94f2b0622b6fe0717512ef54b Mon Sep 17 00:00:00 2001 From: Richard Kuo Date: Fri, 22 Mar 2013 16:05:40 -0500 Subject: Hexagon: add support for ARCH_PFN_OFFSET Add support for loading the kernel at a physical offset. The offset should still be 4M aligned. Signed-off-by: Richard Kuo --- arch/hexagon/kernel/head.S | 22 ++++++++++++++++++---- arch/hexagon/kernel/setup.c | 2 ++ arch/hexagon/kernel/vmlinux.lds.S | 10 ++-------- 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'arch/hexagon/kernel') diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S index d859402c73ba..477320c455f7 100644 --- a/arch/hexagon/kernel/head.S +++ b/arch/hexagon/kernel/head.S @@ -43,14 +43,21 @@ ENTRY(stext) * Symbol is kernel segment address, but we need * the logical/physical address. */ - r24 = asl(r24, #2) - r24 = lsr(r24, #2) + r25 = pc; + r2.h = #0xffc0; + r2.l = #0x0000; + r25 = and(r2,r25); /* R25 holds PHYS_OFFSET now */ + r1.h = #HI(PAGE_OFFSET); + r1.l = #LO(PAGE_OFFSET); + r24 = sub(r24,r1); /* swapper_pg_dir - PAGE_OFFSET */ + r24 = add(r24,r25); /* + PHYS_OFFSET */ - r0 = r24 + r0 = r24; /* aka __pa(swapper_pg_dir) */ /* - * Initialize a 16MB PTE to make the virtual and physical + * Initialize page dir to make the virtual and physical * addresses where the kernel was loaded be identical. + * Done in 4MB chunks. */ #define PTE_BITS ( __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X \ | __HEXAGON_C_WB_L2 << 6 \ @@ -143,6 +150,13 @@ __head_s_vaddr_target: r2 = sub(r2,r0); call memset; + /* Set PHYS_OFFSET; should still be in R25 */ +#ifdef CONFIG_HEXAGON_PHYS_OFFSET + r0.l = #LO(__phys_offset); + r0.h = #HI(__phys_offset); + memw(r0) = r25; +#endif + /* Time to make the doughnuts. */ call start_kernel diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index 94a387835008..2e2304f7b7ee 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c @@ -68,6 +68,8 @@ void __init setup_arch(char **cmdline_p) */ __vmsetvec(_K_VM_event_vector); + printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET); + /* * Simulator has a few differences from the hardware. * For now, check uninitialized-but-mapped memory diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 14e793f6abbf..fafb886511e3 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -18,8 +18,6 @@ * 02110-1301, USA. */ -#define LOAD_OFFSET PAGE_OFFSET - #include #include /* Most of the kernel defines are here */ #include /* except for page_offset */ @@ -36,13 +34,9 @@ See asm-generic/sections.h for seemingly required labels. #define PAGE_SIZE _PAGE_SIZE -/* This LOAD_OFFSET is temporary for debugging on the simulator; it may change - for hypervisor pseudo-physical memory. */ - - SECTIONS { - . = PAGE_OFFSET + LOAD_ADDRESS; + . = PAGE_OFFSET; __init_begin = .; HEAD_TEXT_SECTION @@ -52,7 +46,7 @@ SECTIONS . = ALIGN(_PAGE_SIZE); _stext = .; - .text : AT(ADDR(.text) - LOAD_OFFSET) { + .text : AT(ADDR(.text)) { _text = .; TEXT_TEXT SCHED_TEXT -- cgit v1.2.3