diff options
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r-- | arch/xtensa/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/xtensa/kernel/entry.S | 8 | ||||
-rw-r--r-- | arch/xtensa/kernel/head.S | 2 | ||||
-rw-r--r-- | arch/xtensa/kernel/mxhead.S | 23 | ||||
-rw-r--r-- | arch/xtensa/kernel/pci-dma.c | 45 | ||||
-rw-r--r-- | arch/xtensa/kernel/setup.c | 11 | ||||
-rw-r--r-- | arch/xtensa/kernel/time.c | 2 | ||||
-rw-r--r-- | arch/xtensa/kernel/vectors.S | 4 | ||||
-rw-r--r-- | arch/xtensa/kernel/vmlinux.lds.S | 37 |
9 files changed, 54 insertions, 79 deletions
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile index 50137bc9e..4db730290 100644 --- a/arch/xtensa/kernel/Makefile +++ b/arch/xtensa/kernel/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_SMP) += smp.o mxhead.o obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o AFLAGS_head.o += -mtext-section-literals +AFLAGS_mxhead.o += -mtext-section-literals # In the Xtensa architecture, assembly generates literals which must always # precede the L32R instruction with a relative offset less than 256 kB. diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 504130357..db5c1765b 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S @@ -367,8 +367,10 @@ common_exception: s32i a2, a1, PT_SYSCALL movi a2, 0 s32i a3, a1, PT_EXCVADDR +#if XCHAL_HAVE_LOOPS xsr a2, lcount s32i a2, a1, PT_LCOUNT +#endif /* It is now save to restore the EXC_TABLE_FIXUP variable. */ @@ -429,11 +431,12 @@ common_exception: rsync # PS.WOE => rsync => overflow /* Save lbeg, lend */ - +#if XCHAL_HAVE_LOOPS rsr a4, lbeg rsr a3, lend s32i a4, a1, PT_LBEG s32i a3, a1, PT_LEND +#endif /* Save SCOMPARE1 */ @@ -724,13 +727,14 @@ common_exception_exit: wsr a3, sar /* Restore LBEG, LEND, LCOUNT */ - +#if XCHAL_HAVE_LOOPS l32i a2, a1, PT_LBEG l32i a3, a1, PT_LEND wsr a2, lbeg l32i a2, a1, PT_LCOUNT wsr a3, lend wsr a2, lcount +#endif /* We control single stepping through the ICOUNTLEVEL register. */ diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S index 15a461e2a..9ed55649a 100644 --- a/arch/xtensa/kernel/head.S +++ b/arch/xtensa/kernel/head.S @@ -249,7 +249,7 @@ ENTRY(_startup) __loopt a2, a3, a4, 2 s32i a0, a2, 0 - __endla a2, a4, 4 + __endla a2, a3, 4 #if XCHAL_DCACHE_IS_WRITEBACK diff --git a/arch/xtensa/kernel/mxhead.S b/arch/xtensa/kernel/mxhead.S index 77a161a11..9f3843742 100644 --- a/arch/xtensa/kernel/mxhead.S +++ b/arch/xtensa/kernel/mxhead.S @@ -48,8 +48,6 @@ _SetupOCD: rsync _SetupMMU: - Offset = _SetupMMU - _SecondaryResetVector - #ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX initialize_mmu #endif @@ -62,24 +60,3 @@ _SetupMMU: jx a3 .end no-absolute-literals - - - .section .SecondaryResetVector.remapped_text, "ax" - .global _RemappedSecondaryResetVector - - .org 0 # Need to do org before literals - -_RemappedSecondaryResetVector: - .begin no-absolute-literals - .literal_position - - _j _RemappedSetupMMU - . = _RemappedSecondaryResetVector + Offset - -_RemappedSetupMMU: - -#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX - initialize_mmu -#endif - - .end no-absolute-literals diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index fb75ebf14..cd6669834 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c @@ -15,14 +15,15 @@ * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> */ -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/pci.h> #include <linux/gfp.h> +#include <linux/highmem.h> +#include <linux/mm.h> #include <linux/module.h> -#include <asm/io.h> +#include <linux/pci.h> +#include <linux/string.h> +#include <linux/types.h> #include <asm/cacheflush.h> +#include <asm/io.h> void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) @@ -47,17 +48,36 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, } EXPORT_SYMBOL(dma_cache_sync); +static void do_cache_op(dma_addr_t dma_handle, size_t size, + void (*fn)(unsigned long, unsigned long)) +{ + unsigned long off = dma_handle & (PAGE_SIZE - 1); + unsigned long pfn = PFN_DOWN(dma_handle); + struct page *page = pfn_to_page(pfn); + + if (!PageHighMem(page)) + fn((unsigned long)bus_to_virt(dma_handle), size); + else + while (size > 0) { + size_t sz = min_t(size_t, size, PAGE_SIZE - off); + void *vaddr = kmap_atomic(page); + + fn((unsigned long)vaddr + off, sz); + kunmap_atomic(vaddr); + off = 0; + ++page; + size -= sz; + } +} + static void xtensa_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - void *vaddr; - switch (dir) { case DMA_BIDIRECTIONAL: case DMA_FROM_DEVICE: - vaddr = bus_to_virt(dma_handle); - __invalidate_dcache_range((unsigned long)vaddr, size); + do_cache_op(dma_handle, size, __invalidate_dcache_range); break; case DMA_NONE: @@ -73,13 +93,11 @@ static void xtensa_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, enum dma_data_direction dir) { - void *vaddr; - switch (dir) { case DMA_BIDIRECTIONAL: case DMA_TO_DEVICE: - vaddr = bus_to_virt(dma_handle); - __flush_dcache_range((unsigned long)vaddr, size); + if (XCHAL_DCACHE_IS_WRITEBACK) + do_cache_op(dma_handle, size, __flush_dcache_range); break; case DMA_NONE: @@ -171,7 +189,6 @@ static dma_addr_t xtensa_map_page(struct device *dev, struct page *page, { dma_addr_t dma_handle = page_to_phys(page) + offset; - BUG_ON(PageHighMem(page)); xtensa_sync_single_for_device(dev, dma_handle, size, dir); return dma_handle; } diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 28fc57ef5..9735691f3 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c @@ -190,7 +190,7 @@ static int __init parse_bootparam(const bp_tag_t* tag) #ifdef CONFIG_OF bool __initdata dt_memory_scan = false; -#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY +#if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR; EXPORT_SYMBOL(xtensa_kio_paddr); @@ -334,7 +334,10 @@ extern char _Level5InterruptVector_text_end; extern char _Level6InterruptVector_text_start; extern char _Level6InterruptVector_text_end; #endif - +#ifdef CONFIG_SMP +extern char _SecondaryResetVector_text_start; +extern char _SecondaryResetVector_text_end; +#endif #ifdef CONFIG_S32C1I_SELFTEST @@ -506,6 +509,10 @@ void __init setup_arch(char **cmdline_p) __pa(&_Level6InterruptVector_text_end), 0); #endif +#ifdef CONFIG_SMP + mem_reserve(__pa(&_SecondaryResetVector_text_start), + __pa(&_SecondaryResetVector_text_end), 0); +#endif parse_early_param(); bootmem_init(); diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index b97767dbc..b9ad9fead 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c @@ -148,7 +148,7 @@ void __init time_init(void) local_timer_setup(0); setup_irq(this_cpu_ptr(&ccount_timer)->evt.irq, &timer_irqaction); sched_clock_register(ccount_sched_clock_read, 32, ccount_freq); - clocksource_of_init(); + clocksource_probe(); } /* diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index abcdb527f..fc25318e7 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S @@ -478,6 +478,9 @@ _DoubleExceptionVector_handle_exception: ENDPROC(_DoubleExceptionVector) + .end literal_prefix + + .text /* * Fixup handler for TLB miss in double exception handler for window owerflow. * We get here with windowbase set to the window that was being spilled and @@ -587,7 +590,6 @@ ENTRY(window_overflow_restore_a0_fixup) ENDPROC(window_overflow_restore_a0_fixup) - .end literal_prefix /* * Debug interrupt vector * diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index fc1bc2ba8..c417cbe4e 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S @@ -166,8 +166,6 @@ SECTIONS RELOCATE_ENTRY(_DebugInterruptVector_text, .DebugInterruptVector.text); #if defined(CONFIG_SMP) - RELOCATE_ENTRY(_SecondaryResetVector_literal, - .SecondaryResetVector.literal); RELOCATE_ENTRY(_SecondaryResetVector_text, .SecondaryResetVector.text); #endif @@ -282,17 +280,11 @@ SECTIONS #if defined(CONFIG_SMP) - SECTION_VECTOR (_SecondaryResetVector_literal, - .SecondaryResetVector.literal, - RESET_VECTOR1_VADDR - 4, - SIZEOF(.DoubleExceptionVector.text), - .DoubleExceptionVector.text) - SECTION_VECTOR (_SecondaryResetVector_text, .SecondaryResetVector.text, RESET_VECTOR1_VADDR, - 4, - .SecondaryResetVector.literal) + SIZEOF(.DoubleExceptionVector.text), + .DoubleExceptionVector.text) . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text); @@ -306,31 +298,6 @@ SECTIONS _end = .; - /* only used by the boot loader */ - - . = ALIGN(0x10); - .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) } - - .ResetVector.text RESET_VECTOR_VADDR : - { - *(.ResetVector.text) - } - - - /* - * This is a remapped copy of the Secondary Reset Vector Code. - * It keeps gdb in sync with the PC after switching - * to the temporary mapping used while setting up - * the V2 MMU mappings for Linux. - * - * Only debug information about this section is put in the kernel image. - */ - .SecondaryResetVector.remapped_text 0x46000000 (INFO): - { - *(.SecondaryResetVector.remapped_text) - } - - .xt.lit : { *(.xt.lit) } .xt.prop : { *(.xt.prop) } |