···3333 Qualcomm Hexagon is a processor architecture designed for high3434 performance and low power across a wide variety of applications.35353636+3637config HEXAGON_ARCH_V13738 bool3839···45444645config HEXAGON_ARCH_V44746 bool4747+4848+config HEXAGON_PHYS_OFFSET4949+ def_bool y5050+ ---help---5151+ Platforms that don't load the kernel at zero set this.48524953config FRAME_POINTER5054 def_bool y
···3232#define PAGE_OFFSET _AC(0xc0000000, UL)33333434/*3535- * LOAD_ADDRESS is the physical/linear address of where in memory3636- * the kernel gets loaded. The 12 least significant bits must be zero (0)3737- * due to limitations on setting the EVB3838- *3535+ * Compiling for a platform that needs a crazy physical offset3636+ * (like if the memory starts at 1GB and up) means we need3737+ * an actual PHYS_OFFSET. Should be set up in head.S.3938 */40394141-#ifndef LOAD_ADDRESS4242-#define LOAD_ADDRESS 0x000000004040+#ifdef CONFIG_HEXAGON_PHYS_OFFSET4141+#ifndef __ASSEMBLY__4242+extern unsigned long __phys_offset;4343#endif4444+#define PHYS_OFFSET __phys_offset4545+#endif4646+4747+#ifndef PHYS_OFFSET4848+#define PHYS_OFFSET 04949+#endif5050+5151+#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT)5252+#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET44534554#define TASK_SIZE (PAGE_OFFSET)4655
+3-2
arch/hexagon/include/asm/page.h
···9696 * MIPS says they're only used during mem_init.9797 * also, check if we need a PHYS_OFFSET.9898 */9999-#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET)100100-#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))9999+#define __pa(x) ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET)100100+#define __va(x) ((void *)((unsigned long)(x) - PHYS_OFFSET + PAGE_OFFSET))101101102102/* The "page frame" descriptor is defined in linux/mm.h */103103struct page;···147147 */148148#define kern_addr_valid(addr) (1)149149150150+#include <asm/mem-layout.h>150151#include <asm-generic/memory_model.h>151152/* XXX Todo: implement assembly-optimized version of getorder. */152153#include <asm-generic/getorder.h>
+18-4
arch/hexagon/kernel/head.S
···4343 * Symbol is kernel segment address, but we need4444 * the logical/physical address.4545 */4646- r24 = asl(r24, #2)4747- r24 = lsr(r24, #2)4646+ r25 = pc;4747+ r2.h = #0xffc0;4848+ r2.l = #0x0000;4949+ r25 = and(r2,r25); /* R25 holds PHYS_OFFSET now */5050+ r1.h = #HI(PAGE_OFFSET);5151+ r1.l = #LO(PAGE_OFFSET);5252+ r24 = sub(r24,r1); /* swapper_pg_dir - PAGE_OFFSET */5353+ r24 = add(r24,r25); /* + PHYS_OFFSET */48544949- r0 = r245555+ r0 = r24; /* aka __pa(swapper_pg_dir) */50565157 /*5252- * Initialize a 16MB PTE to make the virtual and physical5858+ * Initialize page dir to make the virtual and physical5359 * addresses where the kernel was loaded be identical.6060+ * Done in 4MB chunks.5461 */5562#define PTE_BITS ( __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X \5663 | __HEXAGON_C_WB_L2 << 6 \···149142150143 r2 = sub(r2,r0);151144 call memset;145145+146146+ /* Set PHYS_OFFSET; should still be in R25 */147147+#ifdef CONFIG_HEXAGON_PHYS_OFFSET148148+ r0.l = #LO(__phys_offset);149149+ r0.h = #HI(__phys_offset);150150+ memw(r0) = r25;151151+#endif152152153153 /* Time to make the doughnuts. */154154 call start_kernel
+2
arch/hexagon/kernel/setup.c
···6868 */6969 __vmsetvec(_K_VM_event_vector);70707171+ printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET);7272+7173 /*7274 * Simulator has a few differences from the hardware.7375 * For now, check uninitialized-but-mapped memory
+2-8
arch/hexagon/kernel/vmlinux.lds.S
···1818 * 02110-1301, USA.1919 */20202121-#define LOAD_OFFSET PAGE_OFFSET2222-2321#include <asm-generic/vmlinux.lds.h>2422#include <asm/asm-offsets.h> /* Most of the kernel defines are here */2523#include <asm/mem-layout.h> /* except for page_offset */···34363537#define PAGE_SIZE _PAGE_SIZE36383737-/* This LOAD_OFFSET is temporary for debugging on the simulator; it may change3838- for hypervisor pseudo-physical memory. */3939-4040-4139SECTIONS4240{4343- . = PAGE_OFFSET + LOAD_ADDRESS;4141+ . = PAGE_OFFSET;44424543 __init_begin = .;4644 HEAD_TEXT_SECTION···46524753 . = ALIGN(_PAGE_SIZE);4854 _stext = .;4949- .text : AT(ADDR(.text) - LOAD_OFFSET) {5555+ .text : AT(ADDR(.text)) {5056 _text = .;5157 TEXT_TEXT5258 SCHED_TEXT
+21-12
arch/hexagon/mm/init.c
···3131 * Define a startpg just past the end of the kernel image and a lastpg3232 * that corresponds to the end of real or simulated platform memory.3333 */3434-#define bootmem_startpg (PFN_UP(((unsigned long) _end) - PAGE_OFFSET))3434+#define bootmem_startpg (PFN_UP(((unsigned long) _end) - PAGE_OFFSET + PHYS_OFFSET))35353636-unsigned long bootmem_lastpg; /* Should be set by platform code */3636+unsigned long bootmem_lastpg; /* Should be set by platform code */3737+unsigned long __phys_offset; /* physical kernel offset >> 12 */37383839/* Set as variable to limit PMD copies */3940int max_kernel_seg = 0x303;···4544/* indicate pfn's of high memory */4645unsigned long highstart_pfn, highend_pfn;47464848-/* struct mmu_gather defined in asm-generic.h; */4947DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);50485149/* Default cache attribute for newly created page tables */···7171{7272 /* No idea where this is actually declared. Seems to evade LXR. */7373 totalram_pages += free_all_bootmem();7474- num_physpages = bootmem_lastpg; /* seriously, what? */7474+ num_physpages = bootmem_lastpg-ARCH_PFN_OFFSET;75757676 printk(KERN_INFO "totalram_pages = %ld\n", totalram_pages);7777···193193 * This needs to change for highmem setups.194194 */195195196196+ /* Prior to this, bootmem_lastpg is actually mem size */197197+ bootmem_lastpg += ARCH_PFN_OFFSET;198198+196199 /* Memory size needs to be a multiple of 16M */197200 bootmem_lastpg = PFN_DOWN((bootmem_lastpg << PAGE_SHIFT) &198201 ~((BIG_KERNEL_PAGE_SIZE) - 1));···204201 * Reserve the top DMA_RESERVE bytes of RAM for DMA (uncached)205202 * memory allocation206203 */207207- bootmap_size = init_bootmem(bootmem_startpg, bootmem_lastpg -208208- PFN_DOWN(DMA_RESERVED_BYTES));204204+205205+ max_low_pfn = bootmem_lastpg - PFN_DOWN(DMA_RESERVED_BYTES);206206+ min_low_pfn = ARCH_PFN_OFFSET;207207+ bootmap_size = init_bootmem_node(NODE_DATA(0), bootmem_startpg, min_low_pfn, max_low_pfn);209208210209 printk(KERN_INFO "bootmem_startpg: 0x%08lx\n", bootmem_startpg);211210 printk(KERN_INFO "bootmem_lastpg: 0x%08lx\n", bootmem_lastpg);212211 printk(KERN_INFO "bootmap_size: %d\n", bootmap_size);212212+ printk(KERN_INFO "min_low_pfn: 0x%08lx\n", min_low_pfn);213213 printk(KERN_INFO "max_low_pfn: 0x%08lx\n", max_low_pfn);214214215215 /*···227221 /* this actually only goes to the end of the first gig */228222 segtable_end = segtable + (1<<(30-22));229223230230- /* Move forward to the start of empty pages */231231- segtable += bootmem_lastpg >> (22-PAGE_SHIFT);224224+ /*225225+ * Move forward to the start of empty pages; take into account226226+ * phys_offset shift.227227+ */232228229229+ segtable += (bootmem_lastpg-ARCH_PFN_OFFSET)>>(22-PAGE_SHIFT);233230 {234234- int i;231231+ int i;235232236236- for (i = 1 ; i <= DMA_RESERVE ; i++)237237- segtable[-i] = ((segtable[-i] & __HVM_PTE_PGMASK_4MB)233233+ for (i = 1 ; i <= DMA_RESERVE ; i++)234234+ segtable[-i] = ((segtable[-i] & __HVM_PTE_PGMASK_4MB)238235 | __HVM_PTE_R | __HVM_PTE_W | __HVM_PTE_X239236 | __HEXAGON_C_UNC << 6240237 | __HVM_PDE_S_4MB);···265256 * Free all the memory that wasn't taken up by the bootmap, the DMA266257 * reserve, or kernel itself.267258 */268268- free_bootmem(PFN_PHYS(bootmem_startpg)+bootmap_size,259259+ free_bootmem(PFN_PHYS(bootmem_startpg) + bootmap_size,269260 PFN_PHYS(bootmem_lastpg - bootmem_startpg) - bootmap_size -270261 DMA_RESERVED_BYTES);271262