History

Merge tag 'csky-for-linus-5.4-rc1' of git://github.com/c-sky/csky-linux

Pull csky updates from Guo Ren: "This round of csky subsystem just some fixups: - Fix mb() synchronization problem - Fix dma_alloc_coherent with PAGE_SO attribute - Fix cache_op failed when cross memory ZONEs - Optimize arch_sync_dma_for_cpu/device with dma_inv_range - Fix ioremap function losing - Fix arch_get_unmapped_area() implementation - Fix defer cache flush for 610 - Support kernel non-aligned access - Fix 610 vipt cache flush mechanism - Fix add zero_fp fixup perf backtrace panic - Move static keyword to the front of declaration - Fix csky_pmu.max_period assignment - Use generic free_initrd_mem() - entry: Remove unneeded need_resched() loop" * tag 'csky-for-linus-5.4-rc1' of git://github.com/c-sky/csky-linux: csky: Move static keyword to the front of declaration csky: entry: Remove unneeded need_resched() loop csky: Fixup csky_pmu.max_period assignment csky: Fixup add zero_fp fixup perf backtrace panic csky: Use generic free_initrd_mem() csky: Fixup 610 vipt cache flush mechanism csky: Support kernel non-aligned access csky: Fixup defer cache flush for 610 csky: Fixup arch_get_unmapped_area() implementation csky: Fixup ioremap function losing csky: Optimize arch_sync_dma_for_cpu/device with dma_inv_range csky/dma: Fixup cache_op failed when cross memory ZONEs csky: Fixup dma_alloc_coherent with PAGE_SO attribute csky: Fixup mb() synchronization problem

Linus Torvalds committed 7 years ago

Commit 80b29b62 parents cef0aa0 9af032a17 files · +291 −212Browse files

Unified · Split

17 files
  1. arch/csky/abiv1/alignment.c +45 −17
  2. arch/csky/abiv1/cacheflush.c +47 −23
  3. arch/csky/abiv1/inc/abi/cacheflush.h +31 −14
  4. arch/csky/abiv1/inc/abi/page.h +3 −2
  5. arch/csky/abiv1/mmap.c +40 −35
  6. arch/csky/include/asm/barrier.h +7 −8
  7. arch/csky/include/asm/cache.h +1 −0
  8. arch/csky/include/asm/io.h +12 −11
  9. arch/csky/include/asm/pgtable.h +10 −0
  10. arch/csky/kernel/entry.S +30 −24
  11. arch/csky/kernel/perf_event.c +2 −2
  12. arch/csky/kernel/process.c +1 −1
  13. arch/csky/mm/cachev1.c +6 −1
  14. arch/csky/mm/cachev2.c +10 −1
  15. arch/csky/mm/dma-mapping.c +28 −48
  16. arch/csky/mm/init.c +0 −16
  17. arch/csky/mm/ioremap.c +18 −9
