Skip to contentSkip to conversation

C-SKY(csky) Linux Kernel Port

PATCH Superseded Guo Ren 12 participants 86 messages Jul 1, 2018 – Jul 13, 2018

Subsystems (10)

v2 of 7 Superseded Latest is v7 →

lore
Share & tools
lore

Guo Ren

author
#0 lore raw

v2 cover C-SKY(csky) Linux Kernel Port

This is the 2th version patchset to add the Linux kernel port for C-SKY(csky). Thanks to everyone who provided feedback on the previous version.

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.2.

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 ck860 (16/32-bit variable length instruction, PIPT Cache,

	 SMP ...)

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

I'm from Hangzhou,China C-SKY Microsystems and responsible for C-SKY Linux port. The development repo is
https://github.com/c-sky/csky-linux

We 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

Any feedback is welcome.

Changes in v2:
a29bfc8 csky: add pre_mmu_init, move misc mmu setup to mm/init.c
4eab702 csky: no need kmap for !VM_EXEC.
6770eec csky: Use TEE as the name of CPU Trusted Execution Enviornment.
a56c8c7 csky: update the cache flush api.
1a48a95 csky: add C-SKY Trust Zone.
b7a0a44 csky: use CONFIG_RAM_BASE as the same in memory of dts.
15adf81 csky: remove unused code.
35c0d97 csky: bugfix lost a cacheline flush when start isn't cacheline-aligned.
4e82c8d csky: use tlbi.alls for ck860 smp temporary.
ae7149e csky: bugfix use kmap_atomic() to prevent no mapped addr.
5538795 csky: bugfix user access in kernel space.
a7aa591 csky: add 16bit user space bkpt.
0de70ec csky: add sync.is for cmpxchg in SMP.
c5c08a1 csky: seperate sync.is and sync for SMP and Non-SMP.
dbbf4dc csky: use sync.is for ck860 mb().
f33f8da csky: rewrite the alignment implement.
68152c7 csky: bugfix alignment pt_regs error.
d618d43 csky: support set_affinity for irq balance in SMP
ebf86c9 csky: bugfix compile error without CONFIG_SMP.
8537eea csky: remove debug code.
4ebc051 csky: bugfix compile error with linux-4.9.56
75a938e csky: C-SKY SMP supported.
0eebc07 csky: use internal function for map_sg.
3d29751 csky: bugfix can't support highmem
b545d2a csky: bugfix r26 is the link reg for jsri_to_jsr.
9e3313a csky: bugfix sync tls for abiv1 in ptrace.
587a0d2 csky: use __NR_rt_sigreturn in asm-generic.
f562b46 csky: bugfix gpr_set & fpr_set
f57266f csky: bugfix fpu_fpe_helper excute mtcr mfcr.
c676669 csky: bugfix ave is default enable on reset.
d40d34d csky: remove unused sc_mask in sigcontext.h.
274b7a2 csky: redesign the signal's api
7501771 csky: bugfix forget restore usp.
923e2ca csky: re-struct the pt_regs for regset.
2a1e499 csky: fixup config.
ada81ec csky: bugfix abiv1 compile error.
e34acb9 csky: bugfix abiv1 couldn't support -mno-stack-size.
ec53560 csky: change irq map, reserve soft_irq&private_irq space.
c7576f7 csky: bugfix modpost warning with -mno-stack-size
c8ff9d4 csky: support csky mp timer alpha version.
deabaaf csky: update .gitignore.
574815c csky: bugfix compile error with abiv1 in 4.15
0b426a7 csky: bugfix format of cpu verion id.
083435f csky: irq-csky-v2 alpha init.
21209e5 csky: add .gitignore
73e19b4 csky: remove FMFS_FPU_REGS/FMTS_FPU_REGS
07e8fac csky: add fpu regset in ptrace.c
cac779d csky: add CSKY_VECIRQ_LEGENCY for SOC bug.
54bab1d csky: move usp into pt_regs.
b167422 csky: support regset for ptrace.
a098d4c csky: remove ARCH_WANT_IPC_PARSE_VERSION
fe61a84 csky: add timer-of support.
27702e2 csky: bugfix boot error.
ebe3edb csky: bugfix gx6605s boot failed - add __HEAD to head.section for head.S - move INIT_SECTION together to fix compile warning. 7138cae csky: coding convension for timer-nationalchip.c
fa7f9bb csky: use ffs instead of fls.
ddc9e81 csky: change to generic irq chip for irq-csky.c
e9be8b9 irqchip: add generic irq chip for irq-nationalchip
2ee83fe csky: add set_handle_irq(), ref from openrisc & arm.
74181d6 csky: use irq_domain_add_linear instead of leagcy.
fa45ae4 csky: bugfix setup stroge order for uncached.
eb8030f csky: add HIGHMEM config in Kconfig
4f983d4 csky: remove "default n" in Kconfig
2467575 csky: use asm-generic/signal.h
77438e5 csky: coding conventions for irq.c
2e4a2b4 csky: optimize the cache flush ops.
96e1c58 csky: add CONFIG_CPU_ASID_BITS.
9339666 csky: add cprcr() cpwcr() for abiv1
ff05be4 csky: add THREAD_SHIFT define in asm/page.h
52ab022 csky: add mfcr() mtcr() in asm/reg_ops.h
bdcd8f3 csky: revert back Kconfig select.
590c7e6 csky: bugfix compile error with CONFIG_AUDIT
1989292 csky: revert some back with cleanup unistd.h
f1454fe csky: cleanup unistd.h
5d2985f csky: cleanup Kconfig and Makefile.
423d97e csky: cancel subdirectories
cae2af4 csky: use asm-generic/fcntl.h

Guo Ren (19):
csky: Build infrastructure
csky: defconfig
csky: Kernel booting
csky: Exception handling
csky: System Call
csky: Cache and TLB routines
csky: MMU and page table management
csky: Process management and Signal
csky: VDSO and rt_sigreturn
csky: IRQ handling
csky: Atomic operations
csky: ELF and module probe
csky: Library functions
csky: User access
csky: Debug and Ptrace GDB
csky: SMP support
csky: Misc headers
clocksource: add C-SKY clocksource drivers
irqchip: add C-SKY irqchip drivers

 arch/csky/Kconfig                        | 211 ++++++++++++
 arch/csky/Kconfig.debug                  |  29 ++
 arch/csky/Makefile                       |  92 ++++++
 arch/csky/abiv1/Makefile                 |   8 +
 arch/csky/abiv1/alignment.c              | 332 +++++++++++++++++++
 arch/csky/abiv1/bswapdi.c                |  18 +
 arch/csky/abiv1/bswapsi.c                |  15 +
 arch/csky/abiv1/cacheflush.c             |  51 +++
 arch/csky/abiv1/inc/abi/cacheflush.h     |  42 +++
 arch/csky/abiv1/inc/abi/ckmmu.h          |  80 +++++
 arch/csky/abiv1/inc/abi/entry.h          | 152 +++++++++
 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        |  47 +++
 arch/csky/abiv1/inc/abi/regdef.h         |  15 +
 arch/csky/abiv1/inc/abi/tlb.h            |  11 +
 arch/csky/abiv1/inc/abi/vdso.h           |  17 +
 arch/csky/abiv1/memcpy.S                 | 344 +++++++++++++++++++
 arch/csky/abiv1/mmap.c                   |  65 ++++
 arch/csky/abiv2/Makefile                 |   4 +
 arch/csky/abiv2/cacheflush.c             |  55 ++++
 arch/csky/abiv2/fpu.c                    | 242 ++++++++++++++
 arch/csky/abiv2/inc/abi/cacheflush.h     |  38 +++
 arch/csky/abiv2/inc/abi/ckmmu.h          |  88 +++++
 arch/csky/abiv2/inc/abi/entry.h          | 149 +++++++++
 arch/csky/abiv2/inc/abi/fpu.h            | 219 ++++++++++++
 arch/csky/abiv2/inc/abi/page.h           |  14 +
 arch/csky/abiv2/inc/abi/pgtable-bits.h   |  36 ++
 arch/csky/abiv2/inc/abi/reg_ops.h        |  38 +++
 arch/csky/abiv2/inc/abi/regdef.h         |  15 +
 arch/csky/abiv2/inc/abi/tlb.h            |  12 +
 arch/csky/abiv2/inc/abi/vdso.h           |  18 +
 arch/csky/abiv2/memcpy.c                 |  43 +++
 arch/csky/boot/Makefile                  |  25 ++
 arch/csky/boot/dts/Makefile              |  14 +
 arch/csky/boot/dts/include/dt-bindings   |   1 +
 arch/csky/configs/gx66xx_defconfig       | 549 +++++++++++++++++++++++++++++++
 arch/csky/configs/qemu_ck807_defconfig   | 541 ++++++++++++++++++++++++++++++
 arch/csky/include/asm/Kbuild             |  72 ++++
 arch/csky/include/asm/addrspace.h        |  10 +
 arch/csky/include/asm/barrier.h          |  19 ++
 arch/csky/include/asm/bitops.h           | 277 ++++++++++++++++
 arch/csky/include/asm/cache.h            |  29 ++
 arch/csky/include/asm/cacheflush.h       |   9 +
 arch/csky/include/asm/checksum.h         |  77 +++++
 arch/csky/include/asm/cmpxchg.h          |  68 ++++
 arch/csky/include/asm/dma-mapping.h      |  13 +
 arch/csky/include/asm/elf.h              | 149 +++++++++
 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              |  10 +
 arch/csky/include/asm/irqflags.h         |  49 +++
 arch/csky/include/asm/mmu.h              |  11 +
 arch/csky/include/asm/mmu_context.h      | 158 +++++++++
 arch/csky/include/asm/page.h             | 104 ++++++
 arch/csky/include/asm/pgalloc.h          | 108 ++++++
 arch/csky/include/asm/pgtable.h          | 301 +++++++++++++++++
 arch/csky/include/asm/processor.h        | 123 +++++++
 arch/csky/include/asm/reg_ops.h          |  16 +
 arch/csky/include/asm/segment.h          |  18 +
 arch/csky/include/asm/shmparam.h         |  10 +
 arch/csky/include/asm/smp.h              |  26 ++
 arch/csky/include/asm/spinlock.h         | 174 ++++++++++
 arch/csky/include/asm/spinlock_types.h   |  20 ++
 arch/csky/include/asm/string.h           |  19 ++
 arch/csky/include/asm/syscall.h          |  69 ++++
 arch/csky/include/asm/syscalls.h         |  14 +
 arch/csky/include/asm/thread_info.h      |  73 ++++
 arch/csky/include/asm/tlb.h              |  19 ++
 arch/csky/include/asm/tlbflush.h         |  22 ++
 arch/csky/include/asm/traps.h            |  39 +++
 arch/csky/include/asm/uaccess.h          | 397 ++++++++++++++++++++++
 arch/csky/include/asm/unistd.h           |   4 +
 arch/csky/include/asm/vdso.h             |  12 +
 arch/csky/include/uapi/asm/Kbuild        |  33 ++
 arch/csky/include/uapi/asm/byteorder.h   |  14 +
 arch/csky/include/uapi/asm/cachectl.h    |  13 +
 arch/csky/include/uapi/asm/ptrace.h      | 105 ++++++
 arch/csky/include/uapi/asm/sigcontext.h  |  13 +
 arch/csky/include/uapi/asm/unistd.h      |  63 ++++
 arch/csky/kernel/Makefile                |   8 +
 arch/csky/kernel/asm-offsets.c           |  85 +++++
 arch/csky/kernel/atomic.S                |  87 +++++
 arch/csky/kernel/cpu-probe.c             |  83 +++++
 arch/csky/kernel/cskyksyms.c             |  31 ++
 arch/csky/kernel/dumpstack.c             |  65 ++++
 arch/csky/kernel/entry.S                 | 407 +++++++++++++++++++++++
 arch/csky/kernel/head.S                  |  81 +++++
 arch/csky/kernel/irq.c                   |  31 ++
 arch/csky/kernel/module.c                |  82 +++++
 arch/csky/kernel/platform.c              |  18 +
 arch/csky/kernel/power.c                 |  31 ++
 arch/csky/kernel/process.c               | 134 ++++++++
 arch/csky/kernel/ptrace.c                | 288 ++++++++++++++++
 arch/csky/kernel/setup.c                 | 148 +++++++++
 arch/csky/kernel/signal.c                | 350 ++++++++++++++++++++
 arch/csky/kernel/smp.c                   | 256 ++++++++++++++
 arch/csky/kernel/syscall.c               |  63 ++++
 arch/csky/kernel/syscall_table.c         |  12 +
 arch/csky/kernel/time.c                  |  12 +
 arch/csky/kernel/traps.c                 | 167 ++++++++++
 arch/csky/kernel/vdso.c                  |  89 +++++
 arch/csky/kernel/vmlinux.lds.S           |  65 ++++
 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                   | 132 ++++++++
 arch/csky/mm/cachev2.c                   |  97 ++++++
 arch/csky/mm/dma-mapping.c               | 216 ++++++++++++
 arch/csky/mm/fault.c                     | 223 +++++++++++++
 arch/csky/mm/highmem.c                   | 210 ++++++++++++
 arch/csky/mm/init.c                      | 122 +++++++
 arch/csky/mm/ioremap.c                   |  49 +++
 arch/csky/mm/syscache.c                  |  29 ++
 arch/csky/mm/tlb.c                       | 210 ++++++++++++
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/timer-csky-v1.c      | 169 ++++++++++
 drivers/clocksource/timer-nationalchip.c | 165 ++++++++++
 drivers/irqchip/Makefile                 |   1 +
 drivers/irqchip/irq-csky-v1.c            | 126 +++++++
 drivers/irqchip/irq-csky-v2.c            | 191 +++++++++++
 drivers/irqchip/irq-nationalchip.c       | 131 ++++++++
 125 files changed, 11618 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/alignment.c
 create mode 100644 arch/csky/abiv1/bswapdi.c
 create mode 100644 arch/csky/abiv1/bswapsi.c
 create mode 100644 arch/csky/abiv1/cacheflush.c
 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/tlb.h
 create mode 100644 arch/csky/abiv1/inc/abi/vdso.h
 create mode 100644 arch/csky/abiv1/memcpy.S
 create mode 100644 arch/csky/abiv1/mmap.c
 create mode 100644 arch/csky/abiv2/Makefile
 create mode 100644 arch/csky/abiv2/cacheflush.c
 create mode 100644 arch/csky/abiv2/fpu.c
 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/tlb.h
 create mode 100644 arch/csky/abiv2/inc/abi/vdso.h
 create mode 100644 arch/csky/abiv2/memcpy.c
 create mode 100644 arch/csky/boot/Makefile
 create mode 100644 arch/csky/boot/dts/Makefile
 create mode 120000 arch/csky/boot/dts/include/dt-bindings
 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/cmpxchg.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/reg_ops.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/smp.h
 create mode 100644 arch/csky/include/asm/spinlock.h
 create mode 100644 arch/csky/include/asm/spinlock_types.h
 create mode 100644 arch/csky/include/asm/string.h
 create mode 100644 arch/csky/include/asm/syscall.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/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/ptrace.h
 create mode 100644 arch/csky/include/uapi/asm/sigcontext.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/smp.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 drivers/clocksource/timer-csky-v1.c
 create mode 100644 drivers/clocksource/timer-nationalchip.c
 create mode 100644 drivers/irqchip/irq-csky-v1.c
 create mode 100644 drivers/irqchip/irq-csky-v2.c
 create mode 100644 drivers/irqchip/irq-nationalchip.c
Signature · 1 line
2.7.4
author
#1 lore raw

PATCH v2 1/19 csky: Build infrastructure

---
 arch/csky/Kconfig                      | 211 +++++++++++++++++++++++++++++++++
 arch/csky/Kconfig.debug                |  29 +++++
 arch/csky/Makefile                     |  92 ++++++++++++++
 arch/csky/abiv1/Makefile               |   8 ++
 arch/csky/abiv2/Makefile               |   4 +
 arch/csky/boot/Makefile                |  25 ++++
 arch/csky/boot/dts/Makefile            |  14 +++
 arch/csky/boot/dts/include/dt-bindings |   1 +
 arch/csky/include/asm/Kbuild           |  72 +++++++++++
 arch/csky/include/uapi/asm/Kbuild      |  33 ++++++
 arch/csky/kernel/Makefile              |   8 ++
 arch/csky/lib/Makefile                 |   1 +
 arch/csky/mm/Makefile                  |  13 ++
 13 files changed, 511 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 120000 arch/csky/boot/dts/include/dt-bindings
 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/lib/Makefile
 create mode 100644 arch/csky/mm/Makefile
arch/csky/Kconfig new file +211 -0
new file mode 100644
index 0000000..cfeb312
@@ -0,0 +1,211 @@
+config CSKY
+	bool
+	default y
+	select ARCH_USE_BUILTIN_BSWAP
+	select COMMON_CLK
+	select CLKSRC_MMIO
+	select CLKSRC_OF
+	select IRQ_DOMAIN
+	select HANDLE_DOMAIN_IRQ
+	select DW_APB_TIMER_OF
+	select GENERIC_ATOMIC64
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_CPU_DEVICES
+	select GENERIC_IRQ_CHIP
+	select GENERIC_IRQ_PROBE
+	select GENERIC_IRQ_SHOW
+	select GENERIC_SCHED_CLOCK
+	select GENERIC_SMP_IDLE_THREAD
+	select HAVE_ARCH_TRACEHOOK
+	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZO
+	select HAVE_KERNEL_LZMA
+	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_RELA if MODULES
+	select NO_BOOTMEM
+	select OF
+	select OF_EARLY_FLATTREE
+	select OF_RESERVED_MEM
+	select PERF_USE_VMALLOC
+	select RTC_LIB
+	select TIMER_OF
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
+
+config CPU_HAS_CACHEV2
+	bool
+
+config CPU_HAS_HILO
+	bool
+
+config CPU_HAS_TLBI
+	bool
+
+config CPU_HAS_LDSTEX
+	bool
+	help
+	  For SMP cpu need "ldex&stex" instrcutions to keep atomic.
+
+config CPU_NEED_TLBSYNC
+	bool
+
+config CPU_NEED_SOFTALIGN
+	bool
+
+config CPU_NO_USER_BKPT
+	bool
+	help
+	  For abiv2 we couldn't use "trap 1" as user space bkpt in gdbserver, because
+	  abiv2 is 16/32bit instruction set and "trap 1" is 32bit.
+	  So we need a 16bit instruction as user space bkpt, and it will cause a illegal
+	  instruction exception.
+	  In kernel we parse the *regs->pc to determine wether send SIGTRAP or not.
+
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y
+
+config HZ
+	int
+	default 100
+
+config GENERIC_CSUM
+	bool
+	default y
+
+config GENERIC_HWEIGHT
+	bool
+	default y
+
+config MMU
+	bool
+	default y
+
+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
+	select CPU_NO_USER_BKPT
+
+config CPU_CK810
+	bool "CSKY CPU ck810"
+	select CPU_HAS_HILO
+	select CPU_NEED_TLBSYNC
+
+config CPU_CK807
+	bool "CSKY CPU ck807"
+	select CPU_HAS_HILO
+
+config CPU_CK860
+	bool "CSKY CPU ck860"
+	select CPU_HAS_TLBI
+	select CPU_HAS_CACHEV2
+	select CPU_HAS_LDSTEX
+endchoice
+
+config CPU_TLB_SIZE
+	int
+	default "128"	if(CPU_CK610 || CPU_CK807 || CPU_CK810)
+	default "1024"	if(CPU_CK860)
+
+config CPU_ASID_BITS
+	int
+	default "8"	if(CPU_CK610 || CPU_CK807 || CPU_CK810)
+	default "12"	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)
+
+config HIGHMEM
+	bool "High Memory Support"
+	depends on !CPU_CK610
+	default y
+
+menuconfig CPU_HAS_FPU
+	bool "CPU has FPU coprocessor"
+	depends on CPU_CK807 || CPU_CK810 || CPU_CK860
+
+menuconfig CPU_HAS_TEE
+	bool "CPU has Trusted Execution Environment"
+	depends on CPU_CK810
+
+config SMP
+	bool "Symmetric Multi-Processing (SMP) support for C-SKY"
+	depends on CPU_CK860
+	default n
+
+config NR_CPUS
+	int "Maximum number of CPUs (2-32)"
+	range 2 32
+	depends on SMP
+	default "4"
+
+comment "*****System type*****"
+
+config RAM_BASE
+	hex "It must be the same with the memory section in your dts"
+	default 0x0
+endmenu
+
+menu "Power management options"
+
+source "kernel/power/Kconfig"
+
+config ARCH_SUSPEND_POSSIBLE
+	bool
+	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"
arch/csky/Kconfig.debug new file +29 -0
new file mode 100644
index 0000000..6978702
@@ -0,0 +1,29 @@
+menu "Kernel hacking"
+
+menu "C-SKY Debug Options"
+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_VECIRQ_LEGENCY
+	bool "Use legency IRQ vector for interrupt, it's for SOC bugfix."
+	help
+	  It's a deprecated method for arch/csky. Don't use it, unless your
+	  SOC has bug.
+
+config CSKY_BUILTIN_DTB
+	bool "Use kernel builtin dtb"
+
+config CSKY_BUILTIN_DTB_NAME
+	string "kernel builtin dtb name"
+	depends on CSKY_BUILTIN_DTB
+endmenu
+
+source "lib/Kconfig.debug"
+
+endmenu
arch/csky/Makefile new file +92 -0

92 lines not on this page · raw message

arch/csky/abiv1/Makefile new file +8 -0
new file mode 100644
index 0000000..c63c6d2
@@ -0,0 +1,8 @@
+obj-y +=	bswapdi.o
+obj-y +=	bswapsi.o
+obj-y +=	cacheflush.o
+obj-y +=	memcpy.o
+obj-y +=	mmap.o
+
+obj-$(CONFIG_CPU_NEED_SOFTALIGN) +=	alignment.o
+
arch/csky/abiv2/Makefile new file +4 -0
new file mode 100644
index 0000000..c90d0fe
@@ -0,0 +1,4 @@
+obj-$(CONFIG_CPU_HAS_FPU)	+= fpu.o
+obj-y				+= memcpy.o
+obj-y				+= cacheflush.o
+
arch/csky/boot/Makefile new file +25 -0
new file mode 100644
index 0000000..c3301a8
@@ -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'
+
arch/csky/boot/dts/Makefile new file +14 -0
new file mode 100644
index 0000000..9afc954
@@ -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
+
arch/csky/boot/dts/include/dt-bindings new file +1 -0
new file mode 120000
index 0000000..08c00e4
@@ -0,0 +1 @@
+../../../../../include/dt-bindings
\ No newline at end of file
arch/csky/include/asm/Kbuild new file +72 -0

72 lines not on this page · raw message

arch/csky/include/uapi/asm/Kbuild new file +33 -0
new file mode 100644
index 0000000..b65252b
@@ -0,0 +1,33 @@
+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 += fcntl.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 += signal.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += statfs.h
+generic-y += stat.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
arch/csky/kernel/Makefile new file +8 -0
new file mode 100644
index 0000000..5403650
@@ -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
+obj-$(CONFIG_SMP) += smp.o
arch/csky/lib/Makefile new file +1 -0
new file mode 100644
index 0000000..02aefbc
@@ -0,0 +1 @@
+lib-y  := memset.o usercopy.o delay.o
arch/csky/mm/Makefile new file +13 -0
new file mode 100644
index 0000000..c870eb3
@@ -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
Signature · 1 line
2.7.4
#2 lore raw

Re: [PATCH V2 01/19] csky: Build infrastructure

Quoted 2 lines · Guo Ren

---

Hi,
Just a few comments...

arch/csky/Kconfig line 3

Quoted 10 lines
arch/csky/Kconfig new file +3 -0
new file mode 100644
index 0000000..cfeb312
@@ -0,0 +1,211 @@
+config CSKY
+	bool
+	default y

shorter:
def_bool y

Quoted 41 lines
arch/csky/Kconfig new file +41 -0
+	select ARCH_USE_BUILTIN_BSWAP
+	select COMMON_CLK
+	select CLKSRC_MMIO
+	select CLKSRC_OF
+	select IRQ_DOMAIN
+	select HANDLE_DOMAIN_IRQ
+	select DW_APB_TIMER_OF
+	select GENERIC_ATOMIC64
+	select GENERIC_CLOCKEVENTS
+	select GENERIC_CPU_DEVICES
+	select GENERIC_IRQ_CHIP
+	select GENERIC_IRQ_PROBE
+	select GENERIC_IRQ_SHOW
+	select GENERIC_SCHED_CLOCK
+	select GENERIC_SMP_IDLE_THREAD
+	select HAVE_ARCH_TRACEHOOK
+	select HAVE_GENERIC_DMA_COHERENT
+	select HAVE_KERNEL_GZIP
+	select HAVE_KERNEL_LZO
+	select HAVE_KERNEL_LZMA
+	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_RELA if MODULES
+	select NO_BOOTMEM
+	select OF
+	select OF_EARLY_FLATTREE
+	select OF_RESERVED_MEM
+	select PERF_USE_VMALLOC
+	select RTC_LIB
+	select TIMER_OF
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
+
+config CPU_HAS_CACHEV2
+	bool
+

arch/csky/Kconfig line 54

Quoted 10 lines
arch/csky/Kconfig new file +10 -0
+config CPU_HAS_HILO
+	bool
+
+config CPU_HAS_TLBI
+	bool
+
+config CPU_HAS_LDSTEX
+	bool
+	help
+	  For SMP cpu need "ldex&stex" instrcutions to keep atomic.

For SMP, CPU needs instructions for atomic operations.

arch/csky/Kconfig line 67

Quoted 13 lines
arch/csky/Kconfig new file +13 -0
+
+config CPU_NEED_TLBSYNC
+	bool
+
+config CPU_NEED_SOFTALIGN
+	bool
+
+config CPU_NO_USER_BKPT
+	bool
+	help
+	  For abiv2 we couldn't use "trap 1" as user space bkpt in gdbserver, because
+	  abiv2 is 16/32bit instruction set and "trap 1" is 32bit.
+	  So we need a 16bit instruction as user space bkpt, and it will cause a illegal

cause an illegal

arch/csky/Kconfig line 69

Quoted 2 lines
arch/csky/Kconfig new file +2 -0
+	  instruction exception.
+	  In kernel we parse the *regs->pc to determine wether send SIGTRAP or not.

whether to send

arch/csky/Kconfig line 73

Quoted 4 lines
arch/csky/Kconfig new file +4 -0
+
+config GENERIC_CALIBRATE_DELAY
+	bool
+	default y

def_bool y

arch/csky/Kconfig line 81

Quoted 8 lines
arch/csky/Kconfig new file +8 -0
+
+config HZ
+	int
+	default 100
+
+config GENERIC_CSUM
+	bool
+	default y

def_bool y

arch/csky/Kconfig line 85

Quoted 4 lines
arch/csky/Kconfig new file +4 -0
+
+config GENERIC_HWEIGHT
+	bool
+	default y

def_bool y

arch/csky/Kconfig line 89

Quoted 4 lines
arch/csky/Kconfig new file +4 -0
+
+config MMU
+	bool
+	default y

same.

arch/csky/Kconfig line 93

Quoted 4 lines
arch/csky/Kconfig new file +4 -0
+
+config RWSEM_GENERIC_SPINLOCK
+	bool
+	default y

same.

arch/csky/Kconfig line 97

Quoted 4 lines
arch/csky/Kconfig new file +4 -0
+
+config TIME_LOW_RES
+	bool
+	default y

again.

arch/csky/Kconfig line 101

Quoted 4 lines
arch/csky/Kconfig new file +4 -0
+
+config TRACE_IRQFLAGS_SUPPORT
+	bool
+	default y

again.

Quoted 40 lines
arch/csky/Kconfig new file +40 -0
+
+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
+	select CPU_NO_USER_BKPT
+
+config CPU_CK810
+	bool "CSKY CPU ck810"
+	select CPU_HAS_HILO
+	select CPU_NEED_TLBSYNC
+
+config CPU_CK807
+	bool "CSKY CPU ck807"
+	select CPU_HAS_HILO
+
+config CPU_CK860
+	bool "CSKY CPU ck860"
+	select CPU_HAS_TLBI
+	select CPU_HAS_CACHEV2
+	select CPU_HAS_LDSTEX
+endchoice
+
+config CPU_TLB_SIZE
+	int
+	default "128"	if(CPU_CK610 || CPU_CK807 || CPU_CK810)
+	default "1024"	if(CPU_CK860)
+

arch/csky/Kconfig line 151

Quoted 10 lines
arch/csky/Kconfig new file +10 -0
+config CPU_ASID_BITS
+	int
+	default "8"	if(CPU_CK610 || CPU_CK807 || CPU_CK810)
+	default "12"	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)

prefer a space after "if" on all those lines above.

Quoted 29 lines
arch/csky/Kconfig new file +29 -0
+
+config HIGHMEM
+	bool "High Memory Support"
+	depends on !CPU_CK610
+	default y
+
+menuconfig CPU_HAS_FPU
+	bool "CPU has FPU coprocessor"
+	depends on CPU_CK807 || CPU_CK810 || CPU_CK860
+
+menuconfig CPU_HAS_TEE
+	bool "CPU has Trusted Execution Environment"
+	depends on CPU_CK810
+
+config SMP
+	bool "Symmetric Multi-Processing (SMP) support for C-SKY"
+	depends on CPU_CK860
+	default n
+
+config NR_CPUS
+	int "Maximum number of CPUs (2-32)"
+	range 2 32
+	depends on SMP
+	default "4"
+
+comment "*****System type*****"
+
+config RAM_BASE
+	hex "It must be the same with the memory section in your dts"

