linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/19] C-SKY(csky) Linux Kernel Port
@ 2018-03-18 19:51 Guo Ren
  2018-03-18 19:51 ` [PATCH 01/19] csky: Kernel booting Guo Ren
                   ` (20 more replies)
  0 siblings, 21 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

This patchset adds architecture support to Linux for C-SKY's 32-bit embedded
CPU cores and the patches are based on linux-4.16-rc5.

There are two ABI versions with several CPU cores in this patchset:
  ABIv1: ck610 (16-bit instruction, 32-bit data path, VIPT Cache ...)
  ABIv2: ck807 ck810 (16/32-bit variable length instruction, PIPT Cache ...)

More information: http://en.c-sky.com

I'm from Hangzhou,China C-SKY Microsystems and responsible for C-SKY Linux
port. My development repo is github.com/c-sky/csky-linux and use buildroot
as our CI-test enviornment. "LTP, Lmbench, uclibc-ng-test ..." will be tested
for every commit. See here for more details:
  https://gitlab.com/c-sky/buildroot/pipelines

You can try C-SKY linux in a few steps:
  $ git clone https://github.com/c-sky/buildroot.git
  $ cd buildroot
  $ make qemu_csky_ck807_uclibc_bt_defconfig
  $ make
It will download "linux uclibc-ng gcc binutils qemu busybox" source code and build
them into one image. How to run, See:
  https://github.com/c-sky/buildroot/blob/master/board/qemu/csky/readme.txt

I've finished uClibc-ng.org upstream and "gcc glibc binutils qemu ..." upstream is
on going and the source code is here:
  https://github.com/c-sky

It's my first patchset to linux and any feedback is welcome :)

Guo Ren (19):
  csky: Kernel booting
  csky: Exception handling and syscall
  csky: Cache and TLB routines
  csky: MMU and page talbe management
  csky: Process management
  csky: IRQ handling
  csky: Atomic operations
  csky: ELF and module probe
  csky: VDSO and rt_sigreturn
  csky: Signal handling
  csky: Library functions
  csky: Debug and Ptrace GDB
  csky: User access
  csky: Misc headers
  csky: Build infrastructure
  csky: Device tree
  csky: defconfig
  clocksource: add timer-nationalchip.c
  irqchip: add irq-nationalchip.c and irq-csky.c

 arch/csky/Kconfig                        | 203 ++++++++++++
 arch/csky/Kconfig.debug                  |  22 ++
 arch/csky/Makefile                       |  92 ++++++
 arch/csky/abiv1/Makefile                 |   8 +
 arch/csky/abiv1/inc/abi/cacheflush.h     |  40 +++
 arch/csky/abiv1/inc/abi/ckmmu.h          | 140 ++++++++
 arch/csky/abiv1/inc/abi/entry.h          | 171 ++++++++++
 arch/csky/abiv1/inc/abi/page.h           |  26 ++
 arch/csky/abiv1/inc/abi/pgtable-bits.h   |  36 ++
 arch/csky/abiv1/inc/abi/reg_ops.h        |  79 +++++
 arch/csky/abiv1/inc/abi/regdef.h         |  27 ++
 arch/csky/abiv1/inc/abi/vdso.h           |  19 ++
 arch/csky/abiv1/src/alignment.c          | 513 +++++++++++++++++++++++++++++
 arch/csky/abiv1/src/bswapdi.c            |  18 +
 arch/csky/abiv1/src/bswapsi.c            |  15 +
 arch/csky/abiv1/src/cacheflush.c         |  32 ++
 arch/csky/abiv1/src/memcpy.S             | 344 +++++++++++++++++++
 arch/csky/abiv1/src/mmap.c               |  65 ++++
 arch/csky/abiv2/Makefile                 |   3 +
 arch/csky/abiv2/inc/abi/cacheflush.h     |   9 +
 arch/csky/abiv2/inc/abi/ckmmu.h          | 126 +++++++
 arch/csky/abiv2/inc/abi/entry.h          | 154 +++++++++
 arch/csky/abiv2/inc/abi/fpu.h            | 296 +++++++++++++++++
 arch/csky/abiv2/inc/abi/page.h           |  20 ++
 arch/csky/abiv2/inc/abi/pgtable-bits.h   |  36 ++
 arch/csky/abiv2/inc/abi/reg_ops.h        |  86 +++++
 arch/csky/abiv2/inc/abi/regdef.h         |  28 ++
 arch/csky/abiv2/inc/abi/vdso.h           |  18 +
 arch/csky/abiv2/src/fpu.c                | 312 ++++++++++++++++++
 arch/csky/abiv2/src/memcpy.c             |  43 +++
 arch/csky/boot/Makefile                  |  25 ++
 arch/csky/boot/dts/Makefile              |  14 +
 arch/csky/boot/dts/gx6605s.dts           | 159 +++++++++
 arch/csky/boot/dts/include/dt-bindings   |   1 +
 arch/csky/boot/dts/qemu.dts              |  87 +++++
 arch/csky/configs/gx66xx_defconfig       | 549 +++++++++++++++++++++++++++++++
 arch/csky/configs/qemu_ck807_defconfig   | 541 ++++++++++++++++++++++++++++++
 arch/csky/include/asm/Kbuild             |  71 ++++
 arch/csky/include/asm/addrspace.h        |  10 +
 arch/csky/include/asm/barrier.h          |  14 +
 arch/csky/include/asm/bitops.h           |  83 +++++
 arch/csky/include/asm/cache.h            |  32 ++
 arch/csky/include/asm/cacheflush.h       |   9 +
 arch/csky/include/asm/checksum.h         |  77 +++++
 arch/csky/include/asm/dma-mapping.h      |  17 +
 arch/csky/include/asm/elf.h              | 151 +++++++++
 arch/csky/include/asm/fixmap.h           |  65 ++++
 arch/csky/include/asm/highmem.h          |  50 +++
 arch/csky/include/asm/io.h               |  23 ++
 arch/csky/include/asm/irq.h              |  12 +
 arch/csky/include/asm/irqflags.h         |  55 ++++
 arch/csky/include/asm/mmu.h              |  11 +
 arch/csky/include/asm/mmu_context.h      | 140 ++++++++
 arch/csky/include/asm/page.h             | 108 ++++++
 arch/csky/include/asm/pgalloc.h          | 113 +++++++
 arch/csky/include/asm/pgtable.h          | 309 +++++++++++++++++
 arch/csky/include/asm/processor.h        | 140 ++++++++
 arch/csky/include/asm/segment.h          |  18 +
 arch/csky/include/asm/shmparam.h         |  10 +
 arch/csky/include/asm/string.h           |  19 ++
 arch/csky/include/asm/syscalls.h         |  14 +
 arch/csky/include/asm/thread_info.h      |  77 +++++
 arch/csky/include/asm/tlb.h              |  24 ++
 arch/csky/include/asm/tlbflush.h         |  22 ++
 arch/csky/include/asm/traps.h            |  39 +++
 arch/csky/include/asm/uaccess.h          | 408 +++++++++++++++++++++++
 arch/csky/include/asm/unistd.h           |   4 +
 arch/csky/include/asm/user.h             | 102 ++++++
 arch/csky/include/asm/vdso.h             |  12 +
 arch/csky/include/uapi/asm/Kbuild        |  30 ++
 arch/csky/include/uapi/asm/byteorder.h   |  14 +
 arch/csky/include/uapi/asm/cachectl.h    |  13 +
 arch/csky/include/uapi/asm/fcntl.h       |  13 +
 arch/csky/include/uapi/asm/ptrace.h      |  97 ++++++
 arch/csky/include/uapi/asm/sigcontext.h  |  33 ++
 arch/csky/include/uapi/asm/signal.h      | 164 +++++++++
 arch/csky/include/uapi/asm/stat.h        |  86 +++++
 arch/csky/include/uapi/asm/unistd.h      | 100 ++++++
 arch/csky/kernel/Makefile                |   8 +
 arch/csky/kernel/asm-offsets.c           |  86 +++++
 arch/csky/kernel/atomic.S                |  55 ++++
 arch/csky/kernel/cpu-probe.c             |  63 ++++
 arch/csky/kernel/cskyksyms.c             |  31 ++
 arch/csky/kernel/dumpstack.c             |  65 ++++
 arch/csky/kernel/entry.S                 | 408 +++++++++++++++++++++++
 arch/csky/kernel/head.S                  |  20 ++
 arch/csky/kernel/irq.c                   |  41 +++
 arch/csky/kernel/module.c                | 130 ++++++++
 arch/csky/kernel/platform.c              |  18 +
 arch/csky/kernel/power.c                 |  31 ++
 arch/csky/kernel/process.c               | 147 +++++++++
 arch/csky/kernel/ptrace.c                | 339 +++++++++++++++++++
 arch/csky/kernel/setup.c                 | 157 +++++++++
 arch/csky/kernel/signal.c                | 379 +++++++++++++++++++++
 arch/csky/kernel/syscall.c               |  65 ++++
 arch/csky/kernel/syscall_table.c         |  12 +
 arch/csky/kernel/time.c                  |  15 +
 arch/csky/kernel/traps.c                 | 152 +++++++++
 arch/csky/kernel/vdso.c                  |  89 +++++
 arch/csky/kernel/vmlinux.lds.S           |  67 ++++
 arch/csky/lib/Makefile                   |   1 +
 arch/csky/lib/delay.c                    |  40 +++
 arch/csky/lib/memset.c                   |  38 +++
 arch/csky/lib/usercopy.c                 | 271 +++++++++++++++
 arch/csky/mm/Makefile                    |  13 +
 arch/csky/mm/cachev1.c                   | 146 ++++++++
 arch/csky/mm/cachev2.c                   |  90 +++++
 arch/csky/mm/dma-mapping.c               | 250 ++++++++++++++
 arch/csky/mm/fault.c                     | 246 ++++++++++++++
 arch/csky/mm/highmem.c                   | 210 ++++++++++++
 arch/csky/mm/init.c                      | 101 ++++++
 arch/csky/mm/ioremap.c                   |  49 +++
 arch/csky/mm/syscache.c                  |  50 +++
 arch/csky/mm/tlb.c                       | 207 ++++++++++++
 arch/csky/oprofile/Makefile              |  13 +
 arch/csky/oprofile/init.c                |  16 +
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/timer-nationalchip.c | 149 +++++++++
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-csky.c               | 151 +++++++++
 drivers/irqchip/irq-nationalchip.c       | 196 +++++++++++
 121 files changed, 11763 insertions(+)
 create mode 100644 arch/csky/Kconfig
 create mode 100644 arch/csky/Kconfig.debug
 create mode 100644 arch/csky/Makefile
 create mode 100644 arch/csky/abiv1/Makefile
 create mode 100644 arch/csky/abiv1/inc/abi/cacheflush.h
 create mode 100644 arch/csky/abiv1/inc/abi/ckmmu.h
 create mode 100644 arch/csky/abiv1/inc/abi/entry.h
 create mode 100644 arch/csky/abiv1/inc/abi/page.h
 create mode 100644 arch/csky/abiv1/inc/abi/pgtable-bits.h
 create mode 100644 arch/csky/abiv1/inc/abi/reg_ops.h
 create mode 100644 arch/csky/abiv1/inc/abi/regdef.h
 create mode 100644 arch/csky/abiv1/inc/abi/vdso.h
 create mode 100644 arch/csky/abiv1/src/alignment.c
 create mode 100644 arch/csky/abiv1/src/bswapdi.c
 create mode 100644 arch/csky/abiv1/src/bswapsi.c
 create mode 100644 arch/csky/abiv1/src/cacheflush.c
 create mode 100644 arch/csky/abiv1/src/memcpy.S
 create mode 100644 arch/csky/abiv1/src/mmap.c
 create mode 100644 arch/csky/abiv2/Makefile
 create mode 100644 arch/csky/abiv2/inc/abi/cacheflush.h
 create mode 100644 arch/csky/abiv2/inc/abi/ckmmu.h
 create mode 100644 arch/csky/abiv2/inc/abi/entry.h
 create mode 100644 arch/csky/abiv2/inc/abi/fpu.h
 create mode 100644 arch/csky/abiv2/inc/abi/page.h
 create mode 100644 arch/csky/abiv2/inc/abi/pgtable-bits.h
 create mode 100644 arch/csky/abiv2/inc/abi/reg_ops.h
 create mode 100644 arch/csky/abiv2/inc/abi/regdef.h
 create mode 100644 arch/csky/abiv2/inc/abi/vdso.h
 create mode 100644 arch/csky/abiv2/src/fpu.c
 create mode 100644 arch/csky/abiv2/src/memcpy.c
 create mode 100644 arch/csky/boot/Makefile
 create mode 100644 arch/csky/boot/dts/Makefile
 create mode 100644 arch/csky/boot/dts/gx6605s.dts
 create mode 120000 arch/csky/boot/dts/include/dt-bindings
 create mode 100644 arch/csky/boot/dts/qemu.dts
 create mode 100644 arch/csky/configs/gx66xx_defconfig
 create mode 100644 arch/csky/configs/qemu_ck807_defconfig
 create mode 100644 arch/csky/include/asm/Kbuild
 create mode 100644 arch/csky/include/asm/addrspace.h
 create mode 100644 arch/csky/include/asm/barrier.h
 create mode 100644 arch/csky/include/asm/bitops.h
 create mode 100644 arch/csky/include/asm/cache.h
 create mode 100644 arch/csky/include/asm/cacheflush.h
 create mode 100644 arch/csky/include/asm/checksum.h
 create mode 100644 arch/csky/include/asm/dma-mapping.h
 create mode 100644 arch/csky/include/asm/elf.h
 create mode 100644 arch/csky/include/asm/fixmap.h
 create mode 100644 arch/csky/include/asm/highmem.h
 create mode 100644 arch/csky/include/asm/io.h
 create mode 100644 arch/csky/include/asm/irq.h
 create mode 100644 arch/csky/include/asm/irqflags.h
 create mode 100644 arch/csky/include/asm/mmu.h
 create mode 100644 arch/csky/include/asm/mmu_context.h
 create mode 100644 arch/csky/include/asm/page.h
 create mode 100644 arch/csky/include/asm/pgalloc.h
 create mode 100644 arch/csky/include/asm/pgtable.h
 create mode 100644 arch/csky/include/asm/processor.h
 create mode 100644 arch/csky/include/asm/segment.h
 create mode 100644 arch/csky/include/asm/shmparam.h
 create mode 100644 arch/csky/include/asm/string.h
 create mode 100644 arch/csky/include/asm/syscalls.h
 create mode 100644 arch/csky/include/asm/thread_info.h
 create mode 100644 arch/csky/include/asm/tlb.h
 create mode 100644 arch/csky/include/asm/tlbflush.h
 create mode 100644 arch/csky/include/asm/traps.h
 create mode 100644 arch/csky/include/asm/uaccess.h
 create mode 100644 arch/csky/include/asm/unistd.h
 create mode 100644 arch/csky/include/asm/user.h
 create mode 100644 arch/csky/include/asm/vdso.h
 create mode 100644 arch/csky/include/uapi/asm/Kbuild
 create mode 100644 arch/csky/include/uapi/asm/byteorder.h
 create mode 100644 arch/csky/include/uapi/asm/cachectl.h
 create mode 100644 arch/csky/include/uapi/asm/fcntl.h
 create mode 100644 arch/csky/include/uapi/asm/ptrace.h
 create mode 100644 arch/csky/include/uapi/asm/sigcontext.h
 create mode 100644 arch/csky/include/uapi/asm/signal.h
 create mode 100644 arch/csky/include/uapi/asm/stat.h
 create mode 100644 arch/csky/include/uapi/asm/unistd.h
 create mode 100644 arch/csky/kernel/Makefile
 create mode 100644 arch/csky/kernel/asm-offsets.c
 create mode 100644 arch/csky/kernel/atomic.S
 create mode 100644 arch/csky/kernel/cpu-probe.c
 create mode 100644 arch/csky/kernel/cskyksyms.c
 create mode 100644 arch/csky/kernel/dumpstack.c
 create mode 100644 arch/csky/kernel/entry.S
 create mode 100644 arch/csky/kernel/head.S
 create mode 100644 arch/csky/kernel/irq.c
 create mode 100644 arch/csky/kernel/module.c
 create mode 100644 arch/csky/kernel/platform.c
 create mode 100644 arch/csky/kernel/power.c
 create mode 100644 arch/csky/kernel/process.c
 create mode 100644 arch/csky/kernel/ptrace.c
 create mode 100644 arch/csky/kernel/setup.c
 create mode 100644 arch/csky/kernel/signal.c
 create mode 100644 arch/csky/kernel/syscall.c
 create mode 100644 arch/csky/kernel/syscall_table.c
 create mode 100644 arch/csky/kernel/time.c
 create mode 100644 arch/csky/kernel/traps.c
 create mode 100644 arch/csky/kernel/vdso.c
 create mode 100644 arch/csky/kernel/vmlinux.lds.S
 create mode 100644 arch/csky/lib/Makefile
 create mode 100644 arch/csky/lib/delay.c
 create mode 100644 arch/csky/lib/memset.c
 create mode 100644 arch/csky/lib/usercopy.c
 create mode 100644 arch/csky/mm/Makefile
 create mode 100644 arch/csky/mm/cachev1.c
 create mode 100644 arch/csky/mm/cachev2.c
 create mode 100644 arch/csky/mm/dma-mapping.c
 create mode 100644 arch/csky/mm/fault.c
 create mode 100644 arch/csky/mm/highmem.c
 create mode 100644 arch/csky/mm/init.c
 create mode 100644 arch/csky/mm/ioremap.c
 create mode 100644 arch/csky/mm/syscache.c
 create mode 100644 arch/csky/mm/tlb.c
 create mode 100644 arch/csky/oprofile/Makefile
 create mode 100644 arch/csky/oprofile/init.c
 create mode 100644 drivers/clocksource/timer-nationalchip.c
 create mode 100644 drivers/irqchip/irq-csky.c
 create mode 100644 drivers/irqchip/irq-nationalchip.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH 01/19] csky: Kernel booting
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 02/19] csky: Exception handling and syscall Guo Ren
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/kernel/head.S  |  20 ++++++
 arch/csky/kernel/setup.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 177 insertions(+)
 create mode 100644 arch/csky/kernel/head.S
 create mode 100644 arch/csky/kernel/setup.c

diff --git a/arch/csky/kernel/head.S b/arch/csky/kernel/head.S
new file mode 100644
index 0000000..a746caf
--- /dev/null
+++ b/arch/csky/kernel/head.S
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include <abi/regdef.h>
+
+ENTRY(_start)
+	/* set super user mode */
+	lrw	a3, DEFAULT_PSR_VALUE
+	mtcr    a3, psr
+	psrset  ee
+
+	/* set stack point */
+	lrw     a3, init_thread_union + THREAD_SIZE
+	mov	sp, a3
+
+	jmpi	csky_start
+END(_start)
+
diff --git a/arch/csky/kernel/setup.c b/arch/csky/kernel/setup.c
new file mode 100644
index 0000000..04c9fbd
--- /dev/null
+++ b/arch/csky/kernel/setup.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/console.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+#include <linux/initrd.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/start_kernel.h>
+#include <asm/sections.h>
+#include <asm/mmu_context.h>
+#include <asm/pgalloc.h>
+
+phys_addr_t __init_memblock memblock_end_of_REG0(void)
+{
+	return (memblock.memory.regions[0].base + memblock.memory.regions[0].size);
+}
+
+phys_addr_t __init_memblock memblock_start_of_REG1(void)
+{
+	return memblock.memory.regions[1].base;
+}
+
+size_t __init_memblock memblock_size_of_REG1(void)
+{
+	return memblock.memory.regions[1].size;
+}
+
+static void __init csky_memblock_init(void)
+{
+	unsigned long zone_size[MAX_NR_ZONES];
+	unsigned long zhole_size[MAX_NR_ZONES];
+	signed long size;
+
+	memblock_reserve(__pa(_stext), _end - _stext);
+#ifdef CONFIG_BLK_DEV_INITRD
+	memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
+#endif
+
+	early_init_fdt_reserve_self();
+	early_init_fdt_scan_reserved_mem();
+
+	memblock_dump_all();
+
+	memset(zone_size, 0, sizeof(zone_size));
+	memset(zhole_size, 0, sizeof(zhole_size));
+
+	min_low_pfn = PFN_UP(memblock_start_of_DRAM());
+	max_low_pfn = PFN_UP(memblock_end_of_REG0());
+	max_pfn = PFN_DOWN(memblock_end_of_DRAM());
+
+	size = max_pfn - min_low_pfn;
+
+	if (memblock.memory.cnt > 1) {
+		zone_size[ZONE_NORMAL]  = PFN_DOWN(memblock_start_of_REG1()) - min_low_pfn;
+		zhole_size[ZONE_NORMAL] = PFN_DOWN(memblock_start_of_REG1()) - max_low_pfn;
+	} else {
+		if (size <= PFN_DOWN(LOWMEM_LIMIT - CONFIG_RAM_BASE))
+			zone_size[ZONE_NORMAL] = max_pfn - min_low_pfn;
+		else {
+			zone_size[ZONE_NORMAL] = PFN_DOWN(LOWMEM_LIMIT - CONFIG_RAM_BASE);
+			max_low_pfn = min_low_pfn + zone_size[ZONE_NORMAL];
+		}
+	}
+
+#ifdef CONFIG_HIGHMEM
+	size = 0;
+	if(memblock.memory.cnt > 1) {
+		size = PFN_DOWN(memblock_size_of_REG1());
+		highstart_pfn = PFN_DOWN(memblock_start_of_REG1());
+	} else {
+		size = max_pfn - min_low_pfn - PFN_DOWN(LOWMEM_LIMIT - CONFIG_RAM_BASE);
+		highstart_pfn =  min_low_pfn + PFN_DOWN(LOWMEM_LIMIT - CONFIG_RAM_BASE);
+	}
+
+	if (size > 0)
+		zone_size[ZONE_HIGHMEM] = size;
+
+	highend_pfn = max_pfn;
+#endif
+	memblock_set_current_limit(PFN_PHYS(max_low_pfn));
+
+	free_area_init_node(0, zone_size, min_low_pfn, zhole_size);
+}
+
+extern void cpu_dt_probe(void);
+void __init setup_arch(char **cmdline_p)
+{
+	*cmdline_p = boot_command_line;
+
+	console_verbose();
+
+	printk("C-SKY: https://c-sky.github.io\n");
+
+	init_mm.start_code = (unsigned long) _stext;
+	init_mm.end_code = (unsigned long) _etext;
+	init_mm.end_data = (unsigned long) _edata;
+	init_mm.brk = (unsigned long) _end;
+
+	parse_early_param();
+
+	csky_memblock_init();
+
+	unflatten_and_copy_device_tree();
+
+	cpu_dt_probe();
+
+	sparse_init();
+
+#ifdef CONFIG_HIGHMEM
+	kmap_init();
+#endif
+	cache_wbinv_all();
+
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+}
+
+extern void pre_trap_init(void);
+asmlinkage __visible void __init csky_start(
+	unsigned int	unused,
+	void *		param
+	)
+{
+	/* Clean up bss section */
+	memset(__bss_start, 0, __bss_stop - __bss_start);
+
+	pre_trap_init();
+
+	/* Setup mmu as coprocessor */
+	select_mmu_cp();
+
+	/*
+	 * Setup page-table and enable TLB-hardrefill
+	 */
+	flush_tlb_all();
+	pgd_init((unsigned long *)swapper_pg_dir);
+	TLBMISS_HANDLER_SETUP_PGD(swapper_pg_dir);
+
+	asid_cache(smp_processor_id()) = ASID_FIRST_VERSION;
+
+	/* Setup page mask to 4k */
+	write_mmu_pagemask(0);
+
+#ifdef CONFIG_CSKY_BUILTIN_DTB
+	printk("Use builtin dtb\n");
+	early_init_dt_scan(__dtb_start);
+#else
+	early_init_dt_scan(param);
+#endif
+	printk("Phys. mem: %ldMB\n", (unsigned long) memblock_phys_mem_size()/1024/1024);
+	start_kernel();
+
+	while(1);
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 02/19] csky: Exception handling and syscall
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
  2018-03-18 19:51 ` [PATCH 01/19] csky: Kernel booting Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-19  1:48   ` Mark Rutland
  2018-03-19  8:50   ` Dominik Brodowski
  2018-03-18 19:51 ` [PATCH 03/19] csky: Cache and TLB routines Guo Ren
                   ` (18 subsequent siblings)
  20 siblings, 2 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/abiv1/inc/abi/entry.h     | 171 ++++++++++++
 arch/csky/abiv1/src/alignment.c     | 513 ++++++++++++++++++++++++++++++++++++
 arch/csky/abiv2/inc/abi/entry.h     | 154 +++++++++++
 arch/csky/include/asm/syscalls.h    |  14 +
 arch/csky/include/asm/traps.h       |  39 +++
 arch/csky/include/asm/unistd.h      |   4 +
 arch/csky/include/uapi/asm/unistd.h | 100 +++++++
 arch/csky/kernel/cpu-probe.c        |  63 +++++
 arch/csky/kernel/entry.S            | 408 ++++++++++++++++++++++++++++
 arch/csky/kernel/syscall.c          |  65 +++++
 arch/csky/kernel/syscall_table.c    |  12 +
 arch/csky/kernel/traps.c            | 152 +++++++++++
 arch/csky/mm/fault.c                | 246 +++++++++++++++++
 13 files changed, 1941 insertions(+)
 create mode 100644 arch/csky/abiv1/inc/abi/entry.h
 create mode 100644 arch/csky/abiv1/src/alignment.c
 create mode 100644 arch/csky/abiv2/inc/abi/entry.h
 create mode 100644 arch/csky/include/asm/syscalls.h
 create mode 100644 arch/csky/include/asm/traps.h
 create mode 100644 arch/csky/include/asm/unistd.h
 create mode 100644 arch/csky/include/uapi/asm/unistd.h
 create mode 100644 arch/csky/kernel/cpu-probe.c
 create mode 100644 arch/csky/kernel/entry.S
 create mode 100644 arch/csky/kernel/syscall.c
 create mode 100644 arch/csky/kernel/syscall_table.c
 create mode 100644 arch/csky/kernel/traps.c
 create mode 100644 arch/csky/mm/fault.c

diff --git a/arch/csky/abiv1/inc/abi/entry.h b/arch/csky/abiv1/inc/abi/entry.h
new file mode 100644
index 0000000..bff3ff2
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/entry.h
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_ENTRY_H
+#define __ASM_CSKY_ENTRY_H
+
+#include <asm/setup.h>
+#include <abi/regdef.h>
+
+/*
+ * Stack layout for exception (sp=r0):
+ *
+ *	 0(sp) - pc
+ *	 4(sp) - orig_a0
+ *	 8(sp) - sr
+ *	 C(sp) - a0/r2
+ *	10(sp) - a1/r3
+ *	14(sp) - a2/r4
+ *	18(sp) - a3/r5
+ *	1C(sp) - r6
+ *	20(sp) - r7
+ *	24(sp) - r8
+ *	28(sp) - r9
+ *	2C(sp) - r10
+ *	30(sp) - r11
+ *	34(sp) - r12
+ *	38(sp) - r13
+ *	3C(sp) - r14
+ *	40(sp) - r1
+ *	44(sp) - r15
+ */
+
+#define LSAVE_A0	0xc
+#define LSAVE_A1	0x10
+#define LSAVE_A2	0x14
+#define LSAVE_A3	0x18
+#define LSAVE_A4	0x1C
+#define LSAVE_A5	0x20
+
+.macro USPTOKSP
+	mtcr	sp, ss1
+	mfcr	sp, ss0
+.endm
+
+.macro KSPTOUSP
+	mtcr	sp, ss0
+	mfcr	sp, ss1
+.endm
+
+.macro GET_USP rx
+	mfcr	\rx, ss1
+.endm
+
+.macro SET_USP rx
+	mtcr	\rx, ss1
+.endm
+
+.macro INCTRAP	rx
+	addi	\rx, 2
+.endm
+
+/*
+ * SAVE_ALL: save the pt_regs to the stack.
+ */
+.macro	SAVE_ALL
+	mtcr    r13, ss2
+	mfcr    r13, epsr
+	btsti   r13, 31
+	bt      1f
+	USPTOKSP
+1:
+	subi    sp, 32
+	subi    sp, 32
+	stw     r13,	(sp, 0)
+	mfcr    r13,	ss2
+	stw     a0,	(sp, 4)
+	stw     a1,	(sp, 8)
+	stw     a2,	(sp, 12)
+	stw     a3,	(sp, 16)
+	stw     r6,	(sp, 20)
+	stw     r7,	(sp, 24)
+	stw     r8,	(sp, 28)
+	stw     r9,	(sp, 32)
+	stw     r10,	(sp, 36)
+	stw     r11,	(sp, 40)
+	stw     r12,	(sp, 44)
+	stw     r13,	(sp, 48)
+	stw     r14,	(sp, 52)
+	stw     r1,	(sp, 56)
+	stw     r15,	(sp, 60)
+
+	subi    sp,	8
+	stw     a0,	(sp, 4)
+	mfcr    r13,	epc
+	stw     r13,	(sp)
+.endm
+
+.macro SAVE_ALL_TRAP
+	SAVE_ALL
+	INCTRAP r13
+	stw     r13,	(sp)
+.endm
+
+.macro	RESTORE_ALL
+	psrclr  ie
+	ldw     a0, (sp)
+	mtcr    a0, epc
+	ldw     a0, (sp, 8)
+	mtcr    a0, epsr
+	btsti   a0, 31
+
+	addi    sp, 12
+	ldw     a0, (sp, 0)
+	ldw     a1, (sp, 4)
+	ldw     a2, (sp, 8)
+	ldw     a3, (sp, 12)
+	ldw     r6, (sp, 16)
+	ldw     r7, (sp, 20)
+	ldw     r8, (sp, 24)
+	ldw     r9, (sp, 28)
+	ldw     r10, (sp, 32)
+	ldw     r11, (sp, 36)
+	ldw     r12, (sp, 40)
+	ldw     r13, (sp, 44)
+	ldw     r14, (sp, 48)
+	ldw     r1, (sp, 52)
+	ldw     r15, (sp, 56)
+	addi    sp, 32
+	addi    sp, 28
+
+	bt      1f
+	KSPTOUSP
+1:
+	rte
+.endm
+
+.macro SAVE_SWITCH_STACK
+	subi    sp, 32
+	stm     r8-r15,(sp)
+.endm
+
+.macro RESTORE_SWITCH_STACK
+        ldm     r8-r15,(sp)
+        addi    sp, 32
+.endm
+
+/* MMU registers operators. */
+.macro RD_MIR	rx
+	cprcr   \rx, cpcr0
+.endm
+
+.macro RD_MEH	rx
+	cprcr   \rx, cpcr4
+.endm
+
+.macro RD_MCIR	rx
+	cprcr   \rx, cpcr8
+.endm
+
+.macro RD_PGDR  rx
+        cprcr   \rx, cpcr29
+.endm
+
+.macro WR_MEH	rx
+	cpwcr   \rx, cpcr4
+.endm
+
+.macro WR_MCIR	rx
+	cpwcr   \rx, cpcr8
+.endm
+
+#endif /* __ASM_CSKY_ENTRY_H */
diff --git a/arch/csky/abiv1/src/alignment.c b/arch/csky/abiv1/src/alignment.c
new file mode 100644
index 0000000..436c389
--- /dev/null
+++ b/arch/csky/abiv1/src/alignment.c
@@ -0,0 +1,513 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/ptrace.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/uaccess.h>
+
+#include <asm/siginfo.h>
+#include <asm/unaligned.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+#define HANDLER_SUCCESS 0
+#define HANDLER_FAILURE	1
+#define SP_NUM 0
+#define R4_NUM 4
+#define R15_NUM 4
+#define R16_NUM 16
+#define R28_NUM 28
+
+#define CODING_BITS(i)  (i & 0xFC000000)
+#define LDST_TYPE(i)    (i & 0xf000)
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_qword;
+static int ai_usermode;
+
+#define UM_WARN		(1 << 0)
+#define UM_FIXUP	(1 << 1)
+#define UM_SIGNAL	(1 << 2)
+
+static const char *usermode_action[] = {
+	"ignored",
+	"warn",
+	"fixup",
+	"fixup+warn",
+	"signal",
+	"signal+warn"
+};
+
+static int alignment_proc_show(struct seq_file *m, void *v)
+{
+	seq_printf(m, "User:\t\t%lu\n", ai_user);
+	seq_printf(m, "System:\t\t%lu\n", ai_sys);
+	seq_printf(m, "Skipped:\t%lu\n", ai_skipped);
+	seq_printf(m, "Half:\t\t%lu\n", ai_half);
+	seq_printf(m, "Word:\t\t%lu\n", ai_word);
+	seq_printf(m, "Qword:\t\t%lu\n", ai_qword);
+	seq_printf(m, "User faults:\t%i (%s)\n", ai_usermode,
+			usermode_action[ai_usermode]);
+
+	return 0;
+}
+
+static int alignment_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, alignment_proc_show, NULL);
+}
+
+static int proc_alignment_write(struct file *file, const char __user *buffer,
+				size_t count, loff_t *pos)
+{
+	char mode;
+
+	if (count > 0) {
+		if (get_user(mode, buffer))
+			return -EFAULT;
+		if (mode >= '0' && mode <= '5')
+			ai_usermode = mode - '0';
+	}
+	return count;
+}
+
+static const struct file_operations alignment_proc_fops = {
+	.open		= alignment_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+	.write		= proc_alignment_write,
+};
+
+#ifdef  __cskyBE__
+#define BE		1
+#define FIRST_BYTE_16	"rotri	%1, 8\n"
+#define FIRST_BYTE_32	"rotri	%1, 24\n"
+#define NEXT_BYTE	"rotri  %1, 24\n"
+#else
+#define BE		0
+#define FIRST_BYTE_16
+#define FIRST_BYTE_32
+#define NEXT_BYTE	"lsri   %1, 8\n"
+#endif
+
+#define __get8_unaligned_check(val,addr,err)		\
+	asm(					\
+	"1:	ldb	%1, (%2)\n"			\
+	"	addi	%2, 1\n"			\
+	"	br	3f\n"				\
+	"2:	movi	%0, 1\n"			\
+	"	br	3f\n"				\
+	"	.section __ex_table,\"a\"\n"		\
+	"	.align	2\n"				\
+	"	.long	1b, 2b\n"			\
+	"	.previous\n"				\
+	"3:\n"						\
+	: "=r" (err), "=r" (val), "=r" (addr)		\
+	: "0" (err), "2" (addr))
+
+#define get16_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		__get8_unaligned_check(v,a,err);		\
+		val =  v << ((BE) ? 8 : 0);			\
+		__get8_unaligned_check(v,a,err);		\
+		val |= v << ((BE) ? 0 : 8);			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define get32_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v, a = addr;		\
+		__get8_unaligned_check(v,a,err);		\
+		val =  v << ((BE) ? 24 :  0);			\
+		__get8_unaligned_check(v,a,err);		\
+		val |= v << ((BE) ? 16 :  8);			\
+		__get8_unaligned_check(v,a,err);		\
+		val |= v << ((BE) ?  8 : 16);			\
+		__get8_unaligned_check(v,a,err);		\
+		val |= v << ((BE) ?  0 : 24);			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put16_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		asm( FIRST_BYTE_16				\
+		"1:	stb	%1, (%2)\n"			\
+		"	addi	%2, 1\n"			\
+			NEXT_BYTE				\
+		"2:	stb	%1, (%2)\n"			\
+		"	br	4f\n"				\
+		"3:	movi	%0, 1\n"			\
+		"	br	4f\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	2\n"				\
+		"	.long	1b, 3b\n"			\
+		"	.long	2b, 3b\n"			\
+		"	.previous\n"				\
+		"4:\n"						\
+		: "=r" (err), "=r" (v), "=r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+#define put32_unaligned_check(val,addr)				\
+	do {							\
+		unsigned int err = 0, v = val, a = addr;	\
+		asm( FIRST_BYTE_32				\
+		"1:	stb	%1, (%2)\n"			\
+		"	addi	%2, 1\n"			\
+			NEXT_BYTE				\
+		"2:	stb	%1, (%2)\n"			\
+		"	addi	%2, 1\n"			\
+			NEXT_BYTE				\
+		"3:	stb	%1, (%2)\n"			\
+		"	addi	%2, 1\n"			\
+			NEXT_BYTE				\
+		"4:	stb	%1, (%2)\n"			\
+		"	br	6f\n"				\
+		"5:	movi	%0, 1\n"			\
+		"	br	6f\n"				\
+		"	.section __ex_table,\"a\"\n"		\
+		"	.align	2\n"				\
+		"	.long	1b, 5b\n"			\
+		"	.long	2b, 5b\n"			\
+		"	.long	3b, 5b\n"			\
+		"	.long	4b, 5b\n"			\
+		"	.previous\n"				\
+		"6:\n"						\
+		: "=r" (err), "=r" (v), "=r" (a)		\
+		: "0" (err), "1" (v), "2" (a));			\
+		if (err)					\
+			goto fault;				\
+	} while (0)
+
+inline static unsigned int
+get_regs_value(unsigned int rx, struct pt_regs *regs)
+{
+	unsigned int value;
+
+	if(rx == 0){
+		if(user_mode(regs)){
+			asm volatile("mfcr %0, ss1\n":"=r"(value));
+		}else{
+			value = sizeof(struct pt_regs) + ((unsigned int)regs);
+		}
+	}else if(rx == 1){
+		value = regs->regs[9];
+	}else if(rx == 15){
+		value = regs->r15;
+	}else{
+		value = *((int *)regs + rx + 1);
+	}
+
+	return value;
+}
+
+inline static int
+put_regs_value(unsigned int value, unsigned int rx, struct pt_regs *regs){
+	if(rx == 0){
+		printk("alignment handler trying to write sp.\n");
+		goto fault;
+	}else if(rx == 1){
+		regs->regs[9] = value;
+	}else if(rx == 15){
+		regs->r15 = value;
+	}else{
+		*((int *)regs + rx + 1) = value;
+	}
+	return 0;
+fault:
+	return 1;
+}
+
+static int
+handle_ldh_ldw_v1(unsigned long instr, struct pt_regs *regs){
+	unsigned int regx = instr & 0xf;
+	unsigned int regz = (instr >> 8) & 0xf;
+	unsigned int imm4 = (instr >> 4) & 0xf;
+	unsigned int destaddr, ldh_ldw;
+	unsigned int dataregx, tmpval32;
+	unsigned short tmpval16;
+
+	dataregx = get_regs_value(regx, regs);
+
+	ldh_ldw = instr & 0x6000;
+	if(ldh_ldw == 0x4000){ // ldh
+		destaddr = dataregx + (imm4 << 1);
+		get16_unaligned_check(tmpval16, destaddr);
+		if(put_regs_value((unsigned int)tmpval16, regz, regs) != 0){
+			goto fault;
+		}
+		ai_half += 1;
+	}else if(ldh_ldw == 0x0000){ // ldw
+		destaddr = dataregx + (imm4 << 2);
+		get32_unaligned_check(tmpval32, destaddr);
+		if(put_regs_value(tmpval32, regz, regs) != 0){
+			goto fault;
+		}
+		ai_word += 1;
+	}else{
+		goto fault;
+	}
+
+	return HANDLER_SUCCESS;
+fault:
+	return HANDLER_FAILURE;
+}
+
+static int
+handle_ldm_v1(unsigned long instr, struct pt_regs *regs){
+	unsigned int regf = instr & 0xf;
+	unsigned int datasp;
+	unsigned int tmpval32, i;
+
+	// regf can not be r0 or r15.
+	if(regf == 0 || regf == 15){
+		goto fault;
+	}
+
+	datasp = get_regs_value(SP_NUM, regs);
+	for(i = regf; i <= R15_NUM; i++){
+		get32_unaligned_check(tmpval32, datasp + (i - regf) * 4);
+		if(put_regs_value(tmpval32, i, regs) != 0){
+			goto fault;
+		}
+	}
+	ai_qword += 1;
+
+	return HANDLER_SUCCESS;
+fault:
+	return HANDLER_FAILURE;
+}
+
+static int
+handle_ldq_v1(unsigned long instr, struct pt_regs *regs){
+	unsigned int regf = instr & 0xf;
+	unsigned int datarf;
+	unsigned int tmpval32, i;
+
+	// regf can not be r4 - r7.
+	if(regf > 3 && regf < 8){
+		goto fault;
+	}
+
+	datarf = get_regs_value(regf, regs);
+	for(i = 4; i <= 8; i++){
+		get32_unaligned_check(tmpval32, datarf + (i - 4) * 4);
+		if(put_regs_value(tmpval32, i, regs) != 0){
+			goto fault;
+		}
+	}
+	ai_qword += 1;
+
+	return HANDLER_SUCCESS;
+fault:
+	return HANDLER_FAILURE;
+}
+
+static int
+handle_sth_stw_v1(unsigned long instr, struct pt_regs *regs){
+	unsigned int regx = instr & 0xf;
+	unsigned int regz = (instr >> 8) & 0xf;
+	unsigned int imm4 = (instr >> 4) & 0xf;
+	unsigned int destaddr, sth_stw;
+	unsigned int dataregx, dataregz;
+
+	dataregx = get_regs_value(regx, regs);
+	dataregz = get_regs_value(regz, regs);
+
+	sth_stw = instr & 0x6000;
+	if(sth_stw == 0x4000){ // sth
+		destaddr = dataregx + (imm4 << 1);
+		put16_unaligned_check(dataregz, destaddr);
+		ai_half += 1;
+	}else if(sth_stw == 0x0000){ //stw
+		destaddr = dataregx + (imm4 << 2);
+		put32_unaligned_check(dataregz, destaddr);
+		ai_word += 1;
+	}else{
+		goto fault;
+	}
+
+	return HANDLER_SUCCESS;
+fault:
+	return HANDLER_FAILURE;
+}
+
+static int
+handle_stq_v1(unsigned long instr, struct pt_regs *regs){
+	unsigned int regf = instr & 0xf;
+	unsigned int datarf;
+	unsigned int tmpval32, i;
+
+	// regf can not be r4 - r7.
+	if(regf > 3 && regf < 8){
+		goto fault;
+	}
+
+	datarf = get_regs_value(regf, regs);
+	for(i = 4; i <= 7; i++){
+		tmpval32 = get_regs_value(i, regs);
+		put32_unaligned_check(tmpval32, datarf + (i - 4) * 4);
+	}
+	ai_qword += 1;
+
+	return HANDLER_SUCCESS;
+fault:
+	return HANDLER_FAILURE;
+}
+
+static int
+handle_stm_v1(unsigned long instr, struct pt_regs *regs){
+	unsigned int regf = instr & 0xf;
+	unsigned int datasp;
+	unsigned int tmpval32, i;
+
+	// regf can not be r0 or r15.
+	if(regf == 0 || regf == 15){
+		goto fault;
+	}
+
+	datasp = get_regs_value(SP_NUM, regs);
+	for(i = regf; i <= R15_NUM; i++){
+		tmpval32 = get_regs_value(i, regs);
+		put32_unaligned_check(tmpval32, datasp + (i - regf) * 4);
+	}
+	ai_qword += 1;
+
+	return HANDLER_SUCCESS;
+fault:
+	return HANDLER_FAILURE;
+}
+
+void csky_alignment(struct pt_regs *regs)
+{
+	int err;
+	unsigned long instr = 0, instrptr;
+	unsigned int fault;
+	u16 tinstr = 0;
+	int (*handler)(unsigned long inst, struct pt_regs *regs) = NULL;
+	int isize = 2;
+	siginfo_t info;
+
+
+	mm_segment_t fs;
+
+	instrptr = instruction_pointer(regs);
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
+	instr = (unsigned long)tinstr;
+
+	set_fs(fs);
+	if (fault) {
+		goto bad_or_fault;
+	}
+
+	if (user_mode(regs)) {
+		goto user;
+	}
+
+	ai_sys += 1;
+fixup:
+	regs->pc += isize;
+
+	if((instr & 0x9000) == 0x9000){ // sth, stw
+		handler = handle_sth_stw_v1;
+	}else if((instr & 0x9000) == 0x8000){ // ldh, ldw
+		handler = handle_ldh_ldw_v1;
+	}else if((instr & 0xfff0) == 0x0070){ // stm
+		handler = handle_stm_v1;
+	}else if((instr & 0xfff0) == 0x0060){ // ldm
+		handler = handle_ldm_v1;
+	}else if((instr & 0xfff0) == 0x0050){ // stq
+		handler = handle_stq_v1;
+	}else if((instr & 0xfff0) == 0x0040){ // ldq
+		handler = handle_ldq_v1;
+	}else{
+		goto bad_or_fault;
+	}
+
+	if (!handler)
+		goto bad_or_fault;
+
+	err = handler(instr, regs);
+	if (err != HANDLER_SUCCESS)
+	{
+		regs->pc -=2;
+		goto bad_or_fault;
+	}
+
+	return;
+
+bad_or_fault:
+	if(fixup_exception(regs)) {
+		ai_skipped += 1;
+		return;
+	}
+
+	die_if_kernel("Alignment trap: not handle this instruction", regs, 0);
+	return;
+
+user:
+	ai_user += 1;
+
+	if (ai_usermode & UM_WARN)
+		printk("Alignment trap: %s(pid=%d) PC=0x%x Ins=0x%x\n",
+			current->comm, current->pid,
+			(unsigned int)regs->pc, (unsigned int)instr);
+
+	if (ai_usermode & UM_FIXUP)
+		goto fixup;
+
+	if (ai_usermode & UM_SIGNAL) {
+		info.si_code = NSIGBUS;
+		info.si_signo = SIGBUS;
+		info.si_errno = 0;
+		force_sig_info(SIGBUS, &info, current);
+	}
+
+	return;
+}
+
+/*
+ * This needs to be done after sysctl_init, otherwise sys/ will be
+ * overwritten.  Actually, this shouldn't be in sys/ at all since
+ * it isn't a sysctl, and it doesn't contain sysctl information.
+ * We now locate it in /proc/cpu/alignment instead.
+ */
+static int __init alignment_init(void)
+{
+	struct proc_dir_entry *res;
+
+	res = proc_mkdir("cpu", NULL);
+	if (!res)
+		return -ENOMEM;
+
+	res = proc_create("alignment", S_IWUSR | S_IRUGO, res, &alignment_proc_fops);
+	if (!res)
+		return -ENOMEM;
+
+	ai_usermode = UM_FIXUP;
+
+	return 0;
+}
+fs_initcall(alignment_init);
diff --git a/arch/csky/abiv2/inc/abi/entry.h b/arch/csky/abiv2/inc/abi/entry.h
new file mode 100644
index 0000000..fc6deab
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/entry.h
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_ENTRY_H
+#define __ASM_CSKY_ENTRY_H
+
+#include <asm/setup.h>
+#include <abi/regdef.h>
+
+#define LSAVE_A0       0xc
+#define LSAVE_A1       0x10
+#define LSAVE_A2       0x14
+#define LSAVE_A3       0x18
+
+#define KSPTOUSP
+#define USPTOKSP
+
+.macro GET_USP rx
+	mfcr	\rx, cr<14, 1>
+.endm
+
+.macro SET_USP rx
+	mtcr	\rx, cr<14, 1>
+.endm
+
+.macro INCTRAP	rx
+	addi	\rx, 4
+.endm
+
+.macro SAVE_ALL
+	subi    sp,  144
+	stw     a0, (sp, 4)
+	stw     a0, (sp, 12)
+	stw     a1, (sp, 16)
+	stw     a2, (sp, 20)
+	stw     a3, (sp, 24)
+	stw     r4, (sp, 28)
+	stw     r5, (sp, 32)
+	stw     r6, (sp, 36)
+	stw     r7, (sp, 40)
+	stw     r8, (sp, 44)
+	stw     r9, (sp, 48)
+	stw     r10, (sp, 52)
+	stw     r11, (sp, 56)
+	stw     r12, (sp, 60)
+	stw     r13, (sp, 64)
+	stw     r15, (sp, 68)
+	addi    sp, 72
+	stm     r16-r31,(sp)
+#ifdef CONFIG_CPU_HAS_HILO
+	mfhi    r22
+	mflo    r23
+	stw     r22, (sp, 64)
+        stw     r23, (sp, 68)
+#endif
+	subi    sp,  72
+
+	mfcr    r22, epsr
+	stw     r22, (sp, 8)
+	mfcr    r22, epc
+	stw     r22, (sp)
+.endm
+.macro SAVE_ALL_TRAP
+	SAVE_ALL
+	INCTRAP	r22
+	stw     r22, (sp)
+.endm
+
+.macro	RESTORE_ALL
+	psrclr  ie
+	ldw     a0, (sp)
+	mtcr    a0, epc
+	ldw     a0, (sp, 8)
+	mtcr    a0, epsr
+	addi    sp, 12
+#ifdef CONFIG_CPU_HAS_HILO
+	ldw     a0, (sp, 124)
+	ldw     a1, (sp, 128)
+	mthi    a0
+	mtlo    a1
+#endif
+	ldw     a0, (sp, 0)
+	ldw     a1, (sp, 4)
+	ldw     a2, (sp, 8)
+	ldw     a3, (sp, 12)
+	ldw     r4, (sp, 16)
+	ldw     r5, (sp, 20)
+	ldw     r6, (sp, 24)
+	ldw     r7, (sp, 28)
+	ldw     r8, (sp, 32)
+	ldw     r9, (sp, 36)
+	ldw     r10, (sp, 40)
+	ldw     r11, (sp, 44)
+	ldw     r12, (sp, 48)
+	ldw     r13, (sp, 52)
+	ldw     r15, (sp, 56)
+	addi    sp, 60
+	ldm     r16-r31,(sp)
+	addi    sp,  72
+1:
+	rte
+.endm
+
+.macro SAVE_SWITCH_STACK
+        subi    sp, 64
+        stm     r4-r11,(sp)
+        stw     r15, (sp, 32)
+        stw     r16, (sp, 36)
+        stw     r17, (sp, 40)
+        stw     r26, (sp, 44)
+        stw     r27, (sp, 48)
+        stw     r28, (sp, 52)
+        stw     r29, (sp, 56)
+        stw     r30, (sp, 60)
+.endm
+
+.macro RESTORE_SWITCH_STACK
+        ldm     r4-r11,(sp)
+        ldw     r15, (sp, 32)
+        ldw     r16, (sp, 36)
+        ldw     r17, (sp, 40)
+        ldw     r26, (sp, 44)
+        ldw     r27, (sp, 48)
+        ldw     r28, (sp, 52)
+        ldw     r29, (sp, 56)
+        ldw     r30, (sp, 60)
+        addi    sp, 64
+.endm
+
+/* MMU registers operators. */
+.macro RD_MIR	rx
+	mfcr    \rx, cr<0, 15>
+.endm
+
+.macro RD_MEH	rx
+	mfcr    \rx, cr<4, 15>
+.endm
+
+.macro RD_MCIR	rx
+	mfcr    \rx, cr<8, 15>
+.endm
+
+.macro RD_PGDR  rx
+        mfcr    \rx, cr<29, 15>
+.endm
+
+.macro WR_MEH	rx
+	mtcr    \rx, cr<4, 15>
+.endm
+
+.macro WR_MCIR	rx
+	mtcr    \rx, cr<8, 15>
+.endm
+
+#endif /* __ASM_CSKY_ENTRY_H */
diff --git a/arch/csky/include/asm/syscalls.h b/arch/csky/include/asm/syscalls.h
new file mode 100644
index 0000000..c478830
--- /dev/null
+++ b/arch/csky/include/asm/syscalls.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_SYSCALLS_H
+#define __ASM_CSKY_SYSCALLS_H
+
+#include <asm-generic/syscalls.h>
+
+long sys_cacheflush(void __user *, unsigned long, int);
+
+long sys_set_thread_area(unsigned long addr);
+
+long sys_csky_fadvise64_64(int fd, int advice, loff_t offset, loff_t len);
+
+#endif /* __ASM_CSKY_SYSCALLS_H */
diff --git a/arch/csky/include/asm/traps.h b/arch/csky/include/asm/traps.h
new file mode 100644
index 0000000..ca82b19
--- /dev/null
+++ b/arch/csky/include/asm/traps.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_TRAPS_H
+#define __ASM_CSKY_TRAPS_H
+
+#define VEC_RESET	0
+#define VEC_ALIGN	1
+#define VEC_ACCESS	2
+#define VEC_ZERODIV	3
+#define VEC_ILLEGAL	4
+#define VEC_PRIV	5
+#define VEC_TRACE	6
+#define VEC_BREAKPOINT	7
+#define VEC_UNRECOVER	8
+#define VEC_SOFTRESET	9
+#define VEC_AUTOVEC	10
+#define VEC_FAUTOVEC	11
+#define VEC_HWACCEL	12
+
+#define	VEC_TLBMISS	14
+#define	VEC_TLBMODIFIED	15
+
+#define VEC_TRAP0	16
+#define VEC_TRAP1	17
+#define VEC_TRAP2	18
+#define VEC_TRAP3	19
+
+#define	VEC_TLBINVALIDL	20
+#define	VEC_TLBINVALIDS	21
+
+#define VEC_PRFL	29
+#define VEC_FPE		30
+
+extern void * vec_base[];
+#define VEC_INIT(i, func) vec_base[i] = (void *)func
+
+void csky_alignment(struct pt_regs*);
+
+#endif /* __ASM_CSKY_TRAPS_H */
diff --git a/arch/csky/include/asm/unistd.h b/arch/csky/include/asm/unistd.h
new file mode 100644
index 0000000..704526c
--- /dev/null
+++ b/arch/csky/include/asm/unistd.h
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <uapi/asm/unistd.h>
+
diff --git a/arch/csky/include/uapi/asm/unistd.h b/arch/csky/include/uapi/asm/unistd.h
new file mode 100644
index 0000000..12ebbba
--- /dev/null
+++ b/arch/csky/include/uapi/asm/unistd.h
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#define __ARCH_WANT_IPC_PARSE_VERSION
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_RENAMEAT
+#define __ARCH_WANT_STAT64
+#define __ARCH_WANT_SYNC_FILE_RANGE2
+#define __ARCH_WANT_SYS_ALARM
+#define __ARCH_WANT_SYS_CLONE
+#define __ARCH_WANT_SYS_FORK
+#define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_GETPGRP
+#define __ARCH_WANT_SYS_IPC
+#define __ARCH_WANT_SYS_LLSEEK
+#define __ARCH_WANT_SYS_NICE
+#define __ARCH_WANT_SYS_OLD_GETRLIMIT
+#define __ARCH_WANT_SYS_OLD_SELECT
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_PAUSE
+#define __ARCH_WANT_SYS_RT_SIGACTION
+#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_SGETMASK
+#define __ARCH_WANT_SYS_SIGNAL
+#define __ARCH_WANT_SYS_SIGPENDING
+#define __ARCH_WANT_SYS_SIGPROCMASK
+#define __ARCH_WANT_SYS_SOCKETCALL
+#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_WAITPID
+#define __ARCH_WANT_SYSCALL_DEPRECATED
+#define __ARCH_WANT_SYSCALL_OFF_T
+#define __ARCH_WANT_SYSCALL_NO_AT
+#define __ARCH_WANT_SYSCALL_NO_FLAGS
+
+#undef	__NR_rt_sigreturn
+#undef	__NR_getppid
+
+#include <asm-generic/unistd.h>
+
+/*
+ * __NR_rt_sigreturn must be 173
+ * Because gcc/config/csky/linux-unwind.h use hard-code 173
+ * to parse rt_sigframe.
+ */
+#if __NR_rt_sigreturn != 139
+#error __NR_rt_sigreturn has changed.
+#endif
+
+#if __NR_getppid != 173
+#error __NR_getppid has changed.
+#endif
+
+#undef	__NR_rt_sigreturn
+#define	__NR_rt_sigreturn 173
+__SC_COMP(__NR_rt_sigreturn, sys_rt_sigreturn, compat_sys_rt_sigreturn)
+
+#undef	__NR_getppid
+#define	__NR_getppid 139
+__SYSCALL(__NR_getppid, sys_getppid)
+
+
+/*
+ * other define
+ */
+#define __NR_set_thread_area	(__NR_arch_specific_syscall + 0)
+__SYSCALL(__NR_set_thread_area, sys_set_thread_area)
+#define __NR_ipc		(__NR_arch_specific_syscall + 1)
+__SYSCALL(__NR_ipc, sys_ipc)
+#define __NR_socketcall		(__NR_arch_specific_syscall + 2)
+__SYSCALL(__NR_socketcall, sys_socketcall)
+#define __NR_ugetrlimit		(__NR_arch_specific_syscall + 3)
+__SYSCALL(__NR_ugetrlimit, sys_getrlimit)
+#define __NR_cacheflush		(__NR_arch_specific_syscall + 4)
+__SYSCALL(__NR_cacheflush, sys_cacheflush)
+#define __NR_sysfs		(__NR_arch_specific_syscall + 5)
+__SYSCALL(__NR_sysfs, sys_sysfs)
+
+__SYSCALL(__NR_fadvise64_64, sys_csky_fadvise64_64)
+
+#define __NR_setgroups32	__NR_setgroups
+#define __NR_getgid32		__NR_getgid
+#define __NR_getgroups32	__NR_getgroups
+#define __NR_setuid32		__NR_setuid
+#define __NR_setgid32		__NR_setgid
+#define __NR_getresgid32	__NR_getresgid
+#define __NR_chown32		__NR_chown
+#define __NR_setfsuid32		__NR_setfsuid
+#define __NR_setfsgid32		__NR_setfsgid
+#define __NR_lchown32		__NR_lchown
+#define __NR_fchown32		__NR_fchown
+#define __NR_geteuid32		__NR_geteuid
+#define __NR_getegid32		__NR_getegid
+#define __NR_getresuid32	__NR_getresuid
+#define __NR_setresuid32	__NR_setresuid
+#define __NR_setresgid32	__NR_setresgid
+#define __NR_setreuid32		__NR_setreuid
+#define __NR_setregid32		__NR_setregid
+#define __NR__llseek		__NR_llseek
+
diff --git a/arch/csky/kernel/cpu-probe.c b/arch/csky/kernel/cpu-probe.c
new file mode 100644
index 0000000..8934583
--- /dev/null
+++ b/arch/csky/kernel/cpu-probe.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/of.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <abi/reg_ops.h>
+#include <linux/memblock.h>
+
+static __init void setup_cpu_msa(void)
+{
+	if (memblock_start_of_DRAM() != (PHYS_OFFSET + CONFIG_RAM_BASE)) {
+		pr_err("C-SKY: dts-DRAM doesn't fit .config: %x-%x.\n",
+			memblock_start_of_DRAM(),
+			PHYS_OFFSET + CONFIG_RAM_BASE);
+		return;
+	}
+
+	mtcr_msa0(PHYS_OFFSET | 0xe);
+	mtcr_msa1(PHYS_OFFSET | 0x6);
+}
+
+__init void cpu_dt_probe(void)
+{
+	setup_cpu_msa();
+}
+
+static int c_show(struct seq_file *m, void *v)
+{
+	seq_printf(m, "C-SKY CPU : %s\n", CSKYCPU_DEF_NAME);
+	seq_printf(m, "revision  : 0x%08x\n", mfcr_cpuidrr());
+	seq_printf(m, "ccr reg   : 0x%08x\n", mfcr_ccr());
+	seq_printf(m, "ccr2 reg  : 0x%08x\n", mfcr_ccr2());
+	seq_printf(m, "hint reg  : 0x%08x\n", mfcr_hint());
+	seq_printf(m, "msa0 reg  : 0x%08x\n", mfcr_msa0());
+	seq_printf(m, "msa1 reg  : 0x%08x\n", mfcr_msa1());
+	seq_printf(m, "\n");
+#ifdef CSKY_ARCH_VERSION
+	seq_printf(m, "arch-version : %s\n", CSKY_ARCH_VERSION);
+	seq_printf(m, "\n");
+#endif
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < 1 ? (void *)1 : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return NULL;
+}
+
+static void c_stop(struct seq_file *m, void *v) {}
+
+const struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= c_show,
+};
+
diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S
new file mode 100644
index 0000000..f0ab7d7
--- /dev/null
+++ b/arch/csky/kernel/entry.S
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/linkage.h>
+#include <abi/entry.h>
+#include <abi/pgtable-bits.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/unistd.h>
+#include <asm/asm-offsets.h>
+#include <linux/threads.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
+#ifdef CONFIG_CPU_HAS_FPU
+#include <abi/fpu.h>
+#endif
+
+#define PTE_INDX_MSK    0xffc
+#define PTE_INDX_SHIFT  10
+#define _PGDIR_SHIFT    22
+#define THREADSIZE_MASK_BIT 13
+
+.macro tlbop_begin name, val0, val1, val2
+ENTRY(csky_\name)
+	mtcr    a3, ss2
+	mtcr    r6, ss3
+	mtcr    a2, ss4
+
+	RD_MEH	a3
+#ifdef CONFIG_CPU_HAS_TLBI
+	tlbi.va	a3
+#else
+	bgeni	a2, 31
+	WR_MCIR	a2
+	bgeni	a2, 25
+	WR_MCIR	a2
+#endif
+
+	RD_PGDR	r6
+	bclri   r6, 0
+	lrw	a2, PHYS_OFFSET
+	subu	r6, a2
+	bseti	r6, 31
+
+	mov     a2, a3
+   	lsri    a2, _PGDIR_SHIFT
+	lsli    a2, 2
+	addu    r6, a2
+	ldw     r6, (r6)
+
+	lrw	a2, PHYS_OFFSET
+	subu	r6, a2
+	bseti	r6, 31
+
+	lsri    a3, PTE_INDX_SHIFT
+	lrw     a2, PTE_INDX_MSK
+	and     a3, a2
+	addu    r6, a3
+	ldw     a3, (r6)
+
+	movi	a2, (_PAGE_PRESENT | \val0)
+	and     a3, a2
+	cmpne   a3, a2
+	bt	\name
+
+	/* First read/write the page, just update the flags */
+	ldw     a3, (r6)
+	bgeni   a2, PAGE_VALID_BIT
+	bseti   a2, PAGE_ACCESSED_BIT
+	bseti   a2, \val1
+	bseti   a2, \val2
+	or      a3, a2
+	stw     a3, (r6)
+
+	/* Some cpu tlb-hardrefill bypass the cache */
+#ifdef CONFIG_CPU_NEED_TLBSYNC
+	movi	a2, 0x22
+	bseti	a2, 6
+	mtcr	r6, cr22
+	mtcr	a2, cr17
+	sync
+#endif
+
+	mfcr    a3, ss2
+	mfcr    r6, ss3
+	mfcr    a2, ss4
+	rte
+\name:
+	mfcr    a3, ss2
+	mfcr    r6, ss3
+	mfcr    a2, ss4
+	SAVE_ALL
+.endm
+.macro tlbop_end is_write
+	RD_MEH	a2
+	psrset  ee, ie
+	mov     a0, sp
+	movi    a1, \is_write
+	jbsr    do_page_fault
+	movi    r11_sig, 0             /* r11 = 0, Not a syscall. */
+	jmpi    ret_from_exception
+.endm
+
+.text
+
+tlbop_begin tlbinvalidl, _PAGE_READ, PAGE_VALID_BIT, PAGE_ACCESSED_BIT
+tlbop_end 0
+
+tlbop_begin tlbinvalids, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
+tlbop_end 1
+
+tlbop_begin tlbmodified, _PAGE_WRITE, PAGE_DIRTY_BIT, PAGE_MODIFIED_BIT
+jbsr csky_cmpxchg_fixup
+tlbop_end 1
+
+ENTRY(csky_systemcall)
+	SAVE_ALL_TRAP
+
+	psrset  ee, ie
+
+	/* Stack frame for syscall, origin call set_esp0 */
+	mov     r12, sp
+
+	bmaski  r11, 13
+	andn    r12, r11
+	bgeni   r11, 9
+	addi    r11, 32
+	addu    r12, r11
+	st      sp, (r12, 0)
+
+	lrw     r11, __NR_syscalls
+	cmphs   syscallid, r11                 /* Check nr of syscall */
+	bt      ret_from_exception
+
+	lrw     r13, sys_call_table
+	ixw     r13, syscallid                 /* Index into syscall table */
+	ldw     r11, (r13)               /* Get syscall function */
+	cmpnei  r11, 0                  /* Check for not null */
+	bf      ret_from_exception
+
+	mov     r9, sp				 /* Get task pointer */
+	bmaski  r10, THREADSIZE_MASK_BIT
+	andn    r9, r10                      /* Get thread_info */
+	ldw     r8, (r9, TINFO_FLAGS)       /* Get thread_info.flags value */
+	btsti   r8, TIF_SYSCALL_TRACE       /* Check if TIF_SYSCALL_TRACE set */
+	bt      1f
+#if defined(__CSKYABIV2__)
+	subi    sp, 8
+	stw  	r5, (sp, 0x4)
+	stw  	r4, (sp, 0x0)
+	jsr     r11                      /* Do system call */
+	addi 	sp, 8
+#else
+	jsr     r11
+#endif
+	stw     a0, (sp, LSAVE_A0)      /* Save return value */
+	jmpi    ret_from_exception
+
+1:
+	movi    a0, 0                   /* enter system call */
+	mov     a1, sp                  /* right now, sp --> pt_regs */
+	jbsr    syscall_trace
+	/* Prepare args before do system call */
+	ldw     a0, (sp, LSAVE_A0)
+	ldw     a1, (sp, LSAVE_A1)
+	ldw     a2, (sp, LSAVE_A2)
+	ldw     a3, (sp, LSAVE_A3)
+#if defined(__CSKYABIV2__)
+	subi    sp, 8
+	stw     r5, (sp, 0x4)
+	stw     r4, (sp, 0x0)
+#else
+	ldw     r6, (sp, LSAVE_A4)
+	ldw     r7, (sp, LSAVE_A5)
+#endif
+	jsr     r11                     /* Do system call */
+#if defined(__CSKYABIV2__)
+	addi    sp, 8
+#endif
+	stw     a0, (sp, LSAVE_A0)     /* Save return value */
+
+	movi    a0, 1                   /* leave system call */
+	mov     a1, sp                  /* right now, sp --> pt_regs */
+	jbsr    syscall_trace
+
+syscall_exit_work:
+	ld       syscallid, (sp, 8)     /* get psr, is user mode? */
+	btsti    syscallid, 31
+	bt       2f
+
+	jmpi     resume_userspace
+
+2:      RESTORE_ALL
+
+ENTRY(ret_from_kernel_thread)
+	jbsr     schedule_tail
+	mov	 a0, r8
+	jsr	 r9
+	jbsr     ret_from_exception
+
+ENTRY(ret_from_fork)
+	jbsr     schedule_tail
+	mov      r9, sp				 /* Get task pointer */
+	bmaski   r10, THREADSIZE_MASK_BIT
+	andn     r9, r10                     /* Get thread_info */
+	ldw      r8, (r9, TINFO_FLAGS)       /* Get thread_info.flags value */
+	movi     r11_sig, 1                  /* is a syscall */
+	btsti    r8, TIF_SYSCALL_TRACE       /* Check if TIF_SYSCALL_TRACE set */
+	bf       3f
+	movi     a0, 1                       /* leave system call */
+	mov      a1, sp                      /* right now, sp --> pt_regs */
+	jbsr     syscall_trace
+3:
+	jbsr     ret_from_exception
+
+ret_from_exception:
+	ld       syscallid, (sp,8)     /* get psr, is user mode? */
+	btsti    syscallid, 31
+	bt       1f
+	/*
+	 * Load address of current->thread_info, Then get address of task_struct
+	 * Get task_needreshed in task_struct
+	 */
+	mov     r9, sp     					 /* Get current stack  pointer */
+	bmaski  r10, THREADSIZE_MASK_BIT
+	andn    r9, r10                      /* Get task_struct */
+
+resume_userspace:
+	ldw      r8, (r9, TINFO_FLAGS)
+	andi     r8, (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED)
+	cmpnei   r8, 0
+	bt       exit_work
+1:  RESTORE_ALL
+
+exit_work:
+	mov      a0, sp                 /* Stack address is arg[0] */
+	jbsr     set_esp0               /* Call C level */
+	btsti    r8, TIF_NEED_RESCHED
+	bt       work_resched
+	cmpnei   r8, 0		/* If thread_info->flag is empty, RESTORE_ALL. */
+	bf       1b
+	mov      a1, sp
+	mov      a0, r8
+	mov      a2, r11_sig        /* syscall? */
+	btsti    r8, TIF_SIGPENDING /* delivering a signal? */
+	clrt     r11_sig            /* prevent further restarts(set r11 = 0) */
+	jbsr     do_notify_resume	/* do signals */
+	br       resume_userspace
+
+work_resched:
+	lrw      syscallid, ret_from_exception
+	mov      r15, syscallid                /* Return address in link */
+	jmpi     schedule
+
+ENTRY(sys_rt_sigreturn)
+	movi	r11_sig, 0
+	jmpi	do_rt_sigreturn
+
+/*
+ * Common trap handler. Standard traps come through here first
+ */
+
+ENTRY(csky_trap)
+	SAVE_ALL
+	psrset   ee
+	movi     r11_sig, 0             /* r11 = 0, Not a syscall. */
+	mov      a0, sp                 /* Push Stack pointer arg */
+	jbsr     trap_c                 /* Call C-level trap handler */
+	jmpi     ret_from_exception
+
+/*
+ * Prototype from libc:
+ * register unsigned int __result asm("a0");
+ * asm( "trap 3" :"=r"(__result)::);
+ */
+ENTRY(csky_get_tls)
+	USPTOKSP
+
+	/* increase epc for continue */
+	mfcr	a0, epc
+	INCTRAP	a0
+	mtcr	a0, epc
+
+	/* get current task thread_info with kernel 8K stack */
+	bmaski   a0, (PAGE_SHIFT + 1)
+	not      a0
+	subi     sp, 1
+	and      a0, sp
+	addi     sp, 1
+
+	/* get tls */
+	ldw      a0, (a0, TINFO_TP_VALUE)
+
+	KSPTOUSP
+	rte
+
+ENTRY(csky_irq)
+	SAVE_ALL
+	psrset  ee       // enable exception
+	movi    r11_sig, 0                   /* r11 = 0, Not a syscall. */
+
+#ifdef CONFIG_PREEMPT
+	mov     r9, sp                       /* Get current stack  pointer */
+	bmaski  r10, THREADSIZE_MASK_BIT
+	andn    r9, r10                      /* Get thread_info */
+
+	/*
+	 * Get task_struct->stack.preempt_count for current,
+	 * and increase 1.
+	 */
+	ldw      r8, (r9, TINFO_PREEMPT)
+	addi     r8, 1
+	stw      r8, (r9, TINFO_PREEMPT)
+#endif
+
+	mov      a0, sp                      /* arg[0] is stack pointer */
+	jbsr     csky_do_auto_IRQ          /* Call handler */
+
+#ifdef CONFIG_PREEMPT
+	subi     r8, 1
+	stw      r8, (r9, TINFO_PREEMPT)
+	cmpnei   r8, 0
+	bt       2f
+	ldw      r8, (r9, TINFO_FLAGS)
+	btsti    r8, TIF_NEED_RESCHED
+	bf       2f
+1:
+	jbsr     preempt_schedule_irq   /* irq en/disable is done inside */
+	ldw      r7, (r9, TINFO_FLAGS)  /* get new tasks TI_FLAGS */
+	btsti    r7, TIF_NEED_RESCHED
+	bt       1b                     /* go again */
+#endif
+2:
+	jmpi     ret_from_exception
+
+/*
+ * a0 =  prev task_struct *
+ * a1 =  next task_struct *
+ * a0 =  return next
+ */
+ENTRY(__switch_to)
+	lrw      a3, TASK_THREAD        /* struct_thread offset in task_struct */
+	addu     a3, a0                 /* a3 point to thread in prev task_struct */
+
+	mfcr     a2, psr                /* Save PSR value */
+	stw      a2, (a3, THREAD_SR)    /* Save PSR in task struct */
+	bclri    a2, 6                  /* Disable interrupts */
+	mtcr     a2, psr
+
+	SAVE_SWITCH_STACK
+
+	GET_USP	 r6
+
+	stw      r6, (a3, THREAD_USP)   /* Save usp in task struct */
+	stw      sp, (a3, THREAD_KSP)   /* Save ksp in task struct */
+
+#ifdef CONFIG_CPU_HAS_FPU
+	FPU_SAVE_REGS
+#endif
+
+#ifdef CONFIG_CPU_HAS_HILO
+	lrw      r10, THREAD_DSPHI
+	add      r10, a3
+	mfhi     r6
+	mflo     r7
+	stw      r6, (r10, 0)           /* THREAD_DSPHI */
+	stw      r7, (r10, 4)           /* THREAD_DSPLO */
+	mfcr     r6, cr14
+	stw      r6, (r10, 8)           /* THREAD_DSPCSR */
+#endif
+
+	/* Set up next process to run */
+	lrw      a3, TASK_THREAD	/* struct_thread offset in task_struct */
+	addu     a3, a1			/* a3 point to thread in next task_struct */
+
+	ldw      sp, (a3, THREAD_KSP)	/* Set next ksp */
+	ldw      r6, (a3, THREAD_USP)	/* Set next usp */
+
+	SET_USP	 r6
+
+#ifdef CONFIG_CPU_HAS_FPU
+	FPU_RESTORE_REGS
+#endif
+
+#ifdef CONFIG_CPU_HAS_HILO
+	lrw      r10, THREAD_DSPHI
+	add      r10, a3
+	ldw      r6, (r10, 8)   /* THREAD_DSPCSR */
+	mtcr     r6, cr14
+	ldw      r6, (r10, 0)    /* THREAD_DSPHI */
+	ldw      r7, (r10, 4)    /* THREAD_DSPLO */
+	mthi     r6
+	mtlo     r7
+#endif
+
+	ldw      a2, (a3, THREAD_SR)    /* Set next PSR */
+	mtcr     a2, psr
+
+#if  defined(__CSKYABIV2__)
+	/* set TLS register (r31) */
+	addi     r7, a1, TASK_THREAD_INFO
+	ldw      r31, (r7, TINFO_TP_VALUE)
+#endif
+
+	RESTORE_SWITCH_STACK
+
+	rts
+ENDPROC(__switch_to)
diff --git a/arch/csky/kernel/syscall.c b/arch/csky/kernel/syscall.c
new file mode 100644
index 0000000..b45f497
--- /dev/null
+++ b/arch/csky/kernel/syscall.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/syscalls.h>
+
+SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
+{
+	struct thread_info *ti = task_thread_info(current);
+
+#if defined(__CSKYABIV2__)
+	struct pt_regs *reg = current_pt_regs();
+	reg->exregs[15] = (long)addr;
+#endif
+	ti->tp_value = addr;
+
+	return 0;
+}
+
+SYSCALL_DEFINE6(mmap2,
+	unsigned long, addr,
+	unsigned long, len,
+	unsigned long, prot,
+	unsigned long, flags,
+	unsigned long, fd,
+	off_t, offset)
+{
+	if (unlikely(offset & (~PAGE_MASK >> 12)))
+		return -EINVAL;
+	return sys_mmap_pgoff(addr, len, prot, flags, fd,
+		offset >> (PAGE_SHIFT - 12));
+}
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+SYSCALL_DEFINE1(mmap,
+	struct mmap_arg_struct *, arg)
+{
+	struct mmap_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EINVAL;
+
+	if (unlikely(a.offset & ~PAGE_MASK))
+		return -EINVAL;
+
+	return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+}
+
+/*
+ * for abiv1 the 64bits args should be even th, So we need mov the advice forward.
+ */
+SYSCALL_DEFINE4(csky_fadvise64_64,
+	int, fd,
+	int, advice,
+	loff_t, offset,
+	loff_t, len)
+{
+	return sys_fadvise64_64(fd, offset, len, advice);
+}
diff --git a/arch/csky/kernel/syscall_table.c b/arch/csky/kernel/syscall_table.c
new file mode 100644
index 0000000..bea8558
--- /dev/null
+++ b/arch/csky/kernel/syscall_table.c
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/syscalls.h>
+#include <asm/syscalls.h>
+
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (call),
+
+void * const sys_call_table[__NR_syscalls] __page_aligned_data = {
+	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
diff --git a/arch/csky/kernel/traps.c b/arch/csky/kernel/traps.c
new file mode 100644
index 0000000..17bcb08
--- /dev/null
+++ b/arch/csky/kernel/traps.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+#include <linux/kallsyms.h>
+#include <linux/rtc.h>
+#include <linux/uaccess.h>
+
+#include <asm/setup.h>
+#include <asm/traps.h>
+#include <asm/pgalloc.h>
+#include <asm/siginfo.h>
+
+#include <asm/mmu_context.h>
+
+#ifdef CONFIG_CPU_HAS_FPU
+#include <abi/fpu.h>
+#endif
+
+/* Defined in entry.S */
+asmlinkage void csky_trap(void);
+
+asmlinkage void csky_systemcall(void);
+asmlinkage void csky_cmpxchg(void);
+asmlinkage void csky_get_tls(void);
+asmlinkage void csky_irq(void);
+
+asmlinkage void csky_tlbinvalidl(void);
+asmlinkage void csky_tlbinvalids(void);
+asmlinkage void csky_tlbmodified(void);
+
+void __init pre_trap_init(void)
+{
+	int i;
+
+	asm volatile(
+		"mtcr %0, vbr\n"
+		::"r"(vec_base));
+
+	for(i=1;i<128;i++) VEC_INIT(i, csky_trap);
+}
+
+void __init trap_init (void)
+{
+	int i;
+
+	/* setup irq */
+	for(i=32;i<128;i++)
+		  VEC_INIT(i, csky_irq);
+	VEC_INIT(VEC_AUTOVEC, csky_irq);
+
+	/* setup trap0 trap2 trap3 */
+	VEC_INIT(VEC_TRAP0, csky_systemcall);
+	VEC_INIT(VEC_TRAP2, csky_cmpxchg);
+	VEC_INIT(VEC_TRAP3, csky_get_tls);
+
+	/* setup MMU TLB exception */
+	VEC_INIT(VEC_TLBINVALIDL, csky_tlbinvalidl);
+	VEC_INIT(VEC_TLBINVALIDS, csky_tlbinvalids);
+	VEC_INIT(VEC_TLBMODIFIED, csky_tlbmodified);
+
+
+#ifdef CONFIG_CPU_HAS_FPU
+	init_fpu();
+#endif
+}
+
+void die_if_kernel (char *str, struct pt_regs *regs, int nr)
+{
+	if (user_mode(regs)) return;
+
+	console_verbose();
+	pr_err("%s: %08x\n",str,nr);
+        show_regs(regs);
+        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
+	do_exit(SIGSEGV);
+}
+
+void buserr(struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	die_if_kernel("Kernel mode BUS error", regs, 0);
+
+	pr_err("User mode Bus Error\n");
+	show_regs(regs);
+
+	current->thread.esp0 = (unsigned long) regs;
+	info.si_signo = SIGSEGV;
+	info.si_errno = 0;
+	force_sig_info(SIGSEGV, &info, current);
+}
+
+asmlinkage void trap_c(struct pt_regs *regs)
+{
+	int sig;
+	unsigned long vector;
+	siginfo_t info;
+
+	asm volatile("mfcr %0, psr":"=r"(vector));
+
+	vector = (vector >> 16) & 0xff;
+
+	switch (vector) {
+		case VEC_ZERODIV:
+			sig = SIGFPE;
+			break;
+		/* ptrace */
+		case VEC_TRACE:
+			info.si_code = TRAP_TRACE;
+			sig = SIGTRAP;
+			break;
+
+		/* gdbserver  breakpoint */
+		case VEC_TRAP1:
+		/* jtagserver breakpoint */
+		case VEC_BREAKPOINT:
+			info.si_code = TRAP_BRKPT;
+			sig = SIGTRAP;
+			break;
+		case VEC_ACCESS:
+			return buserr(regs);
+#ifdef CONFIG_CPU_NEED_SOFTALIGN
+		case VEC_ALIGN:
+			return csky_alignment(regs);
+#endif
+#ifdef CONFIG_CPU_HAS_FPU
+		case VEC_FPE:
+			return fpu_fpe(regs);
+		case VEC_PRIV:
+			if(fpu_libc_helper(regs)) return;
+#endif
+		default:
+			sig = SIGILL;
+			break;
+	}
+	send_sig(sig, current, 0);
+}
+
+asmlinkage void set_esp0 (unsigned long ssp)
+{
+	current->thread.esp0 = ssp;
+}
+
diff --git a/arch/csky/mm/fault.c b/arch/csky/mm/fault.c
new file mode 100644
index 0000000..fe85404
--- /dev/null
+++ b/arch/csky/mm/fault.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/signal.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/version.h>
+#include <linux/vt_kern.h>
+#include <linux/kernel.h>
+#include <linux/extable.h>
+#include <linux/uaccess.h>
+
+#include <asm/hardirq.h>
+#include <asm/mmu_context.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+
+static inline int delay_slot(struct pt_regs *regs)
+{
+        return 0;
+}
+
+static inline unsigned long exception_epc(struct pt_regs *regs)
+{
+        if (!delay_slot(regs))
+                return regs->pc;
+
+        return regs->pc + 4;
+}
+
+int fixup_exception(struct pt_regs *regs)
+{
+        const struct exception_table_entry *fixup;
+
+        fixup = search_exception_tables(exception_epc(regs));
+        if (fixup) {
+                regs->pc = fixup->nextinsn;
+
+                return 1;
+        }
+
+        return 0;
+}
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ */
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+                              unsigned long mmu_meh)
+{
+        struct vm_area_struct * vma = NULL;
+        struct task_struct *tsk = current;
+        struct mm_struct *mm = tsk->mm;
+        siginfo_t info;
+	int fault;
+	unsigned long address = mmu_meh & PAGE_MASK;
+
+        info.si_code = SEGV_MAPERR;
+
+        /*
+         * We fault-in kernel-space virtual memory on-demand. The
+         * 'reference' page table is init_mm.pgd.
+         *
+         * NOTE! We MUST NOT take any locks for this case. We may
+         * be in an interrupt or a critical region, and should
+         * only copy the information from the master page table,
+         * nothing more.
+         */
+        if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
+                goto vmalloc_fault;
+
+        /*
+         * If we're in an interrupt or have no user
+         * context, we must not take the fault..
+         */
+        if (in_atomic() || !mm)
+                goto bad_area_nosemaphore;
+
+        down_read(&mm->mmap_sem);
+        vma = find_vma(mm, address);
+        if (!vma)
+                goto bad_area;
+        if (vma->vm_start <= address)
+                goto good_area;
+        if (!(vma->vm_flags & VM_GROWSDOWN))
+                goto bad_area;
+        if (expand_stack(vma, address))
+                goto bad_area;
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+info.si_code = SEGV_ACCERR;
+
+        if (write) {
+                if (!(vma->vm_flags & VM_WRITE))
+                        goto bad_area;
+        } else {
+                if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
+                        goto bad_area;
+        }
+
+        /*
+         * If for any reason at all we couldn't handle the fault,
+         * make sure we exit gracefully rather than endlessly redo
+         * the fault.
+         */
+        fault = handle_mm_fault(vma, address, write ? FAULT_FLAG_WRITE : 0);
+        if (unlikely(fault & VM_FAULT_ERROR)) {
+                if (fault & VM_FAULT_OOM)
+                        goto out_of_memory;
+                else if (fault & VM_FAULT_SIGBUS)
+                        goto do_sigbus;
+                else if (fault & VM_FAULT_SIGSEGV)
+                        goto bad_area;
+                BUG();
+        }
+        if (fault & VM_FAULT_MAJOR)
+                tsk->maj_flt++;
+        else
+                tsk->min_flt++;
+
+        up_read(&mm->mmap_sem);
+        return;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+        up_read(&mm->mmap_sem);
+
+bad_area_nosemaphore:
+        /* User mode accesses just cause a SIGSEGV */
+        if (user_mode(regs)) {
+                tsk->thread.address = address;
+                tsk->thread.error_code = write;
+#if 0
+                printk(KERN_ERR "do_page_fault() #2: sending SIGSEGV to %s for"
+                       "invalid %s\n%08lx (epc == %08lx)\n",
+                       tsk->comm,
+                       write ? "write access to" : "read access from",
+                       address,
+                       regs->pc);
+#endif
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                /* info.si_code has been set above */
+                info.si_addr = (void __user *) address;
+                force_sig_info(SIGSEGV, &info, tsk);
+                return;
+        }
+
+no_context:
+	/* Are we prepared to handle this kernel fault? */
+        if (fixup_exception(regs)) return;
+
+	/*
+         * Oops. The kernel tried to access some bad page. We'll have to
+         * terminate things with extreme prejudice.
+         */
+        bust_spinlocks(1);
+
+        printk(KERN_ALERT "Unable to handle kernel paging request at virtual "
+               "address %08lx, epc == %08lx\n",
+               address, regs->pc);
+	die_if_kernel("Oops", regs, write);
+
+out_of_memory:
+        /*
+         * We ran out of memory, call the OOM killer, and return the userspace
+         * (which will retry the fault, or kill us if we got oom-killed).
+         */
+        pagefault_out_of_memory();
+        return;
+
+do_sigbus:
+        up_read(&mm->mmap_sem);
+
+        /* Kernel mode? Handle exceptions or die */
+        if (!user_mode(regs))
+                goto no_context;
+
+        tsk->thread.address = address;
+        info.si_signo = SIGBUS;
+        info.si_errno = 0;
+        info.si_code = BUS_ADRERR;
+        info.si_addr = (void __user *) address;
+        force_sig_info(SIGBUS, &info, tsk);
+
+        return;
+vmalloc_fault:
+        {
+                /*
+                 * Synchronize this task's top level page-table
+                 * with the 'reference' page table.
+                 *
+                 * Do _not_ use "tsk" here. We might be inside
+                 * an interrupt in the middle of a task switch..
+                 */
+                int offset = __pgd_offset(address);
+                pgd_t *pgd, *pgd_k;
+                pud_t *pud, *pud_k;
+                pmd_t *pmd, *pmd_k;
+                pte_t *pte_k;
+
+                unsigned long pgd_base;
+		pgd_base = tlb_get_pgd();
+                pgd = (pgd_t *)pgd_base + offset;
+                pgd_k = init_mm.pgd + offset;
+
+                if (!pgd_present(*pgd_k))
+                        goto no_context;
+                set_pgd(pgd, *pgd_k);
+
+                pud = (pud_t *)pgd;
+                pud_k = (pud_t *)pgd_k;
+                if (!pud_present(*pud_k))
+                        goto no_context;
+
+                pmd = pmd_offset(pud, address);
+                pmd_k = pmd_offset(pud_k, address);
+                if (!pmd_present(*pmd_k))
+                        goto no_context;
+                set_pmd(pmd, *pmd_k);
+
+                pte_k = pte_offset_kernel(pmd_k, address);
+                if (!pte_present(*pte_k))
+                        goto no_context;
+                return;
+        }
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 03/19] csky: Cache and TLB routines
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
  2018-03-18 19:51 ` [PATCH 01/19] csky: Kernel booting Guo Ren
  2018-03-18 19:51 ` [PATCH 02/19] csky: Exception handling and syscall Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 04/19] csky: MMU and page talbe management Guo Ren
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/abiv1/inc/abi/cacheflush.h  |  40 +++++++
 arch/csky/abiv1/src/cacheflush.c      |  32 ++++++
 arch/csky/abiv2/inc/abi/cacheflush.h  |   9 ++
 arch/csky/include/asm/barrier.h       |  14 +++
 arch/csky/include/asm/cache.h         |  32 ++++++
 arch/csky/include/asm/cacheflush.h    |   9 ++
 arch/csky/include/asm/dma-mapping.h   |  17 +++
 arch/csky/include/asm/io.h            |  23 ++++
 arch/csky/include/asm/segment.h       |  18 +++
 arch/csky/include/asm/tlb.h           |  24 ++++
 arch/csky/include/asm/tlbflush.h      |  22 ++++
 arch/csky/include/uapi/asm/cachectl.h |  13 +++
 arch/csky/mm/cachev1.c                | 146 ++++++++++++++++++++++++
 arch/csky/mm/cachev2.c                |  90 +++++++++++++++
 arch/csky/mm/syscache.c               |  50 ++++++++
 arch/csky/mm/tlb.c                    | 207 ++++++++++++++++++++++++++++++++++
 16 files changed, 746 insertions(+)
 create mode 100644 arch/csky/abiv1/inc/abi/cacheflush.h
 create mode 100644 arch/csky/abiv1/src/cacheflush.c
 create mode 100644 arch/csky/abiv2/inc/abi/cacheflush.h
 create mode 100644 arch/csky/include/asm/barrier.h
 create mode 100644 arch/csky/include/asm/cache.h
 create mode 100644 arch/csky/include/asm/cacheflush.h
 create mode 100644 arch/csky/include/asm/dma-mapping.h
 create mode 100644 arch/csky/include/asm/io.h
 create mode 100644 arch/csky/include/asm/segment.h
 create mode 100644 arch/csky/include/asm/tlb.h
 create mode 100644 arch/csky/include/asm/tlbflush.h
 create mode 100644 arch/csky/include/uapi/asm/cachectl.h
 create mode 100644 arch/csky/mm/cachev1.c
 create mode 100644 arch/csky/mm/cachev2.c
 create mode 100644 arch/csky/mm/syscache.c
 create mode 100644 arch/csky/mm/tlb.c

diff --git a/arch/csky/abiv1/inc/abi/cacheflush.h b/arch/csky/abiv1/inc/abi/cacheflush.h
new file mode 100644
index 0000000..94c31b4
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/cacheflush.h
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ABI_CSKY_CACHEFLUSH_H
+#define __ABI_CSKY_CACHEFLUSH_H
+
+#include <linux/compiler.h>
+#include <asm/string.h>
+#include <asm/cache.h>
+
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+extern void flush_dcache_page(struct page *);
+
+#define flush_cache_mm(mm)		cache_wbinv_all()
+#define flush_cache_page(vma,page,pfn)	cache_wbinv_all()
+#define flush_cache_dup_mm(mm)		cache_wbinv_all()
+#define flush_icache_page(vma, page)	icache_inv_all()
+
+#define flush_cache_range(mm,start,end)	cache_wbinv_range(start, end)
+#define flush_cache_vmap(start, end)	cache_wbinv_range(start, end)
+#define flush_cache_vunmap(start, end)  cache_wbinv_range(start, end)
+#define flush_icache_range(start, end)	icache_inv_range(start, end)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+do{ \
+	cache_wbinv_all(); \
+	memcpy(dst, src, len); \
+	icache_inv_all(); \
+}while(0)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do{ \
+	cache_wbinv_all(); \
+	memcpy(dst, src, len); \
+}while(0)
+
+#define flush_dcache_mmap_lock(mapping)		do{}while(0)
+#define flush_dcache_mmap_unlock(mapping)	do{}while(0)
+
+#endif /* __ABI_CSKY_CACHEFLUSH_H */
+
diff --git a/arch/csky/abiv1/src/cacheflush.c b/arch/csky/abiv1/src/cacheflush.c
new file mode 100644
index 0000000..caa095a
--- /dev/null
+++ b/arch/csky/abiv1/src/cacheflush.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/syscalls.h>
+#include <linux/spinlock.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/cacheflush.h>
+#include <asm/cachectl.h>
+#include <abi/reg_ops.h>
+
+void flush_dcache_page(struct page *page)
+{
+	struct address_space *mapping = page_mapping(page);
+	unsigned long addr;
+
+	if (mapping && !mapping_mapped(mapping)) {
+		set_bit(PG_arch_1, &(page)->flags);
+		return;
+	}
+
+	/*
+	 * We could delay the flush for the !page_mapping case too.  But that
+	 * case is for exec env/arg pages and those are %99 certainly going to
+	 * get faulted into the tlb (and thus flushed) anyways.
+	 */
+	addr = (unsigned long) page_address(page);
+	dcache_wbinv_range(addr, addr + PAGE_SIZE);
+}
+
diff --git a/arch/csky/abiv2/inc/abi/cacheflush.h b/arch/csky/abiv2/inc/abi/cacheflush.h
new file mode 100644
index 0000000..f5a1b18
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/cacheflush.h
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ABI_CSKY_CACHEFLUSH_H
+#define __ABI_CSKY_CACHEFLUSH_H
+
+#include <asm-generic/cacheflush.h>
+
+#endif /* __ABI_CSKY_CACHEFLUSH_H */
+
diff --git a/arch/csky/include/asm/barrier.h b/arch/csky/include/asm/barrier.h
new file mode 100644
index 0000000..beea9a0
--- /dev/null
+++ b/arch/csky/include/asm/barrier.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_BARRIER_H
+#define __ASM_CSKY_BARRIER_H
+
+#ifndef __ASSEMBLY__
+
+#define nop()	asm volatile ("nop")
+#define mb()	asm volatile ("sync":::"memory")
+
+#include <asm-generic/barrier.h>
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_CSKY_BARRIER_H */
diff --git a/arch/csky/include/asm/cache.h b/arch/csky/include/asm/cache.h
new file mode 100644
index 0000000..9742347
--- /dev/null
+++ b/arch/csky/include/asm/cache.h
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_CACHE_H
+#define __ASM_CSKY_CACHE_H
+
+/* bytes per L1 cache line */
+#define L1_CACHE_SHIFT	CONFIG_L1_CACHE_SHIFT
+
+#define L1_CACHE_BYTES	(1 << L1_CACHE_SHIFT)
+
+#define ARCH_DMA_MINALIGN	L1_CACHE_BYTES
+
+#ifndef __ASSEMBLY__
+
+void dcache_wb_line(unsigned long start);
+
+void icache_inv_range(unsigned long start, unsigned long end);
+void icache_inv_all(void);
+
+void dcache_wb_range(unsigned long start, unsigned long end);
+void dcache_wbinv_range(unsigned long start, unsigned long end);
+void dcache_inv_range(unsigned long start, unsigned long end);
+void dcache_wbinv_all(void);
+
+void cache_wbinv_range(unsigned long start, unsigned long end);
+void cache_wbinv_all(void);
+
+void dma_wbinv_range(unsigned long start, unsigned long end);
+void dma_wb_range(unsigned long start, unsigned long end);
+
+#endif
+#endif  /* __ASM_CSKY_CACHE_H */
diff --git a/arch/csky/include/asm/cacheflush.h b/arch/csky/include/asm/cacheflush.h
new file mode 100644
index 0000000..6a4233b
--- /dev/null
+++ b/arch/csky/include/asm/cacheflush.h
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_CACHEFLUSH_H
+#define __ASM_CSKY_CACHEFLUSH_H
+
+#include <abi/cacheflush.h>
+
+#endif /* __ASM_CSKY_CACHEFLUSH_H */
+
diff --git a/arch/csky/include/asm/dma-mapping.h b/arch/csky/include/asm/dma-mapping.h
new file mode 100644
index 0000000..f901e2d
--- /dev/null
+++ b/arch/csky/include/asm/dma-mapping.h
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_DMA_MAPPING_H
+#define __ASM_DMA_MAPPING_H
+
+extern struct dma_map_ops csky_dma_map_ops;
+
+#ifdef COMPAT_KERNEL_4_9
+static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+#else
+static inline struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
+#endif
+{
+	return &csky_dma_map_ops;
+}
+
+#endif /* __ASM_DMA_MAPPING_H */
diff --git a/arch/csky/include/asm/io.h b/arch/csky/include/asm/io.h
new file mode 100644
index 0000000..fcb2142
--- /dev/null
+++ b/arch/csky/include/asm/io.h
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_IO_H
+#define __ASM_CSKY_IO_H
+
+#include <abi/pgtable-bits.h>
+#include <linux/types.h>
+#include <linux/version.h>
+
+extern void __iomem *ioremap(phys_addr_t offset, size_t size);
+
+extern void iounmap(void *addr);
+
+extern int remap_area_pages(unsigned long address, phys_addr_t phys_addr,
+		size_t size, unsigned long flags);
+
+#define ioremap_nocache(phy, sz)	ioremap(phy, sz)
+#define ioremap_wc ioremap_nocache
+#define ioremap_wt ioremap_nocache
+
+#include <asm-generic/io.h>
+
+#endif /* __ASM_CSKY_IO_H */
diff --git a/arch/csky/include/asm/segment.h b/arch/csky/include/asm/segment.h
new file mode 100644
index 0000000..cf1440c
--- /dev/null
+++ b/arch/csky/include/asm/segment.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_SEGMENT_H
+#define __ASM_CSKY_SEGMENT_H
+
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define KERNEL_DS		((mm_segment_t) { 0xFFFFFFFF })
+#define get_ds()		KERNEL_DS
+
+#define USER_DS			((mm_segment_t) { 0x80000000UL })
+#define get_fs()		(current_thread_info()->addr_limit)
+#define set_fs(x)		(current_thread_info()->addr_limit = (x))
+#define segment_eq(a,b)		((a).seg == (b).seg)
+
+#endif /* __ASM_CSKY_SEGMENT_H */
diff --git a/arch/csky/include/asm/tlb.h b/arch/csky/include/asm/tlb.h
new file mode 100644
index 0000000..428e2b2
--- /dev/null
+++ b/arch/csky/include/asm/tlb.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_TLB_H
+#define __ASM_CSKY_TLB_H
+
+#include <asm/cacheflush.h>
+
+#define tlb_start_vma(tlb, vma) \
+	do { \
+		if (!tlb->fullmm) \
+		cache_wbinv_range(vma->vm_start, vma->vm_end); \
+	}  while (0)
+
+#define tlb_end_vma(tlb, vma) \
+	do { \
+		if (!tlb->fullmm) \
+		cache_wbinv_range(vma->vm_start, vma->vm_end); \
+	}  while (0)
+
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* __ASM_CSKY_TLB_H */
diff --git a/arch/csky/include/asm/tlbflush.h b/arch/csky/include/asm/tlbflush.h
new file mode 100644
index 0000000..d44cb07
--- /dev/null
+++ b/arch/csky/include/asm/tlbflush.h
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_TLBFLUSH_H
+#define __ASM_TLBFLUSH_H
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb_all() flushes all processes TLB entries
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB entries
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ */
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+
+extern void flush_tlb_one(unsigned long vaddr);
+
+#endif
diff --git a/arch/csky/include/uapi/asm/cachectl.h b/arch/csky/include/uapi/asm/cachectl.h
new file mode 100644
index 0000000..38a1a28
--- /dev/null
+++ b/arch/csky/include/uapi/asm/cachectl.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_CACHECTL_H
+#define __ASM_CSKY_CACHECTL_H
+
+/*
+ * See "man cacheflush"
+ */
+#define ICACHE  (1<<0)
+#define DCACHE  (1<<1)
+#define BCACHE  (ICACHE|DCACHE)
+
+#endif /* __ASM_CSKY_CACHECTL_H */
diff --git a/arch/csky/mm/cachev1.c b/arch/csky/mm/cachev1.c
new file mode 100644
index 0000000..797ed72
--- /dev/null
+++ b/arch/csky/mm/cachev1.c
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/spinlock.h>
+#include <asm/cache.h>
+
+/* for L1-cache */
+#define INS_CACHE		(1 << 0)
+#define DATA_CACHE		(1 << 1)
+#define CACHE_INV		(1 << 4)
+#define CACHE_CLR		(1 << 5)
+#define CACHE_OMS		(1 << 6)
+#define CACHE_ITS		(1 << 7)
+#define CACHE_LICF		(1 << 31)
+
+/* for L2-cache */
+#define CR22_LEVEL_SHIFT        (1)
+#define CR22_SET_SHIFT		(7)
+#define CR22_WAY_SHIFT          (30)
+#define CR22_WAY_SHIFT_L2	(29)
+
+static DEFINE_SPINLOCK(cache_lock);
+
+#define cache_op_line(i, value) \
+	asm volatile( \
+		"mtcr	%0, cr22\n" \
+		"mtcr	%1, cr17\n" \
+		::"r"(i), "r"(value))
+
+#define cache_op_line_atomic(i, value) \
+	asm volatile( \
+		"idly4\n" \
+		"mtcr	%0, cr22\n" \
+		"mtcr	%1, cr17\n" \
+		"sync\n" \
+		::"r"(i), "r"(value))
+
+#define CCR2_L2E (1 << 3)
+static void cache_op_all(unsigned int value, unsigned int l2)
+{
+	asm volatile(
+		"mtcr	%0, cr17\n"
+		::"r"(value | CACHE_CLR));
+
+	asm volatile("sync\n");
+
+	if (l2 && (mfcr_ccr2() & CCR2_L2E)) {
+		asm volatile(
+			"mtcr	%0, cr24\n"
+			"sync\n"
+			::"r"(value));
+	}
+}
+
+static void cache_op_range(
+	unsigned int start,
+	unsigned int end,
+	unsigned int value,
+	unsigned int l2)
+{
+	unsigned long i, flags;
+	unsigned int val = value | CACHE_CLR | CACHE_OMS;
+	bool l2_sync;
+
+	if (unlikely((end - start) >= PAGE_SIZE) ||
+	    unlikely(start < PAGE_OFFSET) ||
+	    unlikely(start >= PAGE_OFFSET + LOWMEM_LIMIT)) {
+		cache_op_all(value, l2);
+		return;
+	}
+
+	if ((mfcr_ccr2() & CCR2_L2E) && l2)
+		l2_sync = 1;
+	else
+		l2_sync = 0;
+
+	spin_lock_irqsave(&cache_lock, flags);
+	for(i = start; i < end; i += L1_CACHE_BYTES) {
+		cache_op_line(i, val);
+		if (l2_sync) {
+			asm volatile(
+				"sync\n");
+			asm volatile(
+				"mtcr	%0, cr24\n"
+				::"r"(val));
+		}
+	}
+	spin_unlock_irqrestore(&cache_lock, flags);
+
+	asm volatile("sync\n");
+}
+
+void inline dcache_wb_line(unsigned long start)
+{
+	cache_op_line_atomic(start, DATA_CACHE|CACHE_CLR);
+}
+
+void icache_inv_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, INS_CACHE|CACHE_INV, 0);
+}
+
+void icache_inv_all(void)
+{
+	cache_op_all(INS_CACHE|CACHE_INV, 0);
+}
+
+void dcache_wb_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, DATA_CACHE|CACHE_CLR, 0);
+}
+
+void dcache_wbinv_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 0);
+}
+
+void dcache_inv_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, DATA_CACHE|CACHE_INV, 0);
+}
+
+void dcache_wbinv_all(void)
+{
+	cache_op_all(DATA_CACHE|CACHE_CLR|CACHE_INV, 0);
+}
+
+void cache_wbinv_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, INS_CACHE|DATA_CACHE|CACHE_CLR|CACHE_INV, 0);
+}
+
+void cache_wbinv_all(void)
+{
+	cache_op_all(INS_CACHE|DATA_CACHE|CACHE_CLR|CACHE_INV, 0);
+}
+
+void dma_wbinv_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, DATA_CACHE|CACHE_CLR|CACHE_INV, 1);
+}
+
+void dma_wb_range(unsigned long start, unsigned long end)
+{
+	cache_op_range(start, end, DATA_CACHE|CACHE_INV, 1);
+}
+
diff --git a/arch/csky/mm/cachev2.c b/arch/csky/mm/cachev2.c
new file mode 100644
index 0000000..6414461
--- /dev/null
+++ b/arch/csky/mm/cachev2.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <asm/cache.h>
+
+void inline dcache_wb_line(unsigned long start)
+{
+	asm volatile("dcache.cval1 %0\n"::"r"(start));
+	asm volatile("sync.is\n");
+}
+
+void icache_inv_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES)
+		asm volatile("icache.iva %0\n"::"r"(i));
+	asm volatile("sync.is\n");
+}
+
+void icache_inv_all(void)
+{
+	asm volatile("icache.ialls\n");
+	asm volatile("sync.is\n");
+}
+
+void dcache_wb_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES)
+		asm volatile("dcache.cval1 %0\n"::"r"(i));
+	asm volatile("sync.is\n");
+}
+
+void dcache_wbinv_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES) {
+		asm volatile("dcache.cval1 %0\n"::"r"(i));
+		asm volatile("dcache.iva %0\n"::"r"(i));
+	}
+	asm volatile("sync.is\n");
+}
+
+void dcache_inv_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES)
+		asm volatile("dcache.iva %0\n"::"r"(i));
+	asm volatile("sync.is\n");
+}
+
+void dcache_wbinv_all(void)
+{
+	asm volatile("dcache.ciall\n");
+	asm volatile("sync.is\n");
+}
+
+void cache_wbinv_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES) {
+		asm volatile("dcache.cval1 %0\n"::"r"(i));
+		asm volatile("dcache.iva %0\n"::"r"(i));
+		asm volatile("icache.iva %0\n"::"r"(i));
+	}
+	asm volatile("sync.is\n");
+}
+
+void cache_wbinv_all(void)
+{
+	asm volatile("dcache.ciall\n");
+	asm volatile("icache.ialls\n");
+	asm volatile("sync.is\n");
+}
+
+void dma_wbinv_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES)
+		asm volatile("dcache.civa %0\n"::"r"(i));
+	asm volatile("sync.is\n");
+}
+
+void dma_wb_range(unsigned long start, unsigned long end)
+{
+	unsigned long i;
+	for(i=start; i<end; i+=L1_CACHE_BYTES)
+		asm volatile("dcache.cva %0\n"::"r"(i));
+	asm volatile("sync.is\n");
+}
+
diff --git a/arch/csky/mm/syscache.c b/arch/csky/mm/syscache.c
new file mode 100644
index 0000000..5eeb1bd
--- /dev/null
+++ b/arch/csky/mm/syscache.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/syscalls.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/cachectl.h>
+
+SYSCALL_DEFINE3(cacheflush,
+		void __user *, addr,
+		unsigned long, bytes,
+		int, cache)
+{
+	switch(cache) {
+	case ICACHE:
+		icache_inv_all();
+		break;
+	case DCACHE:
+		dcache_wbinv_all();
+		break;
+	case BCACHE:
+		cache_wbinv_all();
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+void __update_cache(struct vm_area_struct *vma, unsigned long address,
+	pte_t pte)
+{
+	unsigned long addr;
+	struct page *page;
+	unsigned long pfn;
+
+	pfn = pte_pfn(pte);
+	if (unlikely(!pfn_valid(pfn)))
+		return;
+
+	page = pfn_to_page(pfn);
+	addr = (unsigned long) page_address(page);
+
+	if (vma->vm_flags & VM_EXEC ||
+	    pages_do_alias(addr, address & PAGE_MASK))
+		dcache_wbinv_all();
+
+	clear_bit(PG_arch_1, &(page)->flags);
+}
+
diff --git a/arch/csky/mm/tlb.c b/arch/csky/mm/tlb.c
new file mode 100644
index 0000000..4103464
--- /dev/null
+++ b/arch/csky/mm/tlb.c
@@ -0,0 +1,207 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/setup.h>
+#include <asm/mmu_context.h>
+#include <linux/module.h>
+#include <asm/pgtable.h>
+#include <abi/ckmmu.h>
+
+#define CSKY_TLB_SIZE CONFIG_CPU_TLB_SIZE
+
+void flush_tlb_all(void)
+{
+	tlb_invalid_all();
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0)
+		drop_mmu_context(mm,cpu);
+}
+
+#define restore_asid_inv_utlb(oldpid, newpid) \
+do { \
+	if((oldpid & ASID_MASK) == newpid) \
+		write_mmu_entryhi(oldpid +1); \
+	write_mmu_entryhi(oldpid); \
+} while(0)
+
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+			   unsigned long end)
+{
+	struct mm_struct *mm = vma->vm_mm;
+	int cpu = smp_processor_id();
+
+	if (cpu_context(cpu, mm) != 0) {
+		unsigned long size, flags;
+
+		local_irq_save(flags);
+		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+		size = (size + 1) >> 1;
+		if (size <= CSKY_TLB_SIZE/2) {
+			start &= (PAGE_MASK << 1);
+			end += ((PAGE_SIZE << 1) - 1);
+			end &= (PAGE_MASK << 1);
+#ifdef CONFIG_CPU_HAS_TLBI
+			while (start < end) {
+				asm volatile("tlbi.va %0"::"r"(start):);
+				start += (PAGE_SIZE << 1);
+			}
+#else
+			{
+			int oldpid = read_mmu_entryhi();
+			int newpid = cpu_asid(cpu, mm);
+
+			while (start < end) {
+				int idx;
+
+				write_mmu_entryhi(start | newpid);
+				start += (PAGE_SIZE << 1);
+				tlb_probe();
+				idx = read_mmu_index();
+				if (idx >= 0)
+					tlb_invalid_indexed();
+			}
+			restore_asid_inv_utlb(oldpid, newpid);
+			}
+#endif
+		} else {
+			drop_mmu_context(mm, cpu);
+		}
+		local_irq_restore(flags);
+	}
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+        unsigned long size, flags;
+
+        local_irq_save(flags);
+        size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+        if (size <= CSKY_TLB_SIZE) {
+		start &= (PAGE_MASK << 1);
+		end += ((PAGE_SIZE << 1) - 1);
+		end &= (PAGE_MASK << 1);
+#ifdef CONFIG_CPU_HAS_TLBI
+		while (start < end) {
+			asm volatile("tlbi.va %0"::"r"(start):);
+			start += (PAGE_SIZE << 1);
+		}
+#else
+		{
+                int oldpid = read_mmu_entryhi();
+                while (start < end) {
+                        int idx;
+                        write_mmu_entryhi(start);
+			start += (PAGE_SIZE << 1);
+                        tlb_probe();
+                        idx = read_mmu_index();
+                        if (idx >= 0)
+                                tlb_invalid_indexed();
+                }
+		restore_asid_inv_utlb(oldpid, 0);
+		}
+#endif
+	} else
+		flush_tlb_all();
+
+        local_irq_restore(flags);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
+{
+	int cpu = smp_processor_id();
+
+	if (!vma || cpu_context(cpu, vma->vm_mm) != 0) {
+		page &= (PAGE_MASK << 1);
+
+#ifdef CONFIG_CPU_HAS_TLBI
+		asm volatile("tlbi.va %0"::"r"(page):);
+#else
+		{
+		int newpid, oldpid, idx;
+		unsigned long flags;
+		local_irq_save(flags);
+		newpid = cpu_asid(cpu, vma->vm_mm);
+		oldpid = read_mmu_entryhi();
+		write_mmu_entryhi(page | newpid);
+		tlb_probe();
+		idx = read_mmu_index();
+		if(idx >= 0)
+			tlb_invalid_indexed();
+
+		restore_asid_inv_utlb(oldpid, newpid);
+		local_irq_restore(flags);
+		}
+#endif
+	}
+}
+
+/*
+ * Remove one kernel space TLB entry.  This entry is assumed to be marked
+ * global so we don't do the ASID thing.
+ */
+void flush_tlb_one(unsigned long page)
+{
+	page &= (PAGE_MASK << 1);
+
+#ifdef CONFIG_CPU_HAS_TLBI
+	asm volatile("tlbi.va %0"::"r"(page):);
+#else
+	{
+	int idx, oldpid;
+	unsigned long flags;
+	oldpid = read_mmu_entryhi();
+
+	local_irq_save(flags);
+	page = page | (oldpid & 0xff);
+	write_mmu_entryhi(page);
+	tlb_probe();
+	idx = read_mmu_index();
+	if (idx >= 0)
+		tlb_invalid_indexed();
+	restore_asid_inv_utlb(oldpid, oldpid);
+	local_irq_restore(flags);
+	}
+#endif
+}
+
+EXPORT_SYMBOL(flush_tlb_one);
+
+/* show current 32 jtlbs */
+void show_jtlb_table(void)
+{
+	unsigned long flags;
+	int entryhi, entrylo0, entrylo1;
+	int entry;
+	int oldpid;
+
+	local_irq_save(flags);
+	entry = 0;
+	printk("\n\n\n");
+
+	oldpid = read_mmu_entryhi();
+	while (entry < CSKY_TLB_SIZE)
+	{
+		write_mmu_index(entry);
+		tlb_read();
+		entryhi = read_mmu_entryhi();
+		entrylo0 = read_mmu_entrylo0();
+		entrylo0 = entrylo0;
+		entrylo1 = read_mmu_entrylo1();
+		entrylo1 = entrylo1;
+		printk("jtlb[%d]:	entryhi - 0x%x;	entrylo0 - 0x%x;"
+		       "	entrylo1 - 0x%x\n",
+			 entry, entryhi, entrylo0, entrylo1);
+		entry++;
+	}
+	write_mmu_entryhi(oldpid);
+	local_irq_restore(flags);
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 04/19] csky: MMU and page talbe management
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (2 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 03/19] csky: Cache and TLB routines Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 05/19] csky: Process management Guo Ren
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/abiv1/inc/abi/ckmmu.h        | 140 +++++++++++++++
 arch/csky/abiv1/inc/abi/page.h         |  26 +++
 arch/csky/abiv1/inc/abi/pgtable-bits.h |  36 ++++
 arch/csky/abiv1/src/mmap.c             |  65 +++++++
 arch/csky/abiv2/inc/abi/ckmmu.h        | 126 ++++++++++++++
 arch/csky/abiv2/inc/abi/page.h         |  20 +++
 arch/csky/abiv2/inc/abi/pgtable-bits.h |  36 ++++
 arch/csky/include/asm/addrspace.h      |  10 ++
 arch/csky/include/asm/fixmap.h         |  65 +++++++
 arch/csky/include/asm/highmem.h        |  50 ++++++
 arch/csky/include/asm/mmu.h            |  11 ++
 arch/csky/include/asm/page.h           | 108 ++++++++++++
 arch/csky/include/asm/pgalloc.h        | 113 ++++++++++++
 arch/csky/include/asm/pgtable.h        | 309 +++++++++++++++++++++++++++++++++
 arch/csky/include/asm/shmparam.h       |  10 ++
 arch/csky/mm/dma-mapping.c             | 250 ++++++++++++++++++++++++++
 arch/csky/mm/highmem.c                 | 210 ++++++++++++++++++++++
 arch/csky/mm/init.c                    | 101 +++++++++++
 arch/csky/mm/ioremap.c                 |  49 ++++++
 19 files changed, 1735 insertions(+)
 create mode 100644 arch/csky/abiv1/inc/abi/ckmmu.h
 create mode 100644 arch/csky/abiv1/inc/abi/page.h
 create mode 100644 arch/csky/abiv1/inc/abi/pgtable-bits.h
 create mode 100644 arch/csky/abiv1/src/mmap.c
 create mode 100644 arch/csky/abiv2/inc/abi/ckmmu.h
 create mode 100644 arch/csky/abiv2/inc/abi/page.h
 create mode 100644 arch/csky/abiv2/inc/abi/pgtable-bits.h
 create mode 100644 arch/csky/include/asm/addrspace.h
 create mode 100644 arch/csky/include/asm/fixmap.h
 create mode 100644 arch/csky/include/asm/highmem.h
 create mode 100644 arch/csky/include/asm/mmu.h
 create mode 100644 arch/csky/include/asm/page.h
 create mode 100644 arch/csky/include/asm/pgalloc.h
 create mode 100644 arch/csky/include/asm/pgtable.h
 create mode 100644 arch/csky/include/asm/shmparam.h
 create mode 100644 arch/csky/mm/dma-mapping.c
 create mode 100644 arch/csky/mm/highmem.c
 create mode 100644 arch/csky/mm/init.c
 create mode 100644 arch/csky/mm/ioremap.c

diff --git a/arch/csky/abiv1/inc/abi/ckmmu.h b/arch/csky/abiv1/inc/abi/ckmmu.h
new file mode 100644
index 0000000..5bdba66
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/ckmmu.h
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_CKMMUV1_H
+#define __ASM_CSKY_CKMMUV1_H
+
+static inline void select_mmu_cp(void)
+{
+	 asm volatile("cpseti cp15\n");
+}
+
+static inline int read_mmu_index(void)
+{
+	int res;
+	asm volatile(
+		"cprcr %0, cpcr0\n"
+		:"=b" (res));
+	return   res;
+}
+
+static inline void write_mmu_index(int value)
+{
+
+	asm volatile(
+		"cpwcr %0, cpcr0\n"
+		::"b"(value));
+}
+
+static inline int read_mmu_entrylo0(void)
+{
+	int res;
+	asm volatile(
+		"cprcr %0, cpcr2\n"
+		:"=b" (res));
+
+	return res << 6;
+}
+
+static inline int read_mmu_entrylo1(void)
+{
+	int res;
+	asm volatile(
+		"cprcr %0, cpcr3\n"
+		:"=b" (res));
+
+	return res << 6;
+}
+
+static inline void write_mmu_pagemask(int value)
+{
+	asm volatile(
+		"cpwcr %0, cpcr6\n"
+		::"b"(value));
+}
+
+static inline int read_mmu_entryhi(void)
+{
+	int res;
+	asm volatile(
+		"cprcr %0, cpcr4\n"
+		:"=b" (res));
+
+	return res;
+}
+
+static inline void write_mmu_entryhi(int value)
+{
+
+	asm volatile(
+		"cpwcr %0, cpcr4\n"
+		::"b"(value));
+}
+
+/*
+ * TLB operations.
+ */
+static inline void tlb_probe(void)
+{
+	int value = 0x80000000;
+
+	asm volatile(
+		"cpwcr %0, cpcr8\n"
+		::"b"(value));
+}
+
+static inline void tlb_read(void)
+{
+	int value = 0x40000000;
+
+	asm volatile(
+		"cpwcr %0, cpcr8\n"
+		::"b"(value));
+}
+
+static inline void tlb_invalid_all(void)
+{
+	int value = 0x04000000;
+
+	asm volatile(
+		"cpwcr %0, cpcr8\n"
+		::"b"(value));
+}
+
+static inline void tlb_invalid_indexed(void)
+{
+	int value = 0x02000000;
+
+	asm volatile(
+		"cpwcr %0, cpcr8\n"
+		::"b"(value));
+}
+
+/* misc */
+static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
+{
+	asm volatile(
+		"bseti %0, 0		\n"
+		"bclri %0, 31		\n"
+		"addu  %0, %1		\n"
+		"cpseti cp15		\n"
+		"cpwcr %0, cpcr29	\n"
+		::"b"(pgd), "r"(PHYS_OFFSET)
+		:);
+}
+
+static inline unsigned long tlb_get_pgd(void)
+{
+	unsigned long pgd;
+	asm volatile(
+		"cpseti	cp15		\n"
+		"cprcr	%0, cpcr29	\n"
+		"bclri	%0, 0		\n"
+		"subu	%0, %1		\n"
+                "bseti	%0, 31		\n"
+                :"=&b"(pgd)
+		:"r"(PHYS_OFFSET)
+                :);
+	return pgd;
+}
+#endif /* __ASM_CSKY_CKMMUV1_H */
+
diff --git a/arch/csky/abiv1/inc/abi/page.h b/arch/csky/abiv1/inc/abi/page.h
new file mode 100644
index 0000000..b0d2122
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/page.h
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+extern unsigned long shm_align_mask;
+extern void flush_dcache_page(struct page *);
+
+static inline unsigned long pages_do_alias(unsigned long addr1,
+					   unsigned long addr2)
+{
+	return (addr1 ^ addr2) & shm_align_mask;
+}
+
+static inline void clear_user_page(void *addr, unsigned long vaddr,
+				   struct page *page)
+{
+	clear_page(addr);
+	if (pages_do_alias((unsigned long) addr, vaddr & PAGE_MASK))
+		flush_dcache_page(page);
+}
+
+static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
+				  struct page *page)
+{
+	copy_page(to, from);
+	if (pages_do_alias((unsigned long) to, vaddr & PAGE_MASK))
+		flush_dcache_page(page);
+}
diff --git a/arch/csky/abiv1/inc/abi/pgtable-bits.h b/arch/csky/abiv1/inc/abi/pgtable-bits.h
new file mode 100644
index 0000000..3d614f3
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/pgtable-bits.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_PGTABLE_BITS_H
+#define __ASM_CSKY_PGTABLE_BITS_H
+
+/* implemented in software */
+#define _PAGE_ACCESSED		(1<<3)
+#define PAGE_ACCESSED_BIT	(3)
+
+#define _PAGE_READ		(1<<1)
+#define _PAGE_WRITE		(1<<2)
+#define _PAGE_PRESENT		(1<<0)
+
+#define _PAGE_MODIFIED		(1<<4)
+#define PAGE_MODIFIED_BIT	(4)
+
+/* implemented in hardware */
+#define _PAGE_GLOBAL		(1<<6)
+
+#define _PAGE_VALID		(1<<7)
+#define PAGE_VALID_BIT		(7)
+
+#define _PAGE_DIRTY		(1<<8)
+#define PAGE_DIRTY_BIT		(8)
+
+#define _PAGE_CACHE		(3<<9)
+#define _PAGE_UNCACHE		(2<<9)
+
+#define _CACHE_MASK		(7<<9)
+
+#define _CACHE_CACHED		(_PAGE_VALID | _PAGE_CACHE)
+#define _CACHE_UNCACHED		(_PAGE_VALID | _PAGE_UNCACHE)
+
+#define HAVE_ARCH_UNMAPPED_AREA
+
+#endif /* __ASM_CSKY_PGTABLE_BITS_H */
diff --git a/arch/csky/abiv1/src/mmap.c b/arch/csky/abiv1/src/mmap.c
new file mode 100644
index 0000000..e70a74b
--- /dev/null
+++ b/arch/csky/abiv1/src/mmap.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/shm.h>
+#include <linux/sched.h>
+#include <linux/random.h>
+#include <linux/io.h>
+
+unsigned long shm_align_mask = (0x4000 >> 1) - 1;   /* Sane caches */
+
+#define COLOUR_ALIGN(addr,pgoff)                            \
+	((((addr) + shm_align_mask) & ~shm_align_mask) +        \
+	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+		unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+	int do_color_align;
+
+	if (flags & MAP_FIXED) {
+		/*
+		 * We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) &&
+				((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
+			return -EINVAL;
+		return addr;
+	}
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	if (addr) {
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+		vmm = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+				(!vmm || addr + len <= vmm->vm_start))
+			return addr;
+	}
+	addr = TASK_UNMAPPED_BASE;
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
diff --git a/arch/csky/abiv2/inc/abi/ckmmu.h b/arch/csky/abiv2/inc/abi/ckmmu.h
new file mode 100644
index 0000000..7ff5b3f
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/ckmmu.h
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_CKMMUV2_H
+#define __ASM_CSKY_CKMMUV2_H
+
+static inline void select_mmu_cp(void){}
+
+static inline int  read_mmu_index(void)
+{
+	int res;
+	asm volatile("mfcr %0,cr<0, 15>\n"
+		:"=r"(res));
+	return res;
+}
+
+static inline void  write_mmu_index(int value)
+{
+	asm volatile("mtcr %0,cr<0, 15>\n"
+		::"r" (value));
+}
+
+static inline int  read_mmu_entrylo0(void)
+{
+	int res;
+	asm volatile("mfcr %0,cr<2, 15>\n"
+		:"=r"(res));
+	return res;
+}
+
+static inline int  read_mmu_entrylo1(void)
+{
+	int res;
+
+	asm volatile("mfcr %0,cr<3, 15>\n"
+		:"=r"(res));
+	return res;
+}
+
+static inline void  write_mmu_pagemask(int value)
+{
+	asm volatile("mtcr %0,cr<6, 15>\n"
+		::"r" (value));
+}
+
+static inline int  read_mmu_entryhi(void)
+{
+	int res;
+
+	asm volatile("mfcr %0,cr<4, 15>\n"
+		:"=r" (res));
+	return res;
+}
+
+static inline void  write_mmu_entryhi(int value)
+{
+	asm volatile("mtcr %0,cr<4, 15>\n"
+		::"r" (value));
+}
+
+/*
+ * TLB operations.
+ */
+static inline void tlb_probe(void)
+{
+	int value = 0x80000000;
+
+	asm volatile("mtcr %0,cr<8, 15>\n"
+		::"r" (value));
+}
+
+static inline void tlb_read(void)
+{
+	int value = 0x40000000;
+
+	asm volatile("mtcr %0,cr<8, 15>\n"
+		::"r" (value));
+}
+
+static inline void tlb_invalid_all(void)
+{
+#ifdef CONFIG_CPU_HAS_TLBI
+	asm volatile("tlbi.all\n");
+#else
+	int value = 0x04000000;
+
+	asm volatile("mtcr %0,cr<8, 15>\n"
+		::"r" (value));
+#endif
+}
+
+static inline void tlb_invalid_indexed(void)
+{
+	int value = 0x02000000;
+
+	asm volatile("mtcr %0,cr<8, 15>\n"
+		::"r" (value));
+}
+
+/* misc */
+static inline void tlbmiss_handler_setup_pgd(unsigned long pgd)
+{
+	asm volatile(
+		"bseti %0, 0		\n"
+		"bclri %0, 31		\n"
+		"addu  %0, %1		\n"
+		"mtcr  %0, cr<29, 15>	\n"
+		"mtcr  %0, cr<28, 15>	\n"
+		::"r"(pgd), "r"(PHYS_OFFSET)
+		:);
+}
+
+static inline unsigned long tlb_get_pgd(void)
+{
+	unsigned long pgd;
+	asm volatile(
+		"mfcr %0, cr<29, 15>	\n"
+		"bclri	%0, 0		\n"
+		"subu	%0, %1		\n"
+                "bseti	%0, 31		\n"
+                :"=&r"(pgd)
+		:"r"(PHYS_OFFSET)
+                :);
+	return pgd;
+}
+#endif /* __ASM_CSKY_CKMMUV2_H */
+
diff --git a/arch/csky/abiv2/inc/abi/page.h b/arch/csky/abiv2/inc/abi/page.h
new file mode 100644
index 0000000..5f25a68
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/page.h
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+static inline unsigned long pages_do_alias(unsigned long addr1,
+					   unsigned long addr2)
+{
+	return 0;
+}
+
+static inline void clear_user_page(void *addr, unsigned long vaddr,
+				   struct page *page)
+{
+	clear_page(addr);
+}
+
+static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
+				  struct page *page)
+{
+	copy_page(to, from);
+}
+
diff --git a/arch/csky/abiv2/inc/abi/pgtable-bits.h b/arch/csky/abiv2/inc/abi/pgtable-bits.h
new file mode 100644
index 0000000..3ca90fa
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/pgtable-bits.h
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_PGTABLE_BITS_H
+#define __ASM_CSKY_PGTABLE_BITS_H
+
+/* implemented in software */
+#define _PAGE_ACCESSED		(1<<7)
+#define PAGE_ACCESSED_BIT	(7)
+
+#define _PAGE_READ		(1<<8)
+#define _PAGE_WRITE		(1<<9)
+#define _PAGE_PRESENT		(1<<10)
+
+#define _PAGE_MODIFIED		(1<<11)
+#define PAGE_MODIFIED_BIT	(11)
+
+/* implemented in hardware */
+#define _PAGE_GLOBAL		(1<<0)
+
+#define _PAGE_VALID		(1<<1)
+#define PAGE_VALID_BIT		(1)
+
+#define _PAGE_DIRTY		(1<<2)
+#define PAGE_DIRTY_BIT		(2)
+
+#define _PAGE_SO		(1<<5)
+#define _PAGE_BUF		(1<<6)
+
+#define _PAGE_CACHE		(1<<3)
+
+#define _CACHE_MASK		_PAGE_CACHE
+
+#define _CACHE_CACHED		(_PAGE_VALID | _PAGE_CACHE | _PAGE_BUF)
+#define _CACHE_UNCACHED		(_PAGE_VALID | _PAGE_SO)
+
+#endif /* __ASM_CSKY_PGTABLE_BITS_H */
diff --git a/arch/csky/include/asm/addrspace.h b/arch/csky/include/asm/addrspace.h
new file mode 100644
index 0000000..63f86ad
--- /dev/null
+++ b/arch/csky/include/asm/addrspace.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_ADDRSPACE_H
+#define __ASM_CSKY_ADDRSPACE_H
+
+#define KSEG0		0x80000000ul
+#define KSEG0ADDR(a)	(((unsigned long)a & 0x1fffffff) | KSEG0)
+
+#endif /* __ASM_CSKY_ADDRSPACE_H */
+
diff --git a/arch/csky/include/asm/fixmap.h b/arch/csky/include/asm/fixmap.h
new file mode 100644
index 0000000..65a9cf5
--- /dev/null
+++ b/arch/csky/include/asm/fixmap.h
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_FIXMAP_H
+#define __ASM_CSKY_FIXMAP_H
+
+#include <asm/page.h>
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#endif
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special  addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#define FIX_N_COLOURS 8
+	FIX_CMAP_BEGIN,
+	FIX_CMAP_END = FIX_CMAP_BEGIN + (FIX_N_COLOURS * 2),
+#ifdef CONFIG_HIGHMEM
+	/* reserved pte's for temporary kernel mappings */
+	FIX_KMAP_BEGIN = FIX_CMAP_END + 1,
+	FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+	__end_of_fixed_addresses
+};
+
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+#define FIXADDR_TOP	((unsigned long)(long)(int)0xfffe0000)
+#define FIXADDR_SIZE	(__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START	(FIXADDR_TOP - FIXADDR_SIZE)
+
+#include <asm-generic/fixmap.h>
+
+#define kmap_get_fixmap_pte(vaddr) \
+	pte_offset_kernel(pmd_offset((pud_t *)pgd_offset_k(vaddr), vaddr), (vaddr))
+
+#endif /* __ASM_CSKY_FIXMAP_H */
diff --git a/arch/csky/include/asm/highmem.h b/arch/csky/include/asm/highmem.h
new file mode 100644
index 0000000..0132e93
--- /dev/null
+++ b/arch/csky/include/asm/highmem.h
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_HIGHMEM_H
+#define __ASM_CSKY_HIGHMEM_H
+
+#ifdef __KERNEL__
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <asm/kmap_types.h>
+#include <asm/cache.h>
+
+/* undef for production */
+#define HIGHMEM_DEBUG 1
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *pkmap_page_table;
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ */
+#define LAST_PKMAP 1024
+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
+#define PKMAP_NR(virt)  ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+extern void * kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+extern void *kmap(struct page *page);
+extern void kunmap(struct page *page);
+extern void *kmap_atomic(struct page *page);
+extern void __kunmap_atomic(void *kvaddr);
+extern void *kmap_atomic_pfn(unsigned long pfn);
+extern struct page *kmap_atomic_to_page(void *ptr);
+
+#define flush_cache_kmaps() cache_wbinv_all()
+
+extern void kmap_init(void);
+
+#define kmap_prot PAGE_KERNEL
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_CSKY_HIGHMEM_H */
diff --git a/arch/csky/include/asm/mmu.h b/arch/csky/include/asm/mmu.h
new file mode 100644
index 0000000..db29c17
--- /dev/null
+++ b/arch/csky/include/asm/mmu.h
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_MMU_H
+#define __ASM_CSKY_MMU_H
+
+typedef struct {
+	unsigned long asid[NR_CPUS];
+	void *vdso;
+} mm_context_t;
+
+#endif /* __ASM_CSKY_MMU_H */
diff --git a/arch/csky/include/asm/page.h b/arch/csky/include/asm/page.h
new file mode 100644
index 0000000..500bea5
--- /dev/null
+++ b/arch/csky/include/asm/page.h
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_PAGE_H
+#define __ASM_CSKY_PAGE_H
+
+#include <asm/setup.h>
+#include <asm/cache.h>
+#include <linux/const.h>
+
+/*
+ * PAGE_SHIFT determines the page size
+ */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE - 1))
+#define THREAD_SIZE	(PAGE_SIZE * 2)
+
+/*
+ * NOTE: virtual isn't really correct, actually it should be the offset into the
+ * memory node, but we have no highmem, so that works for now.
+ * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots
+ * of the shifts unnecessary.
+ */
+
+#ifndef __ASSEMBLY__
+
+#include <linux/pfn.h>
+
+#define virt_to_pfn(kaddr)      (__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)        __va((pfn) << PAGE_SHIFT)
+
+#define virt_addr_valid(kaddr)  ((void *)(kaddr) >= (void *)PAGE_OFFSET && \
+                                 (void *)(kaddr) < high_memory)
+extern unsigned long min_low_pfn, max_pfn;
+#define pfn_valid(pfn)		((pfn >= min_low_pfn) && (pfn < max_pfn))
+
+extern void *memset(void *dest, int c, size_t l);
+extern void *memcpy (void *to, const void *from, size_t l);
+
+#define clear_page(page)        memset((page), 0, PAGE_SIZE)
+#define copy_page(to,from)      memcpy((to), (from), PAGE_SIZE)
+
+#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
+
+struct page;
+
+#include <abi/page.h>
+
+struct vm_area_struct;
+
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte_low; } pte_t;
+#define pte_val(x)    ((x).pte_low)
+
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct page *pgtable_t;
+
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define ptep_buddy(x)	((pte_t *)((unsigned long)(x) ^ sizeof(pte_t)))
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * This handles the memory map.
+ * We handle pages at KSEG0 for kernels with 32 bit address space.
+ */
+
+#define	PAGE_OFFSET	0x80000000
+#define LOWMEM_LIMIT	0x20000000
+
+#define PHYS_OFFSET	CONFIG_SSEG0_BASE
+#define ARCH_PFN_OFFSET	PFN_DOWN(CONFIG_RAM_BASE + PHYS_OFFSET)
+
+#define MASK_SSEG1(x) ((unsigned long)(x) & (~LOWMEM_LIMIT))
+
+#define __pa(x)		(MASK_SSEG1(x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __va(x)		((void *)((unsigned long)(x) + PAGE_OFFSET - PHYS_OFFSET))
+#define __pa_symbol(x)  __pa(RELOC_HIDE(MASK_SSEG1(x), 0))
+
+#define MAP_NR(x)	PFN_DOWN(MASK_SSEG1(x) - PAGE_OFFSET - CONFIG_RAM_BASE)
+#define virt_to_page(x)		(mem_map + MAP_NR(x))
+
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#define UNCACHE_ADDR(x)		((unsigned long)(x) | LOWMEM_LIMIT)
+
+/*
+ * main RAM and kernel working space are coincident at 0x80000000, but to make
+ * life more interesting, there's also an uncached virtual shadow at 0xb0000000
+ * - these mappings are fixed in the MMU
+ */
+
+#define pfn_to_kaddr(x)       __va(PFN_PHYS(x))
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* __ASM_CSKY_PAGE_H */
diff --git a/arch/csky/include/asm/pgalloc.h b/arch/csky/include/asm/pgalloc.h
new file mode 100644
index 0000000..7324c6b
--- /dev/null
+++ b/arch/csky/include/asm/pgalloc.h
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_PGALLOC_H
+#define __ASM_CSKY_PGALLOC_H
+
+#include <linux/highmem.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+
+static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd,
+        pte_t *pte)
+{
+        set_pmd(pmd, __pmd(__pa(pte)));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+        pgtable_t pte)
+{
+        set_pmd(pmd, __pmd(__pa(page_address(pte))));
+}
+
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+extern void pgd_init(unsigned long *p);
+
+#ifdef COMPAT_KERNEL_4_9
+#define __GFP_RETRY_MAYFAIL __GFP_REPEAT
+#endif
+
+static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
+        unsigned long address)
+{
+        pte_t *pte;
+	unsigned long *kaddr, i;
+
+	pte = (pte_t *) __get_free_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, PTE_ORDER);
+	kaddr = (unsigned long *)pte;
+	if (address & 0x80000000)
+		for(i=0; i<(PAGE_SIZE/4); i++)
+			*(kaddr + i) = 0x1;
+	else
+		clear_page(kaddr);
+
+        return pte;
+}
+
+static inline struct page *pte_alloc_one(struct mm_struct *mm,
+                                            unsigned long address)
+{
+	struct page *pte;
+	unsigned long *kaddr, i;
+
+        pte = alloc_pages(GFP_KERNEL | __GFP_RETRY_MAYFAIL, PTE_ORDER);
+        if (pte) {
+		kaddr = kmap_atomic(pte);
+		if (address & 0x80000000) {
+			for(i=0; i<(PAGE_SIZE/4); i++)
+				*(kaddr + i) = 0x1;
+		} else
+			clear_page(kaddr);
+		kunmap_atomic(kaddr);
+		pgtable_page_ctor(pte);
+        }
+        return pte;
+}
+
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+        free_pages((unsigned long)pte, PTE_ORDER);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+        pgtable_page_dtor(pte);
+        __free_pages(pte, PTE_ORDER);
+}
+
+static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+        free_pages((unsigned long)pgd, PGD_ORDER);
+}
+
+static inline pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+        pgd_t *ret, *init;
+
+        ret = (pgd_t *) __get_free_pages(GFP_KERNEL, PGD_ORDER);
+        if (ret) {
+                init = pgd_offset(&init_mm, 0UL);
+                pgd_init((unsigned long *)ret);
+                memcpy(ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+                       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+#ifdef CONFIG_CPU_NEED_TLBSYNC
+		dcache_wb_range((unsigned int)ret, (unsigned int)(ret + PTRS_PER_PGD));
+#endif
+        }
+
+        return ret;
+}
+
+#define __pte_free_tlb(tlb,pte,address)                 \
+do {                                                    \
+        pgtable_page_dtor(pte);                         \
+        tlb_remove_page((tlb), pte);                    \
+} while (0)
+
+#define check_pgt_cache()               do {} while(0)
+
+extern void pagetable_init(void);
+
+#endif /* __ASM_CSKY_PGALLOC_H */
+
diff --git a/arch/csky/include/asm/pgtable.h b/arch/csky/include/asm/pgtable.h
new file mode 100644
index 0000000..5c01602
--- /dev/null
+++ b/arch/csky/include/asm/pgtable.h
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_PGTABLE_H
+#define __ASM_CSKY_PGTABLE_H
+
+#include <asm/fixmap.h>
+#include <asm/addrspace.h>
+#include <abi/pgtable-bits.h>
+#include <asm-generic/pgtable-nopmd.h>
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT		22
+#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK		(~(PGDIR_SIZE-1))
+
+#define USER_PTRS_PER_PGD	(0x80000000UL/PGDIR_SIZE)
+#define FIRST_USER_ADDRESS	0UL
+
+#define VMALLOC_START		(0xc0008000)
+#ifdef CONFIG_HIGHMEM
+#define PKMAP_BASE		(0xfe000000UL)
+#define VMALLOC_END		(PKMAP_BASE - 2*PAGE_SIZE)
+#else
+#define VMALLOC_END		(FIXADDR_START - 2*PAGE_SIZE)
+#endif
+
+/*
+ * traditional two-level paging structure:
+ */
+#define PGD_ORDER	0
+#define PTE_ORDER	0
+
+#define PTRS_PER_PGD	((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PTE	((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
+
+#define pte_ERROR(e) \
+	printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
+#define pgd_ERROR(e) \
+	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/* Find an entry in the third-level page table.. */
+#define __pte_offset_t(address) \
+	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address) \
+	(pmd_page_vaddr(*(dir)) + __pte_offset_t(address))
+#define pte_offset_map(dir, address) \
+	((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset_t(address))
+#define pmd_page(pmd)			(pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT))
+#define pte_clear(mm,addr,ptep)		set_pte((ptep), \
+					(((unsigned int)addr&0x80000000)?__pte(1):__pte(0)))
+#define pte_none(pte)			(!(pte_val(pte)&0xfffffffe))
+#define pte_present(pte)		(pte_val(pte) & _PAGE_PRESENT )
+#define pte_pfn(x)			((unsigned long)((x).pte_low >> PAGE_SHIFT))
+#define pfn_pte(pfn, prot)		__pte(((unsigned long long)(pfn) << PAGE_SHIFT) \
+						| pgprot_val(prot))
+
+#define __READABLE	(_PAGE_READ | _PAGE_VALID | _PAGE_ACCESSED)
+#define __WRITEABLE	(_PAGE_WRITE | _PAGE_DIRTY | _PAGE_MODIFIED)
+
+#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_MODIFIED | _CACHE_MASK)
+
+#define pte_unmap(pte) ((void)(pte))
+
+#define __swp_type(x)			(((x).val >> 4) & 0xff)
+#define __swp_offset(x)			((x).val >> 12)
+#define __swp_entry(type, offset)	((swp_entry_t) {((type) << 4) | ((offset) << 12) })
+#define __pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x)		((pte_t) { (x).val })
+
+#define pte_page(x)			pfn_to_page(pte_pfn(x))
+#define __mk_pte(page_nr,pgprot)	__pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
+
+/*
+ * CSKY can't do page protection for execute, and considers that the same like
+ * read. Also, write permissions imply read permissions. This is the closest
+ * we can get by reasonable means..
+ */
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _CACHE_CACHED)
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+				_CACHE_CACHED)
+#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_READ | _CACHE_CACHED)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_READ | _CACHE_CACHED)
+#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE | \
+				_PAGE_GLOBAL | _CACHE_CACHED)
+#define PAGE_USERIO	__pgprot(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+				_CACHE_CACHED)
+
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr)	(virt_to_page(empty_zero_page))
+
+extern void load_pgd(unsigned long pg_dir);
+extern pte_t invalid_pte_table[PTRS_PER_PTE];
+
+static inline int pte_special(pte_t pte) { return 0; }
+static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+
+static inline void set_pte(pte_t *p, pte_t pte)
+{
+	*p = pte;
+#if defined(CONFIG_CPU_NEED_TLBSYNC)
+	dcache_wb_line((u32)p);
+#endif
+}
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+{
+	unsigned long ptr;
+
+	ptr = pmd_val(pmd);
+
+	return __va(ptr);
+}
+
+#define pmd_phys(pmd) pmd_val(pmd)
+
+static inline void set_pmd(pmd_t *p, pmd_t pmd)
+{
+	*p = pmd;
+#if defined(CONFIG_CPU_NEED_TLBSYNC)
+	dcache_wb_line((u32)p);
+#endif
+}
+
+
+static inline int pmd_none(pmd_t pmd)
+{
+	return pmd_val(pmd) == __pa(invalid_pte_table);
+}
+
+#define pmd_bad(pmd)	(pmd_val(pmd) & ~PAGE_MASK)
+
+static inline int pmd_present(pmd_t pmd)
+{
+        return (pmd_val(pmd) != __pa(invalid_pte_table));
+}
+
+static inline void pmd_clear(pmd_t *p)
+{
+        pmd_val(*p) = (__pa(invalid_pte_table));
+#if defined(CONFIG_CPU_NEED_TLBSYNC)
+        dcache_wb_line((u32)p);
+#endif
+}
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte)
+{
+	return pte.pte_low & _PAGE_READ;
+}
+
+static inline int pte_write(pte_t pte)
+{
+	return (pte).pte_low & _PAGE_WRITE;
+}
+
+static inline int pte_dirty(pte_t pte)
+{
+	return (pte).pte_low & _PAGE_MODIFIED;
+}
+
+static inline int pte_young(pte_t pte)
+{
+	return (pte).pte_low & _PAGE_ACCESSED;
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_WRITE | _PAGE_DIRTY);
+	return pte;
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_MODIFIED|_PAGE_DIRTY);
+	return pte;
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+	pte_val(pte) &= ~(_PAGE_ACCESSED|_PAGE_VALID);
+	return pte;
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_WRITE;
+	if (pte_val(pte) & _PAGE_MODIFIED)
+		pte_val(pte) |= _PAGE_DIRTY;
+	return pte;
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_MODIFIED;
+	if (pte_val(pte) & _PAGE_WRITE)
+		pte_val(pte) |= _PAGE_DIRTY;
+	return pte;
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+	pte_val(pte) |= _PAGE_ACCESSED;
+	if (pte_val(pte) & _PAGE_READ)
+		pte_val(pte) |= _PAGE_VALID;
+	return pte;
+}
+
+#define __pgd_offset(address)	pgd_index(address)
+#define __pud_offset(address)	(((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1))
+#define __pmd_offset(address)	(((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address)	pgd_offset(&init_mm, address)
+
+#define pgd_index(address)	((address) >> PGDIR_SHIFT)
+
+/*
+ * Macro to make mark a page protection value as "uncacheable".  Note
+ * that "protection" is really a misnomer here as the protection value
+ * contains the memory attribute bits, dirty bits, and various other
+ * bits as well.
+ */
+#define pgprot_noncached pgprot_noncached
+
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+	unsigned long prot = pgprot_val(_prot);
+
+	prot = (prot & ~_CACHE_MASK) | _CACHE_UNCACHED;
+
+	return __pgprot(prot);
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+#define mk_pte(page, pgprot)    pfn_pte(page_to_pfn(page), (pgprot))
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+	return __pte((pte_val(pte) & _PAGE_CHG_MASK) |
+		     (pgprot_val(newprot)));
+}
+
+/* to find an entry in a page-table-directory */
+static inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address)
+{
+	return mm->pgd + pgd_index(address);
+}
+
+/* Find an entry in the third-level page table.. */
+static inline pte_t *pte_offset(pmd_t * dir, unsigned long address)
+{
+	return (pte_t *) (pmd_page_vaddr(*dir)) +
+		((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+}
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+extern void paging_init(void);
+
+extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
+		pte_t pte);
+extern void show_jtlb_table(void);
+
+static inline void update_mmu_cache(struct vm_area_struct *vma,
+		unsigned long address, pte_t *ptep)
+{
+	pte_t pte = *ptep;
+	__update_cache(vma, address, pte);
+}
+
+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
+#define PageSkip(page)		(0)
+#define kern_addr_valid(addr)	(1)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init()	do{}while(0)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+	remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#include <asm-generic/pgtable.h>
+
+#endif /* __ASM_CSKY_PGTABLE_H */
diff --git a/arch/csky/include/asm/shmparam.h b/arch/csky/include/asm/shmparam.h
new file mode 100644
index 0000000..ecf7b65
--- /dev/null
+++ b/arch/csky/include/asm/shmparam.h
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_SHMPARAM_H
+#define __ASM_CSKY_SHMPARAM_H
+
+#define SHMLBA	(4 * PAGE_SIZE)
+
+#define __ARCH_FORCE_SHMLBA
+
+#endif /* __ASM_CSKY_SHMPARAM_H */
diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c
new file mode 100644
index 0000000..bd97a03
--- /dev/null
+++ b/arch/csky/mm/dma-mapping.c
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/io.h>
+#include <linux/cache.h>
+#include <asm/cache.h>
+
+static void *csky_dma_alloc(
+	struct device *dev,
+	size_t size,
+	dma_addr_t *dma_handle,
+	gfp_t gfp,
+	unsigned long attrs
+	)
+{
+	unsigned long ret;
+	void * vaddr;
+
+	if (DMA_ATTR_NON_CONSISTENT & attrs)
+		panic("csky %s panic DMA_ATTR_NON_CONSISTENT.\n", __func__);
+
+	ret =  __get_free_pages((gfp | __GFP_NORETRY) & (~__GFP_HIGHMEM), get_order(size));
+	if (!ret) {
+		pr_err("csky %s no more free pages, %ld.\n", __func__, ret);
+		return NULL;
+	}
+
+	memset((void *)ret, 0, size);
+
+	dma_wbinv_range(ret, ret + size);
+
+	*dma_handle = virt_to_phys((void*)ret);
+
+	vaddr = (void *) UNCACHE_ADDR(ret);
+
+	return vaddr;
+}
+
+static void csky_dma_free(
+	struct device *dev,
+	size_t size,
+	void *vaddr,
+	dma_addr_t dma_handle,
+	unsigned long attrs
+	)
+{
+	unsigned long addr = (unsigned long)phys_to_virt(dma_handle);
+
+	free_pages(addr, get_order(size));
+}
+
+static inline void __dma_sync(
+	unsigned long addr,
+	size_t size,
+	enum dma_data_direction direction)
+{
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		dma_wb_range(addr, addr+size);
+		break;
+	case DMA_FROM_DEVICE:
+	case DMA_BIDIRECTIONAL:
+		dma_wbinv_range(addr, addr+size);
+		break;
+	default:
+		BUG();
+	}
+}
+
+static int csky_dma_map_sg(
+	struct device *dev,
+	struct scatterlist *sg,
+	int nents,
+	enum dma_data_direction direction,
+	unsigned long attrs
+	)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nents; i++, sg++) {
+		unsigned long addr;
+
+		addr = (unsigned long) sg_virt(sg);
+		if (addr)
+			__dma_sync(addr, sg->length, direction);
+		sg->dma_address = virt_to_phys((void *)addr);
+	}
+
+	return nents;
+}
+
+void csky_dma_unmap_sg(
+	struct device *dev,
+	struct scatterlist *sg,
+	int nhwentries,
+	enum dma_data_direction direction,
+	unsigned long attrs
+	)
+{
+	unsigned long addr;
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	for (i = 0; i < nhwentries; i++, sg++) {
+		if (direction != DMA_TO_DEVICE) {
+			addr = (unsigned long) sg_virt(sg);
+			if (addr)
+				__dma_sync(addr, sg->length, direction);
+		}
+	}
+}
+
+static dma_addr_t csky_dma_map_page(
+	struct device *dev,
+	struct page *page,
+	unsigned long offset,
+	size_t size,
+	enum dma_data_direction direction,
+	unsigned long attrs
+	)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long) page_address(page) + offset;
+
+	__dma_sync(addr, size, direction);
+
+	return page_to_phys(page) + offset;
+}
+
+static void csky_dma_unmap_page(
+	struct device *dev,
+	dma_addr_t dma_handle,
+	size_t size,
+	enum dma_data_direction direction,
+	unsigned long attrs
+	)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long)phys_to_virt((unsigned long)dma_handle);
+	__dma_sync(addr, size, direction);
+}
+
+static void csky_dma_sync_single_for_cpu(
+	struct device *dev,
+	dma_addr_t dma_handle,
+	size_t size,
+	enum dma_data_direction direction
+	)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long)phys_to_virt((unsigned long)dma_handle);
+	__dma_sync(addr, size, direction);
+}
+
+static void csky_dma_sync_single_for_device(
+	struct device *dev,
+	dma_addr_t dma_handle,
+	size_t size,
+	enum dma_data_direction direction
+	)
+{
+	unsigned long addr;
+
+	BUG_ON(direction == DMA_NONE);
+
+	addr = (unsigned long)phys_to_virt((unsigned long)dma_handle);
+	__dma_sync(addr, size, direction);
+}
+
+static void csky_dma_sync_sg_for_cpu(
+	struct device *dev,
+	struct scatterlist *sg,
+	int nelems,
+	enum dma_data_direction direction
+	)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++) {
+		__dma_sync((unsigned long)page_address(sg_page(sg)),
+				sg->length, direction);
+	}
+}
+
+static void csky_dma_sync_sg_for_device(
+	struct device *dev,
+	struct scatterlist *sg,
+	int nelems,
+	enum dma_data_direction direction
+	)
+{
+	int i;
+
+	BUG_ON(direction == DMA_NONE);
+
+	/* Make sure that gcc doesn't leave the empty loop body.  */
+	for (i = 0; i < nelems; i++, sg++) {
+		__dma_sync((unsigned long)page_address(sg_page(sg)),
+				sg->length, direction);
+	}
+}
+
+int csky_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return 0;
+}
+
+int csky_dma_supported(struct device *dev, u64 mask)
+{
+	return 1;
+}
+
+struct dma_map_ops csky_dma_map_ops = {
+	.alloc			= csky_dma_alloc,
+	.free			= csky_dma_free,
+	.mmap			= NULL,
+	.get_sgtable		= NULL,
+	.map_page		= csky_dma_map_page,
+	.unmap_page		= csky_dma_unmap_page,
+
+	.map_sg			= csky_dma_map_sg,
+	.unmap_sg		= csky_dma_unmap_sg,
+	.sync_single_for_cpu	= csky_dma_sync_single_for_cpu,
+	.sync_single_for_device	= csky_dma_sync_single_for_device,
+	.sync_sg_for_cpu	= csky_dma_sync_sg_for_cpu,
+	.sync_sg_for_device	= csky_dma_sync_sg_for_device,
+
+	.mapping_error		= csky_dma_mapping_error,
+	.dma_supported		= csky_dma_supported,
+};
+EXPORT_SYMBOL(csky_dma_map_ops);
+
diff --git a/arch/csky/mm/highmem.c b/arch/csky/mm/highmem.c
new file mode 100644
index 0000000..a979b2d
--- /dev/null
+++ b/arch/csky/mm/highmem.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/module.h>
+#include <linux/highmem.h>
+#include <linux/smp.h>
+#include <linux/bootmem.h>
+#include <asm/fixmap.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
+
+static pte_t *kmap_pte;
+
+unsigned long highstart_pfn, highend_pfn;
+
+void *kmap(struct page *page)
+{
+	void *addr;
+
+	might_sleep();
+	if (!PageHighMem(page))
+		return page_address(page);
+	addr = kmap_high(page);
+        flush_tlb_one((unsigned long)addr);
+
+	return addr;
+}
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+	BUG_ON(in_interrupt());
+	if (!PageHighMem(page))
+		return;
+	kunmap_high(page);
+}
+EXPORT_SYMBOL(kunmap);
+
+/*
+ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because
+ * no global lock is needed and because the kmap code must perform a global TLB
+ * invalidation when the kmap pool wraps.
+ *
+ * However when holding an atomic kmap is is not legal to sleep, so atomic
+ * kmaps are appropriate for short, tight code paths only.
+ */
+
+void *kmap_atomic(struct page *page)
+{
+	unsigned long vaddr;
+	int idx, type;
+
+	/* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+	pagefault_disable();
+	if (!PageHighMem(page))
+		return page_address(page);
+
+	type = kmap_atomic_idx_push();
+	idx = type + KM_TYPE_NR*smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+#ifdef CONFIG_DEBUG_HIGHMEM
+	BUG_ON(!pte_none(*(kmap_pte - idx)));
+#endif
+	set_pte(kmap_pte-idx, mk_pte(page, PAGE_KERNEL));
+	flush_tlb_one((unsigned long)vaddr);
+
+	return (void*) vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic);
+
+void __kunmap_atomic(void *kvaddr)
+{
+	unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+	int type;
+	
+	if (vaddr < FIXADDR_START) {
+	    pagefault_enable();
+	    return;
+	}
+	
+	type = kmap_atomic_idx();
+#ifdef CONFIG_DEBUG_HIGHMEM
+	int idx = type + KM_TYPE_NR * smp_processor_id();
+
+	BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx));
+
+	/*
+	 * force other mappings to Oops if they'll try to access
+	 * this pte without first remap it
+	 */
+	pte_clear(&init_mm, vaddr, kmap_pte-idx);
+	flush_tlb_one(vaddr);
+#endif
+
+	kmap_atomic_idx_pop();
+	pagefault_enable();
+}
+EXPORT_SYMBOL(__kunmap_atomic);
+
+/*
+ * This is the same as kmap_atomic() but can map memory that doesn't
+ * have a struct page associated with it.
+ */
+void *kmap_atomic_pfn(unsigned long pfn)
+{
+	unsigned long vaddr;
+	int idx, type;
+
+	pagefault_disable();
+
+	type = kmap_atomic_idx_push();
+	idx = type + KM_TYPE_NR*smp_processor_id();
+	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+	set_pte(kmap_pte-idx, pfn_pte(pfn, PAGE_KERNEL));
+	flush_tlb_one(vaddr);
+
+	return (void*) vaddr;
+}
+
+struct page *kmap_atomic_to_page(void *ptr)
+{
+	unsigned long idx, vaddr = (unsigned long)ptr;
+	pte_t *pte;
+
+	if (vaddr < FIXADDR_START)
+		return virt_to_page(ptr);
+
+	idx = virt_to_fix(vaddr);
+	pte = kmap_pte - (idx - FIX_KMAP_BEGIN);
+	return pte_page(*pte);
+}
+
+static void __init fixrange_init (unsigned long start, unsigned long end,
+                   pgd_t *pgd_base)
+{
+#ifdef CONFIG_HIGHMEM
+	pgd_t *pgd;
+	pud_t *pud;
+	pmd_t *pmd;
+	pte_t *pte;
+	int i, j, k;
+	unsigned long vaddr;
+
+	vaddr = start;
+	i = __pgd_offset(vaddr);
+	j = __pud_offset(vaddr);
+	k = __pmd_offset(vaddr);
+	pgd = pgd_base + i;
+
+	for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
+		pud = (pud_t *)pgd;
+		for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
+			pmd = (pmd_t *)pud;
+			for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
+				if (pmd_none(*pmd)) {
+					pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+					set_pmd(pmd, __pmd(__pa(pte)));
+					BUG_ON(pte != pte_offset_kernel(pmd, 0));
+				}
+				vaddr += PMD_SIZE;
+			}
+			k = 0;
+		}
+		j = 0;
+	}
+#endif
+}
+
+void __init fixaddr_kmap_pages_init(void)
+{
+	unsigned long vaddr;
+	pgd_t *pgd_base;
+#ifdef CONFIG_HIGHMEM
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pud_t *pud;
+	pte_t *pte;
+#endif
+	pgd_base = swapper_pg_dir;
+
+	/*
+	 * Fixed mappings:
+	 */
+	vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+	fixrange_init(vaddr, 0, pgd_base);
+
+#ifdef CONFIG_HIGHMEM
+	/*
+	 * Permanent kmaps:
+	 */
+	vaddr = PKMAP_BASE;
+	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+	pgd = swapper_pg_dir + __pgd_offset(vaddr);
+	pud = (pud_t *)pgd;
+	pmd = pmd_offset(pud, vaddr);
+	pte = pte_offset_kernel(pmd, vaddr);
+	pkmap_page_table = pte;
+#endif
+}
+
+void __init kmap_init(void)
+{
+	unsigned long kmap_vstart;
+
+	fixaddr_kmap_pages_init();
+
+	/* cache the first kmap pte */
+	kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
+	kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
+}
diff --git a/arch/csky/mm/init.c b/arch/csky/mm/init.c
new file mode 100644
index 0000000..884b068
--- /dev/null
+++ b/arch/csky/mm/init.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/bug.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/pagemap.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/highmem.h>
+#include <linux/memblock.h>
+#include <linux/swap.h>
+#include <linux/proc_fs.h>
+#include <linux/pfn.h>
+
+#include <asm/setup.h>
+#include <asm/cachectl.h>
+#include <asm/dma.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <asm/sections.h>
+#include <asm/tlb.h>
+
+pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
+pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
+unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] __page_aligned_bss;
+
+void __init mem_init(void)
+{
+#ifdef CONFIG_HIGHMEM
+	unsigned long tmp;
+	max_mapnr = highend_pfn;
+#else
+	max_mapnr = max_low_pfn;
+#endif
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
+
+	free_all_bootmem();
+
+#ifdef CONFIG_HIGHMEM
+	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
+		struct page *page = pfn_to_page(tmp);
+
+		/* FIXME not sure about */
+		if (!memblock_is_reserved(tmp << PAGE_SHIFT))
+			free_highmem_page(page);
+	}
+#endif
+	mem_init_print_info(NULL);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	if (start < end)
+		printk(KERN_INFO "Freeing initrd memory: %ldk freed\n",
+                     (end - start) >> 10);
+
+	for (; start < end; start += PAGE_SIZE) {
+	ClearPageReserved(virt_to_page(start));
+	init_page_count(virt_to_page(start));
+	free_page(start);
+	totalram_pages++;
+    }
+}
+#endif
+
+extern char __init_begin[], __init_end[];
+extern void __init prom_free_prom_memory(void);
+
+void free_initmem(void)
+{
+	unsigned long addr;
+
+	addr = (unsigned long) &__init_begin;
+	while (addr < (unsigned long) &__init_end) {
+	        ClearPageReserved(virt_to_page(addr));
+	        init_page_count(virt_to_page(addr));
+	        free_page(addr);
+	        totalram_pages++;
+	        addr += PAGE_SIZE;
+	}
+	printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n",
+	        ((unsigned int)&__init_end - (unsigned int)&__init_begin) >> 10);
+}
+
+void pgd_init(unsigned long *p)
+{
+	int i;
+	for (i = 0; i<PTRS_PER_PGD; i++)
+		p[i] = __pa(invalid_pte_table);
+}
+
diff --git a/arch/csky/mm/ioremap.c b/arch/csky/mm/ioremap.c
new file mode 100644
index 0000000..000d3ce
--- /dev/null
+++ b/arch/csky/mm/ioremap.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/io.h>
+
+#include <asm/pgtable.h>
+
+void __iomem *ioremap(phys_addr_t addr, size_t size)
+{
+	phys_addr_t last_addr;
+	unsigned long offset, vaddr;
+	struct vm_struct *area;
+	pgprot_t prot;
+
+	last_addr = addr + size - 1;
+	if (!size || last_addr < addr) {
+		return NULL;
+	}
+
+	offset = addr & (~PAGE_MASK);
+	addr &= PAGE_MASK;
+	size = PAGE_ALIGN(size + offset);
+
+	area = get_vm_area_caller(size, VM_ALLOC, __builtin_return_address(0));
+	if (!area) {
+		return NULL;
+	}
+	vaddr = (unsigned long)area->addr;
+
+	prot = __pgprot(_PAGE_PRESENT | __READABLE | __WRITEABLE |
+			_PAGE_GLOBAL | _CACHE_UNCACHED);
+
+	if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
+		free_vm_area(area);
+		return NULL;
+	}
+
+	return (void __iomem *)(vaddr + offset);
+}
+EXPORT_SYMBOL(ioremap);
+
+void iounmap(void __iomem *addr)
+{
+	vunmap((void *)((unsigned long)addr & PAGE_MASK));
+}
+EXPORT_SYMBOL(iounmap);
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 05/19] csky: Process management
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (3 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 04/19] csky: MMU and page talbe management Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 06/19] csky: IRQ handling Guo Ren
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/include/asm/mmu_context.h | 140 ++++++++++++++++++++++++++++++++++
 arch/csky/include/asm/processor.h   | 140 ++++++++++++++++++++++++++++++++++
 arch/csky/include/asm/thread_info.h |  77 +++++++++++++++++++
 arch/csky/kernel/process.c          | 147 ++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/time.c             |  15 ++++
 5 files changed, 519 insertions(+)
 create mode 100644 arch/csky/include/asm/mmu_context.h
 create mode 100644 arch/csky/include/asm/processor.h
 create mode 100644 arch/csky/include/asm/thread_info.h
 create mode 100644 arch/csky/kernel/process.c
 create mode 100644 arch/csky/kernel/time.c

diff --git a/arch/csky/include/asm/mmu_context.h b/arch/csky/include/asm/mmu_context.h
new file mode 100644
index 0000000..6eeea85
--- /dev/null
+++ b/arch/csky/include/asm/mmu_context.h
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_MMU_CONTEXT_H
+#define __ASM_CSKY_MMU_CONTEXT_H
+
+#include <asm-generic/mm_hooks.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <abi/ckmmu.h>
+
+/*
+ * For the fast tlb miss handlers, we currently keep a per cpu array
+ * of pointers to the current pgd for each processor. Also, the proc.
+ * id is stuffed into the context register. This should be changed to
+ * use the processor id via current->processor, where current is stored
+ * in watch hi/lo. The context register should be used to contiguously
+ * map the page tables.
+ */
+#define TLBMISS_HANDLER_SETUP_PGD(pgd) tlbmiss_handler_setup_pgd((unsigned long)pgd)
+
+#define cpu_context(cpu, mm)	((mm)->context.asid[cpu])
+#define cpu_asid(cpu, mm)	(cpu_context((cpu), (mm)) & ASID_MASK)
+#define asid_cache(cpu)		(cpu_data[cpu].asid_cache)
+
+#define ASID_INC		0x1
+#define ASID_MASK		0xff
+#define ASID_VERSION_MASK	0xffffff00
+#define ASID_FIRST_VERSION	0x100
+
+#define destroy_context(mm)		do{}while(0)
+#define enter_lazy_tlb(mm,tsk)		do{}while(0)
+#define deactivate_mm(tsk,mm)		do{}while(0)
+
+/*
+ *  All unused by hardware upper bits will be considered
+ *  as a software asid extension.
+ */
+static inline void
+get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
+{
+	unsigned long asid = asid_cache(cpu);
+
+	if (! ((asid += ASID_INC) & ASID_MASK) ) {
+		flush_tlb_all();	/* start new asid cycle */
+		if (!asid)		/* fix version if needed */
+			asid = ASID_FIRST_VERSION;
+	}
+	cpu_context(cpu, mm) = asid_cache(cpu) = asid;
+}
+
+/*
+ * Initialize the context related info for a new mm_struct
+ * instance.
+ */
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+	int i;
+
+	for_each_online_cpu(i)
+		cpu_context(i, mm) = 0;
+	return 0;
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+                             struct task_struct *tsk)
+{
+	unsigned int cpu = smp_processor_id();
+	unsigned long flags;
+
+	local_irq_save(flags);
+	/* Check if our ASID is of an older version and thus invalid */
+	if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK)
+		get_new_mmu_context(next, cpu);
+	write_mmu_entryhi(cpu_context(cpu, next));
+	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+
+	/*
+	 * Mark current->active_mm as not "active" anymore.
+	 * We don't want to mislead possible IPI tlb flush routines.
+	 */
+	cpumask_clear_cpu(cpu, mm_cpumask(prev));
+	cpumask_set_cpu(cpu, mm_cpumask(next));
+
+	local_irq_restore(flags);
+}
+
+/*
+ * After we have set current->mm to a new value, this activates
+ * the context for the new mm so we see the new mappings.
+ */
+static inline void
+activate_mm(struct mm_struct *prev, struct mm_struct *next)
+{
+	unsigned long flags;
+	int cpu = smp_processor_id();
+
+	local_irq_save(flags);
+
+	/* Unconditionally get a new ASID.  */
+	get_new_mmu_context(next, cpu);
+
+	write_mmu_entryhi(cpu_context(cpu, next));
+	TLBMISS_HANDLER_SETUP_PGD(next->pgd);
+
+	/* mark mmu ownership change */
+	cpumask_clear_cpu(cpu, mm_cpumask(prev));
+	cpumask_set_cpu(cpu, mm_cpumask(next));
+
+	local_irq_restore(flags);
+}
+
+/*
+ * If mm is currently active_mm, we can't really drop it. Instead,
+ * we will get a new one for it.
+ */
+static inline void
+drop_mmu_context(struct mm_struct *mm, unsigned cpu)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	if (cpumask_test_cpu(cpu, mm_cpumask(mm)))  {
+		get_new_mmu_context(mm, cpu);
+		write_mmu_entryhi(cpu_asid(cpu, mm));
+	} else {
+		/* will get a new context next time */
+		cpu_context(cpu, mm) = 0;
+	}
+
+	local_irq_restore(flags);
+}
+
+#endif /* __ASM_CSKY_MMU_CONTEXT_H */
diff --git a/arch/csky/include/asm/processor.h b/arch/csky/include/asm/processor.h
new file mode 100644
index 0000000..adebea7
--- /dev/null
+++ b/arch/csky/include/asm/processor.h
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_PROCESSOR_H
+#define __ASM_CSKY_PROCESSOR_H
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l;})
+
+#include <linux/bitops.h>
+#include <asm/segment.h>
+#include <asm/ptrace.h>
+#include <asm/current.h>
+#include <asm/cache.h>
+#include <abi/regdef.h>
+#include <abi/reg_ops.h>
+#ifdef CONFIG_CPU_HAS_FPU
+#include <abi/fpu.h>
+#endif
+
+struct cpuinfo_csky {
+	unsigned long udelay_val;
+	unsigned long asid_cache;
+	/*
+	 * Capability and feature descriptor structure for CSKY CPU
+	 */
+	unsigned long options;
+	unsigned int processor_id[4];
+	unsigned int fpu_id;
+} __attribute__((aligned(SMP_CACHE_BYTES)));
+
+extern struct cpuinfo_csky cpu_data[];
+
+/*
+ * User space process size: 2GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.  TASK_SIZE
+ * for a 64 bit kernel expandable to 8192EB, of which the current CSKY
+ * implementations will "only" be able to use 1TB ...
+ */
+#define TASK_SIZE       0x7fff8000UL
+
+#ifdef __KERNEL__
+#define STACK_TOP       TASK_SIZE
+#define STACK_TOP_MAX   STACK_TOP
+#endif
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE      (TASK_SIZE / 3)
+
+struct thread_struct {
+	unsigned long  ksp;       /* kernel stack pointer */
+	unsigned long  usp;       /* user stack pointer */
+	unsigned long  sr;        /* saved status register */
+	unsigned long  esp0;      /* points to SR of stack frame */
+	/* FPU regs */
+	unsigned long  fcr;       /* fpu control reg */
+	unsigned long  fsr;       /* fpu status reg, nothing in CPU_CSKYV2 */
+	unsigned long  fesr;      /* fpu exception status reg */
+	unsigned long  fp[32];    /* fpu general regs.
+ 				      In CPU_CSKYV1(FPU): 32 regs of 32 bits
+ 				        fp[0] store fr0,
+				        fp[1] store fr1...
+ 				      In CPU_CSKYV2(VFP): 16 regs of 64 bits
+				        fp[0] store vr0 low 32 bits,
+				        fp[1] store vr0 high 32 bits... */
+
+	unsigned long  hi;
+	unsigned long  lo;
+	unsigned long  dspcsr;
+
+	/* Other stuff associated with the thread. */
+	unsigned long address;      /* Last user fault */
+	unsigned long error_code;
+	unsigned long trap_no;
+};
+
+#define INIT_THREAD  { \
+	.ksp = (unsigned long) init_thread_union.stack + THREAD_SIZE, \
+	.sr = DEFAULT_PSR_VALUE, \
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ *
+ * pass the data segment into user programs if it exists,
+ * it can't hurt anything as far as I can tell
+ */
+#define start_thread(_regs, _pc, _usp)					\
+do {									\
+	set_fs(USER_DS); /* reads from user space */			\
+	(_regs)->pc = (_pc);						\
+	(_regs)->regs[1] = 0; /* ABIV1 is R7, uClibc_main rtdl arg */	\
+	(_regs)->regs[2] = 0;						\
+	(_regs)->regs[3] = 0; /* ABIV2 is R7, use it? */		\
+	(_regs)->sr &= ~PS_S;						\
+	wrusp(_usp);							\
+} while(0)
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk)    do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define copy_segments(tsk, mm)		do { } while (0)
+#define release_segments(mm)		do { } while (0)
+#define forget_segments()		do { } while (0)
+
+extern unsigned long thread_saved_pc(struct task_struct *tsk);
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define	KSTK_EIP(tsk)							\
+({									\
+	unsigned long eip = 0;						\
+	if ((tsk)->thread.esp0 > PAGE_SIZE &&				\
+	     MAP_NR((tsk)->thread.esp0) < max_mapnr)			\
+		eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc;	\
+		eip;							\
+})
+
+#define	KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->thread.usp)
+
+#define task_pt_regs(p) \
+	((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
+
+#define cpu_relax() barrier()
+
+#endif /* __ASM_CSKY_PROCESSOR_H */
diff --git a/arch/csky/include/asm/thread_info.h b/arch/csky/include/asm/thread_info.h
new file mode 100644
index 0000000..af05d37
--- /dev/null
+++ b/arch/csky/include/asm/thread_info.h
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef _ASM_CSKY_THREAD_INFO_H
+#define _ASM_CSKY_THREAD_INFO_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+#include <asm/page.h>
+#include <abi/regdef.h>
+#include <asm/processor.h>
+
+struct thread_info {
+	struct task_struct	*task;
+	void			*dump_exec_domain;
+	unsigned long		flags;
+	int			preempt_count;
+	unsigned long		tp_value;
+	mm_segment_t		addr_limit;
+	struct restart_block	restart_block;
+	struct pt_regs		*regs;
+};
+
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	.task		= &tsk,			\
+	.preempt_count  = INIT_PREEMPT_COUNT,	\
+	.addr_limit     = KERNEL_DS,		\
+	.restart_block = {			\
+		.fn = do_no_restart_syscall,	\
+	},					\
+}
+
+#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT)
+
+#ifdef COMPAT_KERNEL_4_9
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+#endif
+
+static inline struct thread_info *current_thread_info(void)
+{
+	unsigned long sp;
+
+	asm volatile("mov %0, sp\n":"=r"(sp));
+
+	return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
+}
+
+#endif /* !__ASSEMBLY__ */
+
+/* entry.S relies on these definitions!
+ * bits 0-5 are tested at every exception exit
+ */
+#define TIF_SIGPENDING		0	/* signal pending */
+#define TIF_NOTIFY_RESUME	1       /* callback before returning to user */
+#define TIF_NEED_RESCHED	2	/* rescheduling necessary */
+#define TIF_SYSCALL_TRACE	5	/* syscall trace active */
+#define TIF_DELAYED_TRACE	14	/* single step a syscall */
+#define TIF_POLLING_NRFLAG	16	/* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE		18      /* is terminating due to OOM killer */
+#define TIF_FREEZE		19	/* thread is freezing for suspend */
+#define TIF_RESTORE_SIGMASK	20	/* restore signal mask in do_signal() */
+#define TIF_SECCOMP		21	/* secure computing */
+
+#define _TIF_SIGPENDING         (1 << TIF_SIGPENDING)
+#define _TIF_NOTIFY_RESUME      (1 << TIF_NOTIFY_RESUME)
+#define _TIF_NEED_RESCHED       (1 << TIF_NEED_RESCHED)
+#define _TIF_SYSCALL_TRACE      (1 << TIF_SYSCALL_TRACE)
+#define _TIF_DELAYED_TRACE	(1 << TIF_DELAYED_TRACE)
+#define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
+#define _TIF_MEMDIE		(1 << TIF_MEMDIE)
+#define _TIF_FREEZE             (1 << TIF_FREEZE)
+#define _TIF_RESTORE_SIGMASK    (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_SECCOMP            (1 << TIF_SECCOMP)
+
+#endif	/* _ASM_CSKY_THREAD_INFO_H */
diff --git a/arch/csky/kernel/process.c b/arch/csky/kernel/process.c
new file mode 100644
index 0000000..a7464a4
--- /dev/null
+++ b/arch/csky/kernel/process.c
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#ifndef COMPAT_KERNEL_4_9
+#include <linux/sched/task_stack.h>
+#include <linux/sched/debug.h>
+#endif
+#include <linux/delay.h>
+#include <linux/kallsyms.h>
+#include <linux/uaccess.h>
+#include <asm/elf.h>
+#include <linux/ptrace.h>
+
+struct cpuinfo_csky cpu_data[NR_CPUS];
+
+asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
+
+/*
+ * Some archs flush debug and FPU info here
+ */
+void flush_thread(void){}
+
+/*
+ * Return saved PC from a blocked thread
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
+
+	return sw->r15;
+}
+
+int copy_thread(unsigned long clone_flags,
+		unsigned long usp,
+		unsigned long kthread_arg,
+		struct task_struct *p)
+{
+	struct switch_stack * childstack;
+	unsigned long reg_psr = 0;
+	struct pt_regs *childregs = task_pt_regs(p);
+
+	preempt_disable();
+
+	asm volatile("mfcr %0, psr\n":"=r"(reg_psr));
+
+#ifdef CONFIG_CPU_HAS_FPU
+	save_fp_to_thread(p->thread.fp, &p->thread.fcr, &p->thread.fsr,
+	     &p->thread.fesr);
+#endif
+#ifdef CONFIG_CPU_HAS_HILO
+	asm volatile(
+		"mfhi	%0 \n"
+		"mflo	%1 \n"
+		:"=r"(p->thread.hi),"=r"(p->thread.lo));
+#endif
+	preempt_enable();
+
+	childstack = ((struct switch_stack *) childregs) - 1;
+	memset(childstack, 0, sizeof(struct switch_stack));
+
+	/* setup ksp for switch_to !!! */
+	p->thread.ksp = (unsigned long)childstack;
+
+	if (unlikely(p->flags & PF_KTHREAD)) {
+		memset(childregs, 0, sizeof(struct pt_regs));
+		childstack->r15 = (unsigned long) ret_from_kernel_thread;
+		childstack->r8 = kthread_arg;
+		childstack->r9 = usp;
+		childregs->sr = reg_psr;
+
+		return 0;
+	} else {
+		*childregs = *(current_pt_regs());
+		childstack->r15 = (unsigned long) ret_from_fork;
+	}
+
+	/* Return 0 for subprocess when return from fork(),vfork(),clone() */
+	childregs->a0 = 0;
+
+	if (usp != 0)
+		p->thread.usp = usp;
+	else
+		p->thread.usp = rdusp();
+
+	if (clone_flags & CLONE_SETTLS) {
+		task_thread_info(p)->tp_value = (current_pt_regs())->regs[0];
+#ifdef __CSKYABIV2__
+		childregs->exregs[15] = task_thread_info(p)->tp_value;
+#endif
+	}
+
+	return 0;
+}
+
+/* Fill in the fpu structure for a core dump.  */
+int dump_fpu (struct pt_regs *regs, struct user_cskyfp_struct *fpu)
+{
+	memcpy(fpu, &current->thread.fcr, sizeof(*fpu));
+	return 1;
+}
+EXPORT_SYMBOL(dump_fpu);
+
+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *pr_regs)
+{
+	struct pt_regs *regs = (struct pt_regs *)(tsk->thread.esp0);
+
+	/* NOTE: usp is error value. */
+	ELF_CORE_COPY_REGS ((*pr_regs), regs)
+
+	/* Now fix usp in pr_regs, usp is in pr_regs[2] */
+#if defined(__CSKYABIV2__)
+	(*pr_regs)[16] = tsk->thread.usp;
+#else
+	(*pr_regs)[2] = tsk->thread.usp;
+#endif
+
+	return 1;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+	unsigned long esp, pc;
+	unsigned long stack_page;
+	int count = 0;
+	if (!p || p == current || p->state == TASK_RUNNING)
+		return 0;
+
+	stack_page = (unsigned long)p;
+	esp = p->thread.esp0;
+	do {
+		if (esp < stack_page+sizeof(struct task_struct) ||
+		    esp >= 8184+stack_page)
+			return 0;
+		/*FIXME: There's may be error here!*/
+		pc = ((unsigned long *)esp)[1];
+		/* FIXME: This depends on the order of these functions. */
+		if (!in_sched_functions(pc))
+			return pc;
+		esp = *(unsigned long *) esp;
+	} while (count++ < 16);
+	return 0;
+}
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/csky/kernel/time.c b/arch/csky/kernel/time.c
new file mode 100644
index 0000000..4d9bc05
--- /dev/null
+++ b/arch/csky/kernel/time.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+
+void __init time_init(void)
+{
+	of_clk_init(NULL);
+#ifdef COMPAT_KERNEL_4_9
+	clocksource_probe();
+#else
+	timer_probe();
+#endif
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 06/19] csky: IRQ handling
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (4 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 05/19] csky: Process management Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-19 13:16   ` Thomas Gleixner
  2018-03-18 19:51 ` [PATCH 07/19] csky: Atomic operations Guo Ren
                   ` (14 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/include/asm/irq.h      | 12 +++++++++
 arch/csky/include/asm/irqflags.h | 55 ++++++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/irq.c           | 41 ++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+)
 create mode 100644 arch/csky/include/asm/irq.h
 create mode 100644 arch/csky/include/asm/irqflags.h
 create mode 100644 arch/csky/kernel/irq.c

diff --git a/arch/csky/include/asm/irq.h b/arch/csky/include/asm/irq.h
new file mode 100644
index 0000000..f68e868
--- /dev/null
+++ b/arch/csky/include/asm/irq.h
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_IRQ_H
+#define __ASM_CSKY_IRQ_H
+
+#define NR_IRQS CONFIG_CSKY_NR_IRQS
+
+#include <asm-generic/irq.h>
+
+extern unsigned int (*csky_get_auto_irqno) (void);
+
+#endif /* __ASM_CSKY_IRQ_H */
diff --git a/arch/csky/include/asm/irqflags.h b/arch/csky/include/asm/irqflags.h
new file mode 100644
index 0000000..ac8035a
--- /dev/null
+++ b/arch/csky/include/asm/irqflags.h
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_IRQFLAGS_H
+#define __ASM_CSKY_IRQFLAGS_H
+
+static inline unsigned long arch_local_irq_save(void)
+{
+	unsigned long flags;
+	asm volatile(
+		"mfcr	%0, psr	\n"
+		"psrclr	ie	\n"
+		:"=r"(flags));
+	return flags;
+}
+#define arch_local_irq_save arch_local_irq_save
+
+static inline void arch_local_irq_enable(void)
+{
+	asm volatile("psrset ee, ie\n");
+}
+#define arch_local_irq_enable arch_local_irq_enable
+
+static inline void arch_local_irq_disable(void)
+{
+	asm volatile("psrclr ie\n");
+}
+#define arch_local_irq_disable arch_local_irq_disable
+
+static inline unsigned long arch_local_save_flags(void)
+{
+	unsigned long flags;
+	asm volatile("mfcr %0, psr\n":"=r"(flags));
+	return flags;
+}
+#define arch_local_save_flags arch_local_save_flags
+
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+	asm volatile(
+		"mtcr 	%0, psr \n"
+		::"r" (flags)
+		:"memory"
+		);
+}
+#define arch_local_irq_restore arch_local_irq_restore
+
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+	return !(flags & (1<<6));
+}
+#define arch_irqs_disabled_flags arch_irqs_disabled_flags
+
+#include <asm-generic/irqflags.h>
+
+#endif /* __ASM_CSKY_IRQFLAGS_H */
diff --git a/arch/csky/kernel/irq.c b/arch/csky/kernel/irq.c
new file mode 100644
index 0000000..0cdb4fe
--- /dev/null
+++ b/arch/csky/kernel/irq.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqchip.h>
+
+unsigned int (*csky_get_auto_irqno) (void) = NULL;
+
+void csky_do_IRQ(int irq, struct pt_regs *regs)
+{
+	struct pt_regs *old_regs = set_irq_regs(regs);
+
+	irq_enter();
+	generic_handle_irq(irq);
+	irq_exit();
+
+	set_irq_regs(old_regs);
+}
+
+asmlinkage void csky_do_auto_IRQ(struct pt_regs *regs)
+{
+	unsigned long irq, psr;
+
+	asm volatile("mfcr %0, psr":"=r"(psr));
+
+	irq = (psr >> 16) & 0xff;
+
+	if (irq == 10)
+		irq = csky_get_auto_irqno();
+	else
+		irq -= 32;
+
+	csky_do_IRQ(irq, regs);
+}
+
+void __init init_IRQ(void)
+{
+	irqchip_init();
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 07/19] csky: Atomic operations
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (5 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 06/19] csky: IRQ handling Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 08/19] csky: ELF and module probe Guo Ren
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/kernel/atomic.S | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 arch/csky/kernel/atomic.S

diff --git a/arch/csky/kernel/atomic.S b/arch/csky/kernel/atomic.S
new file mode 100644
index 0000000..e6e9fd2
--- /dev/null
+++ b/arch/csky/kernel/atomic.S
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/linkage.h>
+#include <abi/entry.h>
+
+.text
+
+/*
+ * int csky_cmpxchg(int oldval, int newval, int *ptr)
+ *
+ * If *ptr != oldval && return 1,
+ * else *ptr = newval return 0.
+ */
+ENTRY(csky_cmpxchg)
+	USPTOKSP
+	mfcr	a3, epc
+	INCTRAP	a3
+
+	subi    sp, 8
+	stw     a3, (sp, 0)
+	mfcr    a3, epsr
+	stw     a3, (sp, 4)
+
+	psrset	ee
+1:
+	ldw	a3, (a2)
+	cmpne	a0, a3
+	bt16	3f
+2:
+	stw	a1, (a2)
+3:
+	mvc	a0
+	ldw	a3, (sp, 0)
+	mtcr	a3, epc
+	ldw     a3, (sp, 4)
+	mtcr	a3, epsr
+	addi	sp, 8
+	KSPTOUSP
+	rte
+END(csky_cmpxchg)
+
+/*
+ * Called from tlbmodified exception
+ */
+ENTRY(csky_cmpxchg_fixup)
+	mfcr	a0, epc
+	lrw	a1, 2b
+	cmpne	a1, a0
+	bt	1f
+	subi	a1, (2b - 1b)
+	stw	a1, (sp, 0)
+1:
+	rts
+END(csky_cmpxchg_fixup)
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 08/19] csky: ELF and module probe
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (6 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 07/19] csky: Atomic operations Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 09/19] csky: VDSO and rt_sigreturn Guo Ren
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/include/asm/elf.h | 151 ++++++++++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/module.c   | 130 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 281 insertions(+)
 create mode 100644 arch/csky/include/asm/elf.h
 create mode 100644 arch/csky/kernel/module.c

diff --git a/arch/csky/include/asm/elf.h b/arch/csky/include/asm/elf.h
new file mode 100644
index 0000000..f63a45d
--- /dev/null
+++ b/arch/csky/include/asm/elf.h
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASMCSKY_ELF_H
+#define __ASMCSKY_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#include <asm/ptrace.h>
+#include <asm/user.h>
+#include <abi/regdef.h>
+
+#define ELF_ARCH 39
+
+/* CSKY Relocations */
+#define R_CSKY_NONE               0
+#define R_CSKY_32                 1
+#define R_CSKY_PCIMM8BY4          2
+#define R_CSKY_PCIMM11BY2         3
+#define R_CSKY_PCIMM4BY2          4
+#define R_CSKY_PC32               5
+#define R_CSKY_PCRELJSR_IMM11BY2  6
+#define R_CSKY_GNU_VTINHERIT      7
+#define R_CSKY_GNU_VTENTRY        8
+#define R_CSKY_RELATIVE           9
+#define R_CSKY_COPY               10
+#define R_CSKY_GLOB_DAT           11
+#define R_CSKY_JUMP_SLOT          12
+#define R_CSKY_ADDR_HI16          24
+#define R_CSKY_ADDR_LO16          25
+#define R_CSKY_PCRELJSR_IMM26BY2  40
+
+typedef unsigned long elf_greg_t;
+
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct user_cskyfp_struct elf_fpregset_t;
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE		4096
+#define ELF_CLASS			ELFCLASS32
+#define ELF_PLAT_INIT(_r, load_addr)	_r->a0 = 0
+
+#ifdef  __cskyBE__
+#define ELF_DATA	ELFDATA2MSB
+#else
+#define ELF_DATA	ELFDATA2LSB
+#endif
+
+/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
+   use of this is to invoke "./ld.so someprog" to test out a new version of
+   the loader.  We need to make sure that it is out of the way of the program
+   that it will "exec", and that there is sufficient room for the brk.  */
+
+#define ELF_ET_DYN_BASE	0x0UL
+
+/* The member sort in array pr_reg[x] is pc, r1, r0, psr, r2, r3,r4,
+   r5, r6...... Because GDB difine */
+#if defined(__CSKYABIV2__)
+   #define ELF_CORE_COPY_REGS(pr_reg, regs)     \
+        pr_reg[0] = regs->pc;                   \
+        pr_reg[1] = regs->a1;                   \
+        pr_reg[2] = regs->a0;                   \
+        pr_reg[3] = regs->sr;                   \
+        pr_reg[4] = regs->a2;                   \
+        pr_reg[5] = regs->a3;                   \
+        pr_reg[6] = regs->regs[0];              \
+        pr_reg[7] = regs->regs[1];              \
+        pr_reg[8] = regs->regs[2];              \
+        pr_reg[9] = regs->regs[3];              \
+        pr_reg[10] = regs->regs[4];             \
+        pr_reg[11] = regs->regs[5];             \
+        pr_reg[12] = regs->regs[6];             \
+        pr_reg[13] = regs->regs[7];             \
+        pr_reg[14] = regs->regs[8];             \
+        pr_reg[15] = regs->regs[9];             \
+        pr_reg[16] = rdusp();		        \
+        pr_reg[17] = regs->r15;                 \
+        pr_reg[18] = regs->exregs[0];           \
+        pr_reg[19] = regs->exregs[1];           \
+        pr_reg[20] = regs->exregs[2];           \
+        pr_reg[21] = regs->exregs[3];           \
+        pr_reg[22] = regs->exregs[4];           \
+        pr_reg[23] = regs->exregs[5];           \
+        pr_reg[24] = regs->exregs[6];           \
+        pr_reg[25] = regs->exregs[7];           \
+        pr_reg[26] = regs->exregs[8];           \
+        pr_reg[27] = regs->exregs[9];           \
+        pr_reg[28] = regs->exregs[10];          \
+        pr_reg[29] = regs->exregs[11];          \
+        pr_reg[30] = regs->exregs[12];          \
+        pr_reg[31] = regs->exregs[13];          \
+        pr_reg[32] = regs->exregs[14];          \
+        pr_reg[33] = regs->exregs[15];
+#else
+     #define ELF_CORE_COPY_REGS(pr_reg, regs)   \
+        pr_reg[0] = regs->pc;                   \
+        pr_reg[1] = regs->regs[9];              \
+        pr_reg[2] = rdusp();                    \
+        pr_reg[3] = regs->sr;                   \
+        pr_reg[4] = regs->a0;                   \
+        pr_reg[5] = regs->a1;                   \
+        pr_reg[6] = regs->a2;                   \
+        pr_reg[7] = regs->a3;                   \
+        pr_reg[8] = regs->regs[0];              \
+        pr_reg[9] = regs->regs[1];              \
+        pr_reg[10] = regs->regs[2];             \
+        pr_reg[11] = regs->regs[3];             \
+        pr_reg[12] = regs->regs[4];             \
+        pr_reg[13] = regs->regs[5];             \
+        pr_reg[14] = regs->regs[6];             \
+        pr_reg[15] = regs->regs[7];             \
+        pr_reg[16] = regs->regs[8];             \
+        pr_reg[17] = regs->r15;
+#endif
+
+/* Similar, but for a thread other than current. */
+struct task_struct;
+extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+
+/* This yields a mask that user programs can use to figure out what
+   instruction set this cpu supports.  */
+
+#define ELF_HWCAP	(0)
+
+/* This yields a string that ld.so will use to load implementation
+   specific libraries for optimization.  This is more specific in
+   intent than poking at uname or /proc/cpuinfo.  */
+
+#define ELF_PLATFORM	(NULL)
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
+struct linux_binprm;
+extern int arch_setup_additional_pages(
+		struct linux_binprm *bprm,
+		int uses_interp);
+
+#endif
diff --git a/arch/csky/kernel/module.c b/arch/csky/kernel/module.c
new file mode 100644
index 0000000..ca68315
--- /dev/null
+++ b/arch/csky/kernel/module.c
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <asm/pgtable.h>
+
+#define IS_BSR32(hi16, lo16)        (((hi16) & 0xFC00) == 0xE000)
+#define IS_JSRI32(hi16, lo16)       ((hi16) == 0xEAE0)
+#define CHANGE_JSRI_TO_LRW(addr)    *(uint16_t *)(addr) = (*(uint16_t *)(addr) & 0xFF9F) | 0x0019; \
+							  *((uint16_t *)(addr) + 1) = *((uint16_t *)(addr) + 1) & 0xFFFF
+#define SET_JSR32_R25(addr)         *(uint16_t *)(addr) = 0xE8F9; \
+							  *((uint16_t *)(addr) + 1) = 0x0000;
+
+int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex,
+		unsigned int relsec, struct module *me)
+{
+	unsigned int i;
+	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+	short * temp;
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_CSKY_NONE:
+		case R_CSKY_PCRELJSR_IMM11BY2:
+		case R_CSKY_PCRELJSR_IMM26BY2:
+			/* ignore */
+			break;
+		case R_CSKY_32:
+			/* We add the value into the location given */
+			*location += sym->st_value;
+			break;
+		case R_CSKY_PC32:
+			/* Add the value, subtract its postition */
+			*location += sym->st_value - (uint32_t)location;
+			break;
+		case R_CSKY_ADDR_HI16:
+			temp = ((short  *)location) + 1;
+			*temp = (short)((sym->st_value) >> 16);
+			break;
+		case R_CSKY_ADDR_LO16:
+			temp = ((short  *)location) + 1;
+			*temp = (short)((sym->st_value) & 0xffff);
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+					me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
+		unsigned int symindex, unsigned int relsec, struct module *me)
+{
+	unsigned int i;
+	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+	short * temp;
+#ifdef CONFIG_CPU_CSKYV2
+	uint16_t *location_tmp;
+#endif
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_CSKY_32:
+			/* We add the value into the location given */
+			*location = rel[i].r_addend + sym->st_value;
+			break;
+		case R_CSKY_PC32:
+			/* Add the value, subtract its postition */
+			*location = rel[i].r_addend + sym->st_value
+				- (uint32_t)location;
+			break;
+		case R_CSKY_PCRELJSR_IMM11BY2:
+			break;
+		case R_CSKY_PCRELJSR_IMM26BY2:
+#ifdef CONFIG_CPU_CSKYV2
+			location_tmp = (uint16_t *)location;
+			if (IS_BSR32(*location_tmp, *(location_tmp + 1)))
+				break;
+			else if (IS_JSRI32(*location_tmp, *(location_tmp + 1))) {
+				/* jsri 0x...  --> lrw r25, 0x... */
+				CHANGE_JSRI_TO_LRW(location);
+				/* lsli r0, r0 --> jsr r25 */
+				SET_JSR32_R25(location + 1);
+			}
+#endif
+			break;
+		case R_CSKY_ADDR_HI16:
+			temp = ((short  *)location) + 1;
+			*temp = (short)((rel[i].r_addend + sym->st_value) >> 16);
+			break;
+		case R_CSKY_ADDR_LO16:
+			temp = ((short  *)location) + 1;
+			*temp = (short)((rel[i].r_addend + sym->st_value) & 0xffff);
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+					me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 09/19] csky: VDSO and rt_sigreturn
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (7 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 08/19] csky: ELF and module probe Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 10/19] csky: Signal handling Guo Ren
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/abiv1/inc/abi/vdso.h | 19 +++++++++
 arch/csky/abiv2/inc/abi/vdso.h | 18 +++++++++
 arch/csky/include/asm/vdso.h   | 12 ++++++
 arch/csky/kernel/vdso.c        | 89 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 138 insertions(+)
 create mode 100644 arch/csky/abiv1/inc/abi/vdso.h
 create mode 100644 arch/csky/abiv2/inc/abi/vdso.h
 create mode 100644 arch/csky/include/asm/vdso.h
 create mode 100644 arch/csky/kernel/vdso.c

diff --git a/arch/csky/abiv1/inc/abi/vdso.h b/arch/csky/abiv1/inc/abi/vdso.h
new file mode 100644
index 0000000..029c4e3
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/vdso.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/uaccess.h>
+
+static inline int setup_vdso_page(unsigned short *ptr)
+{
+	int err;
+
+	/* movi r1, 127 */
+	err |= __put_user(0x6000 + (127 << 4)+1, ptr+0);
+	/* addi r1, 32 */
+	err |= __put_user(0x2000 + ((32-1)  << 4)+1, ptr+1);
+	/* addi r1, 173-127-32 */
+	err |= __put_user(0x2000 + (((173-127-32) -1)<< 4)+1, ptr+2);
+	/* trap 0 */
+	err |= __put_user(0x08, ptr+3);
+
+	return err;
+}
diff --git a/arch/csky/abiv2/inc/abi/vdso.h b/arch/csky/abiv2/inc/abi/vdso.h
new file mode 100644
index 0000000..f9da48a
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/vdso.h
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/uaccess.h>
+
+static inline int setup_vdso_page(unsigned short *ptr)
+{
+	int err;
+
+	/* movi r7, 173 */
+	err |= __put_user(0xEA00+7, ptr);
+	err |= __put_user(173,      ptr+1);
+
+	/* trap 0 */
+	err |= __put_user(0xC000,   ptr+2);
+	err |= __put_user(0x2020,   ptr+3);
+
+	return err;
+}
diff --git a/arch/csky/include/asm/vdso.h b/arch/csky/include/asm/vdso.h
new file mode 100644
index 0000000..b275440
--- /dev/null
+++ b/arch/csky/include/asm/vdso.h
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_VDSO_H
+#define __ASM_CSKY_VDSO_H
+
+#include <abi/vdso.h>
+
+struct csky_vdso {
+	unsigned short rt_signal_retcode[4];
+};
+
+#endif /* __ASM_CSKY_VDSO_H */
diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c
new file mode 100644
index 0000000..dd59aae
--- /dev/null
+++ b/arch/csky/kernel/vdso.c
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/unistd.h>
+#include <linux/uaccess.h>
+
+#include <asm/vdso.h>
+#include <asm/cacheflush.h>
+
+static struct page *vdso_page;
+
+static int __init init_vdso(void)
+{
+	struct csky_vdso *vdso;
+	int err = 0;
+
+	vdso_page = alloc_page(GFP_KERNEL);
+	if (!vdso_page)
+		panic("Cannot allocate vdso");
+
+	vdso = vmap(&vdso_page, 1, 0, PAGE_KERNEL);
+	if (!vdso)
+		panic("Cannot map vdso");
+
+	clear_page(vdso);
+
+	/*
+	 * __NR_rt_sigreturn must be 173
+	 * Because gcc/config/csky/linux-unwind.h use hard code to parse rt_sigframe.
+	 */
+	err = setup_vdso_page(vdso->rt_signal_retcode);
+	if (err) panic("Cannot set signal return code, err: %x.", err);
+
+	dcache_wb_range((unsigned long)vdso, (unsigned long)vdso + 16);
+
+	vunmap(vdso);
+
+	return 0;
+}
+subsys_initcall(init_vdso);
+
+int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+{
+	int ret;
+	unsigned long addr;
+	struct mm_struct *mm = current->mm;
+
+	down_write(&mm->mmap_sem);
+
+	addr = get_unmapped_area(NULL, STACK_TOP, PAGE_SIZE, 0, 0);
+	if (IS_ERR_VALUE(addr)) {
+		ret = addr;
+		goto up_fail;
+	}
+
+	ret = install_special_mapping(
+			mm,
+			addr,
+			PAGE_SIZE,
+			VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
+			&vdso_page);
+	if (ret)
+		goto up_fail;
+
+	mm->context.vdso = (void *)addr;
+
+up_fail:
+	up_write(&mm->mmap_sem);
+	return ret;
+}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+	if (vma->vm_mm == NULL)
+		return NULL;
+
+	if (vma->vm_start == (long)vma->vm_mm->context.vdso)
+		return "[vdso]";
+	else
+		return NULL;
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 10/19] csky: Signal handling
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (8 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 09/19] csky: VDSO and rt_sigreturn Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-26 13:04   ` Arnd Bergmann
  2018-03-18 19:51 ` [PATCH 11/19] csky: Library functions Guo Ren
                   ` (10 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/include/uapi/asm/sigcontext.h |  33 +++
 arch/csky/include/uapi/asm/signal.h     | 164 ++++++++++++++
 arch/csky/kernel/signal.c               | 379 ++++++++++++++++++++++++++++++++
 3 files changed, 576 insertions(+)
 create mode 100644 arch/csky/include/uapi/asm/sigcontext.h
 create mode 100644 arch/csky/include/uapi/asm/signal.h
 create mode 100644 arch/csky/kernel/signal.c

diff --git a/arch/csky/include/uapi/asm/sigcontext.h b/arch/csky/include/uapi/asm/sigcontext.h
new file mode 100644
index 0000000..8ef0ce8
--- /dev/null
+++ b/arch/csky/include/uapi/asm/sigcontext.h
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef _ASM_CSKY_SIGCONTEXT_H
+#define _ASM_CSKY_SIGCONTEXT_H
+
+struct sigcontext {
+	unsigned long   sc_mask;     /* old sigmask */
+        unsigned long   sc_usp;      /* old user stack pointer */
+        unsigned long   sc_a0;
+        unsigned long   sc_a1;
+        unsigned long   sc_a2;
+        unsigned long   sc_a3;
+	// ABIV2: r4 ~ r13; ABIV1: r6 ~ r14, r1.
+        unsigned long   sc_regs[10];
+        unsigned long   sc_r15;
+#if (__CSKY__ == 2)                     /* config CPU=cskyv2(ck800) */
+	// r16 ~ r31;
+        unsigned long   sc_exregs[16];
+        unsigned long   sc_rhi;
+        unsigned long   sc_rlo;
+#endif
+        unsigned long   sc_sr;
+        unsigned long   sc_pc;
+	/* fpu */
+        unsigned long   sc_fcr;
+        unsigned long   sc_fsr;		/* Nothing in CPU_CSKYV2 */
+        unsigned long   sc_fesr;
+        unsigned long   sc_feinst1;	/* Nothing in CPU_CSKYV2 */
+        unsigned long   sc_feinst2;	/* Nothing in CPU_CSKYV2 */
+        unsigned long   sc_fpregs[32];
+};
+
+#endif /* _ASM_CSKY_SIGCONTEXT_H */
diff --git a/arch/csky/include/uapi/asm/signal.h b/arch/csky/include/uapi/asm/signal.h
new file mode 100644
index 0000000..3bc0004
--- /dev/null
+++ b/arch/csky/include/uapi/asm/signal.h
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_SIGNAL_H
+#define __ASM_CSKY_SIGNAL_H
+
+#define __ARCH_HAS_SA_RESTORER
+#include <linux/types.h>
+
+/* Avoid too many header ordering problems.  */
+struct siginfo;
+
+#ifdef __KERNEL__
+
+/* Most things should be clean enough to redefine this at will, if care
+   is taken to make libc match.  */
+
+#define _NSIG		64
+#define _NSIG_BPW	32
+#define _NSIG_WORDS	(_NSIG / _NSIG_BPW)
+
+typedef unsigned long old_sigset_t;		/* at least 32 bits */
+
+typedef struct {
+	unsigned long sig[_NSIG_WORDS];
+} sigset_t;
+
+#else
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+#define NSIG		32
+typedef unsigned long sigset_t;
+
+#endif /* __KERNEL__ */
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define SIGSYS		31
+#define	SIGUNUSED	31
+
+/* These should not be considered constants from userland.  */
+#define SIGRTMIN	32
+#define SIGRTMAX	(_NSIG-1)
+
+/*
+ * SA_FLAGS values:
+ *
+ * SA_ONSTACK indicates that a registered stack_t will be used.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
+ * SA_RESETHAND clears the handler when the signal is delivered.
+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
+ * SA_NODEFER prevents the current signal from being masked in the handler.
+ *
+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
+ * Unix names RESETHAND and NODEFER respectively.
+ */
+#define SA_NOCLDSTOP		0x00000001
+#define SA_NOCLDWAIT		0x00000002 /* not supported yet */
+#define SA_SIGINFO		0x00000004
+#define SA_ONSTACK		0x08000000
+#define SA_RESTART		0x10000000
+#define SA_NODEFER		0x40000000
+#define SA_RESETHAND		0x80000000
+
+#define SA_NOMASK		SA_NODEFER
+#define SA_ONESHOT		SA_RESETHAND
+#define SA_INTERRUPT		0x20000000 /* dummy -- ignored */
+
+/*
+ * sigaltstack controls
+ */
+#define SS_ONSTACK	1
+#define SS_DISABLE	2
+
+#define MINSIGSTKSZ	2048
+#define SIGSTKSZ	8192
+
+#include <asm-generic/signal-defs.h>
+
+#ifdef __KERNEL__
+
+/*
+ * These values of sa_flags are used only by the kernel as part of the
+ * irq handling routines.
+ *
+ * SA_INTERRUPT is also used by the irq handling routines.
+ * SA_SHIRQ is for shared interrupt support on PCI and EISA.
+ */
+#define SA_PROBE			SA_ONESHOT
+#define SA_SAMPLE_RANDOM		SA_RESTART
+#define SA_SHIRQ			0x04000000
+#endif
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+#ifndef __KERNEL__
+
+/* Here we must cater to libcs that poke about in kernel headers.  */
+
+struct sigaction {
+	union {
+	  __sighandler_t _sa_handler;
+	  void (*_sa_sigaction)(int, struct siginfo *, void *);
+	} _u;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#define sa_handler	_u._sa_handler
+#define sa_sigaction	_u._sa_sigaction
+
+#endif /* __KERNEL__ */
+
+typedef struct sigaltstack {
+	void *ss_sp;
+	int ss_flags;
+	size_t ss_size;
+} stack_t;
+
+#ifdef __KERNEL__
+
+#include <asm/sigcontext.h>
+#define ptrace_signal_deliver()		do{}while(0)
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/arch/csky/kernel/signal.c b/arch/csky/kernel/signal.c
new file mode 100644
index 0000000..ce27972
--- /dev/null
+++ b/arch/csky/kernel/signal.c
@@ -0,0 +1,379 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+#include <linux/tty.h>
+#include <linux/binfmts.h>
+#include <linux/tracehook.h>
+#include <linux/freezer.h>
+#include <linux/uaccess.h>
+
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+#include <asm/vdso.h>
+
+#include <abi/regdef.h>
+#ifdef CONFIG_CPU_HAS_FPU
+#include <abi/fpu.h>
+#endif
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+struct rt_sigframe
+{
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+};
+
+static inline int
+restore_sigframe(struct pt_regs *regs, struct sigcontext *usc, int *pr2)
+{
+	int err = 0;
+	int i = 0;
+	unsigned long usp;
+
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->task->restart_block.fn = do_no_restart_syscall;
+
+	/* restore passed registers */
+	err |= __get_user(regs->a0, &usc->sc_a0);
+	err |= __get_user(regs->a1, &usc->sc_a1);
+	err |= __get_user(regs->a2, &usc->sc_a2);
+	err |= __get_user(regs->a3, &usc->sc_a3);
+	for(i = 0; i < 10; i++)
+		err |= __get_user(regs->regs[i], &usc->sc_regs[i]);
+
+	err |= __get_user(regs->r15, &usc->sc_r15);
+#if defined(__CSKYABIV2__)
+	for(i = 0; i < 16; i++)
+	{
+		err |= __get_user(regs->exregs[i], &usc->sc_exregs[i]);
+	}
+	err |= __get_user(regs->rhi, &usc->sc_rhi);
+	err |= __get_user(regs->rlo, &usc->sc_rlo);
+#endif
+	err |= __get_user(regs->sr, &usc->sc_sr);
+	err |= __get_user(regs->pc, &usc->sc_pc);
+	err |= __get_user(usp, &usc->sc_usp);
+	wrusp(usp);
+
+#ifdef CONFIG_CPU_HAS_FPU
+	err |= restore_fpu_state(usc);
+#endif
+	*pr2 = regs->a0;
+	return err;
+}
+
+asmlinkage int
+do_rt_sigreturn(void)
+{
+	unsigned long usp = rdusp();
+	struct rt_sigframe *frame = (struct rt_sigframe *)usp;
+	sigset_t set;
+	int a0;
+	struct pt_regs *regs = current_pt_regs();
+
+	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
+		goto badframe;
+	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+		goto badframe;
+
+	sigdelsetmask(&set, ~_BLOCKABLE);
+	spin_lock_irq(&current->sighand->siglock);
+	current->blocked = set;
+	recalc_sigpending( );
+	spin_unlock_irq(&current->sighand->siglock);
+
+	if (restore_sigframe(regs, &frame->uc.uc_mcontext, &a0))
+		goto badframe;
+
+	return a0;
+
+badframe:
+	force_sig(SIGSEGV, current);
+	return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+static inline int setup_sigframe(struct sigcontext *sc, struct pt_regs *regs,
+		unsigned long mask)
+{
+	int err = 0;
+	int i = 0;
+
+	err |= __put_user(mask, &sc->sc_mask);
+	err |= __put_user(rdusp(), &sc->sc_usp);
+	err |= __put_user(regs->a0, &sc->sc_a0);
+	err |= __put_user(regs->a1, &sc->sc_a1);
+	err |= __put_user(regs->a2, &sc->sc_a2);
+	err |= __put_user(regs->a3, &sc->sc_a3);
+	for(i = 0; i < 10; i++)
+	{
+		err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
+	}
+	err |= __put_user(regs->r15, &sc->sc_r15);
+#if defined(__CSKYABIV2__)
+	for(i = 0; i < 16; i++)
+	{
+		err |= __put_user(regs->exregs[i], &sc->sc_exregs[i]);
+	}
+	err |= __put_user(regs->rhi, &sc->sc_rhi);
+	err |= __put_user(regs->rlo, &sc->sc_rlo);
+#endif
+	err |= __put_user(regs->sr, &sc->sc_sr);
+	err |= __put_user(regs->pc, &sc->sc_pc);
+
+#ifdef CONFIG_CPU_HAS_FPU
+	err |= save_fpu_state(sc, regs);
+#endif
+
+	return err;
+}
+
+static inline void *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+	unsigned long usp;
+
+	/* Default to using normal stack.  */
+	usp = rdusp();
+
+	/* This is the X/Open sanctioned signal stack switching.  */
+	if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(usp)) {
+		if (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+		sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *frame;
+	int err = 0;
+
+	struct csky_vdso *vdso = current->mm->context.vdso;
+
+	frame = get_sigframe(ka, regs, sizeof(*frame));
+	if (!frame)
+		return 1;
+
+	err |= __put_user(sig, &frame->sig);
+	err |= __put_user(&frame->info, &frame->pinfo);
+	err |= __put_user(&frame->uc, &frame->puc);
+	err |= copy_siginfo_to_user(&frame->info, info);
+
+	/* Create the ucontext.  */
+	err |= __put_user(0, &frame->uc.uc_flags);
+	err |= __put_user(0, &frame->uc.uc_link);
+	err |= __put_user((void *)current->sas_ss_sp,
+			&frame->uc.uc_stack.ss_sp);
+	err |= __put_user(sas_ss_flags(rdusp()),
+			&frame->uc.uc_stack.ss_flags);
+	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= setup_sigframe(&frame->uc.uc_mcontext, regs, 0);
+	err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+	if (err)
+		goto give_sigsegv;
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+	regs->r15 = (unsigned long)vdso->rt_signal_retcode;
+
+adjust_stack:
+	regs->a0 = sig; /* first arg is signo */
+	regs->a1 = (unsigned long)(&(frame->info)); /* second arg is (siginfo_t*) */
+	regs->a2 = (unsigned long)(&(frame->uc));/* third arg pointer to ucontext */
+	return err;
+
+give_sigsegv:
+	if (sig == SIGSEGV)
+		ka->sa.sa_handler = SIG_DFL;
+	force_sig(SIGSEGV, current);
+	goto adjust_stack;
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static int
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+		sigset_t *oldset, struct pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+	int ret;
+
+	/* set up the stack frame, regardless of SA_SIGINFO, and pass info anyway. */
+	ret = setup_rt_frame(sig, ka, info, oldset, regs);
+
+	if (ret != 0) {
+		force_sigsegv(sig, tsk);
+		return ret;
+	}
+
+	/* Block the signal if we were successful. */
+	spin_lock_irq(&current->sighand->siglock);
+	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
+	if (!(ka->sa.sa_flags & SA_NODEFER))
+		sigaddset(&current->blocked, sig);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	return 0;
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals
+ * that the kernel can handle, and then we build all the user-level signal
+ * handling stack-frames in one go after that.
+ */
+static void do_signal(struct pt_regs *regs, int syscall)
+{
+	unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
+	struct ksignal ksig;
+
+	/*
+	 * We want the common case to go fast, which
+	 * is why we may in certain cases get here from
+	 * kernel mode. Just return without doing anything
+	 * if so.
+	 */
+	if (!user_mode(regs))
+		return;
+
+	current->thread.esp0 = (unsigned long)regs;
+
+	/*
+	 * If we were from a system call, check for system call restarting...
+	 */
+	if (syscall) {
+		continue_addr = regs->pc;
+#if defined(__CSKYABIV2__)
+		restart_addr = continue_addr - 4;
+#else
+		restart_addr = continue_addr - 2;
+#endif
+		retval = regs->a0;
+
+		/*
+		 * Prepare for system call restart.  We do this here so that a
+		 * debugger will see the already changed.
+		 */
+		switch (retval) {
+		case -ERESTARTNOHAND:
+		case -ERESTARTSYS:
+		case -ERESTARTNOINTR:
+			regs->a0 = regs->orig_a0;
+			regs->pc = restart_addr;
+			break;
+		case -ERESTART_RESTARTBLOCK:
+			regs->a0 = -EINTR;
+			break;
+		}
+	}
+
+	if (try_to_freeze())
+		goto no_signal;
+
+	/*
+	 * Get the signal to deliver.  When running under ptrace, at this
+	 * point the debugger may change all our registers ...
+	 */
+	if (get_signal(&ksig)) {
+		sigset_t *oldset;
+
+		/*
+		 * Depending on the signal settings we may need to revert the
+		 * decision to restart the system call.  But skip this if a
+		 * debugger has chosen to restart at a different PC.
+		 */
+		if (regs->pc == restart_addr) {
+			if (retval == -ERESTARTNOHAND
+					|| (retval == -ERESTARTSYS
+						&& !(ksig.ka.sa.sa_flags & SA_RESTART))) {
+				regs->a0 = -EINTR;
+				regs->pc = continue_addr;
+			}
+		}
+
+		if (test_thread_flag(TIF_RESTORE_SIGMASK))
+			oldset = &current->saved_sigmask;
+		else
+			oldset = &current->blocked;
+		/* Whee!  Actually deliver the signal.  */
+		if (handle_signal(ksig.sig, &ksig.ka, &ksig.info, oldset, regs) == 0) {
+			/*
+			 * A signal was successfully delivered; the saved
+			 * sigmask will have been stored in the signal frame,
+			 * and will be restored by sigreturn, so we can simply
+			 * clear the TIF_RESTORE_SIGMASK flag.
+			 */
+			if (test_thread_flag(TIF_RESTORE_SIGMASK))
+				clear_thread_flag(TIF_RESTORE_SIGMASK);
+		}
+		return;
+	}
+
+no_signal:
+	if (syscall) {
+		/*
+		 * Handle restarting a different system call.  As above,
+		 * if a debugger has chosen to restart at a different PC,
+		 * ignore the restart.
+		 */
+		if (retval == -ERESTART_RESTARTBLOCK
+				&& regs->pc == continue_addr) {
+#if defined(__CSKYABIV2__)
+			regs->regs[3] = __NR_restart_syscall;
+			regs->pc -= 4;
+#else
+			regs->regs[9] = __NR_restart_syscall;
+			regs->pc -= 2;
+#endif
+		}
+
+		/* If there's no signal to deliver, we just put the saved sigmask
+		 * back.
+		 */
+		if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+			clear_thread_flag(TIF_RESTORE_SIGMASK);
+			sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+		}
+	}
+}
+
+asmlinkage void
+do_notify_resume(unsigned int thread_flags, struct pt_regs *regs, int syscall)
+{
+	if (thread_flags & _TIF_SIGPENDING)
+		do_signal(regs, syscall);
+
+	if (thread_flags & _TIF_NOTIFY_RESUME) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+	}
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 11/19] csky: Library functions
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (9 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 10/19] csky: Signal handling Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 12/19] csky: Debug and Ptrace GDB Guo Ren
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/abiv1/src/bswapdi.c    |  18 ++
 arch/csky/abiv1/src/bswapsi.c    |  15 ++
 arch/csky/abiv1/src/memcpy.S     | 344 +++++++++++++++++++++++++++++++++++++++
 arch/csky/abiv2/src/fpu.c        | 312 +++++++++++++++++++++++++++++++++++
 arch/csky/abiv2/src/memcpy.c     |  43 +++++
 arch/csky/include/asm/bitops.h   |  83 ++++++++++
 arch/csky/include/asm/checksum.h |  77 +++++++++
 arch/csky/include/asm/string.h   |  19 +++
 arch/csky/kernel/asm-offsets.c   |  86 ++++++++++
 arch/csky/kernel/cskyksyms.c     |  31 ++++
 arch/csky/kernel/platform.c      |  18 ++
 arch/csky/kernel/power.c         |  31 ++++
 arch/csky/lib/delay.c            |  40 +++++
 arch/csky/lib/memset.c           |  38 +++++
 arch/csky/lib/usercopy.c         | 271 ++++++++++++++++++++++++++++++
 arch/csky/oprofile/init.c        |  16 ++
 16 files changed, 1442 insertions(+)
 create mode 100644 arch/csky/abiv1/src/bswapdi.c
 create mode 100644 arch/csky/abiv1/src/bswapsi.c
 create mode 100644 arch/csky/abiv1/src/memcpy.S
 create mode 100644 arch/csky/abiv2/src/fpu.c
 create mode 100644 arch/csky/abiv2/src/memcpy.c
 create mode 100644 arch/csky/include/asm/bitops.h
 create mode 100644 arch/csky/include/asm/checksum.h
 create mode 100644 arch/csky/include/asm/string.h
 create mode 100644 arch/csky/kernel/asm-offsets.c
 create mode 100644 arch/csky/kernel/cskyksyms.c
 create mode 100644 arch/csky/kernel/platform.c
 create mode 100644 arch/csky/kernel/power.c
 create mode 100644 arch/csky/lib/delay.c
 create mode 100644 arch/csky/lib/memset.c
 create mode 100644 arch/csky/lib/usercopy.c
 create mode 100644 arch/csky/oprofile/init.c

diff --git a/arch/csky/abiv1/src/bswapdi.c b/arch/csky/abiv1/src/bswapdi.c
new file mode 100644
index 0000000..7346252
--- /dev/null
+++ b/arch/csky/abiv1/src/bswapdi.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/export.h>
+#include <linux/compiler.h>
+
+unsigned long long notrace __bswapdi2(unsigned long long u)
+{
+	return (((u) & 0xff00000000000000ull) >> 56) |
+	       (((u) & 0x00ff000000000000ull) >> 40) |
+	       (((u) & 0x0000ff0000000000ull) >> 24) |
+	       (((u) & 0x000000ff00000000ull) >>  8) |
+	       (((u) & 0x00000000ff000000ull) <<  8) |
+	       (((u) & 0x0000000000ff0000ull) << 24) |
+	       (((u) & 0x000000000000ff00ull) << 40) |
+	       (((u) & 0x00000000000000ffull) << 56);
+}
+
+EXPORT_SYMBOL(__bswapdi2);
diff --git a/arch/csky/abiv1/src/bswapsi.c b/arch/csky/abiv1/src/bswapsi.c
new file mode 100644
index 0000000..21958ca
--- /dev/null
+++ b/arch/csky/abiv1/src/bswapsi.c
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/export.h>
+#include <linux/compiler.h>
+
+unsigned int notrace __bswapsi2(unsigned int u)
+{
+	return (((u) & 0xff000000) >> 24) |
+	       (((u) & 0x00ff0000) >>  8) |
+	       (((u) & 0x0000ff00) <<  8) |
+	       (((u) & 0x000000ff) << 24);
+}
+
+EXPORT_SYMBOL(__bswapsi2);
+
diff --git a/arch/csky/abiv1/src/memcpy.S b/arch/csky/abiv1/src/memcpy.S
new file mode 100644
index 0000000..f86ad75
--- /dev/null
+++ b/arch/csky/abiv1/src/memcpy.S
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/linkage.h>
+
+.macro	GET_FRONT_BITS rx y
+#ifdef	__cskyLE__
+	lsri	\rx, \y
+#else
+	lsli	\rx, \y
+#endif
+.endm
+
+.macro	GET_AFTER_BITS rx y
+#ifdef	__cskyLE__
+	lsli	\rx, \y
+#else
+	lsri	\rx, \y
+#endif
+.endm
+
+/* void *memcpy(void *dest, const void *src, size_t n); */
+ENTRY(memcpy)
+	mov	r7, r2
+	cmplti	r4, 4                                   /* If len less than 4 bytes */
+	bt	.L_copy_by_byte
+	mov	r6, r2
+	andi	r6, 3
+	cmpnei	r6, 0
+	jbt	.L_dest_not_aligned                     /* If dest is not 4 bytes aligned */
+	mov	r6, r3
+	andi	r6, 3
+	cmpnei	r6, 0
+	jbt	.L_dest_aligned_but_src_not_aligned     /* If dest is aligned, but src is not aligned */
+.L0:
+	cmplti	r4, 16
+	jbt	.L_aligned_and_len_less_16bytes         /* If len less than 16 bytes */
+	subi	sp, 8
+	stw	r8, (sp, 0)
+.L_aligned_and_len_larger_16bytes:                      /* src and dst are all aligned, and len > 16 bytes */
+	ldw	r1, (r3, 0)
+	ldw	r5, (r3, 4)
+	ldw	r8, (r3, 8)
+	stw	r1, (r7, 0)
+	ldw	r1, (r3, 12)
+	stw	r5, (r7, 4)
+	stw	r8, (r7, 8)
+	stw	r1, (r7, 12)
+	subi	r4, 16
+	addi	r3, 16
+	addi	r7, 16
+	cmplti	r4, 16
+	jbf	.L_aligned_and_len_larger_16bytes
+	ldw	r8, (sp, 0)
+	addi	sp, 8
+	cmpnei	r4, 0                    /* If len == 0, return, else goto .L_aligned_and_len_less_16bytes  */
+	jbf	.L_return
+
+.L_aligned_and_len_less_16bytes:
+	cmplti	r4, 4
+	bt	.L_copy_by_byte
+.L1:
+	ldw	r1, (r3, 0)
+	stw	r1, (r7, 0)
+	subi	r4, 4
+	addi	r3, 4
+	addi	r7, 4
+	cmplti	r4, 4
+	jbf	.L1
+	br	.L_copy_by_byte
+
+.L_return:
+	rts
+
+.L_copy_by_byte:                      /* len less than 4 bytes */
+	cmpnei	r4, 0
+	jbf	.L_return
+.L4:
+	ldb	r1, (r3, 0)
+	stb	r1, (r7, 0)
+	addi	r3, 1
+	addi	r7, 1
+	decne	r4
+	jbt	.L4
+	rts
+
+/* If dest is not aligned, just copying some bytes makes the dest align.
+   Afther that, we judge whether the src is aligned. */
+.L_dest_not_aligned:
+	mov	r5, r3
+	rsub	r5, r5, r7
+	abs	r5, r5
+	cmplt	r5, r4
+	bt	.L_copy_by_byte
+	mov	r5, r7
+	sub	r5, r3
+	cmphs	r5, r4
+	bf	.L_copy_by_byte
+	mov	r5, r6
+.L5:
+	ldb	r1, (r3, 0)              /* makes the dest align. */
+	stb	r1, (r7, 0)
+	addi	r5, 1
+	subi	r4, 1
+	addi	r3, 1
+	addi	r7, 1
+	cmpnei	r5, 4
+	jbt	.L5
+	cmplti	r4, 4
+	jbt	.L_copy_by_byte
+	mov	r6, r3                   /* judge whether the src is aligned. */
+	andi	r6, 3
+	cmpnei	r6, 0
+	jbf	.L0
+
+/* Judge the number of misaligned, 1, 2, 3? */
+.L_dest_aligned_but_src_not_aligned:
+	mov	r5, r3
+	rsub	r5, r5, r7
+	abs	r5, r5
+	cmplt	r5, r4
+	bt	.L_copy_by_byte
+	bclri	r3, 0
+	bclri	r3, 1
+	ldw	r1, (r3, 0)
+	addi	r3, 4
+	cmpnei	r6, 2
+	bf	.L_dest_aligned_but_src_not_aligned_2bytes
+	cmpnei	r6, 3
+	bf	.L_dest_aligned_but_src_not_aligned_3bytes
+
+.L_dest_aligned_but_src_not_aligned_1byte:
+	mov	r5, r7
+	sub	r5, r3
+	cmphs	r5, r4
+	bf	.L_copy_by_byte
+	cmplti	r4, 16
+	bf	.L11
+.L10:                                     /* If the len is less than 16 bytes */
+	GET_FRONT_BITS r1 8
+	mov	r5, r1
+	ldw	r6, (r3, 0)
+	mov	r1, r6
+	GET_AFTER_BITS r6 24
+	or	r5, r6
+	stw	r5, (r7, 0)
+	subi	r4, 4
+	addi	r3, 4
+	addi	r7, 4
+	cmplti	r4, 4
+	bf	.L10
+	subi	r3, 3
+	br	.L_copy_by_byte
+.L11:
+	subi	sp, 16
+	stw	r8, (sp, 0)
+	stw	r9, (sp, 4)
+	stw	r10, (sp, 8)
+	stw	r11, (sp, 12)
+.L12:
+	ldw	r5, (r3, 0)
+	ldw	r11, (r3, 4)
+	ldw	r8, (r3, 8)
+	ldw	r9, (r3, 12)
+
+	GET_FRONT_BITS r1 8               /* little or big endian? */
+	mov	r10, r5
+	GET_AFTER_BITS r5 24
+	or	r5, r1
+
+	GET_FRONT_BITS r10 8
+	mov	r1, r11
+	GET_AFTER_BITS r11 24
+	or	r11, r10
+
+	GET_FRONT_BITS r1 8
+	mov	r10, r8
+	GET_AFTER_BITS r8 24
+	or	r8, r1
+
+	GET_FRONT_BITS r10 8
+	mov	r1, r9
+	GET_AFTER_BITS r9 24
+	or	r9, r10
+
+	stw	r5, (r7, 0)
+	stw	r11, (r7, 4)
+	stw	r8, (r7, 8)
+	stw	r9, (r7, 12)
+	subi	r4, 16
+	addi	r3, 16
+	addi	r7, 16
+	cmplti	r4, 16
+	jbf	.L12
+	ldw	r8, (sp, 0)
+	ldw	r9, (sp, 4)
+	ldw	r10, (sp, 8)
+	ldw	r11, (sp, 12)
+	addi	sp , 16
+	cmplti	r4, 4
+	bf	.L10
+	subi	r3, 3
+	br	.L_copy_by_byte
+
+.L_dest_aligned_but_src_not_aligned_2bytes:
+	cmplti	r4, 16
+	bf	.L21
+.L20:
+	GET_FRONT_BITS r1 16
+	mov	r5, r1
+	ldw	r6, (r3, 0)
+	mov	r1, r6
+	GET_AFTER_BITS r6 16
+	or	r5, r6
+	stw	r5, (r7, 0)
+	subi	r4, 4
+	addi	r3, 4
+	addi	r7, 4
+	cmplti	r4, 4
+	bf	.L20
+	subi	r3, 2
+	br	.L_copy_by_byte
+	rts
+
+.L21:	/* n > 16 */
+	subi 	sp, 16
+	stw	r8, (sp, 0)
+	stw	r9, (sp, 4)
+	stw	r10, (sp, 8)
+	stw	r11, (sp, 12)
+
+.L22:
+	ldw	r5, (r3, 0)
+	ldw	r11, (r3, 4)
+	ldw	r8, (r3, 8)
+	ldw	r9, (r3, 12)
+
+	GET_FRONT_BITS r1 16
+	mov	r10, r5
+	GET_AFTER_BITS r5 16
+	or	r5, r1
+
+	GET_FRONT_BITS r10 16
+	mov	r1, r11
+	GET_AFTER_BITS r11 16
+	or	r11, r10
+
+	GET_FRONT_BITS r1 16
+	mov	r10, r8
+	GET_AFTER_BITS r8 16
+	or	r8, r1
+
+	GET_FRONT_BITS r10 16
+	mov	r1, r9
+	GET_AFTER_BITS r9 16
+	or	r9, r10
+
+	stw	r5, (r7, 0)
+	stw	r11, (r7, 4)
+	stw	r8, (r7, 8)
+	stw	r9, (r7, 12)
+	subi	r4, 16
+	addi	r3, 16
+	addi	r7, 16
+	cmplti	r4, 16
+	jbf	.L22
+	ldw	r8, (sp, 0)
+	ldw	r9, (sp, 4)
+	ldw	r10, (sp, 8)
+	ldw	r11, (sp, 12)
+	addi	sp, 16
+	cmplti	r4, 4
+	bf	.L20
+	subi	r3, 2
+	br	.L_copy_by_byte
+
+
+.L_dest_aligned_but_src_not_aligned_3bytes:
+	cmplti	r4, 16
+	bf	.L31
+.L30:
+	GET_FRONT_BITS r1 24
+	mov	r5, r1
+	ldw	r6, (r3, 0)
+	mov	r1, r6
+	GET_AFTER_BITS r6 8
+	or	r5, r6
+	stw	r5, (r7, 0)
+	subi	r4, 4
+	addi	r3, 4
+	addi	r7, 4
+	cmplti	r4, 4
+	bf	.L30
+	subi	r3, 1
+	br	.L_copy_by_byte
+.L31:
+	subi	sp, 16
+	stw	r8, (sp, 0)
+	stw	r9, (sp, 4)
+	stw	r10, (sp, 8)
+	stw	r11, (sp, 12)
+.L32:
+	ldw	r5, (r3, 0)
+	ldw	r11, (r3, 4)
+	ldw	r8, (r3, 8)
+	ldw	r9, (r3, 12)
+
+	GET_FRONT_BITS r1 24
+	mov	r10, r5
+	GET_AFTER_BITS r5 8
+	or	r5, r1
+
+	GET_FRONT_BITS r10 24
+	mov	r1, r11
+	GET_AFTER_BITS r11 8
+	or	r11, r10
+
+	GET_FRONT_BITS r1 24
+	mov	r10, r8
+	GET_AFTER_BITS r8 8
+	or	r8, r1
+
+	GET_FRONT_BITS r10 24
+	mov	r1, r9
+	GET_AFTER_BITS r9 8
+	or	r9, r10
+
+	stw	r5, (r7, 0)
+	stw	r11, (r7, 4)
+	stw	r8, (r7, 8)
+	stw	r9, (r7, 12)
+	subi	r4, 16
+	addi	r3, 16
+	addi	r7, 16
+	cmplti	r4, 16
+	jbf	.L32
+	ldw	r8, (sp, 0)
+	ldw	r9, (sp, 4)
+	ldw	r10, (sp, 8)
+	ldw	r11, (sp, 12)
+	addi	sp, 16
+	cmplti	r4, 4
+	bf	.L30
+	subi	r3, 1
+	br	.L_copy_by_byte
diff --git a/arch/csky/abiv2/src/fpu.c b/arch/csky/abiv2/src/fpu.c
new file mode 100644
index 0000000..2d5d2da
--- /dev/null
+++ b/arch/csky/abiv2/src/fpu.c
@@ -0,0 +1,312 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/ptrace.h>
+#include <linux/uaccess.h>
+
+#if 0 /* FIXME: to support fpu exceptions */
+#define CONFIG_FCR (IDE_STAT | IXE_STAT | UFE_STAT |\
+		    OFE_STAT | DZE_STAT | IOE_STAT)
+#else
+#define CONFIG_FCR 0
+#endif
+
+inline unsigned int
+read_pt_regs(unsigned int rx, struct pt_regs *regs)
+{
+	unsigned int value;
+
+	if(rx < 14)
+		value  = *((int *)regs + rx + 3);
+	else if(rx == 14)
+		if(user_mode(regs))
+			asm volatile("mfcr %0, cr<14, 1>\n":"=r"(value));
+		else
+			value = sizeof(struct pt_regs) + ((unsigned int)regs);
+	else
+		value = *((int *)regs + rx + 2);
+
+	return value;
+}
+
+inline void
+write_pt_regs(unsigned int value, unsigned int rx, struct pt_regs *regs)
+{
+	if(rx < 14)
+		*((int *)regs + rx + 3) = value;
+	else if(rx == 14)
+		if(user_mode(regs))
+			asm volatile("mtcr %0, cr<14, 1>\n"::"r"(value));
+		else
+			printk("math emulate trying to write sp.\n");
+	else
+		*((int *)regs + rx + 2) = value;
+}
+
+void __init init_fpu(void)
+{
+	unsigned long fcr;
+
+	fcr = CONFIG_FCR;
+	asm volatile("mtcr %0, cr<1, 2>\n"::"r"(fcr));
+}
+
+inline unsigned int read_fpcr(void)
+{
+	unsigned int result = 0;
+	asm volatile("mfcr %0, cr<1, 2>\n":"=r"(result));
+	return result;
+}
+
+inline void write_fpcr(unsigned int val)
+{
+	unsigned int result = val | CONFIG_FCR;
+	asm volatile("mtcr %0, cr<1, 2>\n"::"r"(result));
+}
+
+inline unsigned int read_fpesr(void)
+{
+	unsigned int result = 0;
+	asm volatile("mfcr %0, cr<2, 2>\n":"=r"(result));
+	return result;
+}
+
+inline void write_fpesr(unsigned int val)
+{
+	unsigned int result = val;
+	asm volatile("mtcr %0, cr<2, 2>\n"::"r"(result));
+}
+
+/* use as fpc control reg read/write in glibc. */
+int fpu_libc_helper(struct pt_regs * regs)
+{
+	mm_segment_t fs;
+	unsigned long instrptr, regx = 0;
+	unsigned int fault;
+
+	u16 instr_hi, instr_low;
+	unsigned long index_regx = 0, index_fpregx_prev = 0, index_fpregx_next = 0;
+	unsigned long tinstr = 0;
+
+	instrptr = instruction_pointer(regs);
+
+	/* CSKYV2's 32 bit instruction may not align 4 words */
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	fault = __get_user(instr_low, (u16 *)(instrptr & ~1));
+	set_fs(fs);
+	if (fault) {
+		goto bad_or_fault;
+	}
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	fault = __get_user(instr_hi, (u16 *)((instrptr + 2) & ~1));
+	set_fs(fs);
+	if (fault) {
+		goto bad_or_fault;
+	}
+
+	tinstr = instr_hi | ((unsigned long)instr_low << 16);
+
+	index_fpregx_next = ((tinstr >> 21) & 0x1F);
+
+	/* just want to handle instruction which opration cr<1, 2> or cr<2, 2> */
+	if(index_fpregx_next != 2){
+		goto bad_or_fault;
+	}
+
+	/*
+	 * define four macro to distinguish the instruction is mfcr or mtcr.
+	 */
+#define MTCR_MASK 0xFC00FFE0
+#define MFCR_MASK 0xFC00FFE0
+#define MTCR_DISTI 0xC0006420
+#define MFCR_DISTI 0xC0006020
+
+	if ((tinstr & MTCR_MASK) == MTCR_DISTI)
+	{
+		index_regx = (tinstr >> 16) & 0x1F;
+		index_fpregx_prev = tinstr & 0x1F;
+
+		regx = read_pt_regs(index_regx, regs);
+
+		if(index_fpregx_prev == 1) {
+			write_fpcr(regx);
+		} else if (index_fpregx_prev == 2) {
+			write_fpesr(regx);
+		} else {
+			goto bad_or_fault;
+		}
+
+		regs->pc +=4;
+		return 1;
+	} else if ((tinstr & MFCR_MASK) == MFCR_DISTI) {
+		index_regx = tinstr & 0x1F;
+		index_fpregx_prev = ((tinstr >> 16) & 0x1F);
+
+		if (index_fpregx_prev == 1) {
+			regx = read_fpcr();
+		} else if (index_fpregx_prev == 2) {
+			regx = read_fpesr();
+		} else {
+			goto bad_or_fault;
+		}
+
+		write_pt_regs(regx, index_regx, regs);
+
+		regs->pc +=4;
+		return 1;
+	}
+
+bad_or_fault:
+	return 0;
+}
+
+void fpu_fpe(struct pt_regs * regs)
+{
+	int sig;
+	unsigned int fesr;
+	siginfo_t info;
+	asm volatile("mfcr %0, cr<2, 2>":"=r"(fesr));
+
+	if(fesr & FPE_ILLE){
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+	}
+	else if(fesr & FPE_IDC){
+		info.si_code = ILL_ILLOPN;
+		sig = SIGILL;
+	}
+	else if(fesr & FPE_FEC){
+		sig = SIGFPE;
+		if(fesr & FPE_IOC){
+			info.si_code = FPE_FLTINV;
+		}
+		else if(fesr & FPE_DZC){
+			info.si_code = FPE_FLTDIV;
+		}
+		else if(fesr & FPE_UFC){
+			info.si_code = FPE_FLTUND;
+		}
+		else if(fesr & FPE_OFC){
+			info.si_code = FPE_FLTOVF;
+		}
+		else if(fesr & FPE_IXC){
+			info.si_code = FPE_FLTRES;
+		}
+		else {
+			info.si_code = NSIGFPE;
+		}
+	}
+	else {
+		info.si_code = NSIGFPE;
+		sig = SIGFPE;
+	}
+	info.si_signo = SIGFPE;
+	info.si_errno = 0;
+	info.si_addr = (void *)regs->pc;
+	force_sig_info(sig, &info, current);
+}
+
+typedef struct fpregset {
+	int f_fcr;
+	int f_fsr;		/* Nothing in CPU_CSKYV2 */
+	int f_fesr;
+	int f_feinst1;		/* Nothing in CPU_CSKYV2 */
+	int f_feinst2;		/* Nothing in CPU_CSKYV2 */
+	int f_fpregs[32];
+} fpregset_t;
+
+int save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+	int err = 0;
+	fpregset_t fpregs;
+	unsigned long flg;
+	unsigned long tmp1, tmp2, tmp3, tmp4;
+	int * fpgr;
+
+	local_irq_save(flg);
+	fpgr = &(fpregs.f_fpregs[0]);
+	asm volatile(
+		"mfcr    %0, cr<1, 2>\n"
+		"mfcr    %1, cr<2, 2>\n"
+		:"=r"(fpregs.f_fcr),"=r"(fpregs.f_fesr));
+
+	asm volatile(
+		FMFVR_FPU_REGS(vr0, vr1)
+		STW_FPU_REGS(0, 4, 8, 12)
+		FMFVR_FPU_REGS(vr2, vr3)
+		STW_FPU_REGS(16, 20, 24, 28)
+		FMFVR_FPU_REGS(vr4, vr5)
+		STW_FPU_REGS(32, 36, 40, 44)
+		FMFVR_FPU_REGS(vr6, vr7)
+		STW_FPU_REGS(48, 52, 56, 60)
+		"addi    %4, 32\n"
+		"addi    %4, 32\n"
+		FMFVR_FPU_REGS(vr8, vr9)
+		STW_FPU_REGS(0, 4, 8, 12)
+		FMFVR_FPU_REGS(vr10, vr11)
+		STW_FPU_REGS(16, 20, 24, 28)
+		FMFVR_FPU_REGS(vr12, vr13)
+		STW_FPU_REGS(32, 36, 40, 44)
+		FMFVR_FPU_REGS(vr14, vr15)
+		STW_FPU_REGS(48, 52, 56, 60)
+		:"=a"(tmp1),"=a"(tmp2),"=a"(tmp3),
+		"=a"(tmp4),"+a"(fpgr));
+	local_irq_restore(flg);
+
+	err |= copy_to_user(&sc->sc_fcr, &fpregs, sizeof(fpregs));
+	return err;
+}
+
+int restore_fpu_state(struct sigcontext *sc)
+{
+	int err = 0;
+	fpregset_t fpregs;
+	unsigned long flg;
+	unsigned long tmp1, tmp2, tmp3, tmp4;
+	unsigned long fctl0, fctl1, fctl2;
+	int * fpgr;
+
+	if (__copy_from_user(&fpregs, &sc->sc_fcr, sizeof(fpregs)))
+	{
+		err = 1;
+		goto out;
+	}
+
+	local_irq_save(flg);
+	fctl0 = fpregs.f_fcr;
+	fctl1 = fpregs.f_fsr;
+	fctl2 = fpregs.f_fesr;
+	fpgr = &(fpregs.f_fpregs[0]);
+	asm volatile(
+		"mtcr   %0, cr<1, 2>\n"
+		"mtcr   %1, cr<2, 2>\n"
+		::"r"(fctl0), "r"(fctl2));
+
+	asm volatile(
+		LDW_FPU_REGS(0, 4, 8, 12)
+		FMTVR_FPU_REGS(vr0, vr1)
+		LDW_FPU_REGS(16, 20, 24, 28)
+		FMTVR_FPU_REGS(vr2, vr3)
+		LDW_FPU_REGS(32, 36, 40, 44)
+		FMTVR_FPU_REGS(vr4, vr5)
+		LDW_FPU_REGS(48, 52, 56, 60)
+		FMTVR_FPU_REGS(vr6, vr7)
+		"addi   %4, 32\n"
+		"addi   %4, 32\n"
+		LDW_FPU_REGS(0, 4, 8, 12)
+		FMTVR_FPU_REGS(vr8, vr9)
+		LDW_FPU_REGS(16, 20, 24, 28)
+		FMTVR_FPU_REGS(vr10, vr11)
+		LDW_FPU_REGS(32, 36, 40, 44)
+		FMTVR_FPU_REGS(vr12, vr13)
+		LDW_FPU_REGS(48, 52, 56, 60)
+		FMTVR_FPU_REGS(vr14, vr15)
+		:"=a"(tmp1),"=a"(tmp2),"=a"(tmp3),
+		"=a"(tmp4),"+a"(fpgr));
+	local_irq_restore(flg);
+out:
+	return err;
+}
+
diff --git a/arch/csky/abiv2/src/memcpy.c b/arch/csky/abiv2/src/memcpy.c
new file mode 100644
index 0000000..67d8d01
--- /dev/null
+++ b/arch/csky/abiv2/src/memcpy.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/types.h>
+
+/*
+ * memory copy function.
+ */
+void *memcpy (void *to, const void *from, size_t l)
+{
+	char *d = to;
+	const char *s = from;
+
+	if (((long)d | (long)s) & 0x3)
+	{
+		while (l--) *d++ = *s++;
+	}
+	else
+	{
+        	while (l >= 16)
+		{
+			*(((long *)d)) = *(((long *)s));
+			*(((long *)d)+1) = *(((long *)s)+1);
+			*(((long *)d)+2) = *(((long *)s)+2);
+			*(((long *)d)+3) = *(((long *)s)+3);
+			l -= 16;
+			d += 16;
+			s += 16;
+		}
+		while (l > 3)
+		{
+			*(((long *)d)) = *(((long *)s));
+			d = d +4;
+			s = s +4;
+			l -= 4;
+		}
+		while (l)
+		{
+			*d++ = *s++;
+			l--;	
+		}
+	}
+	return to;
+}
diff --git a/arch/csky/include/asm/bitops.h b/arch/csky/include/asm/bitops.h
new file mode 100644
index 0000000..0688786
--- /dev/null
+++ b/arch/csky/include/asm/bitops.h
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_BITOPS_H
+#define __ASM_CSKY_BITOPS_H
+
+#include <linux/irqflags.h>
+#include <linux/compiler.h>
+#include <asm/barrier.h>
+
+/*
+ * asm-generic/bitops/ffs.h
+ */
+static inline int ffs(int x)
+{
+	if(!x) return 0;
+
+	asm volatile (
+		"brev %0\n"
+		"ff1  %0\n"
+		"addi %0, 1\n"
+		:"=r"(x)
+		:"0"(x));
+	return x;
+}
+
+/*
+ * asm-generic/bitops/__ffs.h
+ */
+static __always_inline unsigned long __ffs(unsigned long x)
+{
+	asm volatile (
+		"brev %0\n"
+		"ff1  %0\n"
+		:"=r"(x)
+		:"0"(x));
+	return x;
+}
+
+/*
+ * asm-generic/bitops/fls.h
+ */
+static __always_inline int fls(int x)
+{
+	asm volatile(
+		"ff1 %0\n"
+		:"=r"(x)
+		:"0"(x));
+
+	return (32 - x);
+}
+
+/*
+ * asm-generic/bitops/__fls.h
+ */
+static __always_inline unsigned long __fls(unsigned long x)
+{
+	return fls(x) - 1;
+}
+
+#include <asm-generic/bitops/ffz.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#include <asm-generic/bitops/atomic.h>
+
+/*
+ * bug fix, why only could use atomic!!!!
+ */
+#include <asm-generic/bitops/non-atomic.h>
+#define __clear_bit(nr,vaddr) clear_bit(nr,vaddr)
+
+#include <asm-generic/bitops/le.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+#endif /* __ASM_CSKY_BITOPS_H */
+
diff --git a/arch/csky/include/asm/checksum.h b/arch/csky/include/asm/checksum.h
new file mode 100644
index 0000000..3f7d255
--- /dev/null
+++ b/arch/csky/include/asm/checksum.h
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_CHECKSUM_H
+#define __ASM_CSKY_CHECKSUM_H
+
+#include <linux/in6.h>
+#include <asm/byteorder.h>
+
+static inline __sum16 csum_fold(__wsum csum)
+{
+	u32 tmp;
+	asm volatile(
+		"mov	%1, %0\n"
+		"rori	%0, 16\n"
+		"addu	%0, %1\n"
+		"lsri	%0, 16\n"
+		:"=r"(csum), "=r"(tmp)
+		:"0"(csum));
+	return (__force __sum16)~csum;
+}
+#define csum_fold csum_fold
+
+static inline __wsum
+csum_tcpudp_nofold(
+	__be32 saddr,
+	__be32 daddr,
+	unsigned short len,
+	unsigned short proto,
+	__wsum sum
+	)
+{
+	asm volatile(
+		"clrc\n"
+		"addc    %0, %1\n"
+		"addc    %0, %2\n"
+		"addc    %0, %3\n"
+		"inct    %0\n"
+		:"=r"(sum)
+		:"r"((__force u32)saddr),
+		"r"((__force u32)daddr),
+#ifdef __BIG_ENDIAN
+		"r"(proto + len),
+#else
+		"r"((proto + len) << 8),
+#endif
+		"0" ((__force unsigned long)sum)
+		:"cc");
+	return sum;
+}
+#define csum_tcpudp_nofold csum_tcpudp_nofold
+
+static __inline__ __sum16
+csum_ipv6_magic(
+	const struct in6_addr *saddr,
+	const struct in6_addr *daddr,
+	__u32 len,
+	unsigned short proto,
+	__wsum sum
+	)
+{
+	sum += saddr->in6_u.u6_addr32[0];
+	sum += saddr->in6_u.u6_addr32[1];
+	sum += saddr->in6_u.u6_addr32[2];
+	sum += saddr->in6_u.u6_addr32[3];
+	sum += daddr->in6_u.u6_addr32[0];
+	sum += daddr->in6_u.u6_addr32[1];
+	sum += daddr->in6_u.u6_addr32[2];
+	sum += daddr->in6_u.u6_addr32[3];
+	sum += (len + proto);
+
+	return csum_fold(sum);
+}
+#define _HAVE_ARCH_IPV6_CSUM
+
+#include <asm-generic/checksum.h>
+
+#endif /* __ASM_CSKY_CHECKSUM_H */
diff --git a/arch/csky/include/asm/string.h b/arch/csky/include/asm/string.h
new file mode 100644
index 0000000..2c4878b
--- /dev/null
+++ b/arch/csky/include/asm/string.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef _CSKY_STRING_MM_H_
+#define _CSKY_STRING_MM_H_
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <linux/compiler.h>
+
+#define __HAVE_ARCH_MEMCPY
+extern void * memcpy(void *to, const void *from, size_t l);
+
+/* New and improved.  In arch/csky/lib/memset.c */
+#define __HAVE_ARCH_MEMSET
+extern void * memset(void *dest, int c, size_t l);
+
+#endif
+
+#endif /* _CSKY_STRING_MM_H_ */
diff --git a/arch/csky/kernel/asm-offsets.c b/arch/csky/kernel/asm-offsets.c
new file mode 100644
index 0000000..767fa9c
--- /dev/null
+++ b/arch/csky/kernel/asm-offsets.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/kbuild.h>
+#include <abi/regdef.h>
+
+int main(void)
+{
+	/* offsets into the task struct */
+	DEFINE(TASK_STATE,        offsetof(struct task_struct, state));
+	DEFINE(TASK_THREAD_INFO,  offsetof(struct task_struct, stack));
+	DEFINE(TASK_FLAGS,        offsetof(struct task_struct, flags));
+	DEFINE(TASK_PTRACE,       offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_THREAD,       offsetof(struct task_struct, thread));
+	DEFINE(TASK_MM,           offsetof(struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM,    offsetof(struct task_struct, active_mm));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP,        offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_USP,        offsetof(struct thread_struct, usp));
+	DEFINE(THREAD_SR,         offsetof(struct thread_struct, sr));
+	DEFINE(THREAD_ESP0,       offsetof(struct thread_struct, esp0));
+	DEFINE(THREAD_FESR,       offsetof(struct thread_struct, fesr));
+	DEFINE(THREAD_FSR,        offsetof(struct thread_struct, fsr));
+	DEFINE(THREAD_FCR,        offsetof(struct thread_struct, fcr));
+	DEFINE(THREAD_FPREG,      offsetof(struct thread_struct, fp));
+	DEFINE(THREAD_DSPHI,      offsetof(struct thread_struct, hi));
+	DEFINE(THREAD_DSPLO,      offsetof(struct thread_struct, lo));
+
+	/* offsets into the thread_info struct */
+	DEFINE(TINFO_FLAGS,       offsetof(struct thread_info, flags));
+	DEFINE(TINFO_PREEMPT,     offsetof(struct thread_info, preempt_count));
+	DEFINE(TINFO_ADDR_LIMIT,  offsetof(struct thread_info, addr_limit));
+	DEFINE(TINFO_TP_VALUE,   offsetof(struct thread_info, tp_value));
+	DEFINE(TINFO_TASK,        offsetof(struct thread_info, task));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_PC,             offsetof(struct pt_regs, pc));
+	DEFINE(PT_ORIG_AO,        offsetof(struct pt_regs, orig_a0));
+	DEFINE(PT_SR,             offsetof(struct pt_regs, sr));
+
+	DEFINE(PT_A0,             offsetof(struct pt_regs, a0));
+	DEFINE(PT_A1,             offsetof(struct pt_regs, a1));
+	DEFINE(PT_A2,             offsetof(struct pt_regs, a2));
+	DEFINE(PT_A3,             offsetof(struct pt_regs, a3));
+	DEFINE(PT_REGS0,          offsetof(struct pt_regs, regs[0]));
+	DEFINE(PT_REGS1,          offsetof(struct pt_regs, regs[1]));
+	DEFINE(PT_REGS2,          offsetof(struct pt_regs, regs[2]));
+	DEFINE(PT_REGS3,          offsetof(struct pt_regs, regs[3]));
+	DEFINE(PT_REGS4,          offsetof(struct pt_regs, regs[4]));
+	DEFINE(PT_REGS5,          offsetof(struct pt_regs, regs[5]));
+	DEFINE(PT_REGS6,          offsetof(struct pt_regs, regs[6]));
+	DEFINE(PT_REGS7,          offsetof(struct pt_regs, regs[7]));
+	DEFINE(PT_REGS8,          offsetof(struct pt_regs, regs[8]));
+	DEFINE(PT_REGS9,          offsetof(struct pt_regs, regs[9]));
+	DEFINE(PT_R15,            offsetof(struct pt_regs, r15));
+#if defined(__CSKYABIV2__)
+	DEFINE(PT_R16,            offsetof(struct pt_regs, exregs[0]));
+	DEFINE(PT_R17,            offsetof(struct pt_regs, exregs[1]));
+	DEFINE(PT_R18,            offsetof(struct pt_regs, exregs[2]));
+	DEFINE(PT_R19,            offsetof(struct pt_regs, exregs[3]));
+	DEFINE(PT_R20,            offsetof(struct pt_regs, exregs[4]));
+	DEFINE(PT_R21,            offsetof(struct pt_regs, exregs[5]));
+	DEFINE(PT_R22,            offsetof(struct pt_regs, exregs[6]));
+	DEFINE(PT_R23,            offsetof(struct pt_regs, exregs[7]));
+	DEFINE(PT_R24,            offsetof(struct pt_regs, exregs[8]));
+	DEFINE(PT_R25,            offsetof(struct pt_regs, exregs[9]));
+	DEFINE(PT_R26,            offsetof(struct pt_regs, exregs[10]));
+	DEFINE(PT_R27,            offsetof(struct pt_regs, exregs[11]));
+	DEFINE(PT_R28,            offsetof(struct pt_regs, exregs[12]));
+	DEFINE(PT_R29,            offsetof(struct pt_regs, exregs[13]));
+	DEFINE(PT_R30,            offsetof(struct pt_regs, exregs[14]));
+	DEFINE(PT_R31,            offsetof(struct pt_regs, exregs[15]));
+	DEFINE(PT_RHI,            offsetof(struct pt_regs, rhi));
+	DEFINE(PT_RLO,            offsetof(struct pt_regs, rlo));
+#endif
+	/* offsets into the irq_cpustat_t struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+
+	/* signal defines */
+	DEFINE(SIGSEGV, SIGSEGV);
+	DEFINE(SIGTRAP, SIGTRAP);
+
+	return 0;
+}
diff --git a/arch/csky/kernel/cskyksyms.c b/arch/csky/kernel/cskyksyms.c
new file mode 100644
index 0000000..3f13594
--- /dev/null
+++ b/arch/csky/kernel/cskyksyms.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Defined in libgcc
+ *
+ * See arch/csky/Makefile:
+ *	-print-libgcc-file-name
+ */
+extern void __ashldi3 (void);
+extern void __ashrdi3 (void);
+extern void __lshrdi3 (void);
+extern void __muldi3 (void);
+extern void __ucmpdi2 (void);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__ucmpdi2);
+
+/*
+ * Defined in abiv1/src/memcpy.S
+ * and abiv2/src/memcpy.c
+ */
+EXPORT_SYMBOL(memcpy);
+
+/* Defined in lib/memset.c */
+EXPORT_SYMBOL(memset);
diff --git a/arch/csky/kernel/platform.c b/arch/csky/kernel/platform.c
new file mode 100644
index 0000000..f51654f
--- /dev/null
+++ b/arch/csky/kernel/platform.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/init.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_fdt.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/sys_soc.h>
+#include <linux/io.h>
+
+static int __init csky_platform_init(void)
+{
+	return of_platform_default_populate(NULL, NULL, NULL);
+}
+device_initcall(csky_platform_init);
+
+
diff --git a/arch/csky/kernel/power.c b/arch/csky/kernel/power.c
new file mode 100644
index 0000000..d35e882
--- /dev/null
+++ b/arch/csky/kernel/power.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/reboot.h>
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+void machine_power_off(void)
+{
+	local_irq_disable();
+	if (pm_power_off)
+		pm_power_off();
+	asm volatile ("bkpt");
+}
+
+void machine_halt(void)
+{
+	local_irq_disable();
+	if (pm_power_off)
+		pm_power_off();
+	asm volatile ("bkpt");
+}
+
+void machine_restart(char *cmd)
+{
+	local_irq_disable();
+	do_kernel_restart(cmd);
+	asm volatile ("bkpt");
+}
+
+
diff --git a/arch/csky/lib/delay.c b/arch/csky/lib/delay.c
new file mode 100644
index 0000000..34766a4
--- /dev/null
+++ b/arch/csky/lib/delay.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+void __delay(unsigned long loops)
+{
+       asm volatile (
+		"mov r0, r0\n"
+		"1:declt %0\n"
+		"bf	1b"
+                :"=r"(loops)
+	        :"0"(loops));
+}
+EXPORT_SYMBOL(__delay);
+
+extern unsigned long loops_per_jiffy;
+
+void __const_udelay(unsigned long xloops)
+{
+	unsigned long long loops;
+
+	loops = (unsigned long long)xloops * loops_per_jiffy * HZ;
+
+	__delay(loops >> 32);
+}
+EXPORT_SYMBOL(__const_udelay);
+
+void __udelay(unsigned long usecs)
+{
+	__const_udelay(usecs * 0x10C7UL); /* 2**32 / 1000000 (rounded up) */
+}
+EXPORT_SYMBOL(__udelay);
+
+void __ndelay(unsigned long nsecs)
+{
+	__const_udelay(nsecs * 0x5UL); /* 2**32 / 1000000000 (rounded up) */
+}
+EXPORT_SYMBOL(__ndelay);
diff --git a/arch/csky/lib/memset.c b/arch/csky/lib/memset.c
new file mode 100644
index 0000000..b7897af
--- /dev/null
+++ b/arch/csky/lib/memset.c
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/types.h>
+
+void *memset(void *dest, int c, size_t l)
+{
+	char *d = dest;
+	int ch = c;
+	int tmp;
+
+	if ((long)d & 0x3)
+		while (l--) *d++ = ch;
+	else {
+		ch &= 0xff;
+		tmp = (ch | ch << 8 | ch << 16 | ch << 24);
+
+		while (l >= 16) {
+			*(((long *)d)) = tmp;
+			*(((long *)d)+1) = tmp;
+			*(((long *)d)+2) = tmp;
+			*(((long *)d)+3) = tmp;
+			l -= 16;
+			d += 16;
+		}
+
+		while (l > 3) {
+			*(((long *)d)) = tmp;
+			d = d + 4;
+			l -= 4;
+		}
+
+		while (l) {
+			*d++ = ch;
+			l--;
+		}
+	}
+	return dest;
+}
diff --git a/arch/csky/lib/usercopy.c b/arch/csky/lib/usercopy.c
new file mode 100644
index 0000000..ace4190
--- /dev/null
+++ b/arch/csky/lib/usercopy.c
@@ -0,0 +1,271 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/uaccess.h>
+#include <linux/types.h>
+
+unsigned long
+raw_copy_from_user(
+		void *to,
+		const void *from,
+		unsigned long n)
+{
+	if (access_ok(VERIFY_READ, from, n))
+		__copy_user_zeroing(to,from,n); 
+	else
+		memset(to,0, n);
+	return n;
+}
+EXPORT_SYMBOL(raw_copy_from_user);
+
+unsigned long
+raw_copy_to_user(
+		void *to,
+		const void *from,
+		unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		__copy_user(to,from,n);
+	return n;
+}
+EXPORT_SYMBOL(raw_copy_to_user);
+
+
+/*
+ * copy a null terminated string from userspace.	
+ */
+#define __do_strncpy_from_user(dst,src,count,res)       \
+do{                                                     \
+        int tmp;                                        \
+        long faultres;                                  \
+        asm volatile(                           \
+        "       cmpnei  %3, 0           \n"             \
+        "       bf      4f              \n"             \
+        "1:     cmpnei  %1, 0          	\n"             \
+        "       bf      5f              \n"             \
+        "2:     ldb     %4, (%3, 0)     \n"             \
+        "       stb     %4, (%2, 0)     \n"             \
+        "       cmpnei  %4, 0           \n"             \
+        "       bf      3f              \n"             \
+        "       addi    %3,  1          \n"             \
+        "       addi    %2,  1          \n"             \
+        "       subi    %1,  1          \n"             \
+        "       br      1b              \n"             \
+        "3:     subu	%0, %1          \n"             \
+        "       br      5f              \n"             \
+        "4:     mov     %0, %5          \n"             \
+        "       br      5f              \n"             \
+        ".section __ex_table, \"a\"     \n"             \
+        ".align   2                     \n"             \
+        ".long    2b, 4b                \n"             \
+        ".previous                      \n"             \
+        "5:                             \n"             \
+          :"=r"(res),"=r"(count),"=r"(dst),"=r"(src), "=r"(tmp),"=r"(faultres) \
+          : "5"(-EFAULT),"0"(count), "1"(count), "2"(dst),"3"(src)     	       \
+          : "memory" );	                                \
+} while(0)		
+
+/*
+ * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ * 
+ * Copies a NUL-terminated string from userspace to kernel space.
+ * Caller must check the specified block with access_ok() before calling
+ * this function.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+long
+__strncpy_from_user(
+	char *dst,
+	const char *src,
+	long count)
+{
+	long res;
+	__do_strncpy_from_user(dst, src, count, res);
+	return res;
+}
+EXPORT_SYMBOL(__strncpy_from_user);
+
+/*
+ * strncpy_from_user: - Copy a NUL terminated string from userspace.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @src:   Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ * 
+ * Copies a NUL-terminated string from userspace to kernel space.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+long
+strncpy_from_user(
+	char *dst,
+	const char *src,
+	long count)
+{
+	long res = -EFAULT;
+	if (access_ok(VERIFY_READ, src, 1))
+		__do_strncpy_from_user(dst, src, count, res);
+	return res;
+}
+EXPORT_SYMBOL(strncpy_from_user);
+
+/*
+ * strlen_user: - Get the size of a string in user space.
+ * @str: The string to measure.
+ * @n:   The maximum valid length
+ *
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ * If the string is too long, returns a value greater than @n.
+ */
+long strnlen_user(const char *s, long n)
+{
+
+	unsigned long res,tmp;
+	if(s){
+	asm volatile(
+        "       cmpnei  %1, 0           \n"
+        "       bf      3f              \n"
+        "1:     cmpnei  %0, 0           \n"              
+        "       bf      3f              \n"
+        "2:     ldb     %3, (%1, 0)     \n"             
+        "       cmpnei  %3, 0           \n"             
+        "       bf      3f              \n"             
+        "       subi    %0,  1          \n"             
+        "       addi    %1,  1          \n"             
+        "       br      1b              \n"
+        "3:     subu    %2, %0          \n"
+        "       addi    %2,  1          \n"             
+        "       br      5f              \n"             
+        "4:     movi    %0, 0           \n"             
+        "       br      5f              \n"             
+        ".section __ex_table, \"a\"     \n"             
+        ".align   2                     \n"
+        ".long    2b, 4b                \n"             
+        ".previous                      \n"             
+        "5:                             \n"             
+        :"=r"(n),"=r"(s), "=r"(res), "=r"(tmp)   
+        : "0"(n), "1"(s), "2"(n)      
+        : "cc" );
+		return res;     
+	}
+	return 0;     
+}
+EXPORT_SYMBOL(strnlen_user);
+
+#define __do_clear_user(addr, size)                             \
+do {                                                            \
+	int __d0;                                               \
+	int zvalue;                                             \
+	int tmp;                                                \
+	asm volatile(						\
+		"0:     cmpnei  %1, 0           \n"             \
+		"       bf      7f              \n"             \
+		"       mov     %3, %1          \n"             \
+		"       andi    %3, 3           \n"             \
+		"       cmpnei  %3, 0           \n"             \
+		"       bf      1f              \n"             \
+		"       br      5f              \n"             \
+		"1:     cmplti  %0, 32          \n"   /* 4W */  \
+		"       bt      3f              \n"             \
+		"8:     stw     %2, (%1, 0)     \n"             \
+		"10:    stw     %2, (%1, 4)     \n"             \
+		"11:    stw     %2, (%1, 8)     \n"             \
+		"12:    stw     %2, (%1, 12)    \n"             \
+		"13:    stw     %2, (%1, 16)    \n"             \
+		"14:    stw     %2, (%1, 20)    \n"             \
+		"15:    stw     %2, (%1, 24)    \n"             \
+		"16:    stw     %2, (%1, 28)    \n"             \
+		"       addi    %1, 32          \n"             \
+		"       subi    %0, 32          \n"             \
+		"       br      1b              \n"             \
+		"3:     cmplti  %0, 4           \n"  /* 1W */   \
+		"       bt      5f              \n"             \
+		"4:     stw     %2, (%1, 0)     \n"             \
+		"       addi    %1, 4           \n"             \
+		"       subi    %0, 4           \n"             \
+		"       br      3b              \n"             \
+		"5:     cmpnei  %0, 0           \n"  /* 1B */   \
+		"9:     bf      7f              \n"             \
+		"6:     stb     %2, (%1, 0)     \n"             \
+		"       addi    %1,  1          \n"             \
+		"       subi    %0,  1          \n"             \
+		"       br      5b              \n"             \
+		".section __ex_table,\"a\"      \n"             \
+		".align   2                     \n"             \
+		".long    8b, 9b                \n"             \
+		".long    10b, 9b               \n"             \
+		".long    11b, 9b               \n"             \
+		".long    12b, 9b               \n"             \
+		".long    13b, 9b               \n"             \
+		".long    14b, 9b               \n"             \
+		".long    15b, 9b               \n"             \
+		".long    16b, 9b               \n"             \
+		".long    4b, 9b                \n"             \
+		".long    6b, 9b                \n"             \
+		".previous                      \n"             \
+		"7:                             \n"             \
+		: "=r"(size), "=r" (__d0), "=r"(zvalue), "=r"(tmp) \
+		: "0"(size), "1"(addr), "2"(0)                  \
+		: "memory"                                      \
+	);                                                      \
+} while (0)
+
+/*
+ * clear_user: - Zero a block of memory in user space.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */	
+unsigned long 
+clear_user(void __user *to, unsigned long n)
+{
+	if (access_ok(VERIFY_WRITE, to, n))
+		__do_clear_user(to, n);
+	return n;
+}
+EXPORT_SYMBOL(clear_user);
+
+/*
+ * __clear_user: - Zero a block of memory in user space, with less checking.
+ * @to:   Destination address, in user space.
+ * @n:    Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.  Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
+unsigned long
+__clear_user(void __user *to, unsigned long n)
+{
+	__do_clear_user(to, n);
+	return n;
+}
+EXPORT_SYMBOL(__clear_user);
+
diff --git a/arch/csky/oprofile/init.c b/arch/csky/oprofile/init.c
new file mode 100644
index 0000000..413ad18
--- /dev/null
+++ b/arch/csky/oprofile/init.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/oprofile.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+int __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	return oprofile_perf_init(ops);
+}
+
+void oprofile_arch_exit(void)
+{
+	oprofile_perf_exit();
+}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 12/19] csky: Debug and Ptrace GDB
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (10 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 11/19] csky: Library functions Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-26 13:06   ` Arnd Bergmann
  2018-03-18 19:51 ` [PATCH 13/19] csky: User access Guo Ren
                   ` (8 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/include/uapi/asm/ptrace.h |  97 +++++++++++
 arch/csky/kernel/dumpstack.c        |  65 +++++++
 arch/csky/kernel/ptrace.c           | 339 ++++++++++++++++++++++++++++++++++++
 3 files changed, 501 insertions(+)
 create mode 100644 arch/csky/include/uapi/asm/ptrace.h
 create mode 100644 arch/csky/kernel/dumpstack.c
 create mode 100644 arch/csky/kernel/ptrace.c

diff --git a/arch/csky/include/uapi/asm/ptrace.h b/arch/csky/include/uapi/asm/ptrace.h
new file mode 100644
index 0000000..b8516b2
--- /dev/null
+++ b/arch/csky/include/uapi/asm/ptrace.h
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef _CSKY_PTRACE_H
+#define _CSKY_PTRACE_H
+
+#define REGNO_SR   	32
+#define REGNO_PC   	33
+
+#ifndef __ASSEMBLY__
+
+/* this struct defines the way the registers are stored on the
+   stack during a system call. */
+struct  pt_regs {
+	unsigned long    pc;
+	long             orig_a0;
+	unsigned long    sr;
+	long             a0;  // ABIV2: r0, ABIV1: r2
+	long             a1;  // ABIV2: r1, ABIV1: r3
+	long             a2;  // ABIV2: r2, ABIV1: r4
+	long             a3;  // ABIV2: r3, ABIV1: r5
+	// ABIV2: r4 ~ r13,  ABIV1: r6 ~ r14, r1.
+	long             regs[10];
+	long             r15;
+#if defined(__CSKYABIV2__)
+	// r16~r31;
+	long             exregs[16];
+	long             rhi;
+	long             rlo;
+#endif
+};
+
+/*
+ * Switch stack for switch_to after push pt_regs.
+ *
+ * ABI_CSKYV2: r4 ~ r11, r15 ~ r17, r26 ~ r30;
+ * ABI_CSKYV1: r8 ~ r14, r15;
+ */
+struct  switch_stack {
+#if defined(__CSKYABIV2__)
+	unsigned long   r4;
+        unsigned long   r5;
+        unsigned long   r6;
+        unsigned long   r7;
+	unsigned long   r8;
+        unsigned long   r9;
+        unsigned long   r10;
+        unsigned long   r11;
+#else
+	unsigned long   r8;
+        unsigned long   r9;
+        unsigned long   r10;
+        unsigned long   r11;
+        unsigned long   r12;
+        unsigned long   r13;
+        unsigned long   r14;
+#endif
+        unsigned long   r15;
+#if defined(__CSKYABIV2__)
+        unsigned long   r16;
+        unsigned long   r17;
+        unsigned long   r26;
+        unsigned long   r27;
+        unsigned long   r28;
+        unsigned long   r29;
+        unsigned long   r30;
+#endif
+};
+
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_GET_THREAD_AREA    25
+
+#define CSKY_GREG_NUM             35
+#define CSKY_FREG_NUM_HI          72
+#define CSKY_FREG_NUM_LO          40
+#define CSKY_FCR_NUM              74
+
+#ifdef __KERNEL__
+
+#define PS_S            0x80000000              /* Supervisor Mode */
+
+#define arch_has_single_step() (1)
+#define current_pt_regs() \
+	(struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1
+#define current_user_stack_pointer() rdusp()
+
+#define user_mode(regs) (!((regs)->sr & PS_S))
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+
+void show_regs(struct pt_regs *);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _CSKY_PTRACE_H */
diff --git a/arch/csky/kernel/dumpstack.c b/arch/csky/kernel/dumpstack.c
new file mode 100644
index 0000000..d4be08a
--- /dev/null
+++ b/arch/csky/kernel/dumpstack.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/ptrace.h>
+
+int kstack_depth_to_print = 48;
+
+void show_trace(unsigned long *stack)
+{
+	unsigned long *endstack;
+	unsigned long addr;
+	int i;
+
+	pr_info("Call Trace:");
+	addr = (unsigned long)stack + THREAD_SIZE - 1;
+	endstack = (unsigned long *)(addr & -THREAD_SIZE);
+	i = 0;
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (__kernel_text_address(addr)) {
+#ifndef CONFIG_KALLSYMS
+			if (i % 5 == 0)
+				pr_cont("\n       ");
+#endif
+			pr_cont(" [<%08lx>] %pS\n", addr, (void *)addr);
+			i++;
+		}
+	}
+	pr_cont("\n");
+}
+
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+	unsigned long *p;
+	unsigned long *endstack;
+	int i;
+
+	if (!stack) {
+		if (task)
+			stack = (unsigned long *)task->thread.esp0;
+		else
+			stack = (unsigned long *)&stack;
+	}
+	endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
+
+	pr_info("Stack from %08lx:", (unsigned long)stack);
+	p = stack;
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (p + 1 > endstack)
+			break;
+		if (i % 8 == 0)
+			pr_cont("\n       ");
+		pr_cont(" %08lx", *p++);
+	}
+	pr_cont("\n");
+	show_trace(stack);
+}
+
diff --git a/arch/csky/kernel/ptrace.c b/arch/csky/kernel/ptrace.c
new file mode 100644
index 0000000..9aee8b5
--- /dev/null
+++ b/arch/csky/kernel/ptrace.c
@@ -0,0 +1,339 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/signal.h>
+#include <linux/uaccess.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+
+#include <abi/regdef.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* sets the trace bits. */
+#define TRACE_MODE_SI      1 << 14
+#define TRACE_MODE_RUN     0
+#define TRACE_MODE_JMP     0x3 << 14
+#define TRACE_MODE_MASK    ~(0x3 << 14)
+
+/*
+ * PT_xxx is the stack offset at which the register is  saved.
+ * Notice that usp has no stack-slot and needs to be treated
+ * specially (see get_reg/put_reg below).
+ */
+static int regoff[] = PTRACE_REGOFF_ABI;
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static long get_reg(struct task_struct *task, int regno)
+{
+	unsigned long *addr;
+
+	if (regno == REGNO_USP)
+		addr = &task->thread.usp;
+	else if ((regno < sizeof(regoff)/sizeof(regoff[0])) && (regoff[regno] != -1))
+		addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+	else
+		return 0;
+	return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static int put_reg(struct task_struct *task, int regno,
+		unsigned long data)
+{
+	unsigned long *addr;
+
+	if (regno == REGNO_USP)
+		addr = &task->thread.usp;
+	else if ((regno < sizeof(regoff) / sizeof(regoff[0])) && (regoff[regno] != -1))
+		addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
+	else
+		return -1;
+	*addr = data;
+	return 0;
+}
+/*
+ * Make sure the single step bit is not set.
+ */
+static void singlestep_disable(struct task_struct *child)
+{
+	unsigned long tmp;
+	tmp = (get_reg(child, REGNO_SR) & TRACE_MODE_MASK) | TRACE_MODE_RUN;
+	put_reg(child, REGNO_SR, tmp);
+}
+
+
+static void singlestep_enable(struct task_struct *child)
+{
+	unsigned long tmp;
+	tmp = (get_reg(child, REGNO_SR) & TRACE_MODE_MASK) | TRACE_MODE_SI;
+	put_reg(child, REGNO_SR, tmp);
+}
+
+/*
+ * Make sure the single step bit is set.
+ */
+void user_enable_single_step(struct task_struct *child)
+{
+	if (child->thread.esp0 == 0) return;
+	singlestep_enable(child);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+	if (child->thread.esp0 == 0) return;
+	singlestep_disable(child);
+}
+
+int ptrace_getfpregs(struct task_struct *child, void __user *data)
+{
+
+	if (!access_ok(VERIFY_WRITE, data, sizeof(struct user_cskyfp_struct)))
+		return -EIO;
+
+	if(raw_copy_to_user(data, &child->thread.fcr,
+				sizeof(struct user_cskyfp_struct)))
+		return -EFAULT;
+
+	return 0;
+}
+
+int ptrace_setfpregs(struct task_struct *child, void __user *data)
+{
+	if (!access_ok(VERIFY_READ, data, sizeof(struct user_cskyfp_struct)))
+		return -EIO;
+
+	if(raw_copy_from_user(&child->thread.fcr, data,
+				sizeof(struct user_cskyfp_struct)))
+		return -EFAULT;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	singlestep_disable(child);
+}
+
+/*
+ * Handle the requests of ptrace system call.
+ *
+ * INPUT:
+ * child   - process being traced.
+ * request - request type.
+ * addr    - address of data that this request to read from or write to.
+ * data    - address of data that this request to read to or write from.
+ *
+ * RETURN:
+ * 0       - success
+ * others  - fail
+ */
+long arch_ptrace(struct task_struct *child, long request, unsigned long addr,
+		unsigned long data)
+{
+	unsigned long tmp = 0, ret = 0;
+	int i;
+
+	switch (request) {
+		/* read the word at location addr in the USER area. */
+	case PTRACE_PEEKUSR:
+		if (addr & 3)
+			goto out_eio;
+		addr >>= 2;     /* temporary hack. */
+
+		if (addr >= 0 && addr <= CSKY_GREG_NUM) {
+			tmp = get_reg(child, addr);
+		}else if(addr >= CSKY_FREG_NUM_LO && addr < CSKY_FREG_NUM_HI) {
+			tmp = child->thread.fp[addr - CSKY_FREG_NUM_LO];
+		}else if(addr >= CSKY_FREG_NUM_HI && addr < CSKY_FCR_NUM) {
+			tmp = (&(child->thread.fcr))[addr - CSKY_FREG_NUM_HI];
+		} else
+			break;
+		ret = put_user(tmp,(long unsigned int *) data);
+		break;
+
+	case PTRACE_POKEUSR:  /* write the word at location addr in the USER area */
+		if (addr & 3)
+			goto out_eio;
+		addr >>= 2;     /* temporary hack. */
+
+		if (addr >= 0 && addr <= CSKY_GREG_NUM) {
+			if (put_reg(child, addr, data)) /*** should protect 'psr'? ***/
+				goto out_eio;
+		}else if(addr >= CSKY_FREG_NUM_LO && addr < CSKY_FREG_NUM_HI) {
+			child->thread.fp[addr - CSKY_FREG_NUM_LO] = data;
+		}else if(addr >= CSKY_FREG_NUM_HI && addr <= CSKY_FCR_NUM) {
+			(&(child->thread.fcr))[addr - CSKY_FREG_NUM_HI] = data;
+		}else
+			goto out_eio;
+		break;
+	case PTRACE_GETREGS:    /* Get all gp regs from the child. */
+		for (i = 0; i <= CSKY_GREG_NUM; i++) {
+			tmp = get_reg(child, i);
+			ret = put_user(tmp, (unsigned long *)data);
+			if (ret)
+				break;
+			data += sizeof(long);
+		}
+		break;
+	case PTRACE_SETREGS:    /* Set all gp regs in the child. */
+		for (i = 0; i <= CSKY_GREG_NUM; i++) {
+			ret = get_user(tmp, (unsigned long *)data);
+			if (ret)
+				break;
+			put_reg(child, i, tmp);
+			data += sizeof(long);
+		}
+		break;
+
+	case PTRACE_GETFPREGS:
+		ret = ptrace_getfpregs(child, (void  __user *) data);
+		break;
+
+	case PTRACE_SETFPREGS:
+		ret = ptrace_setfpregs(child, (void __user *) data);
+		break;
+
+	case PTRACE_GET_THREAD_AREA:
+		ret = put_user(task_thread_info(child)->tp_value,
+				(long unsigned int *) data);
+		break;
+	default:
+		ret = ptrace_request(child, request, addr, data);
+		break;
+	}
+
+	return ret;
+out_eio:
+	return -EIO;
+}
+
+/*
+ * If process's system calls is traces, do some corresponding handles in this
+ * fuction before entering system call function and after exiting system call
+ * fuction.
+ */
+asmlinkage void syscall_trace(int why, struct pt_regs * regs)
+{
+	long saved_why;
+	/*
+	 * Save saved_why, why is used to denote syscall entry/exit;
+	 * why = 0:entry, why = 1: exit
+	 */
+	saved_why = regs->regs[SYSTRACE_SAVENUM];
+	regs->regs[SYSTRACE_SAVENUM] = why;
+
+	/* the 0x80 provides a way for the tracing parent to distinguish
+	   between a syscall stop and SIGTRAP delivery */
+	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
+				? 0x80 : 0));
+	/*
+	 * this isn't the same as continuing with a signal, but it will do
+	 * for normal use.  strace only continues with a signal if the
+	 * stopping signal is not SIGTRAP.  -brl
+	 */
+	if (current->exit_code) {
+		send_sig(current->exit_code, current, 1);
+		current->exit_code = 0;
+	}
+
+	regs->regs[SYSTRACE_SAVENUM] = saved_why;
+	return;
+}
+
+void show_regs(struct pt_regs *fp)
+{
+	unsigned long   *sp;
+	unsigned char   *tp;
+	int	i;
+
+	pr_info("\nCURRENT PROCESS:\n\n");
+	pr_info("COMM=%s PID=%d\n", current->comm, current->pid);
+
+	if (current->mm) {
+		pr_info("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
+		       (int) current->mm->start_code,
+		       (int) current->mm->end_code,
+		       (int) current->mm->start_data,
+		       (int) current->mm->end_data,
+		       (int) current->mm->end_data,
+		       (int) current->mm->brk);
+		pr_info("USER-STACK=%08x  KERNEL-STACK=%08x\n\n",
+		       (int) current->mm->start_stack,
+		       (int) (((unsigned long) current) + 2 * PAGE_SIZE));
+	}
+
+	pr_info("PC: 0x%08lx\n", (long)fp->pc);
+	pr_info("orig_a0: 0x%08lx\n", fp->orig_a0);
+	pr_info("PSR: 0x%08lx\n", (long)fp->sr);
+
+	pr_info("a0: 0x%08lx  a1: 0x%08lx  a2: 0x%08lx  a3: 0x%08lx\n",
+	       fp->a0, fp->a1, fp->a2, fp->a3);
+#if defined(__CSKYABIV2__)
+	pr_info("r4: 0x%08lx  r5: 0x%08lx    r6: 0x%08lx    r7: 0x%08lx\n",
+	       fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]);
+	pr_info("r8: 0x%08lx  r9: 0x%08lx   r10: 0x%08lx   r11: 0x%08lx\n",
+	       fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]);
+	pr_info("r12 0x%08lx  r13: 0x%08lx   r15: 0x%08lx\n",
+	       fp->regs[8], fp->regs[9], fp->r15);
+	pr_info("r16:0x%08lx   r17: 0x%08lx   r18: 0x%08lx    r19: 0x%08lx\n",
+	       fp->exregs[0], fp->exregs[1], fp->exregs[2], fp->exregs[3]);
+	pr_info("r20 0x%08lx   r21: 0x%08lx   r22: 0x%08lx    r23: 0x%08lx\n",
+	       fp->exregs[4], fp->exregs[5], fp->exregs[6], fp->exregs[7]);
+	pr_info("r24 0x%08lx   r25: 0x%08lx   r26: 0x%08lx    r27: 0x%08lx\n",
+	       fp->exregs[8], fp->exregs[9], fp->exregs[10], fp->exregs[11]);
+	pr_info("r28 0x%08lx   r29: 0x%08lx   r30: 0x%08lx    r31: 0x%08lx\n",
+	       fp->exregs[12], fp->exregs[13], fp->exregs[14], fp->exregs[15]);
+	pr_info("hi 0x%08lx     lo: 0x%08lx \n",
+	       fp->rhi, fp->rlo);
+#else
+	pr_info("r6: 0x%08lx   r7: 0x%08lx   r8: 0x%08lx   r9: 0x%08lx\n",
+	       fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]);
+	pr_info("r10: 0x%08lx   r11: 0x%08lx   r12: 0x%08lx   r13: 0x%08lx\n",
+	       fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]);
+	pr_info("r14 0x%08lx   r1: 0x%08lx   r15: 0x%08lx\n",
+	       fp->regs[8], fp->regs[9], fp->r15);
+#endif
+
+	pr_info("\nCODE:");
+	tp = ((unsigned char *) fp->pc) - 0x20;
+	tp += ((int)tp % 4) ? 2 : 0;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x40);  i += 4) {
+		if ((i % 0x10) == 0)
+			pr_cont("\n%08x: ", (int) (tp + i));
+		pr_cont("%08x ", (int) *sp++);
+	}
+	pr_cont("\n");
+
+	pr_info("\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			pr_cont("\n%08x: ", (int) (tp + i));
+		pr_cont("%08x ", (int) *sp++);
+	}
+	pr_cont("\n");
+
+	return;
+}
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 13/19] csky: User access
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (11 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 12/19] csky: Debug and Ptrace GDB Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 19:51 ` [PATCH 14/19] csky: Misc headers Guo Ren
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/include/asm/uaccess.h | 408 ++++++++++++++++++++++++++++++++++++++++
 arch/csky/include/asm/user.h    | 102 ++++++++++
 2 files changed, 510 insertions(+)
 create mode 100644 arch/csky/include/asm/uaccess.h
 create mode 100644 arch/csky/include/asm/user.h

diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h
new file mode 100644
index 0000000..b3c3599
--- /dev/null
+++ b/arch/csky/include/asm/uaccess.h
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_UACCESS_H
+#define __ASM_CSKY_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/compiler.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <asm/segment.h>
+
+#define VERIFY_READ	0
+#define VERIFY_WRITE	1
+
+static inline int access_ok(int type, const void * addr, unsigned long size)
+{
+    return (((unsigned long)addr < current_thread_info()->addr_limit.seg) &&
+              ((unsigned long)(addr + size) < current_thread_info()->addr_limit.seg));
+}
+
+static inline int verify_area(int type, const void * addr, unsigned long size)
+{
+    return access_ok(type, addr, size) ? 0 : -EFAULT;
+}
+
+#define __addr_ok(addr) (access_ok(VERIFY_READ, addr,0))
+
+extern int __put_user_bad(void);
+
+/*
+ * Tell gcc we read from memory instead of writing: this is because
+ * we do not write to any memory gcc knows about, so there are no
+ * aliasing issues.
+ */
+
+/*
+ * These are the main single-value transfer routines.  They automatically
+ * use the right size if we just have the right pointer type.
+ *
+ * This gets kind of ugly. We want to return _two_ values in "get_user()"
+ * and yet we don't want to do any pointers, because that is too much
+ * of a performance impact. Thus we have a few rather ugly macros here,
+ * and hide all the ugliness from the user.
+ *
+ * The "__xxx" versions of the user access functions are versions that
+ * do not verify the address space, that must have been done previously
+ * with a separate "access_ok()" call (this is used when we do multiple
+ * accesses to the same area of user memory).
+ *
+ * As we use the same address space for kernel and user data on
+ * Ckcore, we can just do these as direct assignments.  (Of course, the
+ * exception handling means that it's no longer "just"...)
+ */
+
+#define put_user(x,ptr) \
+  __put_user_check((x), (ptr), sizeof(*(ptr)))
+
+#define __put_user(x,ptr) \
+  __put_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+#define __ptr(x) ((unsigned long *)(x))
+
+#define get_user(x,ptr) \
+  __get_user_check((x), (ptr), sizeof(*(ptr)))
+
+#define __get_user(x,ptr) \
+  __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+
+#define __put_user_nocheck(x, ptr, size)                                \
+({                                                                      \
+	long __pu_err=0;                                                \
+	typeof(*(ptr)) *__pu_addr = (ptr);                              \
+	typeof(*(ptr)) __pu_val = (typeof(*(ptr)))(x);                  \
+	if(__pu_addr){                                                  \
+	    __put_user_size(__pu_val, (__pu_addr), (size), __pu_err);   \
+	}                                                               \
+	__pu_err;                                                       \
+})
+
+#define __put_user_check(x,ptr,size)                                    \
+({                                                                      \
+	long __pu_err = -EFAULT;                                        \
+	typeof(*(ptr)) *__pu_addr = (ptr);                              \
+	typeof(*(ptr)) __pu_val = (typeof(*(ptr)))(x);                  \
+	if (access_ok(VERIFY_WRITE, __pu_addr, size) && __pu_addr)      \
+		__put_user_size(__pu_val, __pu_addr, (size), __pu_err); \
+	__pu_err;                                                       \
+})
+
+#define __put_user_size(x,ptr,size,retval)                              \
+do {                                                                    \
+	retval = 0;                                                     \
+	switch (size) {                                                 \
+		case 1: __put_user_asm_b(x, ptr, retval); break;        \
+		case 2: __put_user_asm_h(x, ptr, retval); break;        \
+		case 4: __put_user_asm_w(x, ptr, retval); break;        \
+		case 8: __put_user_asm_64(x, ptr, retval); break;       \
+		default: __put_user_bad();                              \
+	}	                                                        \
+} while (0)
+
+/*
+ * We don't tell gcc that we are accessing memory, but this is OK
+ * because we do not write to any memory gcc knows about, so there
+ * are no aliasing issues.
+ *
+ * Note that PC at a fault is the address *after* the faulting
+ * instruction.
+ */
+#define __put_user_asm_b(x, ptr, err)                           \
+do{                                                             \
+	int errcode;                                            \
+	asm volatile(                                           \
+	         "1:     stb   %1, (%2,0)        \n"            \
+	         "       br    3f                \n"            \
+	         "2:     mov   %0, %3            \n"            \
+	         "       br    3f                \n"            \
+	         ".section __ex_table,\"a\"      \n"            \
+	         ".align   2                     \n"            \
+	         ".long    1b,2b                 \n"            \
+	         ".previous                      \n"            \
+	          "3:                            \n"            \
+	         : "=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode) \
+	         : "0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)     \
+	         : "memory");                                   \
+}while(0)
+
+#define __put_user_asm_h(x, ptr, err)                           \
+do{                                                             \
+	int errcode;                                            \
+	asm volatile(                                           \
+	         "1:     sth   %1, (%2,0)        \n"            \
+	         "       br    3f                \n"            \
+	         "2:     mov   %0, %3            \n"            \
+	         "       br    3f                \n"            \
+	         ".section __ex_table,\"a\"      \n"            \
+	         ".align   2                     \n"            \
+	         ".long    1b,2b                 \n"            \
+	         ".previous                      \n"            \
+	          "3:                            \n"            \
+	         :"=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
+	         :"0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
+	         : "memory");                                   \
+}while(0)
+
+#define __put_user_asm_w(x, ptr, err)                           \
+do{                                                             \
+	int errcode;                                            \
+	asm volatile(                                           \
+	         "1:     stw   %1, (%2,0)        \n"            \
+	         "       br    3f                \n"            \
+	         "2:     mov   %0, %3            \n"            \
+	         "       br    3f                \n"            \
+	         ".section __ex_table,\"a\"      \n"            \
+	         ".align   2                     \n"            \
+	         ".long    1b,2b                 \n"            \
+	         ".previous                      \n"            \
+	          "3:                            \n"            \
+	         :"=r"(err), "=r"(x), "=r"(ptr), "=r"(errcode)  \
+	         :"0"(err), "1"(x), "2"(ptr), "3"(-EFAULT)      \
+	         : "memory");                                   \
+}while(0)
+
+
+#define __put_user_asm_64(x, ptr, err)                          \
+do{                                                             \
+	int tmp;                                                \
+	int errcode;                                            \
+	typeof(*(ptr)) src = ( typeof(*(ptr)))x;                \
+	typeof(*(ptr)) *psrc = &src;                            \
+	                                                        \
+	asm volatile(                                           \
+	        "     ldw     %3, (%1, 0)     \n"               \
+	        "1:   stw     %3, (%2, 0)     \n"               \
+	        "     ldw     %3, (%1, 4)     \n"               \
+	        "2:   stw     %3, (%2, 4)     \n"               \
+	        "     br      4f              \n"               \
+	        "3:   mov     %0, %4          \n"               \
+	        "     br      4f              \n"               \
+	        ".section __ex_table, \"a\"   \n"               \
+	        ".align   2                   \n"               \
+	        ".long    1b, 3b              \n"               \
+	        ".long    2b, 3b              \n"               \
+	        ".previous                    \n"               \
+	        "4:                           \n"               \
+	        :"=r"(err),"=r"(psrc),"=r"(ptr),"=r"(tmp),"=r"(errcode) \
+	        : "0"(err), "1"(psrc), "2"(ptr), "3"(0), "4"(-EFAULT) \
+	        : "memory" );                                   \
+}while (0)
+
+#define __get_user_nocheck(x, ptr, size)                        \
+({                                                              \
+	long  __gu_err;	                                        \
+	__get_user_size(x, (ptr), (size), __gu_err);            \
+	__gu_err;                                               \
+})
+
+#define __get_user_check(x, ptr, size)                          \
+({                                                              \
+	int __gu_err = -EFAULT;	                                \
+	const __typeof__(*(ptr)) __user * __gu_ptr = (ptr);     \
+	if (access_ok(VERIFY_READ, __gu_ptr, size) && __gu_ptr) \
+		__get_user_size(x, __gu_ptr, (size), __gu_err); \
+	__gu_err;                                               \
+})
+
+#define __get_user_size(x, ptr, size, retval)                   \
+do {                                                            \
+	switch (size) {                                         \
+		case 1: __get_user_asm_common((x),ptr,"ldb",retval); break; \
+		case 2: __get_user_asm_common((x),ptr,"ldh",retval); break; \
+		case 4: __get_user_asm_common((x),ptr,"ldw",retval); break; \
+		default:                                        \
+			x=0;                                    \
+			(retval) = __get_user_bad();            \
+	}                                                       \
+} while (0)
+
+#define __get_user_asm_common(x, ptr, ins, err)                 \
+do{                                                             \
+	int errcode;                                            \
+	asm volatile(                                           \
+	        "1:   " ins "   %1, (%4,0)      \n"             \
+	        "       br    3f                \n"             \
+	        /* Fix up codes */                              \
+	        "2:     mov   %0, %2            \n"             \
+	        "       movi  %1, 0             \n"             \
+	        "       br    3f                \n"             \
+	        ".section __ex_table,\"a\"      \n"             \
+	        ".align   2                     \n"             \
+	        ".long    1b,2b                 \n"             \
+	        ".previous                      \n"             \
+	        "3:                            \n"              \
+	        :"=r"(err), "=r"(x), "=r"(errcode)              \
+	        :"0"(0), "r"(ptr), "2"(-EFAULT)                 \
+	        : "memory");                                    \
+}while(0)
+
+extern int __get_user_bad(void);
+
+#define __copy_user(to, from, n)                                \
+do{                                                             \
+	int w0, w1, w2, w3;                                     \
+	asm volatile(                                           \
+		"0:     cmpnei  %1, 0           \n"             \
+		"       bf      8f              \n"             \
+		"       mov     %3, %1          \n"             \
+		"       or      %3, %2          \n"             \
+		"       andi    %3, 3           \n"             \
+		"       cmpnei  %3, 0           \n"             \
+		"       bf      1f              \n"             \
+		"       br      5f              \n"             \
+		"1:     cmplti  %0, 16          \n"   /* 4W */  \
+		"       bt      3f              \n"             \
+		"       ldw     %3, (%2, 0)     \n"             \
+		"       ldw     %4, (%2, 4)     \n"             \
+		"       ldw     %5, (%2, 8)     \n"             \
+		"       ldw     %6, (%2, 12)    \n"             \
+		"2:     stw     %3, (%1, 0)     \n"             \
+		"9:     stw     %4, (%1, 4)     \n"             \
+		"10:    stw     %5, (%1, 8)     \n"             \
+		"11:    stw     %6, (%1, 12)    \n"             \
+		"       addi    %2, 16          \n"             \
+		"       addi    %1, 16          \n"             \
+		"       subi    %0, 16          \n"             \
+		"       br      1b              \n"             \
+		"3:     cmplti  %0, 4           \n"  /* 1W */   \
+		"       bt      5f              \n"             \
+		"       ldw     %3, (%2, 0)     \n"             \
+		"4:     stw     %3, (%1, 0)     \n"             \
+		"       addi    %2, 4           \n"             \
+		"       addi    %1, 4           \n"             \
+		"       subi    %0, 4           \n"             \
+		"       br      3b              \n"             \
+		"5:     cmpnei  %0, 0           \n"  /* 1B */   \
+		"       bf      8f              \n"             \
+		"       ldb     %3, (%2, 0)     \n"             \
+		"6:     stb     %3, (%1, 0)     \n"             \
+		"       addi    %2,  1          \n"             \
+		"       addi    %1,  1          \n"             \
+		"       subi    %0,  1          \n"             \
+		"       br      5b              \n"             \
+		"7:     br      8f              \n"             \
+		".section __ex_table, \"a\"     \n"             \
+		".align   2                     \n"             \
+		".long    2b, 7b                \n"             \
+		".long    9b, 7b                \n"             \
+		".long   10b, 7b                \n"             \
+		".long   11b, 7b                \n"             \
+		".long    4b, 7b                \n"             \
+		".long    6b, 7b                \n"             \
+		".previous                      \n"             \
+		"8:                             \n"             \
+	        : "=r"(n), "=r"(to), "=r"(from), "=r"(w0), "=r"(w1), "=r"(w2), "=r"(w3)   \
+		: "0"(n), "1"(to), "2"(from)                    \
+		: "memory" );                                   \
+} while (0)
+
+#define __copy_user_zeroing(to, from, n) \
+do{                                                             \
+	int tmp;                                                \
+	int nsave;                                              \
+	asm volatile(                                           \
+		"0:     cmpnei  %1, 0           \n"             \
+		"       bf      7f              \n"             \
+		"       mov     %3, %1          \n"             \
+		"       or      %3, %2          \n"             \
+		"       andi    %3, 3           \n"             \
+		"       cmpnei  %3, 0           \n"             \
+		"       bf      1f              \n"             \
+		"       br      5f              \n"             \
+		"1:     cmplti  %0, 16          \n"   /* 4W */  \
+		"       bt      3f              \n"             \
+		"2:     ldw     %3, (%2, 0)     \n"             \
+		"10:    ldw     %4, (%2, 4)     \n"             \
+		"       stw     %3, (%1, 0)     \n"             \
+		"       stw     %4, (%1, 4)     \n"             \
+		"11:    ldw     %3, (%2, 8)     \n"             \
+		"12:    ldw     %4, (%2, 12)    \n"             \
+		"       stw     %3, (%1, 8)     \n"             \
+		"       stw     %4, (%1, 12)    \n"             \
+		"       addi    %2, 16          \n"             \
+		"       addi    %1, 16          \n"             \
+		"       subi    %0, 16          \n"             \
+		"       br      1b              \n"             \
+		"3:     cmplti  %0, 4           \n"  /* 1W */   \
+		"       bt      5f              \n"             \
+		"4:     ldw     %3, (%2, 0)     \n"             \
+		"       stw     %3, (%1, 0)     \n"             \
+		"       addi    %2, 4           \n"             \
+		"       addi    %1, 4           \n"             \
+		"       subi    %0, 4           \n"             \
+		"       br      3b              \n"             \
+		"5:     cmpnei  %0, 0           \n"  /* 1B */   \
+		"       bf      7f              \n"             \
+		"6:     ldb     %3, (%2, 0)     \n"             \
+		"       stb     %3, (%1, 0)     \n"             \
+		"       addi    %2,  1          \n"             \
+		"       addi    %1,  1          \n"             \
+		"       subi    %0,  1          \n"             \
+		"       br      5b              \n"             \
+		"8:     mov     %3, %0          \n" /* zero */  \
+		"       movi    %4, 0           \n"             \
+		"9:     stb     %4, (%1, 0)     \n"             \
+		"       addi    %1, 1           \n"             \
+		"       subi    %3, 1           \n"             \
+		"       cmpnei  %3, 0           \n"             \
+		"       bt      9b              \n"             \
+		"       br      7f              \n"             \
+		".section __ex_table, \"a\"     \n"             \
+		".align   2                     \n"             \
+		".long    2b, 8b                \n"             \
+		".long   10b, 8b                \n"             \
+		".long   11b, 8b                \n"             \
+		".long   12b, 8b                \n"             \
+		".long    4b, 8b                \n"             \
+		".long    6b, 8b                \n"             \
+		".previous                      \n"             \
+		"7:                             \n"             \
+		: "=r"(n), "=r"(to), "=r"(from), "=r"(nsave), "=r"(tmp)   \
+		: "0"(n), "1"(to), "2"(from)                    \
+		: "memory" );                                   \
+} while (0)
+
+unsigned long raw_copy_from_user(void *to, const void *from, unsigned long n);
+unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n);
+
+#ifdef COMPAT_KERNEL_4_9
+#define __copy_from_user(to, from, n) raw_copy_from_user(to, from, n)
+#define __copy_to_user(to, from, n) raw_copy_to_user(to, from, n)
+
+#define __copy_from_user_inatomic	__copy_from_user
+#define __copy_to_user_inatomic		__copy_to_user
+
+#define copy_from_user			__copy_from_user
+#define copy_to_user			__copy_to_user
+#endif
+
+unsigned long clear_user(void *to, unsigned long n);
+unsigned long __clear_user(void __user *to, unsigned long n);
+
+long strncpy_from_user(char *dst, const char *src, long count);
+long __strncpy_from_user(char *dst, const char *src, long count);
+
+/*
+ * Return the size of a string (including the ending 0)
+ *
+ * Return 0 on exception, a value greater than N if too long
+ */
+long strnlen_user(const char *src, long n);
+
+#define strlen_user(str) strnlen_user(str, 32767)
+
+struct exception_table_entry
+{
+	unsigned long insn;
+	unsigned long nextinsn;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#endif /* __ASM_CSKY_UACCESS_H */
diff --git a/arch/csky/include/asm/user.h b/arch/csky/include/asm/user.h
new file mode 100644
index 0000000..8ca8a12
--- /dev/null
+++ b/arch/csky/include/asm/user.h
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_USER_H
+#define __ASM_CSKY_USER_H
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+/*
+ *  Core file format: The core file is written in such a way that gdb
+ *  can understand it and provide useful information to the user (under
+ *  linux we use the 'trad-core' bfd).  There are quite a number of
+ *  obstacles to being able to view the contents of the floating point
+ *  registers, and until these are solved you will not be able to view the
+ *  contents of them.  Actually, you can read in the core file and look at
+ *  the contents of the user struct to find out what the floating point
+ *  registers contain.
+ *  The actual file contents are as follows:
+ *  UPAGE: 1 page consisting of a user struct that tells gdb what is present
+ *  in the file.  Directly after this is a copy of the task_struct, which
+ *  is currently not used by gdb, but it may come in useful at some point.
+ *  All of the registers are stored as part of the upage.  The upage should
+ *  always be only one page.
+ *  DATA: The data area is stored.  We use current->end_text to
+ *  current->brk to pick up all of the user variables, plus any memory
+ *  that may have been malloced.  No attempt is made to determine if a page
+ *  is demand-zero or if a page is totally unused, we just cover the entire
+ *  range.  All of the addresses are rounded in such a way that an integral
+ *  number of pages is written.
+ *  STACK: We need the stack information in order to get a meaningful
+ *  backtrace.  We need to write the data from (esp) to
+ *  current->start_stack, so we round each of these off in order to be able
+ *  to write an integer number of pages.
+ *  The minimum core file size is 3 pages, or 12288 bytes.
+ */
+
+struct user_cskyfp_struct {
+	unsigned long  fcr;         /* fpu control reg */
+	unsigned long  fsr;         /* fpu status reg, nothing in CPU_CSKYV2 */
+	unsigned long  fesr;        /* fpu exception status reg */
+	unsigned long  fp[32];      /* fpu general regs */
+};
+
+/*
+ * This is the old layout of "struct pt_regs" as of Linux 1.x, and
+ * is still the layout used by user (the new pt_regs doesn't have
+ * all registers).
+ *
+ * In this struct, both ABIV1 & ABIV2 have the same general regs:
+ * CSKY ABIv1: r0 ~ r31, psr, pc, hi, lo
+ * CSKY ABIv2: r0 ~ r31, psr, pc, hi, lo
+ * but in CSKY ABIV1, r16 ~ r31 don't exist, so in ABIV1, they are zero.
+ */
+struct user_regs_struct {
+      unsigned long	gregs[32];  // ABIV1, usp = r0; ABIV2, usp = r14
+      unsigned long	psr;
+      unsigned long	pc;
+      unsigned long	hi;
+      unsigned long	lo;
+};
+
+/* user_regs_struct->gregs[REG_WHY].
+ * flag: 0: enter system call
+ *       1: leave system call
+ */
+#define REG_WHY  9
+
+/*
+ * When the kernel dumps core, it starts by dumping the user struct -
+ * this will be used by gdb to figure out where the data and stack segments
+ * are within the file, and what virtual addresses to use.
+ */
+struct user{
+/* We start with the registers, to mimic the way that "memory" is returned
+   from the ptrace(3,...) function.  */
+	struct user_regs_struct  regs;	/* Where the registers are actually stored */
+	int                 u_fpvalid;  /* True if math co-processor being used. */
+
+/* The rest of this junk is to help gdb figure out what goes where */
+	unsigned long int   u_tsize;	/* Text segment size (pages). */
+	unsigned long int   u_dsize;	/* Data segment size (pages). */
+	unsigned long int   u_ssize;	/* Stack segment size (pages). */
+	unsigned long       start_code; /* Starting virtual address of text. */
+	unsigned long       start_stack;/* Starting virtual address of stack area.
+				   					   This is actually the bottom of the stack,
+				      				   the top of the stack is always found in
+									    the esp register.  */
+	long int            signal;     /* Signal that caused the core dump. */
+	int                 reserved;	/* No longer used */
+	unsigned long       u_ar0;		/* Used by gdb to help find the values
+										for the registers. */
+	unsigned long       magic;		/* To uniquely identify a core file */
+	char                u_comm[32];	/* User command that was responsible */
+	struct user_cskyfp_struct  u_fp;   /* Floating point registers */
+	struct user_cskyfp_struct* u_fpstate;	/* Math Co-processor pointer. */
+};
+
+#define NBPG 4096
+#define UPAGES 1
+#define HOST_TEXT_START_ADDR (u.start_code)
+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG)
+
+#endif /* __ASM_CSKY_USER_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 14/19] csky: Misc headers
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (12 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 13/19] csky: User access Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-19 16:11   ` Arnd Bergmann
  2018-03-18 19:51 ` [PATCH 15/19] csky: Build infrastructure Guo Ren
                   ` (6 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/abiv1/inc/abi/reg_ops.h      |  79 +++++++++
 arch/csky/abiv1/inc/abi/regdef.h       |  27 +++
 arch/csky/abiv2/inc/abi/fpu.h          | 296 +++++++++++++++++++++++++++++++++
 arch/csky/abiv2/inc/abi/reg_ops.h      |  86 ++++++++++
 arch/csky/abiv2/inc/abi/regdef.h       |  28 ++++
 arch/csky/include/uapi/asm/byteorder.h |  14 ++
 arch/csky/include/uapi/asm/fcntl.h     |  13 ++
 arch/csky/include/uapi/asm/stat.h      |  86 ++++++++++
 8 files changed, 629 insertions(+)
 create mode 100644 arch/csky/abiv1/inc/abi/reg_ops.h
 create mode 100644 arch/csky/abiv1/inc/abi/regdef.h
 create mode 100644 arch/csky/abiv2/inc/abi/fpu.h
 create mode 100644 arch/csky/abiv2/inc/abi/reg_ops.h
 create mode 100644 arch/csky/abiv2/inc/abi/regdef.h
 create mode 100644 arch/csky/include/uapi/asm/byteorder.h
 create mode 100644 arch/csky/include/uapi/asm/fcntl.h
 create mode 100644 arch/csky/include/uapi/asm/stat.h

diff --git a/arch/csky/abiv1/inc/abi/reg_ops.h b/arch/csky/abiv1/inc/abi/reg_ops.h
new file mode 100644
index 0000000..224acff
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/reg_ops.h
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_REG_OPS_H
+#define __ASM_REG_OPS_H
+
+static inline unsigned int mfcr_cpuidrr(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr13\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_hint(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr30\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_ccr(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr18\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_msa0(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"cprcr %0, cpcr30\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline void mtcr_msa0(unsigned int value)
+{
+	asm volatile(
+		"cpwcr %0, cpcr30\t\n"
+		::"r"(value));
+}
+
+static inline unsigned int mfcr_msa1(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"cprcr %0, cpcr31\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline void mtcr_msa1(unsigned int value)
+{
+	asm volatile(
+		"cpwcr %0, cpcr31\t\n"
+		::"r"(value));
+}
+
+static inline unsigned int mfcr_ccr2(void){return 0;}
+
+/* read/write user stack pointer */
+static inline unsigned long rdusp(void) {
+	register unsigned long usp;
+	asm volatile("mfcr %0, ss1\n\r":"=r"(usp));
+	return usp;
+}
+
+static inline void wrusp(unsigned long usp) {
+	asm volatile("mtcr %0, ss1\n\r"::"r"(usp));
+}
+
+#endif /* __ASM_REG_OPS_H */
+
diff --git a/arch/csky/abiv1/inc/abi/regdef.h b/arch/csky/abiv1/inc/abi/regdef.h
new file mode 100644
index 0000000..f694e8e
--- /dev/null
+++ b/arch/csky/abiv1/inc/abi/regdef.h
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef  __ASM_CSKY_REGDEF_H
+#define  __ASM_CSKY_REGDEF_H
+
+#define syscallid	r1
+#define r11_sig		r11
+
+#define DEFAULT_PSR_VALUE	0x8f000000
+
+#define PTRACE_REGOFF_ABI \
+{ \
+	-1,       PT_REGS9,  PT_A0,    PT_A1,\
+	PT_A2,    PT_A3,     PT_REGS0, PT_REGS1,\
+	PT_REGS2, PT_REGS3,  PT_REGS4, PT_REGS5,\
+	PT_REGS6, PT_REGS7,  PT_REGS8, PT_R15,\
+	-1,       -1,        -1,       -1,\
+	-1,       -1,        -1,       -1,\
+	-1,       -1,        -1,       -1,\
+	-1,       -1,        -1,       -1,\
+	PT_SR,    PT_PC,     -1,       -1,\
+}
+
+#define SYSTRACE_SAVENUM	2
+#define REGNO_USP		0
+
+#endif /* __ASM_CSKY_REGDEF_H */
diff --git a/arch/csky/abiv2/inc/abi/fpu.h b/arch/csky/abiv2/inc/abi/fpu.h
new file mode 100644
index 0000000..5f82f04
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/fpu.h
@@ -0,0 +1,296 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_FPU_H
+#define __ASM_CSKY_FPU_H
+
+#ifndef __ASSEMBLY__ /* C source */
+
+#include <asm/sigcontext.h>
+#include <asm/ptrace.h>
+
+int fpu_libc_helper(struct pt_regs *regs);
+void fpu_fpe(struct pt_regs *regs);
+void __init init_fpu(void);
+
+int restore_fpu_state(struct sigcontext *sc);
+int save_fpu_state(struct sigcontext *sc, struct pt_regs *regs);
+
+/*
+ * Define the fesr bit for fpe handle.
+ */
+#define  FPE_ILLE  (1 << 16)    /* Illegal instruction  */
+#define  FPE_FEC   (1 << 7)     /* Input float-point arithmetic exception */
+#define  FPE_IDC   (1 << 5)     /* Input denormalized exception */
+#define  FPE_IXC   (1 << 4)     /* Inexact exception */
+#define  FPE_UFC   (1 << 3)     /* Underflow exception */
+#define  FPE_OFC   (1 << 2)     /* Overflow exception */
+#define  FPE_DZC   (1 << 1)     /* Divide by zero exception */
+#define  FPE_IOC   (1 << 0)     /* Invalid operation exception */
+#define  FPE_REGULAR_EXCEPTION (FPE_IXC | FPE_UFC | FPE_OFC | FPE_DZC | FPE_IOC)
+
+#ifdef CONFIG_OPEN_FPU_IDE
+#define IDE_STAT   (1 << 5)
+#else
+#define IDE_STAT   0
+#endif
+
+#ifdef CONFIG_OPEN_FPU_IXE
+#define IXE_STAT   (1 << 4)
+#else
+#define IXE_STAT   0
+#endif
+
+#ifdef CONFIG_OPEN_FPU_UFE
+#define UFE_STAT   (1 << 3)
+#else
+#define UFE_STAT   0
+#endif
+
+#ifdef CONFIG_OPEN_FPU_OFE
+#define OFE_STAT   (1 << 2)
+#else
+#define OFE_STAT   0
+#endif
+
+#ifdef CONFIG_OPEN_FPU_DZE
+#define DZE_STAT   (1 << 1)
+#else
+#define DZE_STAT   0
+#endif
+
+#ifdef CONFIG_OPEN_FPU_IOE
+#define IOE_STAT   (1 << 0)
+#else
+#define IOE_STAT   0
+#endif
+
+#define FMFS_FPU_REGS(frw, frx, fry, frz) \
+	"fmfs   %0, "#frw" \n" \
+	"fmfs   %1, "#frx" \n" \
+	"fmfs   %2, "#fry" \n" \
+	"fmfs   %3, "#frz" \n"
+
+#define FMTS_FPU_REGS(frw, frx, fry, frz) \
+	"fmts   %0, "#frw" \n" \
+	"fmts   %1, "#frx" \n" \
+	"fmts   %2, "#fry" \n" \
+	"fmts   %3, "#frz" \n"
+
+#define FMFVR_FPU_REGS(vrx, vry) \
+	"fmfvrl %0, "#vrx" \n" \
+	"fmfvrh %1, "#vrx" \n" \
+	"fmfvrl %2, "#vry" \n" \
+	"fmfvrh %3, "#vry" \n"
+
+#define FMTVR_FPU_REGS(vrx, vry) \
+	"fmtvrl "#vrx", %0 \n" \
+	"fmtvrh "#vrx", %1 \n" \
+	"fmtvrl "#vry", %2 \n" \
+	"fmtvrh "#vry", %3 \n"
+
+#define STW_FPU_REGS(a, b, c, d) \
+	"stw    %0, (%4, "#a") \n" \
+	"stw    %1, (%4, "#b") \n" \
+	"stw    %2, (%4, "#c") \n" \
+	"stw    %3, (%4, "#d") \n"
+
+#define LDW_FPU_REGS(a, b, c, d) \
+	"ldw    %0, (%4, "#a") \n" \
+	"ldw    %1, (%4, "#b") \n" \
+	"ldw    %2, (%4, "#c") \n" \
+	"ldw    %3, (%4, "#d") \n"
+
+static inline void save_fp_to_thread(unsigned long  * fpregs,
+	   unsigned long * fcr, unsigned long * fsr, unsigned long * fesr)
+{
+	unsigned long flg;
+	unsigned long tmp1, tmp2, tmp3, tmp4;
+
+	local_save_flags(flg);
+
+	asm volatile(
+		"mfcr    %0, cr<1, 2> \n"
+		"mfcr    %1, cr<2, 2> \n"
+		:"+r"(tmp1),"+r"(tmp2));
+
+	*fcr = tmp1;
+	/* not use in fpuv2 */
+	*fsr = 0;
+	*fesr = tmp2;
+	asm volatile(
+		FMFVR_FPU_REGS(vr0, vr1)
+		STW_FPU_REGS(0, 4, 8, 12)
+		FMFVR_FPU_REGS(vr2, vr3)
+		STW_FPU_REGS(16, 20, 24, 28)
+		FMFVR_FPU_REGS(vr4, vr5)
+		STW_FPU_REGS(32, 36, 40, 44)
+		FMFVR_FPU_REGS(vr6, vr7)
+		STW_FPU_REGS(48, 52, 56, 60)
+		"addi    %4, 32 \n"
+		"addi    %4, 32 \n"
+		FMFVR_FPU_REGS(vr8, vr9)
+		STW_FPU_REGS(0, 4, 8, 12)
+		FMFVR_FPU_REGS(vr10, vr11)
+		STW_FPU_REGS(16, 20, 24, 28)
+		FMFVR_FPU_REGS(vr12, vr13)
+		STW_FPU_REGS(32, 36, 40, 44)
+		FMFVR_FPU_REGS(vr14, vr15)
+		STW_FPU_REGS(48, 52, 56, 60)
+		:"=a"(tmp1),"=a"(tmp2),"=a"(tmp3),
+		"=a"(tmp4),"+a"(fpregs));
+	local_irq_restore(flg);
+}
+
+#else  /* __ASSEMBLY__ */
+
+#include <asm/asm-offsets.h>
+
+.macro  FPU_SAVE_REGS
+	/* Save FPU control regs task struct */
+	mfcr     r7, cr<1, 2>
+	mfcr     r6, cr<2, 2>
+	stw      r7, (a3, THREAD_FCR)
+	stw      r6, (a3, THREAD_FESR)
+	/* Save FPU general regs task struct */
+	fmfvrl   r6, vr0
+	fmfvrh   r7, vr0
+	fmfvrl   r8, vr1
+	fmfvrh   r9, vr1
+	stw      r6, (a3, THREAD_FPREG + 0)  /* In aviv2: stw can load longer */
+	stw      r7, (a3, THREAD_FPREG + 4)
+	stw      r8, (a3, THREAD_FPREG + 8)
+	stw      r9, (a3, THREAD_FPREG + 12)
+	fmfvrl   r6, vr2
+	fmfvrh   r7, vr2
+	fmfvrl   r8, vr3
+	fmfvrh   r9, vr3
+	stw      r6, (a3, THREAD_FPREG + 16)
+	stw      r7, (a3, THREAD_FPREG + 20)
+	stw      r8, (a3, THREAD_FPREG + 24)
+	stw      r9, (a3, THREAD_FPREG + 28)
+	fmfvrl   r6, vr4
+	fmfvrh   r7, vr4
+	fmfvrl   r8, vr5
+	fmfvrh   r9, vr5
+	stw      r6, (a3, THREAD_FPREG + 32)
+	stw      r7, (a3, THREAD_FPREG + 36)
+	stw      r8, (a3, THREAD_FPREG + 40)
+	stw      r9, (a3, THREAD_FPREG + 44)
+	fmfvrl   r6, vr6
+	fmfvrh   r7, vr6
+	fmfvrl   r8, vr7
+	fmfvrh   r9, vr7
+	stw      r6, (a3, THREAD_FPREG + 48)
+	stw      r7, (a3, THREAD_FPREG + 52)
+	stw      r8, (a3, THREAD_FPREG + 56)
+	stw      r9, (a3, THREAD_FPREG + 60)
+	fmfvrl   r6, vr8
+	fmfvrh   r7, vr8
+	fmfvrl   r8, vr9
+	fmfvrh   r9, vr9
+	stw      r6, (a3, THREAD_FPREG + 64)
+	stw      r7, (a3, THREAD_FPREG + 68)
+	stw      r8, (a3, THREAD_FPREG + 72)
+	stw      r9, (a3, THREAD_FPREG + 76)
+	fmfvrl   r6, vr10
+	fmfvrh   r7, vr10
+	fmfvrl   r8, vr11
+	fmfvrh   r9, vr11
+	stw      r6, (a3, THREAD_FPREG + 80)
+	stw      r7, (a3, THREAD_FPREG + 84)
+	stw      r8, (a3, THREAD_FPREG + 88)
+	stw      r9, (a3, THREAD_FPREG + 92)
+	fmfvrl   r6, vr12
+	fmfvrh   r7, vr12
+	fmfvrl   r8, vr13
+	fmfvrh   r9, vr13
+	stw      r6, (a3, THREAD_FPREG + 96)
+	stw      r7, (a3, THREAD_FPREG + 100)
+	stw      r8, (a3, THREAD_FPREG + 104)
+	stw      r9, (a3, THREAD_FPREG + 108)
+	fmfvrl   r6, vr14
+	fmfvrh   r7, vr14
+	fmfvrl   r8, vr15
+	fmfvrh   r9, vr15
+	stw      r6, (a3, THREAD_FPREG + 112)
+	stw      r7, (a3, THREAD_FPREG + 116)
+	stw      r8, (a3, THREAD_FPREG + 120)
+	stw      r9, (a3, THREAD_FPREG + 124)
+.endm
+
+.macro  FPU_RESTORE_REGS
+	/* Save FPU control regs task struct */
+	ldw      r6, (a3, THREAD_FCR)
+	ldw      r7, (a3, THREAD_FESR)
+	mtcr     r6, cr<1, 2>
+	mtcr     r7, cr<2, 2>
+	/* restore FPU general regs task struct */
+	ldw      r6, (a3, THREAD_FPREG + 0)
+	ldw      r7, (a3, THREAD_FPREG + 4)
+	ldw      r8, (a3, THREAD_FPREG + 8)
+	ldw      r9, (a3, THREAD_FPREG + 12)
+	fmtvrl   vr0, r6
+	fmtvrh   vr0, r7
+	fmtvrl   vr1, r8
+	fmtvrh   vr1, r9
+	ldw      r6, (a3, THREAD_FPREG + 16)
+	ldw      r7, (a3, THREAD_FPREG + 20)
+	ldw      r8, (a3, THREAD_FPREG + 24)
+	ldw      r9, (a3, THREAD_FPREG + 28)
+	fmtvrl   vr2, r6
+	fmtvrh   vr2, r7
+	fmtvrl   vr3, r8
+	fmtvrh   vr3, r9
+	ldw      r6, (a3, THREAD_FPREG + 32)
+	ldw      r7, (a3, THREAD_FPREG + 36)
+	ldw      r8, (a3, THREAD_FPREG + 40)
+	ldw      r9, (a3, THREAD_FPREG + 44)
+	fmtvrl   vr4, r6
+	fmtvrh   vr4, r7
+	fmtvrl   vr5, r8
+	fmtvrh   vr5, r9
+	ldw      r6, (a3, THREAD_FPREG + 48)
+	ldw      r7, (a3, THREAD_FPREG + 52)
+	ldw      r8, (a3, THREAD_FPREG + 56)
+	ldw      r9, (a3, THREAD_FPREG + 60)
+	fmtvrl   vr6, r6
+	fmtvrh   vr6, r7
+	fmtvrl   vr7, r8
+	fmtvrh   vr7, r9
+	ldw      r6, (a3, THREAD_FPREG + 64)
+	ldw      r7, (a3, THREAD_FPREG + 68)
+	ldw      r8, (a3, THREAD_FPREG + 72)
+	ldw      r9, (a3, THREAD_FPREG + 76)
+	fmtvrl   vr8, r6
+	fmtvrh   vr8, r7
+	fmtvrl   vr9, r8
+	fmtvrh   vr9, r9
+	ldw      r6, (a3, THREAD_FPREG + 80)
+	ldw      r7, (a3, THREAD_FPREG + 84)
+	ldw      r8, (a3, THREAD_FPREG + 88)
+	ldw      r9, (a3, THREAD_FPREG + 92)
+	fmtvrl   vr10, r6
+	fmtvrh   vr10, r7
+	fmtvrl   vr11, r8
+	fmtvrh   vr11, r9
+	ldw      r6, (a3, THREAD_FPREG + 96)
+	ldw      r7, (a3, THREAD_FPREG + 100)
+	ldw      r8, (a3, THREAD_FPREG + 104)
+	ldw      r9, (a3, THREAD_FPREG + 108)
+	fmtvrl   vr12, r6
+	fmtvrh   vr12, r7
+	fmtvrl   vr13, r8
+	fmtvrh   vr13, r9
+	ldw      r6, (a3, THREAD_FPREG + 112)
+	ldw      r7, (a3, THREAD_FPREG + 116)
+	ldw      r8, (a3, THREAD_FPREG + 120)
+	ldw      r9, (a3, THREAD_FPREG + 124)
+	fmtvrl   vr14, r6
+	fmtvrh   vr14, r7
+	fmtvrl   vr15, r8
+	fmtvrh   vr15, r9
+.endm
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CSKY_FPU_H */
diff --git a/arch/csky/abiv2/inc/abi/reg_ops.h b/arch/csky/abiv2/inc/abi/reg_ops.h
new file mode 100644
index 0000000..7f66bd6
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/reg_ops.h
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_REG_OPS_H
+#define __ASM_REG_OPS_H
+
+static inline unsigned int mfcr_cpuidrr(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr13\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_hint(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr31\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_ccr(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr18\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_ccr2(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr23\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline unsigned int mfcr_msa0(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr<30, 15>\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline void mtcr_msa0(unsigned int value)
+{
+	asm volatile(
+		"mtcr %0, cr<30, 15>\t\n"
+		::"r"(value));
+}
+
+static inline unsigned int mfcr_msa1(void)
+{
+	unsigned int ret;
+	asm volatile(
+		"mfcr %0, cr<31, 15>\t\n"
+		:"=r"(ret));
+	return ret;
+}
+
+static inline void mtcr_msa1(unsigned int value)
+{
+	asm volatile(
+		"mtcr %0, cr<31, 15>\t\n"
+		::"r"(value));
+}
+
+/* read/write user stack pointer */
+static inline unsigned long rdusp(void) {
+	register unsigned long usp;
+	asm volatile("mfcr %0, cr<14, 1> \n\r":"=r" (usp));
+	return usp;
+}
+
+static inline void wrusp(unsigned long usp) {
+	asm volatile("mtcr %0, cr<14, 1> \n\r"::"r" (usp));
+}
+
+#endif /* __ASM_REG_OPS_H */
+
diff --git a/arch/csky/abiv2/inc/abi/regdef.h b/arch/csky/abiv2/inc/abi/regdef.h
new file mode 100644
index 0000000..11bdc3a
--- /dev/null
+++ b/arch/csky/abiv2/inc/abi/regdef.h
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef  __ASM_CSKY_REGDEF_H
+#define  __ASM_CSKY_REGDEF_H
+
+#define syscallid	r7
+#define r11_sig		r11
+
+#define DEFAULT_PSR_VALUE	0x8f000200
+
+#define PTRACE_REGOFF_ABI \
+{ \
+	PT_A0,    PT_A1,     PT_A2,    PT_A3,\
+	PT_REGS0, PT_REGS1,  PT_REGS2, PT_REGS3,\
+	PT_REGS4, PT_REGS5,  PT_REGS6, PT_REGS7,\
+	PT_REGS8, PT_REGS9,  -1,       PT_R15,\
+	PT_R16,   PT_R17,    PT_R18,   PT_R19,\
+	PT_R20,   PT_R21,    PT_R22,   PT_R23,\
+	PT_R24,   PT_R25,    PT_R26,   PT_R27,\
+	PT_R28,   PT_R29,    PT_R30,   PT_R31,\
+	PT_SR,    PT_PC,     PT_RHI,   PT_RLO,\
+}
+
+#define SYSTRACE_SAVENUM	5
+
+#define REGNO_USP		14
+
+#endif /* __ASM_CSKY_REGDEF_H */
diff --git a/arch/csky/include/uapi/asm/byteorder.h b/arch/csky/include/uapi/asm/byteorder.h
new file mode 100644
index 0000000..d254522
--- /dev/null
+++ b/arch/csky/include/uapi/asm/byteorder.h
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_BYTEORDER_H
+#define __ASM_CSKY_BYTEORDER_H
+
+#if defined(__cskyBE__)
+#include <linux/byteorder/big_endian.h>
+#elif defined(__cskyLE__)
+#include <linux/byteorder/little_endian.h>
+#else
+# error "There is no __cskyBE__, __cskyLE__"
+#endif
+
+#endif /* __ASM_CSKY_BYTEORDER_H */
diff --git a/arch/csky/include/uapi/asm/fcntl.h b/arch/csky/include/uapi/asm/fcntl.h
new file mode 100644
index 0000000..2ee1af2
--- /dev/null
+++ b/arch/csky/include/uapi/asm/fcntl.h
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ASM_CSKY_FCNTL_H
+#define __ASM_CSKY_FCNTL_H
+
+#define O_DIRECTORY	040000
+#define O_NOFOLLOW	0100000
+#define O_DIRECT	0200000
+#define O_LARGEFILE	0400000
+
+#include <asm-generic/fcntl.h>
+
+#endif /* __ASM_CSKY_FCNTL_H */
diff --git a/arch/csky/include/uapi/asm/stat.h b/arch/csky/include/uapi/asm/stat.h
new file mode 100644
index 0000000..2273042
--- /dev/null
+++ b/arch/csky/include/uapi/asm/stat.h
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef _CSKY_STAT_H
+#define _CSKY_STAT_H
+
+struct __old_kernel_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+#define STAT_HAVE_NSEC 
+
+struct stat {
+#if defined(__cskyBE__)
+	unsigned short st_dev;
+	unsigned short __pad1;
+#else
+	unsigned long  st_dev;
+#endif
+	unsigned long  st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+#if defined(__cskyBE__)
+	unsigned short st_rdev;
+	unsigned short __pad2;
+#else
+	unsigned long  st_rdev;
+#endif
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  st_atime_nsec;
+	unsigned long  st_mtime;
+	unsigned long  st_mtime_nsec;
+	unsigned long  st_ctime;
+	unsigned long  st_ctime_nsec;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+/* This matches struct stat64 in glibc2.1, hence the absolutely
+ * insane amounts of padding around dev_t's.
+ */
+struct stat64 {
+	unsigned long long 	st_dev;
+	unsigned char	__pad0[4];
+
+#define STAT64_HAS_BROKEN_ST_INO	1
+	unsigned long	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+
+	unsigned long	st_uid;
+	unsigned long	st_gid;
+
+	unsigned long long	st_rdev;
+	unsigned char	__pad3[4];
+
+	long long		st_size;
+	unsigned long	st_blksize;
+	unsigned long long	st_blocks;		/* Number 512-byte blocks allocated. */
+
+	unsigned long   st_atime;
+	unsigned long   st_atime_nsec;
+
+	unsigned long	st_mtime;
+	unsigned long   st_mtime_nsec;
+
+	unsigned long	st_ctime;
+	unsigned long   st_ctime_nsec;
+	unsigned long long	st_ino;
+};
+
+#endif /* _CSKY_STAT_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 15/19] csky: Build infrastructure
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (13 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 14/19] csky: Misc headers Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-19 15:45   ` Arnd Bergmann
  2018-03-18 19:51 ` [PATCH 16/19] csky: Device tree Guo Ren
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/Kconfig                 | 203 ++++++++++++++++++++++++++++++++++++++
 arch/csky/Kconfig.debug           |  22 +++++
 arch/csky/Makefile                |  92 +++++++++++++++++
 arch/csky/abiv1/Makefile          |   8 ++
 arch/csky/abiv2/Makefile          |   3 +
 arch/csky/boot/Makefile           |  25 +++++
 arch/csky/boot/dts/Makefile       |  14 +++
 arch/csky/include/asm/Kbuild      |  71 +++++++++++++
 arch/csky/include/uapi/asm/Kbuild |  30 ++++++
 arch/csky/kernel/Makefile         |   8 ++
 arch/csky/kernel/vmlinux.lds.S    |  67 +++++++++++++
 arch/csky/lib/Makefile            |   1 +
 arch/csky/mm/Makefile             |  13 +++
 arch/csky/oprofile/Makefile       |  13 +++
 14 files changed, 570 insertions(+)
 create mode 100644 arch/csky/Kconfig
 create mode 100644 arch/csky/Kconfig.debug
 create mode 100644 arch/csky/Makefile
 create mode 100644 arch/csky/abiv1/Makefile
 create mode 100644 arch/csky/abiv2/Makefile
 create mode 100644 arch/csky/boot/Makefile
 create mode 100644 arch/csky/boot/dts/Makefile
 create mode 100644 arch/csky/include/asm/Kbuild
 create mode 100644 arch/csky/include/uapi/asm/Kbuild
 create mode 100644 arch/csky/kernel/Makefile
 create mode 100644 arch/csky/kernel/vmlinux.lds.S
 create mode 100644 arch/csky/lib/Makefile
 create mode 100644 arch/csky/mm/Makefile
 create mode 100644 arch/csky/oprofile/Makefile

diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
new file mode 100644
index 0000000..694c1f8
--- /dev/null
+++ b/arch/csky/Kconfig
@@ -0,0 +1,203 @@
+config CSKY
+	bool
+	default y
+	select ARCH_USE_BUILTIN_BSWAP
+	select ARCH_WANT_IPC_PARSE_VERSION
+	select COMMON_CLK
+	select CLKSRC_MMIO
+	select CLKSRC_OF
+	select DW_APB_TIMER_OF
+	select GENERIC_ATOMIC64
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_CPU_DEVICES
+	select GENERIC_IRQ_CHIP
+	select GENERIC_IRQ_SHOW
+	select GENERIC_SCHED_CLOCK
+	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZO
+	select HAVE_KERNEL_LZMA
+	select HAVE_OPROFILE
+	select HAVE_PERF_EVENTS
+	select HAVE_C_RECORDMCOUNT
+	select HAVE_KPROBES
+	select HAVE_KRETPROBES
+	select HAVE_DMA_API_DEBUG
+	select HAVE_MEMBLOCK
+	select MAY_HAVE_SPARSE_IRQ
+	select MODULES_USE_ELF_REL if MODULES
+	select MODULES_USE_ELF_RELA if MODULES
+	select NO_BOOTMEM
+	select OF
+	select OF_EARLY_FLATTREE
+	select OF_RESERVED_MEM
+	select OLD_SIGACTION
+	select OLD_SIGSUSPEND3
+	select PERF_USE_VMALLOC
+	select RTC_LIB
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
+
+config CPU_HAS_CACHEV2
+	bool
+	default n
+
+config CPU_HAS_HILO
+	bool
+	default n
+
+config CPU_HAS_TLBI
+	bool
+	default n
+
+config CPU_NEED_TLBSYNC
+	bool
+	default n
+
+config CPU_NEED_SOFTALIGN
+	bool
+	default n
+
+config HIGHMEM
+	bool
+	default n
+
+config HZ
+	int
+	default 100
+
+config GENERIC_CSUM
+	bool
+	default y
+
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
+config GENERIC_HWEIGHT
+	bool
+	default y
+
+config MMU
+	bool
+	default y
+
+config NR_CPUS
+	int
+	default "1"
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y
+
+config TIME_LOW_RES
+	bool
+	default y
+
+config TRACE_IRQFLAGS_SUPPORT
+	bool
+	default y
+
+source "init/Kconfig"
+
+source "kernel/Kconfig.freezer"
+
+menu "Processor type and features"
+
+comment "Processor type"
+
+choice
+        prompt "CPU MODEL"
+        default CPU_CK610
+
+config CPU_CK610
+        bool "CSKY CPU ck610"
+	select CPU_NEED_TLBSYNC
+	select CPU_NEED_SOFTALIGN
+
+config CPU_CK810
+        bool "CSKY CPU ck810"
+	select HIGHMEM
+	select CPU_HAS_HILO
+	select CPU_NEED_TLBSYNC
+
+config CPU_CK807
+        bool "CSKY CPU ck807"
+	select HIGHMEM
+	select CPU_HAS_HILO
+
+config CPU_CK860
+        bool "CSKY CPU ck860"
+	select HIGHMEM
+	select CPU_HAS_TLBI
+	select CPU_HAS_CACHEV2
+endchoice
+
+config CPU_TLB_SIZE
+	int
+	default "128"	if(CPU_CK610 || CPU_CK807 || CPU_CK810)
+	default "1024"	if(CPU_CK860)
+
+config L1_CACHE_SHIFT
+	int
+	default "4"	if(CPU_CK610)
+	default "5"	if(CPU_CK807 || CPU_CK810)
+	default "6"	if(CPU_CK860)
+
+menuconfig CPU_HAS_FPU
+	bool "CPU has FPU coprocessor"
+	depends on CPU_CK807 || CPU_CK810 || CPU_CK860
+	default n
+	help
+	  Floating-Point Coprocessor (FPC) is a coprocessor of CK serial processor.
+	  The function of FPC is to provide low-cost high-speed float point computation,
+	  which is full compliance with ANSI/IEEE Std 754, IEEE Standard for Binary
+	  Floating-Point Arithmetic.
+
+comment "*****System type*****"
+
+config SSEG0_BASE
+	hex "Direct mapping physical address"
+	default 0x0
+	help
+	  There are MSAx regs can be used to change the base physical address
+	  of direct mapping. The default base physical address is 0x0.
+
+config RAM_BASE
+	hex "DRAM base address offset from SSEG0_BASE, it must be the same with dts memory."
+	default 0x08000000
+
+config CSKY_NR_IRQS
+	int "NR_IRQS to max virtual interrupt numbers of the whole system"
+	range 64 8192
+	default "128"
+endmenu
+
+menu "Power management options"
+
+source "kernel/power/Kconfig"
+
+config ARCH_SUSPEND_POSSIBLE
+	bool y
+	default y
+endmenu
+
+source "mm/Kconfig"
+
+source "fs/Kconfig.binfmt"
+
+source "kernel/Kconfig.preempt"
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/csky/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/csky/Kconfig.debug b/arch/csky/Kconfig.debug
new file mode 100644
index 0000000..c202cfc
--- /dev/null
+++ b/arch/csky/Kconfig.debug
@@ -0,0 +1,22 @@
+menu "Kernel hacking"
+
+config CSKY_DEBUG_INFO
+	bool "Compile the kernel with debug info, just add -g"
+	depends on !DEBUG_INFO
+	help
+	  DEBUG_INFO and COMPILE_TEST is conflict, so we provide
+	  another way to support -g.
+	  Some drivers eg: DW_MMC need COMPILE_TEST for new cpu
+	  arch :(
+
+config CSKY_BUILTIN_DTB
+	bool "Use kernel builtin dtb"
+	default n
+
+config CSKY_BUILTIN_DTB_NAME
+	string "kernel builtin dtb name"
+	depends on CSKY_BUILTIN_DTB
+
+source "lib/Kconfig.debug"
+
+endmenu
diff --git a/arch/csky/Makefile b/arch/csky/Makefile
new file mode 100644
index 0000000..3089c46
--- /dev/null
+++ b/arch/csky/Makefile
@@ -0,0 +1,92 @@
+OBJCOPYFLAGS	:=-O binary
+GZFLAGS		:=-9
+
+ifdef CONFIG_CPU_HAS_FPU
+FPUEXT =f
+endif
+
+ifdef CONFIG_CPU_CK610
+CPUTYPE	= ck610
+CSKYABI	= abiv1
+endif
+
+ifdef CONFIG_CPU_CK810
+CPUTYPE = ck810$(FPUEXT)
+CSKYABI	= abiv2
+endif
+
+ifdef CONFIG_CPU_CK807
+CPUTYPE = ck807$(FPUEXT)
+CSKYABI	= abiv2
+endif
+
+ifdef CONFIG_CPU_CK860
+CPUTYPE = ck860$(FPUEXT)
+CSKYABI	= abiv2
+endif
+
+ifeq ($(VERSION)_$(PATCHLEVEL), 4_9)
+COMPAT_KERNEL_4_9 = -DCOMPAT_KERNEL_4_9
+endif
+
+KBUILD_CFLAGS +=	-ffreestanding \
+			-fno-tree-dse \
+			-pipe \
+			-Wno-uninitialized \
+			$(COMPAT_KERNEL_4_9) \
+			-mcpu=$(CPUTYPE) \
+			-DCSKYCPU_DEF_NAME=\"$(CPUTYPE)\"
+
+ifeq ($(CONFIG_CSKY_DEBUG_INFO),y)
+KBUILD_CFLAGS += -g
+endif
+
+abidirs := $(patsubst %,arch/csky/%/,$(CSKYABI))
+
+KBUILD_CFLAGS += $(patsubst %,-I$(srctree)/%inc,$(abidirs))
+
+KBUILD_CPPFLAGS += -mlittle-endian
+LDFLAGS += -EL
+
+KBUILD_AFLAGS += $(KBUILD_CFLAGS)
+
+head-y := arch/csky/kernel/head.o
+
+core-y += arch/csky/kernel/
+core-y += arch/csky/mm/
+core-y += arch/csky/$(CSKYABI)/
+
+libs-y += arch/csky/lib/ \
+	$(shell $(CC) $(KBUILD_CFLAGS) $(KCFLAGS) -print-libgcc-file-name)
+
+ifdef CONFIG_CSKY_BUILTIN_DTB
+core-y				+= arch/csky/boot/dts/
+endif
+
+drivers-$(CONFIG_OPROFILE)	+= arch/csky/oprofile/
+
+all: zImage
+
+boot	:= arch/csky/boot
+
+dtbs: scripts
+	$(Q)$(MAKE) $(build)=$(boot)/dts
+
+%.dtb %.dtb.S %.dtb.o: scripts
+	$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
+
+zImage Image uImage: vmlinux dtbs
+	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
+
+archmrproper:
+
+archclean:
+	$(Q)$(MAKE) $(clean)=$(boot)
+	rm -rf arch/csky/include/generated
+
+define archhelp
+  echo  '* zImage       - Compressed kernel image (arch/$(ARCH)/boot/zImage)'
+  echo  '  Image        - Uncompressed kernel image (arch/$(ARCH)/boot/Image)'
+  echo  '  uImage       - U-Boot wrapped zImage'
+endef
+
diff --git a/arch/csky/abiv1/Makefile b/arch/csky/abiv1/Makefile
new file mode 100644
index 0000000..d2cf365
--- /dev/null
+++ b/arch/csky/abiv1/Makefile
@@ -0,0 +1,8 @@
+obj-y +=	src/bswapdi.o
+obj-y +=	src/bswapsi.o
+obj-y +=	src/cacheflush.o
+obj-y +=	src/memcpy.o
+obj-y +=	src/mmap.o
+
+obj-$(CONFIG_CPU_NEED_SOFTALIGN) +=	src/alignment.o
+
diff --git a/arch/csky/abiv2/Makefile b/arch/csky/abiv2/Makefile
new file mode 100644
index 0000000..97f3780
--- /dev/null
+++ b/arch/csky/abiv2/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_CPU_HAS_FPU)	+= src/fpu.o
+obj-y				+= src/memcpy.o
+
diff --git a/arch/csky/boot/Makefile b/arch/csky/boot/Makefile
new file mode 100644
index 0000000..c3301a8
--- /dev/null
+++ b/arch/csky/boot/Makefile
@@ -0,0 +1,25 @@
+targets := Image zImage uImage
+targets += $(dtb-y)
+
+$(obj)/Image: vmlinux FORCE
+	$(call if_changed,objcopy)
+	@echo '  Kernel: $@ is ready'
+
+compress-$(CONFIG_KERNEL_GZIP) = gzip
+compress-$(CONFIG_KERNEL_LZO)  = lzo
+compress-$(CONFIG_KERNEL_LZMA) = lzma
+compress-$(CONFIG_KERNEL_XZ)   = xzkern
+compress-$(CONFIG_KERNEL_LZ4)  = lz4
+
+$(obj)/zImage:  $(obj)/Image FORCE
+	$(call if_changed,$(compress-y))
+	@echo '  Kernel: $@ is ready'
+
+UIMAGE_ARCH		= sandbox
+UIMAGE_COMPRESSION	= $(compress-y)
+UIMAGE_LOADADDR		= $(shell $(NM) vmlinux | awk '$$NF == "_start" {print $$1}')
+
+$(obj)/uImage: $(obj)/zImage
+	$(call if_changed,uimage)
+	@echo 'Image: $@ is ready'
+
diff --git a/arch/csky/boot/dts/Makefile b/arch/csky/boot/dts/Makefile
new file mode 100644
index 0000000..9afc954
--- /dev/null
+++ b/arch/csky/boot/dts/Makefile
@@ -0,0 +1,14 @@
+dtstree	:= $(srctree)/$(src)
+
+ifdef CONFIG_CSKY_BUILTIN_DTB
+builtindtb-y := $(patsubst "%",%,$(CONFIG_CSKY_BUILTIN_DTB_NAME))
+dtb-y += $(builtindtb-y).dtb
+obj-y += $(builtindtb-y).dtb.o
+.SECONDARY: $(obj)/$(builtindtb-y).dtb.S
+else
+dtb-y := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+endif
+
+always += $(dtb-y)
+clean-files += *.dtb *.dtb.S
+
diff --git a/arch/csky/include/asm/Kbuild b/arch/csky/include/asm/Kbuild
new file mode 100644
index 0000000..58b92d8
--- /dev/null
+++ b/arch/csky/include/asm/Kbuild
@@ -0,0 +1,71 @@
+generic-y += asm-offsets.h
+generic-y += atomic.h
+generic-y += auxvec.h
+generic-y += bitsperlong.h
+generic-y += bug.h
+generic-y += bugs.h
+generic-y += clkdev.h
+generic-y += cmpxchg.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += delay.h
+generic-y += device.h
+generic-y += div64.h
+generic-y += dma.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += exec.h
+generic-y += fb.h
+generic-y += ftrace.h
+generic-y += futex.h
+generic-y += gpio.h
+generic-y += hardirq.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += irq_regs.h
+generic-y += ipcbuf.h
+generic-y += irq_work.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += kprobes.h
+generic-y += kvm_para.h
+generic-y += linkage.h
+generic-y += local.h
+generic-y += local64.h
+generic-y += mman.h
+generic-y += mm-arch-hooks.h
+generic-y += module.h
+generic-y += msgbuf.h
+generic-y += mutex.h
+generic-y += param.h
+generic-y += pci.h
+generic-y += percpu.h
+generic-y += posix_types.h
+generic-y += poll.h
+generic-y += preempt.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += setup.h
+generic-y += shmbuf.h
+generic-y += shm.h
+generic-y += siginfo.h
+generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += statfs.h
+generic-y += switch_to.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += timex.h
+generic-y += topology.h
+generic-y += trace_clock.h
+generic-y += types.h
+generic-y += ucontext.h
+generic-y += unaligned.h
+generic-y += vga.h
+generic-y += vmlinux.lds.h
+generic-y += word-at-a-time.h
diff --git a/arch/csky/include/uapi/asm/Kbuild b/arch/csky/include/uapi/asm/Kbuild
new file mode 100644
index 0000000..9668182
--- /dev/null
+++ b/arch/csky/include/uapi/asm/Kbuild
@@ -0,0 +1,30 @@
+include include/uapi/asm-generic/Kbuild.asm
+
+header-y += cachectl.h
+header-y += stat.h
+
+generic-y += auxvec.h
+generic-y += param.h
+generic-y += bpf_perf_event.h
+generic-y += errno.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += ipcbuf.h
+generic-y += shmbuf.h
+generic-y += bitsperlong.h
+generic-y += mman.h
+generic-y += msgbuf.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += resource.h
+generic-y += sembuf.h
+generic-y += siginfo.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += statfs.h
+generic-y += setup.h
+generic-y += swab.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += types.h
+generic-y += ucontext.h
diff --git a/arch/csky/kernel/Makefile b/arch/csky/kernel/Makefile
new file mode 100644
index 0000000..8df5fd9
--- /dev/null
+++ b/arch/csky/kernel/Makefile
@@ -0,0 +1,8 @@
+extra-y := head.o vmlinux.lds
+
+obj-y += entry.o atomic.o signal.o traps.o irq.o time.o vdso.o \
+	 power.o syscall.o platform.o syscall_table.o setup.o \
+	 cskyksyms.o process.o cpu-probe.o ptrace.o dumpstack.o
+
+obj-$(CONFIG_MODULES) += module.o
+
diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..406e6f4
--- /dev/null
+++ b/arch/csky/kernel/vmlinux.lds.S
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <asm/vmlinux.lds.h>
+#include <asm/page.h>
+
+OUTPUT_ARCH(csky)
+ENTRY(_start)
+
+#ifndef __cskyBE__
+jiffies = jiffies_64;
+#else
+jiffies = jiffies_64 + 4;
+#endif
+
+#define VBR_BASE \
+	. = ALIGN(1024); \
+	VMLINUX_SYMBOL(vec_base) = .; \
+	. += 512;
+
+SECTIONS
+{
+	. = PAGE_OFFSET + CONFIG_RAM_BASE;
+	_text = .;
+	HEAD_TEXT_SECTION
+
+	_stext = .;
+	.text : AT(ADDR(.text) - LOAD_OFFSET) {
+		IRQENTRY_TEXT
+		SOFTIRQENTRY_TEXT
+		TEXT_TEXT
+		SCHED_TEXT
+		CPUIDLE_TEXT
+		LOCK_TEXT
+		KPROBES_TEXT
+		*(.fixup)
+		*(.gnu.warning)
+	} = 0
+	_etext = .;
+
+	/* __init_begin __init_end must be page aligned for free_initmem */
+	. = ALIGN(PAGE_SIZE);
+	__init_begin = .;
+
+	INIT_TEXT_SECTION(PAGE_SIZE)
+	INIT_DATA_SECTION(PAGE_SIZE)
+	PERCPU_SECTION(L1_CACHE_BYTES)
+
+	. = ALIGN(PAGE_SIZE);
+	__init_end = .;
+
+	_sdata = .;
+	RO_DATA_SECTION(PAGE_SIZE)
+	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+	_edata = .;
+
+	NOTES
+	EXCEPTION_TABLE(L1_CACHE_BYTES)
+	BSS_SECTION(L1_CACHE_BYTES, PAGE_SIZE, L1_CACHE_BYTES)
+	VBR_BASE
+	_end = . ;
+
+	STABS_DEBUG
+	DWARF_DEBUG
+
+	DISCARDS
+}
+
diff --git a/arch/csky/lib/Makefile b/arch/csky/lib/Makefile
new file mode 100644
index 0000000..02aefbc
--- /dev/null
+++ b/arch/csky/lib/Makefile
@@ -0,0 +1 @@
+lib-y  := memset.o usercopy.o delay.o
diff --git a/arch/csky/mm/Makefile b/arch/csky/mm/Makefile
new file mode 100644
index 0000000..c870eb3
--- /dev/null
+++ b/arch/csky/mm/Makefile
@@ -0,0 +1,13 @@
+ifeq ($(CONFIG_CPU_HAS_CACHEV2),y)
+obj-y +=			cachev2.o
+else
+obj-y +=			cachev1.o
+endif
+
+obj-y +=			dma-mapping.o
+obj-y +=			fault.o
+obj-$(CONFIG_HIGHMEM) +=	highmem.o
+obj-y +=			init.o
+obj-y +=			ioremap.o
+obj-y +=			syscache.o
+obj-y +=			tlb.o
diff --git a/arch/csky/oprofile/Makefile b/arch/csky/oprofile/Makefile
new file mode 100644
index 0000000..8b93284
--- /dev/null
+++ b/arch/csky/oprofile/Makefile
@@ -0,0 +1,13 @@
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o \
+		timer_int.o )
+
+ifeq ($(CONFIG_HW_PERF_EVENTS),y)
+DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o)
+endif
+
+oprofile-y := $(DRIVER_OBJS) init.o
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 16/19] csky: Device tree
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (14 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 15/19] csky: Build infrastructure Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-19 15:28   ` Arnd Bergmann
  2018-03-18 19:51 ` [PATCH 17/19] csky: defconfig Guo Ren
                   ` (4 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/boot/dts/gx6605s.dts         | 159 +++++++++++++++++++++++++++++++++
 arch/csky/boot/dts/include/dt-bindings |   1 +
 arch/csky/boot/dts/qemu.dts            |  87 ++++++++++++++++++
 3 files changed, 247 insertions(+)
 create mode 100644 arch/csky/boot/dts/gx6605s.dts
 create mode 120000 arch/csky/boot/dts/include/dt-bindings
 create mode 100644 arch/csky/boot/dts/qemu.dts

diff --git a/arch/csky/boot/dts/gx6605s.dts b/arch/csky/boot/dts/gx6605s.dts
new file mode 100644
index 0000000..0d34d22
--- /dev/null
+++ b/arch/csky/boot/dts/gx6605s.dts
@@ -0,0 +1,159 @@
+/dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+	model = "Nationalchip gx6605s ck610";
+	compatible = "nationalchip,gx6605s,ck610";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		device_type = "memory";
+		reg = <0x10000000 0x04000000>;
+	};
+
+	cpus {
+		#address-cells = <0>;
+		#size-cells = <0>;
+
+		cpu {
+			device_type = "cpu";
+			ccr	= <0x7d>;
+			hint	= <0x1c>;
+		};
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "nationalchip,intc-v1,ave";
+			reg = <0x00500000 0x400>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		timer0 {
+			compatible = "nationalchip,timer-v1";
+			reg = <0x0020a000 0x400>;
+			clock-frequency = <1000000>;
+			interrupts = <10>;
+			interrupt-parent = <&intc>;
+		};
+
+		ehci: ehci-hcd {
+			compatible = "generic-ehci";
+			reg = <0x00900000 0x400>;
+			interrupt-parent = <&intc>;
+			interrupts = <59>;
+		};
+
+		ohci0: ohci-hcd0 {
+			compatible = "generic-ohci";
+			reg = <0x00a00000 0x400>;
+			interrupt-parent = <&intc>;
+			interrupts = <58>;
+		};
+
+		ohci1: ohci-hcd1 {
+			compatible = "generic-ohci";
+			reg = <0x00b00000 0x400>;
+			interrupt-parent = <&intc>;
+			interrupts = <57>;
+		};
+
+		uart0: serial {
+			compatible = "ns16550a";
+			reg = <0x00403000 0x400>;
+			interrupt-parent = <&intc>;
+			interrupts = <15>;
+			clock-frequency = <29491200>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <1>;
+		};
+
+		gpio0: gpio {
+			compatible = "wd,mbl-gpio";
+			reg-names = "dirout", "dat", "set", "clr";
+			reg = <0x305000 4>, <0x305004 4>, <0x305008 4>, <0x30500c 4>;
+			bgpio-base = <0>;
+			#gpio-cells = <2>;
+			gpio-controller;
+		};
+
+		gpio_buttons {
+			compatible = "gpio-keys-polled";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			poll-interval = <100>;
+			autorepeat;
+
+			button0 {
+				label = "button8";
+				linux,code = <KEY_LEFT>;
+				gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
+			};
+
+			button1 {
+				label = "button6";
+				linux,code = <KEY_RIGHT>;
+				gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
+			};
+
+			button2 {
+				label = "button5";
+				linux,code = <KEY_UP>;
+				gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
+			};
+
+			button3 {
+				label = "button9";
+				linux,code = <KEY_DOWN>;
+				gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+			};
+
+			button4 {
+				label = "button7";
+				linux,code = <KEY_ENTER>;
+				gpios = <&gpio0 7 GPIO_ACTIVE_LOW>;
+			};
+		};
+
+		gpio_leds {
+			compatible = "gpio-leds";
+
+			led0 {
+				label = "led10";
+				gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+				linux,default-trigger = "heartbeat";
+			};
+
+			led1 {
+				label = "led11";
+				gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
+				linux,default-trigger = "timer";
+			};
+
+			led2 {
+				label = "led12";
+				gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
+				linux,default-trigger = "default-on";
+			};
+
+			led3 {
+				label = "led13";
+				gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
+				linux,default-trigger = "default-on";
+			};
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 init=/sbin/init root=/dev/sda2 rw rootwait";
+	};
+};
diff --git a/arch/csky/boot/dts/include/dt-bindings b/arch/csky/boot/dts/include/dt-bindings
new file mode 120000
index 0000000..08c00e4
--- /dev/null
+++ b/arch/csky/boot/dts/include/dt-bindings
@@ -0,0 +1 @@
+../../../../../include/dt-bindings
\ No newline at end of file
diff --git a/arch/csky/boot/dts/qemu.dts b/arch/csky/boot/dts/qemu.dts
new file mode 100644
index 0000000..59e1c83
--- /dev/null
+++ b/arch/csky/boot/dts/qemu.dts
@@ -0,0 +1,87 @@
+/dts-v1/;
+
+/ {
+	model = "qemu.csky";
+	compatible = "csky";
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	memory {
+		device_type = "memory";
+		reg = <0x0 0x40000000>;
+	};
+
+	soc {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		compatible = "simple-bus";
+		ranges;
+
+		intc: interrupt-controller {
+			compatible = "csky,intc-v1";
+			reg = <0xfffff000 0x1000>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+		};
+
+		/* clockevent */
+		timer0 {
+			compatible = "snps,dw-apb-timer";
+			reg = <0xffffd000 0x1000>;
+			clocks = <&dummy_apb>;
+			clock-names = "timer";
+			interrupts = <1>;
+			interrupt-parent = <&intc>;
+		};
+
+		/* clocksource */
+		timer1 {
+			compatible = "snps,dw-apb-timer";
+			reg = <0xffffd014 0x800>;
+			clocks = <&dummy_apb>;
+			clock-names = "timer";
+			interrupts = <2>;
+			interrupt-parent = <&intc>;
+		};
+
+		serial0 {
+			compatible = "ns16550a";
+			reg = <0xffffe000 0x1000>;
+			interrupt-parent = <&intc>;
+			interrupts = <3>;
+			clocks = <&dummy_apb>;
+			baud = <115200>;
+			reg-shift = <2>;
+			reg-io-width = <1>;
+		};
+
+		dummy_apb: apb-clock {
+			compatible = "fixed-clock";
+			clock-frequency = <40000000>;
+			clock-output-names = "dummy_apb";
+			#clock-cells = <0>;
+		};
+
+		gmac: ethernet {
+			compatible = "snps,dwmac";
+			reg = <0xffffa000 0x2000>;
+			interrupt-parent = <&intc>;
+			interrupts = <4>;
+			interrupt-names = "macirq";
+			clocks = <&dummy_apb>;
+			clock-names = "stmmaceth";
+			phy-mode = "mii";
+			snps,pbl = <32>;
+			snps,fixed-burst;
+		};
+
+		qemu-exit {
+			compatible = "csky,qemu-exit";
+			reg = <0xffffc000 0x1000>;
+		};
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,115200 rdinit=/sbin/init root=/dev/ram0";
+	};
+};
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 17/19] csky: defconfig
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (15 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 16/19] csky: Device tree Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-26 13:16   ` Arnd Bergmann
  2018-03-18 19:51 ` [PATCH 18/19] clocksource: add timer-nationalchip.c Guo Ren
                   ` (3 subsequent siblings)
  20 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 arch/csky/configs/gx66xx_defconfig     | 549 +++++++++++++++++++++++++++++++++
 arch/csky/configs/qemu_ck807_defconfig | 541 ++++++++++++++++++++++++++++++++
 2 files changed, 1090 insertions(+)
 create mode 100644 arch/csky/configs/gx66xx_defconfig
 create mode 100644 arch/csky/configs/qemu_ck807_defconfig

diff --git a/arch/csky/configs/gx66xx_defconfig b/arch/csky/configs/gx66xx_defconfig
new file mode 100644
index 0000000..7f2a987
--- /dev/null
+++ b/arch/csky/configs/gx66xx_defconfig
@@ -0,0 +1,549 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_DEFAULT_HOSTNAME="github.com/c-sky"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_FHANDLE is not set
+CONFIG_USELIB=y
+CONFIG_AUDIT=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_RELAY=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_AIO is not set
+CONFIG_USERFAULTFD=y
+CONFIG_EMBEDDED=y
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_AIX_PARTITION=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_FB_NATIONALCHIP=y
+CONFIG_RAM_BASE=0x10000000
+# CONFIG_SUSPEND is not set
+# CONFIG_COMPACTION is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_CFG80211_DEBUGFS=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
+CONFIG_MAC80211_DEBUGFS=y
+CONFIG_RFKILL=y
+CONFIG_RFKILL_INPUT=y
+CONFIG_RFKILL_GPIO=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=y
+CONFIG_AD525X_DPOT=m
+CONFIG_AD525X_DPOT_I2C=m
+CONFIG_DUMMY_IRQ=m
+CONFIG_ICS932S401=m
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_APDS9802ALS=m
+CONFIG_ISL29003=m
+CONFIG_ISL29020=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SENSORS_BH1770=m
+CONFIG_SENSORS_APDS990X=m
+CONFIG_HMC6352=m
+CONFIG_DS1682=m
+CONFIG_USB_SWITCH_FSA9480=m
+CONFIG_SRAM=y
+CONFIG_C2PORT=m
+CONFIG_EEPROM_AT24=m
+CONFIG_EEPROM_LEGACY=m
+CONFIG_EEPROM_MAX6875=m
+CONFIG_SENSORS_LIS3_I2C=m
+CONFIG_ALTERA_STAPL=m
+CONFIG_ECHO=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+CONFIG_USB_RTL8150=y
+CONFIG_USB_RTL8152=y
+CONFIG_USB_USBNET=y
+# CONFIG_WLAN_VENDOR_ADMTEK is not set
+# CONFIG_WLAN_VENDOR_ATH is not set
+# CONFIG_WLAN_VENDOR_ATMEL is not set
+# CONFIG_WLAN_VENDOR_BROADCOM is not set
+# CONFIG_WLAN_VENDOR_CISCO is not set
+# CONFIG_WLAN_VENDOR_INTEL is not set
+# CONFIG_WLAN_VENDOR_INTERSIL is not set
+# CONFIG_WLAN_VENDOR_MARVELL is not set
+CONFIG_MT7601U=m
+# CONFIG_WLAN_VENDOR_RALINK is not set
+CONFIG_RTL8187=y
+CONFIG_RTL8XXXU=y
+CONFIG_RTL8XXXU_UNTESTED=y
+# CONFIG_WLAN_VENDOR_RSI is not set
+# CONFIG_WLAN_VENDOR_ST is not set
+# CONFIG_WLAN_VENDOR_TI is not set
+# CONFIG_WLAN_VENDOR_ZYDAS is not set
+CONFIG_INPUT_SPARSEKMAP=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_ADP5588=m
+CONFIG_KEYBOARD_ADP5589=m
+CONFIG_KEYBOARD_QT1070=m
+CONFIG_KEYBOARD_QT2160=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_GPIO_POLLED=m
+CONFIG_KEYBOARD_TCA6416=m
+CONFIG_KEYBOARD_TCA8418=m
+CONFIG_KEYBOARD_LM8323=m
+CONFIG_KEYBOARD_LM8333=m
+CONFIG_KEYBOARD_MAX7359=m
+CONFIG_KEYBOARD_MCS=m
+CONFIG_KEYBOARD_MPR121=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_KEYBOARD_OPENCORES=m
+CONFIG_KEYBOARD_STOWAWAY=m
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_PS2_SENTELIC=y
+CONFIG_MOUSE_PS2_TOUCHKIT=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_CYAPA=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_MOUSE_SYNAPTICS_I2C=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+CONFIG_JOYSTICK_AS5011=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TABLET=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879_I2C=m
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_BU21013=m
+CONFIG_TOUCHSCREEN_CYTTSP_CORE=m
+CONFIG_TOUCHSCREEN_CYTTSP_I2C=m
+CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m
+CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m
+CONFIG_TOUCHSCREEN_DYNAPRO=m
+CONFIG_TOUCHSCREEN_HAMPSHIRE=m
+CONFIG_TOUCHSCREEN_EETI=m
+CONFIG_TOUCHSCREEN_FUJITSU=m
+CONFIG_TOUCHSCREEN_ILI210X=m
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_WACOM_W8001=m
+CONFIG_TOUCHSCREEN_WACOM_I2C=m
+CONFIG_TOUCHSCREEN_MAX11801=m
+CONFIG_TOUCHSCREEN_MCS5000=m
+CONFIG_TOUCHSCREEN_MMS114=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_EDT_FT5X06=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_PIXCIR=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_TOUCHSCREEN_TSC_SERIO=m
+CONFIG_TOUCHSCREEN_TSC2007=m
+CONFIG_TOUCHSCREEN_ST1232=m
+CONFIG_TOUCHSCREEN_TPS6507X=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AD714X=m
+CONFIG_INPUT_BMA150=m
+CONFIG_INPUT_MMA8450=m
+CONFIG_INPUT_MPU3050=m
+CONFIG_INPUT_KXTJ9=m
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_PCF8574=m
+CONFIG_INPUT_ADXL34X=m
+CONFIG_INPUT_CMA3000=m
+CONFIG_INPUT_CMA3000_I2C=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_RAW=m
+CONFIG_SERIO_ALTERA_PS2=m
+CONFIG_SERIO_PS2MULT=m
+CONFIG_SERIO_ARC_PS2=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_DW=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_TTY_PRINTK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=y
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_HW_RANDOM_TPM=m
+CONFIG_TCG_TIS_I2C_ATMEL=m
+CONFIG_TCG_TIS_I2C_INFINEON=m
+CONFIG_TCG_TIS_I2C_NUVOTON=m
+CONFIG_TCG_ATMEL=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX_PCA9541=m
+CONFIG_I2C_DESIGNWARE_PLATFORM=m
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_SIMTEC=m
+CONFIG_I2C_XILINX=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_TAOS_EVM=m
+CONFIG_I2C_STUB=m
+CONFIG_PPS=m
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_GPIOLIB=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_GENERIC_PLATFORM=y
+CONFIG_POWER_RESET=y
+# CONFIG_HWMON is not set
+CONFIG_SSB=m
+CONFIG_BCMA=m
+CONFIG_BCMA_HOST_SOC=y
+CONFIG_BCMA_DRIVER_GMAC_CMN=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+# CONFIG_USB_GSPCA is not set
+CONFIG_FB=y
+CONFIG_FB_TILEBLITTING=y
+CONFIG_FB_SIMPLE=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_HID_A4TECH=m
+CONFIG_HID_ACRUX=m
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=m
+CONFIG_HID_AUREAL=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EMS_FF=m
+CONFIG_HID_ELECOM=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KEYTOUCH=m
+CONFIG_HID_KYE=m
+CONFIG_HID_WALTOP=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_ICADE=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LCPOWER=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_LOGITECH_HIDPP=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MAGICMOUSE=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_HID_ORTEK=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_PICOLCD=m
+CONFIG_HID_PICOLCD_LEDS=y
+CONFIG_HID_PRIMAX=m
+CONFIG_HID_SAITEK=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SPEEDLINK=m
+CONFIG_HID_STEELSERIES=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_RMI=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TIVO=m
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THINGM=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=m
+CONFIG_HID_WIIMOTE=m
+CONFIG_HID_XINMO=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
+CONFIG_HID_ZYDACRON=m
+CONFIG_HID_SENSOR_HUB=m
+CONFIG_HID_PID=y
+CONFIG_I2C_HID=m
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_STORAGE=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LM3530=m
+CONFIG_LEDS_LM3642=m
+CONFIG_LEDS_PCA9532=m
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_LP5521=m
+CONFIG_LEDS_LP5523=m
+CONFIG_LEDS_LP5562=m
+CONFIG_LEDS_LP8501=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_PCA963X=m
+CONFIG_LEDS_BD2802=m
+CONFIG_LEDS_TCA6507=m
+CONFIG_LEDS_LM355x=m
+CONFIG_LEDS_BLINKM=m
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TRANSIENT=y
+CONFIG_LEDS_TRIGGER_CAMERA=y
+CONFIG_LEDS_TRIGGER_PANIC=y
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_STE_MODEM_RPROC=m
+CONFIG_PM_DEVFREQ=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_DEVFREQ_GOV_PERFORMANCE=y
+CONFIG_DEVFREQ_GOV_POWERSAVE=y
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_NTFS_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_RBTREE_TEST=m
+CONFIG_INTERVAL_TREE_TEST=m
+CONFIG_PERCPU_TEST=m
+CONFIG_TEST_STRING_HELPERS=m
+CONFIG_TEST_KSTRTOX=m
+CONFIG_PERSISTENT_KEYRINGS=y
+CONFIG_TRUSTED_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_PATH=y
+CONFIG_SECURITY_YAMA=y
+CONFIG_INTEGRITY_SIGNATURE=y
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
+CONFIG_IMA=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_EVM=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_CMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRC_CCITT=m
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_CRC8=m
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_TEST=m
+CONFIG_CORDIC=m
+CONFIG_DDR=y
diff --git a/arch/csky/configs/qemu_ck807_defconfig b/arch/csky/configs/qemu_ck807_defconfig
new file mode 100644
index 0000000..0591cbc
--- /dev/null
+++ b/arch/csky/configs/qemu_ck807_defconfig
@@ -0,0 +1,541 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_DEFAULT_HOSTNAME="github.com/c-sky"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_FHANDLE is not set
+CONFIG_USELIB=y
+CONFIG_AUDIT=y
+CONFIG_IRQ_DOMAIN_DEBUG=y
+CONFIG_NO_HZ_IDLE=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_RELAY=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_AIO is not set
+CONFIG_USERFAULTFD=y
+CONFIG_EMBEDDED=y
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_AIX_PARTITION=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_DEFAULT_DEADLINE=y
+CONFIG_NATIONALCHIP_TIMER=y
+CONFIG_NATIONALCHIP_IRQ=y
+CONFIG_CSKY_IRQ=y
+CONFIG_CSKYMAC=y
+CONFIG_CPU_CK807=y
+CONFIG_CPU_HAS_FPU=y
+CONFIG_RAM_BASE=0x0
+# CONFIG_SUSPEND is not set
+# CONFIG_COMPACTION is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=y
+CONFIG_AD525X_DPOT=m
+CONFIG_AD525X_DPOT_I2C=m
+CONFIG_DUMMY_IRQ=m
+CONFIG_ICS932S401=m
+CONFIG_ENCLOSURE_SERVICES=m
+CONFIG_APDS9802ALS=m
+CONFIG_ISL29003=m
+CONFIG_ISL29020=m
+CONFIG_SENSORS_TSL2550=m
+CONFIG_SENSORS_BH1770=m
+CONFIG_SENSORS_APDS990X=m
+CONFIG_HMC6352=m
+CONFIG_DS1682=m
+CONFIG_USB_SWITCH_FSA9480=m
+CONFIG_SRAM=y
+CONFIG_C2PORT=m
+CONFIG_EEPROM_AT24=m
+CONFIG_EEPROM_LEGACY=m
+CONFIG_EEPROM_MAX6875=m
+CONFIG_EEPROM_93CX6=m
+CONFIG_SENSORS_LIS3_I2C=m
+CONFIG_ALTERA_STAPL=m
+CONFIG_ECHO=m
+CONFIG_SCSI=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_CADENCE is not set
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_NET_VENDOR_SYNOPSYS is not set
+# CONFIG_NET_VENDOR_VIA is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_USB_NET_DRIVERS is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_SPARSEKMAP=m
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_ADP5588=m
+CONFIG_KEYBOARD_ADP5589=m
+CONFIG_KEYBOARD_QT1070=m
+CONFIG_KEYBOARD_QT2160=m
+CONFIG_KEYBOARD_LKKBD=m
+CONFIG_KEYBOARD_TCA6416=m
+CONFIG_KEYBOARD_TCA8418=m
+CONFIG_KEYBOARD_LM8323=m
+CONFIG_KEYBOARD_LM8333=m
+CONFIG_KEYBOARD_MAX7359=m
+CONFIG_KEYBOARD_MCS=m
+CONFIG_KEYBOARD_MPR121=m
+CONFIG_KEYBOARD_NEWTON=m
+CONFIG_KEYBOARD_OPENCORES=m
+CONFIG_KEYBOARD_STOWAWAY=m
+CONFIG_KEYBOARD_SUNKBD=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_PS2_SENTELIC=y
+CONFIG_MOUSE_PS2_TOUCHKIT=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_MOUSE_CYAPA=m
+CONFIG_MOUSE_VSXXXAA=m
+CONFIG_MOUSE_SYNAPTICS_I2C=m
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_ANALOG=m
+CONFIG_JOYSTICK_A3D=m
+CONFIG_JOYSTICK_ADI=m
+CONFIG_JOYSTICK_COBRA=m
+CONFIG_JOYSTICK_GF2K=m
+CONFIG_JOYSTICK_GRIP=m
+CONFIG_JOYSTICK_GRIP_MP=m
+CONFIG_JOYSTICK_GUILLEMOT=m
+CONFIG_JOYSTICK_INTERACT=m
+CONFIG_JOYSTICK_SIDEWINDER=m
+CONFIG_JOYSTICK_TMDC=m
+CONFIG_JOYSTICK_IFORCE=m
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_WARRIOR=m
+CONFIG_JOYSTICK_MAGELLAN=m
+CONFIG_JOYSTICK_SPACEORB=m
+CONFIG_JOYSTICK_SPACEBALL=m
+CONFIG_JOYSTICK_STINGER=m
+CONFIG_JOYSTICK_TWIDJOY=m
+CONFIG_JOYSTICK_ZHENHUA=m
+CONFIG_JOYSTICK_AS5011=m
+CONFIG_JOYSTICK_JOYDUMP=m
+CONFIG_INPUT_TABLET=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_AD7879=m
+CONFIG_TOUCHSCREEN_AD7879_I2C=m
+CONFIG_TOUCHSCREEN_ATMEL_MXT=m
+CONFIG_TOUCHSCREEN_BU21013=m
+CONFIG_TOUCHSCREEN_CYTTSP_CORE=m
+CONFIG_TOUCHSCREEN_CYTTSP_I2C=m
+CONFIG_TOUCHSCREEN_CYTTSP4_CORE=m
+CONFIG_TOUCHSCREEN_CYTTSP4_I2C=m
+CONFIG_TOUCHSCREEN_DYNAPRO=m
+CONFIG_TOUCHSCREEN_HAMPSHIRE=m
+CONFIG_TOUCHSCREEN_EETI=m
+CONFIG_TOUCHSCREEN_FUJITSU=m
+CONFIG_TOUCHSCREEN_ILI210X=m
+CONFIG_TOUCHSCREEN_GUNZE=m
+CONFIG_TOUCHSCREEN_ELO=m
+CONFIG_TOUCHSCREEN_WACOM_W8001=m
+CONFIG_TOUCHSCREEN_WACOM_I2C=m
+CONFIG_TOUCHSCREEN_MAX11801=m
+CONFIG_TOUCHSCREEN_MCS5000=m
+CONFIG_TOUCHSCREEN_MMS114=m
+CONFIG_TOUCHSCREEN_MTOUCH=m
+CONFIG_TOUCHSCREEN_INEXIO=m
+CONFIG_TOUCHSCREEN_MK712=m
+CONFIG_TOUCHSCREEN_PENMOUNT=m
+CONFIG_TOUCHSCREEN_EDT_FT5X06=m
+CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
+CONFIG_TOUCHSCREEN_TOUCHWIN=m
+CONFIG_TOUCHSCREEN_PIXCIR=m
+CONFIG_TOUCHSCREEN_TOUCHIT213=m
+CONFIG_TOUCHSCREEN_TSC_SERIO=m
+CONFIG_TOUCHSCREEN_TSC2007=m
+CONFIG_TOUCHSCREEN_ST1232=m
+CONFIG_TOUCHSCREEN_TPS6507X=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AD714X=m
+CONFIG_INPUT_BMA150=m
+CONFIG_INPUT_MMA8450=m
+CONFIG_INPUT_MPU3050=m
+CONFIG_INPUT_KXTJ9=m
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_PCF8574=m
+CONFIG_INPUT_ADXL34X=m
+CONFIG_INPUT_CMA3000=m
+CONFIG_INPUT_CMA3000_I2C=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_RAW=m
+CONFIG_SERIO_ALTERA_PS2=m
+CONFIG_SERIO_PS2MULT=m
+CONFIG_SERIO_ARC_PS2=m
+CONFIG_GAMEPORT_NS558=m
+CONFIG_GAMEPORT_L4=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_TTY_PRINTK=y
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_IPMI_HANDLER=y
+CONFIG_IPMI_DEVICE_INTERFACE=m
+CONFIG_IPMI_SI=m
+CONFIG_IPMI_WATCHDOG=m
+CONFIG_IPMI_POWEROFF=m
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_HW_RANDOM_TPM=m
+CONFIG_TCG_TIS_I2C_ATMEL=m
+CONFIG_TCG_TIS_I2C_INFINEON=m
+CONFIG_TCG_TIS_I2C_NUVOTON=m
+CONFIG_TCG_ATMEL=m
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MUX_PCA9541=m
+CONFIG_I2C_DESIGNWARE_PLATFORM=m
+CONFIG_I2C_OCORES=m
+CONFIG_I2C_PCA_PLATFORM=m
+CONFIG_I2C_SIMTEC=m
+CONFIG_I2C_XILINX=m
+CONFIG_I2C_PARPORT_LIGHT=m
+CONFIG_I2C_TAOS_EVM=m
+CONFIG_I2C_STUB=m
+CONFIG_PPS_CLIENT_LDISC=m
+CONFIG_PPS_CLIENT_GPIO=m
+CONFIG_POWER_RESET=y
+# CONFIG_HWMON is not set
+CONFIG_SSB=m
+CONFIG_BCMA=m
+CONFIG_BCMA_HOST_SOC=y
+CONFIG_BCMA_DRIVER_GMAC_CMN=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+# CONFIG_USB_GSPCA is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_PLATFORM=m
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=m
+CONFIG_BACKLIGHT_ADP8860=m
+CONFIG_BACKLIGHT_ADP8870=m
+CONFIG_BACKLIGHT_LM3639=m
+CONFIG_BACKLIGHT_LV5207LP=m
+CONFIG_BACKLIGHT_BD6107=m
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_GENERIC is not set
+CONFIG_HID_A4TECH=m
+CONFIG_HID_ACRUX=m
+CONFIG_HID_ACRUX_FF=y
+CONFIG_HID_APPLE=m
+CONFIG_HID_AUREAL=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+CONFIG_HID_DRAGONRISE=m
+CONFIG_DRAGONRISE_FF=y
+CONFIG_HID_EMS_FF=m
+CONFIG_HID_ELECOM=m
+CONFIG_HID_EZKEY=m
+CONFIG_HID_KEYTOUCH=m
+CONFIG_HID_KYE=m
+CONFIG_HID_WALTOP=m
+CONFIG_HID_GYRATION=m
+CONFIG_HID_ICADE=m
+CONFIG_HID_TWINHAN=m
+CONFIG_HID_KENSINGTON=m
+CONFIG_HID_LCPOWER=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_LOGITECH_HIDPP=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MAGICMOUSE=m
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MONTEREY=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_HID_ORTEK=m
+CONFIG_HID_PANTHERLORD=m
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PETALYNX=m
+CONFIG_HID_PICOLCD=m
+CONFIG_HID_PICOLCD_BACKLIGHT=y
+CONFIG_HID_PICOLCD_LCD=y
+CONFIG_HID_PICOLCD_LEDS=y
+CONFIG_HID_PRIMAX=m
+CONFIG_HID_SAITEK=m
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SPEEDLINK=m
+CONFIG_HID_STEELSERIES=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_RMI=m
+CONFIG_HID_GREENASIA=m
+CONFIG_GREENASIA_FF=y
+CONFIG_HID_SMARTJOYPLUS=m
+CONFIG_SMARTJOYPLUS_FF=y
+CONFIG_HID_TIVO=m
+CONFIG_HID_TOPSEED=m
+CONFIG_HID_THINGM=m
+CONFIG_HID_THRUSTMASTER=m
+CONFIG_THRUSTMASTER_FF=y
+CONFIG_HID_WACOM=m
+CONFIG_HID_WIIMOTE=m
+CONFIG_HID_XINMO=m
+CONFIG_HID_ZEROPLUS=m
+CONFIG_ZEROPLUS_FF=y
+CONFIG_HID_ZYDACRON=m
+CONFIG_HID_SENSOR_HUB=m
+CONFIG_I2C_HID=m
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LM3530=m
+CONFIG_LEDS_LM3642=m
+CONFIG_LEDS_PCA9532=m
+CONFIG_LEDS_LP3944=m
+CONFIG_LEDS_LP5521=m
+CONFIG_LEDS_LP5523=m
+CONFIG_LEDS_LP5562=m
+CONFIG_LEDS_LP8501=m
+CONFIG_LEDS_PCA955X=m
+CONFIG_LEDS_PCA963X=m
+CONFIG_LEDS_BD2802=m
+CONFIG_LEDS_TCA6507=m
+CONFIG_LEDS_LM355x=m
+CONFIG_LEDS_BLINKM=m
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_ONESHOT=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_BACKLIGHT=m
+CONFIG_LEDS_TRIGGER_CPU=y
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+CONFIG_LEDS_TRIGGER_TRANSIENT=m
+CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_VIRTIO_BALLOON=y
+CONFIG_VIRTIO_MMIO=y
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_STE_MODEM_RPROC=m
+CONFIG_PM_DEVFREQ=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_DEVFREQ_GOV_PERFORMANCE=y
+CONFIG_DEVFREQ_GOV_POWERSAVE=y
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_GENERIC_PHY=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=m
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_UTF8=y
+CONFIG_NTFS_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_CHILDREN=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_CRAMFS=y
+CONFIG_ROMFS_FS=y
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_MAC_ROMAN=m
+CONFIG_NLS_MAC_CELTIC=m
+CONFIG_NLS_MAC_CENTEURO=m
+CONFIG_NLS_MAC_CROATIAN=m
+CONFIG_NLS_MAC_CYRILLIC=m
+CONFIG_NLS_MAC_GAELIC=m
+CONFIG_NLS_MAC_GREEK=m
+CONFIG_NLS_MAC_ICELAND=m
+CONFIG_NLS_MAC_INUIT=m
+CONFIG_NLS_MAC_ROMANIAN=m
+CONFIG_NLS_MAC_TURKISH=m
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_RBTREE_TEST=m
+CONFIG_INTERVAL_TREE_TEST=m
+CONFIG_PERCPU_TEST=m
+CONFIG_TEST_STRING_HELPERS=m
+CONFIG_TEST_KSTRTOX=m
+CONFIG_PERSISTENT_KEYRINGS=y
+CONFIG_TRUSTED_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_SECURITY_PATH=y
+CONFIG_SECURITY_YAMA=y
+CONFIG_INTEGRITY_SIGNATURE=y
+CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
+CONFIG_IMA=y
+CONFIG_IMA_APPRAISE=y
+CONFIG_EVM=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_CMAC=m
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_CRC32=m
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_DES=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRC_CCITT=m
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_CRC8=m
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_TEST=m
+CONFIG_CORDIC=m
+CONFIG_DDR=y
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 18/19] clocksource: add timer-nationalchip.c
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (16 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 17/19] csky: defconfig Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-18 22:07   ` Daniel Lezcano
  2018-03-19  4:15   ` Mark Rutland
  2018-03-18 19:51 ` [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c Guo Ren
                   ` (2 subsequent siblings)
  20 siblings, 2 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/timer-nationalchip.c | 149 +++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)
 create mode 100644 drivers/clocksource/timer-nationalchip.c

diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index d6dec44..d091712 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -76,3 +76,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
 obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
 obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
 obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
+obj-$(CONFIG_CSKY)			+= timer-nationalchip.o
diff --git a/drivers/clocksource/timer-nationalchip.c b/drivers/clocksource/timer-nationalchip.c
new file mode 100644
index 0000000..1279d64
--- /dev/null
+++ b/drivers/clocksource/timer-nationalchip.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/profile.h>
+#include <linux/irq.h>
+#include <linux/rtc.h>
+#include <linux/sizes.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/sched_clock.h>
+
+#define NC_VA_COUNTER_1_STATUS		(void *)(timer_reg + 0x00)
+#define NC_VA_COUNTER_1_VALUE		(void *)(timer_reg + 0x04)
+#define NC_VA_COUNTER_1_CONTROL		(void *)(timer_reg + 0x10)
+#define NC_VA_COUNTER_1_CONFIG		(void *)(timer_reg + 0x20)
+#define NC_VA_COUNTER_1_PRE		(void *)(timer_reg + 0x24)
+#define NC_VA_COUNTER_1_INI		(void *)(timer_reg + 0x28)
+#define NC_VA_COUNTER_2_STATUS		(void *)(timer_reg + 0x40)
+#define NC_VA_COUNTER_2_VALUE		(void *)(timer_reg + 0x44)
+#define NC_VA_COUNTER_2_CONTROL		(void *)(timer_reg + 0x50)
+#define NC_VA_COUNTER_2_CONFIG		(void *)(timer_reg + 0x60)
+#define NC_VA_COUNTER_2_PRE		(void *)(timer_reg + 0x64)
+#define NC_VA_COUNTER_2_INI		(void *)(timer_reg + 0x68)
+#define NC_VA_COUNTER_3_STATUS		(void *)(timer_reg + 0x80)
+#define NC_VA_COUNTER_3_VALUE		(void *)(timer_reg + 0x84)
+#define NC_VA_COUNTER_3_CONTROL		(void *)(timer_reg + 0x90)
+#define NC_VA_COUNTER_3_CONFIG		(void *)(timer_reg + 0xa0)
+#define NC_VA_COUNTER_3_PRE		(void *)(timer_reg + 0xa4)
+#define NC_VA_COUNTER_3_INI		(void *)(timer_reg + 0xa8)
+
+static unsigned int timer_reg;
+
+static inline void timer_reset(void)
+{
+	__raw_writel(0x1,	NC_VA_COUNTER_1_CONTROL);
+	__raw_writel(0x0,	NC_VA_COUNTER_1_CONTROL);
+	__raw_writel(0x3,	NC_VA_COUNTER_1_CONFIG);
+	__raw_writel(26,	NC_VA_COUNTER_1_PRE);
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *dev = (struct clock_event_device *) dev_id;
+
+	__raw_writel(1, NC_VA_COUNTER_1_STATUS);
+
+	dev->event_handler(dev);
+
+	return IRQ_HANDLED;
+}
+
+static int nc_timer_set_periodic(struct clock_event_device *dev)
+{
+	timer_reset();
+
+	__raw_writel(0xFFFFD8EF, NC_VA_COUNTER_1_INI);
+	__raw_writel(0x2, NC_VA_COUNTER_1_CONTROL);
+
+	return 0;
+}
+
+static int nc_timer_set_next_event(unsigned long delta, struct clock_event_device *evt)
+{
+	__raw_writel(0x1,		NC_VA_COUNTER_1_CONTROL);
+	__raw_writel(ULONG_MAX - delta, NC_VA_COUNTER_1_INI);
+	__raw_writel(0x2,		NC_VA_COUNTER_1_CONTROL);
+	return 0;
+}
+
+static int nc_timer_shutdown(struct clock_event_device *dev)
+{
+	__raw_writel(0x0, NC_VA_COUNTER_1_CONTROL);
+	__raw_writel(0x0, NC_VA_COUNTER_1_CONFIG);
+
+	return 0;
+}
+
+static struct clock_event_device nc_ced = {
+	.name			= "nationalchip-clkevent",
+	.features		= CLOCK_EVT_FEAT_PERIODIC
+				| CLOCK_EVT_FEAT_ONESHOT,
+	.rating			= 200,
+	.set_state_shutdown	= nc_timer_shutdown,
+	.set_state_periodic	= nc_timer_set_periodic,
+	.set_next_event		= nc_timer_set_next_event,
+};
+
+static u64 notrace nc_sched_clock_read(void)
+{
+	return (u64) __raw_readl(NC_VA_COUNTER_2_VALUE);
+}
+
+static void nc_csd_enable(void)
+{
+	__raw_writel(0x1, NC_VA_COUNTER_2_CONTROL);
+	__raw_writel(0x0, NC_VA_COUNTER_2_CONTROL);
+	__raw_writel(0x1, NC_VA_COUNTER_2_CONFIG);
+
+	__raw_writel(26,NC_VA_COUNTER_2_PRE);
+	__raw_writel(0, NC_VA_COUNTER_2_INI);
+	__raw_writel(0x2, NC_VA_COUNTER_2_CONTROL);
+}
+
+static int __init nc_timer_init(struct device_node *np)
+{
+	unsigned int irq;
+	unsigned int freq;
+
+	/* parse from devicetree */
+	timer_reg = (unsigned int) of_iomap(np, 0);
+	if (!timer_reg)
+		panic("%s, of_iomap err.\n", __func__);
+
+	irq = irq_of_parse_and_map(np, 0);
+	if (!irq)
+		panic("%s, irq_parse err.\n", __func__);
+
+	if (of_property_read_u32(np, "clock-frequency", &freq))
+		panic("%s, clock-frequency error.\n", __func__);
+
+	pr_info("Nationalchip Timer Init, reg: %x, irq: %d, freq: %d.\n",
+		timer_reg, irq, freq);
+
+	/* setup irq */
+	if (request_irq(irq, timer_interrupt, IRQF_TIMER, np->name, &nc_ced))
+		panic("%s timer_interrupt error.\n", __func__);
+
+	/* register */
+	clockevents_config_and_register(&nc_ced, freq, 1, ULONG_MAX);
+
+	nc_csd_enable();
+	clocksource_mmio_init(NC_VA_COUNTER_2_VALUE, "nationalchip-clksource", freq, 200, 32, clocksource_mmio_readl_up);
+
+	sched_clock_register(nc_sched_clock_read, 32, freq);
+
+	return 0;
+}
+CLOCKSOURCE_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (17 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 18/19] clocksource: add timer-nationalchip.c Guo Ren
@ 2018-03-18 19:51 ` Guo Ren
  2018-03-19  4:26   ` Mark Rutland
  2018-03-19 13:30   ` Thomas Gleixner
  2018-03-18 20:25 ` [PATCH 00/19] C-SKY(csky) Linux Kernel Port Joe Perches
  2018-03-26 13:30 ` Arnd Bergmann
  20 siblings, 2 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-18 19:51 UTC (permalink / raw)
  To: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx, Guo Ren

Signed-off-by: Guo Ren <ren_guo@c-sky.com>
---
 drivers/irqchip/Makefile           |   1 +
 drivers/irqchip/irq-csky.c         | 151 ++++++++++++++++++++++++++++
 drivers/irqchip/irq-nationalchip.c | 196 +++++++++++++++++++++++++++++++++++++
 3 files changed, 348 insertions(+)
 create mode 100644 drivers/irqchip/irq-csky.c
 create mode 100644 drivers/irqchip/irq-nationalchip.c

diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d27e3e3..7b98917 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -85,3 +85,4 @@ obj-$(CONFIG_IRQ_UNIPHIER_AIDET)	+= irq-uniphier-aidet.o
 obj-$(CONFIG_ARCH_SYNQUACER)		+= irq-sni-exiu.o
 obj-$(CONFIG_MESON_IRQ_GPIO)		+= irq-meson-gpio.o
 obj-$(CONFIG_GOLDFISH_PIC) 		+= irq-goldfish-pic.o
+obj-$(CONFIG_CSKY)			+= irq-csky.o irq-nationalchip.o
diff --git a/drivers/irqchip/irq-csky.c b/drivers/irqchip/irq-csky.c
new file mode 100644
index 0000000..77041e3
--- /dev/null
+++ b/drivers/irqchip/irq-csky.c
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+static unsigned int intc_reg;
+
+#define CK_VA_INTC_ICR		(void *)(intc_reg + 0x00)	/* Interrupt control register(High 16bits) */
+#define CK_VA_INTC_ISR		(void *)(intc_reg + 0x00)	/* Interrupt status register(Low 16bits) */
+#define CK_VA_INTC_NEN31_00	(void *)(intc_reg + 0x10)	/* Normal interrupt enable register Low */
+#define	CK_VA_INTC_NEN63_32	(void *)(intc_reg + 0x28)	/* Normal interrupt enable register High */
+#define CK_VA_INTC_IFR31_00	(void *)(intc_reg + 0x08)	/* Normal interrupt force register Low */
+#define CK_VA_INTC_IFR63_32	(void *)(intc_reg + 0x20)	/* Normal interrupt force register High */
+#define	CK_VA_INTC_SOURCE	(void *)(intc_reg + 0x40)	/* Proiority Level Select Registers 0 */
+
+static void ck_irq_mask(struct irq_data *d)
+{
+	unsigned int temp, irq;
+
+	irq = d->irq;
+
+	if (irq < 32) {
+		temp = __raw_readl(CK_VA_INTC_NEN31_00);
+		temp &= ~(1 << irq);
+		__raw_writel(temp, CK_VA_INTC_NEN31_00);
+	} else {
+		temp = __raw_readl(CK_VA_INTC_NEN63_32);
+		temp &= ~(1 << (irq -32));
+		__raw_writel(temp, CK_VA_INTC_NEN63_32);
+	}
+}
+
+static void ck_irq_unmask(struct irq_data *d)
+{
+	unsigned int temp, irq;
+
+	irq = d->irq;
+
+	/* set IFR to support rising edge triggering */
+	if (irq < 32) {
+		temp = __raw_readl(CK_VA_INTC_IFR31_00);
+		temp &= ~(1 << irq);
+		__raw_writel(temp, CK_VA_INTC_IFR31_00);
+	} else {
+		temp = __raw_readl(CK_VA_INTC_IFR63_32);
+		temp &= ~(1 << (irq -32));
+		__raw_writel(temp, CK_VA_INTC_IFR63_32);
+	}
+
+	if (irq < 32) {
+		temp = __raw_readl(CK_VA_INTC_NEN31_00);
+		temp |= 1 << irq;
+		__raw_writel(temp, CK_VA_INTC_NEN31_00);
+	} else {
+		temp = __raw_readl(CK_VA_INTC_NEN63_32);
+		temp |= 1 << (irq -32);
+		__raw_writel(temp, CK_VA_INTC_NEN63_32);
+	}
+}
+
+static struct irq_chip ck_irq_chip = {
+	.name		= "csky_intc_v1",
+	.irq_mask	= ck_irq_mask,
+	.irq_unmask	= ck_irq_unmask,
+};
+
+static int ck_irq_map(struct irq_domain *h, unsigned int virq,
+				irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &ck_irq_chip, handle_level_irq);
+	return 0;
+}
+
+static const struct irq_domain_ops ck_irq_ops = {
+	.map	= ck_irq_map,
+	.xlate	= irq_domain_xlate_onecell,
+};
+
+static unsigned int ck_get_irqno(void)
+{
+	unsigned int temp;
+	temp = __raw_readl(CK_VA_INTC_ISR);
+	return temp & 0x3f;
+};
+
+static int __init
+__intc_init(struct device_node *np, struct device_node *parent, bool ave)
+{
+	struct irq_domain *root_domain;
+	int i;
+
+	csky_get_auto_irqno = ck_get_irqno;
+
+	if (parent)
+		panic("pic not a root intc\n");
+
+	intc_reg = (unsigned int)of_iomap(np, 0);
+	if (!intc_reg)
+		panic("%s, of_iomap err.\n", __func__);
+
+	__raw_writel(0, CK_VA_INTC_NEN31_00);
+	__raw_writel(0,	CK_VA_INTC_NEN63_32);
+
+	if (ave == true)
+		__raw_writel( 0xc0000000, CK_VA_INTC_ICR);
+	else
+		__raw_writel( 0x0, CK_VA_INTC_ICR);
+	/*
+	 * csky irq ctrl has 64 sources.
+	 */
+	#define INTC_IRQS 64
+	for (i=0; i<INTC_IRQS; i=i+4)
+		__raw_writel((i+3)|((i+2)<<8)|((i+1)<<16)|(i<<24),
+				CK_VA_INTC_SOURCE + i);
+
+	root_domain = irq_domain_add_legacy(np, INTC_IRQS, 0, 0, &ck_irq_ops, NULL);
+	if (!root_domain)
+		panic("root irq domain not available\n");
+
+	irq_set_default_host(root_domain);
+
+	return 0;
+}
+
+static int __init
+intc_init(struct device_node *np, struct device_node *parent)
+{
+
+	return __intc_init(np, parent, false);
+}
+IRQCHIP_DECLARE(csky_intc_v1, "csky,intc-v1", intc_init);
+
+/*
+ * use auto vector exceptions 10 for interrupt.
+ */
+static int __init
+intc_init_ave(struct device_node *np, struct device_node *parent)
+{
+	return __intc_init(np, parent, true);
+}
+IRQCHIP_DECLARE(csky_intc_v1_ave, "csky,intc-v1,ave", intc_init_ave);
+
diff --git a/drivers/irqchip/irq-nationalchip.c b/drivers/irqchip/irq-nationalchip.c
new file mode 100644
index 0000000..8c09ebd
--- /dev/null
+++ b/drivers/irqchip/irq-nationalchip.c
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/module.h>
+#include <linux/irqdomain.h>
+#include <linux/irqchip.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#define NC_VA_INTC_NINT31_00		(void *)(intc_reg + 0x00)
+#define NC_VA_INTC_NINT63_32		(void *)(intc_reg + 0x04)
+#define NC_VA_INTC_NPEND31_00		(void *)(intc_reg + 0x10)
+#define NC_VA_INTC_NPEND63_32		(void *)(intc_reg + 0x14)
+#define NC_VA_INTC_NENSET31_00		(void *)(intc_reg + 0x20)
+#define NC_VA_INTC_NENSET63_32		(void *)(intc_reg + 0x24)
+#define NC_VA_INTC_NENCLR31_00		(void *)(intc_reg + 0x30)
+#define NC_VA_INTC_NENCLR63_32		(void *)(intc_reg + 0x34)
+#define NC_VA_INTC_NEN31_00		(void *)(intc_reg + 0x40)
+#define NC_VA_INTC_NEN63_32		(void *)(intc_reg + 0x44)
+#define NC_VA_INTC_NMASK31_00		(void *)(intc_reg + 0x50)
+#define NC_VA_INTC_NMASK63_32		(void *)(intc_reg + 0x54)
+#define NC_VA_INTC_SOURCE		(void *)(intc_reg + 0x60)
+
+static unsigned int intc_reg;
+
+static void nc_irq_mask(struct irq_data *d)
+{
+	unsigned int mask, irq;
+
+	irq = d->irq;
+
+	if (irq < 32) {
+		mask = __raw_readl(NC_VA_INTC_NMASK31_00);
+		mask |= 1 << irq;
+		__raw_writel(mask, NC_VA_INTC_NMASK31_00);
+	} else {
+		mask = __raw_readl(NC_VA_INTC_NMASK63_32);
+		mask |= 1 << (irq - 32);
+		__raw_writel(mask, NC_VA_INTC_NMASK63_32);
+	}
+}
+
+static void nc_irq_unmask(struct irq_data *d)
+{
+	unsigned int mask, irq;
+
+	irq = d->irq;
+
+	if (irq < 32) {
+		mask = __raw_readl(NC_VA_INTC_NMASK31_00);
+		mask &= ~( 1 << irq);
+		__raw_writel(mask, NC_VA_INTC_NMASK31_00);
+	} else {
+		mask = __raw_readl( NC_VA_INTC_NMASK63_32);
+		mask &= ~(1 << (irq - 32));
+		__raw_writel(mask, NC_VA_INTC_NMASK63_32);
+	}
+}
+
+static void nc_irq_en(struct irq_data *d)
+{
+	unsigned int mask, irq;
+
+	irq = d->irq;
+
+	if (irq < 32) {
+		mask = 1 << irq;
+		__raw_writel(mask, NC_VA_INTC_NENSET31_00);
+	} else {
+		mask = 1 << (irq - 32);
+		__raw_writel(mask, NC_VA_INTC_NENSET63_32);
+	}
+
+	nc_irq_unmask(d);
+}
+
+static void nc_irq_dis(struct irq_data *d)
+{
+	unsigned int mask, irq;
+
+	irq = d->irq;
+
+	if (irq < 32) {
+		mask = 1 << irq;
+		__raw_writel(mask, NC_VA_INTC_NENCLR31_00);
+	} else {
+		mask = 1 << (irq - 32);
+		__raw_writel(mask, NC_VA_INTC_NENCLR63_32);
+	}
+
+	nc_irq_mask(d);
+}
+
+struct irq_chip nc_irq_chip = {
+	.name =		"nationalchip_intc_v1",
+	.irq_mask =	nc_irq_mask,
+	.irq_unmask =	nc_irq_unmask,
+	.irq_enable =	nc_irq_en,
+	.irq_disable =	nc_irq_dis,
+};
+
+inline int ff1_64(unsigned int hi, unsigned int lo)
+{
+	int result;
+	asm volatile(
+		"ff1 %0\n"
+		:"=r"(hi)
+		:"r"(hi)
+		:
+	);
+
+	asm volatile(
+		"ff1 %0\n"
+		:"=r"(lo)
+		:"r"(lo)
+		:
+	);
+	if( lo != 32 )
+		result = 31-lo;
+	else if( hi != 32 ) result = 31-hi + 32;
+	else {
+		printk("nc_get_irqno error hi:%x, lo:%x.\n", hi, lo);
+		result = NR_IRQS;
+	}
+	return result;
+}
+
+unsigned int nc_get_irqno(void)
+{
+	unsigned int nint64hi, nint64lo, irq_no;
+
+	nint64lo = __raw_readl(NC_VA_INTC_NINT31_00);
+	nint64hi = __raw_readl(NC_VA_INTC_NINT63_32);
+	irq_no = ff1_64(nint64hi, nint64lo);
+
+	return irq_no;
+}
+
+static int irq_map(struct irq_domain *h, unsigned int virq,
+				irq_hw_number_t hw_irq_num)
+{
+	irq_set_chip_and_handler(virq, &nc_irq_chip, handle_level_irq);
+
+	return 0;
+}
+
+static const struct irq_domain_ops nc_irq_ops = {
+	.map	= irq_map,
+	.xlate	= irq_domain_xlate_onecell,
+};
+
+static int __init
+intc_init(struct device_node *intc, struct device_node *parent)
+{
+	struct irq_domain *root_domain;
+	unsigned int i;
+
+	if (parent)
+		panic("DeviceTree incore intc not a root irq controller\n");
+
+	csky_get_auto_irqno = nc_get_irqno;
+
+	intc_reg = (unsigned int) of_iomap(intc, 0);
+	if (!intc_reg)
+		panic("Nationalchip Intc Reg: %x.\n", intc_reg);
+
+	__raw_writel(0xffffffff, NC_VA_INTC_NENCLR31_00);
+	__raw_writel(0xffffffff, NC_VA_INTC_NENCLR63_32);
+	__raw_writel(0xffffffff, NC_VA_INTC_NMASK31_00);
+	__raw_writel(0xffffffff, NC_VA_INTC_NMASK63_32);
+
+	/*
+	 * nationalchip irq ctrl has 64 sources.
+	 */
+	#define INTC_IRQS 64
+	for (i=0; i<INTC_IRQS; i=i+4)
+		__raw_writel(i|((i+1)<<8)|((i+2)<<16)|((i+3)<<24),
+				NC_VA_INTC_SOURCE + i);
+
+	root_domain = irq_domain_add_legacy(intc, INTC_IRQS, 0, 0,
+			&nc_irq_ops, NULL);
+	if (!root_domain)
+		panic("root irq domain not avail\n");
+
+	irq_set_default_host(root_domain);
+
+	return 0;
+}
+
+IRQCHIP_DECLARE(nationalchip_intc_v1_ave, "nationalchip,intc-v1,ave", intc_init);
+
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/19] C-SKY(csky) Linux Kernel Port
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (18 preceding siblings ...)
  2018-03-18 19:51 ` [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c Guo Ren
@ 2018-03-18 20:25 ` Joe Perches
  2018-03-19  7:11   ` Guo Ren
  2018-03-26 13:30 ` Arnd Bergmann
  20 siblings, 1 reply; 63+ messages in thread
From: Joe Perches @ 2018-03-18 20:25 UTC (permalink / raw)
  To: Guo Ren, linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

On Mon, 2018-03-19 at 03:51 +0800, Guo Ren wrote:
> This patchset adds architecture support to Linux for C-SKY's 32-bit embedded
> CPU cores and the patches are based on linux-4.16-rc5.
> 
> There are two ABI versions with several CPU cores in this patchset:
>   ABIv1: ck610 (16-bit instruction, 32-bit data path, VIPT Cache ...)
>   ABIv2: ck807 ck810 (16/32-bit variable length instruction, PIPT Cache ...)

[]

> It's my first patchset to linux and any feedback is welcome :)

Hello.  You might try to do a git am <series>
on a new branch and correct the various
git whitespace messages that are produced.

It's also possible to run checkpatch and correct
some of the linux-kernel code style conformance
nits it lists.

Perhaps something like:

$ git ls-files arch/csky/ | \
  while read file ; do \
    ./scripts/checkpatch.pl --strict --terse --no-summary $file ; \
  done

add --fix-inplace to the checkpatch line if desired.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 18/19] clocksource: add timer-nationalchip.c
  2018-03-18 19:51 ` [PATCH 18/19] clocksource: add timer-nationalchip.c Guo Ren
@ 2018-03-18 22:07   ` Daniel Lezcano
  2018-03-19  6:59     ` Guo Ren
  2018-03-19  4:15   ` Mark Rutland
  1 sibling, 1 reply; 63+ messages in thread
From: Daniel Lezcano @ 2018-03-18 22:07 UTC (permalink / raw)
  To: Guo Ren, linux-arch, linux-kernel, tglx, jason, arnd
  Cc: c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi Guo,


On 18/03/2018 20:51, Guo Ren wrote:

This patch is a new driver. Please add the hardware details of this
timer and optionally a link to the documentation. No need to write a
book, just a quick summary of it.

> Signed-off-by: Guo Ren <ren_guo@c-sky.com>
> ---
>  drivers/clocksource/Makefile             |   1 +
>  drivers/clocksource/timer-nationalchip.c | 149 +++++++++++++++++++++++++++++++
>  2 files changed, 150 insertions(+)
>  create mode 100644 drivers/clocksource/timer-nationalchip.c
> 
> diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
> index d6dec44..d091712 100644
> --- a/drivers/clocksource/Makefile
> +++ b/drivers/clocksource/Makefile
> @@ -76,3 +76,4 @@ obj-$(CONFIG_H8300_TMR16)		+= h8300_timer16.o
>  obj-$(CONFIG_H8300_TPU)			+= h8300_tpu.o
>  obj-$(CONFIG_CLKSRC_ST_LPC)		+= clksrc_st_lpc.o
>  obj-$(CONFIG_X86_NUMACHIP)		+= numachip.o
> +obj-$(CONFIG_CSKY)			+= timer-nationalchip.o
> diff --git a/drivers/clocksource/timer-nationalchip.c b/drivers/clocksource/timer-nationalchip.c
> new file mode 100644
> index 0000000..1279d64
> --- /dev/null
> +++ b/drivers/clocksource/timer-nationalchip.c
> @@ -0,0 +1,149 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/param.h>

sched ? param ?

> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/profile.h>

profile ?

> +#include <linux/irq.h>
> +#include <linux/rtc.h>
> +#include <linux/sizes.h>

rtc ? sizes ?

> +#include <linux/clocksource.h>
> +#include <linux/clockchips.h>
> +#include <asm/irq.h>
> +#include <asm/io.h>
> +#include <asm/delay.h>

Is the delay API defined for this architecture ? I don't see it used below.

> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/sched_clock.h>
> +
> +#define NC_VA_COUNTER_1_STATUS		(void *)(timer_reg + 0x00)
> +#define NC_VA_COUNTER_1_VALUE		(void *)(timer_reg + 0x04)
> +#define NC_VA_COUNTER_1_CONTROL		(void *)(timer_reg + 0x10)
> +#define NC_VA_COUNTER_1_CONFIG		(void *)(timer_reg + 0x20)
> +#define NC_VA_COUNTER_1_PRE		(void *)(timer_reg + 0x24)
> +#define NC_VA_COUNTER_1_INI		(void *)(timer_reg + 0x28)
> +#define NC_VA_COUNTER_2_STATUS		(void *)(timer_reg + 0x40)
> +#define NC_VA_COUNTER_2_VALUE		(void *)(timer_reg + 0x44)
> +#define NC_VA_COUNTER_2_CONTROL		(void *)(timer_reg + 0x50)
> +#define NC_VA_COUNTER_2_CONFIG		(void *)(timer_reg + 0x60)
> +#define NC_VA_COUNTER_2_PRE		(void *)(timer_reg + 0x64)
> +#define NC_VA_COUNTER_2_INI		(void *)(timer_reg + 0x68)
> +#define NC_VA_COUNTER_3_STATUS		(void *)(timer_reg + 0x80)
> +#define NC_VA_COUNTER_3_VALUE		(void *)(timer_reg + 0x84)
> +#define NC_VA_COUNTER_3_CONTROL		(void *)(timer_reg + 0x90)
> +#define NC_VA_COUNTER_3_CONFIG		(void *)(timer_reg + 0xa0)
> +#define NC_VA_COUNTER_3_PRE		(void *)(timer_reg + 0xa4)
> +#define NC_VA_COUNTER_3_INI		(void *)(timer_reg + 0xa8)
> +
> +static unsigned int timer_reg;
> +
> +static inline void timer_reset(void)
> +{
> +	__raw_writel(0x1,	NC_VA_COUNTER_1_CONTROL);
> +	__raw_writel(0x0,	NC_VA_COUNTER_1_CONTROL);
> +	__raw_writel(0x3,	NC_VA_COUNTER_1_CONFIG);
> +	__raw_writel(26,	NC_VA_COUNTER_1_PRE);

Why are you using the __raw_writel instead of writel ?

No values, explicit macros please.

> +}
> +
> +static irqreturn_t timer_interrupt(int irq, void *dev_id)

timer_interrupt is a too generic name, at least nc_timer_interrupt would
be more accurate.

> +{
> +	struct clock_event_device *dev = (struct clock_event_device *) dev_id;
> +
> +	__raw_writel(1, NC_VA_COUNTER_1_STATUS);
> +
> +	dev->event_handler(dev);
> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int nc_timer_set_periodic(struct clock_event_device *dev)
> +{
> +	timer_reset();
> +
> +	__raw_writel(0xFFFFD8EF, NC_VA_COUNTER_1_INI);
> +	__raw_writel(0x2, NC_VA_COUNTER_1_CONTROL);
> +
> +	return 0;
> +}
> +
> +static int nc_timer_set_next_event(unsigned long delta, struct clock_event_device *evt)
> +{
> +	__raw_writel(0x1,		NC_VA_COUNTER_1_CONTROL);
> +	__raw_writel(ULONG_MAX - delta, NC_VA_COUNTER_1_INI);
> +	__raw_writel(0x2,		NC_VA_COUNTER_1_CONTROL);
> +	return 0;
> +}
> +
> +static int nc_timer_shutdown(struct clock_event_device *dev)
> +{
> +	__raw_writel(0x0, NC_VA_COUNTER_1_CONTROL);
> +	__raw_writel(0x0, NC_VA_COUNTER_1_CONFIG);
> +
> +	return 0;
> +}
> +
> +static struct clock_event_device nc_ced = {
> +	.name			= "nationalchip-clkevent",
> +	.features		= CLOCK_EVT_FEAT_PERIODIC
> +				| CLOCK_EVT_FEAT_ONESHOT,
> +	.rating			= 200,
> +	.set_state_shutdown	= nc_timer_shutdown,
> +	.set_state_periodic	= nc_timer_set_periodic,
> +	.set_next_event		= nc_timer_set_next_event,
> +};
> +
> +static u64 notrace nc_sched_clock_read(void)
> +{
> +	return (u64) __raw_readl(NC_VA_COUNTER_2_VALUE);
> +}
> +
> +static void nc_csd_enable(void)

Can you choose a more explicit name than 'csd'?

> +{
> +	__raw_writel(0x1, NC_VA_COUNTER_2_CONTROL);
> +	__raw_writel(0x0, NC_VA_COUNTER_2_CONTROL);
> +	__raw_writel(0x1, NC_VA_COUNTER_2_CONFIG);
> +
> +	__raw_writel(26,NC_VA_COUNTER_2_PRE);
> +	__raw_writel(0, NC_VA_COUNTER_2_INI);
> +	__raw_writel(0x2, NC_VA_COUNTER_2_CONTROL);
> +}
> +
> +static int __init nc_timer_init(struct device_node *np)
> +{
> +	unsigned int irq;
> +	unsigned int freq;
> +
> +	/* parse from devicetree */
> +	timer_reg = (unsigned int) of_iomap(np, 0);
> +	if (!timer_reg)
> +		panic("%s, of_iomap err.\n", __func__);
> +
> +	irq = irq_of_parse_and_map(np, 0);
> +	if (!irq)
> +		panic("%s, irq_parse err.\n", __func__);
> +
> +	if (of_property_read_u32(np, "clock-frequency", &freq))
> +		panic("%s, clock-frequency error.\n", __func__);
>
> +	pr_info("Nationalchip Timer Init, reg: %x, irq: %d, freq: %d.\n",
> +		timer_reg, irq, freq);
> +
> +	/* setup irq */
> +	if (request_irq(irq, timer_interrupt, IRQF_TIMER, np->name, &nc_ced))
> +		panic("%s timer_interrupt error.\n", __func__);

Replace the "clock-frequency" property to a clock phandle and use the
timer-of API.

That will result on something like that:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clocksource/timer-sprd.c#n124

No panic in init function.

> +	/* register */
> +	clockevents_config_and_register(&nc_ced, freq, 1, ULONG_MAX);
> +
> +	nc_csd_enable();
> +	clocksource_mmio_init(NC_VA_COUNTER_2_VALUE, "nationalchip-clksource", freq, 200, 32, clocksource_mmio_readl_up);

s/nationalchip-clksource/nationalchip/

line wrap

> +	sched_clock_register(nc_sched_clock_read, 32, freq);
> +
> +	return 0;
> +}
> +CLOCKSOURCE_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);

s/CLOCKSOURCE_OF_DECLARE/TIMER_OF_DECLARE/


-- 
 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 02/19] csky: Exception handling and syscall
  2018-03-18 19:51 ` [PATCH 02/19] csky: Exception handling and syscall Guo Ren
@ 2018-03-19  1:48   ` Mark Rutland
  2018-03-19  6:47     ` Guo Ren
  2018-03-19  8:50   ` Dominik Brodowski
  1 sibling, 1 reply; 63+ messages in thread
From: Mark Rutland @ 2018-03-19  1:48 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi,

On Mon, Mar 19, 2018 at 03:51:24AM +0800, Guo Ren wrote:
> +inline static unsigned int
> +get_regs_value(unsigned int rx, struct pt_regs *regs)
> +{
> +	unsigned int value;
> +
> +	if(rx == 0){
> +		if(user_mode(regs)){
> +			asm volatile("mfcr %0, ss1\n":"=r"(value));

Here you open code an MFCR instruction.

I guess MFCR stands for something like move-from-control-register, and MTCR
stands for move-to-control-register?

I see that later on you have helpers for specific registers, e.g. mfcr_cpuidrr().

You might want to follow the example of arm64's read_sysreg() and
write_sysreg(), and have general purpose helpers for thos instructions, e.g.

#define mfcr(reg)						\
({								\
	unsigned long __mfcr_val;				\
	asm volatile("mfcr %0, " #reg "\n" : "=r" (__mfr_val));	\
	__mfcr_val;						\
})

... which avoids needing helpers for each register, as you can do:

ss1_val = mfcr(ss1);
cpuidrr_val = mfcr(cpuidrr);

[...]

> +static __init void setup_cpu_msa(void)
> +{
> +	if (memblock_start_of_DRAM() != (PHYS_OFFSET + CONFIG_RAM_BASE)) {
> +		pr_err("C-SKY: dts-DRAM doesn't fit .config: %x-%x.\n",
> +			memblock_start_of_DRAM(),
> +			PHYS_OFFSET + CONFIG_RAM_BASE);
> +		return;
> +	}

If this is a problem, is it safe to continue at all?

Why does the base address of RAM matter?

> +
> +	mtcr_msa0(PHYS_OFFSET | 0xe);
> +	mtcr_msa1(PHYS_OFFSET | 0x6);

As with MFCR, you could use a generic helper here, e.g.

#define mtcr(val, reg)								\
do {										\
	asm volatile("mtcr %0, " #reg "\n" : "=r" ((unsigned long)val));	\
} while (0);

mtcr(PHYS_OFFSET | 0xe, msa0)
mtcr(PHYS_OFFSET | 0x6, msa1)

> +}
> +
> +__init void cpu_dt_probe(void)
> +{
> +	setup_cpu_msa();
> +}
> +
> +static int c_show(struct seq_file *m, void *v)
> +{
> +	seq_printf(m, "C-SKY CPU : %s\n", CSKYCPU_DEF_NAME);
> +	seq_printf(m, "revision  : 0x%08x\n", mfcr_cpuidrr());
> +	seq_printf(m, "ccr reg   : 0x%08x\n", mfcr_ccr());
> +	seq_printf(m, "ccr2 reg  : 0x%08x\n", mfcr_ccr2());
> +	seq_printf(m, "hint reg  : 0x%08x\n", mfcr_hint());
> +	seq_printf(m, "msa0 reg  : 0x%08x\n", mfcr_msa0());
> +	seq_printf(m, "msa1 reg  : 0x%08x\n", mfcr_msa1());

Do these need to be exposed to userspace?

Does this arch support SMP? I see you don't log information per-cpu.

[...]

> diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S

> +#define THREADSIZE_MASK_BIT 13

You might want to define this as THREAD_SHIFT, and define THREAD_SIZE in terms
of it, so that they're guaranteed to be in sync

e.g. in your <asm/thread_info.h> have:

#define THREAD_SHIFT	13
#define THREAD_SIZE	(1 << THREAD_SHIFT)

[...]

> +ENTRY(csky_systemcall)
> +	SAVE_ALL_TRAP
> +
> +	psrset  ee, ie
> +
> +	/* Stack frame for syscall, origin call set_esp0 */
> +	mov     r12, sp
> +
> +	bmaski  r11, 13
> +	andn    r12, r11
> +	bgeni   r11, 9
> +	addi    r11, 32
> +	addu    r12, r11
> +	st      sp, (r12, 0)
> +
> +	lrw     r11, __NR_syscalls
> +	cmphs   syscallid, r11                 /* Check nr of syscall */
> +	bt      ret_from_exception
> +
> +	lrw     r13, sys_call_table
> +	ixw     r13, syscallid                 /* Index into syscall table */
> +	ldw     r11, (r13)               /* Get syscall function */
> +	cmpnei  r11, 0                  /* Check for not null */
> +	bf      ret_from_exception
> +
> +	mov     r9, sp				 /* Get task pointer */
> +	bmaski  r10, THREADSIZE_MASK_BIT
> +	andn    r9, r10                      /* Get thread_info */

If you have a spare register that you can point at the current task (or you
have preemption-safe percpu ops), I'd recommend moving the thread_info off of
the stack, and implementing THREAD_INFO_IN_TASK_STRUCT.

[...]

> +ENTRY(csky_get_tls)
> +	USPTOKSP
> +
> +	/* increase epc for continue */
> +	mfcr	a0, epc
> +	INCTRAP	a0
> +	mtcr	a0, epc
> +
> +	/* get current task thread_info with kernel 8K stack */
> +	bmaski   a0, (PAGE_SHIFT + 1)

For consistency, and in case you change your stack size in future, this should
be THREADSIZE_MASK_BIT.

[...]

> +/*
> + * This routine handles page faults.  It determines the address,
> + * and the problem, and then passes it off to one of the appropriate
> + * routines.
> + */
> +asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
> +                              unsigned long mmu_meh)
> +{
> +        struct vm_area_struct * vma = NULL;
> +        struct task_struct *tsk = current;
> +        struct mm_struct *mm = tsk->mm;
> +        siginfo_t info;
> +	int fault;
> +	unsigned long address = mmu_meh & PAGE_MASK;
> +
> +        info.si_code = SEGV_MAPERR;
> +
> +        /*
> +         * We fault-in kernel-space virtual memory on-demand. The
> +         * 'reference' page table is init_mm.pgd.
> +         *
> +         * NOTE! We MUST NOT take any locks for this case. We may
> +         * be in an interrupt or a critical region, and should
> +         * only copy the information from the master page table,
> +         * nothing more.
> +         */
> +        if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
> +                goto vmalloc_fault;

You might want to check if this was a user mode fault here, so that users can't trigger vmalloc faults.

Thanks,
Mark.

> +vmalloc_fault:
> +        {
> +                /*
> +                 * Synchronize this task's top level page-table
> +                 * with the 'reference' page table.
> +                 *
> +                 * Do _not_ use "tsk" here. We might be inside
> +                 * an interrupt in the middle of a task switch..
> +                 */
> +                int offset = __pgd_offset(address);
> +                pgd_t *pgd, *pgd_k;
> +                pud_t *pud, *pud_k;
> +                pmd_t *pmd, *pmd_k;
> +                pte_t *pte_k;
> +
> +                unsigned long pgd_base;
> +		pgd_base = tlb_get_pgd();
> +                pgd = (pgd_t *)pgd_base + offset;
> +                pgd_k = init_mm.pgd + offset;
> +
> +                if (!pgd_present(*pgd_k))
> +                        goto no_context;
> +                set_pgd(pgd, *pgd_k);
> +
> +                pud = (pud_t *)pgd;
> +                pud_k = (pud_t *)pgd_k;
> +                if (!pud_present(*pud_k))
> +                        goto no_context;
> +
> +                pmd = pmd_offset(pud, address);
> +                pmd_k = pmd_offset(pud_k, address);
> +                if (!pmd_present(*pmd_k))
> +                        goto no_context;
> +                set_pmd(pmd, *pmd_k);
> +
> +                pte_k = pte_offset_kernel(pmd_k, address);
> +                if (!pte_present(*pte_k))
> +                        goto no_context;
> +                return;
> +        }
> +}
> +
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 18/19] clocksource: add timer-nationalchip.c
  2018-03-18 19:51 ` [PATCH 18/19] clocksource: add timer-nationalchip.c Guo Ren
  2018-03-18 22:07   ` Daniel Lezcano
@ 2018-03-19  4:15   ` Mark Rutland
  2018-03-19  7:03     ` Guo Ren
  1 sibling, 1 reply; 63+ messages in thread
From: Mark Rutland @ 2018-03-19  4:15 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi,

On Mon, Mar 19, 2018 at 03:51:40AM +0800, Guo Ren wrote:
> +#define NC_VA_COUNTER_1_STATUS		(void *)(timer_reg + 0x00)
> +#define NC_VA_COUNTER_1_VALUE		(void *)(timer_reg + 0x04)
> +#define NC_VA_COUNTER_1_CONTROL		(void *)(timer_reg + 0x10)
> +#define NC_VA_COUNTER_1_CONFIG		(void *)(timer_reg + 0x20)
> +#define NC_VA_COUNTER_1_PRE		(void *)(timer_reg + 0x24)
> +#define NC_VA_COUNTER_1_INI		(void *)(timer_reg + 0x28)
> +#define NC_VA_COUNTER_2_STATUS		(void *)(timer_reg + 0x40)
> +#define NC_VA_COUNTER_2_VALUE		(void *)(timer_reg + 0x44)
> +#define NC_VA_COUNTER_2_CONTROL		(void *)(timer_reg + 0x50)
> +#define NC_VA_COUNTER_2_CONFIG		(void *)(timer_reg + 0x60)
> +#define NC_VA_COUNTER_2_PRE		(void *)(timer_reg + 0x64)
> +#define NC_VA_COUNTER_2_INI		(void *)(timer_reg + 0x68)
> +#define NC_VA_COUNTER_3_STATUS		(void *)(timer_reg + 0x80)
> +#define NC_VA_COUNTER_3_VALUE		(void *)(timer_reg + 0x84)
> +#define NC_VA_COUNTER_3_CONTROL		(void *)(timer_reg + 0x90)
> +#define NC_VA_COUNTER_3_CONFIG		(void *)(timer_reg + 0xa0)
> +#define NC_VA_COUNTER_3_PRE		(void *)(timer_reg + 0xa4)
> +#define NC_VA_COUNTER_3_INI		(void *)(timer_reg + 0xa8)

Please define the offsets alone, e.g.

#define NC_VA_COUNTER_1_STATUS	0x00
#define NC_VA_COUNTER_1_VALUE	0x04

... the base address should be added when calling the io accessor. Please see
below.

> +static unsigned int timer_reg;

This should be a void __iomem *, e.g.

static void __iomem *timer_base;

... though it would be better for this to be associated with the instance of
the clock_event_device, so that there can be multiple instances in a system.

> +
> +static inline void timer_reset(void)
> +{
> +	__raw_writel(0x1,	NC_VA_COUNTER_1_CONTROL);
> +	__raw_writel(0x0,	NC_VA_COUNTER_1_CONTROL);
> +	__raw_writel(0x3,	NC_VA_COUNTER_1_CONFIG);
> +	__raw_writel(26,	NC_VA_COUNTER_1_PRE);

Should this be 26 or 0x26?

It would be nice to have mnemonics for these magic numbers.

Please use writel_relaxed() rather than __raw_writel(). e.g.

	writel_relaxed(0x1, timer_base + NC_VA_COUNTER_1_CONTROL);
	writel_relaxed(0x0, timer_base + NC_VA_COUNTER_1_CONTROL);
	writel_relaxed(0x3, timer_base + NC_VA_COUNTER_1_CONTROL);
	writel_relaxed(26, timer_base + NC_VA_COUNTER_1_PRE);

[...]

> +static int __init nc_timer_init(struct device_node *np)
> +{
> +	unsigned int irq;
> +	unsigned int freq;
> +
> +	/* parse from devicetree */
> +	timer_reg = (unsigned int) of_iomap(np, 0);
> +	if (!timer_reg)
> +		panic("%s, of_iomap err.\n", __func__);
> +
> +	irq = irq_of_parse_and_map(np, 0);
> +	if (!irq)
> +		panic("%s, irq_parse err.\n", __func__);
> +
> +	if (of_property_read_u32(np, "clock-frequency", &freq))
> +		panic("%s, clock-frequency error.\n", __func__);
> +
> +	pr_info("Nationalchip Timer Init, reg: %x, irq: %d, freq: %d.\n",
> +		timer_reg, irq, freq);
> +
> +	/* setup irq */
> +	if (request_irq(irq, timer_interrupt, IRQF_TIMER, np->name, &nc_ced))
> +		panic("%s timer_interrupt error.\n", __func__);
> +
> +	/* register */
> +	clockevents_config_and_register(&nc_ced, freq, 1, ULONG_MAX);
> +
> +	nc_csd_enable();
> +	clocksource_mmio_init(NC_VA_COUNTER_2_VALUE, "nationalchip-clksource", freq, 200, 32, clocksource_mmio_readl_up);
> +
> +	sched_clock_register(nc_sched_clock_read, 32, freq);
> +
> +	return 0;
> +}
> +CLOCKSOURCE_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);

This needs a devicetree binding document. Please see Documentation/devicetree/bindings/submitting-patches.txt.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c
  2018-03-18 19:51 ` [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c Guo Ren
@ 2018-03-19  4:26   ` Mark Rutland
  2018-03-19  7:08     ` Guo Ren
  2018-03-19 13:30   ` Thomas Gleixner
  1 sibling, 1 reply; 63+ messages in thread
From: Mark Rutland @ 2018-03-19  4:26 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

On Mon, Mar 19, 2018 at 03:51:41AM +0800, Guo Ren wrote:
> +static unsigned int intc_reg;

This should be a void __iomem *ptr;

> +
> +#define CK_VA_INTC_ICR		(void *)(intc_reg + 0x00)	/* Interrupt control register(High 16bits) */
> +#define CK_VA_INTC_ISR		(void *)(intc_reg + 0x00)	/* Interrupt status register(Low 16bits) */
> +#define CK_VA_INTC_NEN31_00	(void *)(intc_reg + 0x10)	/* Normal interrupt enable register Low */
> +#define	CK_VA_INTC_NEN63_32	(void *)(intc_reg + 0x28)	/* Normal interrupt enable register High */
> +#define CK_VA_INTC_IFR31_00	(void *)(intc_reg + 0x08)	/* Normal interrupt force register Low */
> +#define CK_VA_INTC_IFR63_32	(void *)(intc_reg + 0x20)	/* Normal interrupt force register High */
> +#define	CK_VA_INTC_SOURCE	(void *)(intc_reg + 0x40)	/* Proiority Level Select Registers 0 */

Please use mnemonics for the offsets, and add the base address in the IO
accessors.

[...]

> +		temp = __raw_readl(CK_VA_INTC_NEN31_00);

Please use readl_relaxed() rather than __raw_readl().

> +		__raw_writel(temp, CK_VA_INTC_NEN31_00);

Likewise, please use writel_relaxed() rather than __raw_writel().

[...]

> +static int __init
> +__intc_init(struct device_node *np, struct device_node *parent, bool ave)
> +{
> +	struct irq_domain *root_domain;
> +	int i;
> +
> +	csky_get_auto_irqno = ck_get_irqno;
> +
> +	if (parent)
> +		panic("pic not a root intc\n");
> +
> +	intc_reg = (unsigned int)of_iomap(np, 0);
> +	if (!intc_reg)
> +		panic("%s, of_iomap err.\n", __func__);
> +
> +	__raw_writel(0, CK_VA_INTC_NEN31_00);
> +	__raw_writel(0,	CK_VA_INTC_NEN63_32);
> +
> +	if (ave == true)
> +		__raw_writel( 0xc0000000, CK_VA_INTC_ICR);
> +	else
> +		__raw_writel( 0x0, CK_VA_INTC_ICR);
> +	/*
> +	 * csky irq ctrl has 64 sources.
> +	 */
> +	#define INTC_IRQS 64
> +	for (i=0; i<INTC_IRQS; i=i+4)
> +		__raw_writel((i+3)|((i+2)<<8)|((i+1)<<16)|(i<<24),
> +				CK_VA_INTC_SOURCE + i);
> +
> +	root_domain = irq_domain_add_legacy(np, INTC_IRQS, 0, 0, &ck_irq_ops, NULL);
> +	if (!root_domain)
> +		panic("root irq domain not available\n");
> +
> +	irq_set_default_host(root_domain);
> +
> +	return 0;
> +}
> +
> +static int __init
> +intc_init(struct device_node *np, struct device_node *parent)
> +{
> +
> +	return __intc_init(np, parent, false);
> +}
> +IRQCHIP_DECLARE(csky_intc_v1, "csky,intc-v1", intc_init);
> +
> +/*
> + * use auto vector exceptions 10 for interrupt.
> + */
> +static int __init
> +intc_init_ave(struct device_node *np, struct device_node *parent)
> +{
> +	return __intc_init(np, parent, true);
> +}
> +IRQCHIP_DECLARE(csky_intc_v1_ave, "csky,intc-v1,ave", intc_init_ave);

These need devicetree bindings. Please see
Documentation/devicetree/bindings/submitting-patches.txt.

[...]

> +inline int ff1_64(unsigned int hi, unsigned int lo)
> +{
> +	int result;
> +	asm volatile(
> +		"ff1 %0\n"
> +		:"=r"(hi)
> +		:"r"(hi)
> +		:
> +	);
> +
> +	asm volatile(
> +		"ff1 %0\n"
> +		:"=r"(lo)
> +		:"r"(lo)
> +		:
> +	);
> +	if( lo != 32 )
> +		result = 31-lo;
> +	else if( hi != 32 ) result = 31-hi + 32;
> +	else {
> +		printk("nc_get_irqno error hi:%x, lo:%x.\n", hi, lo);
> +		result = NR_IRQS;
> +	}
> +	return result;
> +}

Please avoid assembly in generic driver code. Here you cna use __ffs64() after
combining the two halves into a 64-bit quantity, or you could use ffs() on each
half.

> +static int __init
> +intc_init(struct device_node *intc, struct device_node *parent)
> +{
> +	struct irq_domain *root_domain;
> +	unsigned int i;
> +
> +	if (parent)
> +		panic("DeviceTree incore intc not a root irq controller\n");
> +
> +	csky_get_auto_irqno = nc_get_irqno;
> +
> +	intc_reg = (unsigned int) of_iomap(intc, 0);
> +	if (!intc_reg)
> +		panic("Nationalchip Intc Reg: %x.\n", intc_reg);
> +
> +	__raw_writel(0xffffffff, NC_VA_INTC_NENCLR31_00);
> +	__raw_writel(0xffffffff, NC_VA_INTC_NENCLR63_32);
> +	__raw_writel(0xffffffff, NC_VA_INTC_NMASK31_00);
> +	__raw_writel(0xffffffff, NC_VA_INTC_NMASK63_32);
> +
> +	/*
> +	 * nationalchip irq ctrl has 64 sources.
> +	 */
> +	#define INTC_IRQS 64
> +	for (i=0; i<INTC_IRQS; i=i+4)
> +		__raw_writel(i|((i+1)<<8)|((i+2)<<16)|((i+3)<<24),
> +				NC_VA_INTC_SOURCE + i);
> +
> +	root_domain = irq_domain_add_legacy(intc, INTC_IRQS, 0, 0,
> +			&nc_irq_ops, NULL);
> +	if (!root_domain)
> +		panic("root irq domain not avail\n");
> +
> +	irq_set_default_host(root_domain);
> +
> +	return 0;
> +}
> +
> +IRQCHIP_DECLARE(nationalchip_intc_v1_ave, "nationalchip,intc-v1,ave", intc_init);

This needs a devicetree binding document.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 02/19] csky: Exception handling and syscall
  2018-03-19  1:48   ` Mark Rutland
@ 2018-03-19  6:47     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-19  6:47 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi Mark,

> Here you open code an MFCR instruction.
> 
> I guess MFCR stands for something like move-from-control-register, and MTCR
> stands for move-to-control-register?
> 
> I see that later on you have helpers for specific registers, e.g. mfcr_cpuidrr().
> 
> You might want to follow the example of arm64's read_sysreg() and
> write_sysreg(), and have general purpose helpers for thos instructions, e.g.
> 
> #define mfcr(reg)						\
> ({								\
> 	unsigned long __mfcr_val;				\
> 	asm volatile("mfcr %0, " #reg "\n" : "=r" (__mfr_val));	\
> 	__mfcr_val;						\
> })
> 
> ... which avoids needing helpers for each register, as you can do:
> 
> ss1_val = mfcr(ss1);
> cpuidrr_val = mfcr(cpuidrr);
>
OK, good idea.

> > +	if (memblock_start_of_DRAM() != (PHYS_OFFSET + CONFIG_RAM_BASE)) {
> > +		pr_err("C-SKY: dts-DRAM doesn't fit .config: %x-%x.\n",
> > +			memblock_start_of_DRAM(),
> > +			PHYS_OFFSET + CONFIG_RAM_BASE);
> > +		return;
> > +	}
> 
> If this is a problem, is it safe to continue at all?
> 
> Why does the base address of RAM matter?
>
We use mips-like direct-mapping tech, and it need 512MB boundary
alignment. And few users need non-512MB boundary phy-addr start,
so we give the CONFIG_RAM_BASE for determine the offset to PHYS_OFFSET.

> > +
> > +	mtcr_msa0(PHYS_OFFSET | 0xe);
> > +	mtcr_msa1(PHYS_OFFSET | 0x6);
> 
> As with MFCR, you could use a generic helper here, e.g.
>
> #define mtcr(val, reg)								\
> do {										\
> 	asm volatile("mtcr %0, " #reg "\n" : "=r" ((unsigned long)val));	\
> } while (0);
> 
> mtcr(PHYS_OFFSET | 0xe, msa0)
> mtcr(PHYS_OFFSET | 0x6, msa1)
>
OK

> > +	seq_printf(m, "C-SKY CPU : %s\n", CSKYCPU_DEF_NAME);
> > +	seq_printf(m, "revision  : 0x%08x\n", mfcr_cpuidrr());
> > +	seq_printf(m, "ccr reg   : 0x%08x\n", mfcr_ccr());
> > +	seq_printf(m, "ccr2 reg  : 0x%08x\n", mfcr_ccr2());
> > +	seq_printf(m, "hint reg  : 0x%08x\n", mfcr_hint());
> > +	seq_printf(m, "msa0 reg  : 0x%08x\n", mfcr_msa0());
> > +	seq_printf(m, "msa1 reg  : 0x%08x\n", mfcr_msa1());
> 
> Do these need to be exposed to userspace?
>
Yes, I'll add more explain info.

> Does this arch support SMP? I see you don't log information per-cpu.
This patch-set doesn't support SMP.
> 
> > diff --git a/arch/csky/kernel/entry.S b/arch/csky/kernel/entry.S
> 
> > +#define THREADSIZE_MASK_BIT 13
> 
> You might want to define this as THREAD_SHIFT, and define THREAD_SIZE in terms
> of it, so that they're guaranteed to be in sync
> 
> e.g. in your <asm/thread_info.h> have:
> 
> #define THREAD_SHIFT	13
> #define THREAD_SIZE	(1 << THREAD_SHIFT)
OK

> If you have a spare register that you can point at the current task (or you
> have preemption-safe percpu ops), I'd recommend moving the thread_info off of
> the stack, and implementing THREAD_INFO_IN_TASK_STRUCT.
>
Em... I'll think about it.

> For consistency, and in case you change your stack size in future, this should
> be THREADSIZE_MASK_BIT.
>
OK

> > +        if (unlikely(address >= VMALLOC_START && address <= VMALLOC_END))
> > +                goto vmalloc_fault;
> 
> You might want to check if this was a user mode fault here, so that users can't trigger vmalloc faults.
Is it necessary to check user mode? If a user-process touch a
kernel-addr, it will cause a supervisor exception.

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 18/19] clocksource: add timer-nationalchip.c
  2018-03-18 22:07   ` Daniel Lezcano
@ 2018-03-19  6:59     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-19  6:59 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: linux-arch, linux-kernel, tglx, jason, arnd, c-sky_gcc_upstream,
	gnu-csky, thomas.petazzoni, wbx

Hi Daniel,

On Sun, Mar 18, 2018 at 11:07:12PM +0100, Daniel Lezcano wrote:
> 
> This patch is a new driver. Please add the hardware details of this
> timer and optionally a link to the documentation. No need to write a
> book, just a quick summary of it.
>
OK

> > +#include <linux/kernel.h>
> > +#include <linux/sched.h>
> > +#include <linux/param.h>
> 
> sched ? param ?
>
I'll cleanup the headers.

> > +#include <linux/init.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/profile.h>
> 
> profile ?
> 
I'll cleanup the headers.

> > +#include <linux/irq.h>
> > +#include <linux/rtc.h>
> > +#include <linux/sizes.h>
> 
> rtc ? sizes ?
> 
I'll cleanup the headers.

> > +#include <linux/clocksource.h>
> > +#include <linux/clockchips.h>
> > +#include <asm/irq.h>
> > +#include <asm/io.h>
> > +#include <asm/delay.h>
> 
> Is the delay API defined for this architecture ? I don't see it used below.
> 
I'll cleanup the headers.

> > +#define NC_VA_COUNTER_3_CONFIG		(void *)(timer_reg + 0xa0)
> > +#define NC_VA_COUNTER_3_PRE		(void *)(timer_reg + 0xa4)
> > +#define NC_VA_COUNTER_3_INI		(void *)(timer_reg + 0xa8)
> > +
> > +static unsigned int timer_reg;
> > +
> > +static inline void timer_reset(void)
> > +{
> > +	__raw_writel(0x1,	NC_VA_COUNTER_1_CONTROL);
> > +	__raw_writel(0x0,	NC_VA_COUNTER_1_CONTROL);
> > +	__raw_writel(0x3,	NC_VA_COUNTER_1_CONFIG);
> > +	__raw_writel(26,	NC_VA_COUNTER_1_PRE);
> 
> Why are you using the __raw_writel instead of writel ?
> 
> No values, explicit macros please.
>
OK

> > +}
> > +
> > +static irqreturn_t timer_interrupt(int irq, void *dev_id)
> 
> timer_interrupt is a too generic name, at least nc_timer_interrupt would
> be more accurate.
>
OK

> > +static u64 notrace nc_sched_clock_read(void)
> > +{
> > +	return (u64) __raw_readl(NC_VA_COUNTER_2_VALUE);
> > +}
> > +
> > +static void nc_csd_enable(void)
> 
> Can you choose a more explicit name than 'csd'?
>
OK, change to nc_clocksource_dev_enable

> > +	/* setup irq */
> > +	if (request_irq(irq, timer_interrupt, IRQF_TIMER, np->name, &nc_ced))
> > +		panic("%s timer_interrupt error.\n", __func__);
> 
> Replace the "clock-frequency" property to a clock phandle and use the
> timer-of API.
> 
> That will result on something like that:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/clocksource/timer-sprd.c#n124
> 
> No panic in init function.
>
OK

> > +	/* register */
> > +	clockevents_config_and_register(&nc_ced, freq, 1, ULONG_MAX);
> > +
> > +	nc_csd_enable();
> > +	clocksource_mmio_init(NC_VA_COUNTER_2_VALUE, "nationalchip-clksource", freq, 200, 32, clocksource_mmio_readl_up);
> 
> s/nationalchip-clksource/nationalchip/
> 
> line wrap
>
OK

> > +	sched_clock_register(nc_sched_clock_read, 32, freq);
> > +
> > +	return 0;
> > +}
> > +CLOCKSOURCE_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);
> 
> s/CLOCKSOURCE_OF_DECLARE/TIMER_OF_DECLARE/
>
OK

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 18/19] clocksource: add timer-nationalchip.c
  2018-03-19  4:15   ` Mark Rutland
@ 2018-03-19  7:03     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-19  7:03 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi Mark,

On Mon, Mar 19, 2018 at 04:15:35AM +0000, Mark Rutland wrote:
> > +#define NC_VA_COUNTER_3_CONTROL		(void *)(timer_reg + 0x90)
> > +#define NC_VA_COUNTER_3_CONFIG		(void *)(timer_reg + 0xa0)
> > +#define NC_VA_COUNTER_3_PRE		(void *)(timer_reg + 0xa4)
> > +#define NC_VA_COUNTER_3_INI		(void *)(timer_reg + 0xa8)
> 
> Please define the offsets alone, e.g.
> 
> #define NC_VA_COUNTER_1_STATUS	0x00
> #define NC_VA_COUNTER_1_VALUE	0x04
> 
> ... the base address should be added when calling the io accessor. Please see
> below.
> 
> > +static unsigned int timer_reg;
> 
> This should be a void __iomem *, e.g.
> 
> static void __iomem *timer_base;
> 
> ... though it would be better for this to be associated with the instance of
> the clock_event_device, so that there can be multiple instances in a system.
>
OK

> > +
> > +static inline void timer_reset(void)
> > +{
> > +	__raw_writel(0x1,	NC_VA_COUNTER_1_CONTROL);
> > +	__raw_writel(0x0,	NC_VA_COUNTER_1_CONTROL);
> > +	__raw_writel(0x3,	NC_VA_COUNTER_1_CONFIG);
> > +	__raw_writel(26,	NC_VA_COUNTER_1_PRE);
> 
> Should this be 26 or 0x26?
No

> 
> It would be nice to have mnemonics for these magic numbers.
>
Yes, you are right.

> Please use writel_relaxed() rather than __raw_writel(). e.g.
> 
> 	writel_relaxed(0x1, timer_base + NC_VA_COUNTER_1_CONTROL);
> 	writel_relaxed(0x0, timer_base + NC_VA_COUNTER_1_CONTROL);
> 	writel_relaxed(0x3, timer_base + NC_VA_COUNTER_1_CONTROL);
> 	writel_relaxed(26, timer_base + NC_VA_COUNTER_1_PRE);
>
OK

> > +CLOCKSOURCE_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);
> 
> This needs a devicetree binding document. Please see Documentation/devicetree/bindings/submitting-patches.txt.
>
OK

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c
  2018-03-19  4:26   ` Mark Rutland
@ 2018-03-19  7:08     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-19  7:08 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

On Mon, Mar 19, 2018 at 04:26:00AM +0000, Mark Rutland wrote:
> On Mon, Mar 19, 2018 at 03:51:41AM +0800, Guo Ren wrote:
> > +static unsigned int intc_reg;
> 
> This should be a void __iomem *ptr;
>
OK

> > +#define CK_VA_INTC_ICR		(void *)(intc_reg + 0x00)	/* Interrupt control register(High 16bits) */
> > +#define CK_VA_INTC_ISR		(void *)(intc_reg + 0x00)	/* Interrupt status register(Low 16bits) */
> > +#define CK_VA_INTC_NEN31_00	(void *)(intc_reg + 0x10)	/* Normal interrupt enable register Low */
> > +#define	CK_VA_INTC_NEN63_32	(void *)(intc_reg + 0x28)	/* Normal interrupt enable register High */
> > +#define CK_VA_INTC_IFR31_00	(void *)(intc_reg + 0x08)	/* Normal interrupt force register Low */
> > +#define CK_VA_INTC_IFR63_32	(void *)(intc_reg + 0x20)	/* Normal interrupt force register High */
> > +#define	CK_VA_INTC_SOURCE	(void *)(intc_reg + 0x40)	/* Proiority Level Select Registers 0 */
> 
> Please use mnemonics for the offsets, and add the base address in the IO
> accessors.
> 
OK

> > +		temp = __raw_readl(CK_VA_INTC_NEN31_00);
> 
> Please use readl_relaxed() rather than __raw_readl().
>
OK

> > +		__raw_writel(temp, CK_VA_INTC_NEN31_00);
> 
> Likewise, please use writel_relaxed() rather than __raw_writel().
>
OK
 
> These need devicetree bindings. Please see
> Documentation/devicetree/bindings/submitting-patches.txt.
>
OK

> Please avoid assembly in generic driver code. Here you cna use __ffs64() after
> combining the two halves into a 64-bit quantity, or you could use ffs() on each
> half.
>
OK

> > +IRQCHIP_DECLARE(nationalchip_intc_v1_ave, "nationalchip,intc-v1,ave", intc_init);
> 
> This needs a devicetree binding document.
OK
Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/19] C-SKY(csky) Linux Kernel Port
  2018-03-18 20:25 ` [PATCH 00/19] C-SKY(csky) Linux Kernel Port Joe Perches
@ 2018-03-19  7:11   ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-19  7:11 UTC (permalink / raw)
  To: Joe Perches
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Thx Joe,

On Sun, Mar 18, 2018 at 01:25:57PM -0700, Joe Perches wrote:
> On Mon, 2018-03-19 at 03:51 +0800, Guo Ren wrote:
> > This patchset adds architecture support to Linux for C-SKY's 32-bit embedded
> > CPU cores and the patches are based on linux-4.16-rc5.
> > 
> > There are two ABI versions with several CPU cores in this patchset:
> >   ABIv1: ck610 (16-bit instruction, 32-bit data path, VIPT Cache ...)
> >   ABIv2: ck807 ck810 (16/32-bit variable length instruction, PIPT Cache ...)
> 
> []
> 
> > It's my first patchset to linux and any feedback is welcome :)
> 
> Hello.  You might try to do a git am <series>
> on a new branch and correct the various
> git whitespace messages that are produced.
> 
> It's also possible to run checkpatch and correct
> some of the linux-kernel code style conformance
> nits it lists.
> 
> Perhaps something like:
> 
> $ git ls-files arch/csky/ | \
>   while read file ; do \
>     ./scripts/checkpatch.pl --strict --terse --no-summary $file ; \
>   done
> 
> add --fix-inplace to the checkpatch line if desired.

OK

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 02/19] csky: Exception handling and syscall
  2018-03-18 19:51 ` [PATCH 02/19] csky: Exception handling and syscall Guo Ren
  2018-03-19  1:48   ` Mark Rutland
@ 2018-03-19  8:50   ` Dominik Brodowski
  2018-03-19 11:03     ` Guo Ren
  1 sibling, 1 reply; 63+ messages in thread
From: Dominik Brodowski @ 2018-03-19  8:50 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

> +#define __ARCH_WANT_SYSCALL_DEPRECATED
> +#define __ARCH_WANT_SYSCALL_OFF_T
> +#define __ARCH_WANT_SYSCALL_NO_AT
> +#define __ARCH_WANT_SYSCALL_NO_FLAGS

Does this arch *really* want these deprecated and obsolete syscalls? See the
commend in include/uapi/asm-generic/unistd.h

 * All syscalls below here should go away really,
 * these are provided for both review and as a porting
 * help for the C library version.

Thanks,
	Dominik

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 02/19] csky: Exception handling and syscall
  2018-03-19  8:50   ` Dominik Brodowski
@ 2018-03-19 11:03     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-19 11:03 UTC (permalink / raw)
  To: Dominik Brodowski
  Cc: linux-arch, linux-kernel, tglx, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi Dominik,

On Mon, Mar 19, 2018 at 09:50:09AM +0100, Dominik Brodowski wrote:
> > +#define __ARCH_WANT_SYSCALL_DEPRECATED
> > +#define __ARCH_WANT_SYSCALL_OFF_T
> > +#define __ARCH_WANT_SYSCALL_NO_AT
> > +#define __ARCH_WANT_SYSCALL_NO_FLAGS
> 
> Does this arch *really* want these deprecated and obsolete syscalls? See the
> commend in include/uapi/asm-generic/unistd.h
> 
>  * All syscalls below here should go away really,
>  * these are provided for both review and as a porting
>  * help for the C library version.
> 
OK, I will cleanup them next and check the unistd.h again.

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 06/19] csky: IRQ handling
  2018-03-18 19:51 ` [PATCH 06/19] csky: IRQ handling Guo Ren
@ 2018-03-19 13:16   ` Thomas Gleixner
  2018-03-20  2:06     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Thomas Gleixner @ 2018-03-19 13:16 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, linux-kernel, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx



On Mon, 19 Mar 2018, Guo Ren wrote:

> Signed-off-by: Guo Ren <ren_guo@c-sky.com>
> ---
>  arch/csky/include/asm/irq.h      | 12 +++++++++
>  arch/csky/include/asm/irqflags.h | 55 ++++++++++++++++++++++++++++++++++++++++
>  arch/csky/kernel/irq.c           | 41 ++++++++++++++++++++++++++++++
>  3 files changed, 108 insertions(+)
>  create mode 100644 arch/csky/include/asm/irq.h
>  create mode 100644 arch/csky/include/asm/irqflags.h
>  create mode 100644 arch/csky/kernel/irq.c
> 
> diff --git a/arch/csky/include/asm/irq.h b/arch/csky/include/asm/irq.h
> new file mode 100644
> index 0000000..f68e868
> --- /dev/null
> +++ b/arch/csky/include/asm/irq.h
> @@ -0,0 +1,12 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
> +#ifndef __ASM_CSKY_IRQ_H
> +#define __ASM_CSKY_IRQ_H
> +
> +#define NR_IRQS CONFIG_CSKY_NR_IRQS
> +
> +#include <asm-generic/irq.h>
> +
> +extern unsigned int (*csky_get_auto_irqno) (void);
> +
> +#endif /* __ASM_CSKY_IRQ_H */
> diff --git a/arch/csky/include/asm/irqflags.h b/arch/csky/include/asm/irqflags.h
> +static inline unsigned long arch_local_irq_save(void)
> +{
> +	unsigned long flags;

Newline between declaration and code please.

> +	asm volatile(
> +		"mfcr	%0, psr	\n"
> +		"psrclr	ie	\n"
> +		:"=r"(flags));

> +++ b/arch/csky/kernel/irq.c
> @@ -0,0 +1,41 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
> +#include <linux/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +
> +unsigned int (*csky_get_auto_irqno) (void) = NULL;
> +
> +void csky_do_IRQ(int irq, struct pt_regs *regs)

static? If not, then it needs a declaration in a header somewhere.

> +{
> +	struct pt_regs *old_regs = set_irq_regs(regs);
> +
> +	irq_enter();
> +	generic_handle_irq(irq);
> +	irq_exit();
> +
> +	set_irq_regs(old_regs);
> +}
> +
> +asmlinkage void csky_do_auto_IRQ(struct pt_regs *regs)
> +{
> +	unsigned long irq, psr;
> +
> +	asm volatile("mfcr %0, psr":"=r"(psr));
> +
> +	irq = (psr >> 16) & 0xff;
> +
> +	if (irq == 10)
> +		irq = csky_get_auto_irqno();
> +	else
> +		irq -= 32;

Please add a comment explaining this magic here. Magic numbers w/o
explanation are bad.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c
  2018-03-18 19:51 ` [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c Guo Ren
  2018-03-19  4:26   ` Mark Rutland
@ 2018-03-19 13:30   ` Thomas Gleixner
  2018-03-20 14:23     ` Guo Ren
  1 sibling, 1 reply; 63+ messages in thread
From: Thomas Gleixner @ 2018-03-19 13:30 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, linux-kernel, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

On Mon, 19 Mar 2018, Guo Ren wrote:
> +static void ck_irq_mask(struct irq_data *d)
> +{
> +	unsigned int temp, irq;
> +
> +	irq = d->irq;
> +
> +	if (irq < 32) {
> +		temp = __raw_readl(CK_VA_INTC_NEN31_00);
> +		temp &= ~(1 << irq);
> +		__raw_writel(temp, CK_VA_INTC_NEN31_00);
> +	} else {
> +		temp = __raw_readl(CK_VA_INTC_NEN63_32);
> +		temp &= ~(1 << (irq -32));
> +		__raw_writel(temp, CK_VA_INTC_NEN63_32);
> +	}
> +}
> +
> +static void ck_irq_unmask(struct irq_data *d)
> +{
> +	unsigned int temp, irq;
> +
> +	irq = d->irq;
> +
> +	/* set IFR to support rising edge triggering */
> +	if (irq < 32) {
> +		temp = __raw_readl(CK_VA_INTC_IFR31_00);
> +		temp &= ~(1 << irq);
> +		__raw_writel(temp, CK_VA_INTC_IFR31_00);
> +	} else {
> +		temp = __raw_readl(CK_VA_INTC_IFR63_32);
> +		temp &= ~(1 << (irq -32));
> +		__raw_writel(temp, CK_VA_INTC_IFR63_32);
> +	}
> +
> +	if (irq < 32) {
> +		temp = __raw_readl(CK_VA_INTC_NEN31_00);
> +		temp |= 1 << irq;
> +		__raw_writel(temp, CK_VA_INTC_NEN31_00);
> +	} else {
> +		temp = __raw_readl(CK_VA_INTC_NEN63_32);
> +		temp |= 1 << (irq -32);
> +		__raw_writel(temp, CK_VA_INTC_NEN63_32);
> +	}
> +}
> +
> +static struct irq_chip ck_irq_chip = {
> +	.name		= "csky_intc_v1",
> +	.irq_mask	= ck_irq_mask,
> +	.irq_unmask	= ck_irq_unmask,
> +};

Please use the generic interrupt chip infrastructure for this.

> +static unsigned int ck_get_irqno(void)
> +{
> +	unsigned int temp;

newline between declaration and code.

> +	temp = __raw_readl(CK_VA_INTC_ISR);
> +	return temp & 0x3f;
> +};
> +
> +static int __init
> +__intc_init(struct device_node *np, struct device_node *parent, bool ave)

What is 'ave'? 

> +{
> +	struct irq_domain *root_domain;
> +	int i;
> +
> +	csky_get_auto_irqno = ck_get_irqno;
> +
> +	if (parent)
> +		panic("pic not a root intc\n");
> +
> +	intc_reg = (unsigned int)of_iomap(np, 0);
> +	if (!intc_reg)
> +		panic("%s, of_iomap err.\n", __func__);
> +
> +	__raw_writel(0, CK_VA_INTC_NEN31_00);
> +	__raw_writel(0,	CK_VA_INTC_NEN63_32);
> +
> +	if (ave == true)

  	if (ave)

> +		__raw_writel( 0xc0000000, CK_VA_INTC_ICR);

No magic numbers. Please use proper defines.

> +	else
> +		__raw_writel( 0x0, CK_VA_INTC_ICR);
> +	/*
> +	 * csky irq ctrl has 64 sources.
> +	 */
> +	#define INTC_IRQS 64

No defines in code.

> +	for (i=0; i<INTC_IRQS; i=i+4)

checkpatch.pl would have told you what's wrong with the above

> +		__raw_writel((i+3)|((i+2)<<8)|((i+1)<<16)|(i<<24),

Eew. Tons of magic numbers and a unreadable coding style. Please use an
inline function with proper comments to calculate that value
> +				CK_VA_INTC_SOURCE + i);
> +
> +	root_domain = irq_domain_add_legacy(np, INTC_IRQS, 0, 0, &ck_irq_ops, NULL);
> +	if (!root_domain)
> +		panic("root irq domain not available\n");
> +
> +	irq_set_default_host(root_domain);
> +
> +	return 0;
> +}
> +
> +static int __init
> +intc_init(struct device_node *np, struct device_node *parent)
> +{
> +

Stray newline

> +	return __intc_init(np, parent, false);
> +}
> +IRQCHIP_DECLARE(csky_intc_v1, "csky,intc-v1", intc_init);
> +
> +/*
> + * use auto vector exceptions 10 for interrupt.
> + */
> +static int __init
> +intc_init_ave(struct device_node *np, struct device_node *parent)
> +{
> +	return __intc_init(np, parent, true);

Why is that 'ave' thing not a property of device tree?

> +}
> +IRQCHIP_DECLARE(csky_intc_v1_ave, "csky,intc-v1,ave", intc_init_ave);
> +
> +static unsigned int intc_reg;
> +
> +static void nc_irq_mask(struct irq_data *d)
> +{
> +	unsigned int mask, irq;
> +
> +	irq = d->irq;
> +
> +	if (irq < 32) {
> +		mask = __raw_readl(NC_VA_INTC_NMASK31_00);
> +		mask |= 1 << irq;
> +		__raw_writel(mask, NC_VA_INTC_NMASK31_00);
> +	} else {
> +		mask = __raw_readl(NC_VA_INTC_NMASK63_32);
> +		mask |= 1 << (irq - 32);
> +		__raw_writel(mask, NC_VA_INTC_NMASK63_32);
> +	}
> +}
> +
> +static void nc_irq_unmask(struct irq_data *d)
> +{
> +	unsigned int mask, irq;
> +
> +	irq = d->irq;
> +
> +	if (irq < 32) {
> +		mask = __raw_readl(NC_VA_INTC_NMASK31_00);
> +		mask &= ~( 1 << irq);
> +		__raw_writel(mask, NC_VA_INTC_NMASK31_00);
> +	} else {
> +		mask = __raw_readl( NC_VA_INTC_NMASK63_32);
> +		mask &= ~(1 << (irq - 32));
> +		__raw_writel(mask, NC_VA_INTC_NMASK63_32);
> +	}
> +}
> +
> +static void nc_irq_en(struct irq_data *d)
> +{
> +	unsigned int mask, irq;
> +
> +	irq = d->irq;
> +
> +	if (irq < 32) {
> +		mask = 1 << irq;
> +		__raw_writel(mask, NC_VA_INTC_NENSET31_00);
> +	} else {
> +		mask = 1 << (irq - 32);
> +		__raw_writel(mask, NC_VA_INTC_NENSET63_32);
> +	}
> +
> +	nc_irq_unmask(d);
> +}
> +
> +static void nc_irq_dis(struct irq_data *d)
> +{
> +	unsigned int mask, irq;
> +
> +	irq = d->irq;
> +
> +	if (irq < 32) {
> +		mask = 1 << irq;
> +		__raw_writel(mask, NC_VA_INTC_NENCLR31_00);
> +	} else {
> +		mask = 1 << (irq - 32);
> +		__raw_writel(mask, NC_VA_INTC_NENCLR63_32);
> +	}
> +
> +	nc_irq_mask(d);
> +}
> +
> +struct irq_chip nc_irq_chip = {
> +	.name =		"nationalchip_intc_v1",
> +	.irq_mask =	nc_irq_mask,
> +	.irq_unmask =	nc_irq_unmask,
> +	.irq_enable =	nc_irq_en,
> +	.irq_disable =	nc_irq_dis,
> +};

Again. This all can use the generic interrupt chip.

> +
> +inline int ff1_64(unsigned int hi, unsigned int lo)

What on earth means ff1_64?

> +{
> +	int result;
> +	asm volatile(
> +		"ff1 %0\n"
> +		:"=r"(hi)
> +		:"r"(hi)
> +		:
> +	);
> +
> +	asm volatile(
> +		"ff1 %0\n"
> +		:"=r"(lo)
> +		:"r"(lo)
> +		:
> +	);

So you want to decode the interrupt number from a bitfield. What's wrong
with ffs()?

> +	if( lo != 32 )
> +		result = 31-lo;

Why is this subtracted? That code makes no sense w/o comments.

> +	else if( hi != 32 ) result = 31-hi + 32;
> +	else {
> +		printk("nc_get_irqno error hi:%x, lo:%x.\n", hi, lo);
> +		result = NR_IRQS;
> +	}

Pleas use braces consistently.

> +	return result;
> +}
> +
> +unsigned int nc_get_irqno(void)

static?

> +{
> +	unsigned int nint64hi, nint64lo, irq_no;
> +
> +	nint64lo = __raw_readl(NC_VA_INTC_NINT31_00);
> +	nint64hi = __raw_readl(NC_VA_INTC_NINT63_32);
> +	irq_no = ff1_64(nint64hi, nint64lo);
> +
> +	return irq_no;
> +}


> +static int __init
> +intc_init(struct device_node *intc, struct device_node *parent)
> +{
> +	struct irq_domain *root_domain;
> +	unsigned int i;
> +
> +	if (parent)
> +		panic("DeviceTree incore intc not a root irq controller\n");
> +
> +	csky_get_auto_irqno = nc_get_irqno;
> +
> +	intc_reg = (unsigned int) of_iomap(intc, 0);
> +	if (!intc_reg)
> +		panic("Nationalchip Intc Reg: %x.\n", intc_reg);
> +
> +	__raw_writel(0xffffffff, NC_VA_INTC_NENCLR31_00);
> +	__raw_writel(0xffffffff, NC_VA_INTC_NENCLR63_32);
> +	__raw_writel(0xffffffff, NC_VA_INTC_NMASK31_00);
> +	__raw_writel(0xffffffff, NC_VA_INTC_NMASK63_32);
> +
> +	/*
> +	 * nationalchip irq ctrl has 64 sources.
> +	 */
> +	#define INTC_IRQS 64
> +	for (i=0; i<INTC_IRQS; i=i+4)
> +		__raw_writel(i|((i+1)<<8)|((i+2)<<16)|((i+3)<<24),
> +				NC_VA_INTC_SOURCE + i);

Same comments as for the other variant.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 16/19] csky: Device tree
  2018-03-18 19:51 ` [PATCH 16/19] csky: Device tree Guo Ren
@ 2018-03-19 15:28   ` Arnd Bergmann
  2018-03-20 13:55     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-19 15:28 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 19, 2018 at 3:51 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> Signed-off-by: Guo Ren <ren_guo@c-sky.com>

Please add a changelog text to each patch, and send patches that add
.dts files or
binding documents to the devicetree mailing list.

> ---
>  arch/csky/boot/dts/gx6605s.dts         | 159 +++++++++++++++++++++++++++++++++
>  arch/csky/boot/dts/include/dt-bindings |   1 +
>  arch/csky/boot/dts/qemu.dts            |  87 ++++++++++++++++++
>  3 files changed, 247 insertions(+)
>  create mode 100644 arch/csky/boot/dts/gx6605s.dts
>  create mode 120000 arch/csky/boot/dts/include/dt-bindings
>  create mode 100644 arch/csky/boot/dts/qemu.dts
>
> diff --git a/arch/csky/boot/dts/gx6605s.dts b/arch/csky/boot/dts/gx6605s.dts
> new file mode 100644
> index 0000000..0d34d22
> --- /dev/null
> +++ b/arch/csky/boot/dts/gx6605s.dts
> @@ -0,0 +1,159 @@
> +/dts-v1/;
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>

It is usually better for an SoC based board to split the SoC specific into a
separate .dtsi file that gets included by the board .dts file.

> +/ {
> +       model = "Nationalchip gx6605s ck610";
> +       compatible = "nationalchip,gx6605s,ck610";

Is ck610 the name of the CPU core? The general convention is to have the
top-level "compatible" property list first the name of the board, then the
name of the soc, but not the name of the CPU core.

> +       #address-cells = <1>;
> +       #size-cells = <1>;
> +
> +       memory {
> +               device_type = "memory";
> +               reg = <0x10000000 0x04000000>;
> +       };
> +
> +       cpus {
> +               #address-cells = <0>;
> +               #size-cells = <0>;
> +
> +               cpu {
> +                       device_type = "cpu";
> +                       ccr     = <0x7d>;
> +                       hint    = <0x1c>;

Here you should list the specific type of CPU in the compatible property and
document the binding for that string in the Documentations/devicetree/bindings
hierarchy. Without a binding, the 'ccr' and 'hint' properties make no sense.

If there is any chance that you could have SMP systems in the future, it
would be better to start with #address-cells=<1>, with appropriate reg
properties.

> +       soc {
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +               compatible = "simple-bus";
> +               ranges;
> +
> +               intc: interrupt-controller {
> +                       compatible = "nationalchip,intc-v1,ave";
> +                       reg = <0x00500000 0x400>;

Each node with a register property also needs the address in the
node name, e.g. "interrupt-controller@500000"

Try building the dtb file with 'make W=1' to get warnings about
when you got that wrong.

> +                       interrupt-controller;
> +                       #interrupt-cells = <1>;
> +               };
> +
> +               timer0 {
> +                       compatible = "nationalchip,timer-v1";

This should be "timer@400"

Also, each device node should have a binding documentation
to explain the binding associated with that "compatible"
string.

> +                       reg = <0x0020a000 0x400>;
> +                       clock-frequency = <1000000>;
> +                       interrupts = <10>;
> +                       interrupt-parent = <&intc>;
> +               };
> +
> +               ehci: ehci-hcd {
> +                       compatible = "generic-ehci";
> +                       reg = <0x00900000 0x400>;
> +                       interrupt-parent = <&intc>;
> +                       interrupts = <59>;
> +               };
> +
> +               ohci0: ohci-hcd0 {


The names here should be "usb@...", not "ehci-hcd"

> +       chosen {
> +               bootargs = "console=ttyS0,115200 rdinit=/sbin/init root=/dev/ram0";
> +       };

The bootargs should not be in the dts file normally, they should come from the
boot loader. For the console, use the "stdout-path" property.

         Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-18 19:51 ` [PATCH 15/19] csky: Build infrastructure Guo Ren
@ 2018-03-19 15:45   ` Arnd Bergmann
  2018-03-20 13:13     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-19 15:45 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 19, 2018 at 3:51 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig
> new file mode 100644
> index 0000000..694c1f8
> --- /dev/null
> +++ b/arch/csky/Kconfig
> @@ -0,0 +1,203 @@
> +config CSKY
> +       bool
> +       default y
> +       select ARCH_USE_BUILTIN_BSWAP
> +       select ARCH_WANT_IPC_PARSE_VERSION

Drop ipc_parse_version here, it's only for old architectures.

> +       select HAVE_OPROFILE
> +       select HAVE_PERF_EVENTS

Do you still need oprofile when you have perf?

> +       select MODULES_USE_ELF_REL if MODULES
> +       select MODULES_USE_ELF_RELA if MODULES

You should only need one of these two.

> +       select OLD_SIGACTION
> +       select OLD_SIGSUSPEND3

These should not be needed.

> +config CPU_HAS_CACHEV2
> +       bool
> +       default n
> +
> +config CPU_HAS_HILO
> +       bool
> +       default n
> +
> +config CPU_HAS_TLBI
> +       bool
> +       default n

'default n' is redundant and can be dropped.

> +config GENERIC_CALIBRATE_DELAY
> +       bool
> +       default y

Does your architecture provide a reliable high-reslution clocksource?
If yes, you
could use that for the delay, rather than a calibrated loop.

> +choice
> +        prompt "CPU MODEL"
> +        default CPU_CK610
> +
> +config CPU_CK610
> +        bool "CSKY CPU ck610"
> +       select CPU_NEED_TLBSYNC
> +       select CPU_NEED_SOFTALIGN
> +
> +config CPU_CK810
> +        bool "CSKY CPU ck810"
> +       select HIGHMEM
> +       select CPU_HAS_HILO
> +       select CPU_NEED_TLBSYNC
> +
> +config CPU_CK807
> +        bool "CSKY CPU ck807"
> +       select HIGHMEM
> +       select CPU_HAS_HILO
> +
> +config CPU_CK860
> +        bool "CSKY CPU ck860"
> +       select HIGHMEM
> +       select CPU_HAS_TLBI
> +       select CPU_HAS_CACHEV2
> +endchoice

Why select 'HIGHMEM' based on the CPU type? You should only need it
when you have more than 1GB of RAM, and it can be a performance
problem when it's enabled without need.

Usually the kernel should allow multiple CPU types to be selected
together, or ask for a "minimum architecture" level to be selected
by allow newer cores to be used as a superset.

> +config CPU_TLB_SIZE
> +       int
> +       default "128"   if(CPU_CK610 || CPU_CK807 || CPU_CK810)
> +       default "1024"  if(CPU_CK860)
> +
> +config L1_CACHE_SHIFT
> +       int
> +       default "4"     if(CPU_CK610)
> +       default "5"     if(CPU_CK807 || CPU_CK810)
> +       default "6"     if(CPU_CK860)

I think you then need to reverse the order of the list here: When e.g. CK860
and CK810 are both enabled, L1_CACHE_SHIFT should be the largest
possible size.

> +config SSEG0_BASE
> +       hex "Direct mapping physical address"
> +       default 0x0
> +       help
> +         There are MSAx regs can be used to change the base physical address
> +         of direct mapping. The default base physical address is 0x0.
> +
> +config RAM_BASE
> +       hex "DRAM base address offset from SSEG0_BASE, it must be the same with dts memory."
> +       default 0x08000000

To allow one kernel to run on multiple boards, it's better to detect
these two at runtime.

> +config CSKY_NR_IRQS
> +       int "NR_IRQS to max virtual interrupt numbers of the whole system"
> +       range 64 8192
> +       default "128"
> +endmenu

This should no longer be needed, with the IRQ domain code, any number
of interrupts
can be used without noticeable overhead.

> +menu "Power management options"
> +
> +source "kernel/power/Kconfig"
> +
> +config ARCH_SUSPEND_POSSIBLE
> +       bool y
> +       default y

Make it either

            def_bool y

or

           bool
           default y


> +config CSKY_BUILTIN_DTB
> +       bool "Use kernel builtin dtb"
> +       default n
> +
> +config CSKY_BUILTIN_DTB_NAME
> +       string "kernel builtin dtb name"
> +       depends on CSKY_BUILTIN_DTB

It's generally better not to use a builtin dtb, but use the bootloader
to pass a dtb.

If you need to support existing bootloaders, the best way is to allow
appending the dtb to the kernel.

> +ifeq ($(VERSION)_$(PATCHLEVEL), 4_9)
> +COMPAT_KERNEL_4_9 = -DCOMPAT_KERNEL_4_9
> +endif

Should not be needed

> +KBUILD_CFLAGS +=       -ffreestanding \

-ffreestanding usually results in worse code and should not be needed

> +                       -fno-tree-dse \
> +                       -pipe \
> +                       -Wno-uninitialized \

For -Wno-uninitialized, better fix the bugs properly. Can you explain
why you want
-fno-tree-dse?

> +++ b/arch/csky/abiv1/Makefile
> @@ -0,0 +1,8 @@
> +obj-y +=       src/bswapdi.o
> +obj-y +=       src/bswapsi.o
> +obj-y +=       src/cacheflush.o
> +obj-y +=       src/memcpy.o
> +obj-y +=       src/mmap.o
> +
> +obj-$(CONFIG_CPU_NEED_SOFTALIGN) +=    src/alignment.o

Better not use subdirectories like that.

Can you explain why you need the alignement fixups?

            Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 14/19] csky: Misc headers
  2018-03-18 19:51 ` [PATCH 14/19] csky: Misc headers Guo Ren
@ 2018-03-19 16:11   ` Arnd Bergmann
  2018-03-20  3:36     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-19 16:11 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 19, 2018 at 3:51 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> +++ b/arch/csky/include/uapi/asm/fcntl.h
> @@ -0,0 +1,13 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
> +#ifndef __ASM_CSKY_FCNTL_H
> +#define __ASM_CSKY_FCNTL_H
> +
> +#define O_DIRECTORY    040000
> +#define O_NOFOLLOW     0100000
> +#define O_DIRECT       0200000
> +#define O_LARGEFILE    0400000
> +
> +#include <asm-generic/fcntl.h>

This should just use the generic file without overrides: Please don't diverge
from the generic syscall ABI.

> --- /dev/null
> +++ b/arch/csky/include/uapi/asm/stat.h
> @@ -0,0 +1,86 @@
> +// SPDX-License-Identifier: GPL-2.0
> +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
> +#ifndef _CSKY_STAT_H
> +#define _CSKY_STAT_H
> +
> +struct __old_kernel_stat {
> +       unsigned short st_dev;

Same here: no need for __old_kernel_stat  or the headers on new architectures.

          Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 06/19] csky: IRQ handling
  2018-03-19 13:16   ` Thomas Gleixner
@ 2018-03-20  2:06     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-20  2:06 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: linux-arch, linux-kernel, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi Thomas,

On Mon, Mar 19, 2018 at 02:16:37PM +0100, Thomas Gleixner wrote:
> > +static inline unsigned long arch_local_irq_save(void)
> > +{
> > +	unsigned long flags;
> 
> Newline between declaration and code please.
OK

> > +void csky_do_IRQ(int irq, struct pt_regs *regs)
> 
> static? If not, then it needs a declaration in a header somewhere.
Yes, need static.

> > +asmlinkage void csky_do_auto_IRQ(struct pt_regs *regs)
> > +{
> > +	unsigned long irq, psr;
> > +
> > +	asm volatile("mfcr %0, psr":"=r"(psr));
> > +
> > +	irq = (psr >> 16) & 0xff;
> > +
> > +	if (irq == 10)
> > +		irq = csky_get_auto_irqno();
> > +	else
> > +		irq -= 32;
> 
> Please add a comment explaining this magic here. Magic numbers w/o
> explanation are bad.
Yes, you are right. I will fixup them next.

PSR is our Processor Status Register and it store the vector number.

'10' is our auto-interrupt exception entry and we need get the irqno
from the interrupt-controller.

The "vector num > 32" is our vector interrupt exception entries, so we
can calculate the irq-num by vector-num and no need to access the
interrupt-controller's io regs.

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 14/19] csky: Misc headers
  2018-03-19 16:11   ` Arnd Bergmann
@ 2018-03-20  3:36     ` Guo Ren
  2018-03-20  7:54       ` Arnd Bergmann
  0 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-20  3:36 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

Hi Arnd,

On Tue, Mar 20, 2018 at 12:11:24AM +0800, Arnd Bergmann wrote:
> On Mon, Mar 19, 2018 at 3:51 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> > +++ b/arch/csky/include/uapi/asm/fcntl.h
> > @@ -0,0 +1,13 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
> > +#ifndef __ASM_CSKY_FCNTL_H
> > +#define __ASM_CSKY_FCNTL_H
> > +
> > +#define O_DIRECTORY    040000
> > +#define O_NOFOLLOW     0100000
> > +#define O_DIRECT       0200000
> > +#define O_LARGEFILE    0400000
> > +
> > +#include <asm-generic/fcntl.h>
> 
> This should just use the generic file without overrides: Please don't diverge
> from the generic syscall ABI.
>

It's a stupid copy from arm/include/uapi/asm/fcntl.h and the csky/bits/fcntl.h
in uclibc-ng and glibc are also defined with:

#define __O_DIRECTORY	 040000	/* Must be a directory.	 */
#define __O_NOFOLLOW	0100000	/* Do not follow links.	 */
#define __O_DIRECT	0200000	/* Direct disk access.	*/
#define __O_LARGEFILE	0400000

So may I keep it for a while?
(I will let glibc uclibc-ng csky/bits/fcntl.h include the linux/uapi/asm/fcntl.h
first.)


> > +struct __old_kernel_stat {
> > +       unsigned short st_dev;
> 
> Same here: no need for __old_kernel_stat  or the headers on new architectures.
>
OK

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 14/19] csky: Misc headers
  2018-03-20  3:36     ` Guo Ren
@ 2018-03-20  7:54       ` Arnd Bergmann
  2018-03-20 13:22         ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-20  7:54 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Tue, Mar 20, 2018 at 11:36 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> Hi Arnd,
>
> On Tue, Mar 20, 2018 at 12:11:24AM +0800, Arnd Bergmann wrote:
>> On Mon, Mar 19, 2018 at 3:51 AM, Guo Ren <ren_guo@c-sky.com> wrote:
>> > +++ b/arch/csky/include/uapi/asm/fcntl.h
>> > @@ -0,0 +1,13 @@
>> > +// SPDX-License-Identifier: GPL-2.0
>> > +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
>> > +#ifndef __ASM_CSKY_FCNTL_H
>> > +#define __ASM_CSKY_FCNTL_H
>> > +
>> > +#define O_DIRECTORY    040000
>> > +#define O_NOFOLLOW     0100000
>> > +#define O_DIRECT       0200000
>> > +#define O_LARGEFILE    0400000
>> > +
>> > +#include <asm-generic/fcntl.h>
>>
>> This should just use the generic file without overrides: Please don't diverge
>> from the generic syscall ABI.
>>
>
> It's a stupid copy from arm/include/uapi/asm/fcntl.h and the csky/bits/fcntl.h
> in uclibc-ng and glibc are also defined with:
>
> #define __O_DIRECTORY    040000 /* Must be a directory.  */
> #define __O_NOFOLLOW    0100000 /* Do not follow links.  */
> #define __O_DIRECT      0200000 /* Direct disk access.  */
> #define __O_LARGEFILE   0400000
>
> So may I keep it for a while?
> (I will let glibc uclibc-ng csky/bits/fcntl.h include the linux/uapi/asm/fcntl.h
> first.)

We generally assume that any upstream kernel ABI cannot be changed, so this
has to be changed before the code gets merged upstream.

You can obviously maintain the old and the new ABI in parallel for a while,
until the libc supports the new ABI, but you can't do that in the patches
you send for integration.

This is more important for the list of system calls, but when you change
the ABI, it should be changed all at once.

           Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-19 15:45   ` Arnd Bergmann
@ 2018-03-20 13:13     ` Guo Ren
  2018-03-21  7:36       ` Arnd Bergmann
  0 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-20 13:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

Hi arnd,

On Mon, Mar 19, 2018 at 11:45:23PM +0800, Arnd Bergmann wrote:
> > +       select ARCH_WANT_IPC_PARSE_VERSION
> 
> Drop ipc_parse_version here, it's only for old architectures.
>
I will remove it.

> > +       select HAVE_OPROFILE
> > +       select HAVE_PERF_EVENTS
> 
> Do you still need oprofile when you have perf?
I'll remove HAVE_OPROFILE and arch/csky/oprofile.

> > +       select MODULES_USE_ELF_REL if MODULES
> > +       select MODULES_USE_ELF_RELA if MODULES
> 
> You should only need one of these two.
Yes, I will keep RELA and current csky-gcc only give .rela section.

> > +       select OLD_SIGACTION
> > +       select OLD_SIGSUSPEND3
> 
> These should not be needed.
Ok, remove them.

> > +config CPU_HAS_TLBI
> > +       bool
> > +       default n
> 
> 'default n' is redundant and can be dropped.
Ok

> > +config GENERIC_CALIBRATE_DELAY
> > +       bool
> > +       default y
> 
> Does your architecture provide a reliable high-reslution clocksource?
> If yes, you
> could use that for the delay, rather than a calibrated loop.
Currently, all boards have clocksource drivers and the reslution is depend on SOC.
I'll try to remove it.

> > +       select HIGHMEM
> > +       select CPU_HAS_TLBI
> > +       select CPU_HAS_CACHEV2
> > +endchoice
> 
> Why select 'HIGHMEM' based on the CPU type? You should only need it
> when you have more than 1GB of RAM, and it can be a performance
> problem when it's enabled without need.
OK, I'll give a HIGHMEM option.
 
> Usually the kernel should allow multiple CPU types to be selected
> together, or ask for a "minimum architecture" level to be selected
> by allow newer cores to be used as a superset.
No, I need keep them seperate.

> > +config CPU_TLB_SIZE
> > +       int
> > +       default "128"   if(CPU_CK610 || CPU_CK807 || CPU_CK810)
> > +       default "1024"  if(CPU_CK860)
> > +
> > +config L1_CACHE_SHIFT
> > +       int
> > +       default "4"     if(CPU_CK610)
> > +       default "5"     if(CPU_CK807 || CPU_CK810)
> > +       default "6"     if(CPU_CK860)
> 
> I think you then need to reverse the order of the list here: When e.g. CK860
> and CK810 are both enabled, L1_CACHE_SHIFT should be the largest
> possible size.
No, I use L1_CACHE_SHIFT to determine the size of cache_line.
When I flush cache for a range of memory, I need the size to loop flush cache line.

> > +config SSEG0_BASE
> > +       hex "Direct mapping physical address"
> > +       default 0x0
> > +       help
> > +         There are MSAx regs can be used to change the base physical address
> > +         of direct mapping. The default base physical address is 0x0.
> > +
> > +config RAM_BASE
> > +       hex "DRAM base address offset from SSEG0_BASE, it must be the same with dts memory."
> > +       default 0x08000000
> 
> To allow one kernel to run on multiple boards, it's better to detect
> these two at runtime.
CK-CPUs have a mips-like direct-mapping, and I use the macros to calculate the virtual-addr 
in headers.

> > +config CSKY_NR_IRQS
> > +       int "NR_IRQS to max virtual interrupt numbers of the whole system"
> > +       range 64 8192
> > +       default "128"
> > +endmenu
> 
> This should no longer be needed, with the IRQ domain code, any number
> of interrupts
> can be used without noticeable overhead.
Not I use it, some of our users need it to expand the GPIO irqs. Because
they don't use irq domain code properly. I move it to Kconfig.debug, OK?

> Make it either
> 
>             def_bool y
> 
> or
> 
>            bool
>            default y
OK

> > +config CSKY_BUILTIN_DTB
> > +       bool "Use kernel builtin dtb"
> > +       default n
> > +
> > +config CSKY_BUILTIN_DTB_NAME
> > +       string "kernel builtin dtb name"
> > +       depends on CSKY_BUILTIN_DTB
> 
> It's generally better not to use a builtin dtb, but use the bootloader
> to pass a dtb.
> 
> If you need to support existing bootloaders, the best way is to allow
> appending the dtb to the kernel.
Most of our boards use bootloader to pass the dtb, but Hangzhou
Nationalchip want dtb compiled in the vmlinux. So I keep it in
Kconfig.debug.

> > +ifeq ($(VERSION)_$(PATCHLEVEL), 4_9)
> > +COMPAT_KERNEL_4_9 = -DCOMPAT_KERNEL_4_9
> > +endif
> 
> Should not be needed
May I keep it? It's a very internal macro for arch/csky and I can
maintain the linux-4.9 together.


> > +KBUILD_CFLAGS +=       -ffreestanding \
> 
> -ffreestanding usually results in worse code and should not be needed
OK, remove it.

> > +                       -fno-tree-dse \
> > +                       -pipe \
> > +                       -Wno-uninitialized \
> 
> For -Wno-uninitialized, better fix the bugs properly. Can you explain
> why you want
It will mask some warnings :P, and I will remove it.

> -fno-tree-dse?
This is from "gcc-4.5 compile linux-4.7" and it will cause wrong code without
-fno-tree-dse for list.h. Now we use gcc-6.3, so I will try to remove it.

> > +++ b/arch/csky/abiv1/Makefile
> > @@ -0,0 +1,8 @@
> > +obj-y +=       src/bswapdi.o
> > +obj-y +=       src/bswapsi.o
> > +obj-y +=       src/cacheflush.o
> > +obj-y +=       src/memcpy.o
> > +obj-y +=       src/mmap.o
> > +
> > +obj-$(CONFIG_CPU_NEED_SOFTALIGN) +=    src/alignment.o
> 
> Better not use subdirectories like that.
Ok, I will change them like this:
  obj-y +=	bswapdi.o
  obj-y +=	bswapsi.o
  ...

> Can you explain why you need the alignement fixups?
For abiv1 ck610 couldn't handle the unalignment address access, so we
need soft-alignment exception to fixup. There is no problem in abiv2 cpus.

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 14/19] csky: Misc headers
  2018-03-20  7:54       ` Arnd Bergmann
@ 2018-03-20 13:22         ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-20 13:22 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Tue, Mar 20, 2018 at 03:54:53PM +0800, Arnd Bergmann wrote:
> We generally assume that any upstream kernel ABI cannot be changed, so this
> has to be changed before the code gets merged upstream.
> 
> You can obviously maintain the old and the new ABI in parallel for a while,
> until the libc supports the new ABI, but you can't do that in the patches
> you send for integration.
> 
> This is more important for the list of system calls, but when you change
> the ABI, it should be changed all at once.
Ok, follow the rules. I will modify uclibc-ng and glibc now.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 16/19] csky: Device tree
  2018-03-19 15:28   ` Arnd Bergmann
@ 2018-03-20 13:55     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-20 13:55 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

Hi Arnd,

On Mon, Mar 19, 2018 at 11:28:03PM +0800, Arnd Bergmann wrote:
> Please add a changelog text to each patch, and send patches that add
> .dts files or
> binding documents to the devicetree mailing list.
Ok

> It is usually better for an SoC based board to split the SoC specific into a
> separate .dtsi file that gets included by the board .dts file.
Ok

> > +/ {
> > +       model = "Nationalchip gx6605s ck610";
> > +       compatible = "nationalchip,gx6605s,ck610";
> 
> Is ck610 the name of the CPU core? The general convention is to have the
> top-level "compatible" property list first the name of the board, then the
> name of the soc, but not the name of the CPU core.
Yes, ck610 is a cpu core of abiv1. and I will change it like this:
	model = "Zhuxian-sword gx6605s Development Board";
	compatible = "zhuxian-sword,gx6605s";
ref: https://c-sky.github.io/docs/gx6605s.html

> Here you should list the specific type of CPU in the compatible property and
> document the binding for that string in the Documentations/devicetree/bindings
> hierarchy. Without a binding, the 'ccr' and 'hint' properties make no sense.
Sorry, I forget remove the cpu region. It's no use now.

> If there is any chance that you could have SMP systems in the future, it
> would be better to start with #address-cells=<1>, with appropriate reg
> properties.
Ok

> Each node with a register property also needs the address in the
> node name, e.g. "interrupt-controller@500000"
Ok

> Try building the dtb file with 'make W=1' to get warnings about
> when you got that wrong.
Thx

> > +               timer0 {
> > +                       compatible = "nationalchip,timer-v1";
> 
> This should be "timer@400"
Ok

> Also, each device node should have a binding documentation
> to explain the binding associated with that "compatible"
> string.
Ok, I will add them.

> > +               ohci0: ohci-hcd0 {
> The names here should be "usb@...", not "ehci-hcd"
Ok

> > +       chosen {
> > +               bootargs = "console=ttyS0,115200 rdinit=/sbin/init root=/dev/ram0";
> > +       };
> 
> The bootargs should not be in the dts file normally, they should come from the
> boot loader.
I want to keep bootargs in dts, because the bootloader only pass the dtb to kernel. 

> For the console, use the "stdout-path" property.
Ok

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c
  2018-03-19 13:30   ` Thomas Gleixner
@ 2018-03-20 14:23     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-20 14:23 UTC (permalink / raw)
  To: Thomas Gleixner
  Cc: linux-arch, linux-kernel, daniel.lezcano, jason, arnd,
	c-sky_gcc_upstream, gnu-csky, thomas.petazzoni, wbx

Hi Thomas,

On Mon, Mar 19, 2018 at 02:30:42PM +0100, Thomas Gleixner wrote:
> > +static struct irq_chip ck_irq_chip = {
> > +	.name		= "csky_intc_v1",
> > +	.irq_mask	= ck_irq_mask,
> > +	.irq_unmask	= ck_irq_unmask,
> > +};
> 
> Please use the generic interrupt chip infrastructure for this.
Ok, I will learn it.

> > +static unsigned int ck_get_irqno(void)
> > +{
> > +	unsigned int temp;
> 
> newline between declaration and code.
Ok

> > +	temp = __raw_readl(CK_VA_INTC_ISR);
> > +	return temp & 0x3f;
> > +};
> > +
> > +static int __init
> > +__intc_init(struct device_node *np, struct device_node *parent, bool ave)
> 
> What is 'ave'?
Ave means the irq-controller works on auto-vector-handler mode, it will
cause 10 exception number and it need read intc-reg to get irq-num.

> No magic numbers. Please use proper defines.
Ok

> > +	else
> > +		__raw_writel( 0x0, CK_VA_INTC_ICR);
> > +	/*
> > +	 * csky irq ctrl has 64 sources.
> > +	 */
> > +	#define INTC_IRQS 64
> 
> No defines in code.
Ok

> 
> > +	for (i=0; i<INTC_IRQS; i=i+4)
> 
> checkpatch.pl would have told you what's wrong with the above
Ok, Thx

> > +		__raw_writel((i+3)|((i+2)<<8)|((i+1)<<16)|(i<<24),
> 
> Eew. Tons of magic numbers and a unreadable coding style. Please use an
> inline function with proper comments to calculate that value
Ok

> > +				CK_VA_INTC_SOURCE + i);
> > +
> > +	root_domain = irq_domain_add_legacy(np, INTC_IRQS, 0, 0, &ck_irq_ops, NULL);
> > +	if (!root_domain)
> > +		panic("root irq domain not available\n");
> > +
> > +	irq_set_default_host(root_domain);
> > +
> > +	return 0;
> > +}
> > +
> > +static int __init
> > +intc_init(struct device_node *np, struct device_node *parent)
> > +{
> > +
> 
> Stray newline
I'll remove, Thx.

> > +	return __intc_init(np, parent, false);
> > +}
> > +IRQCHIP_DECLARE(csky_intc_v1, "csky,intc-v1", intc_init);
> > +
> > +/*
> > + * use auto vector exceptions 10 for interrupt.
> > + */
> > +static int __init
> > +intc_init_ave(struct device_node *np, struct device_node *parent)
> > +{
> > +	return __intc_init(np, parent, true);
> 
> Why is that 'ave' thing not a property of device tree?
I'll change it to a property.

> > +struct irq_chip nc_irq_chip = {
> > +	.name =		"nationalchip_intc_v1",
> > +	.irq_mask =	nc_irq_mask,
> > +	.irq_unmask =	nc_irq_unmask,
> > +	.irq_enable =	nc_irq_en,
> > +	.irq_disable =	nc_irq_dis,
> > +};
> 
> Again. This all can use the generic interrupt chip.
I'll learn the generic interrupt chip.

> > +inline int ff1_64(unsigned int hi, unsigned int lo)
> 
> What on earth means ff1_64?
Find the first high bit '1' of the reg :P

> > +	asm volatile(
> > +		"ff1 %0\n"
> > +		:"=r"(lo)
> > +		:"r"(lo)
> > +		:
> > +	);
> 
> So you want to decode the interrupt number from a bitfield. What's wrong
> with ffs()?
There is no wrong with ffs(). Ok, I will use the ffs().

> > +	if( lo != 32 )
> > +		result = 31-lo;
> 
> Why is this subtracted?
ff1 find from high bit, so we need reverse it to get the right num.
> That code makes no sense w/o comments.
Sorry, I will add.

> > +	else if( hi != 32 ) result = 31-hi + 32;
> > +	else {
> > +		printk("nc_get_irqno error hi:%x, lo:%x.\n", hi, lo);
> > +		result = NR_IRQS;
> > +	}
> 
> Pleas use braces consistently.
Ok

> > +unsigned int nc_get_irqno(void)
> 
> static?
Yes

> Same comments as for the other variant.
Ok

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-20 13:13     ` Guo Ren
@ 2018-03-21  7:36       ` Arnd Bergmann
  2018-03-21 12:41         ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-21  7:36 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Tue, Mar 20, 2018 at 9:13 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> Hi arnd,
>
> On Mon, Mar 19, 2018 at 11:45:23PM +0800, Arnd Bergmann wrote:
>> Does your architecture provide a reliable high-reslution clocksource?
>> If yes, you
>> could use that for the delay, rather than a calibrated loop.
> Currently, all boards have clocksource drivers and the reslution is depend on SOC.
> I'll try to remove it.

If the clocksource depends on a driver rather than a feature of the
architecture,
this may not be worth optimizing though, so maybe leave it as it is for now.

>> Usually the kernel should allow multiple CPU types to be selected
>> together, or ask for a "minimum architecture" level to be selected
>> by allow newer cores to be used as a superset.
> No, I need keep them seperate.

Can you explain? What is it that makes them all incompatible?

>> > +config CPU_TLB_SIZE
>> > +       int
>> > +       default "128"   if(CPU_CK610 || CPU_CK807 || CPU_CK810)
>> > +       default "1024"  if(CPU_CK860)
>> > +
>> > +config L1_CACHE_SHIFT
>> > +       int
>> > +       default "4"     if(CPU_CK610)
>> > +       default "5"     if(CPU_CK807 || CPU_CK810)
>> > +       default "6"     if(CPU_CK860)
>>
>> I think you then need to reverse the order of the list here: When e.g. CK860
>> and CK810 are both enabled, L1_CACHE_SHIFT should be the largest
>> possible size.
> No, I use L1_CACHE_SHIFT to determine the size of cache_line.
> When I flush cache for a range of memory, I need the size to loop flush cache line.

This is still relatively easy to fix, you just need a cpu specific loop
that uses the actual line size rather than the maximum size.

>> > +config SSEG0_BASE
>> > +       hex "Direct mapping physical address"
>> > +       default 0x0
>> > +       help
>> > +         There are MSAx regs can be used to change the base physical address
>> > +         of direct mapping. The default base physical address is 0x0.
>> > +
>> > +config RAM_BASE
>> > +       hex "DRAM base address offset from SSEG0_BASE, it must be the same with dts memory."
>> > +       default 0x08000000
>>
>> To allow one kernel to run on multiple boards, it's better to detect
>> these two at runtime.
> CK-CPUs have a mips-like direct-mapping, and I use the macros to calculate the virtual-addr
> in headers.

On many architectures, we detect the offsets at boot time and pass
them as variables. On
ARM, we go as far as patching the kernel at boot time to have constant
offsets, but usually
it's not worth the effort.

>> > +config CSKY_NR_IRQS
>> > +       int "NR_IRQS to max virtual interrupt numbers of the whole system"
>> > +       range 64 8192
>> > +       default "128"
>> > +endmenu
>>
>> This should no longer be needed, with the IRQ domain code, any number
>> of interrupts
>> can be used without noticeable overhead.
> Not I use it, some of our users need it to expand the GPIO irqs. Because
> they don't use irq domain code properly. I move it to Kconfig.debug, OK?

It sounds like your GPIO driver should get fixed to use irq domains right,
it should not be too hard. The number of GPIOs is typically a compile
time constant today, but we also try to turn it into a dynamic allocation
that we have for IRQs on most targets.

>> > +config CSKY_BUILTIN_DTB
>> > +       bool "Use kernel builtin dtb"
>> > +       default n
>> > +
>> > +config CSKY_BUILTIN_DTB_NAME
>> > +       string "kernel builtin dtb name"
>> > +       depends on CSKY_BUILTIN_DTB
>>
>> It's generally better not to use a builtin dtb, but use the bootloader
>> to pass a dtb.
>>
>> If you need to support existing bootloaders, the best way is to allow
>> appending the dtb to the kernel.
> Most of our boards use bootloader to pass the dtb, but Hangzhou
> Nationalchip want dtb compiled in the vmlinux. So I keep it in
> Kconfig.debug.

What I meant here is that you can get the same behavior by
appending the dtb to the kernel rather than linking it into the
kernel. The reason for preferring the appended one is that you
can more easily use the same kernel binary across boards with
different bootloaders.

>> > +ifeq ($(VERSION)_$(PATCHLEVEL), 4_9)
>> > +COMPAT_KERNEL_4_9 = -DCOMPAT_KERNEL_4_9
>> > +endif
>>
>> Should not be needed
> May I keep it? It's a very internal macro for arch/csky and I can
> maintain the linux-4.9 together.

I'd say it's better to get rid of it for the upstream port, more importantly
getting rid of the code that checks for this symbol. Usually what happens
with version checks like this one is that they get out of sync quickly
as a new kernel version does things differently and diverges more
from the old release you were comparing against. In device drivers,
we tend to remove all those checks.

>> -fno-tree-dse?
> This is from "gcc-4.5 compile linux-4.7" and it will cause wrong code without
> -fno-tree-dse for list.h. Now we use gcc-6.3, so I will try to remove it.

You can also use the cc-ifversion Makefile macro to apply it on
the old compiler. That way you can still use gcc-4.5 as long as
that remains relevant but don't get worse code generation on
modern versions.

>> > +++ b/arch/csky/abiv1/Makefile
>> > @@ -0,0 +1,8 @@
>> > +obj-y +=       src/bswapdi.o
>> > +obj-y +=       src/bswapsi.o
>> > +obj-y +=       src/cacheflush.o
>> > +obj-y +=       src/memcpy.o
>> > +obj-y +=       src/mmap.o
>> > +
>> > +obj-$(CONFIG_CPU_NEED_SOFTALIGN) +=    src/alignment.o
>>
>> Better not use subdirectories like that.
> Ok, I will change them like this:
>   obj-y +=      bswapdi.o
>   obj-y +=      bswapsi.o
>   ...
>
>> Can you explain why you need the alignement fixups?
> For abiv1 ck610 couldn't handle the unalignment address access, so we
> need soft-alignment exception to fixup. There is no problem in abiv2 cpus.

Ok. Generally speaking, architectures that don't allow unaligned access
should have all code built in a way that uses aligned access (gcc normally
falls back to byte access when it encounters an unaligned pointer at
compile time), but if this is just for old CPUs that are not used in future
products, having the fixup does sound simpler, as it allows you to still
run new binaries on the old machines. I haven't looked at the implementation
for the fixup here, but I remember the same thing from the nds32 port.
In that case, we ended up keeping the fixup as an option for old
user space, but disabled to softalign fixups for kernel code. Can you do
the same thing here?

         Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-21  7:36       ` Arnd Bergmann
@ 2018-03-21 12:41         ` Guo Ren
  2018-03-26 13:00           ` Arnd Bergmann
  0 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-21 12:41 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

Hi arnd,

On Wed, Mar 21, 2018 at 03:36:43PM +0800, Arnd Bergmann wrote:
> If the clocksource depends on a driver rather than a feature of the
> architecture,
> this may not be worth optimizing though, so maybe leave it as it is for now.
>
Ok, I'll keep it.

> >> Usually the kernel should allow multiple CPU types to be selected
> >> together, or ask for a "minimum architecture" level to be selected
> >> by allow newer cores to be used as a superset.
> > No, I need keep them seperate.
> 
> Can you explain? What is it that makes them all incompatible?
ck610 is abiv1 and its gcc is different from abiv2, they are:
 - csky-linux-abiv1-gcc
 - csky-linux-abiv2-gcc

ck807/810/860 use the same csky-linux-abiv2-gcc, but their instruction-sets
and pipeline schedule are different. So our gcc must&only use '-mcpu=' to
determine which cpu series is. They are different cpu series.

    ck610 only  have: ck610
    ck807 could have: ck807 ck807f ck807vf ck807ef
    ck810 could have: ck810 ck810f ck810vf ck810ef
    ck860 could have: ck860 ck860f ck860vf
  f: means FPU co-processor
  v: means VDSP co-processor just like "ARM-NEON"
  e: is our old DSP co-processor which use HI-LO regs for operation. In
  current ck807/ck810 they default have HI-LO regs, so ck807&ck807e is
  the same for me.

For this patch-set, we support:
   ck610
  (ck807/ck807f/ck807ef)
  (ck810/ck810e/ck810ef)

> >> > +config CPU_TLB_SIZE
> >> > +       int
> >> > +       default "128"   if(CPU_CK610 || CPU_CK807 || CPU_CK810)
> >> > +       default "1024"  if(CPU_CK860)
> >> > +
> >> > +config L1_CACHE_SHIFT
> >> > +       int
> >> > +       default "4"     if(CPU_CK610)
> >> > +       default "5"     if(CPU_CK807 || CPU_CK810)
> >> > +       default "6"     if(CPU_CK860)
> >>
> >> I think you then need to reverse the order of the list here: When e.g. CK860
> >> and CK810 are both enabled, L1_CACHE_SHIFT should be the largest
> >> possible size.
> > No, I use L1_CACHE_SHIFT to determine the size of cache_line.
> > When I flush cache for a range of memory, I need the size to loop flush cache line.
> 
> This is still relatively easy to fix, you just need a cpu specific loop
> that uses the actual line size rather than the maximum size.
Here is my cacheflush code in mm/cachev2.c:
	#define L1_CACHE_BYTES (1<<L1_CACHE_SHIFT)
	for(i=start; i<end; i+=L1_CACHE_BYTES)
		asm volatile("dcache.cval1 %0\n"::"r"(i));
	asm volatile("sync.is\n");

I use L1_CACHE_BYTES as the loop element to increase. So it must be the
current CPU cache line size for "correct&performance". Each of our CPU-series
has a fixed cache line size:
ck610 is 16Bytes
ck807/ck810 is 32Bytes
ck860 is 64Bytes
So I don't need determine them in .dts or detect on boot, just define them in Kconfig.

> >> > +config SSEG0_BASE
> >> > +       hex "Direct mapping physical address"
> >> > +       default 0x0
> >> > +       help
> >> > +         There are MSAx regs can be used to change the base physical address
> >> > +         of direct mapping. The default base physical address is 0x0.
> >> > +
> >> > +config RAM_BASE
> >> > +       hex "DRAM base address offset from SSEG0_BASE, it must be the same with dts memory."
> >> > +       default 0x08000000
> >>
> >> To allow one kernel to run on multiple boards, it's better to detect
> >> these two at runtime.
> > CK-CPUs have a mips-like direct-mapping, and I use the macros to calculate the virtual-addr
> > in headers.
> 
> On many architectures, we detect the offsets at boot time and pass
> them as variables. On
> ARM, we go as far as patching the kernel at boot time to have constant
> offsets, but usually
> it's not worth the effort.
I know it's duplicate setting with dts for users. But now, I still want
to keep them. I'll consider your advices in future.

> >> > +config CSKY_NR_IRQS
> >> > +       int "NR_IRQS to max virtual interrupt numbers of the whole system"
> >> > +       range 64 8192
> >> > +       default "128"
> >> > +endmenu
> >>
> >> This should no longer be needed, with the IRQ domain code, any number
> >> of interrupts
> >> can be used without noticeable overhead.
> > Not I use it, some of our users need it to expand the GPIO irqs. Because
> > they don't use irq domain code properly. I move it to Kconfig.debug, OK?
> 
> It sounds like your GPIO driver should get fixed to use irq domains right,
> it should not be too hard. The number of GPIOs is typically a compile
> time constant today, but we also try to turn it into a dynamic allocation
> that we have for IRQs on most targets.
Got it, remove the CSKY_NR_IRQS.

> What I meant here is that you can get the same behavior by
> appending the dtb to the kernel rather than linking it into the
> kernel. The reason for preferring the appended one is that you
> can more easily use the same kernel binary across boards with
> different bootloaders.
Ok, got it. I'll use the dtb passed by bootloader first.

> I'd say it's better to get rid of it for the upstream port, more importantly
> getting rid of the code that checks for this symbol. Usually what happens
> with version checks like this one is that they get out of sync quickly
> as a new kernel version does things differently and diverges more
> from the old release you were comparing against. In device drivers,
> we tend to remove all those checks.
Ok, follow the rules.

> 
> >> -fno-tree-dse?
> > This is from "gcc-4.5 compile linux-4.7" and it will cause wrong code without
> > -fno-tree-dse for list.h. Now we use gcc-6.3, so I will try to remove it.
> 
> You can also use the cc-ifversion Makefile macro to apply it on
> the old compiler. That way you can still use gcc-4.5 as long as
> that remains relevant but don't get worse code generation on
> modern versions.
Thx for advice, but we don't need support gcc-4.5 now. I'll just remove
them.

> >> Can you explain why you need the alignement fixups?
> > For abiv1 ck610 couldn't handle the unalignment address access, so we
> > need soft-alignment exception to fixup. There is no problem in abiv2 cpus.
> 
> Ok. Generally speaking, architectures that don't allow unaligned access
> should have all code built in a way that uses aligned access (gcc normally
> falls back to byte access when it encounters an unaligned pointer at
> compile time), but if this is just for old CPUs that are not used in future
> products, having the fixup does sound simpler, as it allows you to still
> run new binaries on the old machines. I haven't looked at the implementation
> for the fixup here, but I remember the same thing from the nds32 port.
> In that case, we ended up keeping the fixup as an option for old
> user space, but disabled to softalign fixups for kernel code. Can you do
> the same thing here?
Ok. I got it, I'll do the same as nds32.

Best Regards
  Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-21 12:41         ` Guo Ren
@ 2018-03-26 13:00           ` Arnd Bergmann
  2018-03-27  2:39             ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-26 13:00 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Wed, Mar 21, 2018 at 1:41 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> Hi arnd,
>
> On Wed, Mar 21, 2018 at 03:36:43PM +0800, Arnd Bergmann wrote:
>> If the clocksource depends on a driver rather than a feature of the
>> architecture,
>> this may not be worth optimizing though, so maybe leave it as it is for now.
>>
> Ok, I'll keep it.
>
>> >> Usually the kernel should allow multiple CPU types to be selected
>> >> together, or ask for a "minimum architecture" level to be selected
>> >> by allow newer cores to be used as a superset.
>> > No, I need keep them seperate.
>>
>> Can you explain? What is it that makes them all incompatible?
> ck610 is abiv1 and its gcc is different from abiv2, they are:
>  - csky-linux-abiv1-gcc
>  - csky-linux-abiv2-gcc
>
> ck807/810/860 use the same csky-linux-abiv2-gcc, but their instruction-sets
> and pipeline schedule are different. So our gcc must&only use '-mcpu=' to
> determine which cpu series is. They are different cpu series.
>
>     ck610 only  have: ck610
>     ck807 could have: ck807 ck807f ck807vf ck807ef
>     ck810 could have: ck810 ck810f ck810vf ck810ef
>     ck860 could have: ck860 ck860f ck860vf
>   f: means FPU co-processor
>   v: means VDSP co-processor just like "ARM-NEON"
>   e: is our old DSP co-processor which use HI-LO regs for operation. In
>   current ck807/ck810 they default have HI-LO regs, so ck807&ck807e is
>   the same for me.
>
> For this patch-set, we support:
>    ck610
>   (ck807/ck807f/ck807ef)
>   (ck810/ck810e/ck810ef)

Ok, I understand the part about ck610 being incompatible, but I'm
still not sure about the 8xx ones: Do you mean it's impossible to
have one kernel that runs across all of them for some other reason,
or is it something you haven't allowed because you see no use for it?

>> >> > +config CPU_TLB_SIZE
>> >> > +       int
>> >> > +       default "128"   if(CPU_CK610 || CPU_CK807 || CPU_CK810)
>> >> > +       default "1024"  if(CPU_CK860)
>> >> > +
>> >> > +config L1_CACHE_SHIFT
>> >> > +       int
>> >> > +       default "4"     if(CPU_CK610)
>> >> > +       default "5"     if(CPU_CK807 || CPU_CK810)
>> >> > +       default "6"     if(CPU_CK860)
>> >>
>> >> I think you then need to reverse the order of the list here: When e.g. CK860
>> >> and CK810 are both enabled, L1_CACHE_SHIFT should be the largest
>> >> possible size.
>> > No, I use L1_CACHE_SHIFT to determine the size of cache_line.
>> > When I flush cache for a range of memory, I need the size to loop flush cache line.
>>
>> This is still relatively easy to fix, you just need a cpu specific loop
>> that uses the actual line size rather than the maximum size.
> Here is my cacheflush code in mm/cachev2.c:
>         #define L1_CACHE_BYTES (1<<L1_CACHE_SHIFT)
>         for(i=start; i<end; i+=L1_CACHE_BYTES)
>                 asm volatile("dcache.cval1 %0\n"::"r"(i));
>         asm volatile("sync.is\n");
>
> I use L1_CACHE_BYTES as the loop element to increase. So it must be the
> current CPU cache line size for "correct&performance". Each of our CPU-series
> has a fixed cache line size:
> ck610 is 16Bytes
> ck807/ck810 is 32Bytes
> ck860 is 64Bytes
> So I don't need determine them in .dts or detect on boot, just define them in Kconfig.

This is basically the same question as above: For c610, using the fixed
value is sufficient, because it's incompatible with the others. But if you want
to run the same kernel on both ck810 and ck860, then it needs some form
of runtime detection.

On other architectures, the L1_CACHE_BYTES constant is the maximum
possible cache line size, and the cache flush function uses the actual size

>> >> > +config SSEG0_BASE
>> >> > +       hex "Direct mapping physical address"
>> >> > +       default 0x0
>> >> > +       help
>> >> > +         There are MSAx regs can be used to change the base physical address
>> >> > +         of direct mapping. The default base physical address is 0x0.
>> >> > +
>> >> > +config RAM_BASE
>> >> > +       hex "DRAM base address offset from SSEG0_BASE, it must be the same with dts memory."
>> >> > +       default 0x08000000
>> >>
>> >> To allow one kernel to run on multiple boards, it's better to detect
>> >> these two at runtime.
>> > CK-CPUs have a mips-like direct-mapping, and I use the macros to calculate the virtual-addr
>> > in headers.
>>
>> On many architectures, we detect the offsets at boot time and pass
>> them as variables. On
>> ARM, we go as far as patching the kernel at boot time to have constant
>> offsets, but usually
>> it's not worth the effort.
> I know it's duplicate setting with dts for users. But now, I still want
> to keep them. I'll consider your advices in future.

Ok. Just make sure that the DT always has this information as well,
so this can be changed in the future when desired, without having to
make incompatible changes to the devicetree binary files.

       Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 10/19] csky: Signal handling
  2018-03-18 19:51 ` [PATCH 10/19] csky: Signal handling Guo Ren
@ 2018-03-26 13:04   ` Arnd Bergmann
  2018-03-27  2:41     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-26 13:04 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Sun, Mar 18, 2018 at 8:51 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> Signed-off-by: Guo Ren <ren_guo@c-sky.com>
> ---
>  arch/csky/include/uapi/asm/sigcontext.h |  33 +++
>  arch/csky/include/uapi/asm/signal.h     | 164 ++++++++++++++
>  arch/csky/kernel/signal.c               | 379 ++++++++++++++++++++++++++++++++
>  3 files changed, 576 insertions(+)

Please have a look at arch/riscv and arch/nds32 for this, I think it can be
simplified. This is an incompatible change of course, but when we change
the system call ABI anyway, that is the right time to do it.


> +#define NSIG           32
> +typedef unsigned long sigset_t;
> +
> +#endif /* __KERNEL__ */
> +
> +#define SIGHUP          1
> +#define SIGINT          2
> +#define SIGQUIT                 3
> +#define SIGILL          4
> +#define SIGTRAP                 5
> +#define SIGABRT                 6
> +#define SIGIOT          6
> +#define SIGBUS          7
> +#define SIGFPE          8
> +#define SIGKILL                 9
> +#define SIGUSR1                10
> +#define SIGSEGV                11
> +#define SIGUSR2                12
> +#define SIGPIPE                13

In particular the constants should come from the asm-generic headers
rather than being duplicated. If you need anything special, it may be
better to modify the generic headers.

        Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 12/19] csky: Debug and Ptrace GDB
  2018-03-18 19:51 ` [PATCH 12/19] csky: Debug and Ptrace GDB Guo Ren
@ 2018-03-26 13:06   ` Arnd Bergmann
  0 siblings, 0 replies; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-26 13:06 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Sun, Mar 18, 2018 at 8:51 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> Signed-off-by: Guo Ren <ren_guo@c-sky.com>

> + */
> +long arch_ptrace(struct task_struct *child, long request, unsigned long addr,
> +               unsigned long data)
> +{
> +       unsigned long tmp = 0, ret = 0;
> +       int i;
> +
> +       switch (request) {
> +               /* read the word at location addr in the USER area. */
> +       case PTRACE_PEEKUSR:

> +
> +       case PTRACE_POKEUSR:  /* write the word at location addr in the USER area */

> +       case PTRACE_GETREGS:    /* Get all gp regs from the child. */

> +       case PTRACE_SETREGS:    /* Set all gp regs in the child. */
> +               for (i = 0; i <= CSKY_GREG_NUM; i++) {
> +                       ret = get_user(tmp, (unsigned long *)data);


I think all of these should use the regset code like arch/riscv/kernel/ptrace.c
does.

       Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 17/19] csky: defconfig
  2018-03-18 19:51 ` [PATCH 17/19] csky: defconfig Guo Ren
@ 2018-03-26 13:16   ` Arnd Bergmann
  2018-03-27  2:21     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-26 13:16 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Sun, Mar 18, 2018 at 8:51 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> Signed-off-by: Guo Ren <ren_guo@c-sky.com>
> ---
>  arch/csky/configs/gx66xx_defconfig     | 549 +++++++++++++++++++++++++++++++++
>  arch/csky/configs/qemu_ck807_defconfig | 541 ++++++++++++++++++++++++++++++++
>  2 files changed, 1090 insertions(+)
>  create mode 100644 arch/csky/configs/gx66xx_defconfig
>  create mode 100644 arch/csky/configs/qemu_ck807_defconfig

These look a lot longer than they should be, they contain many symbols
that I suspenc
are not needed or useful for you.

> diff --git a/arch/csky/configs/gx66xx_defconfig b/arch/csky/configs/gx66xx_defconfig
> new file mode 100644
> index 0000000..7f2a987
> --- /dev/null
> +++ b/arch/csky/configs/gx66xx_defconfig
> @@ -0,0 +1,549 @@
> +# CONFIG_LOCALVERSION_AUTO is not set
> +CONFIG_DEFAULT_HOSTNAME="github.com/c-sky"

This is not a well-formed hostname

> +# CONFIG_SWAP is not set
> +CONFIG_SYSVIPC=y
> +CONFIG_POSIX_MQUEUE=y
> +# CONFIG_FHANDLE is not set
> +CONFIG_USELIB=y
> +CONFIG_AUDIT=y
> +CONFIG_IRQ_DOMAIN_DEBUG=y
> +CONFIG_NO_HZ_IDLE=y
> +CONFIG_HIGH_RES_TIMERS=y
> +CONFIG_BSD_PROCESS_ACCT=y
> +CONFIG_BSD_PROCESS_ACCT_V3=y
> +CONFIG_RELAY=y
> +CONFIG_SYSCTL_SYSCALL=y
> +CONFIG_KALLSYMS_ALL=y
> +# CONFIG_AIO is not set

Disabling swap, fhandle or AIO seems odd, those are commonly
used symbols.

> +CONFIG_USERFAULTFD=y
> +CONFIG_EMBEDDED=y

CONFIG_EMBEDDED should generally not be selected, it's only for
very unusual configurations that need to disable symbols that are
normally required.

> +# CONFIG_PERF_EVENTS is not set
> +# CONFIG_SLUB_DEBUG is not set
> +# CONFIG_COMPAT_BRK is not set
> +CONFIG_PROFILING=y
> +CONFIG_OPROFILE=y

oprofile can go now, since you said you'd remove the code.

> +CONFIG_MODULES=y
> +CONFIG_MODULE_UNLOAD=y

> +CONFIG_BLK_DEV_BSGLIB=y
> +CONFIG_BLK_DEV_INTEGRITY=y
> +CONFIG_PARTITION_ADVANCED=y
> +CONFIG_ACORN_PARTITION=y
> +CONFIG_ACORN_PARTITION_ICS=y
> +CONFIG_ACORN_PARTITION_RISCIX=y
> +CONFIG_AIX_PARTITION=y
> +CONFIG_OSF_PARTITION=y
> +CONFIG_AMIGA_PARTITION=y
> +CONFIG_ATARI_PARTITION=y
> +CONFIG_MAC_PARTITION=y
> +CONFIG_BSD_DISKLABEL=y
> +CONFIG_MINIX_SUBPARTITION=y
> +CONFIG_SOLARIS_X86_PARTITION=y
> +CONFIG_UNIXWARE_DISKLABEL=y
> +CONFIG_LDM_PARTITION=y
> +CONFIG_SGI_PARTITION=y
> +CONFIG_ULTRIX_PARTITION=y
> +CONFIG_SUN_PARTITION=y
> +CONFIG_KARMA_PARTITION=y
> +CONFIG_SYSV68_PARTITION=y

These block device configuration options all seem misplaced
here, it's extremely unlikely that you need them.

> +CONFIG_CMDLINE_PARTITION=y
> +CONFIG_DEFAULT_DEADLINE=y
> +CONFIG_FB_NATIONALCHIP=y
> +CONFIG_RAM_BASE=0x10000000
> +# CONFIG_SUSPEND is not set
> +# CONFIG_COMPACTION is not set
> +CONFIG_NET=y
> +CONFIG_PACKET=y
> +CONFIG_UNIX=y
> +CONFIG_INET=y
> +CONFIG_IP_MULTICAST=y
> +CONFIG_IP_PNP=y
> +CONFIG_IP_PNP_DHCP=y
> +CONFIG_IP_PNP_BOOTP=y
> +CONFIG_IP_PNP_RARP=y
> +# CONFIG_IPV6 is not set
> +CONFIG_CFG80211=y
> +CONFIG_CFG80211_DEBUGFS=y
> +CONFIG_CFG80211_WEXT=y

I would guess you want IPV6 but not WEXT here.

> +CONFIG_MAC80211=y
> +CONFIG_MAC80211_DEBUGFS=y
> +CONFIG_RFKILL=y
> +CONFIG_RFKILL_INPUT=y
> +CONFIG_RFKILL_GPIO=y
> +CONFIG_DEVTMPFS=y
> +CONFIG_DEVTMPFS_MOUNT=y
> +# CONFIG_STANDALONE is not set

No need to turn this off, it might just get in the way of build
testing.

> +CONFIG_KEYBOARD_ADP5588=m
> +CONFIG_KEYBOARD_ADP5589=m
> +CONFIG_KEYBOARD_QT1070=m
> +CONFIG_KEYBOARD_QT2160=m
> +CONFIG_KEYBOARD_LKKBD=m

There are many input devices listed here, most of which you almost
certainly won't need.

> +CONFIG_IPMI_HANDLER=y
> +CONFIG_IPMI_DEVICE_INTERFACE=m
> +CONFIG_IPMI_SI=m
> +CONFIG_IPMI_WATCHDOG=m
> +CONFIG_IPMI_POWEROFF=m

Are you sure you have IPMI hardware?

> +CONFIG_FB=y
> +CONFIG_FB_TILEBLITTING=y
> +CONFIG_FB_SIMPLE=y
> +CONFIG_BACKLIGHT_LCD_SUPPORT=y
> +# CONFIG_LCD_CLASS_DEVICE is not set
> +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
> +# CONFIG_VGA_CONSOLE is not set
> +CONFIG_FRAMEBUFFER_CONSOLE=y
> +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
> +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
> +CONFIG_LOGO=y
> +# CONFIG_LOGO_LINUX_MONO is not set
> +# CONFIG_LOGO_LINUX_VGA16 is not set

For new platforms, using the DRM subsystem is the recommend
way to do graphics, it mostly replaces the framebuffer subsystem
here.

> +CONFIG_STE_MODEM_RPROC=m

I think this is no longer there.

> +CONFIG_EXT2_FS=y
> +CONFIG_EXT2_FS_XATTR=y
> +CONFIG_EXT2_FS_POSIX_ACL=y
> +CONFIG_EXT2_FS_SECURITY=y
> +CONFIG_EXT3_FS=y
> +CONFIG_EXT3_FS_POSIX_ACL=y
> +CONFIG_EXT3_FS_SECURITY=y

Better use EXT4 for the defconfig instead.

        Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/19] C-SKY(csky) Linux Kernel Port
  2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
                   ` (19 preceding siblings ...)
  2018-03-18 20:25 ` [PATCH 00/19] C-SKY(csky) Linux Kernel Port Joe Perches
@ 2018-03-26 13:30 ` Arnd Bergmann
  2018-03-26 15:06   ` [gnu-csky] " Sandra Loosemore
  2018-03-27  1:58   ` Guo Ren
  20 siblings, 2 replies; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-26 13:30 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Sun, Mar 18, 2018 at 8:51 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> This patchset adds architecture support to Linux for C-SKY's 32-bit embedded
> CPU cores and the patches are based on linux-4.16-rc5.
>
> There are two ABI versions with several CPU cores in this patchset:
>   ABIv1: ck610 (16-bit instruction, 32-bit data path, VIPT Cache ...)
>   ABIv2: ck807 ck810 (16/32-bit variable length instruction, PIPT Cache ...)
>
> More information: http://en.c-sky.com
>
> I'm from Hangzhou,China C-SKY Microsystems and responsible for C-SKY Linux
> port. My development repo is github.com/c-sky/csky-linux and use buildroot
> as our CI-test enviornment. "LTP, Lmbench, uclibc-ng-test ..." will be tested
> for every commit. See here for more details:
>   https://gitlab.com/c-sky/buildroot/pipelines
>
> You can try C-SKY linux in a few steps:
>   $ git clone https://github.com/c-sky/buildroot.git
>   $ cd buildroot
>   $ make qemu_csky_ck807_uclibc_bt_defconfig
>   $ make
> It will download "linux uclibc-ng gcc binutils qemu busybox" source code and build
> them into one image. How to run, See:
>   https://github.com/c-sky/buildroot/blob/master/board/qemu/csky/readme.txt
>
> I've finished uClibc-ng.org upstream and "gcc glibc binutils qemu ..." upstream is
> on going and the source code is here:
>   https://github.com/c-sky
>
> It's my first patchset to linux and any feedback is welcome :)

Thanks for your submission. I had started reviewing it over a week
ago, but never
completed since I was travelling in the meantime. I've completed my first pass
now and will wait for a new version before I take a more detailed look.

Overall, it looks nice, but changing the rest of the system call interface will
take a while, this includes several points I've mentioned already, but
to clarify,
every file in arch/csky/include/uapi/asm/ needs to be carefully reviewed to
contain only the minimum required additions to the asm-generic version.

Changing the ABI will obviously get in the way of testing, but this should
be over as soon as the port is merged.

Another interesting question is the status of your toolchain support. I see your
github account contains binutils and gcc repositories, but they are not upstream
yet. Are you working on getting those included in the respective upstream
projects already?

      Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [gnu-csky] [PATCH 00/19] C-SKY(csky) Linux Kernel Port
  2018-03-26 13:30 ` Arnd Bergmann
@ 2018-03-26 15:06   ` Sandra Loosemore
  2018-03-26 15:11     ` Arnd Bergmann
  2018-03-27  1:58   ` Guo Ren
  1 sibling, 1 reply; 63+ messages in thread
From: Sandra Loosemore @ 2018-03-26 15:06 UTC (permalink / raw)
  To: Arnd Bergmann, Guo Ren
  Cc: linux-arch, Jason Cooper, Daniel Lezcano,
	Linux Kernel Mailing List, c-sky_gcc_upstream, wbx,
	thomas.petazzoni, gnu-csky, Thomas Gleixner

On 03/26/2018 07:30 AM, Arnd Bergmann wrote:
> 
> Another interesting question is the status of your toolchain support. I see your
> github account contains binutils and gcc repositories, but they are not upstream
> yet. Are you working on getting those included in the respective upstream
> projects already?

We at Mentor Graphics are working on preparing the abiv2 binutils and 
gcc support for upstream submission.  The existing gcc back end for 
abiv1 is actually completely separate from the abiv2 back end and 
probably eventually needs to be merged with it, but first things first.

-Sandra

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [gnu-csky] [PATCH 00/19] C-SKY(csky) Linux Kernel Port
  2018-03-26 15:06   ` [gnu-csky] " Sandra Loosemore
@ 2018-03-26 15:11     ` Arnd Bergmann
  0 siblings, 0 replies; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-26 15:11 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Guo Ren, linux-arch, Jason Cooper, Daniel Lezcano,
	Linux Kernel Mailing List, c-sky_gcc_upstream, wbx,
	thomas.petazzoni, gnu-csky, Thomas Gleixner

On Mon, Mar 26, 2018 at 5:06 PM, Sandra Loosemore
<sandra@codesourcery.com> wrote:
> On 03/26/2018 07:30 AM, Arnd Bergmann wrote:
>>
>>
>> Another interesting question is the status of your toolchain support. I
>> see your
>> github account contains binutils and gcc repositories, but they are not
>> upstream
>> yet. Are you working on getting those included in the respective upstream
>> projects already?
>
>
> We at Mentor Graphics are working on preparing the abiv2 binutils and gcc
> support for upstream submission.  The existing gcc back end for abiv1 is
> actually completely separate from the abiv2 back end and probably eventually
> needs to be merged with it, but first things first.

Ok, very good. Being able to build abiv2 is probably sufficient for testing
the kernel in a meaningful way, and if you are working on getting that
upstream, I trust that it will happen quick enough. I can always provide
toolchain binaries on kernel.org based a prerelease version like I did
for openrisc, which makes it accessible to other kernel developers doing
cross-arch changes.

      Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 00/19] C-SKY(csky) Linux Kernel Port
  2018-03-26 13:30 ` Arnd Bergmann
  2018-03-26 15:06   ` [gnu-csky] " Sandra Loosemore
@ 2018-03-27  1:58   ` Guo Ren
  1 sibling, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-27  1:58 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 26, 2018 at 03:30:34PM +0200, Arnd Bergmann wrote:
> Thanks for your submission. I had started reviewing it over a week
> ago, but never
> completed since I was travelling in the meantime. I've completed my first pass
> now and will wait for a new version before I take a more detailed look.
> 
> Overall, it looks nice, but changing the rest of the system call interface will
> take a while, this includes several points I've mentioned already, but
> to clarify,
> every file in arch/csky/include/uapi/asm/ needs to be carefully reviewed to
> contain only the minimum required additions to the asm-generic version.
> 
> Changing the ABI will obviously get in the way of testing, but this should
> be over as soon as the port is merged.
I entirely agree with you. After modify the unistd.h, we found a lot of
ltp-cases failed. We are dealing with them.

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 17/19] csky: defconfig
  2018-03-26 13:16   ` Arnd Bergmann
@ 2018-03-27  2:21     ` Guo Ren
  2018-03-27  7:48       ` Arnd Bergmann
  0 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-27  2:21 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 26, 2018 at 03:16:31PM +0200, Arnd Bergmann wrote:
> >  arch/csky/configs/gx66xx_defconfig     | 549 +++++++++++++++++++++++++++++++++
> >  arch/csky/configs/qemu_ck807_defconfig | 541 ++++++++++++++++++++++++++++++++
> >  2 files changed, 1090 insertions(+)
> >  create mode 100644 arch/csky/configs/gx66xx_defconfig
> >  create mode 100644 arch/csky/configs/qemu_ck807_defconfig
> 
> These look a lot longer than they should be, they contain many symbols
> that I suspenc
> are not needed or useful for you.
I'll cleanup the defconfig again.

> 
> > diff --git a/arch/csky/configs/gx66xx_defconfig b/arch/csky/configs/gx66xx_defconfig
> > new file mode 100644
> > index 0000000..7f2a987
> > --- /dev/null
> > +++ b/arch/csky/configs/gx66xx_defconfig
> > @@ -0,0 +1,549 @@
> > +# CONFIG_LOCALVERSION_AUTO is not set
> > +CONFIG_DEFAULT_HOSTNAME="github.com/c-sky"
> 
> This is not a well-formed hostname
I'll remove it.

> 
> > +# CONFIG_SWAP is not set
> > +CONFIG_SYSVIPC=y
> > +CONFIG_POSIX_MQUEUE=y
> > +# CONFIG_FHANDLE is not set
> > +CONFIG_USELIB=y
> > +CONFIG_AUDIT=y
> > +CONFIG_IRQ_DOMAIN_DEBUG=y
> > +CONFIG_NO_HZ_IDLE=y
> > +CONFIG_HIGH_RES_TIMERS=y
> > +CONFIG_BSD_PROCESS_ACCT=y
> > +CONFIG_BSD_PROCESS_ACCT_V3=y
> > +CONFIG_RELAY=y
> > +CONFIG_SYSCTL_SYSCALL=y
> > +CONFIG_KALLSYMS_ALL=y
> > +# CONFIG_AIO is not set
> 
> Disabling swap, fhandle or AIO seems odd, those are commonly
> used symbols.
I'll try to enable them.

> > +CONFIG_USERFAULTFD=y
> > +CONFIG_EMBEDDED=y
> 
> CONFIG_EMBEDDED should generally not be selected, it's only for
> very unusual configurations that need to disable symbols that are
> normally required.
I'll try to enable EMBEDDED.

> 
> > +# CONFIG_PERF_EVENTS is not set
> > +# CONFIG_SLUB_DEBUG is not set
> > +# CONFIG_COMPAT_BRK is not set
> > +CONFIG_PROFILING=y
> > +CONFIG_OPROFILE=y
> 
> oprofile can go now, since you said you'd remove the code.
Yes, remove it.

> > +CONFIG_BLK_DEV_BSGLIB=y
> > +CONFIG_BLK_DEV_INTEGRITY=y
> > +CONFIG_PARTITION_ADVANCED=y
> > +CONFIG_ACORN_PARTITION=y
> > +CONFIG_ACORN_PARTITION_ICS=y
> > +CONFIG_ACORN_PARTITION_RISCIX=y
> > +CONFIG_AIX_PARTITION=y
> > +CONFIG_OSF_PARTITION=y
> > +CONFIG_AMIGA_PARTITION=y
> > +CONFIG_ATARI_PARTITION=y
> > +CONFIG_MAC_PARTITION=y
> > +CONFIG_BSD_DISKLABEL=y
> > +CONFIG_MINIX_SUBPARTITION=y
> > +CONFIG_SOLARIS_X86_PARTITION=y
> > +CONFIG_UNIXWARE_DISKLABEL=y
> > +CONFIG_LDM_PARTITION=y
> > +CONFIG_SGI_PARTITION=y
> > +CONFIG_ULTRIX_PARTITION=y
> > +CONFIG_SUN_PARTITION=y
> > +CONFIG_KARMA_PARTITION=y
> > +CONFIG_SYSV68_PARTITION=y
> 
> These block device configuration options all seem misplaced
> here, it's extremely unlikely that you need them.
I'll try to remove it.

> > +# CONFIG_IPV6 is not set
I'll enable IPV6.

> > +CONFIG_CFG80211=y
> > +CONFIG_CFG80211_DEBUGFS=y
> > +CONFIG_CFG80211_WEXT=y
> 
> I would guess you want IPV6 but not WEXT here.
Gx6605s devlepment board support usb-wifi.
Perhaps WEXT is needed by iwconfig or iwlist? So I just enable it.
However, I'll consider to remove it.

> > +# CONFIG_STANDALONE is not set
> 
> No need to turn this off, it might just get in the way of build
> testing.
Ok, I'll try to enable it.

> > +CONFIG_KEYBOARD_ADP5588=m
> > +CONFIG_KEYBOARD_ADP5589=m
> > +CONFIG_KEYBOARD_QT1070=m
> > +CONFIG_KEYBOARD_QT2160=m
> > +CONFIG_KEYBOARD_LKKBD=m
> 
> There are many input devices listed here, most of which you almost
> certainly won't need.
Yes, remove them.

> > +CONFIG_IPMI_HANDLER=y
> > +CONFIG_IPMI_DEVICE_INTERFACE=m
> > +CONFIG_IPMI_SI=m
> > +CONFIG_IPMI_WATCHDOG=m
> > +CONFIG_IPMI_POWEROFF=m
> 
> Are you sure you have IPMI hardware?
No IPMI hardware, remove them.

> > +CONFIG_FB=y
> > +CONFIG_FB_TILEBLITTING=y
> > +CONFIG_FB_SIMPLE=y
> > +CONFIG_BACKLIGHT_LCD_SUPPORT=y
> > +# CONFIG_LCD_CLASS_DEVICE is not set
> > +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
> > +# CONFIG_VGA_CONSOLE is not set
> > +CONFIG_FRAMEBUFFER_CONSOLE=y
> > +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
> > +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
> > +CONFIG_LOGO=y
> > +# CONFIG_LOGO_LINUX_MONO is not set
> > +# CONFIG_LOGO_LINUX_VGA16 is not set
> 
> For new platforms, using the DRM subsystem is the recommend
> way to do graphics, it mostly replaces the framebuffer subsystem
> here.
These used by:
https://github.com/c-sky/addons-linux/tree/master/addons/drivers/video/fbdev/nationalchip

I'll consider the DRM subsystem.

> > +CONFIG_STE_MODEM_RPROC=m
> 
> I think this is no longer there.
Yes, remove it.

> > +CONFIG_EXT2_FS=y
> > +CONFIG_EXT2_FS_XATTR=y
> > +CONFIG_EXT2_FS_POSIX_ACL=y
> > +CONFIG_EXT2_FS_SECURITY=y
> > +CONFIG_EXT3_FS=y
> > +CONFIG_EXT3_FS_POSIX_ACL=y
> > +CONFIG_EXT3_FS_SECURITY=y
> 
> Better use EXT4 for the defconfig instead.
OK.

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-26 13:00           ` Arnd Bergmann
@ 2018-03-27  2:39             ` Guo Ren
  2018-03-27  7:38               ` Arnd Bergmann
  0 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-27  2:39 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 26, 2018 at 03:00:00PM +0200, Arnd Bergmann wrote:
> Ok, I understand the part about ck610 being incompatible, but I'm
> still not sure about the 8xx ones: Do you mean it's impossible to
> have one kernel that runs across all of them for some other reason,
> or is it something you haven't allowed because you see no use for it?
Sorry, Csky gcc need "-mcpu=ck807" or "-mcpu=ck810" or "-mcpu=ck860" to
determine the back-end policy. So I must seperate them with different vmlinux.

> This is basically the same question as above: For c610, using the fixed
> value is sufficient, because it's incompatible with the others. But if you want
> to run the same kernel on both ck810 and ck860, then it needs some form
> of runtime detection.
Sorry, currently no runtime detection.
But I agree with you that one vmlinux for all cpus is a good design for compat.

> On other architectures, the L1_CACHE_BYTES constant is the maximum
> possible cache line size, and the cache flush function uses the actual size
The same with above, we don't detect cpus on runtime. So we just make it
simple here.

> Ok. Just make sure that the DT always has this information as well,
> so this can be changed in the future when desired, without having to
> make incompatible changes to the devicetree binary files.
Ok

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 10/19] csky: Signal handling
  2018-03-26 13:04   ` Arnd Bergmann
@ 2018-03-27  2:41     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-27  2:41 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Mon, Mar 26, 2018 at 03:04:01PM +0200, Arnd Bergmann wrote:
> On Sun, Mar 18, 2018 at 8:51 PM, Guo Ren <ren_guo@c-sky.com> wrote:
> > Signed-off-by: Guo Ren <ren_guo@c-sky.com>
> > ---
> >  arch/csky/include/uapi/asm/sigcontext.h |  33 +++
> >  arch/csky/include/uapi/asm/signal.h     | 164 ++++++++++++++
> >  arch/csky/kernel/signal.c               | 379 ++++++++++++++++++++++++++++++++
> >  3 files changed, 576 insertions(+)
> 
> Please have a look at arch/riscv and arch/nds32 for this, I think it can be
> simplified. This is an incompatible change of course, but when we change
> the system call ABI anyway, that is the right time to do it.
Ok.

> 
> 
> > +#define NSIG           32
> > +typedef unsigned long sigset_t;
> > +
> > +#endif /* __KERNEL__ */
> > +
> > +#define SIGHUP          1
> > +#define SIGINT          2
> > +#define SIGQUIT                 3
> > +#define SIGILL          4
> > +#define SIGTRAP                 5
> > +#define SIGABRT                 6
> > +#define SIGIOT          6
> > +#define SIGBUS          7
> > +#define SIGFPE          8
> > +#define SIGKILL                 9
> > +#define SIGUSR1                10
> > +#define SIGSEGV                11
> > +#define SIGUSR2                12
> > +#define SIGPIPE                13
> 
> In particular the constants should come from the asm-generic headers
> rather than being duplicated. If you need anything special, it may be
> better to modify the generic headers.
Ok, use asm-generic.

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-27  2:39             ` Guo Ren
@ 2018-03-27  7:38               ` Arnd Bergmann
  2018-03-28  3:49                 ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-27  7:38 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Tue, Mar 27, 2018 at 4:39 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> On Mon, Mar 26, 2018 at 03:00:00PM +0200, Arnd Bergmann wrote:
>> Ok, I understand the part about ck610 being incompatible, but I'm
>> still not sure about the 8xx ones: Do you mean it's impossible to
>> have one kernel that runs across all of them for some other reason,
>> or is it something you haven't allowed because you see no use for it?
>
> Sorry, Csky gcc need "-mcpu=ck807" or "-mcpu=ck810" or "-mcpu=ck860" to
> determine the back-end policy. So I must seperate them with different vmlinux.

Usually the way gcc handles this, either each CPU is a strict superset
of another
one, so you just need to specify the one with the smallest instruction set,
or you have an option like -mcpu=generic that produces the common subset.

>> This is basically the same question as above: For c610, using the fixed
>> value is sufficient, because it's incompatible with the others. But if you want
>> to run the same kernel on both ck810 and ck860, then it needs some form
>> of runtime detection.
> Sorry, currently no runtime detection.
> But I agree with you that one vmlinux for all cpus is a good design for compat.
>
>> On other architectures, the L1_CACHE_BYTES constant is the maximum
>> possible cache line size, and the cache flush function uses the actual size
> The same with above, we don't detect cpus on runtime. So we just make it
> simple here.

Ok, fair enough. It's something that can always be added later, as long as
we keep this in mind early on.

       Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 17/19] csky: defconfig
  2018-03-27  2:21     ` Guo Ren
@ 2018-03-27  7:48       ` Arnd Bergmann
  2018-03-28  3:59         ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-27  7:48 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Tue, Mar 27, 2018 at 4:21 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> On Mon, Mar 26, 2018 at 03:16:31PM +0200, Arnd Bergmann wrote:

>> > +CONFIG_CFG80211=y
>> > +CONFIG_CFG80211_DEBUGFS=y
>> > +CONFIG_CFG80211_WEXT=y
>>
>> I would guess you want IPV6 but not WEXT here.
> Gx6605s devlepment board support usb-wifi.
> Perhaps WEXT is needed by iwconfig or iwlist? So I just enable it.
> However, I'll consider to remove it.

I think it's only for backwards compatibility with old versions of
those tools. There are some older drivers that use WEXT as the
native interface, but CFG80211 based drivers have a netlink
interface.

>> > +CONFIG_FB=y
>> > +CONFIG_FB_TILEBLITTING=y
>> > +CONFIG_FB_SIMPLE=y
>> > +CONFIG_BACKLIGHT_LCD_SUPPORT=y
>> > +# CONFIG_LCD_CLASS_DEVICE is not set
>> > +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
>> > +# CONFIG_VGA_CONSOLE is not set
>> > +CONFIG_FRAMEBUFFER_CONSOLE=y
>> > +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
>> > +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
>> > +CONFIG_LOGO=y
>> > +# CONFIG_LOGO_LINUX_MONO is not set
>> > +# CONFIG_LOGO_LINUX_VGA16 is not set
>>
>> For new platforms, using the DRM subsystem is the recommend
>> way to do graphics, it mostly replaces the framebuffer subsystem
>> here.
> These used by:
> https://github.com/c-sky/addons-linux/tree/master/addons/drivers/video/fbdev/nationalchip
>
> I'll consider the DRM subsystem.

It used to be rather hard to write a new DRM driver, but that has
improved a lot recently. You might be able to fit your driver into
drivers/gpu/drm/tinydrm/, or maybe do something a bit more complex
like drivers/gpu/drm/pl111/ or drivers/gpu/drm/stm/.

       Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-27  7:38               ` Arnd Bergmann
@ 2018-03-28  3:49                 ` Guo Ren
  2018-03-28  7:40                   ` Arnd Bergmann
  0 siblings, 1 reply; 63+ messages in thread
From: Guo Ren @ 2018-03-28  3:49 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

Hi Arnd,

On Tue, Mar 27, 2018 at 09:38:56AM +0200, Arnd Bergmann wrote:
> Usually the way gcc handles this, either each CPU is a strict superset
> of another
> one, so you just need to specify the one with the smallest instruction set,
> or you have an option like -mcpu=generic that produces the common subset.
>
ck807 ck810 ck860 are diffrent architecture, so they can not be strict
superset and there is no option like '-mcpu=generic' in our gcc and
binutils.

I know you want one vmlinux which could run on all ck807 ck810 ck860 with
different dts-setting. But now, may I keep current design for abiv1&abiv2?

In abiv3, we will take your advice seriously.

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 17/19] csky: defconfig
  2018-03-27  7:48       ` Arnd Bergmann
@ 2018-03-28  3:59         ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-28  3:59 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Tue, Mar 27, 2018 at 09:48:23AM +0200, Arnd Bergmann wrote:
> On Tue, Mar 27, 2018 at 4:21 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> > On Mon, Mar 26, 2018 at 03:16:31PM +0200, Arnd Bergmann wrote:
> 
> >> > +CONFIG_CFG80211=y
> >> > +CONFIG_CFG80211_DEBUGFS=y
> >> > +CONFIG_CFG80211_WEXT=y
> >>
> >> I would guess you want IPV6 but not WEXT here.
> > Gx6605s devlepment board support usb-wifi.
> > Perhaps WEXT is needed by iwconfig or iwlist? So I just enable it.
> > However, I'll consider to remove it.
> 
> I think it's only for backwards compatibility with old versions of
> those tools. There are some older drivers that use WEXT as the
> native interface, but CFG80211 based drivers have a netlink
> interface.
Thx for remind. I'll check.

> 
> >> > +CONFIG_FB=y
> >> > +CONFIG_FB_TILEBLITTING=y
> >> > +CONFIG_FB_SIMPLE=y
> >> > +CONFIG_BACKLIGHT_LCD_SUPPORT=y
> >> > +# CONFIG_LCD_CLASS_DEVICE is not set
> >> > +# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
> >> > +# CONFIG_VGA_CONSOLE is not set
> >> > +CONFIG_FRAMEBUFFER_CONSOLE=y
> >> > +CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
> >> > +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
> >> > +CONFIG_LOGO=y
> >> > +# CONFIG_LOGO_LINUX_MONO is not set
> >> > +# CONFIG_LOGO_LINUX_VGA16 is not set
> >>
> >> For new platforms, using the DRM subsystem is the recommend
> >> way to do graphics, it mostly replaces the framebuffer subsystem
> >> here.
> > These used by:
> > https://github.com/c-sky/addons-linux/tree/master/addons/drivers/video/fbdev/nationalchip
> >
> > I'll consider the DRM subsystem.
> 
> It used to be rather hard to write a new DRM driver, but that has
> improved a lot recently. You might be able to fit your driver into
> drivers/gpu/drm/tinydrm/, or maybe do something a bit more complex
> like drivers/gpu/drm/pl111/ or drivers/gpu/drm/stm/.
For this patchset, I won't upstream the fbdev driver. I'll remove the
CONFIG_FB in defconfig first.

Thx for remind about the develop-tips, and it's very helpful.

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-28  3:49                 ` Guo Ren
@ 2018-03-28  7:40                   ` Arnd Bergmann
  2018-03-28  8:04                     ` Guo Ren
  0 siblings, 1 reply; 63+ messages in thread
From: Arnd Bergmann @ 2018-03-28  7:40 UTC (permalink / raw)
  To: Guo Ren
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

On Wed, Mar 28, 2018 at 5:49 AM, Guo Ren <ren_guo@c-sky.com> wrote:
> Hi Arnd,
>
> On Tue, Mar 27, 2018 at 09:38:56AM +0200, Arnd Bergmann wrote:
>> Usually the way gcc handles this, either each CPU is a strict superset
>> of another
>> one, so you just need to specify the one with the smallest instruction set,
>> or you have an option like -mcpu=generic that produces the common subset.
>>
> ck807 ck810 ck860 are diffrent architecture, so they can not be strict
> superset and there is no option like '-mcpu=generic' in our gcc and
> binutils.
>
> I know you want one vmlinux which could run on all ck807 ck810 ck860 with
> different dts-setting. But now, may I keep current design for abiv1&abiv2?
>
> In abiv3, we will take your advice seriously.

Ok, thanks for the clarification. Obviously if they are mutually incompatible,
there is no point in using a common kernel, so your current version is
absolutely fine, and this is similar to how we cannot have a common kernel
between ARMv5, ARMv7-A and ARMv7-M, which are all incompatible
at the kernel level.

One more question for my understanding: Are the three types of ck8xx
CPUs mutually incompatible in user space as well, or are the differences
only for the kernel? For the ARM example, ARMv5 and ARMv7
fundamentally require separate kernels, but both can run user space
programs built for ARMv5.

      Arnd

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH 15/19] csky: Build infrastructure
  2018-03-28  7:40                   ` Arnd Bergmann
@ 2018-03-28  8:04                     ` Guo Ren
  0 siblings, 0 replies; 63+ messages in thread
From: Guo Ren @ 2018-03-28  8:04 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arch, Linux Kernel Mailing List, Thomas Gleixner,
	Daniel Lezcano, Jason Cooper, c-sky_gcc_upstream, gnu-csky,
	thomas.petazzoni, wbx

Hi Arnd,

On Wed, Mar 28, 2018 at 09:40:49AM +0200, Arnd Bergmann wrote:
> Ok, thanks for the clarification. Obviously if they are mutually incompatible,
> there is no point in using a common kernel, so your current version is
> absolutely fine, and this is similar to how we cannot have a common kernel
> between ARMv5, ARMv7-A and ARMv7-M, which are all incompatible
> at the kernel level.
Yes.

> One more question for my understanding: Are the three types of ck8xx
> CPUs mutually incompatible in user space as well, or are the differences
> only for the kernel? For the ARM example, ARMv5 and ARMv7
> fundamentally require separate kernels, but both can run user space
> programs built for ARMv5.

 -mcpu=ck807 app could run on ck807, ck810, ck860.
 -mcpu=ck810 app could run on ck807, ck810, ck860.
 -mcpu=ck860 app only  run on ck860.

They are all incompatible at the kernel level.

Best Regards
 Guo Ren

^ permalink raw reply	[flat|nested] 63+ messages in thread

end of thread, other threads:[~2018-03-28  8:05 UTC | newest]

Thread overview: 63+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-18 19:51 [PATCH 00/19] C-SKY(csky) Linux Kernel Port Guo Ren
2018-03-18 19:51 ` [PATCH 01/19] csky: Kernel booting Guo Ren
2018-03-18 19:51 ` [PATCH 02/19] csky: Exception handling and syscall Guo Ren
2018-03-19  1:48   ` Mark Rutland
2018-03-19  6:47     ` Guo Ren
2018-03-19  8:50   ` Dominik Brodowski
2018-03-19 11:03     ` Guo Ren
2018-03-18 19:51 ` [PATCH 03/19] csky: Cache and TLB routines Guo Ren
2018-03-18 19:51 ` [PATCH 04/19] csky: MMU and page talbe management Guo Ren
2018-03-18 19:51 ` [PATCH 05/19] csky: Process management Guo Ren
2018-03-18 19:51 ` [PATCH 06/19] csky: IRQ handling Guo Ren
2018-03-19 13:16   ` Thomas Gleixner
2018-03-20  2:06     ` Guo Ren
2018-03-18 19:51 ` [PATCH 07/19] csky: Atomic operations Guo Ren
2018-03-18 19:51 ` [PATCH 08/19] csky: ELF and module probe Guo Ren
2018-03-18 19:51 ` [PATCH 09/19] csky: VDSO and rt_sigreturn Guo Ren
2018-03-18 19:51 ` [PATCH 10/19] csky: Signal handling Guo Ren
2018-03-26 13:04   ` Arnd Bergmann
2018-03-27  2:41     ` Guo Ren
2018-03-18 19:51 ` [PATCH 11/19] csky: Library functions Guo Ren
2018-03-18 19:51 ` [PATCH 12/19] csky: Debug and Ptrace GDB Guo Ren
2018-03-26 13:06   ` Arnd Bergmann
2018-03-18 19:51 ` [PATCH 13/19] csky: User access Guo Ren
2018-03-18 19:51 ` [PATCH 14/19] csky: Misc headers Guo Ren
2018-03-19 16:11   ` Arnd Bergmann
2018-03-20  3:36     ` Guo Ren
2018-03-20  7:54       ` Arnd Bergmann
2018-03-20 13:22         ` Guo Ren
2018-03-18 19:51 ` [PATCH 15/19] csky: Build infrastructure Guo Ren
2018-03-19 15:45   ` Arnd Bergmann
2018-03-20 13:13     ` Guo Ren
2018-03-21  7:36       ` Arnd Bergmann
2018-03-21 12:41         ` Guo Ren
2018-03-26 13:00           ` Arnd Bergmann
2018-03-27  2:39             ` Guo Ren
2018-03-27  7:38               ` Arnd Bergmann
2018-03-28  3:49                 ` Guo Ren
2018-03-28  7:40                   ` Arnd Bergmann
2018-03-28  8:04                     ` Guo Ren
2018-03-18 19:51 ` [PATCH 16/19] csky: Device tree Guo Ren
2018-03-19 15:28   ` Arnd Bergmann
2018-03-20 13:55     ` Guo Ren
2018-03-18 19:51 ` [PATCH 17/19] csky: defconfig Guo Ren
2018-03-26 13:16   ` Arnd Bergmann
2018-03-27  2:21     ` Guo Ren
2018-03-27  7:48       ` Arnd Bergmann
2018-03-28  3:59         ` Guo Ren
2018-03-18 19:51 ` [PATCH 18/19] clocksource: add timer-nationalchip.c Guo Ren
2018-03-18 22:07   ` Daniel Lezcano
2018-03-19  6:59     ` Guo Ren
2018-03-19  4:15   ` Mark Rutland
2018-03-19  7:03     ` Guo Ren
2018-03-18 19:51 ` [PATCH 19/19] irqchip: add irq-nationalchip.c and irq-csky.c Guo Ren
2018-03-19  4:26   ` Mark Rutland
2018-03-19  7:08     ` Guo Ren
2018-03-19 13:30   ` Thomas Gleixner
2018-03-20 14:23     ` Guo Ren
2018-03-18 20:25 ` [PATCH 00/19] C-SKY(csky) Linux Kernel Port Joe Perches
2018-03-19  7:11   ` Guo Ren
2018-03-26 13:30 ` Arnd Bergmann
2018-03-26 15:06   ` [gnu-csky] " Sandra Loosemore
2018-03-26 15:11     ` Arnd Bergmann
2018-03-27  1:58   ` Guo Ren

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).