Blackfin: blackfin architecture patch update
PATCH 1/5 Blackfin: blackfin architecture patch update
Hi folks,
Here is the update version of blackfin-arch.patch in -mm tree. simply add support to utrace and it was tested on blackfin STAMP board as well as other following patches.
The whole patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2583/blackfin-arch.patch
The incremental patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2584/blackfin-arch-mm2-update.patch
[PATCH] Blackfin Architecture
This adds support for the Analog Devices Blackfin processor architecture, and currently supports the BF533, BF532, BF531, BF537, BF536, BF534, and BF561 (Dual Core) devices, with a variety of development platforms including those avaliable from Analog Devices (BF533-EZKit, BF533-STAMP, BF537-STAMP, BF561-EZKIT), and Bluetechnix! Tinyboards.
The Blackfin architecture was jointly developed by Intel and Analog Devices Inc. (ADI) as the Micro Signal Architecture (MSA) core and introduced it in December of 2000. Since then ADI has put this core into it’s Blackfin processor family of devices. The Blackfin core has the advantages of a clean, orthogonal,RISC-like microprocessor instruction set. It combines a dual‑MAC (Multiply/Accumulate), state‑of‑the‑art signal processing engine and single-instruction, multiple‑data (SIMD) multimedia capabilities into a single instruction-set architecture.
The Blackfin architecture, including the instruction set, is described by the ADSP-BF53x/BF56x Blackfin® Processor Programming Reference
http://blackfin.uclinux.org/gf/download/frsrelease/29/2549/Blackfin_PRM.pdf
The Blackfin processor is already supported by major releases of gcc, and there are binary and source rpms/tarballs for many architectures at:
http://blackfin.uclinux.org/gf/project/toolchain/frs
There is complete documentation, including "getting started" guides available at:
http://docs.blackfin.uclinux.org/
which provides links to the sources and patches you will need in order to set up a cross-compiling environment for bfin-linux-uclibc
This patch, as well as the other patches (toolchain, distribution, uClibc) are actively supported by Analog Devices Inc, at:
http://blackfin.uclinux.org/
We have tested this on LTP, and our test plan (including pass/fails) can be found at:
http://docs.blackfin.uclinux.org/doku.php?id=testing_the_linux_kernel
---
arch/blackfin/Kconfig | 989 ++++++++ arch/blackfin/Makefile | 81 arch/blackfin/boot/Makefile | 27 arch/blackfin/defconfig | 1314 +++++++++++ arch/blackfin/kernel/Makefile | 13 arch/blackfin/kernel/asm-offsets.c | 140 + arch/blackfin/kernel/bfin_dma_5xx.c | 747 ++++++ arch/blackfin/kernel/bfin_gpio.c | 654 +++++ arch/blackfin/kernel/bfin_ksyms.c | 119 arch/blackfin/kernel/dma-mapping.c | 174 + arch/blackfin/kernel/dualcore_test.c | 51 arch/blackfin/kernel/entry.S | 96 arch/blackfin/kernel/init_task.c | 63 arch/blackfin/kernel/irqchip.c | 149 + arch/blackfin/kernel/module.c | 431 +++ arch/blackfin/kernel/process.c | 398 +++ arch/blackfin/kernel/ptrace.c | 421 +++ arch/blackfin/kernel/setup.c | 921 +++++++ arch/blackfin/kernel/signal.c | 436 +++ arch/blackfin/kernel/sys_bfin.c | 133 + arch/blackfin/kernel/time.c | 330 ++ arch/blackfin/kernel/traps.c | 666 +++++ arch/blackfin/kernel/vmlinux.lds.S | 221 + arch/blackfin/lib/Makefile | 11 arch/blackfin/lib/ashldi3.c | 60 arch/blackfin/lib/ashrdi3.c | 61 arch/blackfin/lib/checksum.c | 142 + arch/blackfin/lib/divsi3.S | 217 + arch/blackfin/lib/gcclib.h | 49 arch/blackfin/lib/ins.S | 71 arch/blackfin/lib/lshrdi3.c | 74 arch/blackfin/lib/memchr.S | 65 arch/blackfin/lib/memcmp.S | 110 arch/blackfin/lib/memcpy.S | 135 + arch/blackfin/lib/memmove.S | 103 arch/blackfin/lib/memset.S | 109 arch/blackfin/lib/modsi3.S | 81 arch/blackfin/lib/muldi3.c | 101 arch/blackfin/lib/outs.S | 64 arch/blackfin/lib/smulsi3_highpart.S | 30 arch/blackfin/lib/strcmp.c | 11 arch/blackfin/lib/strcpy.c | 11 arch/blackfin/lib/strncmp.c | 11 arch/blackfin/lib/strncpy.c | 11 arch/blackfin/lib/udivsi3.S | 300 ++ arch/blackfin/lib/umodsi3.S | 68 arch/blackfin/lib/umulsi3_highpart.S | 23 arch/blackfin/mach-bf533/Kconfig | 92 arch/blackfin/mach-bf533/Makefile | 9 arch/blackfin/mach-bf533/boards/Makefile | 8 arch/blackfin/mach-bf533/boards/cm_bf533.c | 271 ++ arch/blackfin/mach-bf533/boards/ezkit.c | 231 + arch/blackfin/mach-bf533/boards/generic_board.c | 97 arch/blackfin/mach-bf533/boards/stamp.c | 328 ++ arch/blackfin/mach-bf533/cpu.c | 163 + arch/blackfin/mach-bf533/head.S | 776 ++++++ arch/blackfin/mach-bf533/ints-priority.c | 67 arch/blackfin/mach-bf537/Kconfig | 141 + arch/blackfin/mach-bf537/Makefile | 9 arch/blackfin/mach-bf537/boards/Makefile | 8 arch/blackfin/mach-bf537/boards/cm_bf537.c | 379 +++ arch/blackfin/mach-bf537/boards/generic_board.c | 464 +++ arch/blackfin/mach-bf537/boards/led.S | 183 + arch/blackfin/mach-bf537/boards/pnav10.c | 541 ++++ arch/blackfin/mach-bf537/boards/stamp.c | 624 +++++ arch/blackfin/mach-bf537/cpu.c | 163 + arch/blackfin/mach-bf537/head.S | 604 +++++ arch/blackfin/mach-bf537/ints-priority.c | 76 arch/blackfin/mach-bf561/Kconfig | 222 + arch/blackfin/mach-bf561/Makefile | 9 arch/blackfin/mach-bf561/boards/Makefile | 6 arch/blackfin/mach-bf561/boards/cm_bf561.c | 295 ++ arch/blackfin/mach-bf561/boards/ezkit.c | 151 + arch/blackfin/mach-bf561/boards/generic_board.c | 84 arch/blackfin/mach-bf561/coreb.c | 404 +++ arch/blackfin/mach-bf561/head.S | 514 ++++ arch/blackfin/mach-bf561/ints-priority.c | 110 arch/blackfin/mach-common/Makefile | 12 arch/blackfin/mach-common/cache.S | 255 ++ arch/blackfin/mach-common/cacheinit.S | 139 + arch/blackfin/mach-common/cplbhdlr.S | 132 + arch/blackfin/mach-common/cplbinfo.c | 213 + arch/blackfin/mach-common/cplbmgr.S | 609 +++++ arch/blackfin/mach-common/dpmc.S | 420 +++ arch/blackfin/mach-common/entry.S | 1209 ++++++++++ arch/blackfin/mach-common/interrupt.S | 255 ++ arch/blackfin/mach-common/ints-priority-dc.c | 473 +++ arch/blackfin/mach-common/ints-priority-sc.c | 580 ++++ arch/blackfin/mach-common/irqpanic.c | 196 + arch/blackfin/mach-common/lock.S | 206 + arch/blackfin/mach-common/pm.c | 183 + arch/blackfin/mm/Makefile | 5 arch/blackfin/mm/blackfin_sram.c | 537 ++++ arch/blackfin/mm/blackfin_sram.h | 40 arch/blackfin/mm/init.c | 211 + arch/blackfin/mm/kmap.c | 84 arch/blackfin/oprofile/Kconfig | 29 arch/blackfin/oprofile/Makefile | 14 arch/blackfin/oprofile/common.c | 170 + arch/blackfin/oprofile/op_blackfin.h | 100 arch/blackfin/oprofile/op_model_bf533.c | 163 + arch/blackfin/oprofile/timer_int.c | 76 fs/Kconfig.binfmt | 2 include/asm-blackfin/Kbuild | 1 include/asm-blackfin/a.out.h | 25 include/asm-blackfin/atomic.h | 144 + include/asm-blackfin/auxvec.h | 4 include/asm-blackfin/bf5xx_timers.h | 209 + include/asm-blackfin/bfin-global.h | 120 + include/asm-blackfin/bfin5xx_spi.h | 170 + include/asm-blackfin/bfin_simple_timer.h | 13 include/asm-blackfin/bfin_spi_channel.h | 182 + include/asm-blackfin/bfin_sport.h | 177 + include/asm-blackfin/bitops.h | 213 + include/asm-blackfin/blackfin.h | 56 include/asm-blackfin/bug.h | 15 include/asm-blackfin/bugs.h | 16 include/asm-blackfin/byteorder.h | 48 include/asm-blackfin/cache.h | 18 include/asm-blackfin/cacheflush.h | 91 include/asm-blackfin/checksum.h | 101 include/asm-blackfin/cplb.h | 51 include/asm-blackfin/cplbinit.h | 205 + include/asm-blackfin/cpumask.h | 6 include/asm-blackfin/cputime.h | 6 include/asm-blackfin/current.h | 23 include/asm-blackfin/delay.h | 44 include/asm-blackfin/device.h | 7 include/asm-blackfin/div64.h | 1 include/asm-blackfin/dma-mapping.h | 73 include/asm-blackfin/dma.h | 203 + include/asm-blackfin/dpmc.h | 66 include/asm-blackfin/elf.h | 127 + include/asm-blackfin/emergency-restart.h | 6 include/asm-blackfin/entry.h | 61 include/asm-blackfin/errno.h | 6 include/asm-blackfin/fcntl.h | 13 include/asm-blackfin/flat.h | 130 + include/asm-blackfin/futex.h | 6 include/asm-blackfin/gpio.h | 369 +++ include/asm-blackfin/hardirq.h | 41 include/asm-blackfin/hw_irq.h | 6 include/asm-blackfin/ide.h | 32 include/asm-blackfin/io.h | 152 + include/asm-blackfin/ioctl.h | 1 include/asm-blackfin/ioctls.h | 82 include/asm-blackfin/ipc.h | 1 include/asm-blackfin/ipcbuf.h | 30 include/asm-blackfin/irq.h | 72 include/asm-blackfin/irq_regs.h | 1 include/asm-blackfin/kmap_types.h | 21 include/asm-blackfin/l1layout.h | 31 include/asm-blackfin/linkage.h | 7 include/asm-blackfin/local.h | 6 include/asm-blackfin/mach-bf533/anomaly.h | 176 + include/asm-blackfin/mach-bf533/bf533.h | 308 ++ include/asm-blackfin/mach-bf533/bfin_serial_5xx.h | 108 include/asm-blackfin/mach-bf533/blackfin.h | 46 include/asm-blackfin/mach-bf533/cdefBF532.h | 707 +++++ include/asm-blackfin/mach-bf533/defBF532.h | 1178 +++++++++ include/asm-blackfin/mach-bf533/dma.h | 56 include/asm-blackfin/mach-bf533/irq.h | 178 + include/asm-blackfin/mach-bf533/mem_init.h | 316 ++ include/asm-blackfin/mach-bf533/mem_map.h | 169 + include/asm-blackfin/mach-bf535/bf535.h | 1277 ++++++++++ include/asm-blackfin/mach-bf535/bf535_serial.h | 109 include/asm-blackfin/mach-bf535/blackfin.h | 43 include/asm-blackfin/mach-bf535/cdefBF535.h | 121 + include/asm-blackfin/mach-bf535/cdefblackfin.h | 69 include/asm-blackfin/mach-bf535/defBF535.h | 1818 +++++++++++++++ include/asm-blackfin/mach-bf535/defblackfin.h | 444 +++ include/asm-blackfin/mach-bf535/irq.h | 125 + include/asm-blackfin/mach-bf537/anomaly.h | 120 + include/asm-blackfin/mach-bf537/bf537.h | 289 ++ include/asm-blackfin/mach-bf537/bfin_serial_5xx.h | 147 + include/asm-blackfin/mach-bf537/blackfin.h | 430 +++ include/asm-blackfin/mach-bf537/cdefBF534.h | 1823 +++++++++++++++ include/asm-blackfin/mach-bf537/cdefBF537.h | 209 + include/asm-blackfin/mach-bf537/defBF534.h | 2502 +++++++++++++++++++++ include/asm-blackfin/mach-bf537/defBF537.h | 404 +++ include/asm-blackfin/mach-bf537/dma.h | 55 include/asm-blackfin/mach-bf537/irq.h | 219 + include/asm-blackfin/mach-bf537/mem_init.h | 330 ++ include/asm-blackfin/mach-bf537/mem_map.h | 182 + include/asm-blackfin/mach-bf561/anomaly.h | 185 + include/asm-blackfin/mach-bf561/bf561.h | 410 +++ include/asm-blackfin/mach-bf561/bfin_serial_5xx.h | 108 include/asm-blackfin/mach-bf561/blackfin.h | 53 include/asm-blackfin/mach-bf561/cdefBF561.h | 1544 ++++++++++++ include/asm-blackfin/mach-bf561/defBF561.h | 1718 ++++++++++++++ include/asm-blackfin/mach-bf561/dma.h | 36 include/asm-blackfin/mach-bf561/irq.h | 451 +++ include/asm-blackfin/mach-bf561/mem_init.h | 322 ++ include/asm-blackfin/mach-bf561/mem_map.h | 77 include/asm-blackfin/mach-common/cdef_LPBlackfin.h | 474 +++ include/asm-blackfin/mach-common/context.S | 350 ++ include/asm-blackfin/mach-common/def_LPBlackfin.h | 694 +++++ include/asm-blackfin/macros.h | 95 include/asm-blackfin/mem_map.h | 12 include/asm-blackfin/mman.h | 45 include/asm-blackfin/mmu.h | 30 include/asm-blackfin/mmu_context.h | 131 + include/asm-blackfin/module.h | 19 include/asm-blackfin/msgbuf.h | 31 include/asm-blackfin/mutex.h | 9 include/asm-blackfin/namei.h | 19 include/asm-blackfin/page.h | 89 include/asm-blackfin/page_offset.h | 6 include/asm-blackfin/param.h | 22 include/asm-blackfin/pci.h | 148 + include/asm-blackfin/percpu.h | 6 include/asm-blackfin/pgalloc.h | 8 include/asm-blackfin/pgtable.h | 70 include/asm-blackfin/poll.h | 24 include/asm-blackfin/posix_types.h | 65 include/asm-blackfin/processor.h | 105 include/asm-blackfin/ptrace.h | 166 + include/asm-blackfin/resource.h | 6 include/asm-blackfin/scatterlist.h | 26 include/asm-blackfin/sections.h | 7 include/asm-blackfin/segment.h | 7 include/asm-blackfin/semaphore-helper.h | 82 include/asm-blackfin/semaphore.h | 106 include/asm-blackfin/sembuf.h | 25 include/asm-blackfin/setup.h | 17 include/asm-blackfin/shmbuf.h | 42 include/asm-blackfin/shmparam.h | 6 include/asm-blackfin/sigcontext.h | 50 include/asm-blackfin/siginfo.h | 35 include/asm-blackfin/signal.h | 160 + include/asm-blackfin/socket.h | 52 include/asm-blackfin/sockios.h | 12 include/asm-blackfin/spinlock.h | 6 include/asm-blackfin/stat.h | 63 include/asm-blackfin/statfs.h | 6 include/asm-blackfin/string.h | 104 include/asm-blackfin/system.h | 253 ++ include/asm-blackfin/termbits.h | 184 + include/asm-blackfin/termios.h | 106 include/asm-blackfin/thread_info.h | 146 + include/asm-blackfin/timex.h | 18 include/asm-blackfin/tlb.h | 16 include/asm-blackfin/tlbflush.h | 62 include/asm-blackfin/topology.h | 6 include/asm-blackfin/tracehook.h | 79 include/asm-blackfin/traps.h | 75 include/asm-blackfin/types.h | 66 include/asm-blackfin/uaccess.h | 254 ++ include/asm-blackfin/ucontext.h | 30 include/asm-blackfin/unaligned.h | 6 include/asm-blackfin/unistd.h | 382 +++ include/asm-blackfin/user.h | 89 include/asm-blackfin/xor.h | 1 include/linux/elf-em.h | 1 include/linux/spi/ad7877.h | 24 include/linux/usb_sl811.h | 26 init/Kconfig | 2 lib/Kconfig.debug | 2 scripts/genksyms/genksyms.c | 3 scripts/mod/mk_elfconfig.c | 3 260 files changed, 51444 insertions(+), 5 deletions(-)
https://blackfin.uclinux.org/gf/download/frsrelease/39/2583/blackfin-arch.patch
---
Thanks
-Bryan Wu
Quoted 5 lines · Bryan
The whole patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2583/blackfin-arch.p
atch The incremental patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2584/blackfin-arch-m
m2-update.patch
I'm not sure if that was intentional, but the second patch does not apply on top of the -mm kernel but rather patch the the patch old itself. This basically makes it impossible to review just that part, so better provide the diff between the kernel with the old patch and the kernel with the new patch next time.
OTOH, from what I could see from the contents, the changes themselves look pretty good, I'd probably add my 'Acked-by' if I could read that patch more easily ;-)
Arnd <><
Quoted 9 lines · Arnd Bergmann
Quoted 2 lines · Bryan
The whole patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2583/blackfin-arch.p
Quoted 2 lines
atch The incremental patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2584/blackfin-arch-m
Quoted 1 line
m2-update.patch
Quoted 8 lines
I'm not sure if that was intentional, but the second patch does not apply
on top of the -mm kernel but rather patch the the patch old itself. This basically makes it impossible to review just that part, so better
provide the diff between the kernel with the old patch and the kernel with the new patch next time.
Sorry for messing up this incremental patch. Here is the updated incremental patch
---
arch/blackfin/Kconfig | 122 ++++++- arch/blackfin/kernel/entry.S | 4 arch/blackfin/kernel/irqchip.c | 5 arch/blackfin/kernel/process.c | 48 ++ arch/blackfin/kernel/setup.c | 41 +- arch/blackfin/kernel/signal.c | 5 arch/blackfin/kernel/sys_bfin.c | 16 arch/blackfin/kernel/time.c | 6 arch/blackfin/kernel/traps.c | 4 arch/blackfin/lib/ashldi3.c | 4 arch/blackfin/lib/ashrdi3.c | 4 arch/blackfin/lib/checksum.c | 4 arch/blackfin/lib/divsi3.S | 8 arch/blackfin/lib/lshrdi3.c | 4 arch/blackfin/lib/memcpy.S | 6 arch/blackfin/lib/memset.S | 6 arch/blackfin/lib/modsi3.S | 7 arch/blackfin/lib/muldi3.c | 4 arch/blackfin/lib/smulsi3_highpart.S | 6 arch/blackfin/lib/udivsi3.S | 9 arch/blackfin/lib/umodsi3.S | 5 arch/blackfin/lib/umulsi3_highpart.S | 6 arch/blackfin/mach-bf537/boards/stamp.c | 49 ++ arch/blackfin/mach-bf537/head.S | 1 arch/blackfin/mach-bf561/boards/generic_board.c | 2 arch/blackfin/mach-common/cache.S | 2 arch/blackfin/mach-common/cplbhdlr.S | 4 arch/blackfin/mach-common/cplbmgr.S | 4 arch/blackfin/mach-common/entry.S | 17 - arch/blackfin/mach-common/ints-priority-dc.c | 4 arch/blackfin/mach-common/ints-priority-sc.c | 4 include/asm-blackfin/cplbinit.h | 397 ++++++++++++------------ include/asm-blackfin/delay.h | 5 include/asm-blackfin/dma-mapping.h | 5 include/asm-blackfin/mach-bf533/bf533.h | 11 include/asm-blackfin/mach-bf533/mem_map.h | 62 ++- include/asm-blackfin/mach-bf537/bf537.h | 11 include/asm-blackfin/mach-bf537/defBF534.h | 2 include/asm-blackfin/mach-bf537/mem_map.h | 77 +++- include/asm-blackfin/mach-bf561/bf561.h | 5 include/asm-blackfin/mach-bf561/mem_map.h | 28 + include/asm-blackfin/pgtable.h | 8 include/asm-blackfin/uaccess.h | 41 -- include/asm-blackfin/unistd.h | 2 include/asm-blackfin/xor.h | 1 init/Kconfig | 3 46 files changed, 725 insertions(+), 344 deletions(-)
arch/blackfin/Kconfig +110 -12
@@ -9,6 +9,10 @@ config MMU bool default n +config ZONE_DMA + bool + default y + config FPU bool default n
@@ -21,6 +25,10 @@ config RWSEM_XCHGADD_ALGORITHM bool default n +config BLACKFIN + bool + default y + config BFIN bool default y
@@ -140,21 +148,14 @@ config BF_REV_0_5 endchoice -config BLACKFIN +config BFIN_DUAL_CORE bool - depends on (BF537 || BF536 \ - || BF534 || BF561 || BF535 || BF533 || BF532 || BF531) + depends on (BF561) default y config BFIN_SINGLE_CORE bool - depends on (BF537 || BF536 \ - || BF534 || BF535 || BF533 || BF532 || BF531) - default y - -config BFIN_DUAL_CORE - bool - depends on (BF561) + depends on !BFIN_DUAL_CORE default y choice
@@ -427,11 +428,104 @@ comment "Memory Optimizations" config I_ENTRY_L1 bool "Locate interrupt entry code in L1 Memory" - default n + default y help If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked into L1 instruction memory.(less latency) +config EXCPT_IRQ_SYSC_L1 + bool "Locate entire ASM lowlevel excepetion / interrupt - Syscall and CPLB handler code in L1 Memory" + default y + help + If enabled entire ASM lowlevel exception and interrupt entry code (STORE/RESTORE CONTEXT) is linked + into L1 instruction memory.(less latency) + +config DO_IRQ_L1 + bool "Locate frequently called do_irq dispatcher function in L1 Memory" + default y + help + If enabled frequently called do_irq dispatcher function is linked + into L1 instruction memory.(less latency) + +config CORE_TIMER_IRQ_L1 + bool "Locate frequently called timer_interrupt() function in L1 Memory" + default y + help + If enabled frequently called timer_interrupt() function is linked + into L1 instruction memory.(less latency) + +config IDLE_L1 + bool "Locate frequently idle function in L1 Memory" + default y + help + If enabled frequently called idle function is linked + into L1 instruction memory.(less latency) + +config SCHEDULE_L1 + bool "Locate kernel schedule function in L1 Memory" + default y + help + If enabled frequently called kernel schedule is linked + into L1 instruction memory.(less latency) + +config ARITHMETIC_OPS_L1 + bool "Locate kernel owned arithmetic functions in L1 Memory" + default y + help + If enabled arithmetic functions are linked + into L1 instruction memory.(less latency) + +config ACCESS_OK_L1 + bool "Locate access_ok function in L1 Memory" + default y + help + If enabled access_ok function is linked + into L1 instruction memory.(less latency) + +config MEMSET_L1 + bool "Locate memset function in L1 Memory" + default y + help + If enabled memset function is linked + into L1 instruction memory.(less latency) + +config MEMCPY_L1 + bool "Locate memcpy function in L1 Memory" + default y + help + If enabled memcpy function is linked + into L1 instruction memory.(less latency) + +config SYS_BFIN_SPINLOCK_L1 + bool "Locate sys_bfin_spinlock function in L1 Memory" + default y + help + If enabled sys_bfin_spinlock function is linked + into L1 instruction memory.(less latency) + +config IP_CHECKSUM_L1 + bool "Locate IP Checksum function in L1 Memory" + default n + help + If enabled IP Checksum function is linked + into L1 instruction memory.(less latency) + +config SYSCALL_TAB_L1 + bool "Locate Syscall Table L1 Data Memory" + default n + depends on !BF531 + help + If enabled the Syscall LUT is linked + into L1 data memory.(less latency) + +config CPLB_SWITCH_TAB_L1 + bool "Locate CPLB Switch Tables L1 Data Memory" + default n + depends on !BF531 + help + If enabled the CPLB Switch Tables are linked + into L1 data memory.(less latency) + endmenu
@@ -488,6 +582,10 @@ config BLKFIN_CACHE bool "Enable ICACHE" config BLKFIN_DCACHE bool "Enable DCACHE" +config BLKFIN_DCACHE_BANKA + bool "Enable only 16k BankA DCACHE - BankB is SRAM" + depends on BLKFIN_DCACHE && !BF531 + default n config BLKFIN_CACHE_LOCK bool "Enable Cache Locking"
@@ -817,7 +915,7 @@ config DEBUG_KERNEL_START config DEBUG_SERIAL_EARLY_INIT bool "Initialize serial driver early" default n - depends on SERIAL_BLACKFIN + depends on SERIAL_BFIN help Say Y here if you want to get kernel output early when kernel crashes before the normal console initialization. If this option
arch/blackfin/kernel/entry.S +4 -0
@@ -36,7 +36,11 @@ #include <asm/mach-common/context.S> +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else .text +#endif ENTRY(_ret_from_fork) SP += -12;
arch/blackfin/kernel/irqchip.c +5 -0
@@ -97,6 +97,11 @@ int show_interrupts(struct seq_file *p,* come via this function. Instead, they should provide their * own 'handler' */ + +#ifdef CONFIG_DO_IRQ_L1 +asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text)); +#endif + asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) {struct pt_regs *old_regs;
arch/blackfin/kernel/process.c +48 -0
57 lines not on this page · raw message
arch/blackfin/kernel/setup.c +31 -10
74 lines not on this page · raw message
arch/blackfin/kernel/signal.c +5 -0
@@ -66,6 +66,11 @@ struct rt_sigframe {struct ucontext uc; }; +asmlinkage int sys_sigaltstack(const stack_t * uss, stack_t * uoss) +{ +return do_sigaltstack (uss, uoss,rdusp ()); +} +static inline int rt_restore_ucontext (struct pt_regs *regs,struct ucontext *uc,int *pr0) {
arch/blackfin/kernel/sys_bfin.c +0 -16
@@ -115,19 +115,3 @@ asmlinkage void *sys_dma_memcpy(void *de {return safe_dma_memcpy (dest, src, len); } - -/* -* Do a system call from kernel instead of calling sys_execve so we -* end up with proper pt_regs. -*/ -int kernel_execve (const char *filename,char *const argv[],char *const envp[]) -{ - register long __res asm ("P0") = __NR_execve; - register long __a asm ("R0") = (long)(filename); - register long __b asm ("R1") = (long)(argv); - register long __c asm ("R2") = (long)(envp); - asmvolatile ("raise 15" :"+d" (__a) - :"d" (__res),"d" (__b),"d" (__c)); -return __a; -} -
arch/blackfin/kernel/time.c +5 -1
@@ -197,6 +197,10 @@ static inline int set_rtc_mmss(unsigned* timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick */ +#ifdef CONFIG_CORE_TIMER_IRQ_L1 +irqreturn_t timer_interrupt (int irq,void *dummy)__attribute__((l1_text)); +#endif +irqreturn_t timer_interrupt (int irq,void *dummy) {/* last time the cmos clock got updated */
@@ -243,7 +247,7 @@ void __init time_init(void)* userspace to have to deal with time values greater than * 2^31 seconds (which uClibc cannot cope with yet) */ -if (bfin_read_RTC_STAT () &0x60000000 ) { +if ((bfin_read_RTC_STAT () &0xC0000000 ) ==0xC0000000 ) {printk (KERN_NOTICE "bfin-rtc: invalid date; resetting\n" );bfin_write_RTC_STAT (0 ); }
arch/blackfin/kernel/traps.c +4 -0
@@ -622,6 +622,10 @@ void dump_bfin_regs(struct pt_regs *fp,printk ("\n\n" ); } +#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 +asmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); +#endif + asmlinkage int sys_bfin_spinlock(int *spinlock) {int ret =0 ;
arch/blackfin/lib/ashldi3.c +4 -0
@@ -31,6 +31,10 @@#include "gcclib.h" +#ifdef CONFIG_ARITHMETIC_OPS_L1 +DItype __ashldi3 (DItype u,word_type b)__attribute__((l1_text)); +#endif +DItype __ashldi3 (DItype u,word_type b) {DIunion w;
arch/blackfin/lib/ashrdi3.c +4 -0
@@ -31,6 +31,10 @@#include "gcclib.h" +#ifdef CONFIG_ARITHMETIC_OPS_L1 +DItype __ashrdi3 (DItype u,word_type b)__attribute__((l1_text)); +#endif +DItype __ashrdi3 (DItype u,word_type b) {DIunion w;
arch/blackfin/lib/checksum.c +4 -0
@@ -34,6 +34,10 @@#include <net/checksum.h> #include <asm/checksum.h> +#ifdef CONFIG_IP_CHECKSUM_L1 +static unsigned short do_csum (const unsigned char *buff,int len)__attribute__((l1_text)); +#endif +static unsigned short do_csum (const unsigned char *buff,int len) { registerunsigned long sum =0 ;
arch/blackfin/lib/divsi3.S +7 -1
@@ -46,7 +46,13 @@ .global ___divsi3; -.align 8; +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + +.align 2; ___divsi3 :
arch/blackfin/lib/lshrdi3.c +4 -0
@@ -45,6 +45,10 @@ typedef union {DItype ll; } DIunion; +#ifdef CONFIG_ARITHMETIC_OPS_L1 +DItype __lshrdi3 (DItype u,word_type b)__attribute__((l1_text)); +#endif +DItype __lshrdi3 (DItype u,word_type b) {DIunion w;
arch/blackfin/lib/memcpy.S +6 -0
@@ -36,6 +36,12 @@ #include <linux/linkage.h> +#ifdef CONFIG_MEMCPY_L1 +.section .l1.text +#else +.text +#endif + .align 2 ENTRY(_memcpy)
arch/blackfin/lib/memset.S +6 -0
@@ -33,6 +33,12 @@ .align 2 +#ifdef CONFIG_MEMSET_L1 +.section .l1.text +#else +.text +#endif + /* * C Library function MEMSET * R0 = address (leave unchanged to form result)
arch/blackfin/lib/modsi3.S +7 -0
@@ -39,6 +39,13 @@ .type ___modsi3, STT_FUNC; .extern ___divsi3; .type ___divsi3, STT_FUNC; + +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + ___modsi3: CC=R0==0;
arch/blackfin/lib/muldi3.c +4 -0
@@ -83,6 +83,10 @@ typedef union {ditype ll; } diunion; +#ifdef CONFIG_ARITHMETIC_OPS_L1 +ditype __muldi3 (ditype u,ditype v)__attribute__((l1_text)); +#endif +ditype __muldi3 (ditype u,ditype v) {diunion w;
arch/blackfin/lib/smulsi3_highpart.S +6 -0
@@ -2,6 +2,12 @@ .global ___smulsi3_highpart; .type ___smulsi3_highpart, STT_FUNC; +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + ___smulsi3_highpart: R2 = R1.L * R0.L (FU); R3 = R1.H * R0.L (IS,M);
arch/blackfin/lib/udivsi3.S +8 -1
@@ -33,6 +33,13 @@ #define CARRY AC0 +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + + ENTRY(___udivsi3) CC = R0 < R1 (IU); /* If X < Y, always return 0 */
@@ -105,7 +112,7 @@ ENTRY(___udivsi3) ** with some post-adjustment */ R3 = R1 >> 1; /* Pre-scaled divisor for primitive case */ - R2 = R0 >> 16 ; + R2 = R0 >> 16; R2 = R3 - R2; /* shifted divisor < upper 16 bits of dividend */ CC &= CARRY;
arch/blackfin/lib/umodsi3.S +5 -0
@@ -29,7 +29,12 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else .text +#endif + .extern ___udivsi3; .globl ___umodsi3 ___umodsi3:
arch/blackfin/lib/umulsi3_highpart.S +6 -0
@@ -2,6 +2,12 @@ .global ___umulsi3_highpart; .type ___umulsi3_highpart, STT_FUNC; +#ifdef CONFIG_ARITHMETIC_OPS_L1 +.section .l1.text +#else +.text +#endif + ___umulsi3_highpart: R2 = R1.H * R0.H, R3 = R1.L * R0.H (FU); R0 = R1.L * R0.L, R1 = R1.H * R0.L (FU);
arch/blackfin/mach-bf537/boards/stamp.c +49 -0
61 lines not on this page · raw message
arch/blackfin/mach-bf537/head.S +0 -1
@@ -240,7 +240,6 @@ ENTRY(__stext) r0 = AMGCTLVAL; w[p2] = r0; ssync; - call _real_start; /* This section keeps the processor in supervisor mode * during kernel boot. Switches to user mode at end of boot.
arch/blackfin/mach-bf561/boards/generic_board.c +2 -0
@@ -34,6 +34,8 @@#include <linux/platform_device.h> #include <asm/irq.h> +char *bfin_board_name ="UNKNOWN BOARD" ; +/* * Driver needs to know address, irq and flag pin. */
arch/blackfin/mach-common/cache.S +1 -1
@@ -211,7 +211,7 @@ ENTRY(_dcache_invalidate) /* Configures the data cache again */ - R6 = (ACACHE_BCACHE | ENDCPLB | PORT_PREF0); + R6 = DMEM_CNTR; R7 = R7 | R6; CLI R6;
arch/blackfin/mach-common/cplbhdlr.S +4 -0
@@ -33,7 +33,11 @@ #include <asm/cplb.h> #include <asm/entry.h> +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else .text +#endif .type _cplb_mgr, STT_FUNC; .type _panic_cplb_error, STT_FUNC;
arch/blackfin/mach-common/cplbmgr.S +4 -0
@@ -55,7 +55,11 @@ #include <asm/blackfin.h> #include <asm/cplb.h> +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else .text +#endif .align 2; ENTRY(_cplb_mgr)
arch/blackfin/mach-common/entry.S +14 -3
@@ -79,13 +79,18 @@ # define DEBUG_STOP_HWTRACE #endif +#ifdef CONFIG_EXCPT_IRQ_SYSC_L1 +.section .l1.text +#else .text +#endif /* Slightly simplified and streamlined entry point for CPLB misses. * This one does not lower the level to IRQ5, and thus can be used to * patch up CPLB misses on the kernel stack. */ ENTRY(_ex_dcplb) +#if defined(ANOMALY_05000261) /* * Work around an anomaly: if we see a new DCPLB fault, return * without doing anything. Then, if we get the same fault again,
@@ -99,6 +104,7 @@ ENTRY(_ex_dcplb) cc = r6 == r7; if !cc jump _return_from_exception; /* fall through */ +#endif ENTRY(_ex_icplb) (R7:6,P5:4) = [sp++];
@@ -333,7 +339,7 @@ ENTRY(_trap) /* Exception: 4th entry int [sp + PT_R0] = r7; /* return value from system call */ jump .Lsyscall_really_exit; -ENTRY(_execve) +ENTRY(_kernel_execve) link SIZEOF_PTREGS; p0 = sp; r3 = SIZEOF_PTREGS / 4;
@@ -749,7 +755,11 @@ ENTRY(_init_exception_buff) * a CPLB. This is needed to ensure we don't get double fault conditions */ +#ifdef CONFIG_SYSCALL_TAB_L1 +.section .l1.data +#else .data +#endif ALIGN _extable: /* entry for each EXCAUSE[5:0]
@@ -1010,7 +1020,7 @@ ENTRY(_sys_call_table) .long _sys_getcwd .long _sys_capget .long _sys_capset /* 185 */ - .long _sys_ni_syscall /* old sys_sigaltstack */ + .long _sys_sigaltstack .long _sys_sendfile .long _sys_ni_syscall /* streams1 */ .long _sys_ni_syscall /* streams2 */
@@ -1178,10 +1188,11 @@ _exception_stack: .endr _exception_stack_top: +#if defined(ANOMALY_05000261) /* Used by the assembly entry point to work around an anomaly. */ _last_cplb_fault_retx: .long 0; - +#endif /* * Single instructions can have multiple faults, which need to be * handled by traps.c, in irq5. We store the exception cause to ensure
arch/blackfin/mach-common/ints-priority-dc.c +4 -0
@@ -438,6 +438,10 @@ int __init init_arch_irq(void)return 0 ; } +#ifdef CONFIG_DO_IRQ_L1 +void do_irq (int vec,struct pt_regs *fp)__attribute__((l1_text)); +#endif +void do_irq (int vec,struct pt_regs *fp) {if (vec ==EVT_IVTMR_P ) {
arch/blackfin/mach-common/ints-priority-sc.c +4 -0
@@ -547,6 +547,10 @@ int __init init_arch_irq(void)return 0 ; } +#ifdef CONFIG_DO_IRQ_L1 +void do_irq (int vec,struct pt_regs *fp)__attribute__((l1_text)); +#endif +void do_irq (int vec,struct pt_regs *fp) {if (vec ==EVT_IVTMR_P ) {
include/asm-blackfin/cplbinit.h +205 -192
397 lines not on this page · raw message
include/asm-blackfin/delay.h +3 -2
@@ -7,10 +7,11 @@ static inline void __delay(unsigned long/* FIXME: Currently the assembler doesn't recognize Loop Register Clobbers, uncomment this as soon those are implemented */ /* -__asm__ __volatile__ ( "\t LSETUP (1,1) LC0= %0\n\t" -"l:\t NOP;\n\t" +__asm__ __volatile__ ( "\t LSETUP (1f,1f) LC0= %0\n\t" +"1:\t NOP;\n\t" : :"a" (loops) : "LT0","LB0","LC0"); +*/ __asm__ __volatile__("[--SP] = LC0;\n\t"
include/asm-blackfin/dma-mapping.h +5 -0
@@ -65,4 +65,9 @@ static inline BUG_ON(direction == DMA_NONE); } +/* Now for the API extensions over the pci_ one */ + +#define dma_alloc_noncoherent (d, s, h, f) dma_alloc_coherent(d, s, h, f) +#define dma_free_noncoherent (d, s, v, h) dma_free_coherent(d, s, v, h) +#endif /* _BLACKFIN_DMA_MAPPING_H */
include/asm-blackfin/mach-bf533/bf533.h +1 -10
@@ -53,15 +53,6 @@/***************************/ -#define BLKFIN_ICACHESIZE (16*1024) - -#if defined(CONFIG_BF533 ) || defined(CONFIG_BF532 ) -#define BLKFIN_DCACHESIZE (32*1024) -#define BLKFIN_DSUPBANKS 2 -#else -#define BLKFIN_DCACHESIZE (16*1024) -#define BLKFIN_DSUPBANKS 1 -#endif #define BLKFIN_DSUBBANKS 4#define BLKFIN_DWAYS 2
@@ -280,7 +271,7 @@ | CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND)#endif -#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) +#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
include/asm-blackfin/mach-bf533/mem_map.h +48 -14
103 lines not on this page · raw message
include/asm-blackfin/mach-bf537/bf537.h +1 -10
@@ -63,15 +63,6 @@/***************************/ -#define BLKFIN_ICACHESIZE (16*1024) - -#if defined(CONFIG_BF537 ) || defined(CONFIG_BF534 ) -#define BLKFIN_DCACHESIZE (32*1024) -#define BLKFIN_DSUPBANKS 2 -#else -#define BLKFIN_DCACHESIZE (16*1024) -#define BLKFIN_DSUPBANKS 1 -#endif #define BLKFIN_DSUBBANKS 4#define BLKFIN_DWAYS 2
@@ -261,7 +252,7 @@#endif -#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY ) +#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY )#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY )
include/asm-blackfin/mach-bf537/defBF534.h +1 -1
@@ -1171,7 +1171,7 @@#define GM 0x0008/* Get More (When RDBR Full, Overwrite/Discard*) */ #define PSSE 0x0010/* Slave-Select Input Enable */ #define EMISO 0x0020/* Enable MISO As Output */ -#define SIZE 0x0100/* Size of Words (16/8* Bits) */ +#define SPI_SIZE 0x0100/* Size of Words (16/8* Bits) */ #define LSBF 0x0200/* LSB First */ #define CPHA 0x0400/* Clock Phase */ #define CPOL 0x0800/* Clock Polarity */
include/asm-blackfin/mach-bf537/mem_map.h +58 -19
121 lines not on this page · raw message
include/asm-blackfin/mach-bf561/bf561.h +1 -4
@@ -74,14 +74,11 @@* Blackfin Cache setup */ -#define BLKFIN_ICACHESIZE (16*1024) -#define BLKFIN_DCACHESIZE (32*1024)#define BLKFIN_ISUBBANKS 4#define BLKFIN_IWAYS 4#define BLKFIN_ILINES 32 -#define BLKFIN_DSUPBANKS 2#define BLKFIN_DSUBBANKS 4#define BLKFIN_DWAYS 2#define BLKFIN_DLINES 64
@@ -351,7 +348,7 @@#endif -#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY) +#define L1_DMEMORY (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)#define SDRAM_DNON_CHBL (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)#define SDRAM_EBIU (CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_DIRTY)#define SDRAM_OOPS (CPLB_VALID | ANOMALY_05000158_WORKAROUND | CPLB_LOCK | CPLB_DIRTY)
include/asm-blackfin/mach-bf561/mem_map.h +22 -6
@@ -23,6 +23,12 @@/* Level 1 Memory */ +#ifdef CONFIG_BLKFIN_CACHE +#define BLKFIN_ICACHESIZE (16*1024) +#else +#define BLKFIN_ICACHESIZE (0*1024) +#endif +/* Memory Map for ADSP-BF561 processors */ #ifdef CONFIG_BF561
@@ -33,18 +39,28 @@#define L1_CODE_LENGTH 0x4000#ifdef CONFIG_BLKFIN_DCACHE -#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) + +#ifdef CONFIG_BLKFIN_DCACHE_BANKA +#define DMEM_CNTR (ACACHE_BSRAM | ENDCPLB | PORT_PREF0)#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH 0x8000 +#define BLKFIN_DCACHESIZE (16*1024) +#define BLKFIN_DSUPBANKS 1#else -#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) -#define L1_DATA_A_LENGTH 0x8000 +#define DMEM_CNTR (ACACHE_BCACHE | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH (0x8000 - 0x4000) +#define L1_DATA_B_LENGTH (0x8000 - 0x4000) +#define BLKFIN_DCACHESIZE (32*1024) +#define BLKFIN_DSUPBANKS 2#endif -#ifdef CONFIG_BLKFIN_DCACHE -#define L1_DATA_B_LENGTH (0x8000 - 0x4000)#else +#define DMEM_CNTR (ASRAM_BSRAM | ENDCPLB | PORT_PREF0) +#define L1_DATA_A_LENGTH 0x8000#define L1_DATA_B_LENGTH 0x8000 -#endif +#define BLKFIN_DCACHESIZE (0*1024) +#define BLKFIN_DSUPBANKS 0 +#endif /*CONFIG_BLKFIN_DCACHE*/ #endif /* Level 2 Memory */
include/asm-blackfin/pgtable.h +8 -0
@@ -59,4 +59,12 @@ extern unsigned int kobjsize(const void#define VMALLOC_START 0#define VMALLOC_END 0xffffffff +#define __HAVE_ARCH_ENTER_LAZY_CPU_MODE +#define arch_enter_lazy_cpu_mode () do {} while (0) +#define arch_leave_lazy_cpu_mode () do {} while (0) + +#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE +#define arch_enter_lazy_mmu_mode () do {} while (0) +#define arch_leave_lazy_mmu_mode () do {} while (0) +#endif /* _BLACKFIN_PGTABLE_H */
include/asm-blackfin/uaccess.h +4 -37
52 lines not on this page · raw message
include/asm-blackfin/unistd.h +1 -1
@@ -188,7 +188,7 @@#define __NR_getcwd 183#define __NR_capget 184#define __NR_capset 185 -/* 186 __NR_sigaltstack obsolete */ +#define __NR_sigaltstack 186#define __NR_sendfile 187/* 188 __NR_getpmsg */ /* 189 __NR_putpmsg */
include/asm-blackfin/xor.h +1 -0
@@ -0,0 +1 @@ +#include <asm-generic/xor.h>
init/Kconfig +1 -2
@@ -336,7 +336,7 @@ menuconfig EMBEDDED config UID16 bool "Enable 16-bit UID system calls" if EMBEDDED - depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) || BFIN + depends on ARM || BFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION) default y help This enables the legacy 16-bit UID syscall wrappers.
@@ -443,7 +443,6 @@ config FUTEX config EPOLL bool "Enable eventpoll support" if EMBEDDED default y - depends on MMU help Disabling this option will cause the kernel to be built without support for epoll family of system calls.
_
Thanks
-Bryan Wu
Quoted 3 lines · Bryan
Here is the update version of blackfin-arch.patch in -mm tree. simply add support to utrace and it was tested on blackfin STAMP board as well as other following patches.
Wow, this has come a long way since I looked at the patches last year, good work!
I've gone through the complete patch again now, and these are the issues I've found in it. None of these are show-stoppers and I'd like to see it all go in during the next merge window. There should be enough time until then to address these points:
Quoted 5 lines
(quoted diff) +5
-0+EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(dump_thread); +
Review
Quoted 10 lines
(quoted diff) +10
-0+EXPORT_SYMBOL(ip_fast_csum); + +EXPORT_SYMBOL(kernel_thread); + +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_trylock); +EXPORT_SYMBOL(__down_interruptible); + +EXPORT_SYMBOL(is_in_rom);
In general, please put EXPORT_SYMBOL lines below the definition of the symbol itself. This list of exports should only be used for symbols that come from assembly files.
You should probably also think about whether some of them are better done as EXPORT_SYMBOL_GPL.
Review
Quoted 6 lines
(quoted diff) +6
-0+ pending = bfin_read_IPEND() & ~0x8000; + other_ints = pending & (pending - 1); + if (other_ints == 0) + lower_to_irq14(); + irq_exit(); +
The last line here has trailing whitespace. While this gets automatically removed by akpm's scripts, you're normally better off not adding it in the first place, because it may cause your follow-on patches not to apply, aside from being wrong to start with.
Review
Quoted 11 lines
(quoted diff) +11
-0+void machine_halt(void) +{ + for (;;) + /* nothing */ ; +} + +void machine_power_off(void) +{ + for (;;) + /* nothing */ ; +}
It might be nicer to make this
for (;;)
asm volatile ("idle");Otherwise you end up burning CPU cycles after a halt without any particular need.
Quoted 13 lines
(quoted diff) +13
-0+#if defined(CONFIG_MTD_UCLINUX) + /* generic memory mapped MTD driver */ + memory_mtd_end = memory_end; + + mtd_phys = _ramstart; + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); + +# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) + if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) + mtd_size = + PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); +# endif +
Review
Quoted 10 lines
(quoted diff) +10
-0+# if defined(CONFIG_CRAMFS) + if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); +# endif + +# if defined(CONFIG_ROMFS_FS) + if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 + && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) + mtd_size = + PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
This detection seems to me like a strange thing to do in setup_arch(). It should be possible to do this much later, at a point where the system is much less fragile and e.g. printk works. It could even be moved into some place in the mtd code itself, since other architectures might want to do the same thing.
Quoted 5 lines
(quoted diff) +5
-0+#if defined(CONFIG_BF561) +static struct cpu cpu[2]; +#else +static struct cpu cpu[1]; +#endif
Review
Quoted 10 lines
(quoted diff) +10
-0+static int __init topology_init(void) +{ +#if defined (CONFIG_BF561) + register_cpu(&cpu[0], 0); + register_cpu(&cpu[1], 1); + return 0; +#else + return register_cpu(cpu, 0); +#endif +}
I think you should try to avoid the special-case stuff here. You can have CONFIG_NR_CPUS in Kconfig set dependent on CONFIG_BF561 and change the code here (and similarly in other places) to
static struct cpu cpu[NR_CPUS];
static int __init topology_init(void)
{
int i;
for (i=0; i< NR_CPUS; i++) {
register_cpu(&cpu[i], i);
return 0;
}Review
Quoted 8 lines
(quoted diff) +8
-0+ for (i = ZERO_P; i <= L2_MEM; i++) { + + if (cplb_data[i].valid) { + + as_1m = cplb_data[i].start % SIZE_1M; + + /* We need to make sure all sections are properly 1M aligned + * However between Kernel Memory and the Kernel mtd section, depending
on the
Review
Quoted 8 lines
(quoted diff) +8
-0+ * rootfs size, there can be overlapping memory areas. + */ + + if (as_1m) { +#ifdef CONFIG_MTD_UCLINUX + if (i == SDRAM_RAM_MTD) { + if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start) + cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M))
+ SIZE_1M;
I count 6 levels of indentation, which severely limits readability, especially when you have terms this complex in the last level. Please try to split up functions like this into smaller units.
Quoted 3 lines
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one
time.
Quoted 1 line
+ * If a second signal with
SA_ONSTACKset arrives while working on a
sigstack,
Quoted 3 lines
+ *
SA_ONSTACKis ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
This comment is probably outdated.
Quoted 1 line
+extern int
setup_irq(unsigned int irq, struct irqaction *handler);
this extern should be in a header.
Review
Quoted 8 lines
(quoted diff) +8
-0+asmlinkage void trap_c(struct pt_regs *fp) +{ + int j, sig = 0; + siginfo_t info; + unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; + +#ifdef CONFIG_KGDB +# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code,
fp,); } while (0)
Quoted 1 line
+# define
CHK_DEBUGGER_TRAP_MAYBE()do { if (kgdb_connected)
CHK_DEBUGGER_TRAP(); } while (0)
Quoted 38 lines
(quoted diff) +38
-0+#else +# define CHK_DEBUGGER_TRAP() do { } while (0) +# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) +#endif + + trace_buffer_save(j); + + /* trap_c() will be called for exceptions. During exceptions + * processing, the pc value should be set with retx value. + * With this change we can cleanup some code in signal.c- TODO + */ + fp->orig_pc = fp->retx; + /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", + trapnr, fp->ipend, fp->pc, fp->retx); */ + + /* send the appropriate signal to the user program */ + switch (trapnr) { + + /* This table works in conjuction with the one in ./mach-common/entry.S + * Some exceptions are handled there (in assembly, in exception space) + * Some are handled here, (in C, in interrupt space) + * Some, like CPLB, are handled in both, where the normal path is + * handled in assembly/exception space, and the error path is handled + * here + */ + + /* 0x00 - Linux Syscall, getting here is an error */ + /* 0x01 - userspace gdb breakpoint, handled here */ + case VEC_EXCPT01: + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP_MAYBE(); + /* Check if this is a breakpoint in kernel space */ + if (fp->ipend & 0xffc0) + return; + else + break; +#ifdef CONFIG_KGDB
Review
Quoted 10 lines
(quoted diff) +10
-0+ case VEC_EXCPT02 : /* gdb connection */ + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP(); + return; +#else + /* 0x02 - User Defined, Caught by default */ +#endif + /* 0x03 - Atomic test and set */ + case VEC_EXCPT03:
The table here probably gets converted by gcc into a lookup table, but I think it would be clearer to make that explicit and force the table here with something like:
static void trap_breakpoint(struct pt_regs *fp, siginfo_t *info,
unsigned int trapnr)
{
info->si_code = TRAP_ILLTRAP;
CHK_DEBUGGER_TRAP_MAYBE();
if (fp->ipend & 0xffc0)
return 0;
return SIGTRAP;
}#ifdef CONFIG_KGDB
static void trap_kgdb(struct pt_regs *fp, siginfo_t *info,
unsigned int trapnr)
{
info->si_code = TRAP_ILLTRAP;
CHK_DEBUGGER_TRAP();
return SIGTRAP;
}#endif
static void (traps[])(struct pt_regs *fp, siginfo_t *info,
unsigned int trapnr) = {
[VEC_EXCPT01] &trap_breakpoint, /* 0x01 - userspace gdb breakpoint */
#ifdef CONFIG_KGDB
[VEC_EXCPT02] &trap_kgdb, /* gdb connection */
#endif
...
};asmlinkage void trap_c(struct pt_regs *fp)
{
...
if (trapnr > 0x3f)
goto error;
if (!traps[trapnr])
goto out;
ret = traps[trapno](fp, &info, trapnr);
if (!ret)
goto out;
...That should make sure you get the efficient trap handling almost and might even
save some code space (you'd have to try that).
Quoted 6 lines
(quoted diff) +6
-0+asmlinkage int sys_bfin_spinlock(int *spinlock) +{ + int ret = 0; + int tmp = 0; + + local_irq_disable();
Review
Quoted 10 lines
(quoted diff) +10
-0+ ret = get_user(tmp, spinlock); + if (ret == 0) { + if (tmp) + ret = 1; + tmp = 1; + put_user(tmp, spinlock); + } + local_irq_enable(); + return ret; +}
I'm curious: In your dual-core bf561, don't you actually need to implement something that maintains atomicity across cores rather than just across processes?
Review
Quoted 5 lines
(quoted diff) +5
-0+#include <net/checksum.h> +#include <asm/checksum.h> + +#ifdef CONFIG_IP_CHECKSUM_L1 +static unsigned short do_csum(const unsigned char *buff, int
len)__attribute__((l1_text));
Review
Quoted 13 lines
(quoted diff) +13
-0+#endif + +static unsigned short do_csum(const unsigned char *buff, int len) +{ + register unsigned long sum = 0; + int swappem = 0; + + if (1 & (unsigned long)buff) { + sum = *buff << 8; + buff++; + len--; + ++swappem; + }
For the non-L1 case, is there actually anything specific to blackfin in this code? I wonder if we should instead have a totally generic version of that in lib/csum.c for those architectures that don't want their own optimizations for this.
Review
Quoted 12 lines
(quoted diff) +12
-0+static struct platform_device *stamp_devices[] __initdata = { +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) + &bfin_pcmcia_cf_device, +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) + &sl811_hcd_device, +#endif
This array reminds me of the bad old days when all initialization functions had to be called from a common function. Normally I don't like to recommend using section magic for anything, but in this case I guess you'd be better off if you just do your own thing here, like:
#define BFIN_PLATFORM_DEVICE(name) struct platform_device name \
__attribute((section("initdata.platformdev")))
then declare your platform devices in the respective driver, like
static BFIN_PLATFORM_DEVICE(rtc_device) = {
...
};and loop through the new section like you do for the initcalls.
Review
Quoted 10 lines
(quoted diff) +10
-0+void get_bf537_ether_addr(char *addr) +{ + /* currently the mac addr is saved in flash */ + int flash_mac = 0x203f0000; + *(u32 *)(&(addr[0])) = *(int *)flash_mac; + flash_mac += 4; + *(u16 *)(&(addr[4])) = (u16)*(int *)flash_mac; +} + +EXPORT_SYMBOL(get_bf537_ether_addr);
This looks wrong in a number of aspects. Are there other things stored in the flash so you can make this a more general flash abstraction? Is there more than one driver using this at all? If not, it should probably be part of the driver, with the exact address being a compile-time constant for that driver.
It should probably also use bfin_readXX instead direct dereferences.
Review
Quoted 2 lines
(quoted diff) +2
-0+/* The number of spurious interrupts */ +volatile unsigned int num_spurious;
Why volatile? It probably does not what you intended, maybe it should be atomic_t instead.
Quoted 7 lines
(quoted diff) +7
-0+/* BASE LEVEL interrupt handler routines */ +asmlinkage void evt_emulation(void); +asmlinkage void evt_exception(void); +asmlinkage void trap(void); +asmlinkage void evt_ivhw(void); +asmlinkage void evt_timer(void); +asmlinkage void evt_evt2(void);
Review
Quoted 10 lines
(quoted diff) +10
-0+asmlinkage void evt_evt7(void); +asmlinkage void evt_evt8(void); +asmlinkage void evt_evt9(void); +asmlinkage void evt_evt10(void); +asmlinkage void evt_evt11(void); +asmlinkage void evt_evt12(void); +asmlinkage void evt_evt13(void); +asmlinkage void evt_soft_int1(void); +asmlinkage void evt_system_call(void); +asmlinkage void init_exception_buff(void);
move the extern definitions to a header file please
Quoted 6 lines
(quoted diff) +6
-0+/* BASE LEVEL interrupt handler routines */ +asmlinkage void evt_emulation(void); +asmlinkage void evt_exception(void); +asmlinkage void trap(void); +asmlinkage void evt_ivhw(void); +asmlinkage void evt_timer(void);
Review
Quoted 10 lines
(quoted diff) +10
-0+asmlinkage void evt_evt2(void); +asmlinkage void evt_evt7(void); +asmlinkage void evt_evt8(void); +asmlinkage void evt_evt9(void); +asmlinkage void evt_evt10(void); +asmlinkage void evt_evt11(void); +asmlinkage void evt_evt12(void); +asmlinkage void evt_evt13(void); +asmlinkage void evt_soft_int1(void); +asmlinkage void evt_system_call(void);
Then you don't have to write them twice ;-)
Quoted 8 lines
(quoted diff) +8
-0+static __inline__ void atomic_add(int i, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter += i; + local_irq_restore(flags); +}
Review
Quoted 10 lines
(quoted diff) +10
-0+ +static __inline__ void atomic_sub(int i, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter -= i; + local_irq_restore(flags); + +}
The implementation of the atomic_t type looks very generic. Maybe it could be moved to asm-generic/atomic-irqdisable.h or similar to be shared by all architectures without atomic operations.
Quoted 16 lines
(quoted diff) +16
-0+struct spi_device_t { + char *dev_name; + + unsigned short flag; + unsigned short bdrate; + + unsigned short enable; + unsigned short master; + unsigned short out_opendrain; + unsigned short polar; + unsigned short phase; + unsigned short byteorder; /* 0: MSB first; 1: LSB first; */ + unsigned short size; /* 0: 8 bits; 1: 16 bits */ + unsigned short emiso; + unsigned short send_zero; + unsigned short more_data;
Review
Quoted 10 lines
(quoted diff) +10
-0+ unsigned short slave_sel; + unsigned short ti_mod; + + unsigned short dma; /* use dma mode or not */ + unsigned short dma_config; /* only valid if dma enabled */ + + irqreturn_t(*irq_handler) (int irq, void *dev_id, + struct pt_regs *regs); + void *priv_data; +};
How does this fit in with the generic SPI code? Does it duplicate stuff from there, or do you use it?
Quoted 12 lines
(quoted diff) +12
-0+static __inline__ void set_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a |= mask; + local_irq_restore(flags); +}
Review
Quoted 10 lines
(quoted diff) +10
-0+ +static __inline__ void __set_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a |= mask; +}
same as for the atomic header, this could become generic.
Quoted 32 lines
(quoted diff) +32
-0+#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define SSYNC() do { int _tmp; \ + __asm__ __volatile__ ("cli %0;\n\t"\ + "nop;nop;\n\t"\ + "ssync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define SSYNC() do { int _tmp; \ + __asm__ __volatile__ ("cli %0;\n\t"\ + "ssync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define SSYNC() do {__builtin_bfin_ssync();} while (0) +#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define SSYNC() do {__asm__ __volatile__ ("ssync;\n\t") } while (0) +#endif + + +#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define CSYNC() do { int _tmp; \ + __asm__ __volatile__ ("cli %0;\n\t"\ + "nop;nop;\n\t"\ + "csync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define CSYNC() do { int _tmp; \
Review
Quoted 10 lines
(quoted diff) +10
-0+ __asm__ __volatile__ ("cli %0;\n\t"\ + "csync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define CSYNC() do {__builtin_bfin_csync();} while (0) +#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define CSYNC() do {__asm__ __volatile__ ("csync;\n\t") } while (0) +#endif
it would be nice if you could convert these to inline functions instead of macros.
Quoted 1 line
+static inline struct
task_struct*get_current(void)__attribute__
((__const__));
Review
Quoted 6 lines
(quoted diff) +6
-0+static inline struct task_struct *get_current(void) +{ + return (current_thread_info()->task); +} + +#define current (get_current())
You might want to maintain the current variable in the L1 memory, but probably that difference it not measurable.
Review
Quoted 9 lines
(quoted diff) +9
-0+#ifdef BFIN_DMA_NDEBUG +#define assert(expr) do {} while(0) +#else +#define assert(expr) \ + if (!(expr)) { \ + printk(KERN_INFO "Assertion failed! %s, %s, %s, line=%d \n", \ + #expr, __FILE__,__FUNCTION__,__LINE__); \ + } +#endif
Please don't define your own assert() functions, in the kernel we have BUG_ON and WARN_ON for this.
Quoted 30 lines
(quoted diff) +30
-0+#ifndef _BLACKFIN_DPMC_H_ +#define _BLACKFIN_DPMC_H_ + +#define SLEEP_MODE 1 +#define DEEP_SLEEP_MODE 2 +#define ACTIVE_PLL_DISABLED 3 +#define FULLON_MODE 4 +#define ACTIVE_PLL_ENABLED 5 +#define HIBERNATE_MODE 6 + +#define IOCTL_FULL_ON_MODE _IO('s', 0xA0) +#define IOCTL_ACTIVE_MODE _IO('s', 0xA1) +#define IOCTL_SLEEP_MODE _IO('s', 0xA2) +#define IOCTL_DEEP_SLEEP_MODE _IO('s', 0xA3) +#define IOCTL_HIBERNATE_MODE _IO('s', 0xA4) +#define IOCTL_CHANGE_FREQUENCY _IOW('s', 0xA5, unsigned long) +#define IOCTL_CHANGE_VOLTAGE _IOW('s', 0xA6, unsigned long) +#define IOCTL_SET_CCLK _IOW('s', 0xA7, unsigned long) +#define IOCTL_SET_SCLK _IOW('s', 0xA8, unsigned long) +#define IOCTL_GET_PLLSTATUS _IOW('s', 0xA9, unsigned long) +#define IOCTL_GET_CORECLOCK _IOW('s', 0xAA, unsigned long) +#define IOCTL_GET_SYSTEMCLOCK _IOW('s', 0xAB, unsigned long) +#define IOCTL_GET_VCO _IOW('s', 0xAC, unsigned long) +#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD) +#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE) +#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long) +#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0) +#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1) + +#define DPMC_MINOR 254
Review
Quoted 10 lines
(quoted diff) +10
-0+ +#define ON 0 +#define OFF 1 + +unsigned long calc_volt(void); +int calc_vlev(int vlt); +unsigned long change_voltage(unsigned long volt); +int calc_msel(int vco_hz); +unsigned long change_frequency(unsigned long vco_mhz); +int set_pll_div(unsigned short sel, unsigned char flag);
In general, you should be careful not to mix in-kernel declarations with user-visible parts. In this case, the ioctl definitions need to be exported via 'make headers_install', while the function declarations clearly are not useful for user space and should therefore be inside of '#ifdef __KERNEL__'. You should then list this file as 'unifdef-y' in the Kbuild file.
Review
Quoted 3 lines
(quoted diff) +3
-0+ +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2)
set_personality((ibcs2)?PER_SVR4:PER_LINUX)
Quoted 1 line
+#endif
This looks bogus, I don't think you implement personalities.
Quoted 5 lines
(quoted diff) +5
-0+#define readb(addr) ({ unsigned __v; \ + int _tmp; \ + __asm__ __volatile__ ("cli %1;\n\t"\ + "NOP;NOP;SSYNC;\n\t"\ + "%0 = b [%2] (z);\n\t"\
Review
Quoted 10 lines
(quoted diff) +10
-0+ "sti %1;\n\t" \ + : "=d"(__v), "=d"(_tmp): "a"(addr)); (unsigned char)__v; }) + +#define readw(addr) ({ unsigned __v; \ + int _tmp; \ + __asm__ __volatile__ ("cli %1;\n\t"\ + "NOP;NOP;SSYNC;\n\t"\ + "%0 = w [%2] (z);\n\t"\ + "sti %1;\n\t" \ + : "=d"(__v), "=d"(_tmp): "a"(addr)); (unsigned short)__v; })
They should probably be inline functions.
Quoted 33 lines
(quoted diff) +33
-0+#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420
Review
Quoted 10 lines
(quoted diff) +10
-0+#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux
device) */
Quoted 1 line
+#define TIOCSPTLCK
_IOW('T',0x31, int)/* Lock/unlock Pty */
These look like another good candidate for an asm-generic version.
Review
Quoted 2 lines
(quoted diff) +2
-0+ +extern void sys_free_irq(unsigned int irq, void *dev_id);
This functions should probably be renamed. Anything that starts with 'sys_' is normally a system call.
+
Review
Quoted 10 lines
(quoted diff) +10
-0+/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */ +#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val) +#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val) +#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT) +#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val) +#define bfin_read_CHIPID() bfin_read32(CHIPID) +#define bfin_read_SWRST() bfin_read16(SWRST) +#define bfin_write_SWRST(val) bfin_write16(SWRST,val)
I remember that we have discussed these macro abstractions before, but don't recall the result of the discussion. You have around 5000 such macros, and I still think it's not a helpful abstraction. It is much more common for device drivers to just use the read/write accessors directly. IIRC the objections that were raised (and my replies to them) were roughly:
Quoted 3 lines
the driver writer doesn't want to know the size of the variable, and if it changes, they need to change every instance in the code, not just the macro.
A driver writer should better know the type of variable he is changing, e.g. because of the type he passes in and out. Also, hardware registers don't suddenly change in size.
Quoted 3 lines
These macros allow us to work around hardware bugs when accessing the registers by simply redefining the accessor to do something more complex.
If there is a bug in the hardware, the workaround belongs into the driver. You can then still define a special inline function to access that particular register.
Arnd <><
Quoted 4 lines · Arnd Bergmann
It might be nicer to make this
for (;;) asm volatile ("idle");
This looks remarkably like relax_cpu()
Signature · 2 lines
http://www.PowerDNS.com Open source, database driven DNS Software http://netherlabs.nl Open and Closed source services
Quoted 4 lines · On Saturday 03 March 2007 23:50:02 bert hubert wrote:
Quoted 2 lines
for (;;)
asm volatile ("idle");This looks remarkably like
relax_cpu()
Actually not: cpu_relax() is defined as barrier(), it can't call idle because that might make it sleep for a indefinite amount of time (until the next interrupt, but only if they are enabled).
Some nice architectures provide a hardware mechanism to do cpu_relax, like going to low-power mode for a few microseconds, but this one doesn't seem to have it.
Arnd <><
Quoted 24 lines · Arnd Bergmann
Quoted 3 lines · Bryan
Here is the update version of blackfin-arch.patch in -mm tree. simply add support to utrace and it was tested on blackfin STAMP board as well as other following patches.
Wow, this has come a long way since I looked at the patches last year, good work!
I've gone through the complete patch again now, and these are the issues I've found in it. None of these are show-stoppers and I'd like to see it all go in during the next merge window. There should be enough time until then to address these points:
Quoted 11 lines
(quoted diff) +11
-0+EXPORT_SYMBOL(__ioremap); +EXPORT_SYMBOL(strcmp); +EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(dump_thread); + +EXPORT_SYMBOL(ip_fast_csum); + +EXPORT_SYMBOL(kernel_thread); + +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down);
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+EXPORT_SYMBOL(__down_trylock); +EXPORT_SYMBOL(__down_interruptible); + +EXPORT_SYMBOL(is_in_rom);In general, please put
EXPORT_SYMBOLlines below the definition of the symbol itself. This list of exports should only be used for symbols that come from assembly files.
What is the right way to export symbol coming from c files?
Quoted 3 lines
You should probably also think about whether some of them are better done as
EXPORT_SYMBOL_GPL.
It is probably not. We need code using those symbols, no matter it's non-GPLd or GPLd.
Quoted 27 lines
Review
Quoted 7 lines
(quoted diff) +6
-0+ pending = bfin_read_IPEND() & ~0x8000; + other_ints = pending & (pending - 1); + if (other_ints == 0) + lower_to_irq14(); + irq_exit(); +The last line here has trailing whitespace. While this gets automatically removed by akpm's scripts, you're normally better off not adding it in the first place, because it may cause your follow-on patches not to apply, aside from being wrong to start with.
Review
Quoted 11 lines
(quoted diff) +11
-0+void machine_halt(void) +{ + for (;;) + /* nothing */ ; +} + +void machine_power_off(void) +{ + for (;;) + /* nothing */ ; +}It might be nicer to make this
Quoted 5 lines
for (;;) asm volatile ("idle");Otherwise you end up burning CPU cycles after a halt without any particular need.
Good suggestion, thanks.
Quoted 22 lines
Quoted 22 lines
(quoted diff) +21
-0+#if defined(CONFIG_MTD_UCLINUX) + /* generic memory mapped MTD driver */ + memory_mtd_end = memory_end; + + mtd_phys = _ramstart; + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); + +# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) + if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) + mtd_size = + PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); +# endif + +# if defined(CONFIG_CRAMFS) + if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); +# endif + +# if defined(CONFIG_ROMFS_FS) + if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 + && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ mtd_size = + PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));This detection seems to me like a strange thing to do in
setup_arch(). It should be possible to do this much later, at a point where the system is much less fragile and e.g. printk works. It could even be moved into some place in the mtd code itself, since other architectures might want to do the same thing.
After download the rootfs image from host to the target ram, we need to move the image to the right place, so we need to know the size of the image at this time.
Quoted 21 lines
Quoted 6 lines
(quoted diff) +5
-0+#if defined(CONFIG_BF561) +static struct cpu cpu[2]; +#else +static struct cpu cpu[1]; +#endifReview
Quoted 10 lines
(quoted diff) +10
-0+static int __init topology_init(void) +{ +#if defined (CONFIG_BF561) + register_cpu(&cpu[0], 0); + register_cpu(&cpu[1], 1); + return 0; +#else + return register_cpu(cpu, 0); +#endif +}I think you should try to avoid the special-case stuff here. You can have
CONFIG_NR_CPUSinKconfigset dependent onCONFIG_BF561and change the code here (and similarly in other places) to
Quoted 9 lines
static struct cpu cpu[NR_CPUS];
static int__inittopology_init(void){ int i; for (i=0; i< NR_CPUS; i++) { register_cpu(&cpu[i], i); return 0; }
Good suggestions, thanks.
Quoted 161 lines
Review
Quoted 8 lines
(quoted diff) +8
-0+ for (i = ZERO_P; i <= L2_MEM; i++) { + + if (cplb_data[i].valid) { + + as_1m = cplb_data[i].start % SIZE_1M; + + /* We need to make sure all sections are properly 1M aligned + * However between Kernel Memory and the Kernel mtd section, dependingon the
Review
Quoted 8 lines
(quoted diff) +8
-0+ * rootfs size, there can be overlapping memory areas. + */ + + if (as_1m) { +#ifdef CONFIG_MTD_UCLINUX + if (i == SDRAM_RAM_MTD) { + if ((cplb_data[SDRAM_KERN].end + 1) > cplb_data[SDRAM_RAM_MTD].start) + cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M))+
SIZE_1M;I count 6 levels of indentation, which severely limits readability, especially when you have terms this complex in the last level. Please try to split up functions like this into smaller units.
Quoted 3 lines
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at onetime.
Quoted 1 line
+ * If a second signal with
SA_ONSTACKset arrives while working on asigstack,
Quoted 3 lines
+ *
SA_ONSTACKis ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */This comment is probably outdated.
Quoted 1 line
+extern int
setup_irq(unsigned int irq, struct irqaction *handler);this extern should be in a header.
Review
Quoted 8 lines
(quoted diff) +8
-0+asmlinkage void trap_c(struct pt_regs *fp) +{ + int j, sig = 0; + siginfo_t info; + unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; + +#ifdef CONFIG_KGDB +# define CHK_DEBUGGER_TRAP() do { CHK_DEBUGGER(trapnr, sig, info.si_code,fp,); } while (0)
Quoted 1 line
+# define
CHK_DEBUGGER_TRAP_MAYBE()do { if (kgdb_connected)
CHK_DEBUGGER_TRAP(); } while (0)Quoted 38 lines
(quoted diff) +38
-0+#else +# define CHK_DEBUGGER_TRAP() do { } while (0) +# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) +#endif + + trace_buffer_save(j); + + /* trap_c() will be called for exceptions. During exceptions + * processing, the pc value should be set with retx value. + * With this change we can cleanup some code in signal.c- TODO + */ + fp->orig_pc = fp->retx; + /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", + trapnr, fp->ipend, fp->pc, fp->retx); */ + + /* send the appropriate signal to the user program */ + switch (trapnr) { + + /* This table works in conjuction with the one in ./mach-common/entry.S + * Some exceptions are handled there (in assembly, in exception space) + * Some are handled here, (in C, in interrupt space) + * Some, like CPLB, are handled in both, where the normal path is + * handled in assembly/exception space, and the error path is handled + * here + */ + + /* 0x00 - Linux Syscall, getting here is an error */ + /* 0x01 - userspace gdb breakpoint, handled here */ + case VEC_EXCPT01: + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP_MAYBE(); + /* Check if this is a breakpoint in kernel space */ + if (fp->ipend & 0xffc0) + return; + else + break; +#ifdef CONFIG_KGDBReview
Quoted 10 lines
(quoted diff) +10
-0+ case VEC_EXCPT02 : /* gdb connection */ + info.si_code = TRAP_ILLTRAP; + sig = SIGTRAP; + CHK_DEBUGGER_TRAP(); + return; +#else + /* 0x02 - User Defined, Caught by default */ +#endif + /* 0x03 - Atomic test and set */ + case VEC_EXCPT03:The table here probably gets converted by gcc into a lookup table, but I think it would be clearer to make that explicit and force the table here with something like:
static void trap_breakpoint(struct
pt_regs*fp,siginfo_t*info,
unsigned int trapnr){ info->si_code = TRAP_ILLTRAP; CHK_DEBUGGER_TRAP_MAYBE(); if (fp->ipend & 0xffc0) return 0; return SIGTRAP; }#ifdef
CONFIG_KGDB
static void trap_kgdb(structpt_regs*fp,siginfo_t*info,
unsigned int trapnr){ info->si_code = TRAP_ILLTRAP; CHK_DEBUGGER_TRAP(); return SIGTRAP; }#endif
static void (traps[])(struct
pt_regs*fp,siginfo_t*info,unsigned int trapnr) = { [VEC_EXCPT01] &trap_breakpoint, /* 0x01 - userspace gdb breakpoint */ #ifdef CONFIG_KGDB [VEC_EXCPT02] &trap_kgdb, /* gdb connection */ #endif ... };asmlinkage void
trap_c(struct pt_regs *fp){ ... if (trapnr > 0x3f) goto error; if (!traps[trapnr]) goto out; ret = traps[trapno](fp, &info, trapnr); if (!ret) goto out; ...That should make sure you get the efficient trap handling almost and might even
save some code space (you'd have to try that).Quoted 12 lines
(quoted diff) +12
-0+asmlinkage int sys_bfin_spinlock(int *spinlock) +{ + int ret = 0; + int tmp = 0; + + local_irq_disable(); + ret = get_user(tmp, spinlock); + if (ret == 0) { + if (tmp) + ret = 1; + tmp = 1; + put_user(tmp, spinlock);
Quoted 8 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+ } + local_irq_enable(); + return ret; +}I'm curious: In your dual-core bf561, don't you actually need to implement something that maintains atomicity across cores rather than just across processes?
Yes, bf561 is a dual-core processor, but we are using only one core of bf561 now.
IMHO, BF561 architecture was not designed for SMP or NUMA.
Quoted 72 lines
Review
Quoted 6 lines
(quoted diff) +5
-0+#include <net/checksum.h> +#include <asm/checksum.h> + +#ifdef CONFIG_IP_CHECKSUM_L1 +static unsigned short do_csum(const unsigned char *buff, intlen)__attribute__((l1_text));
Review
Quoted 13 lines
(quoted diff) +13
-0+#endif + +static unsigned short do_csum(const unsigned char *buff, int len) +{ + register unsigned long sum = 0; + int swappem = 0; + + if (1 & (unsigned long)buff) { + sum = *buff << 8; + buff++; + len--; + ++swappem; + }For the non-L1 case, is there actually anything specific to blackfin in this code? I wonder if we should instead have a totally generic version of that in
lib/csum.cfor those architectures that don't want their own optimizations for this.Review
Quoted 12 lines
(quoted diff) +12
-0+static struct platform_device *stamp_devices[] __initdata = { +#if defined(CONFIG_RTC_DRV_BFIN) || defined(CONFIG_RTC_DRV_BFIN_MODULE) + &rtc_device, +#endif + +#if defined(CONFIG_BFIN_CFPCMCIA) || defined(CONFIG_BFIN_CFPCMCIA_MODULE) + &bfin_pcmcia_cf_device, +#endif + +#if defined(CONFIG_USB_SL811_HCD) || defined(CONFIG_USB_SL811_HCD_MODULE) + &sl811_hcd_device, +#endifThis array reminds me of the bad old days when all initialization functions had to be called from a common function. Normally I don't like to recommend using section magic for anything, but in this case I guess you'd be better off if you just do your own thing here, like:
#define
BFIN_PLATFORM_DEVICE(name)structplatform_devicename \
__attribute((section("initdata.platformdev")))then declare your platform devices in the respective driver, like
static BFIN_PLATFORM_DEVICE(rtc_device) = { ... };and loop through the new section like you do for the initcalls.
Review
Quoted 10 lines
(quoted diff) +10
-0+void get_bf537_ether_addr(char *addr) +{ + /* currently the mac addr is saved in flash */ + int flash_mac = 0x203f0000; + *(u32 *)(&(addr[0])) = *(int *)flash_mac; + flash_mac += 4; + *(u16 *)(&(addr[4])) = (u16)*(int *)flash_mac; +} + +EXPORT_SYMBOL(get_bf537_ether_addr);This looks wrong in a number of aspects. Are there other things stored in the flash so you can make this a more general flash abstraction? Is there more than one driver using this at all? If not, it should probably be part of the driver, with the exact address being a compile-time constant for that driver.
Quoted 1 line
It should probably also use
bfin_readXXinstead direct dereferences.
Good suggestions, thanks.
Quoted 90 lines
Review
Quoted 3 lines
(quoted diff) +2
-0+/* The number of spurious interrupts */ +volatile unsigned int num_spurious;Why volatile? It probably does not what you intended, maybe it should be
atomic_tinstead.Quoted 7 lines
(quoted diff) +7
-0+/* BASE LEVEL interrupt handler routines */ +asmlinkage void evt_emulation(void); +asmlinkage void evt_exception(void); +asmlinkage void trap(void); +asmlinkage void evt_ivhw(void); +asmlinkage void evt_timer(void); +asmlinkage void evt_evt2(void);Review
Quoted 10 lines
(quoted diff) +10
-0+asmlinkage void evt_evt7(void); +asmlinkage void evt_evt8(void); +asmlinkage void evt_evt9(void); +asmlinkage void evt_evt10(void); +asmlinkage void evt_evt11(void); +asmlinkage void evt_evt12(void); +asmlinkage void evt_evt13(void); +asmlinkage void evt_soft_int1(void); +asmlinkage void evt_system_call(void); +asmlinkage void init_exception_buff(void);move the extern definitions to a header file please
Quoted 6 lines
(quoted diff) +6
-0+/* BASE LEVEL interrupt handler routines */ +asmlinkage void evt_emulation(void); +asmlinkage void evt_exception(void); +asmlinkage void trap(void); +asmlinkage void evt_ivhw(void); +asmlinkage void evt_timer(void);Review
Quoted 10 lines
(quoted diff) +10
-0+asmlinkage void evt_evt2(void); +asmlinkage void evt_evt7(void); +asmlinkage void evt_evt8(void); +asmlinkage void evt_evt9(void); +asmlinkage void evt_evt10(void); +asmlinkage void evt_evt11(void); +asmlinkage void evt_evt12(void); +asmlinkage void evt_evt13(void); +asmlinkage void evt_soft_int1(void); +asmlinkage void evt_system_call(void);Then you don't have to write them twice ;-)
Quoted 8 lines
(quoted diff) +8
-0+static __inline__ void atomic_add(int i, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter += i; + local_irq_restore(flags); +}Review
Quoted 10 lines
(quoted diff) +10
-0+ +static __inline__ void atomic_sub(int i, atomic_t * v) +{ + long flags; + + local_irq_save(flags); + v->counter -= i; + local_irq_restore(flags); + +}The implementation of the
atomic_ttype looks very generic. Maybe it could be moved toasm-generic/atomic-irqdisable.hor similar to be shared by all architectures without atomic operations.Quoted 21 lines
(quoted diff) +21
-0+struct spi_device_t { + char *dev_name; + + unsigned short flag; + unsigned short bdrate; + + unsigned short enable; + unsigned short master; + unsigned short out_opendrain; + unsigned short polar; + unsigned short phase; + unsigned short byteorder; /* 0: MSB first; 1: LSB first; */ + unsigned short size; /* 0: 8 bits; 1: 16 bits */ + unsigned short emiso; + unsigned short send_zero; + unsigned short more_data; + unsigned short slave_sel; + unsigned short ti_mod; + + unsigned short dma; /* use dma mode or not */ + unsigned short dma_config; /* only valid if dma enabled */
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +5
-0+ + irqreturn_t(*irq_handler) (int irq, void *dev_id, + struct pt_regs *regs); + void *priv_data; +};How does this fit in with the generic SPI code? Does it duplicate stuff from there, or do you use it?
We use our own. We have dma which can be used for SPI operations.
Quoted 251 lines
Quoted 13 lines
(quoted diff) +12
-0+static __inline__ void set_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + unsigned long flags; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + local_irq_save(flags); + *a |= mask; + local_irq_restore(flags); +}Review
Quoted 10 lines
(quoted diff) +10
-0+ +static __inline__ void __set_bit(int nr, volatile unsigned long *addr) +{ + int *a = (int *)addr; + int mask; + + a += nr >> 5; + mask = 1 << (nr & 0x1f); + *a |= mask; +}same as for the atomic header, this could become generic.
Quoted 32 lines
(quoted diff) +32
-0+#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define SSYNC() do { int _tmp; \ + __asm__ __volatile__ ("cli %0;\n\t"\ + "nop;nop;\n\t"\ + "ssync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define SSYNC() do { int _tmp; \ + __asm__ __volatile__ ("cli %0;\n\t"\ + "ssync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define SSYNC() do {__builtin_bfin_ssync();} while (0) +#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define SSYNC() do {__asm__ __volatile__ ("ssync;\n\t") } while (0) +#endif + + +#if defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define CSYNC() do { int _tmp; \ + __asm__ __volatile__ ("cli %0;\n\t"\ + "nop;nop;\n\t"\ + "csync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define CSYNC() do { int _tmp; \Review
Quoted 10 lines
(quoted diff) +10
-0+ __asm__ __volatile__ ("cli %0;\n\t"\ + "csync;\n\t"\ + "sti %0;\n\t" \ + :"=d"(_tmp):);\ + } while (0) +#elif !defined(ANOMALY_05000312) && defined(ANOMALY_05000244) +#define CSYNC() do {__builtin_bfin_csync();} while (0) +#elif !defined(ANOMALY_05000312) && !defined(ANOMALY_05000244) +#define CSYNC() do {__asm__ __volatile__ ("csync;\n\t") } while (0) +#endifit would be nice if you could convert these to inline functions instead of macros.
Quoted 1 line
+static inline struct
task_struct*get_current(void)__attribute__((
__const__));Review
Quoted 6 lines
(quoted diff) +6
-0+static inline struct task_struct *get_current(void) +{ + return (current_thread_info()->task); +} + +#define current (get_current())You might want to maintain the current variable in the L1 memory, but probably that difference it not measurable.
Review
Quoted 9 lines
(quoted diff) +9
-0+#ifdef BFIN_DMA_NDEBUG +#define assert(expr) do {} while(0) +#else +#define assert(expr) \ + if (!(expr)) { \ + printk(KERN_INFO "Assertion failed! %s, %s, %s, line=%d \n", \ + #expr, __FILE__,__FUNCTION__,__LINE__); \ + } +#endifPlease don't define your own
assert()functions, in the kernel we haveBUG_ONandWARN_ONfor this.Quoted 30 lines
(quoted diff) +30
-0+#ifndef _BLACKFIN_DPMC_H_ +#define _BLACKFIN_DPMC_H_ + +#define SLEEP_MODE 1 +#define DEEP_SLEEP_MODE 2 +#define ACTIVE_PLL_DISABLED 3 +#define FULLON_MODE 4 +#define ACTIVE_PLL_ENABLED 5 +#define HIBERNATE_MODE 6 + +#define IOCTL_FULL_ON_MODE _IO('s', 0xA0) +#define IOCTL_ACTIVE_MODE _IO('s', 0xA1) +#define IOCTL_SLEEP_MODE _IO('s', 0xA2) +#define IOCTL_DEEP_SLEEP_MODE _IO('s', 0xA3) +#define IOCTL_HIBERNATE_MODE _IO('s', 0xA4) +#define IOCTL_CHANGE_FREQUENCY _IOW('s', 0xA5, unsigned long) +#define IOCTL_CHANGE_VOLTAGE _IOW('s', 0xA6, unsigned long) +#define IOCTL_SET_CCLK _IOW('s', 0xA7, unsigned long) +#define IOCTL_SET_SCLK _IOW('s', 0xA8, unsigned long) +#define IOCTL_GET_PLLSTATUS _IOW('s', 0xA9, unsigned long) +#define IOCTL_GET_CORECLOCK _IOW('s', 0xAA, unsigned long) +#define IOCTL_GET_SYSTEMCLOCK _IOW('s', 0xAB, unsigned long) +#define IOCTL_GET_VCO _IOW('s', 0xAC, unsigned long) +#define IOCTL_DISABLE_WDOG_TIMER _IO('s', 0xAD) +#define IOCTL_UNMASK_WDOG_WAKEUP_EVENT _IO('s',0xAE) +#define IOCTL_PROGRAM_WDOG_TIMER _IOW('s',0xAF,unsigned long) +#define IOCTL_CLEAR_WDOG_WAKEUP_EVENT _IO('s',0xB0) +#define IOCTL_SLEEP_DEEPER_MODE _IO('s',0xB1) + +#define DPMC_MINOR 254Review
Quoted 10 lines
(quoted diff) +10
-0+ +#define ON 0 +#define OFF 1 + +unsigned long calc_volt(void); +int calc_vlev(int vlt); +unsigned long change_voltage(unsigned long volt); +int calc_msel(int vco_hz); +unsigned long change_frequency(unsigned long vco_mhz); +int set_pll_div(unsigned short sel, unsigned char flag);In general, you should be careful not to mix in-kernel declarations with user-visible parts. In this case, the ioctl definitions need to be exported via 'make
headers_install', while the function declarations clearly are not useful for user space and should therefore be inside of '#ifdef__KERNEL__'. You should then list this file as 'unifdef-y' in theKbuildfile.Review
Quoted 3 lines
(quoted diff) +3
-0+ +#ifdef __KERNEL__ +#define SET_PERSONALITY(ex, ibcs2)set_personality((ibcs2)?PER_SVR4:PER_LINUX)
Quoted 1 line
+#endif
This looks bogus, I don't think you implement personalities.
Quoted 5 lines
(quoted diff) +5
-0+#define readb(addr) ({ unsigned __v; \ + int _tmp; \ + __asm__ __volatile__ ("cli %1;\n\t"\ + "NOP;NOP;SSYNC;\n\t"\ + "%0 = b [%2] (z);\n\t"\Review
Quoted 10 lines
(quoted diff) +10
-0+ "sti %1;\n\t" \ + : "=d"(__v), "=d"(_tmp): "a"(addr)); (unsigned char)__v; }) + +#define readw(addr) ({ unsigned __v; \ + int _tmp; \ + __asm__ __volatile__ ("cli %1;\n\t"\ + "NOP;NOP;SSYNC;\n\t"\ + "%0 = w [%2] (z);\n\t"\ + "sti %1;\n\t" \ + : "=d"(__v), "=d"(_tmp): "a"(addr)); (unsigned short)__v; })They should probably be inline functions.
Quoted 33 lines
(quoted diff) +33
-0+#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420Review
Quoted 10 lines
(quoted diff) +10
-0+#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-muxdevice) */
Quoted 1 line
+#define TIOCSPTLCK
_IOW('T',0x31, int)/* Lock/unlock Pty */These look like another good candidate for an asm-generic version.
Review
Quoted 2 lines
(quoted diff) +2
-0+ +extern void sys_free_irq(unsigned int irq, void *dev_id);This functions should probably be renamed. Anything that starts with '
sys_' is normally a system call.+
Review
Quoted 10 lines
(quoted diff) +10
-0+/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */ +#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL(val) bfin_write16(PLL_CTL,val) +#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT(val) bfin_write16(PLL_STAT,val) +#define bfin_read_PLL_LOCKCNT() bfin_read16(PLL_LOCKCNT) +#define bfin_write_PLL_LOCKCNT(val) bfin_write16(PLL_LOCKCNT,val) +#define bfin_read_CHIPID() bfin_read32(CHIPID) +#define bfin_read_SWRST() bfin_read16(SWRST) +#define bfin_write_SWRST(val) bfin_write16(SWRST,val)I remember that we have discussed these macro abstractions before, but don't recall the result of the discussion. You have around 5000 such macros, and I still think it's not a helpful abstraction. It is much more common for device drivers to just use the read/write accessors directly. IIRC the objections that were raised (and my replies to them) were roughly:
Quoted 3 lines
the driver writer doesn't want to know the size of the variable, and if it changes, they need to change every instance in the code, not just the macro.
A driver writer should better know the type of variable he is changing, e.g. because of the type he passes in and out. Also, hardware registers don't suddenly change in size.
Quoted 7 lines
Quoted 3 lines
These macros allow us to work around hardware bugs when accessing the registers by simply redefining the accessor to do something more complex.
If there is a bug in the hardware, the workaround belongs into the driver. You can then still define a special inline function to access that particular register.
-Aubrey
Quoted 7 lines · Aubrey Li
Quoted 3 lines · Arnd Bergmann
In general, please put
EXPORT_SYMBOLlines below the definition of the symbol itself. This list of exports should only be used for symbols that come from assembly files.What is the right way to export symbol coming from c files?
As I said, below the symbol definition, like
int global_var;EXPORT_SYMBOL(global_var);
int global_function(void)
{
return 3;
}EXPORT_SYMBOL(global_function);
Quoted 9 lines
Quoted 5 lines
This detection seems to me like a strange thing to do in
setup_arch(). It should be possible to do this much later, at a point where the system is much less fragile and e.g. printk works. It could even be moved into some place in the mtd code itself, since other architectures might want to do the same thing.After download the rootfs image from host to the target ram, we need to move the image to the right place, so we need to know the size of the image at this time.
Well, it doesn't have to be in the modular part of the kernel, but some place later than setup_arch() would be a step in the right direction. If you need it before the file systems, an arch_initcall() might be the right place.
Quoted 7 lines
Quoted 3 lines
I'm curious: In your dual-core bf561, don't you actually need to implement something that maintains atomicity across cores rather than just across processes?
Yes, bf561 is a dual-core processor, but we are using only one core of bf561 now.
IMHO, BF561 architecture was not designed for SMP or NUMA.
Interesting, so what is the intended use of the other core? Does the hardware have any way of supporting concurrency between the cores, other than sending interrupts between them?
Quoted 4 lines
Quoted 2 lines
How does this fit in with the generic SPI code? Does it duplicate stuff from there, or do you use it?
We use our own. We have dma which can be used for SPI operations.
I just looked again at your code. My question was more directed at whether you use your own SPI abstraction layer instead of drivers/spi, which you fortunately don't. The piece I was missing however is the spi_bfin5xx.c driver, which was not part of this patch, though you seem to rely on it. Is that already part of the -mm kernel?
Arnd <><
Quoted 11 lines · Arnd Bergmann
Quoted 7 lines · Aubrey Li
Quoted 3 lines · Arnd Bergmann
In general, please put
EXPORT_SYMBOLlines below the definition of the symbol itself. This list of exports should only be used for symbols that come from assembly files.What is the right way to export symbol coming from c files?
As I said, below the symbol definition, like
Quoted 9 lines
int
global_var;EXPORT_SYMBOL(global_var);int
global_function(void){ return 3; }
EXPORT_SYMBOL(global_function);
Got it, the rule will be followed.
Quoted 4 lines
Quoted 4 lines
Quoted 3 lines
I'm curious: In your dual-core bf561, don't you actually need to implement something that maintains atomicity across cores rather than just across processes?
Quoted 8 lines
Quoted 3 lines
Yes, bf561 is a dual-core processor, but we are using only one core of bf561 now.
IMHO, BF561 architecture was not designed for SMP or NUMA.Interesting, so what is the intended use of the other core? Does the hardware have any way of supporting concurrency between the cores, other than sending interrupts between them?
AFAIK, the dual-core in BF561 have their own L1 memory which can be configured as cache respectively. So there is no hardware to help cache coherence management, it is very hard to implement SMP, right?
Maybe NUMA is a solution, but it is not a wonderful solution.
In some application product, BF561 core A is running Linux kernel +Applications while BF561 core B is just for some complicated video/audio codec algorithm.
Any Linux multicore solution in BF561 situation is highly welcome.
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines
How does this fit in with the generic SPI code? Does it duplicate stuff from there, or do you use it?
We use our own. We have dma which can be used for SPI operations.
Quoted 7 lines
I just looked again at your code. My question was more directed at whether you use your own SPI abstraction layer instead of
drivers/spi, which you fortunately don't. The piece I was missing however is thespi_bfin5xx.cdriver, which was not part of this patch, though you seem to rely on it. Is that already part of the -mm kernel?Arnd <><
I will send out the SPI patch ASAP. and your signature is very interesting, it looks like a fish -:)
Another question: when is the merge point from -mm to linus mainline, is it the same as the merge window after 2.6.21 released?
Thanks again
-Bryan Wu
Quoted 1 line · Bryan
Maybe NUMA is a solution, but it is not a wonderful solution.
NUMA doesn't help you. Linux only runs on cache-coherent NUMA, which this isn't.
Quoted 5 lines
In some application product, BF561 core A is running Linux kernel +Applications while BF561 core B is just for some complicated video/audio codec algorithm.
Any Linux multicore solution in BF561 situation is highly welcome.
You definitely can't use the cache mode in this case, but one idea that should make atomic instructions work is to always do these on one of the two cores, and use cross-core interrupts to trigger an update. It's probably pretty inefficient and you also need to do something about atomic updates (spinlock_t and atomic_t) when interrupts are disabled.
Quoted 2 lines
Another question: when is the merge point from -mm to linus mainline, is it the same as the merge window after 2.6.21 released?
It's the same.
Arnd <><
Quoted 8 lines · Arnd Bergmann
Quoted 2 lines · Bryan
Here is the update version of blackfin-arch.patch in -mm tree. simply add support to utrace and it was tested on blackfin STAMP
board
Quoted 1 line
as well as other following patches.
Wow, this has come a long way since I looked at the patches last year, good work!
Yeah, old friend comes back. Thanks a lot for your review. We fixed lots of things according to your review since last year.
Quoted 5 lines
I've gone through the complete patch again now, and these are the issues I've found in it. None of these are show-stoppers and I'd like to see it all go in during the next merge window. There should be enough time until then to address these points:
Lots of valuable comments got from you, we will get things done soon. So could please give us some information about the merge window schedule, we may try to catch this.
Quoted 35 lines
+
Review
Quoted 3 lines
(quoted diff) +3
-0+/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */ +#define bfin_read_PLL_CTL() bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL(val)
bfin_write16(PLL_CTL,val)Review
Quoted 2 lines
(quoted diff) +2
-0+#define bfin_read_PLL_STAT() bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT(val)
bfin_write16(PLL_STAT,val)Quoted 1 line
+#define
bfin_read_PLL_LOCKCNT()
bfin_read16(PLL_LOCKCNT)Quoted 1 line
+#define
bfin_write_PLL_LOCKCNT(val)
bfin_write16(PLL_LOCKCNT,val)Review
Quoted 3 lines
(quoted diff) +3
-0+#define bfin_read_CHIPID() bfin_read32(CHIPID) +#define bfin_read_SWRST() bfin_read16(SWRST) +#define bfin_write_SWRST(val)
bfin_write16(SWRST,val)I remember that we have discussed these macro abstractions before, but don't
recall the result of the discussion. You have around 5000 such macros, and I still think it's not a helpful abstraction. It is much more common
for device drivers to just use the read/write accessors directly. IIRC the objections that were raised (and my replies to them) were roughly:Quoted 3 lines
the driver writer doesn't want to know the size of the variable, and if it changes, they need to change every instance in the code, not just the macro.
A driver writer should better know the type of variable he is changing,
e.g. because of the type he passes in and out. Also, hardware registers
don't suddenly change in size.
Quoted 9 lines
Quoted 1 line
These macros allow us to work around hardware bugs when accessing
the
Quoted 2 lines
registers by simply redefining the accessor to do something more complex.
If there is a bug in the hardware, the workaround belongs into the driver. You can then still define a special inline function to access that particular register.
Oh, if we should fix this issue, there are lots of work to do because tons of drivers rely on this. Maybe after some team internal discussion, we will give a solution to this.
Thanks again
Best Regards,
-Bryan Wu
Quoted 2 lines · Bryan
So could please give us some information about the merge window schedule, we may try to catch this.
The merge window opens after 2.6.21 gets released and is open for two weeks aftre that. The idea is however that you have everything ready at the start of the merge window.
Quoted 3 lines
Oh, if we should fix this issue, there are lots of work to do because tons of drivers rely on this. Maybe after some team internal discussion, we will give a solution to this.
You can probably use a short perl script (or similar) to automate the conversion.
Arnd <><
Quoted 21 lines · Arnd Bergmann
Quoted 21 lines
(quoted diff) +21
-0+#if defined(CONFIG_MTD_UCLINUX) + /* generic memory mapped MTD driver */ + memory_mtd_end = memory_end; + + mtd_phys = _ramstart; + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); + +# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) + if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) + mtd_size = + PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); +# endif + +# if defined(CONFIG_CRAMFS) + if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) + mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); +# endif + +# if defined(CONFIG_ROMFS_FS) + if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 + && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
Quoted 8 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ mtd_size = + PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));This detection seems to me like a strange thing to do in
setup_arch(). It should be possible to do this much later, at a point where the system is much less fragile and e.g. printk works. It could even be moved into some place in the mtd code itself, since other architectures might want to do the same thing.
the MTD code already does this ... the difference is that the blackfin port changes the memory layout dynamically by relocating the rootfs from the end of its data section to the end of memory ... that's why it's done so early in the boot process, it shrinks the memory pool available to the kernel allocator
Quoted 44 lines
Quoted 33 lines
(quoted diff) +33
-0+#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E +#define TIOCGPGRP 0x540F +#define TIOCSPGRP 0x5410 +#define TIOCOUTQ 0x5411 +#define TIOCSTI 0x5412 +#define TIOCGWINSZ 0x5413 +#define TIOCSWINSZ 0x5414 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define FIONREAD 0x541B +#define TIOCINQ FIONREAD +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420Review
Quoted 10 lines
(quoted diff) +10
-0+#define FIONBIO 0x5421 +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-muxdevice) */
Quoted 3 lines
Quoted 1 line
+#define TIOCSPTLCK
_IOW('T',0x31, int)/* Lock/unlock Pty */These look like another good candidate for an asm-generic version.
yeah, most everyone has the same ioctl values for terminal cruft
Quoted 7 lines
Quoted 3 lines
These macros allow us to work around hardware bugs when accessing the registers by simply redefining the accessor to do something more complex.
If there is a bug in the hardware, the workaround belongs into the driver. You can then still define a special inline function to access that particular register.
not when it's an anomaly in a register that is not driver specific (like the VR_CTL register), or it's a peripheral that has no generic driver [yet] (like the SPORT or PPI)
-mike
Quoted 6 lines · Bryan
Here is the update version of blackfin-arch.patch in -mm tree. simply add support to utrace and it was tested on blackfin STAMP board as well as other following patches.
The whole patch is located at URL:
https://blackfin.uclinux.org/gf/download/frsrelease/39/2583/blackfin-arch.patch
It would be nice if this could be split and posted incrementally for review. It's a bit of a pain reading through the entire thing in one shot.
Anyways..
Quoted 4 lines
Index: linux-2.6/arch/blackfin/Kconfig
===================================================================arch/blackfin/Kconfig new file +0
-0
[snip]
arch/blackfin/Kconfig
Quoted 4 lines
arch/blackfin/Kconfig new file +4
-0+config ZONE_DMA + bool + default y +
You don't need this, just get rid of it and shove everything in ZONE_NORMAL.
arch/blackfin/Kconfig
Quoted 8 lines
arch/blackfin/Kconfig new file +8
-0+config BLACKFIN + bool + default y + +config BFIN + bool + default y +
Why are there two of these?
arch/blackfin/Kconfig
Quoted 4 lines
arch/blackfin/Kconfig new file +4
-0+config GENERIC_IRQ_PROBE + bool + default y +
Whitespace damage.
arch/blackfin/Kconfig
Quoted 4 lines
arch/blackfin/Kconfig new file +4
-0+config UCLINUX + bool + default y +
Dead symbol.
arch/blackfin/Kconfig
Quoted 9 lines
arch/blackfin/Kconfig new file +9
-0+comment "Memory Optimizations" + +config I_ENTRY_L1 + bool "Locate interrupt entry code in L1 Memory" + default y + help + If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked + into L1 instruction memory.(less latency) +
Wow, this is really crying out for a special linker section with slightly more intelligent relocation logic. You should flag the performance critical parts to be located in L1 memory directly with a section attribute, rather than making everything selectable. If you overflow you can simply spill in to main memory.
arch/blackfin/Kconfig
Quoted 12 lines
arch/blackfin/Kconfig new file +12
-0+choice + prompt "Uncached SDRAM region" + default DMA_UNCACHED_1M + depends BFIN_DMA_5XX +config DMA_UNCACHED_2M + bool "Enable 2M DMA Zone" +config DMA_UNCACHED_1M + bool "Enable 1M DMA Zone" +config DMA_UNCACHED_NONE + bool "Disable DMA Zone" +endchoice +
Contrary to the comment, this is not a zone.
Quoted 4 lines
arch/blackfin/Kconfig new file +4
-0+config DEBUG_HUNT_FOR_ZERO + bool "Catch NULL pointer reads/writes" + default y + help
arch/blackfin/Kconfig
Quoted 10 lines
arch/blackfin/Kconfig new file +10
-0+ Say Y here to catch reads/writes to anywhere in the memory range + from 0x0000 - 0x0FFF (the first 4k) of memory. This is useful in + catching common programming errors such as NULL pointer dereferences. + + Misbehaving applications will be killed (generate a SEGV) while the + kernel will trigger a panic. + + Enabling this option will take up an extra entry in CPLB table. + Otherwise, there is no extra overhead. +
Is this sane to have conditional?
arch/blackfin/Kconfig
Quoted 8 lines
arch/blackfin/Kconfig new file +8
-0+config BOOTPARAM + bool "Compiled-in Kernel Boot Parameter" + +config BOOTPARAM_STRING + string "Kernel Boot Parameter" + default "console=ttyS0,57600" + depends on BOOTPARAM +
Any reason not to use CMDLINE_BOOL/CMDLINE like every other platform?
arch/blackfin/Kconfig
Quoted 5 lines
arch/blackfin/Kconfig new file +5
-0+config NO_KERNEL_MSG + bool "Suppress Kernel BUG Messages" + help + Do not output any debug BUG messages within the kernel. +
This is useless. For starters, CONFIG_BUG already does this. Secondly, this isn't used anywhere.
arch/blackfin/Kconfig
Quoted 10 lines
arch/blackfin/Kconfig new file +10
-0+int __init blackfin_dma_init(void) +{ + int i; + + printk(KERN_INFO "Blackfin DMA Controller\n"); + + for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { + dma_ch[i].chan_status = DMA_CHANNEL_FREE; + dma_ch[i].regs = base_addr[i]; + init_MUTEX(&(dma_ch[i].dmalock));
The dmalock is only ever used as a mutex, use that instead.
Quoted 6 lines
arch/blackfin/Kconfig new file +6
-0+void dma_alloc_init(unsigned long start, unsigned long end) +{ + spin_lock_init(&dma_page_lock); + dma_initialized = 0; + + dma_page = (unsigned int *)__get_free_page(GFP_KERNEL);
arch/blackfin/Kconfig
Quoted 10 lines
arch/blackfin/Kconfig new file +10
-0+ memset(dma_page, 0, PAGE_SIZE); + dma_base = PAGE_ALIGN(start); + dma_size = PAGE_ALIGN(end) - PAGE_ALIGN(start); + dma_pages = dma_size >> PAGE_SHIFT; + memset((void *)dma_base, 0, DMA_UNCACHED_REGION); + dma_initialized = 1; + + printk(KERN_INFO "%s: dma_page @ 0x%p - %d pages at 0x%08lx\n", __FUNCTION__, + dma_page, dma_pages, dma_base); +}
That's an "interesting" way of doing a bitmap. Please use a proper bitmap for dma_page, there's infrastructure for all of this already without having to come up with new schemes. dma_declare_coherent() is a good example.
arch/blackfin/Kconfig
Quoted 12 lines
arch/blackfin/Kconfig new file +12
-0+void *dma_alloc_coherent(struct device *dev, size_t size, + dma_addr_t * dma_handle, gfp_t gfp) +{ + void *ret; + + ret = (void *)__alloc_dma_pages(get_pages(size)); + + if (ret) { + memset(ret, 0, size); + *dma_handle = virt_to_phys(ret); + } +
No dcache write-back?
Quoted 15 lines
arch/blackfin/Kconfig new file +15
-0+dma_addr_t +dma_map_single(struct device *dev, void *ptr, size_t size, + enum dma_data_direction direction) +{ + BUG_ON(direction == DMA_NONE); + + blackfin_dcache_invalidate_range((unsigned long)ptr, + (unsigned long)ptr + size); + + return (dma_addr_t) ptr; +} + +int +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, + enum dma_data_direction direction)
arch/blackfin/Kconfig
Quoted 10 lines
arch/blackfin/Kconfig new file +10
-0+{ + int i; + + BUG_ON(direction == DMA_NONE); + + for (i = 0; i < nents; i++) + invalidate_dcache_range(sg_dma_address(&sg[i]), + sg_dma_address(&sg[i]) + + sg_dma_len(&sg[i])); +
Why are you using the different flushing routines here?
arch/blackfin/Kconfig
Quoted 5 lines
arch/blackfin/Kconfig new file +5
-0+#ifdef DEBUG_SERIAL_EARLY_INIT + bfin_console_init(); /* early console registration */ + /* this give a chance to get printk() working before crash. */ +#endif +
Why not expose this as a sensible early_printk implementation?
arch/blackfin/Kconfig
Quoted 8 lines
arch/blackfin/Kconfig new file +8
-0+#ifdef CONFIG_CONSOLE +#ifdef CONFIG_FRAMEBUFFER + conswitchp = &fb_con; +#else + conswitchp = 0; +#endif +#endif +
Can't you do this in the defconfig?
arch/blackfin/Kconfig
Quoted 9 lines
arch/blackfin/Kconfig new file +9
-0+ /* check the size of the l1 area */ + l1_length = _etext_l1 - _stext_l1; + if (l1_length > L1_CODE_LENGTH) + panic("L1 memory overflow\n"); + + l1_length = _ebss_l1 - _sdata_l1; + if (l1_length > L1_DATA_A_LENGTH) + panic("L1 memory overflow\n"); +
That's not very nice. You can figure this out already at link time.
arch/blackfin/Kconfig
Quoted 2 lines
arch/blackfin/Kconfig new file +2
-0+void do_gettimeofday(struct timeval *tv) +int do_settimeofday(struct timespec *tv)
These can use CONFIG_GENERIC_TIME.
arch/blackfin/Kconfig
Quoted 5 lines
arch/blackfin/Kconfig new file +5
-0+static struct platform_device *cm_bf533_devices[] __initdata = { +#if defined(CONFIG_SERIAL_BFIN) || defined(CONFIG_SERIAL_BFIN_MODULE) + &bfin_uart_device, +#endif +
Why? You'll already free this up if nothing claims it.
One of the benefits of having the driver model is that we're able to get rid of this sort of ifdef abortion.
arch/blackfin/Kconfig
Quoted 9 lines
arch/blackfin/Kconfig new file +9
-0+ /* + * initialize the bad page table and bad page to point + * to a couple of allocated pages + */ + empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE); + memset((void *)empty_zero_page, 0, PAGE_SIZE); +
dcache handling?
arch/blackfin/Kconfig
Quoted 6 lines
arch/blackfin/Kconfig new file +6
-0+ tmp = (unsigned long)l1sram_alloc(sizeof(struct l1_scratch_task_info)); + if (tmp != (unsigned long)L1_SCRATCH_TASK_INFO) { + printk(KERN_EMERG "mem_init(): Did not get the right address from l1sram_alloc: %08lx != %08lx\n", + tmp, (unsigned long)L1_SCRATCH_TASK_INFO); + panic("No L1, time to give up\n"); + }
This platform seems to really want to panic() at the first sign of trouble. This is not a good policy, especially for something that's only a micro-optimization.
Quoted 1 line
Index:
linux-2.6/arch/blackfin/mm/kmap.c
All of this can be inlined in io.h, there's nothing noteworthy here.
arch/blackfin/Kconfig
Quoted 2 lines
arch/blackfin/Kconfig new file +2
-0+static struct semaphore pfmon_sem; +
Use a mutex.
Quoted 3 lines
arch/blackfin/Kconfig new file +3
-0+int __init oprofile_arch_init(struct oprofile_operations *ops) +{ +#ifdef CONFIG_HARDWARE_PM
[snip]
arch/blackfin/Kconfig
Quoted 5 lines
arch/blackfin/Kconfig new file +5
-0+#else + return -1; +#endif +} +
Uh.. fix your dependencies.
arch/blackfin/Kconfig
Quoted 2 lines
arch/blackfin/Kconfig new file +2
-0+unsigned curr_pfctl, curr_count[2]; +
Globals?
Quoted 10 lines
Index:
linux-2.6/include/asm-blackfin/bug.h
===================================================================include/asm-blackfin/bug.h new file +5
-0@@ -0,0 +1,15 @@ +#ifndef _BLACKFIN_BUG_H +#define _BLACKFIN_BUG_H + +#ifdef CONFIG_BUG +#define HAVE_ARCH_BUG
include/asm-blackfin/bug.h line 15
Quoted 10 lines
include/asm-blackfin/bug.h new file +10
-0+#define BUG () do { \ + dump_stack(); \ + printk(KERN_WARNING "\nkernel BUG at %s:%d!\n",\ + __FILE__, __LINE__); \ + panic("BUG!"); \ +} while (0) +#endif + +#include <asm-generic/bug.h> +#endif
What do you need HAVE_ARCH_BUG for? You're not doing anything with it..
include/asm-blackfin/bug.h
Quoted 12 lines
include/asm-blackfin/bug.h new file +12
-0+#ifndef __ARCH_BLACKFIN_CACHE_H +#define __ARCH_BLACKFIN_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_SHIFT 5/* BlackFin loads 32 bytes for cache */ +#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) + +/* For speed we do need to align these ...MaTed---*/ +/* But include/linux/cache.h does this for us if we DO not define ...MaTed---*/ +#define __cacheline_aligned/***** maybe no need this Tony *****/ +#define ____cacheline_aligned +
What the hell?
Quoted 12 lines
include/asm-blackfin/bug.h new file +12
-0+static inline void flush_icache_range (unsigned start,unsigned end) +{ +#if defined(CONFIG_BLKFIN_DCACHE ) && defined(CONFIG_BLKFIN_CACHE ) + +# if defined(CONFIG_BLKFIN_WT ) +blackfin_icache_flush_range ((start), (end)); +# else +blackfin_icache_dcache_flush_range ((start), (end)); +# endif + +#else +
include/asm-blackfin/bug.h
Quoted 10 lines
include/asm-blackfin/bug.h new file +10
-0+# if defined(CONFIG_BLKFIN_CACHE ) +blackfin_icache_flush_range ((start), (end)); +# endif +# if defined(CONFIG_BLKFIN_DCACHE ) +blackfin_dcache_flush_range ((start), (end)); +# endif + +#endif +} +
This would probably be cleaner out-of-line, you can hide most of this ugliness in your Makefile instead.
include/asm-blackfin/bug.h
Quoted 12 lines
include/asm-blackfin/bug.h new file +12
-0+#pragma pack(2) +struct dmasg_t { +unsigned long next_desc_addr; +unsigned long start_addr; +unsigned short cfg; +unsigned short x_count; +short x_modify; +unsigned short y_count; +short y_modify; +}; +#pragma pack() +
Do you really need to use pragma?
Quoted 1 line
+struct
dma_register_t{
Why is there a _t here?
include/asm-blackfin/bug.h
Quoted 2 lines
include/asm-blackfin/bug.h new file +2
-0+#define STR (X ) STR1(X) +#define STR1 (X ) #X
You can use __stringify() for this if you feel you must.
include/asm-blackfin/bug.h
Quoted 5 lines
include/asm-blackfin/bug.h new file +5
-0+static inline unsigned long bfin_get_addr_from_rp (unsigned long *ptr, +unsigned long relval, +unsigned long flags, +unsigned long *persistent) +{
Some of these look frighteningly large to be inlined..
include/asm-blackfin/bug.h
Quoted 3 lines
include/asm-blackfin/bug.h new file +3
-0+#define dma_cache_inv (_start,_size) do { blkfin_inv_cache_all();} while (0) +#define dma_cache_wback (_start,_size) do { } while (0) +#define dma_cache_wback_inv (_start,_size) do { blkfin_inv_cache_all();} while (0)
What's the point of having selective flushing if you're 1) going to blow it all away, and 2) not use these in the dma-mapping cases?
include/asm-blackfin/bug.h
Quoted 7 lines
include/asm-blackfin/bug.h new file +7
-0+/* Clock and System Control (0xFFC0 0400-0xFFC0 07FF) */ +#define bfin_read_PLL_CTL () bfin_read16(PLL_CTL) +#define bfin_write_PLL_CTL (val) bfin_write16(PLL_CTL,val) +#define bfin_read_PLL_STAT () bfin_read16(PLL_STAT) +#define bfin_write_PLL_STAT (val) bfin_write16(PLL_STAT,val) +#define bfin_read_PLL_LOCKCNT () bfin_read16(PLL_LOCKCNT) +#define bfin_write_PLL_LOCKCNT (val) bfin_write16(PLL_LOCKCNT,val)
What sort of magical abstraction is this? Is there some reason you can't just read and write the registers directly rather than having a wrapper for _every_ possible register?
There are literally _thousands_ of lines of this stuff, and I imagine that careful auditing would reveal that not even 5% of them are actually used by the port. Presumably you have a processor manual, use that when you need it, rather than inlining this crap in the kernel.
Quoted 6 lines · Paul Mundt
Quoted 6 lines
(quoted diff) +6
-0+comment "Memory Optimizations" + +config I_ENTRY_L1 + bool "Locate interrupt entry code in L1 Memory" + default y + help
Quoted 8 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+ If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked + into L1 instruction memory.(less latency) +Wow, this is really crying out for a special linker section with slightly more intelligent relocation logic. You should flag the performance critical parts to be located in L1 memory directly with a section attribute, rather than making everything selectable. If you overflow you can simply spill in to main memory.
This is done intentionally, because it's also possible for user code to be loaded into L1 memory. We want to give users the option to avoid filling it all up with kernel code.
Bernd
Signature · 4 lines
This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, Vincent Roche, Joseph E. McDonough
Quoted 16 lines · Bernd Schmidt
Quoted 6 lines · Paul Mundt
Quoted 6 lines
(quoted diff) +6
-0+comment "Memory Optimizations" + +config I_ENTRY_L1 + bool "Locate interrupt entry code in L1 Memory" + default y + helpQuoted 8 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+ If enabled interrupt entry code (STORE/RESTORE CONTEXT) is linked + into L1 instruction memory.(less latency) +Wow, this is really crying out for a special linker section with slightly more intelligent relocation logic. You should flag the performance critical parts to be located in L1 memory directly with a section attribute, rather than making everything selectable. If you overflow you can simply spill in to main memory.
Quoted 4 lines
This is done intentionally, because it's also possible for user code to be loaded into L1 memory. We want to give users the option to avoid filling it all up with kernel code.
So then why not make the userspace component of it optional and allow a size cap for kernel usage that's configurable if it's enabled? This degree of abstraction is almost worse than no abstraction.
On Mon 5 Mar 2007 07:39, Paul Mundt pondered:
Quoted 18 lines · Bernd Schmidt
Quoted 17 lines
Quoted 15 lines · Paul Mundt
Quoted 9 lines
(quoted diff) +7
-0+comment "Memory Optimizations" + +config I_ENTRY_L1 + bool "Locate interrupt entry code in L1 Memory" + default y + help + If enabled interrupt entry code (STORE/RESTORE CONTEXT) islinked + into L1 instruction memory.(less latency) +
Wow, this is really crying out for a special linker section with slightly more intelligent relocation logic. You should flag the performance critical parts to be located in L1 memory directly with a section attribute, rather than making everything selectable. If you overflow you can simply spill in to main memory.
Quoted 7 lines
Quoted 3 lines
This is done intentionally, because it's also possible for user code to be loaded into L1 memory. We want to give users the option to avoid filling it all up with kernel code.
So then why not make the userspace component of it optional and allow a
size cap for kernel usage that's configurable if it's enabled? This degree of abstraction is almost worse than no abstraction.
I don't understand why you think lots of options are a bad thing??
For most embedded targets, people want/need easy knobs to turn to try and optimise the system level performance. I would guess that SH users want to do the same thing?
That is what this does - it is just a easy to use knob.
-Robin
Quoted 10 lines · Robin Getz
On Mon 5 Mar 2007 07:39, Paul Mundt pondered:
Quoted 8 lines · Bernd Schmidt
Quoted 3 lines
This is done intentionally, because it's also possible for user code to be loaded into L1 memory.?? We want to give users the option to avoid filling it all up with kernel code.
So then why not make the userspace component of it optional and allow a
size cap for kernel usage that's configurable if it's enabled? This degree of abstraction is almost worse than no abstraction.
Quoted 8 lines
I don't understand why you think lots of options are a bad thing??
For most embedded targets, people want/need easy knobs to turn to try and optimise the system level performance. I would guess that SH users want to do the same thing?
That is what this does - it is just a easy to use knob.
This is hardly a knob, you're adding one config option per function to relocate in to the L1 memory, leaving it up to the user to decide what's best positioned there from the kernel point of view and what's left with userspace to play with. This is simply _not_ how you want to do this sort of interface, rather than making any sort of usability decisions, you've pushed it all on the user under the label of flexibility.
What happens now if you suddenly start having other blocks of SRAM in future parts that are either shared across CPUs or just more buffer space for a single CPU? Do you start to repeat the config options for that space, too?
There are things that will be a win to have located in on-chip SRAM, and others that will be less important. If you're concerned about this, you should simply pinpoint the hot paths that benefit the most from being relocated and weight that against a build-time configuration of how much room the user wants to play with. This way you can figure out all of your limits directly at link time, as you're arguably looking at an effectively static configuration anyways.
If you really want to break it down on priority, use something similar to initcall levels. Start with the most critical bits, and stash as much as possible in whatever on-chip memory you have available (while heeding the user constraints) and then spill the rest to system memory.
Throwing this all at the user simply shows that the functions being relocated haven't been profiled adequately with real workloads. You can't seriously expect your users to define what's the most timing critical and hope to get useful result.
These are simply not things the user should ever _care_ about. If a user wants to use on-chip memory, presumably they have a target application in mind, and they know how much space they need. Beyond that, they expect the kernel to do the best it can with the space that's left over for it to play with. If a user has to sit around profiling their workload to figure out what config options to set to chew through the rest of the L1 memory, you've completely lost at intuitive design.
This is like taking the KDE approach to UI design and applying it to the kernel, exposing every possible setting as a user-settable option and avoiding setting any sort of sane default in the hope that user knows best. This simply doesn't work.
On Mon 5 Mar 2007 09:00, Paul Mundt pondered:
Quoted 37 lines · Robin Getz
Quoted 5 lines
On Mon 5 Mar 2007 07:39, Paul Mundt pondered:
Quoted 1 line · Bernd Schmidt
That is what this does - it is just a easy to use knob.
This is hardly a knob, you're adding one config option per function to relocate in to the L1 memory, leaving it up to the user to decide what's best positioned there from the kernel point of view and what's left with userspace to play with. This is simply _not_ how you want to do this sort
of interface, rather than making any sort of usability decisions, you've pushed it all on the user under the label of flexibility.What happens now if you suddenly start having other blocks of SRAM in future parts that are either shared across CPUs or just more buffer space
for a single CPU? Do you start to repeat the config options for that space, too?There are things that will be a win to have located in on-chip SRAM, and others that will be less important. If you're concerned about this, you should simply pinpoint the hot paths that benefit the most from being relocated and weight that against a build-time configuration of how much room the user wants to play with. This way you can figure out all of your
limits directly at link time, as you're arguably looking at an effectively static configuration anyways.If you really want to break it down on priority, use something similar to
initcall levels. Start with the most critical bits, and stash as much as possible in whatever on-chip memory you have available (while heeding the
user constraints) and then spill the rest to system memory.
Quoted 2 lines
Throwing this all at the user simply shows that the functions being relocated haven't been profiled adequately with real workloads.
Actually - that is not true at all - we have profiled these extensively across many workloads on various real world applications from fax machine to bar code scanner, to software radio, to internet radio - and that is the point - it all depends on what the user application/drivers that are loaded are doing. I can't decided what is best for the user, because I don't know what they are doing.
Quoted 2 lines
You can't seriously expect your users to define what's the most timing critical and hope to get useful result.
Yeah, we do - and the users who want to get the best performance - spend the effort in doing so - the others live with the defaults.
Quoted 1 line
These are simply not things the user should ever _care_ about.
Maybe users on Blackfin are more sophisticated than ones using SH?
The reason we did this - is because we saw many end users doing the same thing, and wanted to give people a standard way to do it - that we could test/stand behind and give people support.
Quoted 5 lines
If a user
wants to use on-chip memory, presumably they have a target application in mind, and they know how much space they need. Beyond that, they expect the kernel to do the best it can with the space that's left over for it to play with.
And that is the problem - the kernel doesn't know how much on chip memory an application which will be loaded in the future might need. The user needs to be able to control the amount of on-chip memory that the kernel uses - hence the knobs.
Quoted 3 lines
If a user has to sit around profiling their workload to figure out what config options to set to chew through the rest of the L1 memory, you've completely lost at intuitive design.
Embedded has never been intuitive.
Normally, the majority of end users leave things set by the default, meaning their application doesn't use the on-chip memory, and the kernel is allowed to. If they want to start using on-chip memory, they are forced to do a re-compile, with the kernel functions using off-chip memory, and see how much of on-chip memory their application uses. They calculate the difference, and do a little system level profiling, and put the most used kernel functions back.
Although this isn't intuitive., it is pretty straight forward and mechanical. People do it all the time.
Quoted 4 lines
This is like taking the KDE approach to UI design and applying it to the kernel, exposing every possible setting as a user-settable option and avoiding setting any sort of sane default in the hope that user knows best. This simply doesn't work.
There is a certain level of user sophistication expected when designing a deeply embedded application. I don't think this is a good comparison. Besides - I like (and use) all the knobs in KDE.
You are asking me to try to decide what is best for all the potential end users, with out knowing what the end user is doing. What ends up happening is that people make modifications (normally poor ones) and then still ask for help when their modifications break.
I would rather give them a supported (but arguablely confusing) method of customisation. (This is why it was added - end users were asking for it, and when we didn't have it, they would try to make the modifications themselves, break it, and report a bug. After telling 8 different people the same thing, when do you decide this is a feature you need to support?)
-Robin
-Robin
Quoted 11 lines · Robin Getz
On Mon 5 Mar 2007 09:00, Paul Mundt pondered:
Quoted 2 lines
Throwing this all at the user simply shows that the functions being relocated haven't been profiled adequately with real workloads.
Actually - that is not true at all - we have profiled these extensively across many workloads on various real world applications from fax machine to bar code scanner, to software radio, to internet radio - and that is the point - it all depends on what the user application/drivers that are loaded are doing. I can't decided what is best for the user, because I don't know what they are doing.
And there are just as many cases that are common regardless of the workload that are simply good decisions. Exception vectors are a good example, either you get a boost from having them in L1 memory or you don't, the workload really doesn't matter.
Workloads will of course have variations, but it's optimizing the hot paths that end up being quite common that end up being the most useful. These are not things that should be required from the end user.
Quoted 10 lines
Quoted 4 lines
If a user wants to use on-chip memory, presumably they have a target application in mind, and they know how much space they need. Beyond that, they expect the kernel to do the best it can with the space that's left over for it to play with.
And that is the problem - the kernel doesn't know how much on chip memory an application which will be loaded in the future might need. The user needs to be able to control the amount of on-chip memory that the kernel uses - hence the knobs.
That's crap, for the exact reason that these are not run-time configurable knobs, they are static build-time components. If a user has to scale back the kernel users until their application fits, then they already know how much space they're going to need. Once you know that, reserving a chunk for userspace and limiting the kernel's usage is quite simple.
Quoted 6 lines
Quoted 3 lines
If a user has to sit around profiling their workload to figure out what config options to set to chew through the rest of the L1 memory, you've completely lost at intuitive design.
Embedded has never been intuitive.
Embedded has also never been about throwing everything at the user that's possible. Flexibility is good. Intelligent design is good. Blindly tossing everything the user's way and hoping for the best is not.
Quoted 8 lines
Normally, the majority of end users leave things set by the default, meaning their application doesn't use the on-chip memory, and the kernel is allowed to. If they want to start using on-chip memory, they are forced to do a re-compile, with the kernel functions using off-chip memory, and see how much of on-chip memory their application uses. They calculate the difference, and do a little system level profiling, and put the most used kernel functions back.
Yes, precisely. This is all something that should be done by the kernel _for_ the user. They can of course add their own instrumentation to the hot paths that their workload hits that aren't generally handled, but this should not be a required step.
If I'm working on an embedded application, I expect my kernel to do some sensible things with the hardware available. I don't want to have to manually configure ever possible thing in order to get a system that behaves in a reasonable manner, and I certainly don't want to have to do this multiple times with a profiler for paths that are inevitably going to be quite common anyways.
Quoted 5 lines
You are asking me to try to decide what is best for all the potential end users, with out knowing what the end user is doing. What ends up happening is that people make modifications (normally poor ones) and then still ask for help when their modifications break.
No, I'm asking you to set some sensible defaults, provide an interface that works for the common cases, and allow the special cases to remain simply that.
Quoted 6 lines
I would rather give them a supported (but arguablely confusing) method of customisation. (This is why it was added - end users were asking for it, and when we didn't have it, they would try to make the modifications themselves, break it, and report a bug. After telling 8 different people the same thing, when do you decide this is a feature you need to support?)
There's also a substantial differences between what customers are telling you they want, what they're trying to accomplish, and what they actually need. If you want to add something simple, setup an attribute tag for the section and tell the customers to flag the cases they're most concerned with. Obviously you expect them to be sitting there with a profiler open anyways, so this should not be a problem. Also note that we are not required to accept bad code in the kernel because you happen to have customer requirements for it.
The point is, doing this as a config option design is just broken. It doesn't scale for new code, and it doesn't scale as soon as you start throwing in more blocks of SRAM with varying locality, latencies, etc. Littering around ifdefs for this stuff all over the code is equally ugly.
I'll reiterate my original suggestion, allow the user to cap the amount of memory that's used by the kernel, then add something akin to initcall levels that you can use for prioritizing items to be relocated in on-chip memory, while spilling the rest to RAM. With this sort of scheme you can also trivially spill in to additional SRAM pools and whatever else you have handy as you go along.
You can of course argue that as an embedded platform the user must make all of these decisions on their own, but there can be a compromise if the kernel's at least half-way intelligent about matters. Embedded has never been about hand-waving and expecting the user to solve all of the difficult problems just because they can.
While it may not count for much, until something is done about this and the other issues that were raised earlier in the thread, I'd have to NAK this patch. If not wanting to manually select everything that goes in to L1 memory makes me too unsophisticated by blackfin standards, so be it ;-)
On Mon 5 Mar 2007 12:32, Paul Mundt pondered:
Quoted 14 lines · Robin Getz
Quoted 4 lines
On Mon 5 Mar 2007 09:00, Paul Mundt pondered:
Quoted 2 lines
Throwing this all at the user simply shows that the functions being relocated haven't been profiled adequately with real workloads.
Quoted 8 lines
Actually - that is not true at all - we have profiled these extensively
across many workloads on various real world applications from fax machine to bar code scanner, to software radio, to internet radio - and that is the point - it all depends on what the user application/drivers
that are loaded are doing. I can't decided what is best for the user, because I don't know what they are doing.
Quoted 4 lines
And there are just as many cases that are common regardless of the workload that are simply good decisions. Exception vectors are a good example, either you get a boost from having them in L1 memory or you don't, the workload really doesn't matter.
Then you have not profiled the same applications I have. I see different results in on this platform.
Quoted 3 lines
Workloads will of course have variations, but it's optimizing the hot paths that end up being quite common that end up being the most useful. These are not things that should be required from the end user.
The end user is the only one who knows what is work load is.
Quoted 10 lines
Quoted 9 lines
Quoted 4 lines
If a user wants to use on-chip memory, presumably they have a target application in mind, and they know how much space they need. Beyond that, they expect the kernel to do the best it can with the space that's left over for it to play with.
And that is the problem - the kernel doesn't know how much on chip memory an application which will be loaded in the future might need. The user needs to be able to control the amount of on-chip memory that the kernel uses - hence the knobs.
Quoted 6 lines
That's crap, for the exact reason that these are not run-time configurable knobs, they are static build-time components. If a user has to scale back the kernel users until their application fits, then they already know how much space they're going to need. Once you know that, reserving a chunk for userspace and limiting the kernel's usage is quite simple.
OK - you want me to remove 14 selections (yeah - I agree that is alot), and replace them with one selection, and a header file, that the user has to maintain separately from the .config, which everyone does already? IMHO - that is harder for an end user to maintain than our existing proposal.
Quoted 10 lines
Quoted 5 lines
Quoted 3 lines
If a user has to sit around profiling their workload to figure out what config options to set to chew through the rest of the L1 memory, you've completely lost at intuitive design.
Embedded has never been intuitive.
Embedded has also never been about throwing everything at the user that's possible. Flexibility is good. Intelligent design is good. Blindly tossing everything the user's way and hoping for the best is not.
default settings?
Hope is not a strategy that we use. Careful design is (most of the time).
Quoted 14 lines
Quoted 8 lines
Normally, the majority of end users leave things set by the default, meaning their application doesn't use the on-chip memory, and the kernel is allowed to. If they want to start using on-chip memory, they are forced to do a re-compile, with the kernel functions using off-chip memory, and see how much of on-chip memory their application uses. They calculate the difference, and do a little system level profiling, and put the most used kernel functions back.
Yes, precisely. This is all something that should be done by the kernel _for_ the user. They can of course add their own instrumentation to the hot paths that their workload hits that aren't generally handled, but this should not be a required step.
Quoted 6 lines
If I'm working on an embedded application, I expect my kernel to do some sensible things with the hardware available. I don't want to have to manually configure ever possible thing in order to get a system that behaves in a reasonable manner, and I certainly don't want to have to do this multiple times with a profiler for paths that are inevitably going to be quite common anyways.
People do all kinds of things to make their application work better on a processor that cost less than lunch for one person.
The applications always work without system level tuning - but they can work up to 2x faster with a little performance tweaking. To most people, spending the day or two - doing the tweaking to get max performance that the chip is capable of is worth the effort.
Quoted 8 lines
Quoted 4 lines
You are asking me to try to decide what is best for all the potential end users, with out knowing what the end user is doing. What ends up happening is that people make modifications (normally poor ones) and then still ask for help when their modifications break.
No, I'm asking you to set some sensible defaults, provide an interface that works for the common cases, and allow the special cases to remain simply that.
In my opinion - that is what we have.
Quoted 6 lines
Quoted 6 lines
I would rather give them a supported (but arguablely confusing) method of customisation. (This is why it was added - end users were asking for it, and when we didn't have it, they would try to make the modifications themselves, break it, and report a bug. After telling 8 different people the same thing,
Quoted 8 lines
There's also a substantial differences between what customers are telling
you they want, what they're trying to accomplish, and what they actually need. If you want to add something simple, setup an attribute tag for the
section and tell the customers to flag the cases they're most concerned with. Obviously you expect them to be sitting there with a profiler open anyways, so this should not be a problem.
This is what people do today (without our proposal). This is what was causing all the problems. This is what we are trying to avoid.
Quoted 2 lines
Also note that we are not required to accept bad code in the kernel because you happen to have customer requirements for it.
I am not asking you to accept bad code. I'm trying to explain why we came to a specific design decision, and went down a specific path, after thinking about and a similar idea as your suggestion.
Quoted 5 lines
The point is, doing this as a config option design is just broken. It doesn't scale for new code, and it doesn't scale as soon as you start throwing in more blocks of SRAM with varying locality, latencies, etc. Littering around ifdefs for this stuff all over the code is equally ugly.
It is equally bad to force end users to maintain a patch set, to change around our best guess of what their fast paths might be in a .h file.
Quoted 6 lines
I'll reiterate my original suggestion, allow the user to cap the amount of memory that's used by the kernel, then add something akin to initcall levels that you can use for prioritizing items to be relocated in on-chip memory, while spilling the rest to RAM. With this sort of scheme you can also trivially spill in to additional SRAM pools and whatever else you have handy as you go along.
I don't understand how this is radically different than what we have today. You are suggesting that we take the knobs that are easy to modify, and hide them, to create pain for a user who wants to/needs to use them. I don't think this is good design either.
Quoted 3 lines
You can of course argue that as an embedded platform the user must make all of these decisions on their own, but there can be a compromise if the kernel's at least half-way intelligent about matters.
I guess it is an disagreement in overall design philosophy - I thought the kernel was suppost to be flexible enough to handle the corner cases, and robust enough to ensure proper operation in all cases. What we are attempting to do (maybe poorly - jury is still out), is continue to add flexibility, putting the burden on us - the maintainers of all the files where the #ifdefs exist (all in arch/blackfin or include/asm-blackfin), to make it easier (both from use and maintenance) on end users.
If your disagreement is - this doesn't make it easier, it makes it harder - then OK - but I don't think moving the controls somewhere else makes it easier. Plus I am not sure how I would explain things - "there are n levels of prioritizing if a function will be in slow or fast SRAM. Setting things to the highest priority may not mean it will go in the fastest SRAM, and you won't know until runtime, when your application doesn't run as fast as it should or by digging through the map file and looking at the address of the function".
This is a worst case explanation, and I am sure that you could think of something better. I tend to be negative.
What we have today - is a switch (not a knob). If you select too much, link fails. There is no "spill over" - by design. It is in on-chip SRAM, or not.
Quoted 5 lines
While it may not count for much, until something is done about this and the other issues that were raised earlier in the thread, I'd have to NAK this patch. If not wanting to manually select everything that goes in to L1 memory makes me too unsophisticated by blackfin standards, so be it ;-)
It's not that we don't appreciate the thoughts and time that you have looking into this - we do and Thanks - I guess I would rather have something that:
- hard failure, rather than soft failure. (it works, or it doesn't boot)
- is maintained in .config file
We are all about worrying about good design, proper code, and future maintenance/extendability. I think that this specific part of the patch meet those goals.
As for the other pieces of the patch, that you pointed out - most need to be fixed per your comments. Thanks again for the time.
-Robin
Quoted 5 lines · Paul Mundt
Review
Quoted 3 lines
(quoted diff) +3
-0+config DEBUG_HUNT_FOR_ZERO + bool "Catch NULL pointer reads/writes" + default yIs this sane to have conditional?
yes ... with the ability to change the load address of the kernel, you can create a reserved chunk of memory for users to utilize in their custom kernel/userspace apps
an abuse of no-mmu to be sure ;)
Quoted 6 lines
Quoted 6 lines
(quoted diff) +6
-0+#ifdef CONFIG_BUG +#define HAVE_ARCH_BUG +#define BUG() do { \ + dump_stack(); \ + printk(KERN_WARNING "\nkernel BUG at %s:%d!\n",\ + __FILE__, __LINE__); \
Quoted 8 lines
Review
Quoted 6 lines
(quoted diff) +6
-0+ panic("BUG!"); \ +} while (0) +#endif + +#include <asm-generic/bug.h> +#endifWhat do you need
HAVE_ARCH_BUGfor? You're not doing anything with it..
last i checked, the default BUG() does not include the dump_stack() ... if things have changed, then sure the generic bug implementation is OK, otherwise this helps us with debugging
-mike
Quoted 10 lines · Paul Mundt
Quoted 3 lines
(quoted diff) +3
-0+int __init oprofile_arch_init(struct oprofile_operations *ops) +{ +#ifdef CONFIG_HARDWARE_PM[snip]
Review
Quoted 4 lines
(quoted diff) +4
-0+#else + return -1; +#endif +}Uh.. fix your dependencies.
can you elaborate ?
-mike
Quoted 5 lines · Mike Frysinger
Quoted 4 lines · Paul Mundt
Quoted 3 lines
(quoted diff) +3
-0+int __init oprofile_arch_init(struct oprofile_operations *ops) +{ +#ifdef CONFIG_HARDWARE_PM[snip]
Quoted 8 lines
Quoted 6 lines
Review
Quoted 4 lines
(quoted diff) +4
-0+#else + return -1; +#endif +}Uh.. fix your dependencies.
can you elaborate ?
This code does nothing if CONFIG_HARDWARE_PM isn't enabled, so your best bet is to simply have an op_model_null for the cases where you can't support the counters and work out the dependencies in the Makefile. Trying to hack both of these together in one driver is not the way to go.