arch/csky/Kconfig line 190

Quoted 10 lines
arch/csky/Kconfig new file +10 -0
+	default 0x0
+endmenu
+
+menu "Power management options"
+
+source "kernel/power/Kconfig"
+
+config ARCH_SUSPEND_POSSIBLE
+	bool
+	default y

shorter:
def_bool y

Quoted 31 lines
arch/csky/Kconfig new file +21 -0
+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"
arch/csky/Kconfig.debug new file +4 -0
new file mode 100644
index 0000000..6978702
@@ -0,0 +1,29 @@
+menu "Kernel hacking"
+
+menu "C-SKY Debug Options"
+config CSKY_DEBUG_INFO

arch/csky/Kconfig.debug line 14

Quoted 10 lines
arch/csky/Kconfig.debug new file +10 -0
+	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_VECIRQ_LEGENCY
+	bool "Use legency IRQ vector for interrupt, it's for SOC bugfix."

legacy

Quoted 15 lines
arch/csky/Kconfig.debug new file +15 -0
+	help
+	  It's a deprecated method for arch/csky. Don't use it, unless your
+	  SOC has bug.
+
+config CSKY_BUILTIN_DTB
+	bool "Use kernel builtin dtb"
+
+config CSKY_BUILTIN_DTB_NAME
+	string "kernel builtin dtb name"
+	depends on CSKY_BUILTIN_DTB
+endmenu
+
+source "lib/Kconfig.debug"
+
+endmenu
Signature · 1 line
~Randy
author
#3 lore raw

Re: [PATCH V2 01/19] csky: Build infrastructure

Hi Randy,

Quoted 3 lines · Randy Dunlap

Hi,
Just a few comments...

Thx for your review. I'll fixup all of you mentioned and self-check again.

Guo Ren

maintainer
#4 lore raw

Re: [PATCH V2 01/19] csky: Build infrastructure

In reply to Guo Ren
Quoted 3 lines · Guo Ren

---

[...]

arch/csky/Kconfig.debug line 25

Quoted 7 lines
arch/csky/Kconfig.debug new file +7 -0
+config CSKY_BUILTIN_DTB
+       bool "Use kernel builtin dtb"
+
+config CSKY_BUILTIN_DTB_NAME
+       string "kernel builtin dtb name"
+       depends on CSKY_BUILTIN_DTB
+endmenu

These options generally exist for backwards compatibility with legacy bootloaders that don't support DT which shouldn't apply here given this is a new arch. If we need this for other reasons, it should not be an architecture specific option.

Rob

author
#5 lore raw

Re: [PATCH V2 01/19] csky: Build infrastructure

Quoted 4 lines · Rob Herring
Quoted 4 lines
arch/csky/Kconfig.debug new file +4 -0
+config CSKY_BUILTIN_DTB
+       bool "Use kernel builtin dtb"
+
+config CSKY_BUILTIN_DTB_NAME
Quoted 8 lines

arch/csky/Kconfig.debug line 25

Quoted 3 lines
arch/csky/Kconfig.debug new file +3 -0
+       string "kernel builtin dtb name"
+       depends on CSKY_BUILTIN_DTB
+endmenu

These options generally exist for backwards compatibility with legacy bootloaders that don't support DT which shouldn't apply here given this is a new arch. If we need this for other reasons, it should not be an architecture specific option.

We want the BUILTIN_DTB for some boards and they don't need change dtb at all. And I just follow other archs BUILTIN_DTB in their Kconfig. eg:
xtensa, h8300, mips, nds32, sh, openrisc, arc ...

I just keep this in Kconfig.debug and it's not a recommended method.

Guo Ren

maintainer
#6 lore raw

Re: [PATCH V2 01/19] csky: Build infrastructure

In reply to Guo Ren
Quoted 17 lines · Guo Ren
arch/csky/Kconfig new file +15 -0
+choice
+       prompt "CPU MODEL"
+       default CPU_CK610
+
+config CPU_CK610
+       bool "CSKY CPU ck610"
+       select CPU_NEED_TLBSYNC
+       select CPU_NEED_SOFTALIGN
+       select CPU_NO_USER_BKPT
+
+config CPU_CK810
+       bool "CSKY CPU ck810"
+       select CPU_HAS_HILO
+       select CPU_NEED_TLBSYNC
+

arch/csky/Kconfig line 135

Quoted 10 lines
arch/csky/Kconfig new file +10 -0
+config CPU_CK807
+       bool "CSKY CPU ck807"
+       select CPU_HAS_HILO
+
+config CPU_CK860
+       bool "CSKY CPU ck860"
+       select CPU_HAS_TLBI
+       select CPU_HAS_CACHEV2
+       select CPU_HAS_LDSTEX
+endchoice

It looks like the CK8xx CPUs are basically compatible, so it would be nice to have a way to configure a kernel that can run on all of them, picking a safe default for options that depend on a particular CPU. E.g. when only CK860 supports SMP, you might start out by making SMP "depend on !(CPU_CK807 || CPU_CK810)", as an alternative to implementing a way for an SMP-enabled kernel to run on non-SMP CPUs (arm has that, but it's probably too complex for your needs).

Similarly, you can set L1_CACHE_BYTES to the largest possible size, and make things like CPU_TLB_SIZE dynamically detected.

arch/csky/Kconfig.debug line 11

Quoted 9 lines
arch/csky/Kconfig.debug new file +9 -0
+menu "C-SKY Debug Options"
+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 :(

Just send a patch to change those dependencies, there is no reason not to apply those. Generally speaking, the kernel should not contain workarounds for particular (mis-)features of the kernel, when you can just change those.

arch/csky/include/asm/Kbuild line 2

Quoted 8 lines
arch/csky/include/asm/Kbuild new file +2 -0
new file mode 100644
index 0000000..5de6519
@@ -0,0 +1,72 @@
+generic-y += asm-offsets.h
+generic-y += atomic.h

The asm-generic version of atomic.h is a bit inefficient, you might want to provide an optimized version for your architecture.

arch/csky/include/asm/Kbuild line 3

Quoted 1 line
arch/csky/include/asm/Kbuild new file +1 -0
+generic-y += auxvec.h

You should not need asm/auxvec.h or uapi/asm/auxvec.h

arch/csky/include/asm/Kbuild line 5

Quoted 2 lines
arch/csky/include/asm/Kbuild new file +2 -0
+generic-y += bitsperlong.h
+generic-y += bug.h

providing your own bug.h might be helpful too.
Have a look

arch/csky/include/asm/Kbuild line 8

Quoted 3 lines
arch/csky/include/asm/Kbuild new file +3 -0
+generic-y += bugs.h
+generic-y += clkdev.h
+generic-y += cputime.h

asm-generic/cputime.h no loinger exists

arch/csky/include/asm/Kbuild line 31

Quoted 1 line
arch/csky/include/asm/Kbuild new file +1 -0
+generic-y += kvm_para.h

Do you support KVM?

arch/csky/include/asm/Kbuild line 56

Quoted 1 line
arch/csky/include/asm/Kbuild new file +1 -0
+generic-y += sizes.h

Deprecated and should not be needed

Arnd

author
#7 lore raw

Re: [PATCH V2 01/19] csky: Build infrastructure

Quoted 11 lines · Arnd Bergmann

It looks like the CK8xx CPUs are basically compatible, so it would be nice to have a way to configure a kernel that can run on all of them, picking a safe default for options that depend on a particular CPU. E.g. when only CK860 supports SMP, you might start out by making SMP "depend on !(CPU_CK807 || CPU_CK810)", as an alternative to implementing a way for an SMP-enabled kernel to run on non-SMP CPUs (arm has that, but it's probably too complex for your needs).

Similarly, you can set L1_CACHE_BYTES to the largest possible size, and make things like CPU_TLB_SIZE dynamically detected.

We talked about this topic in the last patchsets. Ck807/810/860 are mutually incompatible in kernel level but both can run user space programs in ck807/810.

Quoted 5 lines · Arnd Bergmann

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.

Quoted 5 lines

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.

Quoted 6 lines
Quoted 6 lines
arch/csky/Kconfig.debug new file +6 -0
+menu "C-SKY Debug Options"
+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
Quoted 8 lines

arch/csky/Kconfig.debug line 11

Quoted 3 lines
arch/csky/Kconfig.debug new file +3 -0
+         another way to support -g.
+         Some drivers eg: DW_MMC need COMPILE_TEST for new cpu
+         arch :(

Just send a patch to change those dependencies, there is no reason not to apply those. Generally speaking, the kernel should not contain workarounds for particular (mis-)features of the kernel, when you can just change those.

Ok.

Quoted 5 lines
Quoted 1 line

+generic-y += atomic.h

The asm-generic version of atomic.h is a bit inefficient, you might want to provide an optimized version for your architecture.

Ok.

Quoted 3 lines
Quoted 1 line

+generic-y += auxvec.h

You should not need asm/auxvec.h or uapi/asm/auxvec.h

Ok.

Quoted 4 lines
Quoted 1 line

+generic-y += bug.h

providing your own bug.h might be helpful too.
Have a look

Ok.

Quoted 3 lines
Quoted 1 line

+generic-y += cputime.h

asm-generic/cputime.h no loinger exists

Ok, remove it.

Quoted 3 lines
Quoted 1 line

+generic-y += kvm_para.h

Do you support KVM?

No, remove it, thx.

Quoted 3 lines
Quoted 1 line

+generic-y += sizes.h

Deprecated and should not be needed

Ok, remove it.

Guo Ren

author
#8 lore raw

PATCH v2 2/19 csky: defconfig

In reply to Guo Ren
---
 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
arch/csky/configs/gx66xx_defconfig new file +549 -0
new file mode 100644
index 0000000..7f2a987
@@ -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
arch/csky/configs/qemu_ck807_defconfig new file +541 -0

541 lines not on this page · raw message

Signature · 1 line
2.7.4
maintainer
#9 lore raw

Re: [PATCH V2 02/19] csky: defconfig

Quoted 1 line · Guo Ren

Needs a commit msg. Perhaps some overview of what's in each config.

Quoted 7 lines
---
 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

Are these configs mutually exclusive? We try to have one kernel build serve many platforms. So you'd probably want to divide things between the 2 ABIs.

It looks like you still have lots of options enabled that I wouldn't expect you to need. Start with something more minimal for what you need to boot and support upstream.

For a full config, you can use allmodconfig at least to build test.

Rob

author
#10 lore raw

Re: [PATCH V2 02/19] csky: defconfig

Quoted 4 lines · Rob Herring

Are these configs mutually exclusive? We try to have one kernel build serve many platforms. So you'd probably want to divide things between the 2 ABIs.

Yes, they are mutually exclusive, and may I prepare defconfigs like these:
abiv1_defconfig
abiv2_defconfig (ck807 ck810 ck860 are also mutually exclusive in -mcpu=ck807/ck810/ck860, you need "make menuconfig" to select correct CPU, so they couldn't be determined from DT. just like ARMv5, ARMv7-A and ARMv7-M)

Quoted 3 lines

It looks like you still have lots of options enabled that I wouldn't expect you to need. Start with something more minimal for what you need to boot and support upstream.

Ok, I'll clean them up in next version patch.

Quoted 1 line

For a full config, you can use allmodconfig at least to build test.

Thx for the tip.

Guo Ren

author
#11 lore raw

PATCH v2 3/19 csky: Kernel booting

In reply to Guo Ren
---
 arch/csky/kernel/head.S        |  81 ++++++++++++++++++++++
 arch/csky/kernel/setup.c       | 148 +++++++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/vmlinux.lds.S |  65 ++++++++++++++++++
 3 files changed, 294 insertions(+)
 create mode 100644 arch/csky/kernel/head.S
 create mode 100644 arch/csky/kernel/setup.c
 create mode 100644 arch/csky/kernel/vmlinux.lds.S
arch/csky/kernel/head.S new file +81 -0
new file mode 100644
index 0000000..3f0be9a
@@ -0,0 +1,81 @@
+// 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>
+
+__HEAD
+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)
+
+#ifdef CONFIG_SMP
+.align 10
+ENTRY(_start_smp_secondary)
+	/* Invalid I/Dcache BTB BHT */
+	movi	a3, 7
+	lsli	a3, 16
+	addi	a3, (1<<4) | 3
+	mtcr	a3, cr17
+
+	tlbi.all
+
+	/* setup PAGEMASK */
+	movi	a3, 0
+	mtcr	a3, cr<6, 15>
+
+	/* setup MEL0/MEL1 */
+	grs	a0, _start_smp_pc
+_start_smp_pc:
+	bmaski  a1, 13
+	andn    a0, a1
+	movi    a1, 0x00000006
+	movi    a2, 0x00001006
+	or      a1, a0
+	or      a2, a0
+	mtcr	a1, cr<2, 15>
+	mtcr	a2, cr<3, 15>
+
+	/* setup MEH */
+	mtcr	a0, cr<4, 15>
+
+	/* write TLB */
+	bgeni   a3, 28
+	mtcr	a3, cr<8, 15>
+
+	/* setup msa0 & msa1 */
+	lrw	a3, PHYS_OFFSET | 0x8e
+	mtcr	a3, cr<30, 15>
+	lrw	a3, PHYS_OFFSET | 0x26
+	mtcr	a3, cr<31, 15>
+
+	/* enable MMU */
+	movi	a3, 1
+	mtcr    a3, cr18
+
+	jmpi	_goto_mmu_on
+_goto_mmu_on:
+	movi	a3, 0xaa
+
+	lrw	a3, DEFAULT_PSR_VALUE
+	mtcr    a3, psr
+	psrset  ee
+
+	/* set stack point */
+	lrw     a3, secondary_stack
+	ld.w	a3, (a3, 0)
+	mov	sp, a3
+
+	jmpi	csky_start_secondary
+END(_start_smp_secondary)
+#endif
arch/csky/kernel/setup.c new file +148 -0

148 lines not on this page · raw message

arch/csky/kernel/vmlinux.lds.S new file +65 -0

65 lines not on this page · raw message

Signature · 1 line
2.7.4
author
#12 lore raw

PATCH v2 4/19 csky: Exception handling

In reply to Guo Ren
---
 arch/csky/abiv1/alignment.c     | 332 ++++++++++++++++++++++++++++++++
 arch/csky/abiv1/inc/abi/entry.h | 152 +++++++++++++++
 arch/csky/abiv2/inc/abi/entry.h | 149 +++++++++++++++
 arch/csky/include/asm/traps.h   |  39 ++++
 arch/csky/include/asm/unistd.h  |   4 +
 arch/csky/kernel/cpu-probe.c    |  83 ++++++++
 arch/csky/kernel/entry.S        | 407 ++++++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/traps.c        | 167 +++++++++++++++++
 arch/csky/mm/fault.c            | 223 ++++++++++++++++++++++
 9 files changed, 1556 insertions(+)
 create mode 100644 arch/csky/abiv1/alignment.c
 create mode 100644 arch/csky/abiv1/inc/abi/entry.h
 create mode 100644 arch/csky/abiv2/inc/abi/entry.h
 create mode 100644 arch/csky/include/asm/traps.h
 create mode 100644 arch/csky/include/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/traps.c
 create mode 100644 arch/csky/mm/fault.c
arch/csky/abiv1/alignment.c new file +332 -0
new file mode 100644
index 0000000..5acc86f
@@ -0,0 +1,332 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/kernel.h>
+#include <linux/uaccess.h>
+#include <linux/ptrace.h>
+
+static int align_enable = 1;
+static int align_count  = 0;
+
+static inline uint32_t get_ptreg(struct pt_regs *regs, uint32_t rx)
+{
+	return *((int *)&(regs->a0) - 2 + rx);
+}
+
+static inline void put_ptreg(struct pt_regs *regs, uint32_t rx, uint32_t val)
+{
+	*((int *)&(regs->a0) - 2 + rx) = val;
+}
+
+/*
+ * Get byte-value from addr and set it to *valp.
+ *
+ * Success: return 0
+ * Failure: return 1
+ */
+static int ldb_asm(uint32_t addr, uint32_t *valp)
+{
+	uint32_t val;
+	int err;
+
+	if (!access_ok(VERIFY_READ, (void *)addr, 1))
+		return 1;
+
+	asm volatile (
+		"movi	%0, 0			\n"
+		"1:				\n"
+		"ldb	%1, (%2)		\n"
+		"br	3f			\n"
+		"2:				\n"
+		"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)
+	);
+
+	*valp = val;
+
+	return err;
+}
+
+/*
+ * Put byte-value to addr.
+ *
+ * Success: return 0
+ * Failure: return 1
+ */
+static volatile int stb_asm(uint32_t addr, uint32_t val)
+{
+	int err;
+
+	if (!access_ok(VERIFY_WRITE, (void *)addr, 1))
+		return 1;
+
+	asm volatile (
+		"movi	%0, 0			\n"
+		"1:				\n"
+		"stb	%1, (%2)		\n"
+		"br	3f			\n"
+		"2:				\n"
+		"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)
+	);
+
+	return err;
+}
+
+/*
+ * Get half-word from [rx + imm]
+ *
+ * Success: return 0
+ * Failure: return 1
+ */
+static int ldh_c(struct pt_regs *regs, uint32_t rz, uint32_t addr)
+{
+	uint32_t byte0, byte1;
+
+	if (ldb_asm(addr, &byte0))
+		return 1;
+	addr += 1;
+	if (ldb_asm(addr, &byte1))
+		return 1;
+
+	byte0 |= byte1 << 8;
+	put_ptreg(regs, rz, byte0);
+
+	return 0;
+}
+
+/*
+ * Store half-word to [rx + imm]
+ *
+ * Success: return 0
+ * Failure: return 1
+ */
+static int sth_c(struct pt_regs *regs, uint32_t rz, uint32_t addr)
+{
+	uint32_t byte0, byte1;
+
+	byte0 = byte1 = get_ptreg(regs, rz);
+
+	byte0 &= 0xff;
+
+	if (stb_asm(addr, byte0))
+		return 1;
+
+	addr += 1;
+	byte1 = (byte1 >> 8) & 0xff;
+	if (stb_asm(addr, byte1))
+		return 1;
+
+	return 0;
+}
+
+/*
+ * Get word from [rx + imm]
+ *
+ * Success: return 0
+ * Failure: return 1
+ */
+static int ldw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr)
+{
+	uint32_t byte0, byte1, byte2, byte3;
+
+	if (ldb_asm(addr, &byte0))
+		return 1;
+
+	addr += 1;
+	if (ldb_asm(addr, &byte1))
+		return 1;
+
+	addr += 1;
+	if (ldb_asm(addr, &byte2))
+		return 1;
+
+	addr += 1;
+	if (ldb_asm(addr, &byte3))
+		return 1;
+
+	byte0 |= byte1 << 8;
+	byte0 |= byte2 << 16;
+	byte0 |= byte3 << 24;
+
+	put_ptreg(regs, rz, byte0);
+
+	return 0;
+}
+
+/*
+ * Store word to [rx + imm]
+ *
+ * Success: return 0
+ * Failure: return 1
+ */
+static int stw_c(struct pt_regs *regs, uint32_t rz, uint32_t addr)
+{
+	uint32_t byte0, byte1, byte2, byte3;
+
+	byte0 = byte1 = byte2 = byte3 = get_ptreg(regs, rz);
+
+	byte0 &= 0xff;
+
+	if (stb_asm(addr, byte0))
+		return 1;
+
+	addr += 1;
+	byte1 = (byte1 >> 8) & 0xff;
+	if (stb_asm(addr, byte1))
+		return 1;
+
+	addr += 1;
+	byte2 = (byte2 >> 16) & 0xff;
+	if (stb_asm(addr, byte2))
+		return 1;
+
+	addr += 1;
+	byte3 = (byte3 >> 24) & 0xff;
+	if (stb_asm(addr, byte3))
+		return 1;
+
+	align_count++;
+
+	return 0;
+}
+
+extern int fixup_exception(struct pt_regs *regs);
+
+#define OP_LDH 0xc000
+#define OP_STH 0xd000
+#define OP_LDW 0x8000
+#define OP_STW 0x9000
+
+void csky_alignment(struct pt_regs *regs)
+{
+	int ret;
+	uint16_t tmp;
+	uint32_t opcode = 0;
+	uint32_t rx     = 0;
+	uint32_t rz     = 0;
+	uint32_t imm    = 0;
+	uint32_t addr   = 0;
+
+	siginfo_t info;
+
+	if (!user_mode(regs))
+		goto bad_area;
+
+	ret = get_user(tmp, (uint16_t *)instruction_pointer(regs));
+	if (ret) {
+		pr_err("%s get_user failed.\n", __func__);
+		goto bad_area;
+	}
+
+	opcode = (uint32_t)tmp;
+
+	rx  = opcode & 0xf;
+	imm = (opcode >> 4) & 0xf;
+	rz  = (opcode >> 8) & 0xf;
+	opcode &= 0xf000;
+
+	if (rx == 0 || rx == 15 || rz == 0 || rz == 15)
+		goto bad_area;
+
+	switch(opcode) {
+	case OP_LDH:
+		addr = get_ptreg(regs, rx) + (imm << 1);
+		ret = ldh_c(regs, rz, addr);
+		break;
+	case OP_LDW:
+		addr = get_ptreg(regs, rx) + (imm << 2);
+		ret = ldw_c(regs, rz, addr);
+		break;
+	case OP_STH:
+		addr = get_ptreg(regs, rx) + (imm << 1);
+		ret = sth_c(regs, rz, addr);
+		break;
+	case OP_STW:
+		addr = get_ptreg(regs, rx) + (imm << 2);
+		ret = stw_c(regs, rz, addr);
+		break;
+	}
+
+	if(ret)
+		goto bad_area;
+
+	regs->pc += 2;
+
+	return;
+
+bad_area:
+	if (!user_mode(regs)) {
+		if (fixup_exception(regs))
+			return;
+
+		bust_spinlocks(1);
+		pr_alert("%s opcode: %x, rz: %d, rx: %d, imm: %d, addr: %x.\n",
+		          __func__, opcode, rz, rx, imm, addr);
+		show_regs(regs);
+		bust_spinlocks(0);
+		do_exit(SIGKILL);
+	}
+
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code  = BUS_ADRALN;
+	info.si_addr  = (void __user *)addr;
+
+	force_sig_info(info.si_signo, &info, current);
+
+	return;
+}
+
+static struct ctl_table alignment_tbl[4] = {
+	{
+		.procname = "enable",
+		.data = &align_enable,
+		.maxlen = sizeof(align_enable),
+		.mode = 0666,
+		.proc_handler = &proc_dointvec
+	},
+	{
+		.procname = "count",
+		.data = &align_count,
+		.maxlen = sizeof(align_count),
+		.mode = 0666,
+		.proc_handler = &proc_dointvec
+	},
+	{}
+};
+
+static struct ctl_table sysctl_table[2] = {
+	{
+	 .procname = "csky_alignment",
+	 .mode = 0555,
+	 .child = alignment_tbl},
+	{}
+};
+
+static struct ctl_path sysctl_path[2] = {
+	{.procname = "csky"},
+	{}
+};
+
+static int __init csky_alignment_init(void)
+{
+	register_sysctl_paths(sysctl_path, sysctl_table);
+	return 0;
+}
+
+arch_initcall(csky_alignment_init);
+
arch/csky/abiv1/inc/abi/entry.h new file +152 -0

152 lines not on this page · raw message

arch/csky/abiv2/inc/abi/entry.h new file +149 -0

149 lines not on this page · raw message

arch/csky/include/asm/traps.h new file +39 -0
new file mode 100644
index 0000000..ca82b19
@@ -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 */
arch/csky/include/asm/unistd.h new file +4 -0
new file mode 100644
index 0000000..704526c
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <uapi/asm/unistd.h>
+
arch/csky/kernel/cpu-probe.c new file +83 -0

83 lines not on this page · raw message

arch/csky/kernel/entry.S new file +407 -0

407 lines not on this page · raw message

arch/csky/kernel/traps.c new file +167 -0

167 lines not on this page · raw message

arch/csky/mm/fault.c new file +223 -0

223 lines not on this page · raw message

Signature · 1 line
2.7.4
author
#13 lore raw

PATCH v2 5/19 csky: System Call

In reply to Guo Ren
---
 arch/csky/include/asm/syscall.h     | 69 +++++++++++++++++++++++++++++++++++++
 arch/csky/include/asm/syscalls.h    | 14 ++++++++
 arch/csky/include/uapi/asm/unistd.h | 63 +++++++++++++++++++++++++++++++++
 arch/csky/kernel/syscall.c          | 63 +++++++++++++++++++++++++++++++++
 arch/csky/kernel/syscall_table.c    | 12 +++++++
 5 files changed, 221 insertions(+)
 create mode 100644 arch/csky/include/asm/syscall.h
 create mode 100644 arch/csky/include/asm/syscalls.h
 create mode 100644 arch/csky/include/uapi/asm/unistd.h
 create mode 100644 arch/csky/kernel/syscall.c
 create mode 100644 arch/csky/kernel/syscall_table.c
arch/csky/include/asm/syscall.h new file +69 -0
new file mode 100644
index 0000000..8966739
@@ -0,0 +1,69 @@
+#ifndef __ASM_SYSCALL_H
+#define __ASM_SYSCALL_H
+
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <abi/regdef.h>
+
+static inline int
+syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs_syscallid(regs);
+}
+
+static inline void
+syscall_rollback(struct task_struct *task, struct pt_regs *regs)
+{
+	regs->a0 = regs->orig_a0;
+}
+
+static inline long
+syscall_get_error(struct task_struct *task, struct pt_regs *regs)
+{
+	unsigned long error = regs->a0;
+
+	return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long
+syscall_get_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+	return regs->a0;
+}
+
+static inline void
+syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
+			 int error, long val)
+{
+	regs->a0 = (long) error ?: val;
+}
+
+static inline void
+syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+	if (i == 0) {
+		args[0] = regs->orig_a0;
+		args++;
+		i++;
+		n--;
+	}
+	memcpy(args, &regs->a1 + i * sizeof(regs->a1), n * sizeof(args[0]));
+}
+
+static inline void
+syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
+		      unsigned int i, unsigned int n, const unsigned long *args)
+{
+	BUG_ON(i + n > 6);
+        if (i == 0) {
+		regs->orig_a0 = args[0];
+		args++;
+		i++;
+		n--;
+        }
+	memcpy(&regs->a1 + i * sizeof(regs->a1), args, n * sizeof(regs->a0));
+}
+
+#endif	/* __ASM_SYSCALL_H */
arch/csky/include/asm/syscalls.h new file +14 -0
new file mode 100644
index 0000000..c478830
@@ -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 */
arch/csky/include/uapi/asm/unistd.h new file +63 -0

63 lines not on this page · raw message

arch/csky/kernel/syscall.c new file +63 -0

63 lines not on this page · raw message

arch/csky/kernel/syscall_table.c new file +12 -0
new file mode 100644
index 0000000..bea8558
@@ -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>
+};
Signature · 1 line
2.7.4
maintainer
#14 lore raw

Re: [PATCH V2 05/19] csky: System Call

Quoted 1 line · Guo Ren

We really need all new architectures to use the generic syscall ABI, see below for the details.

Quoted 20 lines
arch/csky/include/uapi/asm/unistd.h new file +14 -0
new file mode 100644
index 0000000..0ea9b5a
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_RENAMEAT
+#define __ARCH_WANT_STAT64
+#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

arch/csky/include/uapi/asm/unistd.h line 24

Quoted 10 lines
arch/csky/include/uapi/asm/unistd.h new file +10 -0
+#define __ARCH_WANT_SYS_OLDUMOUNT
+#define __ARCH_WANT_SYS_PAUSE
+#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

I think these all need to be removed, with the exception of __ARCH_WANT_SYS_CLONE. It would be nice though to change the imlpementation in the kernel so we no longer need to set that either.

Quoted 4 lines
arch/csky/include/uapi/asm/unistd.h new file +4 -0
+#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)

arch/csky/include/uapi/asm/unistd.h line 44

Quoted 10 lines
arch/csky/include/uapi/asm/unistd.h new file +10 -0
+#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)

We definitely don't want ipc, socketcall, ugetrlimit, or sysfs.

cacheflush is probbably needed.

For fadvise64_64, please redefine the symbol name so the table points at the right entry.

I'm not completely sure about set_thread_area, can you explain what you need that for?

Quoted 7 lines
arch/csky/include/uapi/asm/unistd.h new file +7 -0
+#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_setfsuid32                __NR_setfsuid

arch/csky/include/uapi/asm/unistd.h line 62

Quoted 10 lines
arch/csky/include/uapi/asm/unistd.h new file +10 -0
+#define __NR_setfsgid32                __NR_setfsgid
+#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

These should also get removed.

Quoted 12 lines
arch/csky/include/uapi/asm/unistd.h new file +12 -0
+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)
+{

arch/csky/include/uapi/asm/unistd.h

Quoted 10 lines
arch/csky/include/uapi/asm/unistd.h new file +10 -0
+       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);
+}

This can be removed since there is mmap2()

Arnd

author
#15 lore raw

Re: [PATCH V2 05/19] csky: System Call

Quoted 2 lines · Arnd Bergmann

We really need all new architectures to use the generic syscall ABI, see below for the details.

Ok, follow the rules.

Quoted 19 lines
Quoted 19 lines
arch/csky/include/uapi/asm/unistd.h new file +19 -0
+#define __ARCH_WANT_OLD_READDIR
+#define __ARCH_WANT_RENAMEAT
+#define __ARCH_WANT_STAT64
+#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_OLDUMOUNT
+#define __ARCH_WANT_SYS_PAUSE
+#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
Quoted 8 lines