arch/csky/abiv1/alignment.c+45−17
@@ -5,8 +5,10 @@ · 4 unmodified lines
5#include <linux/uaccess.h>5#include <linux/uaccess.h>
6#include <linux/ptrace.h>6#include <linux/ptrace.h>
7 7
8static int align_enable = 1;8static int align_kern_enable = 1;
9static int align_count;9static int align_usr_enable = 1;
10static int align_kern_count = 0;
11static int align_usr_count = 0;
10 12
11static inline uint32_t get_ptreg(struct pt_regs *regs, uint32_t rx)13static inline uint32_t get_ptreg(struct pt_regs *regs, uint32_t rx)
12{14{
@@ -32,9 +34,6 @@ static int ldb_asm(uint32_t addr, uint32_t *valp) · 19 unmodified lines
32 uint32_t val;34 uint32_t val;
33 int err;35 int err;
34 36
35 if (!access_ok((void *)addr, 1))
36 return 1;
37
38 asm volatile (37 asm volatile (
39 "movi %0, 0\n"38 "movi %0, 0\n"
40 "1:\n"39 "1:\n"
@@ -67,9 +66,6 @@ static int stb_asm(uint32_t addr, uint32_t val) · 26 unmodified lines
67{66{
68 int err;67 int err;
69 68
70 if (!access_ok((void *)addr, 1))
71 return 1;
72
73 asm volatile (69 asm volatile (
74 "movi %0, 0\n"70 "movi %0, 0\n"
75 "1:\n"71 "1:\n"
@@ -203,8 +199,6 @@ static int stw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr) · 127 unmodified lines
203 if (stb_asm(addr, byte3))199 if (stb_asm(addr, byte3))
204 return 1;200 return 1;
205 201
206 align_count++;
207
208 return 0;202 return 0;
209}203}
210 204
@@ -226,7 +220,14 @@ void csky_alignment(struct pt_regs *regs) · 15 unmodified lines
226 uint32_t addr = 0;220 uint32_t addr = 0;
227 221
228 if (!user_mode(regs))222 if (!user_mode(regs))
223 goto kernel_area;
224
225 if (!align_usr_enable) {
226 pr_err("%s user disabled.\n", __func__);
229 goto bad_area;227 goto bad_area;
228 }
229
230 align_usr_count++;
230 231
231 ret = get_user(tmp, (uint16_t *)instruction_pointer(regs));232 ret = get_user(tmp, (uint16_t *)instruction_pointer(regs));
232 if (ret) {233 if (ret) {
@@ -234,6 +235,19 @@ void csky_alignment(struct pt_regs *regs) · 1 unmodified line
234 goto bad_area;235 goto bad_area;
235 }236 }
236 237
238 goto good_area;
239
240kernel_area:
241 if (!align_kern_enable) {
242 pr_err("%s kernel disabled.\n", __func__);
243 goto bad_area;
244 }
245
246 align_kern_count++;
247
248 tmp = *(uint16_t *)instruction_pointer(regs);
249
250good_area:
237 opcode = (uint32_t)tmp;251 opcode = (uint32_t)tmp;
238 252
239 rx = opcode & 0xf;253 rx = opcode & 0xf;
@@ -286,18 +300,32 @@ bad_area: · 46 unmodified lines
286 force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);300 force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)addr);
287}301}
288 302
289static struct ctl_table alignment_tbl[4] = {303static struct ctl_table alignment_tbl[5] = {
304 {
305 .procname = "kernel_enable",
306 .data = &align_kern_enable,
307 .maxlen = sizeof(align_kern_enable),
308 .mode = 0666,
309 .proc_handler = &proc_dointvec
310 },
311 {
312 .procname = "user_enable",
313 .data = &align_usr_enable,
314 .maxlen = sizeof(align_usr_enable),
315 .mode = 0666,
316 .proc_handler = &proc_dointvec
317 },
290 {318 {
291 .procname = "enable",319 .procname = "kernel_count",
292 .data = &align_enable,320 .data = &align_kern_count,
293 .maxlen = sizeof(align_enable),321 .maxlen = sizeof(align_kern_count),
294 .mode = 0666,322 .mode = 0666,
295 .proc_handler = &proc_dointvec323 .proc_handler = &proc_dointvec
296 },324 },
297 {325 {
298 .procname = "count",326 .procname = "user_count",
299 .data = &align_count,327 .data = &align_usr_count,
300 .maxlen = sizeof(align_count),328 .maxlen = sizeof(align_usr_count),
301 .mode = 0666,329 .mode = 0666,
302 .proc_handler = &proc_dointvec330 .proc_handler = &proc_dointvec
303 },331 },
arch/csky/abiv1/cacheflush.c+47−23
@@ -11,42 +11,66 @@ · 10 unmodified lines
11#include <asm/cacheflush.h>11#include <asm/cacheflush.h>
12#include <asm/cachectl.h>12#include <asm/cachectl.h>
13 13
14#define PG_dcache_clean PG_arch_1
15
14void flush_dcache_page(struct page *page)16void flush_dcache_page(struct page *page)
15{17{
16 struct address_space *mapping = page_mapping(page);18 struct address_space *mapping;
17 unsigned long addr;
18 19
19 if (mapping && !mapping_mapped(mapping)) {20 if (page == ZERO_PAGE(0))
20 set_bit(PG_arch_1, &(page)->flags);
21 return;21 return;
22 }
23 22
24 /*23 mapping = page_mapping_file(page);
25 * We could delay the flush for the !page_mapping case too. But that24
26 * case is for exec env/arg pages and those are %99 certainly going to25 if (mapping && !page_mapcount(page))
27 * get faulted into the tlb (and thus flushed) anyways.26 clear_bit(PG_dcache_clean, &page->flags);
28 */27 else {
29 addr = (unsigned long) page_address(page);28 dcache_wbinv_all();
30 dcache_wb_range(addr, addr + PAGE_SIZE);29 if (mapping)
30 icache_inv_all();
31 set_bit(PG_dcache_clean, &page->flags);
32 }
31}33}
34EXPORT_SYMBOL(flush_dcache_page);
32 35
33void update_mmu_cache(struct vm_area_struct *vma, unsigned long address,36void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr,
34 pte_t *pte)37 pte_t *ptep)
35{38{
36 unsigned long addr;39 unsigned long pfn = pte_pfn(*ptep);
37 struct page *page;40 struct page *page;
38 unsigned long pfn;
39 41
40 pfn = pte_pfn(*pte);42 if (!pfn_valid(pfn))
41 if (unlikely(!pfn_valid(pfn)))
42 return;43 return;
43 44
44 page = pfn_to_page(pfn);45 page = pfn_to_page(pfn);
45 addr = (unsigned long) page_address(page);46 if (page == ZERO_PAGE(0))
47 return;
48
49 if (!test_and_set_bit(PG_dcache_clean, &page->flags))
50 dcache_wbinv_all();
46 51
47 if (vma->vm_flags & VM_EXEC ||52 if (page_mapping_file(page)) {
48 pages_do_alias(addr, address & PAGE_MASK))53 if (vma->vm_flags & VM_EXEC)
49 cache_wbinv_all();54 icache_inv_all();
55 }
56}
57
58void flush_kernel_dcache_page(struct page *page)
59{
60 struct address_space *mapping;
61
62 mapping = page_mapping_file(page);
63
64 if (!mapping || mapping_mapped(mapping))
65 dcache_wbinv_all();
66}
67EXPORT_SYMBOL(flush_kernel_dcache_page);
68
69void flush_cache_range(struct vm_area_struct *vma, unsigned long start,
70 unsigned long end)
71{
72 dcache_wbinv_all();
50 73
51 clear_bit(PG_arch_1, &(page)->flags);74 if (vma->vm_flags & VM_EXEC)
75 icache_inv_all();
52}76}
arch/csky/abiv1/inc/abi/cacheflush.h+31−14
@@ -4,46 +4,63 @@ · 3 unmodified lines
4#ifndef __ABI_CSKY_CACHEFLUSH_H4#ifndef __ABI_CSKY_CACHEFLUSH_H
5#define __ABI_CSKY_CACHEFLUSH_H5#define __ABI_CSKY_CACHEFLUSH_H
6 6
7#include <linux/compiler.h>7#include <linux/mm.h>
8#include <asm/string.h>8#include <asm/string.h>
9#include <asm/cache.h>9#include <asm/cache.h>
10 10
11#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 111#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
12extern void flush_dcache_page(struct page *);12extern void flush_dcache_page(struct page *);
13 13
14#define flush_cache_mm(mm) cache_wbinv_all()14#define flush_cache_mm(mm) dcache_wbinv_all()
15#define flush_cache_page(vma, page, pfn) cache_wbinv_all()15#define flush_cache_page(vma, page, pfn) cache_wbinv_all()
16#define flush_cache_dup_mm(mm) cache_wbinv_all()16#define flush_cache_dup_mm(mm) cache_wbinv_all()
17 17
18#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
19extern void flush_kernel_dcache_page(struct page *);
20
21#define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages)
22#define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages)
23
24static inline void flush_kernel_vmap_range(void *addr, int size)
25{
26 dcache_wbinv_all();
27}
28static inline void invalidate_kernel_vmap_range(void *addr, int size)
29{
30 dcache_wbinv_all();
31}
32
33#define ARCH_HAS_FLUSH_ANON_PAGE
34static inline void flush_anon_page(struct vm_area_struct *vma,
35 struct page *page, unsigned long vmaddr)
36{
37 if (PageAnon(page))
38 cache_wbinv_all();
39}
40
18/*41/*
19 * if (current_mm != vma->mm) cache_wbinv_range(start, end) will be broken.42 * if (current_mm != vma->mm) cache_wbinv_range(start, end) will be broken.
20 * Use cache_wbinv_all() here and need to be improved in future.43 * Use cache_wbinv_all() here and need to be improved in future.
21 */44 */
22#define flush_cache_range(vma, start, end) cache_wbinv_all()45extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
23#define flush_cache_vmap(start, end) cache_wbinv_range(start, end)46#define flush_cache_vmap(start, end) cache_wbinv_all()
24#define flush_cache_vunmap(start, end) cache_wbinv_range(start, end)47#define flush_cache_vunmap(start, end) cache_wbinv_all()
25 48
26#define flush_icache_page(vma, page) cache_wbinv_all()49#define flush_icache_page(vma, page) do {} while (0);
27#define flush_icache_range(start, end) cache_wbinv_range(start, end)50#define flush_icache_range(start, end) cache_wbinv_range(start, end)
28 51
29#define flush_icache_user_range(vma, pg, adr, len) \52#define flush_icache_user_range(vma,page,addr,len) \
30 cache_wbinv_range(adr, adr + len)53 flush_dcache_page(page)
31 54
32#define copy_from_user_page(vma, page, vaddr, dst, src, len) \55#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
33do { \56do { \
34 cache_wbinv_all(); \
35 memcpy(dst, src, len); \57 memcpy(dst, src, len); \
36 cache_wbinv_all(); \
37} while (0)58} while (0)
38 59
39#define copy_to_user_page(vma, page, vaddr, dst, src, len) \60#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
40do { \61do { \
41 cache_wbinv_all(); \
42 memcpy(dst, src, len); \62 memcpy(dst, src, len); \
43 cache_wbinv_all(); \63 cache_wbinv_all(); \
44} while (0)64} while (0)
45 65
46#define flush_dcache_mmap_lock(mapping) do {} while (0)
47#define flush_dcache_mmap_unlock(mapping) do {} while (0)
48
49#endif /* __ABI_CSKY_CACHEFLUSH_H */66#endif /* __ABI_CSKY_CACHEFLUSH_H */
arch/csky/abiv1/inc/abi/page.h+3−2
@@ -1,13 +1,14 @@
1/* SPDX-License-Identifier: GPL-2.0 */1/* SPDX-License-Identifier: GPL-2.0 */
2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.2// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3 3
4extern unsigned long shm_align_mask;4#include <asm/shmparam.h>
5
5extern void flush_dcache_page(struct page *page);6extern void flush_dcache_page(struct page *page);
6 7
7static inline unsigned long pages_do_alias(unsigned long addr1,8static inline unsigned long pages_do_alias(unsigned long addr1,
8 unsigned long addr2)9 unsigned long addr2)
9{10{
10 return (addr1 ^ addr2) & shm_align_mask;11 return (addr1 ^ addr2) & (SHMLBA-1);
11}12}
12 13
13static inline void clear_user_page(void *addr, unsigned long vaddr,14static inline void clear_user_page(void *addr, unsigned long vaddr,
arch/csky/abiv1/mmap.c+40−35
@@ -9,58 +9,63 @@ · 8 unmodified lines
9#include <linux/random.h>9#include <linux/random.h>
10#include <linux/io.h>10#include <linux/io.h>
11 11
12unsigned long shm_align_mask = (0x4000 >> 1) - 1; /* Sane caches */12#define COLOUR_ALIGN(addr,pgoff) \
13 ((((addr)+SHMLBA-1)&~(SHMLBA-1)) + \
14 (((pgoff)<<PAGE_SHIFT) & (SHMLBA-1)))
13 15
14#define COLOUR_ALIGN(addr, pgoff) \16/*
15 ((((addr) + shm_align_mask) & ~shm_align_mask) + \17 * We need to ensure that shared mappings are correctly aligned to
16 (((pgoff) << PAGE_SHIFT) & shm_align_mask))18 * avoid aliasing issues with VIPT caches. We need to ensure that
17 19 * a specific page of an object is always mapped at a multiple of
18unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,20 * SHMLBA bytes.
21 *
22 * We unconditionally provide this function for all cases.
23 */
24unsigned long
25arch_get_unmapped_area(struct file *filp, unsigned long addr,
19 unsigned long len, unsigned long pgoff, unsigned long flags)26 unsigned long len, unsigned long pgoff, unsigned long flags)
20{27{
21 struct vm_area_struct *vmm;28 struct mm_struct *mm = current->mm;
22 int do_color_align;29 struct vm_area_struct *vma;
30 int do_align = 0;
31 struct vm_unmapped_area_info info;
32
33 /*
34 * We only need to do colour alignment if either the I or D
35 * caches alias.
36 */
37 do_align = filp || (flags & MAP_SHARED);
23 38
39 /*
40 * We enforce the MAP_FIXED case.
41 */
24 if (flags & MAP_FIXED) {42 if (flags & MAP_FIXED) {
25 /*43 if (flags & MAP_SHARED &&
26 * We do not accept a shared mapping if it would violate44 (addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1))
27 * cache aliasing constraints.
28 */
29 if ((flags & MAP_SHARED) &&
30 ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
31 return -EINVAL;45 return -EINVAL;
32 return addr;46 return addr;
33 }47 }
34 48
35 if (len > TASK_SIZE)49 if (len > TASK_SIZE)
36 return -ENOMEM;50 return -ENOMEM;
37 do_color_align = 0;51
38 if (filp || (flags & MAP_SHARED))
39 do_color_align = 1;
40 if (addr) {52 if (addr) {
41 if (do_color_align)53 if (do_align)
42 addr = COLOUR_ALIGN(addr, pgoff);54 addr = COLOUR_ALIGN(addr, pgoff);
43 else55 else
44 addr = PAGE_ALIGN(addr);56 addr = PAGE_ALIGN(addr);
45 vmm = find_vma(current->mm, addr);57
58 vma = find_vma(mm, addr);
46 if (TASK_SIZE - len >= addr &&59 if (TASK_SIZE - len >= addr &&
47 (!vmm || addr + len <= vmm->vm_start))60 (!vma || addr + len <= vm_start_gap(vma)))
48 return addr;61 return addr;
49 }62 }
50 addr = TASK_UNMAPPED_BASE;
51 if (do_color_align)
52 addr = COLOUR_ALIGN(addr, pgoff);
53 else
54 addr = PAGE_ALIGN(addr);
55 63
56 for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {64 info.flags = 0;
57 /* At this point: (!vmm || addr < vmm->vm_end). */65 info.length = len;
58 if (TASK_SIZE - len < addr)66 info.low_limit = mm->mmap_base;
59 return -ENOMEM;67 info.high_limit = TASK_SIZE;
60 if (!vmm || addr + len <= vmm->vm_start)68 info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0;
61 return addr;69 info.align_offset = pgoff << PAGE_SHIFT;
62 addr = vmm->vm_end;70 return vm_unmapped_area(&info);
63 if (do_color_align)
64 addr = COLOUR_ALIGN(addr, pgoff);
65 }
66}71}
arch/csky/include/asm/barrier.h+7−8
@@ -9,11 +9,12 @@ · 8 unmodified lines
9#define nop() asm volatile ("nop\n":::"memory")9#define nop() asm volatile ("nop\n":::"memory")
10 10
11/*11/*
12 * sync: completion barrier12 * sync: completion barrier, all sync.xx instructions
13 * sync.s: completion barrier and shareable to other cores13 * guarantee the last response recieved by bus transaction
14 * sync.i: completion barrier with flush cpu pipeline14 * made by ld/st instructions before sync.s
15 * sync.is: completion barrier with flush cpu pipeline and shareable to15 * sync.s: inherit from sync, but also shareable to other cores
16 * other cores16 * sync.i: inherit from sync, but also flush cpu pipeline
17 * sync.is: the same with sync.i + sync.s
17 *18 *
18 * bar.brwarw: ordering barrier for all load/store instructions before it19 * bar.brwarw: ordering barrier for all load/store instructions before it
19 * bar.brwarws: ordering barrier for all load/store instructions before it20 * bar.brwarws: ordering barrier for all load/store instructions before it
@@ -27,9 +28,7 @@ · 7 unmodified lines
27 */28 */
28 29
29#ifdef CONFIG_CPU_HAS_CACHEV230#ifdef CONFIG_CPU_HAS_CACHEV2
30#define mb() asm volatile ("bar.brwarw\n":::"memory")31#define mb() asm volatile ("sync.s\n":::"memory")
31#define rmb() asm volatile ("bar.brar\n":::"memory")
32#define wmb() asm volatile ("bar.bwaw\n":::"memory")
33 32
34#ifdef CONFIG_SMP33#ifdef CONFIG_SMP
35#define __smp_mb() asm volatile ("bar.brwarws\n":::"memory")34#define __smp_mb() asm volatile ("bar.brwarws\n":::"memory")
arch/csky/include/asm/cache.h+1−0
@@ -24,6 +24,7 @@ void cache_wbinv_range(unsigned long start, unsigned long end); · 23 unmodified lines
24void cache_wbinv_all(void);24void cache_wbinv_all(void);
25 25
26void dma_wbinv_range(unsigned long start, unsigned long end);26void dma_wbinv_range(unsigned long start, unsigned long end);
27void dma_inv_range(unsigned long start, unsigned long end);
27void dma_wb_range(unsigned long start, unsigned long end);28void dma_wb_range(unsigned long start, unsigned long end);
28 29
29#endif30#endif
arch/csky/include/asm/io.h+12−11
@@ -4,17 +4,10 @@ · 3 unmodified lines
4#ifndef __ASM_CSKY_IO_H4#ifndef __ASM_CSKY_IO_H
5#define __ASM_CSKY_IO_H5#define __ASM_CSKY_IO_H
6 6
7#include <abi/pgtable-bits.h>7#include <asm/pgtable.h>
8#include <linux/types.h>8#include <linux/types.h>
9#include <linux/version.h>9#include <linux/version.h>
10 10
11extern void __iomem *ioremap(phys_addr_t offset, size_t size);
12
13extern void iounmap(void *addr);
14
15extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
16 size_t size, unsigned long flags);
17
18/*11/*
19 * I/O memory access primitives. Reads are ordered relative to any12 * I/O memory access primitives. Reads are ordered relative to any
20 * following Normal memory access. Writes are ordered relative to any prior13 * following Normal memory access. Writes are ordered relative to any prior
@@ -40,9 +33,17 @@ extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr, · 19 unmodified lines
40#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); mb(); })33#define writel(v,c) ({ wmb(); writel_relaxed((v),(c)); mb(); })
41#endif34#endif
42 35
43#define ioremap_nocache(phy, sz) ioremap(phy, sz)36/*
44#define ioremap_wc ioremap_nocache37 * I/O memory mapping functions.
45#define ioremap_wt ioremap_nocache38 */
39extern void __iomem *ioremap_cache(phys_addr_t addr, size_t size);
40extern void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot);
41extern void iounmap(void *addr);
42
43#define ioremap(addr, size) __ioremap((addr), (size), pgprot_noncached(PAGE_KERNEL))
44#define ioremap_wc(addr, size) __ioremap((addr), (size), pgprot_writecombine(PAGE_KERNEL))
45#define ioremap_nocache(addr, size) ioremap((addr), (size))
46#define ioremap_cache ioremap_cache
46 47
47#include <asm-generic/io.h>48#include <asm-generic/io.h>
48 49
arch/csky/include/asm/pgtable.h+10−0
@@ -258,6 +258,16 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) · 257 unmodified lines
258{258{
259 unsigned long prot = pgprot_val(_prot);259 unsigned long prot = pgprot_val(_prot);
260 260
261 prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED | _PAGE_SO;
262
263 return __pgprot(prot);
264}
265
266#define pgprot_writecombine pgprot_writecombine
267static inline pgprot_t pgprot_writecombine(pgprot_t _prot)
268{
269 unsigned long prot = pgprot_val(_prot);
270
261 prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;271 prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
262 272
263 return __pgprot(prot);273 return __pgprot(prot);
arch/csky/kernel/entry.S+30−24
@@ -17,6 +17,12 @@ · 16 unmodified lines
17#define PTE_INDX_SHIFT 1017#define PTE_INDX_SHIFT 10
18#define _PGDIR_SHIFT 2218#define _PGDIR_SHIFT 22
19 19
20.macro zero_fp
21#ifdef CONFIG_STACKTRACE
22 movi r8, 0
23#endif
24.endm
25
20.macro tlbop_begin name, val0, val1, val226.macro tlbop_begin name, val0, val1, val2
21ENTRY(csky_\name)27ENTRY(csky_\name)
22 mtcr a3, ss228 mtcr a3, ss2
@@ -96,6 +102,7 @@ ENTRY(csky_\name) · 73 unmodified lines
96 SAVE_ALL 0102 SAVE_ALL 0
97.endm103.endm
98.macro tlbop_end is_write104.macro tlbop_end is_write
105 zero_fp
99 RD_MEH a2106 RD_MEH a2
100 psrset ee, ie107 psrset ee, ie
101 mov a0, sp108 mov a0, sp
@@ -120,6 +127,7 @@ tlbop_end 1 · 18 unmodified lines
120 127
121ENTRY(csky_systemcall)128ENTRY(csky_systemcall)
122 SAVE_ALL TRAP0_SIZE129 SAVE_ALL TRAP0_SIZE
130 zero_fp
123 131
124 psrset ee, ie132 psrset ee, ie
125 133
@@ -136,9 +144,9 @@ ENTRY(csky_systemcall) · 10 unmodified lines
136 mov r9, sp144 mov r9, sp
137 bmaski r10, THREAD_SHIFT145 bmaski r10, THREAD_SHIFT
138 andn r9, r10146 andn r9, r10
139 ldw r8, (r9, TINFO_FLAGS)147 ldw r12, (r9, TINFO_FLAGS)
140 ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)148 ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
141 cmpnei r8, 0149 cmpnei r12, 0
142 bt csky_syscall_trace150 bt csky_syscall_trace
143#if defined(__CSKYABIV2__)151#if defined(__CSKYABIV2__)
144 subi sp, 8152 subi sp, 8
@@ -180,7 +188,7 @@ csky_syscall_trace: · 35 unmodified lines
180 188
181ENTRY(ret_from_kernel_thread)189ENTRY(ret_from_kernel_thread)
182 jbsr schedule_tail190 jbsr schedule_tail
183 mov a0, r8191 mov a0, r10
184 jsr r9192 jsr r9
185 jbsr ret_from_exception193 jbsr ret_from_exception
186 194
@@ -189,9 +197,9 @@ ENTRY(ret_from_fork) · 2 unmodified lines
189 mov r9, sp197 mov r9, sp
190 bmaski r10, THREAD_SHIFT198 bmaski r10, THREAD_SHIFT
191 andn r9, r10199 andn r9, r10
192 ldw r8, (r9, TINFO_FLAGS)200 ldw r12, (r9, TINFO_FLAGS)
193 ANDI_R3 r8, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)201 ANDI_R3 r12, (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT)
194 cmpnei r8, 0202 cmpnei r12, 0
195 bf ret_from_exception203 bf ret_from_exception
196 mov a0, sp /* sp = pt_regs pointer */204 mov a0, sp /* sp = pt_regs pointer */
197 jbsr syscall_trace_exit205 jbsr syscall_trace_exit
@@ -209,9 +217,9 @@ ret_from_exception: · 11 unmodified lines
209 bmaski r10, THREAD_SHIFT217 bmaski r10, THREAD_SHIFT
210 andn r9, r10218 andn r9, r10
211 219
212 ldw r8, (r9, TINFO_FLAGS)220 ldw r12, (r9, TINFO_FLAGS)
213 andi r8, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)221 andi r12, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
214 cmpnei r8, 0222 cmpnei r12, 0
215 bt exit_work223 bt exit_work
2161:2241:
217 RESTORE_ALL225 RESTORE_ALL
@@ -220,11 +228,11 @@ exit_work: · 2 unmodified lines
220 lrw syscallid, ret_from_exception228 lrw syscallid, ret_from_exception
221 mov lr, syscallid229 mov lr, syscallid
222 230
223 btsti r8, TIF_NEED_RESCHED231 btsti r12, TIF_NEED_RESCHED
224 bt work_resched232 bt work_resched
225 233
226 mov a0, sp234 mov a0, sp
227 mov a1, r8235 mov a1, r12
228 jmpi do_notify_resume236 jmpi do_notify_resume
229 237
230work_resched:238work_resched:
@@ -232,6 +240,7 @@ work_resched: · 1 unmodified line
232 240
233ENTRY(csky_trap)241ENTRY(csky_trap)
234 SAVE_ALL 0242 SAVE_ALL 0
243 zero_fp
235 psrset ee244 psrset ee
236 mov a0, sp /* Push Stack pointer arg */245 mov a0, sp /* Push Stack pointer arg */
237 jbsr trap_c /* Call C-level trap handler */246 jbsr trap_c /* Call C-level trap handler */
@@ -265,6 +274,7 @@ ENTRY(csky_get_tls) · 27 unmodified lines
265 274
266ENTRY(csky_irq)275ENTRY(csky_irq)
267 SAVE_ALL 0276 SAVE_ALL 0
277 zero_fp
268 psrset ee278 psrset ee
269 279
270#ifdef CONFIG_PREEMPT280#ifdef CONFIG_PREEMPT
@@ -276,27 +286,23 @@ ENTRY(csky_irq) · 5 unmodified lines
276 * Get task_struct->stack.preempt_count for current,286 * Get task_struct->stack.preempt_count for current,
277 * and increase 1.287 * and increase 1.
278 */288 */
279 ldw r8, (r9, TINFO_PREEMPT)289 ldw r12, (r9, TINFO_PREEMPT)
280 addi r8, 1290 addi r12, 1
281 stw r8, (r9, TINFO_PREEMPT)291 stw r12, (r9, TINFO_PREEMPT)
282#endif292#endif
283 293
284 mov a0, sp294 mov a0, sp
285 jbsr csky_do_IRQ295 jbsr csky_do_IRQ
286 296
287#ifdef CONFIG_PREEMPT297#ifdef CONFIG_PREEMPT
288 subi r8, 1298 subi r12, 1
289 stw r8, (r9, TINFO_PREEMPT)299 stw r12, (r9, TINFO_PREEMPT)
290 cmpnei r8, 0300 cmpnei r12, 0
291 bt 2f301 bt 2f
292 ldw r8, (r9, TINFO_FLAGS)302 ldw r12, (r9, TINFO_FLAGS)
293 btsti r8, TIF_NEED_RESCHED303 btsti r12, TIF_NEED_RESCHED
294 bf 2f304 bf 2f
2951:
296 jbsr preempt_schedule_irq /* irq en/disable is done inside */305 jbsr preempt_schedule_irq /* irq en/disable is done inside */
297 ldw r7, (r9, TINFO_FLAGS) /* get new tasks TI_FLAGS */
298 btsti r7, TIF_NEED_RESCHED
299 bt 1b /* go again */
300#endif306#endif
3012:3072:
302 jmpi ret_from_exception308 jmpi ret_from_exception
arch/csky/kernel/perf_event.c+2−2
@@ -1306,7 +1306,7 @@ int csky_pmu_device_probe(struct platform_device *pdev, · 1305 unmodified lines
1306 &csky_pmu.count_width)) {1306 &csky_pmu.count_width)) {
1307 csky_pmu.count_width = DEFAULT_COUNT_WIDTH;1307 csky_pmu.count_width = DEFAULT_COUNT_WIDTH;
1308 }1308 }
1309 csky_pmu.max_period = BIT(csky_pmu.count_width) - 1;1309 csky_pmu.max_period = BIT_ULL(csky_pmu.count_width) - 1;
1310 1310
1311 csky_pmu.plat_device = pdev;1311 csky_pmu.plat_device = pdev;
1312 1312
@@ -1337,7 +1337,7 @@ int csky_pmu_device_probe(struct platform_device *pdev, · 24 unmodified lines
1337 return ret;1337 return ret;
1338}1338}
1339 1339
1340const static struct of_device_id csky_pmu_of_device_ids[] = {1340static const struct of_device_id csky_pmu_of_device_ids[] = {
1341 {.compatible = "csky,csky-pmu"},1341 {.compatible = "csky,csky-pmu"},
1342 {},1342 {},
1343};1343};
arch/csky/kernel/process.c+1−1
@@ -55,7 +55,7 @@ int copy_thread(unsigned long clone_flags, · 54 unmodified lines
55 if (unlikely(p->flags & PF_KTHREAD)) {55 if (unlikely(p->flags & PF_KTHREAD)) {
56 memset(childregs, 0, sizeof(struct pt_regs));56 memset(childregs, 0, sizeof(struct pt_regs));
57 childstack->r15 = (unsigned long) ret_from_kernel_thread;57 childstack->r15 = (unsigned long) ret_from_kernel_thread;
58 childstack->r8 = kthread_arg;58 childstack->r10 = kthread_arg;
59 childstack->r9 = usp;59 childstack->r9 = usp;
60 childregs->sr = mfcr("psr");60 childregs->sr = mfcr("psr");
61 } else {61 } else {
arch/csky/mm/cachev1.c+6−1
@@ -120,7 +120,12 @@ void dma_wbinv_range(unsigned long start, unsigned long end) · 119 unmodified lines
120 cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);120 cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
121}121}
122 122
123void dma_inv_range(unsigned long start, unsigned long end)
124{
125 cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
126}
127
123void dma_wb_range(unsigned long start, unsigned long end)128void dma_wb_range(unsigned long start, unsigned long end)
124{129{
125 cache_op_range(start, end, DATA_CACHE|CACHE_INV, 1);130 cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
126}131}
arch/csky/mm/cachev2.c+10−1
@@ -69,11 +69,20 @@ void dma_wbinv_range(unsigned long start, unsigned long end) · 68 unmodified lines
69 sync_is();69 sync_is();
70}70}
71 71
72void dma_inv_range(unsigned long start, unsigned long end)
73{
74 unsigned long i = start & ~(L1_CACHE_BYTES - 1);
75
76 for (; i < end; i += L1_CACHE_BYTES)
77 asm volatile("dcache.iva %0\n"::"r"(i):"memory");
78 sync_is();
79}
80
72void dma_wb_range(unsigned long start, unsigned long end)81void dma_wb_range(unsigned long start, unsigned long end)
73{82{
74 unsigned long i = start & ~(L1_CACHE_BYTES - 1);83 unsigned long i = start & ~(L1_CACHE_BYTES - 1);
75 84
76 for (; i < end; i += L1_CACHE_BYTES)85 for (; i < end; i += L1_CACHE_BYTES)
77 asm volatile("dcache.civa %0\n"::"r"(i):"memory");86 asm volatile("dcache.cva %0\n"::"r"(i):"memory");
78 sync_is();87 sync_is();
79}88}
arch/csky/mm/dma-mapping.c+28−48
@@ -14,69 +14,50 @@ · 13 unmodified lines
14#include <linux/version.h>14#include <linux/version.h>
15#include <asm/cache.h>15#include <asm/cache.h>
16 16
17void arch_dma_prep_coherent(struct page *page, size_t size)
18{
19 if (PageHighMem(page)) {
20 unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
21
22 do {
23 void *ptr = kmap_atomic(page);
24 size_t _size = (size < PAGE_SIZE) ? size : PAGE_SIZE;
25
26 memset(ptr, 0, _size);
27 dma_wbinv_range((unsigned long)ptr,
28 (unsigned long)ptr + _size);
29
30 kunmap_atomic(ptr);
31
32 page++;
33 size -= PAGE_SIZE;
34 count--;
35 } while (count);
36 } else {
37 void *ptr = page_address(page);
38
39 memset(ptr, 0, size);
40 dma_wbinv_range((unsigned long)ptr, (unsigned long)ptr + size);
41 }
42}
43
44static inline void cache_op(phys_addr_t paddr, size_t size,17static inline void cache_op(phys_addr_t paddr, size_t size,
45 void (*fn)(unsigned long start, unsigned long end))18 void (*fn)(unsigned long start, unsigned long end))
46{19{
47 struct page *page = pfn_to_page(paddr >> PAGE_SHIFT);20 struct page *page = phys_to_page(paddr);
48 unsigned int offset = paddr & ~PAGE_MASK;21 void *start = __va(page_to_phys(page));
49 size_t left = size;22 unsigned long offset = offset_in_page(paddr);
50 unsigned long start;23 size_t left = size;
51 24
52 do {25 do {
53 size_t len = left;26 size_t len = left;
54 27
28 if (offset + len > PAGE_SIZE)
29 len = PAGE_SIZE - offset;
30
55 if (PageHighMem(page)) {31 if (PageHighMem(page)) {
56 void *addr;32 start = kmap_atomic(page);
57 33
58 if (offset + len > PAGE_SIZE) {34 fn((unsigned long)start + offset,
59 if (offset >= PAGE_SIZE) {35 (unsigned long)start + offset + len);
60 page += offset >> PAGE_SHIFT;
61 offset &= ~PAGE_MASK;
62 }
63 len = PAGE_SIZE - offset;
64 }
65 36
66 addr = kmap_atomic(page);37 kunmap_atomic(start);
67 start = (unsigned long)(addr + offset);
68 fn(start, start + len);
69 kunmap_atomic(addr);
70 } else {38 } else {
71 start = (unsigned long)phys_to_virt(paddr);39 fn((unsigned long)start + offset,
72 fn(start, start + size);40 (unsigned long)start + offset + len);
73 }41 }
74 offset = 0;42 offset = 0;
43
75 page++;44 page++;
45 start += PAGE_SIZE;
76 left -= len;46 left -= len;
77 } while (left);47 } while (left);
78}48}
79 49
50static void dma_wbinv_set_zero_range(unsigned long start, unsigned long end)
51{
52 memset((void *)start, 0, end - start);
53 dma_wbinv_range(start, end);
54}
55
56void arch_dma_prep_coherent(struct page *page, size_t size)
57{
58 cache_op(page_to_phys(page), size, dma_wbinv_set_zero_range);
59}
60
80void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,61void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
81 size_t size, enum dma_data_direction dir)62 size_t size, enum dma_data_direction dir)
82{63{
@@ -98,11 +79,10 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr, · 15 unmodified lines
98{79{
99 switch (dir) {80 switch (dir) {
100 case DMA_TO_DEVICE:81 case DMA_TO_DEVICE:
101 cache_op(paddr, size, dma_wb_range);82 return;
102 break;
103 case DMA_FROM_DEVICE:83 case DMA_FROM_DEVICE:
104 case DMA_BIDIRECTIONAL:84 case DMA_BIDIRECTIONAL:
105 cache_op(paddr, size, dma_wbinv_range);85 cache_op(paddr, size, dma_inv_range);
106 break;86 break;
107 default:87 default:
108 BUG();88 BUG();
arch/csky/mm/init.c+0−16
@@ -60,22 +60,6 @@ void __init mem_init(void) · 59 unmodified lines
60 mem_init_print_info(NULL);60 mem_init_print_info(NULL);
61}61}
62 62
63#ifdef CONFIG_BLK_DEV_INITRD
64void free_initrd_mem(unsigned long start, unsigned long end)
65{
66 if (start < end)
67 pr_info("Freeing initrd memory: %ldk freed\n",
68 (end - start) >> 10);
69
70 for (; start < end; start += PAGE_SIZE) {
71 ClearPageReserved(virt_to_page(start));
72 init_page_count(virt_to_page(start));
73 free_page(start);
74 totalram_pages_inc();
75 }
76}
77#endif
78
79extern char __init_begin[], __init_end[];63extern char __init_begin[], __init_end[];
80 64
81void free_initmem(void)65void free_initmem(void)
arch/csky/mm/ioremap.c+18−9
@@ -8,12 +8,12 @@ · 7 unmodified lines
8 8
9#include <asm/pgtable.h>9#include <asm/pgtable.h>
10 10
11void __iomem *ioremap(phys_addr_t addr, size_t size)11static void __iomem *__ioremap_caller(phys_addr_t addr, size_t size,
12 pgprot_t prot, void *caller)
12{13{
13 phys_addr_t last_addr;14 phys_addr_t last_addr;
14 unsigned long offset, vaddr;15 unsigned long offset, vaddr;
15 struct vm_struct *area;16 struct vm_struct *area;
16 pgprot_t prot;
17 17
18 last_addr = addr + size - 1;18 last_addr = addr + size - 1;
19 if (!size || last_addr < addr)19 if (!size || last_addr < addr)
@@ -23,15 +23,12 @@ void __iomem *ioremap(phys_addr_t addr, size_t size) · 3 unmodified lines
23 addr &= PAGE_MASK;23 addr &= PAGE_MASK;
24 size = PAGE_ALIGN(size + offset);24 size = PAGE_ALIGN(size + offset);
25 25
26 area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0));26 area = get_vm_area_caller(size, VM_IOREMAP, caller);
27 if (!area)27 if (!area)
28 return NULL;28 return NULL;
29 29
30 vaddr = (unsigned long)area->addr;30 vaddr = (unsigned long)area->addr;
31 31
32 prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
33 _PAGE_GLOBAL | _CACHE_UNCACHED | _PAGE_SO);
34
35 if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {32 if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
36 free_vm_area(area);33 free_vm_area(area);
37 return NULL;34 return NULL;
@@ -39,7 +36,20 @@ void __iomem *ioremap(phys_addr_t addr, size_t size) · 1 unmodified line
39 36
40 return (void __iomem *)(vaddr + offset);37 return (void __iomem *)(vaddr + offset);
41}38}
42EXPORT_SYMBOL(ioremap);39
40void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
41{
42 return __ioremap_caller(phys_addr, size, prot,
43 __builtin_return_address(0));
44}
45EXPORT_SYMBOL(__ioremap);
46
47void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
48{
49 return __ioremap_caller(phys_addr, size, PAGE_KERNEL,
50 __builtin_return_address(0));
51}
52EXPORT_SYMBOL(ioremap_cache);
43 53
44void iounmap(void __iomem *addr)54void iounmap(void __iomem *addr)
45{55{
@@ -51,10 +61,9 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, · 5 unmodified lines
51 unsigned long size, pgprot_t vma_prot)61 unsigned long size, pgprot_t vma_prot)
52{62{
53 if (!pfn_valid(pfn)) {63 if (!pfn_valid(pfn)) {
54 vma_prot.pgprot |= _PAGE_SO;
55 return pgprot_noncached(vma_prot);64 return pgprot_noncached(vma_prot);
56 } else if (file->f_flags & O_SYNC) {65 } else if (file->f_flags & O_SYNC) {
57 return pgprot_noncached(vma_prot);66 return pgprot_writecombine(vma_prot);
58 }67 }
59 68
60 return vma_prot;69 return vma_prot;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t