arch/csky/include/uapi/asm/unistd.h line 24

Quoted 3 lines
arch/csky/include/uapi/asm/unistd.h new file +3 -0
+#define __ARCH_WANT_SYS_UTIME
+#define __ARCH_WANT_SYS_VFORK
+#define __ARCH_WANT_SYS_WAITPID

I think these all need to be removed, with the exception of __ARCH_WANT_SYS_CLONE. It would be nice though to change the imlpementation in the kernel so we no longer need to set that either.

Ok.

Quoted 8 lines
Quoted 8 lines
arch/csky/include/uapi/asm/unistd.h new file +8 -0
+#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)
Quoted 8 lines

arch/csky/include/uapi/asm/unistd.h line 44

Quoted 6 lines
arch/csky/include/uapi/asm/unistd.h new file +6 -0
+#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)

We definitely don't want ipc, socketcall, ugetrlimit, or sysfs.

Ok, remove them.

Quoted 2 lines

For fadvise64_64, please redefine the symbol name so the table points at the right entry.

We need exchange the args for abiv1. loff_t is 64bit and abiv1 need 8-bytes align in args.
/*
* 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);
}
Quoted 3 lines

I'm not completely sure about set_thread_area, can you explain what you need that for?

In abiv1 there is no tls register, so we use "trap 3" for csky_get_tls defined in arch/csky/kernel/entry.S to get tls.

Also we use set_thread_area to set tls in kernel.

For abiv2 it has r31 for tls-reg, but we still keep the mechanism.

Quoted 11 lines
Quoted 11 lines
arch/csky/include/uapi/asm/unistd.h new file +11 -0
+#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_setfsuid32                __NR_setfsuid
+#define __NR_setfsgid32                __NR_setfsgid
+#define __NR_fchown32          __NR_fchown
+#define __NR_geteuid32         __NR_geteuid
+#define __NR_getegid32         __NR_getegid
Quoted 8 lines

arch/csky/include/uapi/asm/unistd.h line 62

Quoted 6 lines
arch/csky/include/uapi/asm/unistd.h new file +6 -0
+#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

These should also get removed.

Ok.

Quoted 16 lines
Quoted 16 lines
arch/csky/kernel/syscall.c new file +16 -0
+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;
Quoted 8 lines

arch/csky/kernel/syscall.c line 51

Quoted 6 lines
arch/csky/kernel/syscall.c new file +6 -0
+
+       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);
+}

This can be removed since there is mmap2()

Ok.

Guo Ren

maintainer
#16 lore raw

Re: [PATCH V2 05/19] csky: System Call

Quoted 31 lines · Guo Ren
Quoted 17 lines
Quoted 5 lines
arch/csky/include/uapi/asm/unistd.h new file +4 -0
+#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)

arch/csky/include/uapi/asm/unistd.h line 44

Quoted 10 lines
arch/csky/include/uapi/asm/unistd.h new file +10 -0
+#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)

We definitely don't want ipc, socketcall, ugetrlimit, or sysfs.

Ok, remove them.

Quoted 2 lines

For fadvise64_64, please redefine the symbol name so the table points at the right entry.

We need exchange the args for abiv1. loff_t is 64bit and abiv1 need 8-bytes align in args.
/*
* 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)

Quoted 3 lines
{
        return sys_fadvise64_64(fd, offset, len, advice);
}

Right, I do understand what it's used for, my point was that you don't really need a separate system call number for it, just redirect the entry point using the same trick that nds32 has in arch/nds32/kernel/syscall_table.c:

#define sys_fadvise64_64 csky_fadvise64_64

Quoted 8 lines
Quoted 2 lines

I'm not completely sure about set_thread_area, can you explain what you need that for?

In abiv1 there is no tls register, so we use "trap 3" for csky_get_tls defined in arch/csky/kernel/entry.S to get tls.

Also we use set_thread_area to set tls in kernel.

For abiv2 it has r31 for tls-reg, but we still keep the mechanism.

ok.

Arnd

author
#17 lore raw

Re: [PATCH V2 05/19] csky: System Call

Quoted 6 lines · Arnd Bergmann

Right, I do understand what it's used for, my point was that you don't really need a separate system call number for it, just redirect the entry point using the same trick that nds32 has in arch/nds32/kernel/syscall_table.c:

#define sys_fadvise64_64 csky_fadvise64_64

Thx for the tip :)

Guo Ren

author
#18 lore raw

PATCH v2 6/19 csky: Cache and TLB routines

In reply to Guo Ren
---
 arch/csky/abiv1/cacheflush.c          |  51 +++++++++
 arch/csky/abiv1/inc/abi/cacheflush.h  |  42 +++++++
 arch/csky/abiv1/inc/abi/tlb.h         |  11 ++
 arch/csky/abiv2/cacheflush.c          |  55 +++++++++
 arch/csky/abiv2/inc/abi/cacheflush.h  |  38 ++++++
 arch/csky/abiv2/inc/abi/tlb.h         |  12 ++
 arch/csky/include/asm/barrier.h       |  19 +++
 arch/csky/include/asm/cache.h         |  29 +++++
 arch/csky/include/asm/cacheflush.h    |   9 ++
 arch/csky/include/asm/dma-mapping.h   |  13 +++
 arch/csky/include/asm/io.h            |  23 ++++
 arch/csky/include/asm/tlb.h           |  19 +++
 arch/csky/include/asm/tlbflush.h      |  22 ++++
 arch/csky/include/uapi/asm/cachectl.h |  13 +++
 arch/csky/mm/cachev1.c                | 132 +++++++++++++++++++++
 arch/csky/mm/cachev2.c                |  97 ++++++++++++++++
 arch/csky/mm/syscache.c               |  29 +++++
 arch/csky/mm/tlb.c                    | 210 ++++++++++++++++++++++++++++++++++
 18 files changed, 824 insertions(+)
 create mode 100644 arch/csky/abiv1/cacheflush.c
 create mode 100644 arch/csky/abiv1/inc/abi/cacheflush.h
 create mode 100644 arch/csky/abiv1/inc/abi/tlb.h
 create mode 100644 arch/csky/abiv2/cacheflush.c
 create mode 100644 arch/csky/abiv2/inc/abi/cacheflush.h
 create mode 100644 arch/csky/abiv2/inc/abi/tlb.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/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
arch/csky/abiv1/cacheflush.c new file +51 -0
new file mode 100644
index 0000000..cb176f4
@@ -0,0 +1,51 @@
+// 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>
+
+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);
+}
+
+void update_mmu_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))
+		cache_wbinv_all();
+
+	clear_bit(PG_arch_1, &(page)->flags);
+}
+
arch/csky/abiv1/inc/abi/cacheflush.h new file +42 -0

42 lines not on this page · raw message

arch/csky/abiv1/inc/abi/tlb.h new file +11 -0
new file mode 100644
index 0000000..cf0c8d9
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ABI_CSKY_TLB_H
+#define __ABI_CSKY_TLB_H
+
+#define tlb_start_vma(tlb, vma) \
+	do { \
+		if (!tlb->fullmm) \
+			cache_wbinv_all(); \
+	}  while (0)
+#endif /* __ABI_CSKY_TLB_H */
arch/csky/abiv2/cacheflush.c new file +55 -0

55 lines not on this page · raw message

arch/csky/abiv2/inc/abi/cacheflush.h new file +38 -0
new file mode 100644
index 0000000..3c99bb2
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+#ifndef __ABI_CSKY_CACHEFLUSH_H
+#define __ABI_CSKY_CACHEFLUSH_H
+
+/* Keep includes the same across arches.  */
+#include <linux/mm.h>
+
+/*
+ * The cache doesn't need to be flushed when TLB entries change when
+ * the cache is mapped to physical memory, not virtual memory
+ */
+#define flush_cache_all()			do { } while (0)
+#define flush_cache_mm(mm)			do { } while (0)
+#define flush_cache_dup_mm(mm)			do { } while (0)
+#define flush_cache_range(vma, start, end)	do { } while (0)
+#define flush_cache_page(vma, vmaddr, pfn)	do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
+#define flush_dcache_page(page)			do { } while (0)
+#define flush_dcache_mmap_lock(mapping)		do { } while (0)
+#define flush_dcache_mmap_unlock(mapping)	do { } while (0)
+
+#define flush_icache_range(start, end)		cache_wbinv_range(start, end)
+#define flush_icache_user_range(vma,pg,adr,len)	cache_wbinv_range(adr, adr + len)
+void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+
+#define flush_cache_vmap(start, end)		do { } while (0)
+#define flush_cache_vunmap(start, end)		do { } while (0)
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+	do { \
+		memcpy(dst, src, len); \
+		flush_icache_user_range(vma, page, vaddr, len); \
+	} while (0)
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+	memcpy(dst, src, len)
+
+#endif /* __ABI_CSKY_CACHEFLUSH_H */
+
arch/csky/abiv2/inc/abi/tlb.h new file +12 -0
new file mode 100644
index 0000000..0faa4e9
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ABI_CSKY_TLB_H
+#define __ABI_CSKY_TLB_H
+
+#define tlb_start_vma(tlb, vma) \
+	do { \
+		if (!tlb->fullmm && (vma->vm_flags & VM_EXEC)) \
+			icache_inv_all(); \
+	}  while (0)
+
+#endif /* __ABI_CSKY_TLB_H */
arch/csky/include/asm/barrier.h new file +19 -0
new file mode 100644
index 0000000..7254527
@@ -0,0 +1,19 @@
+// 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")
+
+#ifdef CONFIG_SMP
+#define mb()	asm volatile ("sync.is":::"memory")
+#else
+#define mb()	asm volatile ("sync":::"memory")
+#endif
+
+#include <asm-generic/barrier.h>
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_CSKY_BARRIER_H */
arch/csky/include/asm/cache.h new file +29 -0
new file mode 100644
index 0000000..d9224f9
@@ -0,0 +1,29 @@
+#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_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 */
arch/csky/include/asm/cacheflush.h new file +9 -0
new file mode 100644
index 0000000..6a4233b
@@ -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 */
+
arch/csky/include/asm/dma-mapping.h new file +13 -0
new file mode 100644
index 0000000..4c91a3e
@@ -0,0 +1,13 @@
+// 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;
+
+static inline struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
+{
+	return &csky_dma_map_ops;
+}
+
+#endif /* __ASM_DMA_MAPPING_H */
arch/csky/include/asm/io.h new file +23 -0
new file mode 100644
index 0000000..fcb2142
@@ -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 */
arch/csky/include/asm/tlb.h new file +19 -0
new file mode 100644
index 0000000..b2ea919
@@ -0,0 +1,19 @@
+// 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>
+#include <abi/tlb.h>
+
+#define tlb_end_vma(tlb, vma) \
+	do { \
+		if (!tlb->fullmm) \
+			flush_tlb_range(vma, 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 */
arch/csky/include/asm/tlbflush.h new file +22 -0
new file mode 100644
index 0000000..d44cb07
@@ -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
arch/csky/include/uapi/asm/cachectl.h new file +13 -0
new file mode 100644
index 0000000..38a1a28
@@ -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 */
arch/csky/mm/cachev1.c new file +132 -0

132 lines not on this page · raw message

arch/csky/mm/cachev2.c new file +97 -0

97 lines not on this page · raw message

arch/csky/mm/syscache.c new file +29 -0
new file mode 100644
index 0000000..9f5a373
@@ -0,0 +1,29 @@
+// 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_range((unsigned long)addr, (unsigned long)addr + bytes);
+		break;
+	case DCACHE:
+		dcache_wbinv_range((unsigned long)addr, (unsigned long)addr + bytes);
+		break;
+	case BCACHE:
+		cache_wbinv_range((unsigned long)addr, (unsigned long)addr + bytes);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
arch/csky/mm/tlb.c new file +210 -0

210 lines not on this page · raw message

Signature · 1 line
2.7.4
maintainer
#19 lore raw

Re: [PATCH V2 06/19] csky: Cache and TLB routines

Quoted 10 lines · Guo Ren
arch/csky/include/asm/barrier.h new file +4 -0
new file mode 100644
index 0000000..7254527
@@ -0,0 +1,19 @@
+// 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

arch/csky/include/asm/barrier.h line 14

Quoted 10 lines
arch/csky/include/asm/barrier.h new file +10 -0
+
+#ifndef __ASSEMBLY__
+
+#define nop()	asm volatile ("nop")
+
+#ifdef CONFIG_SMP
+#define mb()	asm volatile ("sync.is":::"memory")
+#else
+#define mb()	asm volatile ("sync":::"memory")
+#endif

This is very suspect, please elaborate.

What I would've expected is:

#define mb() asm volatile ("sync" ::: "memory")

#ifdef CONFIG_SMP
#define __smp_mb() asm volatile ("sync.is" ::: "memory") #endif

Is that in fact what you meant?

Do you have a reference to your architecture manual and memory model description somewhere?

Quoted 5 lines
arch/csky/include/asm/barrier.h new file +5 -0
+
+#include <asm-generic/barrier.h>
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_CSKY_BARRIER_H */
author
#20 lore raw

Re: [PATCH V2 06/19] csky: Cache and TLB routines

Quoted 12 lines · Peter Zijlstra

arch/csky/include/asm/barrier.h line 14

Quoted 5 lines
arch/csky/include/asm/barrier.h new file +5 -0
+#ifdef CONFIG_SMP
+#define mb()	asm volatile ("sync.is":::"memory")
+#else
+#define mb()	asm volatile ("sync":::"memory")
+#endif

This is very suspect, please elaborate.

What I would've expected is:

#define mb() asm volatile ("sync" ::: "memory")

Quoted 8 lines

#ifdef CONFIG_SMP
#define __smp_mb() asm volatile ("sync.is" ::: "memory") #endif

Is that in fact what you meant?

Do you have a reference to your architecture manual and memory model description somewhere?

I'll fixup it in next version patch.

author
#21 lore raw

PATCH v2 7/19 csky: MMU and page table management

In reply to Guo Ren
---
 arch/csky/abiv1/inc/abi/ckmmu.h        |  80 +++++++++
 arch/csky/abiv1/inc/abi/page.h         |  26 +++
 arch/csky/abiv1/inc/abi/pgtable-bits.h |  36 ++++
 arch/csky/abiv1/mmap.c                 |  65 +++++++
 arch/csky/abiv2/inc/abi/ckmmu.h        |  88 ++++++++++
 arch/csky/abiv2/inc/abi/page.h         |  14 ++
 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           | 104 ++++++++++++
 arch/csky/include/asm/pgalloc.h        | 108 ++++++++++++
 arch/csky/include/asm/pgtable.h        | 301 +++++++++++++++++++++++++++++++++
 arch/csky/include/asm/segment.h        |  18 ++
 arch/csky/include/asm/shmparam.h       |  10 ++
 arch/csky/mm/dma-mapping.c             | 216 +++++++++++++++++++++++
 arch/csky/mm/highmem.c                 | 210 +++++++++++++++++++++++
 arch/csky/mm/init.c                    | 122 +++++++++++++
 arch/csky/mm/ioremap.c                 |  49 ++++++
 20 files changed, 1619 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/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/segment.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
arch/csky/abiv1/inc/abi/ckmmu.h new file +80 -0
new file mode 100644
index 0000000..e8e7d43
@@ -0,0 +1,80 @@
+// 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
+#include <abi/reg_ops.h>
+
+static inline void select_mmu_cp(void)
+{
+	 asm volatile("cpseti cp15\n");
+}
+
+static inline int read_mmu_index(void)
+{
+	return cprcr("cpcr0");
+}
+
+static inline void write_mmu_index(int value)
+{
+	cpwcr("cpcr0", value);
+}
+
+static inline int read_mmu_entrylo0(void)
+{
+	return cprcr("cpcr2") << 6;
+}
+
+static inline int read_mmu_entrylo1(void)
+{
+	return cprcr("cpcr3") << 6;
+}
+
+static inline void write_mmu_pagemask(int value)
+{
+	cpwcr("cpcr6", value);
+}
+
+static inline int read_mmu_entryhi(void)
+{
+	return cprcr("cpcr4");
+}
+
+static inline void write_mmu_entryhi(int value)
+{
+	cpwcr("cpcr4", value);
+}
+
+/*
+ * TLB operations.
+ */
+static inline void tlb_probe(void)
+{
+	cpwcr("cpcr8", 0x80000000);
+}
+
+static inline void tlb_read(void)
+{
+	cpwcr("cpcr8", 0x40000000);
+}
+
+static inline void tlb_invalid_all(void)
+{
+	cpwcr("cpcr8", 0x04000000);
+}
+
+static inline void tlb_invalid_indexed(void)
+{
+	cpwcr("cpcr8", 0x02000000);
+}
+
+static inline void setup_pgd(unsigned long pgd)
+{
+	cpwcr("cpcr29", pgd);
+}
+
+static inline unsigned long get_pgd(void)
+{
+	return cprcr("cpcr29");
+}
+#endif /* __ASM_CSKY_CKMMUV1_H */
+
arch/csky/abiv1/inc/abi/page.h new file +26 -0
new file mode 100644
index 0000000..b0d2122
@@ -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);
+}
arch/csky/abiv1/inc/abi/pgtable-bits.h new file +36 -0
new file mode 100644
index 0000000..3d614f3
@@ -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 */
arch/csky/abiv1/mmap.c new file +65 -0

65 lines not on this page · raw message

arch/csky/abiv2/inc/abi/ckmmu.h new file +88 -0

88 lines not on this page · raw message

arch/csky/abiv2/inc/abi/page.h new file +14 -0
new file mode 100644
index 0000000..41f5633
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+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);
+}
+
arch/csky/abiv2/inc/abi/pgtable-bits.h new file +36 -0
new file mode 100644
index 0000000..3ca90fa
@@ -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 */
arch/csky/include/asm/addrspace.h new file +10 -0
new file mode 100644
index 0000000..63f86ad
@@ -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 */
+
arch/csky/include/asm/fixmap.h new file +65 -0

65 lines not on this page · raw message

arch/csky/include/asm/highmem.h new file +50 -0

50 lines not on this page · raw message

arch/csky/include/asm/mmu.h new file +11 -0
new file mode 100644
index 0000000..db29c17
@@ -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 */
arch/csky/include/asm/page.h new file +104 -0

104 lines not on this page · raw message

arch/csky/include/asm/pgalloc.h new file +108 -0

108 lines not on this page · raw message

arch/csky/include/asm/pgtable.h new file +301 -0

301 lines not on this page · raw message

arch/csky/include/asm/segment.h new file +18 -0
new file mode 100644
index 0000000..cf1440c
@@ -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 */
arch/csky/include/asm/shmparam.h new file +10 -0
new file mode 100644
index 0000000..ecf7b65
@@ -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 */
arch/csky/mm/dma-mapping.c new file +216 -0

216 lines not on this page · raw message

arch/csky/mm/highmem.c new file +210 -0

210 lines not on this page · raw message

arch/csky/mm/init.c new file +122 -0

122 lines not on this page · raw message

arch/csky/mm/ioremap.c new file +49 -0

49 lines not on this page · raw message

Signature · 1 line
2.7.4
#22 lore raw

Re: [PATCH V2 07/19] csky: MMU and page table management

This commit is missing an explanation.

For the dma-mapping code please use the generic kernel/dma/noncoherent.c code instead of duplicating it.

author
#23 lore raw

Re: [PATCH V2 07/19] csky: MMU and page table management

Quoted 1 line · Christoph Hellwig

This commit is missing an explanation.

The patch is for abiv1 & abiv2 CPU series' MMU support.
- abiv1 CPU (CK610) is VIPT cache and it doesn't support highmem.
- abiv2 CPUs are all PIPT cache and they could support highmem.
We seperate abiv1 and abiv2 into two direcotries for coding convention.

Quoted 2 lines

For the dma-mapping code please use the generic kernel/dma/noncoherent.c code instead of duplicating it.

Thx for the tips and I think you mean the lib/dma-noncoherent.c in the lastest kernel source and not in linux-4.16.2.

I'll rebase on the newest RC version of linux in next version patch and reuse the code in lib/dma-noncoherent.c.

Current csky_dma_alloc implementation is not good, it use 512MB uncached area to mirror the Normal cachable-512MB area. In next version patch, we will increase the max-Normal memory zone to (1GB + 768MB). In csky_dma_alloc we will seperate the atomic_dma and non-atomic_dma and reserve the area in fixmap area.

Here is my memory layout plan in next version patch:
Fixmap : 0xffc02000 – 0xfffff000 (4 MB - 12KB) kmap_atomic, dma_atomic ...
Pkmap : 0xff800000 – 0xffc00000 (4 MB) PTR_PER_PTE = 1024
Vmalloc : 0xf0200000 – 0xff000000 (238 MB) max: 238MB + 256MB + 1GB
Lowmem : 0x80000000 – 0xf0000000 (1G + 768 MB)

Guo Ren

author
#24 lore raw

PATCH v2 8/19 csky: Process management and Signal

In reply to Guo Ren
---
 arch/csky/abiv2/fpu.c                   | 242 ++++++++++++++++++++++
 arch/csky/abiv2/inc/abi/fpu.h           | 219 ++++++++++++++++++++
 arch/csky/include/asm/mmu_context.h     | 158 ++++++++++++++
 arch/csky/include/asm/processor.h       | 123 +++++++++++
 arch/csky/include/asm/thread_info.h     |  73 +++++++
 arch/csky/include/uapi/asm/sigcontext.h |  13 ++
 arch/csky/kernel/process.c              | 134 ++++++++++++
 arch/csky/kernel/signal.c               | 350 ++++++++++++++++++++++++++++++++
 arch/csky/kernel/time.c                 |  12 ++
 9 files changed, 1324 insertions(+)
 create mode 100644 arch/csky/abiv2/fpu.c
 create mode 100644 arch/csky/abiv2/inc/abi/fpu.h
 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/include/uapi/asm/sigcontext.h
 create mode 100644 arch/csky/kernel/process.c
 create mode 100644 arch/csky/kernel/signal.c
 create mode 100644 arch/csky/kernel/time.c
arch/csky/abiv2/fpu.c new file +242 -0
new file mode 100644
index 0000000..330a908
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#include <linux/ptrace.h>
+#include <linux/uaccess.h>
+#include <abi/reg_ops.h>
+
+#define MTCR_MASK	0xFC00FFE0
+#define MFCR_MASK	0xFC00FFE0
+#define MTCR_DIST	0xC0006420
+#define MFCR_DIST	0xC0006020
+
+void __init init_fpu(void)
+{
+	mtcr("cr<1, 2>", 0);
+}
+
+/*
+ * fpu_libc_helper() is to help libc to excute:
+ *  - mfcr %a, cr<1, 2>
+ *  - mfcr %a, cr<2, 2>
+ *  - mtcr %a, cr<1, 2>
+ *  - mtcr %a, cr<2, 2>
+ */
+int fpu_libc_helper(struct pt_regs * regs)
+{
+	int fault;
+	unsigned long instrptr, regx = 0;
+	unsigned long index = 0, tmp = 0;
+	unsigned long tinstr = 0;
+	u16 instr_hi, instr_low;
+
+	instrptr = instruction_pointer(regs);
+	if (instrptr & 1) return 0;
+
+	fault = __get_user(instr_low, (u16 *)instrptr);
+	if (fault) return 0;
+
+	fault = __get_user(instr_hi, (u16 *)(instrptr + 2));
+	if (fault) return 0;
+
+	tinstr = instr_hi | ((unsigned long)instr_low << 16);
+
+	if (((tinstr >> 21) & 0x1F) != 2) return 0;
+
+	if ((tinstr & MTCR_MASK) == MTCR_DIST)
+	{
+		index = (tinstr >> 16) & 0x1F;
+		if(index > 13) return 0;
+
+		tmp = tinstr & 0x1F;
+		if (tmp > 2) return 0;
+
+		regx =  *(&regs->a0 + index);
+
+		if(tmp == 1)
+			mtcr("cr<1, 2>", regx);
+		else if (tmp == 2)
+			mtcr("cr<2, 2>", regx);
+		else
+			return 0;
+
+		regs->pc +=4;
+		return 1;
+	}
+
+	if ((tinstr & MFCR_MASK) == MFCR_DIST) {
+		index = tinstr & 0x1F;
+		if(index > 13) return 0;
+
+		tmp = ((tinstr >> 16) & 0x1F);
+		if (tmp > 2) return 0;
+
+		if (tmp == 1)
+			regx = mfcr("cr<1, 2>");
+		else if (tmp == 2)
+			regx = mfcr("cr<2, 2>");
+		else
+			return 0;
+
+		*(&regs->a0 + index) = regx;
+
+		regs->pc +=4;
+		return 1;
+	}
+
+	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);
+}
+
+#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"
+
+void save_to_user_fp(struct user_fp *user_fp)
+{
+	unsigned long flg;
+	unsigned long tmp1, tmp2, tmp3, tmp4;
+	unsigned long *fpregs;
+
+	local_save_flags(flg);
+
+
+	asm volatile(
+		"mfcr    %0, cr<1, 2> \n"
+		"mfcr    %1, cr<2, 2> \n"
+		:"=r"(tmp1),"=r"(tmp2));
+
+	user_fp->fcr = tmp1;
+	user_fp->fesr = tmp2;
+
+	fpregs = &user_fp->vr[0];
+	asm volatile(
+		FMFVR_FPU_REGS(vr0, vr1)
+		STW_FPU_REGS(0, 4, 16, 20)
+		FMFVR_FPU_REGS(vr2, vr3)
+		STW_FPU_REGS(32, 36, 48, 52)
+		FMFVR_FPU_REGS(vr4, vr5)
+		STW_FPU_REGS(64, 68, 80, 84)
+		FMFVR_FPU_REGS(vr6, vr7)
+		STW_FPU_REGS(96, 100, 112, 116)
+		"addi    %4, 128\n"
+		FMFVR_FPU_REGS(vr8, vr9)
+		STW_FPU_REGS(0, 4, 16, 20)
+		FMFVR_FPU_REGS(vr10, vr11)
+		STW_FPU_REGS(32, 36, 48, 52)
+		FMFVR_FPU_REGS(vr12, vr13)
+		STW_FPU_REGS(64, 68, 80, 84)
+		FMFVR_FPU_REGS(vr14, vr15)
+		STW_FPU_REGS(96, 100, 112, 116)
+		:"=a"(tmp1),"=a"(tmp2),"=a"(tmp3),
+		"=a"(tmp4),"+a"(fpregs));
+
+	local_irq_restore(flg);
+}
+
+void restore_from_user_fp(struct user_fp *user_fp)
+{
+	unsigned long flg;
+	unsigned long tmp1, tmp2, tmp3, tmp4;
+	unsigned long *fpregs;
+
+	local_irq_save(flg);
+
+	tmp1 = user_fp->fcr;
+	tmp2 = user_fp->fesr;
+
+	asm volatile(
+		"mtcr   %0, cr<1, 2>\n"
+		"mtcr   %1, cr<2, 2>\n"
+		::"r"(tmp1), "r"(tmp2));
+
+	fpregs = &user_fp->vr[0];
+	asm volatile(
+		LDW_FPU_REGS(0, 4, 16, 20)
+		FMTVR_FPU_REGS(vr0, vr1)
+		LDW_FPU_REGS(32, 36, 48, 52)
+		FMTVR_FPU_REGS(vr2, vr3)
+		LDW_FPU_REGS(64, 68, 80, 84)
+		FMTVR_FPU_REGS(vr4, vr5)
+		LDW_FPU_REGS(96, 100, 112, 116)
+		FMTVR_FPU_REGS(vr6, vr7)
+		"addi   %4, 128\n"
+		LDW_FPU_REGS(0, 4, 16, 20)
+		FMTVR_FPU_REGS(vr8, vr9)
+		LDW_FPU_REGS(32, 36, 48, 52)
+		FMTVR_FPU_REGS(vr10, vr11)
+		LDW_FPU_REGS(64, 68, 80, 84)
+		FMTVR_FPU_REGS(vr12, vr13)
+		LDW_FPU_REGS(96, 100, 112, 116)
+		FMTVR_FPU_REGS(vr14, vr15)
+		:"=a"(tmp1),"=a"(tmp2),"=a"(tmp3),
+		"=a"(tmp4),"+a"(fpregs));
+
+	local_irq_restore(flg);
+}
+
+
arch/csky/abiv2/inc/abi/fpu.h new file +219 -0

219 lines not on this page · raw message

arch/csky/include/asm/mmu_context.h new file +158 -0

158 lines not on this page · raw message

arch/csky/include/asm/processor.h new file +123 -0

123 lines not on this page · raw message

arch/csky/include/asm/thread_info.h new file +73 -0

73 lines not on this page · raw message

arch/csky/include/uapi/asm/sigcontext.h new file +13 -0
new file mode 100644
index 0000000..633cb14
@@ -0,0 +1,13 @@
+// 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
+
+#include <asm/ptrace.h>
+
+struct sigcontext {
+	struct pt_regs	sc_pt_regs;
+	struct user_fp	sc_user_fp;
+};
+
+#endif /* __ASM_CSKY_SIGCONTEXT_H */
arch/csky/kernel/process.c new file +134 -0

134 lines not on this page · raw message

arch/csky/kernel/signal.c new file +350 -0

350 lines not on this page · raw message

arch/csky/kernel/time.c new file +12 -0
new file mode 100644
index 0000000..7cbdc1e
@@ -0,0 +1,12 @@
+// 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);
+
+	timer_probe();
+}
+
Signature · 1 line
2.7.4
author
#25 lore raw

PATCH v2 9/19 csky: VDSO and rt_sigreturn

In reply to Guo Ren
---
 arch/csky/abiv1/inc/abi/vdso.h | 17 ++++++++
 arch/csky/abiv2/inc/abi/vdso.h | 18 +++++++++
 arch/csky/include/asm/vdso.h   | 12 ++++++
 arch/csky/kernel/vdso.c        | 89 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 136 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
arch/csky/abiv1/inc/abi/vdso.h new file +17 -0
new file mode 100644
index 0000000..a99f0e4
@@ -0,0 +1,17 @@
+// 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 = 0;
+
+	/* movi r1, 127 */
+	err |= __put_user(0x67f1, ptr + 0);
+	/* addi r1, (139 - 127) */
+	err |= __put_user(0x20b1, ptr + 1);
+	/* trap 0 */
+	err |= __put_user(0x0008, ptr + 2);
+
+	return err;
+}
arch/csky/abiv2/inc/abi/vdso.h new file +18 -0
new file mode 100644
index 0000000..aa2d489
@@ -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 = 0;
+
+	/* movi r7, 173 */
+	err |= __put_user(0xea07, ptr);
+	err |= __put_user(0x008b,      ptr+1);
+
+	/* trap 0 */
+	err |= __put_user(0xc000,   ptr+2);
+	err |= __put_user(0x2020,   ptr+3);
+
+	return err;
+}
arch/csky/include/asm/vdso.h new file +12 -0
new file mode 100644
index 0000000..b275440
@@ -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 */
arch/csky/kernel/vdso.c new file +89 -0

89 lines not on this page · raw message

Signature · 1 line
2.7.4
author
#26 lore raw

PATCH v2 10/19 csky: IRQ handling

In reply to Guo Ren
---
 arch/csky/include/asm/irq.h      | 10 ++++++++
 arch/csky/include/asm/irqflags.h | 49 ++++++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/irq.c           | 31 +++++++++++++++++++++++++
 3 files changed, 90 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
arch/csky/include/asm/irq.h new file +10 -0
new file mode 100644
index 0000000..9390cb0
@@ -0,0 +1,10 @@
+// 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
+
+#include <asm-generic/irq.h>
+
+extern void set_handle_irq(void (*handle_irq)(struct pt_regs *));
+
+#endif /* __ASM_CSKY_IRQ_H */
arch/csky/include/asm/irqflags.h new file +49 -0

49 lines not on this page · raw message

arch/csky/kernel/irq.c new file +31 -0
new file mode 100644
index 0000000..ef2600d
@@ -0,0 +1,31 @@
+// 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>
+#include <asm/traps.h>
+#include <asm/smp.h>
+
+static void (*handle_arch_irq)(struct pt_regs *regs) = NULL;
+
+void __init set_handle_irq(void (*handle_irq)(struct pt_regs *))
+{
+	if (handle_arch_irq)
+		return;
+
+	handle_arch_irq = handle_irq;
+}
+
+void __init init_IRQ(void)
+{
+	irqchip_init();
+#ifdef CONFIG_SMP
+	setup_smp_ipi();
+#endif
+}
+
+asmlinkage void __irq_entry csky_do_IRQ(struct pt_regs *regs)
+{
+	handle_arch_irq(regs);
+}
Signature · 1 line
2.7.4
author
#27 lore raw

PATCH v2 11/19 csky: Atomic operations

In reply to Guo Ren
---
 arch/csky/include/asm/cmpxchg.h        |  68 +++++++++++++
 arch/csky/include/asm/spinlock.h       | 174 +++++++++++++++++++++++++++++++++
 arch/csky/include/asm/spinlock_types.h |  20 ++++
 arch/csky/kernel/atomic.S              |  87 +++++++++++++++++
 4 files changed, 349 insertions(+)
 create mode 100644 arch/csky/include/asm/cmpxchg.h
 create mode 100644 arch/csky/include/asm/spinlock.h
 create mode 100644 arch/csky/include/asm/spinlock_types.h
 create mode 100644 arch/csky/kernel/atomic.S
arch/csky/include/asm/cmpxchg.h new file +68 -0
new file mode 100644
index 0000000..1c30a28
@@ -0,0 +1,68 @@
+#ifndef __ASM_CSKY_CMPXCHG_H
+#define __ASM_CSKY_CMPXCHG_H
+
+#ifdef CONFIG_CPU_HAS_LDSTEX
+#include <linux/bug.h>
+#include <asm/barrier.h>
+
+#define __xchg(new, ptr, size)					\
+({								\
+	__typeof__(ptr) __ptr = (ptr);				\
+	__typeof__(new) __new = (new);				\
+	__typeof__(*(ptr)) __ret;				\
+	unsigned long tmp;					\
+	switch (size) {						\
+	case 4:							\
+		asm volatile (					\
+		"1:	ldex.w		%0, (%3) \n"		\
+		"	mov		%1, %2   \n"		\
+		"	stex.w		%1, (%3) \n"		\
+		"	bez		%1, 1b   \n"		\
+			: "=&r" (__ret), "=&r" (tmp)		\
+			: "r" (__new), "r"(__ptr)		\
+			: "memory");				\
+		smp_mb();					\
+		break;						\
+	default:						\
+		BUILD_BUG();					\
+	}							\
+	__ret;							\
+})
+
+#define xchg(ptr, x)	(__xchg((x), (ptr), sizeof(*(ptr))))
+
+#define __cmpxchg(ptr, old, new, size)				\
+({								\
+	__typeof__(ptr) __ptr = (ptr);				\
+	__typeof__(new) __new = (new);				\
+	__typeof__(new) __tmp;					\
+	__typeof__(old) __old = (old);				\
+	__typeof__(*(ptr)) __ret;				\
+	switch (size) {						\
+	case 4:							\
+		asm volatile (					\
+		"1:	ldex.w		%0, (%3) \n"		\
+		"	cmpne		%0, %4   \n"		\
+		"	bt		2f       \n"		\
+		"	mov		%1, %2   \n"		\
+		"	stex.w		%1, (%3) \n"		\
+		"	bez		%1, 1b   \n"		\
+		"2:				 \n"		\
+			: "=&r" (__ret), "=&r" (__tmp)		\
+			: "r" (__new), "r"(__ptr), "r"(__old)	\
+			: "memory");				\
+		smp_mb();					\
+		break;						\
+	default:						\
+		BUILD_BUG();					\
+	}							\
+	__ret;							\
+})
+
+#define cmpxchg(ptr, o, n) \
+	(__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))
+#else
+#include <asm-generic/cmpxchg.h>
+#endif
+
+#endif /* __ASM_CSKY_CMPXCHG_H */
arch/csky/include/asm/spinlock.h new file +174 -0

174 lines not on this page · raw message

arch/csky/include/asm/spinlock_types.h new file +20 -0
new file mode 100644
index 0000000..ea890ef
@@ -0,0 +1,20 @@
+#ifndef __ASM_CSKY_SPINLOCK_TYPES_H
+#define __ASM_CSKY_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+typedef struct {
+	unsigned int lock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED	{ 0 }
+
+typedef struct {
+	unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED		{ 0 }
+
+#endif
arch/csky/kernel/atomic.S new file +87 -0

87 lines not on this page · raw message

Signature · 1 line
2.7.4
maintainer
#28 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 48 lines · Guo Ren
arch/csky/include/asm/cmpxchg.h new file +48 -0
+#include <asm/barrier.h>
+
+#define __xchg(new, ptr, size)					\
+({								\
+	__typeof__(ptr) __ptr = (ptr);				\
+	__typeof__(new) __new = (new);				\
+	__typeof__(*(ptr)) __ret;				\
+	unsigned long tmp;					\
+	switch (size) {						\
+	case 4:							\
+		asm volatile (					\
+		"1:	ldex.w		%0, (%3) \n"		\
+		"	mov		%1, %2   \n"		\
+		"	stex.w		%1, (%3) \n"		\
+		"	bez		%1, 1b   \n"		\
+			: "=&r" (__ret), "=&r" (tmp)		\
+			: "r" (__new), "r"(__ptr)		\
+			: "memory");				\
+		smp_mb();					\
+		break;						\
+	default:						\
+		BUILD_BUG();					\
+	}							\
+	__ret;							\
+})
+
+#define xchg(ptr, x)	(__xchg((x), (ptr), sizeof(*(ptr))))
+
+#define __cmpxchg(ptr, old, new, size)				\
+({								\
+	__typeof__(ptr) __ptr = (ptr);				\
+	__typeof__(new) __new = (new);				\
+	__typeof__(new) __tmp;					\
+	__typeof__(old) __old = (old);				\
+	__typeof__(*(ptr)) __ret;				\
+	switch (size) {						\
+	case 4:							\
+		asm volatile (					\
+		"1:	ldex.w		%0, (%3) \n"		\
+		"	cmpne		%0, %4   \n"		\
+		"	bt		2f       \n"		\
+		"	mov		%1, %2   \n"		\
+		"	stex.w		%1, (%3) \n"		\
+		"	bez		%1, 1b   \n"		\
+		"2:				 \n"		\
+			: "=&r" (__ret), "=&r" (__tmp)		\
+			: "r" (__new), "r"(__ptr), "r"(__old)	\
+			: "memory");				\

arch/csky/include/asm/cmpxchg.h line 63

Quoted 10 lines
arch/csky/include/asm/cmpxchg.h new file +10 -0
+		smp_mb();					\
+		break;						\
+	default:						\
+		BUILD_BUG();					\
+	}							\
+	__ret;							\
+})
+
+#define cmpxchg(ptr, o, n) \
+	(__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))

What's the memory ordering rules for your LDEX/STEX ?

The mandated semantics for xchg() / cmpxchg() is an effective smp_mb() before _and_ after.

The above implementation suggests LDEX implies a SYNC.IS, is this correct?

author
#29 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 54 lines · Peter Zijlstra
Quoted 52 lines · Guo Ren
arch/csky/include/asm/cmpxchg.h new file +52 -0
+#include <asm/barrier.h>
+
+#define __xchg(new, ptr, size)					\
+({								\
+	__typeof__(ptr) __ptr = (ptr);				\
+	__typeof__(new) __new = (new);				\
+	__typeof__(*(ptr)) __ret;				\
+	unsigned long tmp;					\
+	switch (size) {						\
+	case 4:							\
+		asm volatile (					\
+		"1:	ldex.w		%0, (%3) \n"		\
+		"	mov		%1, %2   \n"		\
+		"	stex.w		%1, (%3) \n"		\
+		"	bez		%1, 1b   \n"		\
+			: "=&r" (__ret), "=&r" (tmp)		\
+			: "r" (__new), "r"(__ptr)		\
+			: "memory");				\
+		smp_mb();					\
+		break;						\
+	default:						\
+		BUILD_BUG();					\
+	}							\
+	__ret;							\
+})
+
+#define xchg(ptr, x)	(__xchg((x), (ptr), sizeof(*(ptr))))
+
+#define __cmpxchg(ptr, old, new, size)				\
+({								\
+	__typeof__(ptr) __ptr = (ptr);				\
+	__typeof__(new) __new = (new);				\
+	__typeof__(new) __tmp;					\
+	__typeof__(old) __old = (old);				\
+	__typeof__(*(ptr)) __ret;				\
+	switch (size) {						\
+	case 4:							\
+		asm volatile (					\
+		"1:	ldex.w		%0, (%3) \n"		\
+		"	cmpne		%0, %4   \n"		\
+		"	bt		2f       \n"		\
+		"	mov		%1, %2   \n"		\
+		"	stex.w		%1, (%3) \n"		\
+		"	bez		%1, 1b   \n"		\
+		"2:				 \n"		\
+			: "=&r" (__ret), "=&r" (__tmp)		\
+			: "r" (__new), "r"(__ptr), "r"(__old)	\
+			: "memory");				\
+		smp_mb();					\
+		break;						\
+	default:						\
+		BUILD_BUG();					\
Quoted 8 lines

arch/csky/include/asm/cmpxchg.h line 63

Quoted 6 lines
arch/csky/include/asm/cmpxchg.h new file +6 -0
+	}							\
+	__ret;							\
+})
+
+#define cmpxchg(ptr, o, n) \
+	(__cmpxchg((ptr), (o), (n), sizeof(*(ptr))))

What's the memory ordering rules for your LDEX/STEX ?

Every CPU has a local exclusive monitor.

"Ldex rz, (rx, #off)" will add an entry into the local monitor, and the entry is composed of a address tag and a exclusive flag (inited with 1). Any stores (include other cores') will break the exclusive flag to 0 in the entry which could be indexed by the address tag.

"Stex rz, (rx, #off)" has two condition:
1. Store Success: When the entry's exclusive flag is 1, it will store rz to the [rx + off] address and the rz will be set to 1.
2. Store Failure: When the entry's exclusive flag is 0, just rz will be set to 0.

Quoted 2 lines

The mandated semantics for xchg() / cmpxchg() is an effective smp_mb() before _and_ after.

	switch (size) {						\
	case 4:							\
		smp_mb();					\
		asm volatile (					\
		"1:	ldex.w		%0, (%3) \n"		\
		"	mov		%1, %2   \n"		\
		"	stex.w		%1, (%3) \n"		\
		"	bez		%1, 1b   \n"		\
			: "=&r" (__ret), "=&r" (tmp)		\
			: "r" (__new), "r"(__ptr)		\
			: "memory");				\
		smp_mb();					\
		break;						\

Hmm?
But I couldn't undertand what's wrong without the 1th smp_mb()? 1th smp_mb will make all ld/st finish before ldex.w. Is it necessary?

Quoted 2 lines

The above implementation suggests LDEX implies a SYNC.IS, is this correct?

No, ldex doesn't imply a sync.is.

Guo Ren

maintainer
#30 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 10 lines · Guo Ren
Quoted 1 line · Peter Zijlstra

What's the memory ordering rules for your LDEX/STEX ?

Every CPU has a local exclusive monitor.

"Ldex rz, (rx, #off)" will add an entry into the local monitor, and the entry is composed of a address tag and a exclusive flag (inited with 1). Any stores (include other cores') will break the exclusive flag to 0 in the entry which could be indexed by the address tag.

Quoted 5 lines

"Stex rz, (rx, #off)" has two condition:
1. Store Success: When the entry's exclusive flag is 1, it will store rz to the [rx + off] address and the rz will be set to 1.
2. Store Failure: When the entry's exclusive flag is 0, just rz will be set to 0.

That's how LL/SC works. What I was asking is if they have any effect on memory ordering. Some architectures have LL/SC imply memory ordering, most do not.

Going by your spinlock implementation they don't imply any memory ordering.

Quoted 16 lines
Quoted 2 lines

The mandated semantics for xchg() / cmpxchg() is an effective smp_mb() before _and_ after.

	switch (size) {						\
	case 4:							\
		smp_mb();					\
		asm volatile (					\
		"1:	ldex.w		%0, (%3) \n"		\
		"	mov		%1, %2   \n"		\
		"	stex.w		%1, (%3) \n"		\
		"	bez		%1, 1b   \n"		\
			: "=&r" (__ret), "=&r" (tmp)		\
			: "r" (__new), "r"(__ptr)		\
			: "memory");				\
		smp_mb();					\
		break;						\
Quoted 3 lines

Hmm?
But I couldn't undertand what's wrong without the 1th smp_mb()? 1th smp_mb will make all ld/st finish before ldex.w. Is it necessary?

Yes.

	CPU0			CPU1

	r1 = READ_ONCE(x);	WRITE_ONCE(y, 1);
	r2 = xchg(&y, 2);	smp_store_release(&x, 1);

must not allow: r1==1 && r2==0

Quoted 3 lines
Quoted 2 lines

The above implementation suggests LDEX implies a SYNC.IS, is this correct?

No, ldex doesn't imply a sync.is.

Right, as per the spinlock emails, then your proposed primitives are incorrect.

maintainer
#31 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 11 lines · Peter Zijlstra
Quoted 2 lines

But I couldn't undertand what's wrong without the 1th smp_mb()? 1th smp_mb will make all ld/st finish before ldex.w. Is it necessary?

Yes.

	CPU0			CPU1

	r1 = READ_ONCE(x);	WRITE_ONCE(y, 1);
	r2 = xchg(&y, 2);	smp_store_release(&x, 1);

must not allow: r1==1 && r2==0

Also, since you said "SYNC.IS" is a pipeline flush, those instruction-sync primitives normally do not imply a store-buffer flush, does yours? If not it is not a valid smp_mb() implementation.

Notably:

	CPU0				CPU1

	WRITE_ONCE(x, 1);		WRITE_ONCE(y, 1);
	smp_mb();			smp_mb();
	r0 = READ_ONCE(y);		r1 = READ_ONCE(x);

must not allow: r0==0 && r1==0

Which would be possible with a regular instruction-sync barrier, but must absolutely not be true with a full memory barrier.

(and you can replace the smp_mb(); r = READ_ONCE(); with r = xchg() to again see why you need that first smp_mb()).

author
#32 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 11 lines · Peter Zijlstra
Quoted 7 lines
	CPU0			CPU1

	r1 = READ_ONCE(x);	WRITE_ONCE(y, 1);
	r2 = xchg(&y, 2);	smp_store_release(&x, 1);

must not allow: r1==1 && r2==0

Also, since you said "SYNC.IS" is a pipeline flush, those instruction-sync primitives normally do not imply a store-buffer flush, does yours? If not it is not a valid smp_mb() implementation.

Sync.is will flush pipeline and store-buffer.

"sync" means completion memory barrier.
"i" means flush cpu pipeline.
"s" means sharable to other cpus.

Quoted 9 lines

Notably:

	CPU0				CPU1

	WRITE_ONCE(x, 1);		WRITE_ONCE(y, 1);
	smp_mb();			smp_mb();
	r0 = READ_ONCE(y);		r1 = READ_ONCE(x);
Quoted 7 lines

must not allow: r0==0 && r1==0

Which would be possible with a regular instruction-sync barrier, but must absolutely not be true with a full memory barrier.

(and you can replace the smp_mb(); r = READ_ONCE(); with r = xchg() to again see why you need that first smp_mb()).

	CPU0			CPU1

	WRITE_ONCE(x, 1)	WRITE_ONCE(y, 1)
	r0 = xchg(&y, 2)	r1 = xchg(&x, 2)

must not allow: r0==0 && r1==0
So we must add a smp_mb between WRITE_ONCE() and xchg(), right?

Guo Ren

#33 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 9 lines · Guo Ren

On Fri, Jul 06, 2018 at 02:17:16PM +0200, Peter Zijlstra wrote:

	CPU0			CPU1

	WRITE_ONCE(x, 1)	WRITE_ONCE(y, 1)
	r0 = xchg(&y, 2)	r1 = xchg(&x, 2)

must not allow: r0==0 && r1==0
So we must add a smp_mb between WRITE_ONCE() and xchg(), right?

The state (r0==0 && r1==0) _must_ not be allowed in the above snippet (so, even without the additional smp_mb() between WRITE_ONCE() and xchg()). In informal terms, xchg() provides the smp_mb().

Compare implementations of xchg() and xchg_relaxed(). The following could also be helpful (in addition to the references pointed out earlier):

Documentation/atomic_t.txt

Andrea

Quoted 3 lines

Guo Ren

author
#34 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 8 lines · Andrea Parri
Quoted 7 lines · Guo Ren

On Fri, Jul 06, 2018 at 02:17:16PM +0200, Peter Zijlstra wrote:

	CPU0			CPU1

	WRITE_ONCE(x, 1)	WRITE_ONCE(y, 1)
	r0 = xchg(&y, 2)	r1 = xchg(&x, 2)
Quoted 6 lines
Quoted 2 lines

must not allow: r0==0 && r1==0
So we must add a smp_mb between WRITE_ONCE() and xchg(), right?

The state (r0==0 && r1==0) _must_ not be allowed in the above snippet (so, even without the additional smp_mb() between WRITE_ONCE() and xchg()). In informal terms, xchg() provides the smp_mb().

Got it, thx.

Quoted 4 lines

Compare implementations of xchg() and xchg_relaxed(). The following could also be helpful (in addition to the references pointed out earlier):

Documentation/atomic_t.txt

Thx for the tip.

Guo Ren

author
#35 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

In reply to Peter Zijlstra
Quoted 6 lines · Peter Zijlstra

That's how LL/SC works. What I was asking is if they have any effect on memory ordering. Some architectures have LL/SC imply memory ordering, most do not.

Going by your spinlock implementation they don't imply any memory ordering.

ldex/stex don't imply any memory ordering.

Quoted 21 lines
Quoted 17 lines
Quoted 3 lines

The mandated semantics for xchg() / cmpxchg() is an effective smp_mb() before _and_ after.

	switch (size) {						\
	case 4:							\
		smp_mb();					\
		asm volatile (					\
		"1:	ldex.w		%0, (%3) \n"		\
		"	mov		%1, %2   \n"		\
		"	stex.w		%1, (%3) \n"		\
		"	bez		%1, 1b   \n"		\
			: "=&r" (__ret), "=&r" (tmp)		\
			: "r" (__new), "r"(__ptr)		\
			: "memory");				\
		smp_mb();					\
		break;						\
Quoted 3 lines

Hmm?
But I couldn't undertand what's wrong without the 1th smp_mb()? 1th smp_mb will make all ld/st finish before ldex.w. Is it necessary?

Quoted 8 lines

Yes.

	CPU0			CPU1

	r1 = READ_ONCE(x);	WRITE_ONCE(y, 1);
	r2 = xchg(&y, 2);	smp_store_release(&x, 1);

must not allow: r1==1 && r2==0

CPU1 smp_store_release could be finished before WRITE_ONCE, so r1=1 && r2=0?

Quoted 6 lines
Quoted 3 lines
Quoted 2 lines

The above implementation suggests LDEX implies a SYNC.IS, is this correct?

No, ldex doesn't imply a sync.is.

Right, as per the spinlock emails, then your proposed primitives are incorrect.

Yes, approve.

Guo Ren

#36 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Hi Guo,

Quoted 9 lines · Guo Ren
Quoted 6 lines · Peter Zijlstra
	CPU0			CPU1

	r1 = READ_ONCE(x);	WRITE_ONCE(y, 1);
	r2 = xchg(&y, 2);	smp_store_release(&x, 1);

must not allow: r1==1 && r2==0

CPU1 smp_store_release could be finished before WRITE_ONCE, so r1=1 && r2=0?

The emphasis is on the "must": your implementation __must__ prevent this from happening (say, by inserting memory barriers in smp_store_release()); if your implementation allows the state (r1==1 && r2==0), then the imple- mentation is incorrect.

I'd suggest you have a look at the Linux-kernel memory consistency model documentation and the associated tools, starting with:

Documentation/memory-barriers.txt
tools/memory-model/

(and please do not hesitate to ask questions about them, if something is
unclear).

Andrea

author
#37 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 9 lines · Andrea Parri

Hi Guo,

Quoted 6 lines · Guo Ren
Quoted 5 lines · Peter Zijlstra
	CPU0			CPU1

	r1 = READ_ONCE(x);	WRITE_ONCE(y, 1);
	r2 = xchg(&y, 2);	smp_store_release(&x, 1);
Quoted 8 lines
Quoted 3 lines
Quoted 1 line

must not allow: r1==1 && r2==0

CPU1 smp_store_release could be finished before WRITE_ONCE, so r1=1 && r2=0?

The emphasis is on the "must": your implementation __must__ prevent this from happening (say, by inserting memory barriers in smp_store_release()); if your implementation allows the state (r1==1 && r2==0), then the imple- mentation is incorrect.

Ok, Got it.

Quoted 5 lines

I'd suggest you have a look at the Linux-kernel memory consistency model documentation and the associated tools, starting with:

Documentation/memory-barriers.txt
tools/memory-model/

Thx for the tips.

Quoted 2 lines

(and please do not hesitate to ask questions about them, if something is
unclear).

I'll. Thx again.

Guo Ren

maintainer
#38 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

In reply to Guo Ren
Quoted 6 lines · Guo Ren
arch/csky/include/asm/spinlock.h new file +6 -0
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+
+	asm volatile (

arch/csky/include/asm/spinlock.h line 25

Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+		"1:	ldex.w		%0, (%1) \n"
+		"	bnez		%0, 1b   \n"
+		"	movi		%0, 1    \n"
+		"	stex.w		%0, (%1) \n"
+		"	bez		%0, 1b   \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+	smp_mb();
+}

Test-and-set with MB acting as ACQUIRE, ok.

Quoted 5 lines
arch/csky/include/asm/spinlock.h new file +5 -0
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+

arch/csky/include/asm/spinlock.h line 41

Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+	smp_mb();
+	asm volatile (
+		"1:	ldex.w		%0, (%1) \n"
+		"	movi		%0, 0    \n"
+		"	stex.w		%0, (%1) \n"
+		"	bez		%0, 1b   \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+}

MB acting for RELEASE, but _why_ are you using a LDEX/STEX to clear the lock word? Would not a normal store work?

Also, the fact that you need MB for release implies your LDEX does not in fact imply anything and your xchg/cmpxchg implementation is broken.

Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+
+	asm volatile (
+		"1:	ldex.w		%0, (%1) \n"
+		"	bnez		%0, 2f   \n"
+		"	movi		%0, 1    \n"
+		"	stex.w		%0, (%1) \n"

arch/csky/include/asm/spinlock.h line 62

Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+		"	bez		%0, 1b   \n"
+		"	movi		%0, 0    \n"
+		"2:				 \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+	smp_mb();
+
+	return !tmp;
+}

Strictly speaking you can avoid the MB on failure. You only need to provide ACQUIRE semantics on success.

That said, I would really suggest you implement a ticket lock instead of a test-and-set lock. They're not really all that complicated and do provide better worst case behaviour.

Quoted 1 line

+/****** read lock/unlock/trylock ******/

Please have a look at using qrwlock -- esp. if you implement a ticket lock, then the rwlock comes for 'free'.

author
#39 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 12 lines · Peter Zijlstra
Quoted 10 lines · Guo Ren
arch/csky/include/asm/spinlock.h new file +10 -0
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+
+	asm volatile (
+		"1:	ldex.w		%0, (%1) \n"
+		"	bnez		%0, 1b   \n"
+		"	movi		%0, 1    \n"
+		"	stex.w		%0, (%1) \n"
Quoted 8 lines

arch/csky/include/asm/spinlock.h line 25

Quoted 6 lines
arch/csky/include/asm/spinlock.h new file +6 -0
+		"	bez		%0, 1b   \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+	smp_mb();
+}

Test-and-set with MB acting as ACQUIRE, ok.

Em ... Ok, I'll try to use test-and-set function instead of it.

Quoted 10 lines
Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+
+	smp_mb();
+	asm volatile (
+		"1:	ldex.w		%0, (%1) \n"
+		"	movi		%0, 0    \n"
+		"	stex.w		%0, (%1) \n"
Quoted 8 lines

arch/csky/include/asm/spinlock.h line 25

Quoted 5 lines
arch/csky/include/asm/spinlock.h new file +5 -0
+		"	bez		%0, 1b   \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+}

MB acting for RELEASE, but _why_ are you using a LDEX/STEX to clear the lock word? Would not a normal store work?

Normal store is enough, I'll fixup it in next version patch.

Quoted 2 lines

Also, the fact that you need MB for release implies your LDEX does not in fact imply anything and your xchg/cmpxchg implementation is broken.

xchg/cmxchg broken without 1th smp_mb()? Why we need protect the instructions flow before the ldex.w?

Quoted 24 lines
Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+static inline int arch_spin_trylock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+
+	asm volatile (
+		"1:	ldex.w		%0, (%1) \n"
+		"	bnez		%0, 2f   \n"
+		"	movi		%0, 1    \n"
+		"	stex.w		%0, (%1) \n"

arch/csky/include/asm/spinlock.h line 62

Quoted 10 lines
arch/csky/include/asm/spinlock.h new file +10 -0
+		"	bez		%0, 1b   \n"
+		"	movi		%0, 0    \n"
+		"2:				 \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+	smp_mb();
+
+	return !tmp;
+}

Strictly speaking you can avoid the MB on failure. You only need to provide ACQUIRE semantics on success.

Quoted 3 lines

That said, I would really suggest you implement a ticket lock instead of a test-and-set lock. They're not really all that complicated and do provide better worst case behaviour.

Ok, I'll try to implement ticket lock in next version patch.

Quoted 6 lines
Quoted 3 lines

+/****** read lock/unlock/trylock ******/

Please have a look at using qrwlock -- esp. if you implement a ticket lock, then the rwlock comes for 'free'.

Ok, I'll try it.

Guo Ren

maintainer
#40 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 21 lines · Guo Ren
Quoted 12 lines · Peter Zijlstra
Quoted 10 lines · Guo Ren
arch/csky/include/asm/spinlock.h new file +10 -0
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+	unsigned int *p = &lock->lock;
+	unsigned int tmp;
+
+	asm volatile (
+		"1:	ldex.w		%0, (%1) \n"
+		"	bnez		%0, 1b   \n"
+		"	movi		%0, 1    \n"
+		"	stex.w		%0, (%1) \n"
Quoted 8 lines

arch/csky/include/asm/spinlock.h line 25

Quoted 6 lines
arch/csky/include/asm/spinlock.h new file +6 -0
+		"	bez		%0, 1b   \n"
+		: "=&r" (tmp)
+		: "r"(p)
+		: "memory");
+	smp_mb();
+}

Test-and-set with MB acting as ACQUIRE, ok.

Quoted 1 line

Em ... Ok, I'll try to use test-and-set function instead of it.

"test-and-set" is just the name of this type of spinlock implementation.

You _could_ use the linux test_and_set bitop, but those are defined on unsigned long and spinlock_t is generally assumed to be of unsigned int size.

Go with the ticket locks as per below.

Quoted 4 lines
Quoted 2 lines

Also, the fact that you need MB for release implies your LDEX does not in fact imply anything and your xchg/cmpxchg implementation is broken.

xchg/cmxchg broken without 1th smp_mb()? Why we need protect the instructions flow before the ldex.w?

See the email I send earlier in that thread.

Quoted 1 line

Ok, I'll try to implement ticket lock in next version patch.

If you need inspiration, look at:

git show 81bb5c6420635dfd058c210bd342c29c95ccd145^1:arch/arm64/include/asm/spinlock.h

Or look at the current version of that file and ignore the LSE version.

Note that unlock is a store half-word (u16), not having seen your arch manual yet I don't know if you even have that.

maintainer
#41 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 4 lines · Peter Zijlstra
Quoted 1 line

Ok, I'll try to implement ticket lock in next version patch.

If you need inspiration, look at:

My bad, just look at the arm (not arm64) version.

author
#42 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

In reply to Peter Zijlstra
Quoted 10 lines · Peter Zijlstra
Quoted 2 lines
Quoted 1 line

Test-and-set with MB acting as ACQUIRE, ok.

Em ... Ok, I'll try to use test-and-set function instead of it.

"test-and-set" is just the name of this type of spinlock implementation.

You _could_ use the linux test_and_set bitop, but those are defined on unsigned long and spinlock_t is generally assumed to be of unsigned int size.

Go with the ticket locks as per below.

Ok, I'll learn it.

Quoted 4 lines
Quoted 1 line

Ok, I'll try to implement ticket lock in next version patch.

If you need inspiration, look at:

arch/arm/include/asm/spinlock.h

Quoted 5 lines

Or look at the current version of that file and ignore the LSE version.

Note that unlock is a store half-word (u16), not having seen your arch manual yet I don't know if you even have that.

Nice tips, thank you very much.

Guo Ren

maintainer
#43 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

In reply to Guo Ren
Quoted 21 lines · Guo Ren
arch/csky/kernel/atomic.S new file +21 -0
+#ifdef CONFIG_CPU_HAS_LDSTEX
+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:
+	ldex	a3, (a2)
+	cmpne	a0, a3
+	bt16	2f
+	mov	a3, a1
+	stex	a3, (a2)
+	bez	a3, 1b
+2:
+	sync.is

arch/csky/kernel/atomic.S line 44

Quoted 10 lines
arch/csky/kernel/atomic.S new file +10 -0
+	mvc	a0
+	ldw	a3, (sp, 0)
+	mtcr	a3, epc
+	ldw     a3, (sp, 4)
+	mtcr	a3, epsr
+	addi	sp, 8
+	KSPTOUSP
+	rte
+END(csky_cmpxchg)
+#else

Please explain... if the CPU has LDEX/STEX, then _why_ do you need this?

author
#44 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 26 lines · Peter Zijlstra
Quoted 25 lines · Guo Ren
arch/csky/kernel/atomic.S new file +25 -0
+#ifdef CONFIG_CPU_HAS_LDSTEX
+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:
+	ldex	a3, (a2)
+	cmpne	a0, a3
+	bt16	2f
+	mov	a3, a1
+	stex	a3, (a2)
+	bez	a3, 1b
+2:
+	sync.is
+	mvc	a0
+	ldw	a3, (sp, 0)
+	mtcr	a3, epc
+	ldw     a3, (sp, 4)
Quoted 8 lines

arch/csky/kernel/atomic.S line 44

Quoted 6 lines
arch/csky/kernel/atomic.S new file +6 -0
+	mtcr	a3, epsr
+	addi	sp, 8
+	KSPTOUSP
+	rte
+END(csky_cmpxchg)
+#else

Please explain... if the CPU has LDEX/STEX, then _why_ do you need this?

Our libc use csky_cmpxchg and we want it compatible. Of course, we'll also implement the ldex/stex atomic operations in libs in future.

Guo Ren

maintainer
#45 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 35 lines · Guo Ren
Quoted 26 lines · Peter Zijlstra
Quoted 25 lines · Guo Ren
arch/csky/kernel/atomic.S new file +25 -0
+#ifdef CONFIG_CPU_HAS_LDSTEX
+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:
+	ldex	a3, (a2)
+	cmpne	a0, a3
+	bt16	2f
+	mov	a3, a1
+	stex	a3, (a2)
+	bez	a3, 1b
+2:
+	sync.is
+	mvc	a0
+	ldw	a3, (sp, 0)
+	mtcr	a3, epc
+	ldw     a3, (sp, 4)
Quoted 8 lines

arch/csky/kernel/atomic.S line 44

Quoted 6 lines
arch/csky/kernel/atomic.S new file +6 -0
+	mtcr	a3, epsr
+	addi	sp, 8
+	KSPTOUSP
+	rte
+END(csky_cmpxchg)
+#else

Please explain... if the CPU has LDEX/STEX, then _why_ do you need this?

Quoted 2 lines

Our libc use csky_cmpxchg and we want it compatible. Of course, we'll also implement the ldex/stex atomic operations in libs in future.

I would strongly suggest not providing this syscall on SMP systems from the get go. There is no point in starting with legacy problems without an actual legacy.

author
#46 lore raw

Re: [PATCH V2 11/19] csky: Atomic operations

Quoted 36 lines · Peter Zijlstra
Quoted 35 lines · Guo Ren
Quoted 34 lines · Peter Zijlstra
Quoted 21 lines · Guo Ren
arch/csky/kernel/atomic.S new file +21 -0
+#ifdef CONFIG_CPU_HAS_LDSTEX
+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:
+	ldex	a3, (a2)
+	cmpne	a0, a3
+	bt16	2f
+	mov	a3, a1
+	stex	a3, (a2)
+	bez	a3, 1b
+2:
+	sync.is

arch/csky/kernel/atomic.S line 44

Quoted 10 lines
arch/csky/kernel/atomic.S new file +10 -0
+	mvc	a0
+	ldw	a3, (sp, 0)
+	mtcr	a3, epc
+	ldw     a3, (sp, 4)
+	mtcr	a3, epsr
+	addi	sp, 8
+	KSPTOUSP
+	rte
+END(csky_cmpxchg)
+#else

Please explain... if the CPU has LDEX/STEX, then _why_ do you need this?

Quoted 6 lines
Quoted 2 lines

Our libc use csky_cmpxchg and we want it compatible. Of course, we'll also implement the ldex/stex atomic operations in libs in future.

I would strongly suggest not providing this syscall on SMP systems from the get go. There is no point in starting with legacy problems without an actual legacy.

Ok.

author
#47 lore raw

PATCH v2 12/19 csky: ELF and module probe

In reply to Guo Ren
---
 arch/csky/include/asm/elf.h | 149 ++++++++++++++++++++++++++++++++++++++++++++
 arch/csky/kernel/module.c   |  82 ++++++++++++++++++++++++
 2 files changed, 231 insertions(+)
 create mode 100644 arch/csky/include/asm/elf.h
 create mode 100644 arch/csky/kernel/module.c
arch/csky/include/asm/elf.h new file +149 -0
new file mode 100644
index 0000000..9a7967c
@@ -0,0 +1,149 @@
+// 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 <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;
+
+typedef struct user_fp elf_fpregset_t;
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+/*
+ * 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] = regs->usp;			\
+        pr_reg[17] = regs->lr;			\
+        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->tls;
+#else
+     #define ELF_CORE_COPY_REGS(pr_reg, regs)   \
+        pr_reg[0] = regs->pc;                   \
+        pr_reg[1] = regs->regs[9];              \
+        pr_reg[2] = regs->usp;			\
+        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->lr;
+#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
arch/csky/kernel/module.c new file +82 -0

82 lines not on this page · raw message

Signature · 1 line
2.7.4
author
#48 lore raw

PATCH v2 13/19 csky: Library functions

In reply to Guo Ren
---
 arch/csky/abiv1/bswapdi.c      |  18 +++
 arch/csky/abiv1/bswapsi.c      |  15 ++
 arch/csky/abiv1/memcpy.S       | 344 +++++++++++++++++++++++++++++++++++++++++
 arch/csky/abiv2/memcpy.c       |  43 ++++++
 arch/csky/include/asm/string.h |  19 +++
 arch/csky/kernel/asm-offsets.c |  85 ++++++++++
 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 +++++
 11 files changed, 682 insertions(+)
 create mode 100644 arch/csky/abiv1/bswapdi.c
 create mode 100644 arch/csky/abiv1/bswapsi.c
 create mode 100644 arch/csky/abiv1/memcpy.S
 create mode 100644 arch/csky/abiv2/memcpy.c
 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
arch/csky/abiv1/bswapdi.c new file +18 -0
new file mode 100644
index 0000000..7346252
@@ -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);
arch/csky/abiv1/bswapsi.c new file +15 -0
new file mode 100644
index 0000000..21958ca
@@ -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);
+
arch/csky/abiv1/memcpy.S new file +344 -0

344 lines not on this page · raw message

arch/csky/abiv2/memcpy.c new file +43 -0

43 lines not on this page · raw message

arch/csky/include/asm/string.h new file +19 -0
new file mode 100644
index 0000000..2c4878b
@@ -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_ */
arch/csky/kernel/asm-offsets.c new file +85 -0

85 lines not on this page · raw message

arch/csky/kernel/cskyksyms.c new file +31 -0
new file mode 100644
index 0000000..3f13594
@@ -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);
arch/csky/kernel/platform.c new file +18 -0
new file mode 100644
index 0000000..f51654f
@@ -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);
+
+
arch/csky/kernel/power.c new file +31 -0
new file mode 100644
index 0000000..d35e882
@@ -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");
+}
+
+
arch/csky/lib/delay.c new file +40 -0
new file mode 100644
index 0000000..34766a4
@@ -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);
arch/csky/lib/memset.c new file +38 -0
new file mode 100644
index 0000000..b7897af
@@ -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;
+}
Signature · 1 line
2.7.4
maintainer
#49 lore raw

Re: [PATCH V2 13/19] csky: Library functions

Quoted 19 lines · Guo Ren
arch/csky/kernel/cskyksyms.c new file +12 -0
new file mode 100644
index 0000000..3f13594
@@ -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
+ */

arch/csky/kernel/cskyksyms.c line 22

Quoted 10 lines
arch/csky/kernel/cskyksyms.c new file +10 -0
+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);

It's better to avoid relying on libgcc here. Please use the CONFIG_GENERIC_LIB_ASHLDI3/ASHRDI3/LSHRDI3/etc helpers that we already have in the kernel.

Arnd

author
#50 lore raw

Re: [PATCH V2 13/19] csky: Library functions

Quoted 3 lines · Arnd Bergmann

It's better to avoid relying on libgcc here. Please use the CONFIG_GENERIC_LIB_ASHLDI3/ASHRDI3/LSHRDI3/etc helpers that we already have in the kernel.

Ok, I'll try

Guo Ren

author
#51 lore raw

PATCH v2 14/19 csky: User access

In reply to Guo Ren
---
 arch/csky/include/asm/uaccess.h | 397 ++++++++++++++++++++++++++++++++++++++++
 arch/csky/lib/usercopy.c        | 271 +++++++++++++++++++++++++++
 2 files changed, 668 insertions(+)
 create mode 100644 arch/csky/include/asm/uaccess.h
 create mode 100644 arch/csky/lib/usercopy.c
arch/csky/include/asm/uaccess.h new file +397 -0
new file mode 100644
index 0000000..81063c3
@@ -0,0 +1,397 @@
+// 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);
+
+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 */
arch/csky/lib/usercopy.c new file +271 -0

271 lines not on this page · raw message

Signature · 1 line
2.7.4
author
#52 lore raw

PATCH v2 15/19 csky: Debug and Ptrace GDB

In reply to Guo Ren
---
 arch/csky/include/uapi/asm/ptrace.h | 105 +++++++++++++
 arch/csky/kernel/dumpstack.c        |  65 ++++++++
 arch/csky/kernel/ptrace.c           | 288 ++++++++++++++++++++++++++++++++++++
 3 files changed, 458 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
arch/csky/include/uapi/asm/ptrace.h new file +105 -0
new file mode 100644
index 0000000..f5228dd
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef _CSKY_PTRACE_H
+#define _CSKY_PTRACE_H
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long	tls;
+	unsigned long	lr;
+	unsigned long	pc;
+	unsigned long	sr;
+	unsigned long	usp;
+
+	/*
+	 * a0, a1, a2, a3:
+	 * abiv1: r2, r3, r4, r5
+	 * abiv2: r0, r1, r2, r3
+	 */
+	unsigned long	orig_a0;
+	unsigned long	a0;
+	unsigned long	a1;
+	unsigned long	a2;
+	unsigned long	a3;
+
+	/*
+	 * ABIV2: r4 ~ r13
+	 * ABIV1: r6 ~ r14, r1
+	 */
+	unsigned long	regs[10];
+
+#if defined(__CSKYABIV2__)
+	/* r16 ~ r30 */
+	unsigned long	exregs[15];
+
+	unsigned long	rhi;
+	unsigned long	rlo;
+	unsigned long	pad; /* reserved */
+#endif
+};
+
+struct user_fp {
+	unsigned long	vr[64];
+	unsigned long	fcr;
+	unsigned long	fesr;
+	unsigned long	fid;
+	unsigned long	reserved;
+};
+
+/*
+ * 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
+};
+
+#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 user_stack_pointer(regs) ((regs)->usp)
+
+#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 */
arch/csky/kernel/dumpstack.c new file +65 -0

65 lines not on this page · raw message

arch/csky/kernel/ptrace.c new file +288 -0

288 lines not on this page · raw message

Signature · 1 line
2.7.4
author
#53 lore raw

PATCH v2 16/19 csky: SMP support

In reply to Guo Ren
---
 arch/csky/include/asm/smp.h |  26 +++++
 arch/csky/kernel/smp.c      | 256 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 282 insertions(+)
 create mode 100644 arch/csky/include/asm/smp.h
 create mode 100644 arch/csky/kernel/smp.c
arch/csky/include/asm/smp.h new file +26 -0
new file mode 100644
index 0000000..9a53abf
@@ -0,0 +1,26 @@
+#ifndef __ASM_CSKY_SMP_H
+#define __ASM_CSKY_SMP_H
+
+#include <linux/cpumask.h>
+#include <linux/irqreturn.h>
+#include <linux/threads.h>
+
+#ifdef CONFIG_SMP
+
+void __init setup_smp(void);
+
+void __init setup_smp_ipi(void);
+
+void __init enable_smp_ipi(void);
+
+void arch_send_call_function_ipi_mask(struct cpumask *mask);
+
+void arch_send_call_function_single_ipi(int cpu);
+
+void __init set_send_ipi(void (*func)(const unsigned long *, unsigned long));
+
+#define raw_smp_processor_id()	(current_thread_info()->cpu)
+
+#endif /* CONFIG_SMP */
+
+#endif /* __ASM_CSKY_SMP_H */
arch/csky/kernel/smp.c new file +256 -0

256 lines not on this page · raw message

Signature · 1 line
2.7.4
maintainer
#54 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 41 lines · Guo Ren
arch/csky/kernel/smp.c new file +41 -0
+static irqreturn_t handle_ipi(int irq, void *dev)
+{
+	unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits;
+
+	while (true) {
+		unsigned long ops;
+
+		/* Order bit clearing and data access. */
+		mb();
+
+		ops = xchg(pending_ipis, 0);
+		if (ops == 0)
+			return IRQ_HANDLED;
+
+		if (ops & (1 << IPI_RESCHEDULE))
+			scheduler_ipi();
+
+		if (ops & (1 << IPI_CALL_FUNC))
+			generic_smp_call_function_interrupt();
+
+		BUG_ON((ops >> IPI_MAX) != 0);
+
+		/* Order data access and bit testing. */
+		mb();
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void (*send_arch_ipi)(const unsigned long *mask, unsigned long irq) = NULL;
+
+void __init set_send_ipi(void (*func)(const unsigned long *, unsigned long))
+{
+	if (send_arch_ipi)
+		return;
+
+	send_arch_ipi = func;
+}
+
+static void
+send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)

arch/csky/kernel/smp.c line 86

Quoted 10 lines
arch/csky/kernel/smp.c new file +10 -0
+{
+	int i;
+
+	mb();
+	for_each_cpu(i, to_whom)
+		set_bit(operation, &ipi_data[i].bits);
+
+	mb();
+	send_arch_ipi(cpumask_bits(to_whom), IPI_IRQ);
+}

Please explain those mb()'s... I'm thinking you meant to use smp_mb().

But then for handle_ipi(), the xchg() should already imply all those. And the send_ipi_message() only needs the second.

author
#55 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 47 lines · Peter Zijlstra
Quoted 46 lines · Guo Ren
arch/csky/kernel/smp.c new file +46 -0
+static irqreturn_t handle_ipi(int irq, void *dev)
+{
+	unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits;
+
+	while (true) {
+		unsigned long ops;
+
+		/* Order bit clearing and data access. */
+		mb();
+
+		ops = xchg(pending_ipis, 0);
+		if (ops == 0)
+			return IRQ_HANDLED;
+
+		if (ops & (1 << IPI_RESCHEDULE))
+			scheduler_ipi();
+
+		if (ops & (1 << IPI_CALL_FUNC))
+			generic_smp_call_function_interrupt();
+
+		BUG_ON((ops >> IPI_MAX) != 0);
+
+		/* Order data access and bit testing. */
+		mb();
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void (*send_arch_ipi)(const unsigned long *mask, unsigned long irq) = NULL;
+
+void __init set_send_ipi(void (*func)(const unsigned long *, unsigned long))
+{
+	if (send_arch_ipi)
+		return;
+
+	send_arch_ipi = func;
+}
+
+static void
+send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
+{
+	int i;
+
+	mb();
+	for_each_cpu(i, to_whom)
Quoted 8 lines

arch/csky/kernel/smp.c line 86

Quoted 5 lines
arch/csky/kernel/smp.c new file +5 -0
+		set_bit(operation, &ipi_data[i].bits);
+
+	mb();
+	send_arch_ipi(cpumask_bits(to_whom), IPI_IRQ);
+}

Please explain those mb()'s... I'm thinking you meant to use smp_mb().

Yes, smp_mb(). Current smp_mb()&mb() is the same: sync.is.

In next version patch, I'll seperate smp_mb() and mb() and use ld/st.barrier instead of sync.is. Sync.is is expensive that it flush cpu's pipeline.

Quoted 1 line

But then for handle_ipi(), the xchg() should already imply all those.

Yes, approve.

Quoted 1 line

And the send_ipi_message() only needs the second.

Yes, approve.

Guo Ren

maintainer
#56 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 5 lines · Guo Ren
Quoted 1 line

Please explain those mb()'s... I'm thinking you meant to use smp_mb().

Yes, smp_mb(). Current smp_mb()&mb() is the same: sync.is.

In next version patch, I'll seperate smp_mb() and mb() and use ld/st.barrier instead of sync.is. Sync.is is expensive that it flush cpu's pipeline.

I'll second my own call for documentation, because now there's three memory ordering instructions:

"SYNC", "SYNC.IS" and "LD/ST.BARRIER"

None of which have yet been explained.

author
#57 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 8 lines · Peter Zijlstra
Quoted 5 lines · Guo Ren
Quoted 1 line

Please explain those mb()'s... I'm thinking you meant to use smp_mb().

Yes, smp_mb(). Current smp_mb()&mb() is the same: sync.is.

In next version patch, I'll seperate smp_mb() and mb() and use ld/st.barrier instead of sync.is. Sync.is is expensive that it flush cpu's pipeline.

Quoted 6 lines

I'll second my own call for documentation, because now there's three memory ordering instructions:

"SYNC", "SYNC.IS" and "LD/ST.BARRIER"

None of which have yet been explained.

In C-SKY there are:

sync:        completion barrier
sync.s:      completion barrier and shareable to other cores
sync.i:      completion barrier with flush cpu pipeline
sync.is:     completion barrier with flush cpu pipeline and shareable to other cores 
bar.brwarw:  ordering barrier for all load/store instructions before it
bar.brwarws: ordering barrier for all load/store instructions before it and shareable to other cores
bar.brar:    ordering barrier for all load       instructions before it
bar.brars:   ordering barrier for all load       instructions before it and shareable to other cores
bar.bwaw:    ordering barrier for all store      instructions before it
bar.bwaws:   ordering barrier for all store      instructions before it and shareable to other cores
#58 lore raw

Re: [PATCH V2 16/19] csky: SMP support

In reply to Guo Ren
Quoted 6 lines · Guo Ren
arch/csky/kernel/smp.c new file +6 -0
+static int csky_of_cpu(struct device_node *node)
+{
+	const char *status;
+	int cpu;
+
+	if (of_property_read_u32(node, "reg", &cpu))

arch/csky/kernel/smp.c line 159

Quoted 10 lines
arch/csky/kernel/smp.c new file +10 -0
+		goto error;
+
+	if (cpu >= NR_CPUS)
+		goto error;
+
+	if (of_property_read_string(node, "status", &status))
+		status = "enable";
+
+	if (strcmp(status, "disable") == 0)
+		goto error;

Please use of_device_is_available(node); "enable" is not a sensible value for the status property, and "disable" (rather than "disabled") is simply unusual.

Neither "enable" nor "disable" are correct values for the status property.

What is the value in the reg property, exactly? Is there a unique ID in hardware for each CPU in the system?

It would be good to document this, e.g. as arm does in Documentation/devicetree/bindings/arm/cpus.txt

Quoted 9 lines
arch/csky/kernel/smp.c new file +9 -0
+
+	return cpu;
+error:
+	return -ENODEV;
+}
+
+void __init setup_smp(void)
+{
+	struct device_node *node = NULL;

arch/csky/kernel/smp.c line 178

Quoted 10 lines
arch/csky/kernel/smp.c new file +10 -0
+	int cpu;
+
+	while ((node = of_find_node_by_type(node, "cpu"))) {
+		cpu = csky_of_cpu(node);
+		if (cpu >= 0) {
+			set_cpu_possible(cpu, true);
+			set_cpu_present(cpu, true);
+		}
+	}
+}

What happens if/when the value in the reg property is larger than NR_CPUS?

Quoted 12 lines
arch/csky/kernel/smp.c new file +12 -0
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
+{
+	unsigned int tmp;
+
+	secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE;
+
+	secondary_hint = mfcr("cr31");
+
+	secondary_ccr  = mfcr("cr18");
+
+	pr_info("%s: CPU%u\n", __func__, cpu);
+

arch/csky/kernel/smp.c line 208

Quoted 10 lines
arch/csky/kernel/smp.c new file +10 -0
+	tmp = mfcr("cr<29, 0>");
+	tmp |= 1 << cpu;
+	mtcr("cr<29, 0>", tmp);
+
+	while (!cpu_online(cpu));
+
+	secondary_stack = 0;
+
+	return 0;
+}

I don't see a start address being setup here, so I assume that CPUs branch to a fixed address out-of-reset. Does that mean that the kernel has to be loaded at a particular physical address on a given platform?

Thanks,
Mark.

author
#59 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 10 lines · Mark Rutland

arch/csky/kernel/smp.c line 159

Quoted 8 lines
arch/csky/kernel/smp.c new file +8 -0
+	if (cpu >= NR_CPUS)
+		goto error;
+
+	if (of_property_read_string(node, "status", &status))
+		status = "enable";
+
+	if (strcmp(status, "disable") == 0)
+		goto error;

Please use of_device_is_available(node);

Ok.

Quoted 4 lines

"enable" is not a sensible value for
the status property, and "disable" (rather than "disabled") is simply unusual.

Neither "enable" nor "disable" are correct values for the status property.

	cpus {
		#address-cells = <1>;
		#size-cells = <0>;
		cpu@0 {
			device_type = "cpu";
			reg = <0>;
			status = "on";
		};

		cpu@1 {
			device_type = "cpu";
			reg = <1>;
			status = "off";
		};
	};
Quoted 1 line

What is the value in the reg property, exactly?

See above, I'll remove the reg property and it's no use.

Quoted 2 lines

Is there a unique ID in
hardware for each CPU in the system?

There is no unique ID in current CPU: ck860.

Quoted 3 lines

It would be good to document this, e.g. as arm does in Documentation/devicetree/bindings/arm/cpus.txt

Ok.

Quoted 13 lines
Quoted 13 lines
arch/csky/kernel/smp.c new file +13 -0
+
+	return cpu;
+error:
+	return -ENODEV;
+}
+
+void __init setup_smp(void)
+{
+	struct device_node *node = NULL;
+	int cpu;
+
+	while ((node = of_find_node_by_type(node, "cpu"))) {
+		cpu = csky_of_cpu(node);
Quoted 8 lines

arch/csky/kernel/smp.c line 178

Quoted 6 lines
arch/csky/kernel/smp.c new file +6 -0
+		if (cpu >= 0) {
+			set_cpu_possible(cpu, true);
+			set_cpu_present(cpu, true);
+		}
+	}
+}

What happens if/when the value in the reg property is larger than NR_CPUS?

Bug. I'll add NR_CPUS limit.

Quoted 18 lines
Quoted 18 lines
arch/csky/kernel/smp.c new file +18 -0
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
+{
+	unsigned int tmp;
+
+	secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE;
+
+	secondary_hint = mfcr("cr31");
+
+	secondary_ccr  = mfcr("cr18");
+
+	pr_info("%s: CPU%u\n", __func__, cpu);
+
+	tmp = mfcr("cr<29, 0>");
+	tmp |= 1 << cpu;
+	mtcr("cr<29, 0>", tmp);
+
+	while (!cpu_online(cpu));
+
Quoted 8 lines

arch/csky/kernel/smp.c line 208

Quoted 4 lines
arch/csky/kernel/smp.c new file +4 -0
+	secondary_stack = 0;
+
+	return 0;
+}

I don't see a start address being setup here, so I assume that CPUs branch to a fixed address out-of-reset. Does that mean that the kernel has to be loaded at a particular physical address on a given platform?

No, not a fixed address. I put it arch/csky/kernel/traps.c:79-83 trap_init()

#ifdef CONFIG_SMP
	mtcr("cr<28, 0>", virt_to_phys(vec_base));

	VEC_INIT(VEC_RESET, (void *)virt_to_phys(_start_smp_secondary));

#endi

Guo Ren

#60 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 18 lines · Guo Ren
Quoted 10 lines · Mark Rutland

arch/csky/kernel/smp.c line 159

Quoted 8 lines
arch/csky/kernel/smp.c new file +8 -0
+	if (cpu >= NR_CPUS)
+		goto error;
+
+	if (of_property_read_string(node, "status", &status))
+		status = "enable";
+
+	if (strcmp(status, "disable") == 0)
+		goto error;

Please use of_device_is_available(node);

Ok.

Quoted 4 lines

"enable" is not a sensible value for
the status property, and "disable" (rather than "disabled") is simply unusual.

Neither "enable" nor "disable" are correct values for the status property.

Quoted 15 lines
	cpus {
		#address-cells = <1>;
		#size-cells = <0>;
		cpu@0 {
			device_type = "cpu";
			reg = <0>;
			status = "on";
		};

		cpu@1 {
			device_type = "cpu";
			reg = <1>;
			status = "off";
		};
	};

Neither "on" nor "off" are standard status values either.

Please see the devicetree spec [1], section 2.3.4. Valid values are:

* "okay" // equivalent to no status property present
* "disabled"
* "fail"
* "fail-sss"

Quoted 6 lines
Quoted 1 line

What is the value in the reg property, exactly?

See above, I'll remove the reg property and it's no use.

Quoted 2 lines

Is there a unique ID in
hardware for each CPU in the system?

There is no unique ID in current CPU: ck860.

I'm a bit confused. You write (1 << cpu) into cv<29, 0>, to enable a particular CPU, so I assume that bit uniquely identifies a CPU, and therefore the reg is some unique ID for the CPU.

[...]

Quoted 26 lines
Quoted 18 lines
Quoted 18 lines
arch/csky/kernel/smp.c new file +18 -0
+int __cpu_up(unsigned int cpu, struct task_struct *tidle)
+{
+	unsigned int tmp;
+
+	secondary_stack = (unsigned int)tidle->stack + THREAD_SIZE;
+
+	secondary_hint = mfcr("cr31");
+
+	secondary_ccr  = mfcr("cr18");
+
+	pr_info("%s: CPU%u\n", __func__, cpu);
+
+	tmp = mfcr("cr<29, 0>");
+	tmp |= 1 << cpu;
+	mtcr("cr<29, 0>", tmp);
+
+	while (!cpu_online(cpu));
+
Quoted 8 lines

arch/csky/kernel/smp.c line 208

Quoted 4 lines
arch/csky/kernel/smp.c new file +4 -0
+	secondary_stack = 0;
+
+	return 0;
+}

I don't see a start address being setup here, so I assume that CPUs branch to a fixed address out-of-reset. Does that mean that the kernel has to be loaded at a particular physical address on a given platform?

Quoted 7 lines

No, not a fixed address. I put it arch/csky/kernel/traps.c:79-83 trap_init()

#ifdef CONFIG_SMP
	mtcr("cr<28, 0>", virt_to_phys(vec_base));

	VEC_INIT(VEC_RESET, (void *)virt_to_phys(_start_smp_secondary));

#endi

I see.

Is this SMP bringup mechanism architectual, or are you likely to need another mechanism to turn on CPUs on future chips?

You probably want to use an enable-method property to describe this.

Thanks,
Mark.

[1] https://www.devicetree.org/specifications/

author
#61 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 6 lines · Mark Rutland

Please see the devicetree spec [1], section 2.3.4. Valid values are:

* "okay" // equivalent to no status property present
* "disabled"
* "fail"
* "fail-sss"

Nice tip, thx.

Quoted 2 lines

I'm a bit confused. You write (1 << cpu) into cv<29, 0>, to enable a particular CPU, so I assume that bit uniquely identifies a CPU,

Yes, you're right and cr<29, 0>'s bit uniquely identifies a cpu.

Quoted 2 lines

and
therefore the reg is some unique ID for the CPU.

static int csky_of_cpu(struct device_node *node)

{
	const char *status;

	if (of_property_read_string(node, "status", &status))
		status = "okay";

	if (strcmp(status, "disabled") == 0)
		goto error;

	return 1;
error:
	return 0;
}

void __init setup_smp(void)

{
	struct device_node *node = NULL;
	int i = 0;

	while ((node = of_find_node_by_type(node, "cpu"))) {
		if (!csky_of_cpu(node))
			continue;

		set_cpu_possible(i, true);
		set_cpu_present(i, true);

		i++;
	}
}

Hmm?

No <reg> in next version patch, it's no use.

Quoted 4 lines

I see.

Is this SMP bringup mechanism architectual, or are you likely to need another mechanism to turn on CPUs on future chips?

It's the only SMP bringup mechanism architectual for C-SKY SMP. There is no another way in future and SOC vendor couldn't change it.

Quoted 1 line

You probably want to use an enable-method property to describe this.

No, thx.

Guo Ren

#62 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 16 lines · Guo Ren
Quoted 6 lines · Mark Rutland

Please see the devicetree spec [1], section 2.3.4. Valid values are:

* "okay" // equivalent to no status property present
* "disabled"
* "fail"
* "fail-sss"

Nice tip, thx.

Quoted 2 lines

I'm a bit confused. You write (1 << cpu) into cv<29, 0>, to enable a particular CPU, so I assume that bit uniquely identifies a CPU,

Yes, you're right and cr<29, 0>'s bit uniquely identifies a cpu.

Quoted 2 lines

and
therefore the reg is some unique ID for the CPU.

static int csky_of_cpu(struct device_node *node)

Quoted 13 lines
{
	const char *status;

	if (of_property_read_string(node, "status", &status))
		status = "okay";

	if (strcmp(status, "disabled") == 0)
		goto error;

	return 1;
error:
	return 0;
}

Please don't open-code this. Use of_device_is_available(), which checks the status property itself. e.g.

void __init setup_smp(void)

{
	struct device_node *node = NULL;

	while ((node = of_find_node_by_type(node, "cpu"))) {
		if (!of_device_is_available(node))
			continue;

		...
	}
}
Quoted 15 lines

void __init setup_smp(void)

{
	struct device_node *node = NULL;
	int i = 0;

	while ((node = of_find_node_by_type(node, "cpu"))) {
		if (!csky_of_cpu(node))
			continue;

		set_cpu_possible(i, true);
		set_cpu_present(i, true);

		i++;
	}
}
Quoted 3 lines

Hmm?

No <reg> in next version patch, it's no use.

Please use the reg property, you need it to describe which particular CPUs are available.

You probably also want a mapping from Linux logical CPU id to your physical CPU id, and a sanity check on this. See arm64 for an example.

Quoted 9 lines
Quoted 4 lines

I see.

Is this SMP bringup mechanism architectual, or are you likely to need another mechanism to turn on CPUs on future chips?

It's the only SMP bringup mechanism architectual for C-SKY SMP. There is no another way in future and SOC vendor couldn't change it.

Quoted 1 line

You probably want to use an enable-method property to describe this.

No, thx.

Fair enough.

Thanks,
Mark.

author
#63 lore raw

Re: [PATCH V2 16/19] csky: SMP support

Quoted 4 lines · Mark Rutland

Please don't open-code this. Use of_device_is_available(), which checks the status property itself. e.g.

void __init setup_smp(void)

Quoted 10 lines
{
	struct device_node *node = NULL;

	while ((node = of_find_node_by_type(node, "cpu"))) {
		if (!of_device_is_available(node))
			continue;

		...
	}
}

Ok, approve.

Quoted 5 lines

Please use the reg property, you need it to describe which particular CPUs are available.

You probably also want a mapping from Linux logical CPU id to your physical CPU id, and a sanity check on this. See arm64 for an example.

Yes, you are right. Reg property could determine which bit of CPU in cr<0, 29> could be booted.

Thx for the tips.

Guo Ren

author
#64 lore raw

PATCH v2 17/19 csky: Misc headers

In reply to Guo Ren
---
 arch/csky/abiv1/inc/abi/reg_ops.h      |  47 ++++++
 arch/csky/abiv1/inc/abi/regdef.h       |  15 ++
 arch/csky/abiv2/inc/abi/reg_ops.h      |  38 +++++
 arch/csky/abiv2/inc/abi/regdef.h       |  15 ++
 arch/csky/include/asm/bitops.h         | 277 +++++++++++++++++++++++++++++++++
 arch/csky/include/asm/checksum.h       |  77 +++++++++
 arch/csky/include/asm/reg_ops.h        |  16 ++
 arch/csky/include/uapi/asm/byteorder.h |  14 ++
 8 files changed, 499 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/reg_ops.h
 create mode 100644 arch/csky/abiv2/inc/abi/regdef.h
 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/reg_ops.h
 create mode 100644 arch/csky/include/uapi/asm/byteorder.h
arch/csky/abiv1/inc/abi/reg_ops.h new file +47 -0
new file mode 100644
index 0000000..7c31ac3
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ABI_REG_OPS_H
+#define __ABI_REG_OPS_H
+#include <asm/reg_ops.h>
+
+#define cprcr(reg)					\
+({							\
+	unsigned int tmp;				\
+	asm volatile("cprcr %0, "reg"\n":"=b"(tmp));	\
+	tmp;						\
+})
+
+#define cpwcr(reg, val)					\
+({							\
+	asm volatile("cpwcr %0, "reg"\n"::"b"(val));	\
+})
+
+static inline unsigned int mfcr_hint(void)
+{
+	return mfcr("cr30");
+}
+
+static inline unsigned int mfcr_msa0(void)
+{
+	return cprcr("cpcr30");
+}
+
+static inline void mtcr_msa0(unsigned int value)
+{
+	cpwcr("cpcr30", value);
+}
+
+static inline unsigned int mfcr_msa1(void)
+{
+	return cprcr("cpcr31");
+}
+
+static inline void mtcr_msa1(unsigned int value)
+{
+	cpwcr("cpcr31", value);
+}
+
+static inline unsigned int mfcr_ccr2(void){return 0;}
+
+#endif /* __ABI_REG_OPS_H */
+
arch/csky/abiv1/inc/abi/regdef.h new file +15 -0
new file mode 100644
index 0000000..0c3596d
@@ -0,0 +1,15 @@
+// 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 regs_syscallid(regs) regs->regs[9]
+
+#define DEFAULT_PSR_VALUE	0x8f000000
+
+#define SYSTRACE_SAVENUM	2
+
+#endif /* __ASM_CSKY_REGDEF_H */
arch/csky/abiv2/inc/abi/reg_ops.h new file +38 -0
new file mode 100644
index 0000000..a8b2a52
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
+#ifndef __ABI_REG_OPS_H
+#define __ABI_REG_OPS_H
+#include <asm/reg_ops.h>
+
+static inline unsigned int mfcr_hint(void)
+{
+	return mfcr("cr31");
+}
+
+static inline unsigned int mfcr_ccr2(void)
+{
+	return mfcr("cr23");
+}
+
+static inline unsigned int mfcr_msa0(void)
+{
+	return mfcr("cr<30, 15>");
+}
+
+static inline void mtcr_msa0(unsigned int value)
+{
+	mtcr("cr<30, 15>", value);
+}
+
+static inline unsigned int mfcr_msa1(void)
+{
+	return mfcr("cr<31, 15>");
+}
+
+static inline void mtcr_msa1(unsigned int value)
+{
+	mtcr("cr<31, 15>", value);
+}
+
+#endif /* __ABI_REG_OPS_H */
+
arch/csky/abiv2/inc/abi/regdef.h new file +15 -0
new file mode 100644
index 0000000..2c36d60
@@ -0,0 +1,15 @@
+// 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 regs_syscallid(regs) regs->regs[3]
+
+#define DEFAULT_PSR_VALUE	0x8f000200
+
+#define SYSTRACE_SAVENUM	5
+
+#endif /* __ASM_CSKY_REGDEF_H */
arch/csky/include/asm/bitops.h new file +277 -0

277 lines not on this page · raw message

arch/csky/include/asm/checksum.h new file +77 -0

77 lines not on this page · raw message

arch/csky/include/asm/reg_ops.h new file +16 -0
new file mode 100644
index 0000000..6963e5a
@@ -0,0 +1,16 @@
+#ifndef __ASM_REGS_OPS_H
+#define __ASM_REGS_OPS_H
+
+#define mfcr(reg)					\
+({							\
+	unsigned int tmp;				\
+	asm volatile("mfcr %0, "reg"\n":"=r"(tmp));	\
+	tmp;						\
+})
+
+#define mtcr(reg, val)					\
+({							\
+	asm volatile("mtcr %0, "reg"\n"::"r"(val));	\
+})
+
+#endif /* __ASM_REGS_OPS_H */
arch/csky/include/uapi/asm/byteorder.h new file +14 -0
new file mode 100644
index 0000000..d254522
@@ -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 */
Signature · 1 line
2.7.4
author
#65 lore raw

PATCH v2 18/19 clocksource: add C-SKY clocksource drivers

In reply to Guo Ren
---
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/timer-csky-v1.c      | 169 +++++++++++++++++++++++++++++++
 drivers/clocksource/timer-nationalchip.c | 165 ++++++++++++++++++++++++++++++
 3 files changed, 335 insertions(+)
 create mode 100644 drivers/clocksource/timer-csky-v1.c
 create mode 100644 drivers/clocksource/timer-nationalchip.c
drivers/clocksource/Makefile +1 -0
index d6dec44..bbc567b 100644
@@ -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-csky-v1.o timer-nationalchip.o
drivers/clocksource/timer-csky-v1.c new file +169 -0

169 lines not on this page · raw message

drivers/clocksource/timer-nationalchip.c new file +165 -0

165 lines not on this page · raw message

Signature · 1 line
2.7.4
#66 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

On Mon, 2 Jul 2018, Guo Ren wrote:

-EEMPTYCHANGELOG

drivers/clocksource/timer-csky-v1.c line 2

Quoted 6 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.

newline please

Quoted 7 lines
drivers/clocksource/timer-csky-v1.c new file +7 -0
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched_clock.h>
+#include <linux/cpu.h>
+#include <asm/reg_ops.h>
+
+#include "timer-of.h"

drivers/clocksource/timer-csky-v1.c line 19

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+
+#define PTIM_CTLR	"cr<0, 14>"
+#define PTIM_TSR	"cr<1, 14>"
+#define PTIM_CCVR_HI	"cr<2, 14>"
+#define PTIM_CCVR_LO	"cr<3, 14>"
+#define PTIM_LVR	"cr<6, 14>"
+
+#define BITS_CSKY_TIMER	56
+
+DECLARE_PER_CPU(struct timer_of, csky_to);

static?

drivers/clocksource/timer-csky-v1.c line 32

Quoted 13 lines
drivers/clocksource/timer-csky-v1.c new file +13 -0
+
+static int csky_timer_irq;
+static int csky_timer_rate;
+
+static inline u64 get_ccvr(void)
+{
+	u32 lo, hi, t;
+
+	do {
+		hi = mfcr(PTIM_CCVR_HI);
+		lo = mfcr(PTIM_CCVR_LO);
+		t  = mfcr(PTIM_CCVR_HI);
+	} while(t != hi);

No idea which frequency this timer ticks at, but if the 32 bit wrap does not come too fast, then you really should avoid that loop. That function is called very frequently.

drivers/clocksource/timer-csky-v1.c line 76

Quoted 5 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+	return ((u64)hi << 32) | lo;
+}
+
 
+DEFINE_PER_CPU(struct timer_of, csky_to) = {

static

Quoted 6 lines
drivers/clocksource/timer-csky-v1.c new file +6 -0
+	.flags = TIMER_OF_CLOCK | TIMER_OF_IRQ,
+
+	.clkevt = {
+		.name = "C-SKY SMP Timer V1",
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_ONESHOT,

drivers/clocksource/timer-csky-v1.c line 92

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+		.set_state_shutdown		= csky_timer_shutdown,
+		.set_state_oneshot		= csky_timer_oneshot,
+		.set_state_oneshot_stopped	= csky_timer_oneshot_stopped,
+		.set_next_event			= csky_timer_set_next_event,
+	},
+
+	.of_irq = {
+		.handler = timer_interrupt,
+		.flags = IRQF_TIMER,
+		.percpu = 1,

This is inconsistent. You made it half tabular and half not. Please use tabular style consistently.

drivers/clocksource/timer-csky-v1.c line 96

Quoted 4 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+	},
+};
+
+/*** clock event for percpu ***/

Please refrain from inventing new horrible comment styles.

Quoted 27 lines
drivers/clocksource/timer-csky-v1.c new file +27 -0
+static int csky_timer_starting_cpu(unsigned int cpu)
+{
+	struct timer_of *to = this_cpu_ptr(&csky_to);
+
+	to->clkevt.cpumask = cpumask_of(smp_processor_id());
+
+	clockevents_config_and_register(&to->clkevt, csky_timer_rate, 0, ULONG_MAX);
+
+	enable_percpu_irq(csky_timer_irq, 0);
+
+	return 0;
+}
+
+static int csky_timer_dying_cpu(unsigned int cpu)
+{
+	disable_percpu_irq(csky_timer_irq);
+
+	return 0;
+}
+
+/*** clock source ***/
+static u64 sched_clock_read(void)
+{
+	return get_ccvr();
+}
+
+static u64 clksrc_read(struct clocksource *c)

drivers/clocksource/timer-csky-v1.c line 133

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+{
+	return get_ccvr();
+}
+
+struct clocksource csky_clocksource = {
+	.name = "csky_timer_v1_clksrc",
+	.rating = 400,
+	.mask = CLOCKSOURCE_MASK(BITS_CSKY_TIMER),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+	.read = clksrc_read,

tabular style please

Quoted 15 lines
drivers/clocksource/timer-csky-v1.c new file +15 -0
+};
+
+static void csky_clksrc_init(void)
+{
+	clocksource_register_hz(&csky_clocksource, csky_timer_rate);
+
+	sched_clock_register(sched_clock_read, BITS_CSKY_TIMER, csky_timer_rate);
+}
+
+static int __init csky_timer_v1_init(struct device_node *np)
+{
+	int ret;
+	struct timer_of *to = this_cpu_ptr(&csky_to);
+
+	ret = timer_of_init(np, to);

drivers/clocksource/timer-csky-v1.c line 158

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+	if (ret)
+		return ret;
+
+	csky_timer_irq = to->of_irq.irq;
+	csky_timer_rate = timer_of_rate(to);
+
+	ret = cpuhp_setup_state(CPUHP_AP_DUMMY_TIMER_STARTING,
+				"clockevents/csky/timer:starting",
+				csky_timer_starting_cpu,
+				csky_timer_dying_cpu);

Oh no. Just picking a random hotplug event is not how it works. Add your own please and make sure it's at the proper place.

Quoted 4 lines

+++ b/drivers/clocksource/timer-nationalchip.c

drivers/clocksource/timer-csky-v1.c new file +2 -0
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.

...

drivers/clocksource/timer-csky-v1.c

Quoted 5 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+#include <linux/init.h>
 
+static irqreturn_t timer_interrupt(int irq, void *dev)
+{
+	struct clock_event_device *ce = (struct clock_event_device *) dev;

Pointless type cast.

Quoted 17 lines
drivers/clocksource/timer-csky-v1.c new file +16 -0
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	writel_relaxed(STATUS_clr, base + TIMER_STATUS);
+
+	ce->event_handler(ce);
+
+	return IRQ_HANDLED;
+}
 
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+	.clkevt = {
+		.name = TIMER_NAME,
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC |
+			CLOCK_EVT_FEAT_ONESHOT,

drivers/clocksource/timer-csky-v1.c

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+		.set_state_shutdown	= nc_timer_shutdown,
+		.set_state_periodic	= nc_timer_set_periodic,
+		.set_next_event		= nc_timer_set_next_event,
+		.cpumask = cpu_possible_mask,
+	},
+
+	.of_irq = {
+		.handler = timer_interrupt,
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},

See above

Quoted 1 line

+};

Thanks,

tglx

author
#67 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

Quoted 1 line · Thomas Gleixner

-EEMPTYCHANGELOG

Ok

Quoted 4 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.

newline please

Ok

Quoted 5 lines

drivers/clocksource/timer-csky-v1.c line 19

Quoted 3 lines
drivers/clocksource/timer-csky-v1.c new file +3 -0
+#define BITS_CSKY_TIMER	56
+
+DECLARE_PER_CPU(struct timer_of, csky_to);

static?

Ok.

Quoted 10 lines
Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +9 -0
+
+static int csky_timer_irq;
+static int csky_timer_rate;
+
+static inline u64 get_ccvr(void)
+{
+	u32 lo, hi, t;
+
+	do {
Quoted 8 lines

drivers/clocksource/timer-csky-v1.c line 32

Quoted 4 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+		hi = mfcr(PTIM_CCVR_HI);
+		lo = mfcr(PTIM_CCVR_LO);
+		t  = mfcr(PTIM_CCVR_HI);
+	} while(t != hi);

No idea which frequency this timer ticks at, but if the 32 bit wrap does not come too fast, then you really should avoid that loop. That function is called very frequently.

0000006c <clksrc_read>:

		hi = mfcr(PTIM_CCVR_HI);
  6c:	c1c26023 	mfcr      	r3, cr<2, 14>
		lo = mfcr(PTIM_CCVR_LO);
  70:	c1c36021 	mfcr      	r1, cr<3, 14>
		t  = mfcr(PTIM_CCVR_HI);
  74:	c1c26022 	mfcr      	r2, cr<2, 14>
	} while(t != hi);

78: 648e cmpne r3, r2
7a: 0bf9 bt 0x6c // 6c <clksrc_read>

When two read cr<2, 14> is not equal, we'll retry. So only when CCVR_LO is at 0xffffffff between the two read of CCVR_HI. That's very very small probability event for "bt 0x6c".

Don't worry about the "do {...} whie(t != hi)", it's no performance issue.

Quoted 3 lines
Quoted 1 line

+DEFINE_PER_CPU(struct timer_of, csky_to) = {

static

Ok.

Quoted 11 lines
Quoted 11 lines
drivers/clocksource/timer-csky-v1.c new file +11 -0
+	.flags = TIMER_OF_CLOCK | TIMER_OF_IRQ,
+
+	.clkevt = {
+		.name = "C-SKY SMP Timer V1",
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown		= csky_timer_shutdown,
+		.set_state_oneshot		= csky_timer_oneshot,
+		.set_state_oneshot_stopped	= csky_timer_oneshot_stopped,
+		.set_next_event			= csky_timer_set_next_event,
+	},
Quoted 8 lines

drivers/clocksource/timer-csky-v1.c line 92

Quoted 5 lines
drivers/clocksource/timer-csky-v1.c new file +5 -0
+
+	.of_irq = {
+		.handler = timer_interrupt,
+		.flags = IRQF_TIMER,
+		.percpu = 1,

This is inconsistent. You made it half tabular and half not. Please use tabular style consistently.

Ok.

	.clkevt = {
		.name				= "C-SKY SMP Timer V1",
		.features			= CLOCK_EVT_FEAT_PERCPU |
						  CLOCK_EVT_FEAT_ONESHOT,
		.rating				= 300,
		.set_state_shutdown		= csky_timer_shutdown,
		.set_state_oneshot		= csky_timer_oneshot,
		.set_state_oneshot_stopped	= csky_timer_oneshot_stopped,
		.set_next_event			= csky_timer_set_next_event,
	},

	.of_irq = {
		.handler			= timer_interrupt,
		.flags				= IRQF_TIMER,
		.percpu				= 1,
Quoted 3 lines
Quoted 1 line

+/*** clock event for percpu ***/

Please refrain from inventing new horrible comment styles.

Ok.
/* clock event for percpu */

Quoted 8 lines

drivers/clocksource/timer-csky-v1.c line 133

Quoted 6 lines
drivers/clocksource/timer-csky-v1.c new file +6 -0
+struct clocksource csky_clocksource = {
+	.name = "csky_timer_v1_clksrc",
+	.rating = 400,
+	.mask = CLOCKSOURCE_MASK(BITS_CSKY_TIMER),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+	.read = clksrc_read,

tabular style please

Ok.

Quoted 7 lines

drivers/clocksource/timer-csky-v1.c line 158

Quoted 4 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+	ret = cpuhp_setup_state(CPUHP_AP_DUMMY_TIMER_STARTING,
+				"clockevents/csky/timer:starting",
+				csky_timer_starting_cpu,
+				csky_timer_dying_cpu);

Oh no. Just picking a random hotplug event is not how it works. Add your own please and make sure it's at the proper place.

like this?
include/linux/cpuhotplug.h:
CPUHP_AP_KVM_ARM_TIMER_STARTING,
+ CPUHP_AP_CSKY_TIMER_STARTING,

	/* Must be the last timer callback */
	CPUHP_AP_DUMMY_TIMER_STARTING,
Quoted 3 lines

drivers/clocksource/timer-nationalchip.c line 30

Quoted 1 line
drivers/clocksource/timer-nationalchip.c new file +1 -0
+	struct clock_event_device *ce = (struct clock_event_device *) dev;

Pointless type cast.

Ok.
struct clock_event_device *ce = dev;

Quoted 4 lines

drivers/clocksource/timer-nationalchip.c line 99

Quoted 2 lines
drivers/clocksource/timer-nationalchip.c new file +2 -0
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},

See above

Ok, tabular

Guo Ren

#68 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

Quoted 23 lines · Guo Ren
Quoted 5 lines · Thomas Gleixner
Quoted 5 lines
drivers/clocksource/timer-csky-v1.c new file +5 -0
+static inline u64 get_ccvr(void)
+{
+	u32 lo, hi, t;
+
+	do {
Quoted 8 lines

drivers/clocksource/timer-csky-v1.c line 32

Quoted 4 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+		hi = mfcr(PTIM_CCVR_HI);
+		lo = mfcr(PTIM_CCVR_LO);
+		t  = mfcr(PTIM_CCVR_HI);
+	} while(t != hi);

No idea which frequency this timer ticks at, but if the 32 bit wrap does not come too fast, then you really should avoid that loop. That function is called very frequently.

0000006c <clksrc_read>:

		hi = mfcr(PTIM_CCVR_HI);
  6c:	c1c26023 	mfcr      	r3, cr<2, 14>
		lo = mfcr(PTIM_CCVR_LO);
  70:	c1c36021 	mfcr      	r1, cr<3, 14>
		t  = mfcr(PTIM_CCVR_HI);
  74:	c1c26022 	mfcr      	r2, cr<2, 14>
	} while(t != hi);
Quoted 8 lines

78: 648e cmpne r3, r2
7a: 0bf9 bt 0x6c // 6c <clksrc_read>

When two read cr<2, 14> is not equal, we'll retry. So only when CCVR_LO is at 0xffffffff between the two read of CCVR_HI. That's very very small probability event for "bt 0x6c".

Don't worry about the "do {...} whie(t != hi)", it's no performance issue.

But _three_ mfcr plus a conditional jump which _cannot_ be predicted are a performance issue. When you can replace that with a single mfcr, then you win a lot, really. The time keeping and the sched clock code can handle that nicely unless you really have fast wrap arounds on the LO word.

Thanks,

tglx

author
#69 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

Quoted 31 lines · Thomas Gleixner
Quoted 30 lines · Guo Ren
Quoted 5 lines · Thomas Gleixner
Quoted 5 lines
drivers/clocksource/timer-csky-v1.c new file +5 -0
+static inline u64 get_ccvr(void)
+{
+	u32 lo, hi, t;
+
+	do {
Quoted 8 lines

drivers/clocksource/timer-csky-v1.c line 32

Quoted 4 lines
drivers/clocksource/timer-csky-v1.c new file +4 -0
+		hi = mfcr(PTIM_CCVR_HI);
+		lo = mfcr(PTIM_CCVR_LO);
+		t  = mfcr(PTIM_CCVR_HI);
+	} while(t != hi);

No idea which frequency this timer ticks at, but if the 32 bit wrap does not come too fast, then you really should avoid that loop. That function is called very frequently.

0000006c <clksrc_read>:

		hi = mfcr(PTIM_CCVR_HI);
  6c:	c1c26023 	mfcr      	r3, cr<2, 14>
		lo = mfcr(PTIM_CCVR_LO);
  70:	c1c36021 	mfcr      	r1, cr<3, 14>
		t  = mfcr(PTIM_CCVR_HI);
  74:	c1c26022 	mfcr      	r2, cr<2, 14>
	} while(t != hi);

78: 648e cmpne r3, r2
7a: 0bf9 bt 0x6c // 6c <clksrc_read>

When two read cr<2, 14> is not equal, we'll retry. So only when CCVR_LO is at 0xffffffff between the two read of CCVR_HI. That's very very small probability event for "bt 0x6c".

Quoted 6 lines
Quoted 1 line

Don't worry about the "do {...} whie(t != hi)", it's no performance issue.

But _three_ mfcr plus a conditional jump which _cannot_ be predicted are a performance issue. When you can replace that with a single mfcr, then you win a lot, really. The time keeping and the sched clock code can handle that nicely unless you really have fast wrap arounds on the LO word.

Timer's frequency is about 50Mhz-100Mhz and LO word wrap arounds timer is about 42s ~ 84s.

Our Branch prediction buffer will let the CPU speculative execute continually. So the "bt" won't be the performance issue.

And I could modify it like this:

static inline u64 get_ccvr(void)

{
	u32 lo, hi, t;

	t  = mfcr(PTIM_CCVR_LO);
	hi = mfcr(PTIM_CCVR_HI);
	lo = mfcr(PTIM_CCVR_LO);

	if (lo < t) hi++;

	return ((u64)hi << 32) | lo;
}
	t  = mfcr(PTIM_CCVR_LO);
  50:	c1c36023 	mfcr      	r3, cr<3, 14>
	hi = mfcr(PTIM_CCVR_HI);
  54:	c1c26021 	mfcr      	r1, cr<2, 14>
	lo = mfcr(PTIM_CCVR_LO);
  58:	c1c3602c 	mfcr      	r12, cr<3, 14>
	if (lo < t) hi++;
  5c:	64f0      	cmphs      	r12, r3
  5e:	c4210c21 	incf      	r1, r1, 1
	return ((u64)hi << 32) | lo;

62: 3200 movi r2, 0

Hmm? (No jump at all)

Guo Ren

#70 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

In reply to Guo Ren

Hi Guo,

as you are introducing a new drivers, add a detailed changelog describing in details the timers.

Quoted 8 lines · Guo Ren
---
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/timer-csky-v1.c      | 169 +++++++++++++++++++++++++++++++
 drivers/clocksource/timer-nationalchip.c | 165 ++++++++++++++++++++++++++++++
 3 files changed, 335 insertions(+)
 create mode 100644 drivers/clocksource/timer-csky-v1.c
 create mode 100644 drivers/clocksource/timer-nationalchip.c

Provide two separates patches, one for each timer.

drivers/clocksource/Makefile obj-$(CONFIG_H8300_TMR16) += h8300_timer16.o · line 79

Quoted 9 lines
drivers/clocksource/Makefile +1 -0
index d6dec44..bbc567b 100644
@@ -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-csky-v1.o timer-nationalchip.o

Split this in two.

CONFIG_TIMER_CSKY += timer-csky.o

Note, no v1.

CONFIG_TIMER_NATCHIP += timer-natchip.o

And in the Kconfig add the silent timer option.

config TIMER_CSKY
bool

config TIMER_NATCHIP
bool

(If you want to keep the nationalchip name, I'm fine with that).

Quoted 18 lines
drivers/clocksource/timer-csky-v1.c new file +12 -0
new file mode 100644
index 0000000..f3a822a
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched_clock.h>
+#include <linux/cpu.h>
+#include <asm/reg_ops.h>
+
+#include "timer-of.h"
+
+#define PTIM_CTLR	"cr<0, 14>"
+#define PTIM_TSR	"cr<1, 14>"

drivers/clocksource/timer-csky-v1.c line 22

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+#define PTIM_CCVR_HI	"cr<2, 14>"
+#define PTIM_CCVR_LO	"cr<3, 14>"
+#define PTIM_LVR	"cr<6, 14>"
+
+#define BITS_CSKY_TIMER	56
+
+DECLARE_PER_CPU(struct timer_of, csky_to);
+
+static int csky_timer_irq;
+static int csky_timer_rate;

You can get the value from the timer-of in all the places it is needed.

Quoted 47 lines
drivers/clocksource/timer-csky-v1.c new file +47 -0
+static inline u64 get_ccvr(void)
+{
+	u32 lo, hi, t;
+
+	do {
+		hi = mfcr(PTIM_CCVR_HI);
+		lo = mfcr(PTIM_CCVR_LO);
+		t  = mfcr(PTIM_CCVR_HI);
+	} while(t != hi);
+
+	return ((u64)hi << 32) | lo;
+}
+
+static irqreturn_t timer_interrupt(int irq, void *dev)
+{
+	struct timer_of *to = this_cpu_ptr(&csky_to);
+
+	mtcr(PTIM_TSR, 0);
+
+	to->clkevt.event_handler(&to->clkevt);
+
+	return IRQ_HANDLED;
+}
+
+static int csky_timer_set_next_event(unsigned long delta, struct clock_event_device *ce)
+{
+	mtcr(PTIM_LVR, delta);
+
+	return 0;
+}
+
+static int csky_timer_shutdown(struct clock_event_device *ce)
+{
+	mtcr(PTIM_CTLR, 0);
+
+	return 0;
+}
+
+static int csky_timer_oneshot(struct clock_event_device *ce)
+{
+	mtcr(PTIM_CTLR, 1);
+
+	return 0;
+}
+
+static int csky_timer_oneshot_stopped(struct clock_event_device *ce)
+{

drivers/clocksource/timer-csky-v1.c line 80

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+	mtcr(PTIM_CTLR, 0);
+
+	return 0;
+}
+
+DEFINE_PER_CPU(struct timer_of, csky_to) = {
+	.flags = TIMER_OF_CLOCK | TIMER_OF_IRQ,
+
+	.clkevt = {
+		.name = "C-SKY SMP Timer V1",

If the node name is nice enough, you can discard this. See below TIMER_OF_DECLARE comment.

Quoted 7 lines
drivers/clocksource/timer-csky-v1.c new file +7 -0
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown		= csky_timer_shutdown,
+		.set_state_oneshot		= csky_timer_oneshot,
+		.set_state_oneshot_stopped	= csky_timer_oneshot_stopped,
+		.set_next_event			= csky_timer_set_next_event,
+	},

drivers/clocksource/timer-csky-v1.c line 99

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+
+	.of_irq = {
+		.handler = timer_interrupt,
+		.flags = IRQF_TIMER> +		.percpu = 1,> +	},
+};
+
+/*** clock event for percpu ***/
+static int csky_timer_starting_cpu(unsigned int cpu)
+{
+	struct timer_of *to = this_cpu_ptr(&csky_to);

per_cpu_ptr(&csky_to, cpu);

drivers/clocksource/timer-csky-v1.c line 101

Quoted 1 line
drivers/clocksource/timer-csky-v1.c new file +1 -0
+	to->clkevt.cpumask = cpumask_of(smp_processor_id());

cpumask_of(cpu); ?

drivers/clocksource/timer-csky-v1.c line 99

Quoted 2 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
+
+	clockevents_config_and_register(&to->clkevt, csky_timer_rate, 0, ULONG_MAX);

I suggest to choose something different than zero for the min_delta.

Quoted 15 lines
drivers/clocksource/timer-csky-v1.c new file +15 -0
+	enable_percpu_irq(csky_timer_irq, 0);
+
+	return 0;
+}
+
+static int csky_timer_dying_cpu(unsigned int cpu)
+{
+	disable_percpu_irq(csky_timer_irq);
+
+	return 0;
+}
+
+/*** clock source ***/
+static u64 sched_clock_read(void)
+{

drivers/clocksource/timer-csky-v1.c line 129

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+	return get_ccvr();
+}
+
+static u64 clksrc_read(struct clocksource *c)
+{
+	return get_ccvr();
+}
+
+struct clocksource csky_clocksource = {
+	.name = "csky_timer_v1_clksrc",

"csky"

Quoted 25 lines
drivers/clocksource/timer-csky-v1.c new file +25 -0
+	.rating = 400,
+	.mask = CLOCKSOURCE_MASK(BITS_CSKY_TIMER),
+	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+	.read = clksrc_read,
+};
+
+static void csky_clksrc_init(void)
+{
+	clocksource_register_hz(&csky_clocksource, csky_timer_rate);
+
+	sched_clock_register(sched_clock_read, BITS_CSKY_TIMER, csky_timer_rate);
+}
+
+static int __init csky_timer_v1_init(struct device_node *np)
+{
+	int ret;
+	struct timer_of *to = this_cpu_ptr(&csky_to);
+
+	ret = timer_of_init(np, to);
+	if (ret)
+		return ret;
+
+	csky_timer_irq = to->of_irq.irq;
+	csky_timer_rate = timer_of_rate(to);
+

drivers/clocksource/timer-csky-v1.c line 164

Quoted 10 lines
drivers/clocksource/timer-csky-v1.c new file +10 -0
+	ret = cpuhp_setup_state(CPUHP_AP_DUMMY_TIMER_STARTING,
+				"clockevents/csky/timer:starting",
+				csky_timer_starting_cpu,
+				csky_timer_dying_cpu);
+	if (ret) {
+		pr_err("%s: Failed to cpuhp_setup_state.\n", __func__);
+		return ret;
+	}
+
+	csky_clksrc_init();

inline the function here. It is not worth to add a function for a couple of lines which is called one time.

drivers/clocksource/timer-csky-v1.c line 161

Quoted 2 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
+
+	return ret;

return 0;

drivers/clocksource/timer-csky-v1.c line 163

Quoted 2 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
+}
+TIMER_OF_DECLARE(csky_timer_v1, "csky,timer-v1", csky_timer_v1_init);

Stick to the hardware name.

eg.

TIMER_OF_DECLARE(csky_610, "csky,ck610-timer", csky_timer_init); TIMER_OF_DECLARE(csky_807, "csky,ck807-timer", csky_timer_init);

(Beside /proc/interrupts will show the node name which states clearly what timer it is).

...

v1, v2, etc ... has no sense here.

Quoted 23 lines
drivers/clocksource/timer-csky-v1.c new file +1 -0
+
drivers/clocksource/timer-nationalchip.c new file +16 -0
new file mode 100644
index 0000000..8f4e1e5
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/sched_clock.h>
+
+#include "timer-of.h"
+
+#define TIMER_NAME	"nc_timer"
+#define TIMER_FREQ	1000000
+#define CLKSRC_OFFSET	0x40
+
+#define TIMER_STATUS	0x00
+#define TIMER_VALUE	0x04
+#define TIMER_CONTRL	0x10
+#define TIMER_CONFIG	0x20

drivers/clocksource/timer-nationalchip.c line 26

Quoted 10 lines
drivers/clocksource/timer-nationalchip.c new file +10 -0
+#define TIMER_DIV	0x24
+#define TIMER_INI	0x28
+
+#define STATUS_clr	BIT(0)
+
+#define CONTRL_rst	BIT(0)
+#define CONTRL_start	BIT(1)
+
+#define CONFIG_en	BIT(0)
+#define CONFIG_irq_en	BIT(1)

Prefix the macros with a shortened timer name and don't mix lower case and uppercase.

NC_ is too short, something like NATCHIP may be better.

drivers/clocksource/timer-nationalchip.c line 28

Quoted 2 lines
drivers/clocksource/timer-nationalchip.c new file +2 -0
+
+static irqreturn_t timer_interrupt(int irq, void *dev)

Fix the function name.

Quoted 48 lines
drivers/clocksource/timer-nationalchip.c new file +48 -0
+{
+	struct clock_event_device *ce = (struct clock_event_device *) dev;
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	writel_relaxed(STATUS_clr, base + TIMER_STATUS);
+
+	ce->event_handler(ce);
+
+	return IRQ_HANDLED;
+}
+
+static int nc_timer_set_periodic(struct clock_event_device *ce)
+{
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	/* reset */
+	writel_relaxed(CONTRL_rst, base + TIMER_CONTRL);
+
+	/* config the timeout value */
+	writel_relaxed(ULONG_MAX - timer_of_period(to_timer_of(ce)),
+		       base + TIMER_INI);
+
+	/* enable with irq and start */
+	writel_relaxed(CONFIG_en|CONFIG_irq_en, base + TIMER_CONFIG);
+	writel_relaxed(CONTRL_start, base + TIMER_CONTRL);
+
+	return 0;
+}
+
+static int nc_timer_set_next_event(unsigned long delta, struct clock_event_device *ce)
+{
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	/* use reset to pause timer */
+	writel_relaxed(CONTRL_rst, base + TIMER_CONTRL);
+
+	/* config next timeout value */
+	writel_relaxed(ULONG_MAX - delta, base + TIMER_INI);
+	writel_relaxed(CONTRL_start, base + TIMER_CONTRL);
+
+	return 0;
+}
+
+static int nc_timer_shutdown(struct clock_event_device *ce)
+{
+	void __iomem *base = timer_of_base(to_timer_of(ce));
+
+	writel_relaxed(0, base + TIMER_CONTRL);

drivers/clocksource/timer-nationalchip.c line 86

Quoted 10 lines
drivers/clocksource/timer-nationalchip.c new file +10 -0
+	writel_relaxed(0, base + TIMER_CONFIG);
+
+	return 0;
+}
+
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+	.clkevt = {
+		.name = TIMER_NAME,

Let the node name.

drivers/clocksource/timer-nationalchip.c line 92

Quoted 6 lines
drivers/clocksource/timer-nationalchip.c new file +6 -0
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC |
+			CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown	= nc_timer_shutdown,
+		.set_state_periodic	= nc_timer_set_periodic,
+		.set_next_event		= nc_timer_set_next_event,

set_oneshot ?

Quoted 13 lines
drivers/clocksource/timer-nationalchip.c new file +13 -0
+		.cpumask = cpu_possible_mask,
+	},
+
+	.of_irq = {
+		.handler = timer_interrupt,
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},
+};
+
+static u64 notrace nc_sched_clock_read(void)
+{
+	void __iomem *base;
+

drivers/clocksource/timer-nationalchip.c line 115

Quoted 10 lines
drivers/clocksource/timer-nationalchip.c new file +10 -0
+	base = timer_of_base(&to) + CLKSRC_OFFSET; 
+
+	return (u64) readl_relaxed(base + TIMER_VALUE);
+}
+
+static void nc_timer_set_div(void __iomem *base)
+{
+	unsigned int div;
+
+	div = timer_of_rate(&to)/TIMER_FREQ - 1;

space ' / '

Is it
(timer_of_rate(&to) / TIMER_FREQ) - 1
or
timer_of_rate(&to) / (TIMER_FREQ - 1)

?

Quoted 20 lines
drivers/clocksource/timer-nationalchip.c new file +20 -0
+
+	writel_relaxed(div, base + TIMER_DIV);
+}
+
+static void nc_clkevt_init(void __iomem *base)
+{
+	/* reset */
+	writel_relaxed(CONTRL_rst, base + TIMER_CONTRL);
+
+	/* reset config */
+	writel_relaxed(0, base + TIMER_CONFIG);
+
+	nc_timer_set_div(base);
+
+	clockevents_config_and_register(&to.clkevt, TIMER_FREQ, 1, ULONG_MAX);
+}
+
+static void nc_clksrc_init(void __iomem *base)
+{
+	writel_relaxed(CONTRL_rst, base + TIMER_CONTRL);

drivers/clocksource/timer-nationalchip.c line 145

Quoted 10 lines
drivers/clocksource/timer-nationalchip.c new file +10 -0
+
+	writel_relaxed(CONFIG_en, base + TIMER_CONFIG);
+
+	nc_timer_set_div(base);
+
+	writel_relaxed(0, base + TIMER_INI);
+	writel_relaxed(CONTRL_start, base + TIMER_CONTRL);
+
+	clocksource_mmio_init(base + TIMER_VALUE, "nationalchip", TIMER_FREQ, 200, 32,
+			      clocksource_mmio_readl_up);

return code check ?

Quoted 8 lines
drivers/clocksource/timer-nationalchip.c new file +8 -0
+	sched_clock_register(nc_sched_clock_read, 32, TIMER_FREQ);
+}
+
+static int __init nc_timer_init(struct device_node *np)
+{
+	int ret;
+
+	ret = timer_of_init(np, &to);

drivers/clocksource/timer-nationalchip.c line 164

Quoted 10 lines
drivers/clocksource/timer-nationalchip.c new file +10 -0
+	if (ret)
+		return ret;
+
+	nc_clkevt_init(timer_of_base(&to));
+
+	nc_clksrc_init(timer_of_base(&to) + CLKSRC_OFFSET);
+
+	return 0;
+}
+TIMER_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);

same comment than cksy timer.

Signature · 5 lines
 <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
author
#71 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

Quoted 4 lines · Daniel Lezcano
Quoted 2 lines
 create mode 100644 drivers/clocksource/timer-csky-v1.c
 create mode 100644 drivers/clocksource/timer-nationalchip.c

Provide two separates patches, one for each timer.

Ok.

Quoted 13 lines
Quoted 1 line

+obj-$(CONFIG_CSKY) += timer-csky-v1.o timer-nationalchip.o

Split this in two.

CONFIG_TIMER_CSKY += timer-csky.o

Note, no v1.

CONFIG_TIMER_NATCHIP += timer-natchip.o

And in the Kconfig add the silent timer option.

Quoted 7 lines

config TIMER_CSKY
bool

config TIMER_NATCHIP
bool

(If you want to keep the nationalchip name, I'm fine with that).

Ok, NATCHIP & timer-natchip :)

Quoted 4 lines

drivers/clocksource/timer-csky-v1.c line 22

Quoted 2 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
+static int csky_timer_irq;
+static int csky_timer_rate;

You can get the value from the timer-of in all the places it is needed.

Ok, I could remove them.

But in csky_timer_v1_init: ret = timer_of_init(np, to)
We only init 1th cpu's timer_of struct, and others just static inited by:

DEFINE_PER_CPU(struct timer_of, csky_to) = {
.flags = TIMER_OF_CLOCK | TIMER_OF_IRQ,

.clkevt = {
.name = "C-SKY SMP Timer V1",
.rating = 300,
.features = CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_ONESHOT,
.set_state_shutdown = csky_timer_shutdown,
.set_state_oneshot = csky_timer_oneshot,
.set_state_oneshot_stopped = csky_timer_oneshot_stopped,
.set_next_event = csky_timer_set_next_event,
},

.of_irq = {
.handler = timer_interrupt,
.flags = IRQF_TIMER,
.percpu = 1,
},
};

So I still need "for_each_cpu(cpu, cpu_possible_mask)" to init every csky_to ...

Quoted 6 lines

drivers/clocksource/timer-csky-v1.c line 80

Quoted 3 lines
drivers/clocksource/timer-csky-v1.c new file +3 -0
+
+	.clkevt = {
+		.name = "C-SKY SMP Timer V1",

If the node name is nice enough, you can discard this. See below TIMER_OF_DECLARE comment.

Ok, remove it :)

Quoted 5 lines

drivers/clocksource/timer-csky-v1.c line 99

Quoted 3 lines
drivers/clocksource/timer-csky-v1.c new file +3 -0
+static int csky_timer_starting_cpu(unsigned int cpu)
+{
+	struct timer_of *to = this_cpu_ptr(&csky_to);

per_cpu_ptr(&csky_to, cpu);

Ok, thx for the tip.

Quoted 3 lines

drivers/clocksource/timer-csky-v1.c line 101

Quoted 1 line
drivers/clocksource/timer-csky-v1.c new file +1 -0
+	to->clkevt.cpumask = cpumask_of(smp_processor_id());

cpumask_of(cpu); ?

Yes.

Quoted 3 lines

drivers/clocksource/timer-csky-v1.c line 103

Quoted 1 line
drivers/clocksource/timer-csky-v1.c new file +1 -0
+	clockevents_config_and_register(&to->clkevt, csky_timer_rate, 0, ULONG_MAX);

I suggest to choose something different than zero for the min_delta.

Agree, I'll use 1 :) clockevents_config_and_register(&to->clkevt, csky_timer_rate, 1, ULONG_MAX);

Quoted 4 lines

drivers/clocksource/timer-csky-v1.c line 129

Quoted 2 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
+struct clocksource csky_clocksource = {
+	.name = "csky_timer_v1_clksrc",

"csky"

struct clocksource csky_clocksource = {
	.name = "csky,mptimer",

Hmm?

Quoted 4 lines

drivers/clocksource/timer-csky-v1.c line 164

Quoted 1 line
drivers/clocksource/timer-csky-v1.c new file +1 -0
+	csky_clksrc_init();

inline the function here. It is not worth to add a function for a couple of lines which is called one time.

Ok

Quoted 9 lines
Quoted 1 line

+TIMER_OF_DECLARE(csky_timer_v1, "csky,timer-v1", csky_timer_v1_init);

Stick to the hardware name.

eg.

TIMER_OF_DECLARE(csky_610, "csky,ck610-timer", csky_timer_init); TIMER_OF_DECLARE(csky_807, "csky,ck807-timer", csky_timer_init);

Quoted 6 lines

(Beside /proc/interrupts will show the node name which states clearly what timer it is).

...

v1, v2, etc ... has no sense here.

TIMER_OF_DECLARE(csky_610, "nationachip,ck610-timer", natchip_timer_init); TIMER_OF_DECLARE(csky_807, "csky,ck807-timer", csky_timer_init); TIMER_OF_DECLARE(csky_810, "csky,ck810-timer", csky_timer_init); TIMER_OF_DECLARE(csky_860, "csky,ck860-timer", csky_timer_init); TIMER_OF_DECLARE(csky_860mp, "csky,ck860-mptimer", csky_mptimer_init);

Hmm?

Quoted 10 lines

drivers/clocksource/timer-nationalchip.c line 26

Quoted 7 lines
drivers/clocksource/timer-nationalchip.c new file +7 -0
+#define STATUS_clr	BIT(0)
+
+#define CONTRL_rst	BIT(0)
+#define CONTRL_start	BIT(1)
+
+#define CONFIG_en	BIT(0)
+#define CONFIG_irq_en	BIT(1)

Prefix the macros with a shortened timer name and don't mix lower case and uppercase.

Ok.

#define STATUS_CLR BIT(0)

#define CONTRL_RST BIT(0)
#define CONTRL_START BIT(1)

#define CONFIG_EN BIT(0)
#define CONFIG_IRQ_EN BIT(1)

Quoted 1 line

NC_ is too short, something like NATCHIP may be better.

Ok, good name.

Quoted 3 lines
Quoted 1 line

+static irqreturn_t timer_interrupt(int irq, void *dev)

Fix the function name.

static irqreturn_t natchip_timer_interrupt(int irq, void *dev) Hmm?

Quoted 7 lines

drivers/clocksource/timer-nationalchip.c line 86

Quoted 5 lines
drivers/clocksource/timer-nationalchip.c new file +5 -0
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+	.clkevt = {
+		.name = TIMER_NAME,

Let the node name.

Ok, remove it.

Quoted 8 lines

drivers/clocksource/timer-nationalchip.c line 92

Quoted 6 lines
drivers/clocksource/timer-nationalchip.c new file +6 -0
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC |
+			CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown	= nc_timer_shutdown,
+		.set_state_periodic	= nc_timer_set_periodic,
+		.set_next_event		= nc_timer_set_next_event,

set_oneshot ?

Yes oneshort, but also could support periodic. But in fact, it only works with oneshort.

Quoted 26 lines
Quoted 13 lines
drivers/clocksource/timer-nationalchip.c new file +13 -0
+		.cpumask = cpu_possible_mask,
+	},
+
+	.of_irq = {
+		.handler = timer_interrupt,
+		.flags = IRQF_TIMER | IRQF_IRQPOLL,
+	},
+};
+
+static u64 notrace nc_sched_clock_read(void)
+{
+	void __iomem *base;
+

drivers/clocksource/timer-nationalchip.c line 115

Quoted 10 lines
drivers/clocksource/timer-nationalchip.c new file +10 -0
+	base = timer_of_base(&to) + CLKSRC_OFFSET; 
+
+	return (u64) readl_relaxed(base + TIMER_VALUE);
+}
+
+static void nc_timer_set_div(void __iomem *base)
+{
+	unsigned int div;
+
+	div = timer_of_rate(&to)/TIMER_FREQ - 1;

space ' / '

Quoted 6 lines

Is it
(timer_of_rate(&to) / TIMER_FREQ) - 1
or
timer_of_rate(&to) / (TIMER_FREQ - 1)

?

Thx, I'll modify it like this:
div = (timer_of_rate(&to) / TIMER_FREQ) - 1;

Quoted 4 lines

drivers/clocksource/timer-nationalchip.c line 145

Quoted 2 lines
drivers/clocksource/timer-nationalchip.c new file +2 -0
+	clocksource_mmio_init(base + TIMER_VALUE, "nationalchip", TIMER_FREQ, 200, 32,
+			      clocksource_mmio_readl_up);

return code check ?

Ok, add return code check.

Quoted 3 lines
Quoted 1 line

+TIMER_OF_DECLARE(nc_timer, "nationalchip,timer-v1", nc_timer_init);

same comment than cksy timer.

Ok.

Guo Ren

#72 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

On 05/07/2018 05:30, Guo Ren wrote:

[ ... ]

Quoted 27 lines
Quoted 2 lines

You can get the value from the timer-of in all the places it is needed.

Ok, I could remove them.

But in csky_timer_v1_init: ret = timer_of_init(np, to)
We only init 1th cpu's timer_of struct, and others just static inited by:

DEFINE_PER_CPU(struct timer_of, csky_to) = {
.flags = TIMER_OF_CLOCK | TIMER_OF_IRQ,

.clkevt = {
.name = "C-SKY SMP Timer V1",
.rating = 300,
.features = CLOCK_EVT_FEAT_PERCPU | CLOCK_EVT_FEAT_ONESHOT,
.set_state_shutdown = csky_timer_shutdown,
.set_state_oneshot = csky_timer_oneshot,
.set_state_oneshot_stopped = csky_timer_oneshot_stopped,
.set_next_event = csky_timer_set_next_event,
},

.of_irq = {
.handler = timer_interrupt,
.flags = IRQF_TIMER,
.percpu = 1,
},
};

Quoted 2 lines

So I still need "for_each_cpu(cpu, cpu_possible_mask)" to init every csky_to ...

That is what is unclear for me. percpu or IRQF_PERCPU ?

Have a look at the commit 9995f4f184613fb02ee73092b03545520a72b104, changelog and the comment in the init function.

Can you give a similar description for this timer ?

[ ... ]

Quoted 7 lines
Quoted 4 lines

drivers/clocksource/timer-csky-v1.c line 129

Quoted 2 lines
drivers/clocksource/timer-csky-v1.c new file +2 -0
+struct clocksource csky_clocksource = {
+	.name = "csky_timer_v1_clksrc",

"csky"

struct clocksource csky_clocksource = {
	.name = "csky,mptimer",

Hmm?

Yes

[ ... ]

Quoted 8 lines
Quoted 1 line

v1, v2, etc ... has no sense here.

TIMER_OF_DECLARE(csky_610, "nationachip,ck610-timer", natchip_timer_init); TIMER_OF_DECLARE(csky_807, "csky,ck807-timer", csky_timer_init); TIMER_OF_DECLARE(csky_810, "csky,ck810-timer", csky_timer_init); TIMER_OF_DECLARE(csky_860, "csky,ck860-timer", csky_timer_init); TIMER_OF_DECLARE(csky_860mp, "csky,ck860-mptimer", csky_mptimer_init);

Hmm?

Yep, fine.

Quoted 12 lines
Quoted 10 lines

drivers/clocksource/timer-nationalchip.c line 26

Quoted 7 lines
drivers/clocksource/timer-nationalchip.c new file +7 -0
+#define STATUS_clr	BIT(0)
+
+#define CONTRL_rst	BIT(0)
+#define CONTRL_start	BIT(1)
+
+#define CONFIG_en	BIT(0)
+#define CONFIG_irq_en	BIT(1)

Prefix the macros with a shortened timer name and don't mix lower case and uppercase.

Ok.

Quoted 7 lines

#define STATUS_CLR BIT(0)

#define CONTRL_RST BIT(0)
#define CONTRL_START BIT(1)

#define CONFIG_EN BIT(0)
#define CONFIG_IRQ_EN BIT(1)

NATCHIP_STATUS_CLR
NATCHIP_CONTROL_RST
NATCHIP_CONTROL_START

NATCHIP_CONFIG_EN
NATCHIP_CONFIG_IRQ_EN

Quoted 8 lines
Quoted 1 line

NC_ is too short, something like NATCHIP may be better.

Ok, good name.

Quoted 3 lines
Quoted 1 line

+static irqreturn_t timer_interrupt(int irq, void *dev)

Fix the function name.

static irqreturn_t natchip_timer_interrupt(int irq, void *dev) Hmm?

Fine.

Quoted 17 lines
Quoted 7 lines

drivers/clocksource/timer-nationalchip.c line 86

Quoted 5 lines
drivers/clocksource/timer-nationalchip.c new file +5 -0
+static struct timer_of to = {
+	.flags = TIMER_OF_IRQ | TIMER_OF_BASE | TIMER_OF_CLOCK,
+
+	.clkevt = {
+		.name = TIMER_NAME,

Let the node name.

Ok, remove it.

Quoted 8 lines

drivers/clocksource/timer-nationalchip.c line 92

Quoted 6 lines
drivers/clocksource/timer-nationalchip.c new file +6 -0
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC |
+			CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown	= nc_timer_shutdown,
+		.set_state_periodic	= nc_timer_set_periodic,
+		.set_next_event		= nc_timer_set_next_event,

set_oneshot ?

Quoted 2 lines

Yes oneshort, but also could support periodic. But in fact, it only works with oneshort.

In the flags, it is specified periodic and oneshot but only the set_periodic ops is set.

[ ... ]

Quoted 4 lines
Quoted 4 lines

drivers/clocksource/timer-nationalchip.c line 115

Quoted 1 line
drivers/clocksource/timer-nationalchip.c new file +1 -0
+	div = timer_of_rate(&to)/TIMER_FREQ - 1;

space ' / '

Quoted 8 lines
Quoted 6 lines

Is it
(timer_of_rate(&to) / TIMER_FREQ) - 1
or
timer_of_rate(&to) / (TIMER_FREQ - 1)

?

Thx, I'll modify it like this:
div = (timer_of_rate(&to) / TIMER_FREQ) - 1;

I wanted to be sure it wasn't the latter. In this case, you don't need parenthesis, so just add the spaces around the '/' operator.

Signature · 5 lines
 <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
author
#73 lore raw

Re: [PATCH V2 18/19] clocksource: add C-SKY clocksource drivers

Quoted 4 lines · Daniel Lezcano
Quoted 2 lines

So I still need "for_each_cpu(cpu, cpu_possible_mask)" to init every csky_to ...

That is what is unclear for me. percpu or IRQF_PERCPU ?

IRQF_PERCPU

Quoted 4 lines

Have a look at the commit 9995f4f184613fb02ee73092b03545520a72b104, changelog and the comment in the init function.

Can you give a similar description for this timer ?

Ok, thx for the tip.

Quoted 8 lines
Quoted 7 lines

#define STATUS_CLR BIT(0)

#define CONTRL_RST BIT(0)
#define CONTRL_START BIT(1)

#define CONFIG_EN BIT(0)
#define CONFIG_IRQ_EN BIT(1)

Quoted 6 lines

NATCHIP_STATUS_CLR
NATCHIP_CONTROL_RST
NATCHIP_CONTROL_START

NATCHIP_CONFIG_EN
NATCHIP_CONFIG_IRQ_EN

Ok

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

drivers/clocksource/timer-nationalchip.c line 92

Quoted 6 lines
drivers/clocksource/timer-nationalchip.c new file +6 -0
+		.rating = 300,
+		.features = CLOCK_EVT_FEAT_DYNIRQ | CLOCK_EVT_FEAT_PERIODIC |
+			CLOCK_EVT_FEAT_ONESHOT,
+		.set_state_shutdown	= nc_timer_shutdown,
+		.set_state_periodic	= nc_timer_set_periodic,
+		.set_next_event		= nc_timer_set_next_event,

set_oneshot ?

Quoted 5 lines
Quoted 2 lines

Yes oneshort, but also could support periodic. But in fact, it only works with oneshort.

In the flags, it is specified periodic and oneshot but only the set_periodic ops is set.

Got it, add set_oneshot.

Quoted 5 lines
Quoted 2 lines

Thx, I'll modify it like this:
div = (timer_of_rate(&to) / TIMER_FREQ) - 1;

I wanted to be sure it wasn't the latter. In this case, you don't need parenthesis, so just add the spaces around the '/' operator.

Ok

Guo Ren

author
#74 lore raw

PATCH v2 19/19 irqchip: add C-SKY irqchip drivers

In reply to Guo Ren
---
 drivers/irqchip/Makefile           |   1 +
 drivers/irqchip/irq-csky-v1.c      | 126 ++++++++++++++++++++++++
 drivers/irqchip/irq-csky-v2.c      | 191 +++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-nationalchip.c | 131 +++++++++++++++++++++++++
 4 files changed, 449 insertions(+)
 create mode 100644 drivers/irqchip/irq-csky-v1.c
 create mode 100644 drivers/irqchip/irq-csky-v2.c
 create mode 100644 drivers/irqchip/irq-nationalchip.c
drivers/irqchip/Makefile +1 -0
index d27e3e3..51e7316 100644
@@ -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-v1.o irq-csky-v2.o irq-nationalchip.o
drivers/irqchip/irq-csky-v1.c new file +126 -0

126 lines not on this page · raw message

drivers/irqchip/irq-csky-v2.c new file +191 -0

191 lines not on this page · raw message

drivers/irqchip/irq-nationalchip.c new file +131 -0

131 lines not on this page · raw message

Signature · 1 line
2.7.4
maintainer
#75 lore raw

Re: [PATCH V2 19/19] irqchip: add C-SKY irqchip drivers

Quoted 1 line · Guo Ren

Commit message needed.

Quoted 32 lines
---
 drivers/irqchip/Makefile           |   1 +
 drivers/irqchip/irq-csky-v1.c      | 126 ++++++++++++++++++++++++
 drivers/irqchip/irq-csky-v2.c      | 191 +++++++++++++++++++++++++++++++++++++
 drivers/irqchip/irq-nationalchip.c | 131 +++++++++++++++++++++++++
 4 files changed, 449 insertions(+)
 create mode 100644 drivers/irqchip/irq-csky-v1.c
 create mode 100644 drivers/irqchip/irq-csky-v2.c
 create mode 100644 drivers/irqchip/irq-nationalchip.c
drivers/irqchip/Makefile +1 -0
index d27e3e3..51e7316 100644
@@ -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-v1.o irq-csky-v2.o irq-nationalchip.o
drivers/irqchip/irq-csky-v1.c new file +6 -0
new file mode 100644
index 0000000..64ea564
@@ -0,0 +1,126 @@
+// 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>

drivers/irqchip/irq-csky-v1.c line 16

Quoted 10 lines
drivers/irqchip/irq-csky-v1.c new file +10 -0
+#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>
+#include <asm/traps.h>
+
+#ifdef CONFIG_CSKY_VECIRQ_LEGENCY

Do you mean "legacy"?

It would be better to make this run-time so you can support multiple platforms in one build. You should be able to determine this from DT.

Quoted 2 lines
drivers/irqchip/irq-csky-v1.c new file +2 -0
+#include <asm/reg_ops.h>
+#endif

[...]

Quoted 1 line

+IRQCHIP_DECLARE(csky_intc_v1, "csky,intc-v1", csky_intc_v1_init);

DT bindings must be documented. And the vendor prefix must also be registered in vendor-prefixes.txt.

[...]

Quoted 1 line

+IRQCHIP_DECLARE(csky_intc_v2, "csky,intc-v2", csky_intc_v2_init);

And this one. Use of v1, v2, etc. is generally discouraged unless there is some strict versioning behind it. Most bindings use implementation specific compatible strings (which typically means the SoC name/number as part of it).

[...]

Quoted 1 line

+IRQCHIP_DECLARE(nationalchip_intc_v1_ave, "nationalchip,intc-v1,ave", intc_init);

Here too. And your timers as well.

You'll also need to do cpu bindings as well especially for SMP.

Rob

author
#76 lore raw

Re: [PATCH V2 19/19] irqchip: add C-SKY irqchip drivers

Quoted 1 line · Rob Herring

Commit message needed.

Ok

Quoted 1 line

Do you mean "legacy"?

Yes, it's from arch/csky/Kconfig.debug, and I'll correct it in next version patch.

Quoted 2 lines

It would be better to make this run-time so you can support multiple platforms in one build. You should be able to determine this from DT.

The CSKY_VECIRQ_LEGACY means when cpu receive the IRQ, it will directly enter into the exception vector entry indexed by IRQ number. Just some old SOC need the feature. We reserve it just as we've mentioned in arch/csky/Kconfig.debug:

config CSKY_VECIRQ_LEGENCY
bool "Use legency IRQ vector for interrupt, it's for SOC bugfix." help
It's a deprecated method for arch/csky. Don't use it, unless your SOC has bug.

As we need this config to setup the vector tables in arch/csky/kernel/traps.c, "determine this from DT" isn't suitable for us.

Quoted 4 lines
Quoted 1 line

+IRQCHIP_DECLARE(csky_intc_v1, "csky,intc-v1", csky_intc_v1_init);

DT bindings must be documented. And the vendor prefix must also be registered in vendor-prefixes.txt.

Ok, thx for the tips. I'll follow the rules.

Quoted 10 lines
Quoted 1 line

+IRQCHIP_DECLARE(csky_intc_v2, "csky,intc-v2", csky_intc_v2_init);

And this one. Use of v1, v2, etc. is generally discouraged unless there is some strict versioning behind it. Most bindings use implementation specific compatible strings (which typically means the SoC name/number as part of it).

Quoted 1 line

+IRQCHIP_DECLARE(nationalchip_intc_v1_ave, "nationalchip,intc-v1,ave", intc_init);

Here too. And your timers as well.

"csky,intc-v1/v2" are used in many SOCs, just like "arm,gic-v2/v3". So may I change them like these?:
csky,intc-v1 >>> csky,ck807-intc

                  csky,ck810-intc
                  csky,ck860-intc

csky,intc-v2 >>> csky,ck860-mpintc

nationalchip,intc-v1,ave >>> nationalchip,ck610-gx6605s-intc

Quoted 1 line

You'll also need to do cpu bindings as well especially for SMP.

Ok, thx for tips.

#77 lore raw

Re: [PATCH V2 19/19] irqchip: add C-SKY irqchip drivers

In reply to Guo Ren

On Mon, 2 Jul 2018, Guo Ren wrote:

-EEMPTYCHANGELOG

Review

Quoted 3 lines
(quoted diff) +2 -0
+
+#ifdef CONFIG_CSKY_VECIRQ_LEGENCY

I assume you meant _LEGACY

Review

Quoted 2 lines
(quoted diff) +2 -0
+#include <asm/reg_ops.h>
+#endif

Also why making the include conditional. Just include it always and be done with it.

Quoted 21 lines
drivers/irqchip/irq-csky-v1.c new file +21 -0
+static void __iomem *reg_base;
+
+#define INTC_ICR	0x00
+#define INTC_ISR	0x00
+#define INTC_NEN31_00	0x10
+#define INTC_NEN63_32	0x28
+#define INTC_IFR31_00	0x08
+#define INTC_IFR63_32	0x20
+#define INTC_SOURCE	0x40
+
+#define INTC_IRQS	64
+
+#define INTC_ICR_AVE	BIT(31)
+
+#define VEC_IRQ_BASE	32
+
+static struct irq_domain *root_domain;
+
+static void __init ck_set_gc(void __iomem *reg_base, u32 irq_base,
+			     u32 mask_reg)
+{

drivers/irqchip/irq-csky-v1.c line 50

Quoted 10 lines
drivers/irqchip/irq-csky-v1.c new file +10 -0
+	struct irq_chip_generic *gc;
+
+	gc = irq_get_domain_generic_chip(root_domain, irq_base);
+	gc->reg_base = reg_base;
+	gc->chip_types[0].regs.mask = mask_reg;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+}
+
+static struct irq_domain *root_domain;

You have the same declaration 10 lines above already....

drivers/irqchip/irq-csky-v1.c line 57

Quoted 7 lines
drivers/irqchip/irq-csky-v1.c new file +7 -0
+static void ck_irq_handler(struct pt_regs *regs)
+{
+#ifdef CONFIG_CSKY_VECIRQ_LEGENCY
+	irq_hw_number_t irq = ((mfcr("psr") >> 16) & 0xff) - VEC_IRQ_BASE;
+#else
+	irq_hw_number_t irq = readl_relaxed(reg_base + INTC_ISR) & 0x3f;
+#endif

You can avoid the ifdeffery by doing:

	irq_hw_number_t irq;

	if (IS_ENABLED(CONFIG_CSKY_VECIRQ_LEGENCY))
		irq = ((mfcr("psr") >> 16) & 0xff) - VEC_IRQ_BASE;
	else
		irq = readl_relaxed(reg_base + INTC_ISR) & 0x3f;

which makes the whole thing more readable.

drivers/irqchip/irq-csky-v1.c line 62

Quoted 5 lines
drivers/irqchip/irq-csky-v1.c new file +5 -0
+	handle_domain_irq(root_domain, irq, regs);
+}
+
+#define expand_byte_to_word(i) (i|(i<<8)|(i<<16)|(i<<24))
+static inline void setup_irq_channel(void __iomem *reg_base)

Please do not glue a define and a function declaration togetther w/o a new line in between. That's really hard to parse.

Also please make that expand macro an inline function.

Review

Quoted 2 lines
(quoted diff) +2 -0
+{
+	int i;

Bah: writel_relaxed(u32 value, ...). So why 'int' ? Just because?

drivers/irqchip/irq-csky-v1.c line 68

Quoted 4 lines
drivers/irqchip/irq-csky-v1.c new file +4 -0
+
+	/*
+	 * There are 64 irq nums and irq-channels and one byte per channel.
+	 * Setup every channel with the same hwirq num.

This is magic and not understandable for an outsider.

drivers/irqchip/irq-csky-v1.c line 71

Quoted 3 lines
drivers/irqchip/irq-csky-v1.c new file +3 -0
+	 */
+	for (i = 0; i < INTC_IRQS; i += 4) {
+		writel_relaxed(expand_byte_to_word(i) + 0x00010203,

No magic numbers please w/o explanation. And '+' is the wrong operator here, really. Stick that into the expand function:

static inline u32 build_intc_ctrl(u32 idx)

{
	u32 res;

	/*
	 * Set the same index for each channel (or whatever
	 * this means in reality).
	 */
	res = idx | (idx << 8) | (idx || 16) | (idx << 24);

	/*
	 * Set the channel magic number in descending order because
	 * the most significant bit comes first. (Replace with
	 * something which has not been pulled out of thin air).
	 */
	return res | 0x00010203;
}

Hmm?

Quoted 19 lines
drivers/irqchip/irq-csky-v1.c new file +19 -0
+			       reg_base + INTC_SOURCE + i);
+	}
+}
+
+static int __init
+csky_intc_v1_init(struct device_node *node, struct device_node *parent)
+{
+	u32 clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;
+
+	if (parent) {
+		pr_err("C-SKY Intc not a root irq controller\n");
+		return -EINVAL;
+	}
+
+	reg_base = of_iomap(node, 0);
+	if (!reg_base) {
+		pr_err("C-SKY Intc unable to map: %p.\n", node);
+		return -EINVAL;

drivers/irqchip/irq-csky-v1.c line 100

Quoted 10 lines
drivers/irqchip/irq-csky-v1.c new file +10 -0
+	}
+
+	writel_relaxed(0, reg_base + INTC_NEN31_00);
+	writel_relaxed(0, reg_base + INTC_NEN63_32);
+
+#ifndef CONFIG_CSKY_VECIRQ_LEGENCY
+	writel_relaxed(INTC_ICR_AVE, reg_base + INTC_ICR);
+#else
+	writel_relaxed(0, reg_base + INTC_ICR);
+#endif

See above.

Review line 2

Quoted 4 lines

+++ b/drivers/irqchip/irq-csky-v2.c

(quoted diff) +2 -0
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

Please stick an empty newline here for separation

Quoted 1 line
(quoted diff) +1 -0
+#include <linux/kernel.h>

...

drivers/irqchip/irq-csky-v2.c line 49

Quoted 6 lines
drivers/irqchip/irq-csky-v2.c new file +6 -0
+static void csky_irq_v2_handler(struct pt_regs *regs)
+{
+	static void __iomem	*reg_base;
+	irq_hw_number_t		hwirq;
+
+	reg_base = *this_cpu_ptr(&intcl_reg);

Wheee!

	static void __iomem *reg_base = this_cpu_read(intcl_reg);
	irq_hw_number_t	hwirq;

Hmm?

Quoted 10 lines
drivers/irqchip/irq-csky-v2.c new file +10 -0
+
+#ifdef CONFIG_SMP
+static int csky_irq_set_affinity(struct irq_data *d,
+				 const struct cpumask *mask_val,
+				 bool force)
+{
+	unsigned int cpu;
+
+	if (!force)
+		cpu = cpumask_any_and(mask_val, cpu_online_mask);

drivers/irqchip/irq-csky-v2.c line 100

Quoted 10 lines
drivers/irqchip/irq-csky-v2.c new file +10 -0
+	else
+		cpu = cpumask_first(mask_val);
+
+	if (cpu >= nr_cpu_ids)
+		return -EINVAL;
+
+	/* Enable interrupt destination */
+	cpu |= BIT(31);
+
+	writel_relaxed(cpu, INTCG_base + INTCG_CIDSTR + (4*(d->hwirq - COMM_IRQ_BASE)));

Spaces between '4' and '*' and '(d->)' please. And to avoid the overly long line use a local variable to calculate the value.

Quoted 14 lines
drivers/irqchip/irq-csky-v2.c new file +14 -0
+	irq_data_update_effective_affinity(d, cpumask_of(cpu));
+
+	return IRQ_SET_MASK_OK_DONE;
+}
+#endif
+
+static struct irq_chip csky_irq_chip = {
+	.name           = "C-SKY SMP Intc V2",
+	.irq_eoi	= csky_irq_v2_eoi,
+	.irq_enable	= csky_irq_v2_enable,
+	.irq_disable	= csky_irq_v2_disable,
+#ifdef CONFIG_SMP
+	.irq_set_affinity = csky_irq_set_affinity,
+#endif

drivers/irqchip/irq-csky-v2.c line 125

Quoted 10 lines
drivers/irqchip/irq-csky-v2.c new file +10 -0
+};
+
+static int csky_irqdomain_map(struct irq_domain *d, unsigned int irq,
+			      irq_hw_number_t hwirq)
+{
+	if(hwirq < COMM_IRQ_BASE) {
+		irq_set_percpu_devid(irq);
+		irq_set_chip_and_handler(irq, &csky_irq_chip, handle_percpu_irq);
+	} else
+		irq_set_chip_and_handler(irq, &csky_irq_chip, handle_fasteoi_irq);

The else path wants curly braces as well.

drivers/irqchip/irq-csky-v1.c line 2

Quoted 7 lines
drivers/irqchip/irq-csky-v1.c new file +6 -0
+
+	return 0;
+}
+++ b/drivers/irqchip/irq-nationalchip.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.

See above

Quoted 1 line
(quoted diff) +1 -0
+#include <linux/kernel.h>

...

Quoted 23 lines
drivers/irqchip/irq-nationalchip.c new file +22 -0
+static struct irq_domain *root_domain;
+
+static void nc_irq_handler(struct pt_regs *regs)
+{
+	u32 status, irq;
+
+	do {
+		status = readl_relaxed(reg_base + INTC_NINT31_00);
+		if (status) {
+			irq = __ffs(status);
+		} else {
+			status = readl_relaxed(reg_base + INTC_NINT63_32);
+			if (status)
+				irq = __ffs(status) + 32;
+			else
+				return;
+		}
+		handle_domain_irq(root_domain, irq, regs);
+	} while(1);
+}
+
 
+#define expand_byte_to_word(i) (i|(i<<8)|(i<<16)|(i<<24))

drivers/irqchip/irq-nationalchip.c line 76

Quoted 10 lines
drivers/irqchip/irq-nationalchip.c new file +10 -0
+static inline void setup_irq_channel(void __iomem *reg_base)
+{
+	int i;
+
+	/*
+	 * There are 64 irq nums and irq-channels and one byte per channel.
+	 * Setup every channel with the same hwirq num.
+	 */
+	for (i = 0; i < INTC_IRQS; i += 4) {
+		writel_relaxed(expand_byte_to_word(i) + 0x03020100,

This magic number is the reverse of the above magic. Is that intentional.

Review

Quoted 2 lines
(quoted diff) +2 -0
+			       reg_base + INTC_SOURCE + i);
+	}

See above.

drivers/irqchip/irq-nationalchip.c line 85

Quoted 7 lines
drivers/irqchip/irq-nationalchip.c new file +7 -0
+}
+
+static int __init
+intc_init(struct device_node *node, struct device_node *parent)
+{
+	u32 clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;

Aside of that the whole thing might share the code with the other one, but it might not be worth it. At least this wants to be documented in the changelog why sharing the code is not useful...

Thanks,

tglx

author
#78 lore raw

Re: [PATCH V2 19/19] irqchip: add C-SKY irqchip drivers

Quoted 1 line · Thomas Gleixner

-EEMPTYCHANGELOG

Ok, I'll seperate this patchset's changelog from cover-letter in next version patch.

Quoted 3 lines
Quoted 1 line

+#ifdef CONFIG_CSKY_VECIRQ_LEGENCY

I assume you meant _LEGACY

Yes.

Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+#include <asm/reg_ops.h>
+#endif

Also why making the include conditional. Just include it always and be done with it.

Ok.

Quoted 25 lines
Quoted 25 lines
drivers/irqchip/irq-csky-v1.c new file +25 -0
+static void __iomem *reg_base;
+
+#define INTC_ICR	0x00
+#define INTC_ISR	0x00
+#define INTC_NEN31_00	0x10
+#define INTC_NEN63_32	0x28
+#define INTC_IFR31_00	0x08
+#define INTC_IFR63_32	0x20
+#define INTC_SOURCE	0x40
+
+#define INTC_IRQS	64
+
+#define INTC_ICR_AVE	BIT(31)
+
+#define VEC_IRQ_BASE	32
+
+static struct irq_domain *root_domain;
+
+static void __init ck_set_gc(void __iomem *reg_base, u32 irq_base,
+			     u32 mask_reg)
+{
+	struct irq_chip_generic *gc;
+
+	gc = irq_get_domain_generic_chip(root_domain, irq_base);
+	gc->reg_base = reg_base;
Quoted 8 lines

drivers/irqchip/irq-csky-v1.c line 50

Quoted 6 lines
drivers/irqchip/irq-csky-v1.c new file +6 -0
+	gc->chip_types[0].regs.mask = mask_reg;
+	gc->chip_types[0].chip.irq_mask = irq_gc_mask_clr_bit;
+	gc->chip_types[0].chip.irq_unmask = irq_gc_mask_set_bit;
+}
+
+static struct irq_domain *root_domain;

You have the same declaration 10 lines above already....

Opps, thx. I'll remove.

Quoted 10 lines

drivers/irqchip/irq-csky-v1.c line 57

Quoted 7 lines
drivers/irqchip/irq-csky-v1.c new file +7 -0
+static void ck_irq_handler(struct pt_regs *regs)
+{
+#ifdef CONFIG_CSKY_VECIRQ_LEGENCY
+	irq_hw_number_t irq = ((mfcr("psr") >> 16) & 0xff) - VEC_IRQ_BASE;
+#else
+	irq_hw_number_t irq = readl_relaxed(reg_base + INTC_ISR) & 0x3f;
+#endif

You can avoid the ifdeffery by doing:

Quoted 8 lines
	irq_hw_number_t irq;

	if (IS_ENABLED(CONFIG_CSKY_VECIRQ_LEGENCY))
		irq = ((mfcr("psr") >> 16) & 0xff) - VEC_IRQ_BASE;
	else
		irq = readl_relaxed(reg_base + INTC_ISR) & 0x3f;

which makes the whole thing more readable.

Ok, good idea.

Quoted 45 lines

Review

Quoted 2 lines
(quoted diff) +2 -0
+#define expand_byte_to_word(i) (i|(i<<8)|(i<<16)|(i<<24))
+static inline void setup_irq_channel(void __iomem *reg_base)

Please do not glue a define and a function declaration togetther w/o a new line in between. That's really hard to parse.

Also please make that expand macro an inline function.

Review

Quoted 2 lines
(quoted diff) +2 -0
+{
+	int i;

Bah: writel_relaxed(u32 value, ...). So why 'int' ? Just because?

drivers/irqchip/irq-csky-v1.c line 68

Quoted 4 lines
drivers/irqchip/irq-csky-v1.c new file +4 -0
+
+	/*
+	 * There are 64 irq nums and irq-channels and one byte per channel.
+	 * Setup every channel with the same hwirq num.

This is magic and not understandable for an outsider.

drivers/irqchip/irq-csky-v1.c line 71

Quoted 3 lines
drivers/irqchip/irq-csky-v1.c new file +3 -0
+	 */
+	for (i = 0; i < INTC_IRQS; i += 4) {
+		writel_relaxed(expand_byte_to_word(i) + 0x00010203,

No magic numbers please w/o explanation. And '+' is the wrong operator here, really. Stick that into the expand function:

static inline u32 build_intc_ctrl(u32 idx)

{
	u32 res;

	/*
	 * Set the same index for each channel (or whatever
	 * this means in reality).
	 */
	res = idx | (idx << 8) | (idx || 16) | (idx << 24);

	/*
	 * Set the channel magic number in descending order because
	 * the most significant bit comes first. (Replace with
	 * something which has not been pulled out of thin air).
	 */
	return res | 0x00010203;
}
Quoted 1 line

Hmm?

That's Ok. And here is my implementation:

static inline u32 build_intc_ctrl(u32 idx)

{
	/*
	 * One channel is one byte in a word-width register, so
	 * there are four channels in a word-width register.
	 *
	 * Set the same index for each channel and it will make
	 * "irq num = channel num".
	 */
	return (idx             | ((idx + 1) << 8) |
	      ((idx + 2) << 16) | ((idx + 3) << 24));
}

Hmm? (No magic number)

Quoted 7 lines

drivers/irqchip/irq-csky-v1.c line 100

Quoted 5 lines
drivers/irqchip/irq-csky-v1.c new file +5 -0
+#ifndef CONFIG_CSKY_VECIRQ_LEGENCY
+	writel_relaxed(INTC_ICR_AVE, reg_base + INTC_ICR);
+#else
+	writel_relaxed(0, reg_base + INTC_ICR);
+#endif

See above.

Ok, use if (IS_ENABLED(CONFIG_CSKY_VECIRQ_LEGENCY))

Quoted 6 lines

Review line 2

Quoted 4 lines

+++ b/drivers/irqchip/irq-csky-v2.c

(quoted diff) +2 -0
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

Please stick an empty newline here for separation

Ok

Quoted 11 lines

drivers/irqchip/irq-csky-v2.c line 49

Quoted 4 lines
drivers/irqchip/irq-csky-v2.c new file +4 -0
+	static void __iomem	*reg_base;
+	irq_hw_number_t		hwirq;
+
+	reg_base = *this_cpu_ptr(&intcl_reg);

Wheee!

	static void __iomem *reg_base = this_cpu_read(intcl_reg);
	irq_hw_number_t	hwirq;

Hmm?

Thx for the tips and I'll use this_cpu_read() without static.
void __iomem *reg_base = this_cpu_read(intcl_reg);

Quoted 4 lines

drivers/irqchip/irq-csky-v2.c line 100

Quoted 1 line
drivers/irqchip/irq-csky-v2.c new file +1 -0
+	writel_relaxed(cpu, INTCG_base + INTCG_CIDSTR + (4*(d->hwirq - COMM_IRQ_BASE)));

Spaces between '4' and '*' and '(d->)' please. And to avoid the overly long line use a local variable to calculate the value.

Ok.

Quoted 4 lines

drivers/irqchip/irq-csky-v2.c line 125

Quoted 2 lines
drivers/irqchip/irq-csky-v2.c new file +2 -0
+	} else
+		irq_set_chip_and_handler(irq, &csky_irq_chip, handle_fasteoi_irq);

The else path wants curly braces as well.

Ok.

Quoted 4 lines

drivers/irqchip/irq-nationalchip.c line 2

Quoted 2 lines
drivers/irqchip/irq-nationalchip.c new file +2 -0
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Hangzhou NationalChip Science & Technology Co.,Ltd.

See above

Ok, stick an empty newline

Quoted 8 lines

drivers/irqchip/irq-nationalchip.c line 76

Quoted 1 line
drivers/irqchip/irq-nationalchip.c new file +1 -0
+		writel_relaxed(expand_byte_to_word(i) + 0x03020100,

This magic number is the reverse of the above magic. Is that intentional.

Review line 14

Quoted 2 lines
(quoted diff) +2 -0
+			       reg_base + INTC_SOURCE + i);
+	}

See above.

No magic number and use inline func.

Quoted 9 lines

drivers/irqchip/irq-nationalchip.c line 85

Quoted 5 lines
drivers/irqchip/irq-nationalchip.c new file +5 -0
+static int __init
+intc_init(struct device_node *node, struct device_node *parent)
+{
+	u32 clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
+	int ret;

Aside of that the whole thing might share the code with the other one, but it might not be worth it. At least this wants to be documented in the changelog why sharing the code is not useful...

Do you mean merge irq-csky-v1.c irq-csky-v2.c irq-nationalchip.c into one file eg: irq-csky.c?

Guo Ren

#79 lore raw

Re: [PATCH V2 19/19] irqchip: add C-SKY irqchip drivers

Quoted 15 lines · Guo Ren

On Tue, Jul 03, 2018 at 11:28:03AM +0200, Thomas Gleixner wrote:
That's Ok. And here is my implementation:

static inline u32 build_intc_ctrl(u32 idx)

{
	/*
	 * One channel is one byte in a word-width register, so
	 * there are four channels in a word-width register.
	 *
	 * Set the same index for each channel and it will make
	 * "irq num = channel num".
	 */
	return (idx             | ((idx + 1) << 8) |
	      ((idx + 2) << 16) | ((idx + 3) << 24));
}
Quoted 1 line

Hmm? (No magic number)

Ok :)

Quoted 7 lines
Quoted 7 lines

drivers/irqchip/irq-csky-v2.c line 49

Quoted 4 lines
drivers/irqchip/irq-csky-v2.c new file +4 -0
+	static void __iomem	*reg_base;
+	irq_hw_number_t		hwirq;
+
+	reg_base = *this_cpu_ptr(&intcl_reg);

Wheee!

Quoted 6 lines
Quoted 4 lines
	static void __iomem *reg_base = this_cpu_read(intcl_reg);
	irq_hw_number_t	hwirq;

Hmm?

Thx for the tips and I'll use this_cpu_read() without static.
void __iomem *reg_base = this_cpu_read(intcl_reg);

Yeah, I surely missed to drop the static ...

Quoted 7 lines
Quoted 4 lines

Aside of that the whole thing might share the code with the other one, but it might not be worth it. At least this wants to be documented in the changelog why sharing the code is not useful...

Do you mean merge irq-csky-v1.c irq-csky-v2.c irq-nationalchip.c into one file eg: irq-csky.c?

Yes, but only if there is enough code to share without creating an ifdef mess. But that looks doable

Thanks,

tglx

author
#80 lore raw

Re: [PATCH V2 19/19] irqchip: add C-SKY irqchip drivers

Quoted 5 lines · Thomas Gleixner
Quoted 2 lines

Do you mean merge irq-csky-v1.c irq-csky-v2.c irq-nationalchip.c into one file eg: irq-csky.c?

Yes, but only if there is enough code to share without creating an ifdef mess. But that looks doable

Ok, I'll try.

Guo Ren

#81 lore raw
In reply to Guo Ren

Can you say what the --target tuple should be so that I can add the arch to my collection of Fedora cross-binutils and cross-gcc tools built from upstream binutils and gcc sources?

Thanks,
David

author
#82 lore raw
Quoted 3 lines · David Howells

Can you say what the --target tuple should be so that I can add the arch to my collection of Fedora cross-binutils and cross-gcc tools built from upstream binutils and gcc sources?

Metor Graghics are helping us upstream gcc and binutils.

@Sandra,

Could you help me to reply the question?

#83 lore raw
Quoted 9 lines · Guo Ren
Quoted 3 lines · David Howells

Can you say what the --target tuple should be so that I can add the arch to my collection of Fedora cross-binutils and cross-gcc tools built from upstream binutils and gcc sources?

Metor Graghics are helping us upstream gcc and binutils.

@Sandra,

Could you help me to reply the question?

Neither binutils nor gcc support for C-SKY are in the upstream repositories yet. We should be resubmitting the binutils port soon (with bug fixes to address the test failures that caused it to be rejected the last time), and the gcc port will follow that shortly.

The target triplets we have been testing are csky-elf, csky-linux-gnu, and csky-linux-uclibc. Note that the gcc port will only support v2 processors/ABI so that is the default ABI for these triplets.

I'm not familiar with the Fedora tools, but to build a complete toolchain you'll need library support as well and I'm not sure what the submission status/plans for that are. E.g. Mentor did a newlib/libgloss port for local testing of the ELF toolchain and provided it to C-SKY, but pushing that to the upstream repository ourselves is not on our todo list.

-Sandra

author
#84 lore raw
Quoted 20 lines · Sandra Loosemore
Quoted 9 lines · Guo Ren
Quoted 3 lines · David Howells

Can you say what the --target tuple should be so that I can add the arch to my collection of Fedora cross-binutils and cross-gcc tools built from upstream binutils and gcc sources?

Metor Graghics are helping us upstream gcc and binutils.

@Sandra,

Could you help me to reply the question?

Neither binutils nor gcc support for C-SKY are in the upstream repositories yet. We should be resubmitting the binutils port soon (with bug fixes to address the test failures that caused it to be rejected the last time), and the gcc port will follow that shortly.

The target triplets we have been testing are csky-elf, csky-linux-gnu, and csky-linux-uclibc. Note that the gcc port will only support v2 processors/ABI so that is the default ABI for these triplets.

Quoted 7 lines

I'm not familiar with the Fedora tools, but to build a complete toolchain you'll need library support as well and I'm not sure what the submission status/plans for that are. E.g. Mentor did a newlib/libgloss port for local testing of the ELF toolchain and provided it to C-SKY, but pushing that to the upstream repository ourselves is not on our todo list.

-Sandra

Thank you, Sandra.

Guo Ren

#85 lore raw
In reply to Sandra Loosemore
Quoted 3 lines · Sandra Loosemore

I'm not familiar with the Fedora tools, but to build a complete toolchain you'll need library support as well and I'm not sure what the submission status/plans for that are.

The idea behind the cross-gcc package in Fedora is that it's for kernel builds and bootloader-type things only. It builds libgcc, but doesn't use kernel headers or a C library[*] as this enormously simplifies things.

The reasons being:

(1) Not all arches can use the same set of C libraries (some can't use glibc and some don't have a uClibc port).

(2) I can only build each individual compiler against a single C library - so if you have two or more incompatible environments, you're out of luck - I can only use one.

(3) Building lots more compilers for individual environments would massively increase the build size and time. A full cross-gcc build now takes the best part of a day to build.

[*] Yes, there's one exception: it builds the arm compiler against an arm
cross-glibc - not my idea.

David