You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge master.kernel.org:/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (30 commits) Blackfin serial driver: supporting BF548-EZKIT serial port Video Console: Blackfin doesnt support VGA console Blackfin arch: Add peripheral io API to gpio header file Blackfin arch: set up gpio interrupt IRQ_PJ9 for BF54x ATAPI PATA driver Blackfin arch: add missing CONFIG_LARGE_ALLOCS when upstream merging Blackfin arch: as pointed out by Robert P. J. Day, update the CPU_FREQ name to match current Kconfig Blackfin arch: extract the entry point from the linked kernel Blackfin arch: clean up some coding style issues Blackfin arch: combine the common code of free_initrd_mem and free_initmem Blackfin arch: Add Support for Peripheral PortMux and resouce allocation Blackfin arch: use PAGE_SIZE when doing aligns rather than hardcoded values Blackfin arch: fix bug set dma_address properly in dma_map_sg Blackfin arch: Disable CACHELINE_ALIGNED_L1 for BF54x by default Blackfin arch: Port the dm9000 driver to Blackfin by using the correct low-level io routines Blackfin arch: There is no CDPRIO Bit in the EBIU_AMGCTL Register of BF54x arch Blackfin arch: scrub dead code Blackfin arch: Fix Warning add some defines in BF54x header file Blackfin arch: add BF54x missing GPIO access functions Blackfin arch: Some memory and code optimizations - Fix SYS_IRQS Blackfin arch: Enable BF54x PIN/GPIO interrupts ...
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
A Simple Guide to Configure KGDB
|
||||
|
||||
Sonic Zhang <sonic.zhang@analog.com>
|
||||
Aug. 24th 2006
|
||||
|
||||
|
||||
This KGDB patch enables the kernel developer to do source level debugging on
|
||||
the kernel for the Blackfin architecture. The debugging works over either the
|
||||
ethernet interface or one of the uarts. Both software breakpoints and
|
||||
hardware breakpoints are supported in this version.
|
||||
http://docs.blackfin.uclinux.org/doku.php?id=kgdb
|
||||
|
||||
|
||||
2 known issues:
|
||||
1. This bug:
|
||||
http://blackfin.uclinux.org/tracker/index.php?func=detail&aid=544&group_id=18&atid=145
|
||||
The GDB client for Blackfin uClinux causes incorrect values of local
|
||||
variables to be displayed when the user breaks the running of kernel in GDB.
|
||||
2. Because of a hardware bug in Blackfin 533 v1.0.3:
|
||||
05000067 - Watchpoints (Hardware Breakpoints) are not supported
|
||||
Hardware breakpoints cannot be set properly.
|
||||
|
||||
|
||||
Debug over Ethernet:
|
||||
|
||||
1. Compile and install the cross platform version of gdb for blackfin, which
|
||||
can be found at $(BINROOT)/bfin-elf-gdb.
|
||||
|
||||
2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under
|
||||
"Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
|
||||
With this selected, option "Full Symbolic/Source Debugging support" and
|
||||
"Compile the kernel with frame pointers" are also selected.
|
||||
|
||||
3. Select option "KGDB: connect over (Ethernet)". Add "kgdboe=@target-IP/,@host-IP/" to
|
||||
the option "Compiled-in Kernel Boot Parameter" under "Kernel hacking".
|
||||
|
||||
4. Connect minicom to the serial port and boot the kernel image.
|
||||
|
||||
5. Configure the IP "/> ifconfig eth0 target-IP"
|
||||
|
||||
6. Start GDB client "bfin-elf-gdb vmlinux".
|
||||
|
||||
7. Connect to the target "(gdb) target remote udp:target-IP:6443".
|
||||
|
||||
8. Set software breakpoint "(gdb) break sys_open".
|
||||
|
||||
9. Continue "(gdb) c".
|
||||
|
||||
10. Run ls in the target console "/> ls".
|
||||
|
||||
11. Breakpoint hits. "Breakpoint 1: sys_open(..."
|
||||
|
||||
12. Display local variables and function paramters.
|
||||
(*) This operation gives wrong results, see known issue 1.
|
||||
|
||||
13. Single stepping "(gdb) si".
|
||||
|
||||
14. Remove breakpoint 1. "(gdb) del 1"
|
||||
|
||||
15. Set hardware breakpoint "(gdb) hbreak sys_open".
|
||||
|
||||
16. Continue "(gdb) c".
|
||||
|
||||
17. Run ls in the target console "/> ls".
|
||||
|
||||
18. Hardware breakpoint hits. "Breakpoint 1: sys_open(...".
|
||||
(*) This hardware breakpoint will not be hit, see known issue 2.
|
||||
|
||||
19. Continue "(gdb) c".
|
||||
|
||||
20. Interrupt the target in GDB "Ctrl+C".
|
||||
|
||||
21. Detach from the target "(gdb) detach".
|
||||
|
||||
22. Exit GDB "(gdb) quit".
|
||||
|
||||
|
||||
Debug over the UART:
|
||||
|
||||
1. Compile and install the cross platform version of gdb for blackfin, which
|
||||
can be found at $(BINROOT)/bfin-elf-gdb.
|
||||
|
||||
2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under
|
||||
"Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
|
||||
With this selected, option "Full Symbolic/Source Debugging support" and
|
||||
"Compile the kernel with frame pointers" are also selected.
|
||||
|
||||
3. Select option "KGDB: connect over (UART)". Set "KGDB: UART port number" to be
|
||||
a different one from the console. Don't forget to change the mode of
|
||||
blackfin serial driver to PIO. Otherwise kgdb works incorrectly on UART.
|
||||
|
||||
4. If you want connect to kgdb when the kernel boots, enable
|
||||
"KGDB: Wait for gdb connection early"
|
||||
|
||||
5. Compile kernel.
|
||||
|
||||
6. Connect minicom to the serial port of the console and boot the kernel image.
|
||||
|
||||
7. Start GDB client "bfin-elf-gdb vmlinux".
|
||||
|
||||
8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
|
||||
|
||||
9. Connect to the target on the second serial port "(gdb) target remote /dev/ttyS1".
|
||||
|
||||
10. Set software breakpoint "(gdb) break sys_open".
|
||||
|
||||
11. Continue "(gdb) c".
|
||||
|
||||
12. Run ls in the target console "/> ls".
|
||||
|
||||
13. A breakpoint is hit. "Breakpoint 1: sys_open(..."
|
||||
|
||||
14. All other operations are the same as that in KGDB over Ethernet.
|
||||
|
||||
|
||||
Debug over the same UART as console:
|
||||
|
||||
1. Compile and install the cross platform version of gdb for blackfin, which
|
||||
can be found at $(BINROOT)/bfin-elf-gdb.
|
||||
|
||||
2. Apply this patch to the 2.6.x kernel. Select the menuconfig option under
|
||||
"Kernel hacking" -> "Kernel debugging" -> "KGDB: kernel debug with remote gdb".
|
||||
With this selected, option "Full Symbolic/Source Debugging support" and
|
||||
"Compile the kernel with frame pointers" are also selected.
|
||||
|
||||
3. Select option "KGDB: connect over UART". Set "KGDB: UART port number" to console.
|
||||
Don't forget to change the mode of blackfin serial driver to PIO.
|
||||
Otherwise kgdb works incorrectly on UART.
|
||||
|
||||
4. If you want connect to kgdb when the kernel boots, enable
|
||||
"KGDB: Wait for gdb connection early"
|
||||
|
||||
5. Connect minicom to the serial port and boot the kernel image.
|
||||
|
||||
6. (Optional) Ask target to wait for gdb connection by entering Ctrl+A. In minicom, you should enter Ctrl+A+A.
|
||||
|
||||
7. Start GDB client "bfin-elf-gdb vmlinux".
|
||||
|
||||
8. Set the baud rate in GDB "(gdb) set remotebaud 57600".
|
||||
|
||||
9. Connect to the target "(gdb) target remote /dev/ttyS0".
|
||||
|
||||
10. Set software breakpoint "(gdb) break sys_open".
|
||||
|
||||
11. Continue "(gdb) c". Then enter Ctrl+C twice to stop GDB connection.
|
||||
|
||||
12. Run ls in the target console "/> ls". Dummy string can be seen on the console.
|
||||
|
||||
13. Then connect the gdb to target again. "(gdb) target remote /dev/ttyS0".
|
||||
Now you will find a breakpoint is hit. "Breakpoint 1: sys_open(..."
|
||||
|
||||
14. All other operations are the same as that in KGDB over Ethernet. The only
|
||||
difference is that after continue command in GDB, please stop GDB
|
||||
connection by 2 "Ctrl+C"s and connect again after breakpoints are hit or
|
||||
Ctrl+A is entered.
|
||||
+56
-3
@@ -71,6 +71,7 @@ config GENERIC_CALIBRATE_DELAY
|
||||
|
||||
config IRQCHIP_DEMUX_GPIO
|
||||
bool
|
||||
depends on (BF53x || BF561 || BF54x)
|
||||
default y
|
||||
|
||||
source "init/Kconfig"
|
||||
@@ -114,6 +115,26 @@ config BF537
|
||||
help
|
||||
BF537 Processor Support.
|
||||
|
||||
config BF542
|
||||
bool "BF542"
|
||||
help
|
||||
BF542 Processor Support.
|
||||
|
||||
config BF544
|
||||
bool "BF544"
|
||||
help
|
||||
BF544 Processor Support.
|
||||
|
||||
config BF548
|
||||
bool "BF548"
|
||||
help
|
||||
BF548 Processor Support.
|
||||
|
||||
config BF549
|
||||
bool "BF549"
|
||||
help
|
||||
BF549 Processor Support.
|
||||
|
||||
config BF561
|
||||
bool "BF561"
|
||||
help
|
||||
@@ -125,6 +146,11 @@ choice
|
||||
prompt "Silicon Rev"
|
||||
default BF_REV_0_2 if BF537
|
||||
default BF_REV_0_3 if BF533
|
||||
default BF_REV_0_0 if BF549
|
||||
|
||||
config BF_REV_0_0
|
||||
bool "0.0"
|
||||
depends on (BF549)
|
||||
|
||||
config BF_REV_0_2
|
||||
bool "0.2"
|
||||
@@ -150,6 +176,16 @@ config BF_REV_NONE
|
||||
|
||||
endchoice
|
||||
|
||||
config BF53x
|
||||
bool
|
||||
depends on (BF531 || BF532 || BF533 || BF534 || BF536 || BF537)
|
||||
default y
|
||||
|
||||
config BF54x
|
||||
bool
|
||||
depends on (BF542 || BF544 || BF548 || BF549)
|
||||
default y
|
||||
|
||||
config BFIN_DUAL_CORE
|
||||
bool
|
||||
depends on (BF561)
|
||||
@@ -198,6 +234,12 @@ config BFIN537_BLUETECHNIX_CM
|
||||
help
|
||||
CM-BF537 support for EVAL- and DEV-Board.
|
||||
|
||||
config BFIN548_EZKIT
|
||||
bool "BF548-EZKIT"
|
||||
depends on (BF548 || BF549)
|
||||
help
|
||||
BFIN548-EZKIT board Support.
|
||||
|
||||
config BFIN561_BLUETECHNIX_CM
|
||||
bool "Bluetechnix CM-BF561"
|
||||
depends on (BF561)
|
||||
@@ -265,6 +307,7 @@ config BFIN_SHARED_FLASH_ENET
|
||||
source "arch/blackfin/mach-bf533/Kconfig"
|
||||
source "arch/blackfin/mach-bf561/Kconfig"
|
||||
source "arch/blackfin/mach-bf537/Kconfig"
|
||||
source "arch/blackfin/mach-bf548/Kconfig"
|
||||
|
||||
menu "Board customizations"
|
||||
|
||||
@@ -497,7 +540,8 @@ config IP_CHECKSUM_L1
|
||||
|
||||
config CACHELINE_ALIGNED_L1
|
||||
bool "Locate cacheline_aligned data to L1 Data Memory"
|
||||
default y
|
||||
default y if !BF54x
|
||||
default n if BF54x
|
||||
depends on !BF531
|
||||
help
|
||||
If enabled cacheline_anligned data is linked
|
||||
@@ -541,9 +585,17 @@ endchoice
|
||||
|
||||
source "mm/Kconfig"
|
||||
|
||||
config LARGE_ALLOCS
|
||||
bool "Allow allocating large blocks (> 1MB) of memory"
|
||||
help
|
||||
Allow the slab memory allocator to keep chains for very large
|
||||
memory sizes - upto 32MB. You may need this if your system has
|
||||
a lot of RAM, and you need to able to allocate very large
|
||||
contiguous chunks. If unsure, say N.
|
||||
|
||||
config BFIN_DMA_5XX
|
||||
bool "Enable DMA Support"
|
||||
depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561)
|
||||
depends on (BF533 || BF532 || BF531 || BF537 || BF536 || BF534 || BF561 || BF54x)
|
||||
default y
|
||||
help
|
||||
DMA driver for BF5xx.
|
||||
@@ -686,6 +738,7 @@ config C_AMCKEN
|
||||
|
||||
config C_CDPRIO
|
||||
bool "DMA has priority over core for ext. accesses"
|
||||
depends on !BF54x
|
||||
default n
|
||||
|
||||
config C_B0PEN
|
||||
@@ -839,7 +892,7 @@ endchoice
|
||||
|
||||
endmenu
|
||||
|
||||
if (BF537 || BF533)
|
||||
if (BF537 || BF533 || BF54x)
|
||||
|
||||
menu "CPU Frequency scaling"
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ machine-$(CONFIG_BF533) := bf533
|
||||
machine-$(CONFIG_BF534) := bf537
|
||||
machine-$(CONFIG_BF536) := bf537
|
||||
machine-$(CONFIG_BF537) := bf537
|
||||
machine-$(CONFIG_BF548) := bf548
|
||||
machine-$(CONFIG_BF549) := bf548
|
||||
machine-$(CONFIG_BF561) := bf561
|
||||
MACHINE := $(machine-y)
|
||||
export MACHINE
|
||||
|
||||
@@ -13,7 +13,8 @@ extra-y += vmlinux.bin vmlinux.gz
|
||||
|
||||
quiet_cmd_uimage = UIMAGE $@
|
||||
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(ARCH) -O linux -T kernel \
|
||||
-C gzip -a $(CONFIG_BOOT_LOAD) -e $(CONFIG_BOOT_LOAD) -n 'Linux-$(KERNELRELEASE)' \
|
||||
-C gzip -n 'Linux-$(KERNELRELEASE)' -a $(CONFIG_BOOT_LOAD) \
|
||||
-e $(shell $(NM) vmlinux | awk '$$NF == "__start" {print $$1}') \
|
||||
-d $< $@
|
||||
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,9 +6,12 @@ extra-y := init_task.o vmlinux.lds
|
||||
|
||||
obj-y := \
|
||||
entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
|
||||
sys_bfin.o time.o traps.o irqchip.o dma-mapping.o bfin_gpio.o \
|
||||
flat.o
|
||||
sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
|
||||
fixed_code.o cplbinit.o cacheinit.o
|
||||
|
||||
obj-$(CONFIG_BF53x) += bfin_gpio.o
|
||||
obj-$(CONFIG_BF561) += bfin_gpio.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o
|
||||
obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
|
||||
@@ -32,11 +32,10 @@
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/thread_info.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/thread_info.h>
|
||||
|
||||
#define DEFINE(sym, val) \
|
||||
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
|
||||
#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/param.h>
|
||||
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
@@ -45,67 +46,6 @@
|
||||
***************************************************************************/
|
||||
|
||||
static struct dma_channel dma_ch[MAX_BLACKFIN_DMA_CHANNEL];
|
||||
#if defined (CONFIG_BF561)
|
||||
static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
|
||||
(struct dma_register *) DMA1_0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_2_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_3_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_4_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_5_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_6_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_7_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_8_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_9_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_10_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_11_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_2_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_3_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_4_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_5_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_6_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_7_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_8_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_9_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_10_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_11_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA1_D0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA1_S0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA1_D1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA1_S1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA2_D0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA2_S0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA2_D1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA2_S1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) IMDMA_D0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) IMDMA_S0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) IMDMA_D1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) IMDMA_S1_NEXT_DESC_PTR,
|
||||
};
|
||||
#else
|
||||
static struct dma_register *base_addr[MAX_BLACKFIN_DMA_CHANNEL] = {
|
||||
(struct dma_register *) DMA0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA2_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA3_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA4_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA5_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA6_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA7_NEXT_DESC_PTR,
|
||||
#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
|
||||
(struct dma_register *) DMA8_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA9_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA10_NEXT_DESC_PTR,
|
||||
(struct dma_register *) DMA11_NEXT_DESC_PTR,
|
||||
#endif
|
||||
(struct dma_register *) MDMA_D0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA_S0_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA_D1_NEXT_DESC_PTR,
|
||||
(struct dma_register *) MDMA_S1_NEXT_DESC_PTR,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Set the Buffer Clear bit in the Configuration register of specific DMA
|
||||
@@ -138,149 +78,6 @@ static int __init blackfin_dma_init(void)
|
||||
|
||||
arch_initcall(blackfin_dma_init);
|
||||
|
||||
/*
|
||||
* Form the channel find the irq number for that channel.
|
||||
*/
|
||||
#if !defined(CONFIG_BF561)
|
||||
|
||||
static int bf533_channel2irq(unsigned int channel)
|
||||
{
|
||||
int ret_irq = -1;
|
||||
|
||||
switch (channel) {
|
||||
case CH_PPI:
|
||||
ret_irq = IRQ_PPI;
|
||||
break;
|
||||
|
||||
#if (defined(CONFIG_BF537) || defined(CONFIG_BF534) || defined(CONFIG_BF536))
|
||||
case CH_EMAC_RX:
|
||||
ret_irq = IRQ_MAC_RX;
|
||||
break;
|
||||
|
||||
case CH_EMAC_TX:
|
||||
ret_irq = IRQ_MAC_TX;
|
||||
break;
|
||||
|
||||
case CH_UART1_RX:
|
||||
ret_irq = IRQ_UART1_RX;
|
||||
break;
|
||||
|
||||
case CH_UART1_TX:
|
||||
ret_irq = IRQ_UART1_TX;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case CH_SPORT0_RX:
|
||||
ret_irq = IRQ_SPORT0_RX;
|
||||
break;
|
||||
|
||||
case CH_SPORT0_TX:
|
||||
ret_irq = IRQ_SPORT0_TX;
|
||||
break;
|
||||
|
||||
case CH_SPORT1_RX:
|
||||
ret_irq = IRQ_SPORT1_RX;
|
||||
break;
|
||||
|
||||
case CH_SPORT1_TX:
|
||||
ret_irq = IRQ_SPORT1_TX;
|
||||
break;
|
||||
|
||||
case CH_SPI:
|
||||
ret_irq = IRQ_SPI;
|
||||
break;
|
||||
|
||||
case CH_UART_RX:
|
||||
ret_irq = IRQ_UART_RX;
|
||||
break;
|
||||
|
||||
case CH_UART_TX:
|
||||
ret_irq = IRQ_UART_TX;
|
||||
break;
|
||||
|
||||
case CH_MEM_STREAM0_SRC:
|
||||
case CH_MEM_STREAM0_DEST:
|
||||
ret_irq = IRQ_MEM_DMA0;
|
||||
break;
|
||||
|
||||
case CH_MEM_STREAM1_SRC:
|
||||
case CH_MEM_STREAM1_DEST:
|
||||
ret_irq = IRQ_MEM_DMA1;
|
||||
break;
|
||||
}
|
||||
return ret_irq;
|
||||
}
|
||||
|
||||
# define channel2irq(channel) bf533_channel2irq(channel)
|
||||
|
||||
#else
|
||||
|
||||
static int bf561_channel2irq(unsigned int channel)
|
||||
{
|
||||
int ret_irq = -1;
|
||||
|
||||
switch (channel) {
|
||||
case CH_PPI0:
|
||||
ret_irq = IRQ_PPI0;
|
||||
break;
|
||||
case CH_PPI1:
|
||||
ret_irq = IRQ_PPI1;
|
||||
break;
|
||||
case CH_SPORT0_RX:
|
||||
ret_irq = IRQ_SPORT0_RX;
|
||||
break;
|
||||
case CH_SPORT0_TX:
|
||||
ret_irq = IRQ_SPORT0_TX;
|
||||
break;
|
||||
case CH_SPORT1_RX:
|
||||
ret_irq = IRQ_SPORT1_RX;
|
||||
break;
|
||||
case CH_SPORT1_TX:
|
||||
ret_irq = IRQ_SPORT1_TX;
|
||||
break;
|
||||
case CH_SPI:
|
||||
ret_irq = IRQ_SPI;
|
||||
break;
|
||||
case CH_UART_RX:
|
||||
ret_irq = IRQ_UART_RX;
|
||||
break;
|
||||
case CH_UART_TX:
|
||||
ret_irq = IRQ_UART_TX;
|
||||
break;
|
||||
|
||||
case CH_MEM_STREAM0_SRC:
|
||||
case CH_MEM_STREAM0_DEST:
|
||||
ret_irq = IRQ_MEM_DMA0;
|
||||
break;
|
||||
case CH_MEM_STREAM1_SRC:
|
||||
case CH_MEM_STREAM1_DEST:
|
||||
ret_irq = IRQ_MEM_DMA1;
|
||||
break;
|
||||
case CH_MEM_STREAM2_SRC:
|
||||
case CH_MEM_STREAM2_DEST:
|
||||
ret_irq = IRQ_MEM_DMA2;
|
||||
break;
|
||||
case CH_MEM_STREAM3_SRC:
|
||||
case CH_MEM_STREAM3_DEST:
|
||||
ret_irq = IRQ_MEM_DMA3;
|
||||
break;
|
||||
|
||||
case CH_IMEM_STREAM0_SRC:
|
||||
case CH_IMEM_STREAM0_DEST:
|
||||
ret_irq = IRQ_IMEM_DMA0;
|
||||
break;
|
||||
case CH_IMEM_STREAM1_SRC:
|
||||
case CH_IMEM_STREAM1_DEST:
|
||||
ret_irq = IRQ_IMEM_DMA1;
|
||||
break;
|
||||
}
|
||||
return ret_irq;
|
||||
}
|
||||
|
||||
# define channel2irq(channel) bf561_channel2irq(channel)
|
||||
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Request the specific DMA channel from the system.
|
||||
*-----------------------------------------------------------------------------*/
|
||||
@@ -535,7 +332,7 @@ set_bfin_dma_config(char direction, char flow_mode,
|
||||
}
|
||||
EXPORT_SYMBOL(set_bfin_dma_config);
|
||||
|
||||
void set_dma_sg(unsigned int channel, struct dmasg * sg, int nr_sg)
|
||||
void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg)
|
||||
{
|
||||
BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
|
||||
&& channel < MAX_BLACKFIN_DMA_CHANNEL));
|
||||
@@ -604,7 +401,7 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
|
||||
|
||||
if (size <= 0)
|
||||
return NULL;
|
||||
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
if ((unsigned long)src < memory_end)
|
||||
@@ -748,7 +545,6 @@ void *dma_memcpy(void *dest, const void *src, size_t size)
|
||||
addr = __dma_memcpy(dest+bulk, src+bulk, rest);
|
||||
return addr;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dma_memcpy);
|
||||
|
||||
void *safe_dma_memcpy(void *dest, const void *src, size_t size)
|
||||
@@ -761,14 +557,13 @@ EXPORT_SYMBOL(safe_dma_memcpy);
|
||||
|
||||
void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
|
||||
{
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(addr);
|
||||
local_irq_save(flags);
|
||||
|
||||
blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(addr);
|
||||
bfin_write_MDMA_D0_X_COUNT(len);
|
||||
bfin_write_MDMA_D0_X_MODIFY(0);
|
||||
bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
|
||||
@@ -796,9 +591,9 @@ EXPORT_SYMBOL(dma_outsb);
|
||||
void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
local_irq_save(flags);
|
||||
bfin_write_MDMA_D0_START_ADDR(buf);
|
||||
bfin_write_MDMA_D0_START_ADDR(buf);
|
||||
bfin_write_MDMA_D0_X_COUNT(len);
|
||||
bfin_write_MDMA_D0_X_MODIFY(1);
|
||||
bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
|
||||
@@ -827,12 +622,12 @@ EXPORT_SYMBOL(dma_insb);
|
||||
void dma_outsw(void __iomem *addr, const void *buf, unsigned short len)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(addr);
|
||||
local_irq_save(flags);
|
||||
|
||||
blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(addr);
|
||||
bfin_write_MDMA_D0_X_COUNT(len);
|
||||
bfin_write_MDMA_D0_X_MODIFY(0);
|
||||
bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
|
||||
@@ -859,10 +654,10 @@ EXPORT_SYMBOL(dma_outsw);
|
||||
void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(buf);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(buf);
|
||||
bfin_write_MDMA_D0_X_COUNT(len);
|
||||
bfin_write_MDMA_D0_X_MODIFY(2);
|
||||
bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
|
||||
@@ -891,12 +686,12 @@ EXPORT_SYMBOL(dma_insw);
|
||||
void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
blackfin_dcache_flush_range((unsigned int)buf,(unsigned int)(buf) + len);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(addr);
|
||||
local_irq_save(flags);
|
||||
|
||||
blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(addr);
|
||||
bfin_write_MDMA_D0_X_COUNT(len);
|
||||
bfin_write_MDMA_D0_X_MODIFY(0);
|
||||
bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
|
||||
@@ -923,10 +718,10 @@ EXPORT_SYMBOL(dma_outsl);
|
||||
void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(buf);
|
||||
|
||||
bfin_write_MDMA_D0_START_ADDR(buf);
|
||||
bfin_write_MDMA_D0_X_COUNT(len);
|
||||
bfin_write_MDMA_D0_X_MODIFY(4);
|
||||
bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
|
||||
|
||||
@@ -162,7 +162,7 @@ static void port_setup(unsigned short gpio, unsigned short usage)
|
||||
|
||||
static void default_gpio(unsigned short gpio)
|
||||
{
|
||||
unsigned short bank,bitmask;
|
||||
unsigned short bank, bitmask;
|
||||
|
||||
bank = gpio_bank(gpio);
|
||||
bitmask = gpio_bit(gpio);
|
||||
@@ -183,7 +183,7 @@ static int __init bfin_gpio_init(void)
|
||||
|
||||
printk(KERN_INFO "Blackfin GPIO Controller\n");
|
||||
|
||||
for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE)
|
||||
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE)
|
||||
reserved_map[gpio_bank(i)] = 0;
|
||||
|
||||
#if defined(BF537_FAMILY) && (defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
|
||||
@@ -478,7 +478,7 @@ u32 gpio_pm_setup(void)
|
||||
u32 sic_iwr = 0;
|
||||
u16 bank, mask, i, gpio;
|
||||
|
||||
for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
|
||||
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
|
||||
mask = wakeup_map[gpio_bank(i)];
|
||||
bank = gpio_bank(i);
|
||||
|
||||
@@ -522,12 +522,11 @@ u32 gpio_pm_setup(void)
|
||||
return IWR_ENABLE_ALL;
|
||||
}
|
||||
|
||||
|
||||
void gpio_pm_restore(void)
|
||||
{
|
||||
u16 bank, mask, i;
|
||||
|
||||
for (i = 0; i < MAX_BLACKFIN_GPIOS; i+=GPIO_BANKSIZE) {
|
||||
for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
|
||||
mask = wakeup_map[gpio_bank(i)];
|
||||
bank = gpio_bank(i);
|
||||
|
||||
@@ -591,7 +590,6 @@ int gpio_request(unsigned short gpio, const char *label)
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_request);
|
||||
|
||||
|
||||
void gpio_free(unsigned short gpio)
|
||||
{
|
||||
unsigned long flags;
|
||||
@@ -616,7 +614,6 @@ void gpio_free(unsigned short gpio)
|
||||
}
|
||||
EXPORT_SYMBOL(gpio_free);
|
||||
|
||||
|
||||
void gpio_direction_input(unsigned short gpio)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
@@ -28,10 +28,11 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/checksum.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/* platform dependent support */
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2004-2007 Analog Devices Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/cpu.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/cplbinit.h>
|
||||
|
||||
#if defined(CONFIG_BLKFIN_CACHE)
|
||||
void bfin_icache_init(void)
|
||||
{
|
||||
unsigned long *table = icplb_table;
|
||||
unsigned long ctrl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CPLBS; i++) {
|
||||
unsigned long addr = *table++;
|
||||
unsigned long data = *table++;
|
||||
if (addr == (unsigned long)-1)
|
||||
break;
|
||||
bfin_write32(ICPLB_ADDR0 + i * 4, addr);
|
||||
bfin_write32(ICPLB_DATA0 + i * 4, data);
|
||||
}
|
||||
ctrl = bfin_read_IMEM_CONTROL();
|
||||
ctrl |= IMC | ENICPLB;
|
||||
bfin_write_IMEM_CONTROL(ctrl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BLKFIN_DCACHE)
|
||||
void bfin_dcache_init(void)
|
||||
{
|
||||
unsigned long *table = dcplb_table;
|
||||
unsigned long ctrl;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_CPLBS; i++) {
|
||||
unsigned long addr = *table++;
|
||||
unsigned long data = *table++;
|
||||
if (addr == (unsigned long)-1)
|
||||
break;
|
||||
bfin_write32(DCPLB_ADDR0 + i * 4, addr);
|
||||
bfin_write32(DCPLB_DATA0 + i * 4, data);
|
||||
}
|
||||
ctrl = bfin_read_DMEM_CONTROL();
|
||||
ctrl |= DMEM_CNTR;
|
||||
bfin_write_DMEM_CONTROL(ctrl);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,433 @@
|
||||
/*
|
||||
* Blackfin CPLB initialization
|
||||
*
|
||||
* Copyright 2004-2007 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/cplbinit.h>
|
||||
|
||||
u_long icplb_table[MAX_CPLBS+1];
|
||||
u_long dcplb_table[MAX_CPLBS+1];
|
||||
|
||||
#ifdef CONFIG_CPLB_SWITCH_TAB_L1
|
||||
u_long ipdt_table[MAX_SWITCH_I_CPLBS+1]__attribute__((l1_data));
|
||||
u_long dpdt_table[MAX_SWITCH_D_CPLBS+1]__attribute__((l1_data));
|
||||
|
||||
#ifdef CONFIG_CPLB_INFO
|
||||
u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS]__attribute__((l1_data));
|
||||
u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS]__attribute__((l1_data));
|
||||
#endif /* CONFIG_CPLB_INFO */
|
||||
|
||||
#else
|
||||
|
||||
u_long ipdt_table[MAX_SWITCH_I_CPLBS+1];
|
||||
u_long dpdt_table[MAX_SWITCH_D_CPLBS+1];
|
||||
|
||||
#ifdef CONFIG_CPLB_INFO
|
||||
u_long ipdt_swapcount_table[MAX_SWITCH_I_CPLBS];
|
||||
u_long dpdt_swapcount_table[MAX_SWITCH_D_CPLBS];
|
||||
#endif /* CONFIG_CPLB_INFO */
|
||||
|
||||
#endif /*CONFIG_CPLB_SWITCH_TAB_L1*/
|
||||
|
||||
struct s_cplb {
|
||||
struct cplb_tab init_i;
|
||||
struct cplb_tab init_d;
|
||||
struct cplb_tab switch_i;
|
||||
struct cplb_tab switch_d;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE)
|
||||
static struct cplb_desc cplb_data[] = {
|
||||
{
|
||||
.start = 0,
|
||||
.end = SIZE_1K,
|
||||
.psize = SIZE_1K,
|
||||
.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
|
||||
.i_conf = SDRAM_OOPS,
|
||||
.d_conf = SDRAM_OOPS,
|
||||
#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO)
|
||||
.valid = 1,
|
||||
#else
|
||||
.valid = 0,
|
||||
#endif
|
||||
.name = "ZERO Pointer Saveguard",
|
||||
},
|
||||
{
|
||||
.start = L1_CODE_START,
|
||||
.end = L1_CODE_START + L1_CODE_LENGTH,
|
||||
.psize = SIZE_4M,
|
||||
.attr = INITIAL_T | SWITCH_T | I_CPLB,
|
||||
.i_conf = L1_IMEMORY,
|
||||
.d_conf = 0,
|
||||
.valid = 1,
|
||||
.name = "L1 I-Memory",
|
||||
},
|
||||
{
|
||||
.start = L1_DATA_A_START,
|
||||
.end = L1_DATA_B_START + L1_DATA_B_LENGTH,
|
||||
.psize = SIZE_4M,
|
||||
.attr = INITIAL_T | SWITCH_T | D_CPLB,
|
||||
.i_conf = 0,
|
||||
.d_conf = L1_DMEMORY,
|
||||
#if ((L1_DATA_A_LENGTH > 0) || (L1_DATA_B_LENGTH > 0))
|
||||
.valid = 1,
|
||||
#else
|
||||
.valid = 0,
|
||||
#endif
|
||||
.name = "L1 D-Memory",
|
||||
},
|
||||
{
|
||||
.start = 0,
|
||||
.end = 0, /* dynamic */
|
||||
.psize = 0,
|
||||
.attr = INITIAL_T | SWITCH_T | I_CPLB | D_CPLB,
|
||||
.i_conf = SDRAM_IGENERIC,
|
||||
.d_conf = SDRAM_DGENERIC,
|
||||
.valid = 1,
|
||||
.name = "SDRAM Kernel",
|
||||
},
|
||||
{
|
||||
.start = 0, /* dynamic */
|
||||
.end = 0, /* dynamic */
|
||||
.psize = 0,
|
||||
.attr = INITIAL_T | SWITCH_T | D_CPLB,
|
||||
.i_conf = SDRAM_IGENERIC,
|
||||
.d_conf = SDRAM_DNON_CHBL,
|
||||
.valid = 1,
|
||||
.name = "SDRAM RAM MTD",
|
||||
},
|
||||
{
|
||||
.start = 0, /* dynamic */
|
||||
.end = 0, /* dynamic */
|
||||
.psize = SIZE_1M,
|
||||
.attr = INITIAL_T | SWITCH_T | D_CPLB,
|
||||
.d_conf = SDRAM_DNON_CHBL,
|
||||
.valid = 1,
|
||||
.name = "SDRAM Uncached DMA ZONE",
|
||||
},
|
||||
{
|
||||
.start = 0, /* dynamic */
|
||||
.end = 0, /* dynamic */
|
||||
.psize = 0,
|
||||
.attr = SWITCH_T | D_CPLB,
|
||||
.i_conf = 0, /* dynamic */
|
||||
.d_conf = 0, /* dynamic */
|
||||
.valid = 1,
|
||||
.name = "SDRAM Reserved Memory",
|
||||
},
|
||||
{
|
||||
.start = ASYNC_BANK0_BASE,
|
||||
.end = ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE,
|
||||
.psize = 0,
|
||||
.attr = SWITCH_T | D_CPLB,
|
||||
.d_conf = SDRAM_EBIU,
|
||||
.valid = 1,
|
||||
.name = "ASYNC Memory",
|
||||
},
|
||||
{
|
||||
#if defined(CONFIG_BF561)
|
||||
.start = L2_SRAM,
|
||||
.end = L2_SRAM_END,
|
||||
.psize = SIZE_1M,
|
||||
.attr = SWITCH_T | D_CPLB,
|
||||
.i_conf = L2_MEMORY,
|
||||
.d_conf = L2_MEMORY,
|
||||
.valid = 1,
|
||||
#else
|
||||
.valid = 0,
|
||||
#endif
|
||||
.name = "L2 Memory",
|
||||
}
|
||||
};
|
||||
|
||||
static u16 __init lock_kernel_check(u32 start, u32 end)
|
||||
{
|
||||
if ((start <= (u32) _stext && end >= (u32) _end)
|
||||
|| (start >= (u32) _stext && end <= (u32) _end))
|
||||
return IN_KERNEL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned short __init
|
||||
fill_cplbtab(struct cplb_tab *table,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long block_size, unsigned long cplb_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
switch (block_size) {
|
||||
case SIZE_4M:
|
||||
i = 3;
|
||||
break;
|
||||
case SIZE_1M:
|
||||
i = 2;
|
||||
break;
|
||||
case SIZE_4K:
|
||||
i = 1;
|
||||
break;
|
||||
case SIZE_1K:
|
||||
default:
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
cplb_data = (cplb_data & ~(3 << 16)) | (i << 16);
|
||||
|
||||
while ((start < end) && (table->pos < table->size)) {
|
||||
|
||||
table->tab[table->pos++] = start;
|
||||
|
||||
if (lock_kernel_check(start, start + block_size) == IN_KERNEL)
|
||||
table->tab[table->pos++] =
|
||||
cplb_data | CPLB_LOCK | CPLB_DIRTY;
|
||||
else
|
||||
table->tab[table->pos++] = cplb_data;
|
||||
|
||||
start += block_size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned short __init
|
||||
close_cplbtab(struct cplb_tab *table)
|
||||
{
|
||||
|
||||
while (table->pos < table->size) {
|
||||
|
||||
table->tab[table->pos++] = 0;
|
||||
table->tab[table->pos++] = 0; /* !CPLB_VALID */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* helper function */
|
||||
static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
|
||||
{
|
||||
if (cplb_data[i].psize) {
|
||||
fill_cplbtab(t,
|
||||
cplb_data[i].start,
|
||||
cplb_data[i].end,
|
||||
cplb_data[i].psize,
|
||||
cplb_data[i].i_conf);
|
||||
} else {
|
||||
#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263))
|
||||
if (i == SDRAM_KERN) {
|
||||
fill_cplbtab(t,
|
||||
cplb_data[i].start,
|
||||
cplb_data[i].end,
|
||||
SIZE_4M,
|
||||
cplb_data[i].i_conf);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
fill_cplbtab(t,
|
||||
cplb_data[i].start,
|
||||
a_start,
|
||||
SIZE_1M,
|
||||
cplb_data[i].i_conf);
|
||||
fill_cplbtab(t,
|
||||
a_start,
|
||||
a_end,
|
||||
SIZE_4M,
|
||||
cplb_data[i].i_conf);
|
||||
fill_cplbtab(t, a_end,
|
||||
cplb_data[i].end,
|
||||
SIZE_1M,
|
||||
cplb_data[i].i_conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __fill_data_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_end)
|
||||
{
|
||||
if (cplb_data[i].psize) {
|
||||
fill_cplbtab(t,
|
||||
cplb_data[i].start,
|
||||
cplb_data[i].end,
|
||||
cplb_data[i].psize,
|
||||
cplb_data[i].d_conf);
|
||||
} else {
|
||||
fill_cplbtab(t,
|
||||
cplb_data[i].start,
|
||||
a_start, SIZE_1M,
|
||||
cplb_data[i].d_conf);
|
||||
fill_cplbtab(t, a_start,
|
||||
a_end, SIZE_4M,
|
||||
cplb_data[i].d_conf);
|
||||
fill_cplbtab(t, a_end,
|
||||
cplb_data[i].end,
|
||||
SIZE_1M,
|
||||
cplb_data[i].d_conf);
|
||||
}
|
||||
}
|
||||
|
||||
void __init generate_cpl_tables(void)
|
||||
{
|
||||
|
||||
u16 i, j, process;
|
||||
u32 a_start, a_end, as, ae, as_1m;
|
||||
|
||||
struct cplb_tab *t_i = NULL;
|
||||
struct cplb_tab *t_d = NULL;
|
||||
struct s_cplb cplb;
|
||||
|
||||
cplb.init_i.size = MAX_CPLBS;
|
||||
cplb.init_d.size = MAX_CPLBS;
|
||||
cplb.switch_i.size = MAX_SWITCH_I_CPLBS;
|
||||
cplb.switch_d.size = MAX_SWITCH_D_CPLBS;
|
||||
|
||||
cplb.init_i.pos = 0;
|
||||
cplb.init_d.pos = 0;
|
||||
cplb.switch_i.pos = 0;
|
||||
cplb.switch_d.pos = 0;
|
||||
|
||||
cplb.init_i.tab = icplb_table;
|
||||
cplb.init_d.tab = dcplb_table;
|
||||
cplb.switch_i.tab = ipdt_table;
|
||||
cplb.switch_d.tab = dpdt_table;
|
||||
|
||||
cplb_data[SDRAM_KERN].end = memory_end;
|
||||
|
||||
#ifdef CONFIG_MTD_UCLINUX
|
||||
cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start;
|
||||
cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size;
|
||||
cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0;
|
||||
# if defined(CONFIG_ROMFS_FS)
|
||||
cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB;
|
||||
|
||||
/*
|
||||
* The ROMFS_FS size is often not multiple of 1MB.
|
||||
* This can cause multiple CPLB sets covering the same memory area.
|
||||
* This will then cause multiple CPLB hit exceptions.
|
||||
* Workaround: We ensure a contiguous memory area by extending the kernel
|
||||
* memory section over the mtd section.
|
||||
* For ROMFS_FS memory must be covered with ICPLBs anyways.
|
||||
* So there is no difference between kernel and mtd memory setup.
|
||||
*/
|
||||
|
||||
cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;;
|
||||
cplb_data[SDRAM_RAM_MTD].valid = 0;
|
||||
|
||||
# endif
|
||||
#else
|
||||
cplb_data[SDRAM_RAM_MTD].valid = 0;
|
||||
#endif
|
||||
|
||||
cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION;
|
||||
cplb_data[SDRAM_DMAZ].end = _ramend;
|
||||
|
||||
cplb_data[RES_MEM].start = _ramend;
|
||||
cplb_data[RES_MEM].end = physical_mem_end;
|
||||
|
||||
if (reserved_mem_dcache_on)
|
||||
cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC;
|
||||
else
|
||||
cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL;
|
||||
|
||||
if (reserved_mem_icache_on)
|
||||
cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC;
|
||||
else
|
||||
cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL;
|
||||
|
||||
for (i = ZERO_P; i <= L2_MEM; i++) {
|
||||
if (!cplb_data[i].valid)
|
||||
continue;
|
||||
|
||||
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
|
||||
* rootfs size, there can be overlapping memory areas.
|
||||
*/
|
||||
|
||||
if (as_1m && i != L1I_MEM && i != L1D_MEM) {
|
||||
#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;
|
||||
else
|
||||
cplb_data[SDRAM_RAM_MTD].start = (cplb_data[i].start & (-2*SIZE_1M));
|
||||
} else
|
||||
#endif
|
||||
printk(KERN_WARNING "Unaligned Start of %s at 0x%X\n",
|
||||
cplb_data[i].name, cplb_data[i].start);
|
||||
}
|
||||
|
||||
as = cplb_data[i].start % SIZE_4M;
|
||||
ae = cplb_data[i].end % SIZE_4M;
|
||||
|
||||
if (as)
|
||||
a_start = cplb_data[i].start + (SIZE_4M - (as));
|
||||
else
|
||||
a_start = cplb_data[i].start;
|
||||
|
||||
a_end = cplb_data[i].end - ae;
|
||||
|
||||
for (j = INITIAL_T; j <= SWITCH_T; j++) {
|
||||
|
||||
switch (j) {
|
||||
case INITIAL_T:
|
||||
if (cplb_data[i].attr & INITIAL_T) {
|
||||
t_i = &cplb.init_i;
|
||||
t_d = &cplb.init_d;
|
||||
process = 1;
|
||||
} else
|
||||
process = 0;
|
||||
break;
|
||||
case SWITCH_T:
|
||||
if (cplb_data[i].attr & SWITCH_T) {
|
||||
t_i = &cplb.switch_i;
|
||||
t_d = &cplb.switch_d;
|
||||
process = 1;
|
||||
} else
|
||||
process = 0;
|
||||
break;
|
||||
default:
|
||||
process = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!process)
|
||||
continue;
|
||||
if (cplb_data[i].attr & I_CPLB)
|
||||
__fill_code_cplbtab(t_i, i, a_start, a_end);
|
||||
|
||||
if (cplb_data[i].attr & D_CPLB)
|
||||
__fill_data_cplbtab(t_d, i, a_start, a_end);
|
||||
}
|
||||
}
|
||||
|
||||
/* close tables */
|
||||
|
||||
close_cplbtab(&cplb.init_i);
|
||||
close_cplbtab(&cplb.init_d);
|
||||
|
||||
cplb.init_i.tab[cplb.init_i.pos] = -1;
|
||||
cplb.init_d.tab[cplb.init_d.pos] = -1;
|
||||
cplb.switch_i.tab[cplb.switch_i.pos] = -1;
|
||||
cplb.switch_d.tab[cplb.switch_d.pos] = -1;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/bfin-global.h>
|
||||
|
||||
static spinlock_t dma_page_lock;
|
||||
@@ -159,10 +159,13 @@ dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
|
||||
|
||||
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]));
|
||||
for (i = 0; i < nents; i++, sg++) {
|
||||
sg->dma_address = page_address(sg->page) + sg->offset;
|
||||
|
||||
invalidate_dcache_range(sg_dma_address(sg),
|
||||
sg_dma_address(sg) +
|
||||
sg_dma_len(sg));
|
||||
}
|
||||
|
||||
return nents;
|
||||
}
|
||||
|
||||
@@ -30,19 +30,19 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static int *testarg = (int*)0xfeb00000;
|
||||
static int *testarg = (int *)0xfeb00000;
|
||||
|
||||
static int test_init(void)
|
||||
{
|
||||
*testarg = 1;
|
||||
printk("Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
|
||||
printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n",
|
||||
*testarg, testarg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void test_exit(void)
|
||||
{
|
||||
printk("Dual core test module removed: testarg = [%d]\n", *testarg);
|
||||
printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg);
|
||||
}
|
||||
|
||||
module_init(test_init);
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* This file contains sequences of code that will be copied to a
|
||||
* fixed location, defined in <asm/atomic_seq.h>. The interrupt
|
||||
* handlers ensure that these sequences appear to be atomic when
|
||||
* executed from userspace.
|
||||
* These are aligned to 16 bytes, so that we have some space to replace
|
||||
* these sequences with something else (e.g. kernel traps if we ever do
|
||||
* BF561 SMP).
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <asm/entry.h>
|
||||
|
||||
.text
|
||||
ENTRY(_fixed_code_start)
|
||||
|
||||
.align 16
|
||||
ENTRY(_sigreturn_stub)
|
||||
P0 = __NR_rt_sigreturn;
|
||||
EXCPT 0;
|
||||
/* Speculative execution paranoia. */
|
||||
0: JUMP.S 0b;
|
||||
ENDPROC (_sigreturn_stub)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Atomic swap, 8 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R1: value to store
|
||||
* Output: R0: old contents of the memory address, zero extended.
|
||||
*/
|
||||
ENTRY(_atomic_xchg32)
|
||||
R0 = [P0];
|
||||
[P0] = R1;
|
||||
rts;
|
||||
ENDPROC (_atomic_xchg32)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Compare and swap, 32 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R1: compare value
|
||||
* R2: new value to store
|
||||
* The new value is stored if the contents of the memory
|
||||
* address is equal to the compare value.
|
||||
* Output: R0: old contents of the memory address.
|
||||
*/
|
||||
ENTRY(_atomic_cas32)
|
||||
R0 = [P0];
|
||||
CC = R0 == R1;
|
||||
IF !CC JUMP 1f;
|
||||
[P0] = R2;
|
||||
1:
|
||||
rts;
|
||||
ENDPROC (_atomic_cas32)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Atomic add, 32 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R0: value to add
|
||||
* Outputs: R0: new contents of the memory address.
|
||||
* R1: previous contents of the memory address.
|
||||
*/
|
||||
ENTRY(_atomic_add32)
|
||||
R1 = [P0];
|
||||
R0 = R1 + R0;
|
||||
[P0] = R0;
|
||||
rts;
|
||||
ENDPROC (_atomic_add32)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Atomic sub, 32 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R0: value to subtract
|
||||
* Outputs: R0: new contents of the memory address.
|
||||
* R1: previous contents of the memory address.
|
||||
*/
|
||||
ENTRY(_atomic_sub32)
|
||||
R1 = [P0];
|
||||
R0 = R1 - R0;
|
||||
[P0] = R0;
|
||||
rts;
|
||||
ENDPROC (_atomic_sub32)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Atomic ior, 32 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R0: value to ior
|
||||
* Outputs: R0: new contents of the memory address.
|
||||
* R1: previous contents of the memory address.
|
||||
*/
|
||||
ENTRY(_atomic_ior32)
|
||||
R1 = [P0];
|
||||
R0 = R1 | R0;
|
||||
[P0] = R0;
|
||||
rts;
|
||||
ENDPROC (_atomic_ior32)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Atomic ior, 32 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R0: value to ior
|
||||
* Outputs: R0: new contents of the memory address.
|
||||
* R1: previous contents of the memory address.
|
||||
*/
|
||||
ENTRY(_atomic_and32)
|
||||
R1 = [P0];
|
||||
R0 = R1 & R0;
|
||||
[P0] = R0;
|
||||
rts;
|
||||
ENDPROC (_atomic_ior32)
|
||||
|
||||
.align 16
|
||||
/*
|
||||
* Atomic ior, 32 bit.
|
||||
* Inputs: P0: memory address to use
|
||||
* R0: value to ior
|
||||
* Outputs: R0: new contents of the memory address.
|
||||
* R1: previous contents of the memory address.
|
||||
*/
|
||||
ENTRY(_atomic_xor32)
|
||||
R1 = [P0];
|
||||
R0 = R1 ^ R0;
|
||||
[P0] = R0;
|
||||
rts;
|
||||
ENDPROC (_atomic_ior32)
|
||||
|
||||
ENTRY(_fixed_code_end)
|
||||
+26
-29
@@ -36,24 +36,22 @@ unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
|
||||
unsigned long val;
|
||||
|
||||
switch (type) {
|
||||
case FLAT_BFIN_RELOC_TYPE_16_BIT:
|
||||
case FLAT_BFIN_RELOC_TYPE_16H_BIT:
|
||||
usptr = (unsigned short *)ptr;
|
||||
pr_debug("*usptr = %x", get_unaligned(usptr));
|
||||
val = get_unaligned(usptr);
|
||||
val += *persistent;
|
||||
break;
|
||||
case FLAT_BFIN_RELOC_TYPE_16_BIT:
|
||||
case FLAT_BFIN_RELOC_TYPE_16H_BIT:
|
||||
usptr = (unsigned short *)ptr;
|
||||
pr_debug("*usptr = %x", get_unaligned(usptr));
|
||||
val = get_unaligned(usptr);
|
||||
val += *persistent;
|
||||
break;
|
||||
|
||||
case FLAT_BFIN_RELOC_TYPE_32_BIT:
|
||||
pr_debug("*ptr = %lx", get_unaligned(ptr));
|
||||
val = get_unaligned(ptr);
|
||||
break;
|
||||
case FLAT_BFIN_RELOC_TYPE_32_BIT:
|
||||
pr_debug("*ptr = %lx", get_unaligned(ptr));
|
||||
val = get_unaligned(ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_debug("BINFMT_FLAT: Unknown relocation type %x\n",
|
||||
type);
|
||||
|
||||
return 0;
|
||||
default:
|
||||
pr_debug("BINFMT_FLAT: Unknown relocation type %x\n", type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,21 +79,20 @@ void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
|
||||
int type = (relval >> 26) & 7;
|
||||
|
||||
switch (type) {
|
||||
case FLAT_BFIN_RELOC_TYPE_16_BIT:
|
||||
put_unaligned(addr, usptr);
|
||||
pr_debug("new value %x at %p", get_unaligned(usptr),
|
||||
usptr);
|
||||
break;
|
||||
case FLAT_BFIN_RELOC_TYPE_16_BIT:
|
||||
put_unaligned(addr, usptr);
|
||||
pr_debug("new value %x at %p", get_unaligned(usptr), usptr);
|
||||
break;
|
||||
|
||||
case FLAT_BFIN_RELOC_TYPE_16H_BIT:
|
||||
put_unaligned(addr >> 16, usptr);
|
||||
pr_debug("new value %x", get_unaligned(usptr));
|
||||
break;
|
||||
case FLAT_BFIN_RELOC_TYPE_16H_BIT:
|
||||
put_unaligned(addr >> 16, usptr);
|
||||
pr_debug("new value %x", get_unaligned(usptr));
|
||||
break;
|
||||
|
||||
case FLAT_BFIN_RELOC_TYPE_32_BIT:
|
||||
put_unaligned(addr, ptr);
|
||||
pr_debug("new ptr =%lx", get_unaligned(ptr));
|
||||
break;
|
||||
case FLAT_BFIN_RELOC_TYPE_32_BIT:
|
||||
put_unaligned(addr, ptr);
|
||||
pr_debug("new ptr =%lx", get_unaligned(ptr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(bfin_put_addr_at_rp);
|
||||
|
||||
@@ -82,7 +82,7 @@ int show_interrupts(struct seq_file *p, void *v)
|
||||
seq_printf(p, ", %s", action->name);
|
||||
|
||||
seq_putc(p, '\n');
|
||||
unlock:
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&irq_desc[i].lock, flags);
|
||||
} else if (i == NR_IRQS) {
|
||||
seq_printf(p, "Err: %10lu\n", irq_err_count);
|
||||
|
||||
@@ -0,0 +1,421 @@
|
||||
/*
|
||||
* File: arch/blackfin/kernel/kgdb.c
|
||||
* Based on:
|
||||
* Author: Sonic Zhang
|
||||
*
|
||||
* Created:
|
||||
* Description:
|
||||
*
|
||||
* Rev: $Id: kgdb_bfin_linux-2.6.x.patch 4934 2007-02-13 09:32:11Z sonicz $
|
||||
*
|
||||
* Modified:
|
||||
* Copyright 2005-2006 Analog Devices Inc.
|
||||
*
|
||||
* Bugs: Enter bugs at http://blackfin.uclinux.org/
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see the file COPYING, or write
|
||||
* to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ptrace.h> /* for linux pt_regs struct */
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/debugger.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/irq.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/blackfin.h>
|
||||
|
||||
/* Put the error code here just in case the user cares. */
|
||||
int gdb_bf533errcode;
|
||||
/* Likewise, the vector number here (since GDB only gets the signal
|
||||
number through the usual means, and that's not very specific). */
|
||||
int gdb_bf533vector = -1;
|
||||
|
||||
#if KGDB_MAX_NO_CPUS != 8
|
||||
#error change the definition of slavecpulocks
|
||||
#endif
|
||||
|
||||
void regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
|
||||
{
|
||||
gdb_regs[BFIN_R0] = regs->r0;
|
||||
gdb_regs[BFIN_R1] = regs->r1;
|
||||
gdb_regs[BFIN_R2] = regs->r2;
|
||||
gdb_regs[BFIN_R3] = regs->r3;
|
||||
gdb_regs[BFIN_R4] = regs->r4;
|
||||
gdb_regs[BFIN_R5] = regs->r5;
|
||||
gdb_regs[BFIN_R6] = regs->r6;
|
||||
gdb_regs[BFIN_R7] = regs->r7;
|
||||
gdb_regs[BFIN_P0] = regs->p0;
|
||||
gdb_regs[BFIN_P1] = regs->p1;
|
||||
gdb_regs[BFIN_P2] = regs->p2;
|
||||
gdb_regs[BFIN_P3] = regs->p3;
|
||||
gdb_regs[BFIN_P4] = regs->p4;
|
||||
gdb_regs[BFIN_P5] = regs->p5;
|
||||
gdb_regs[BFIN_SP] = regs->reserved;
|
||||
gdb_regs[BFIN_FP] = regs->fp;
|
||||
gdb_regs[BFIN_I0] = regs->i0;
|
||||
gdb_regs[BFIN_I1] = regs->i1;
|
||||
gdb_regs[BFIN_I2] = regs->i2;
|
||||
gdb_regs[BFIN_I3] = regs->i3;
|
||||
gdb_regs[BFIN_M0] = regs->m0;
|
||||
gdb_regs[BFIN_M1] = regs->m1;
|
||||
gdb_regs[BFIN_M2] = regs->m2;
|
||||
gdb_regs[BFIN_M3] = regs->m3;
|
||||
gdb_regs[BFIN_B0] = regs->b0;
|
||||
gdb_regs[BFIN_B1] = regs->b1;
|
||||
gdb_regs[BFIN_B2] = regs->b2;
|
||||
gdb_regs[BFIN_B3] = regs->b3;
|
||||
gdb_regs[BFIN_L0] = regs->l0;
|
||||
gdb_regs[BFIN_L1] = regs->l1;
|
||||
gdb_regs[BFIN_L2] = regs->l2;
|
||||
gdb_regs[BFIN_L3] = regs->l3;
|
||||
gdb_regs[BFIN_A0_DOT_X] = regs->a0x;
|
||||
gdb_regs[BFIN_A0_DOT_W] = regs->a0w;
|
||||
gdb_regs[BFIN_A1_DOT_X] = regs->a1x;
|
||||
gdb_regs[BFIN_A1_DOT_W] = regs->a1w;
|
||||
gdb_regs[BFIN_ASTAT] = regs->astat;
|
||||
gdb_regs[BFIN_RETS] = regs->rets;
|
||||
gdb_regs[BFIN_LC0] = regs->lc0;
|
||||
gdb_regs[BFIN_LT0] = regs->lt0;
|
||||
gdb_regs[BFIN_LB0] = regs->lb0;
|
||||
gdb_regs[BFIN_LC1] = regs->lc1;
|
||||
gdb_regs[BFIN_LT1] = regs->lt1;
|
||||
gdb_regs[BFIN_LB1] = regs->lb1;
|
||||
gdb_regs[BFIN_CYCLES] = 0;
|
||||
gdb_regs[BFIN_CYCLES2] = 0;
|
||||
gdb_regs[BFIN_USP] = regs->usp;
|
||||
gdb_regs[BFIN_SEQSTAT] = regs->seqstat;
|
||||
gdb_regs[BFIN_SYSCFG] = regs->syscfg;
|
||||
gdb_regs[BFIN_RETI] = regs->pc;
|
||||
gdb_regs[BFIN_RETX] = regs->retx;
|
||||
gdb_regs[BFIN_RETN] = regs->retn;
|
||||
gdb_regs[BFIN_RETE] = regs->rete;
|
||||
gdb_regs[BFIN_PC] = regs->pc;
|
||||
gdb_regs[BFIN_CC] = 0;
|
||||
gdb_regs[BFIN_EXTRA1] = 0;
|
||||
gdb_regs[BFIN_EXTRA2] = 0;
|
||||
gdb_regs[BFIN_EXTRA3] = 0;
|
||||
gdb_regs[BFIN_IPEND] = regs->ipend;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extracts ebp, esp and eip values understandable by gdb from the values
|
||||
* saved by switch_to.
|
||||
* thread.esp points to ebp. flags and ebp are pushed in switch_to hence esp
|
||||
* prior to entering switch_to is 8 greater then the value that is saved.
|
||||
* If switch_to changes, change following code appropriately.
|
||||
*/
|
||||
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
{
|
||||
gdb_regs[BFIN_SP] = p->thread.ksp;
|
||||
gdb_regs[BFIN_PC] = p->thread.pc;
|
||||
gdb_regs[BFIN_SEQSTAT] = p->thread.seqstat;
|
||||
}
|
||||
|
||||
void gdb_regs_to_regs(unsigned long *gdb_regs, struct pt_regs *regs)
|
||||
{
|
||||
regs->r0 = gdb_regs[BFIN_R0];
|
||||
regs->r1 = gdb_regs[BFIN_R1];
|
||||
regs->r2 = gdb_regs[BFIN_R2];
|
||||
regs->r3 = gdb_regs[BFIN_R3];
|
||||
regs->r4 = gdb_regs[BFIN_R4];
|
||||
regs->r5 = gdb_regs[BFIN_R5];
|
||||
regs->r6 = gdb_regs[BFIN_R6];
|
||||
regs->r7 = gdb_regs[BFIN_R7];
|
||||
regs->p0 = gdb_regs[BFIN_P0];
|
||||
regs->p1 = gdb_regs[BFIN_P1];
|
||||
regs->p2 = gdb_regs[BFIN_P2];
|
||||
regs->p3 = gdb_regs[BFIN_P3];
|
||||
regs->p4 = gdb_regs[BFIN_P4];
|
||||
regs->p5 = gdb_regs[BFIN_P5];
|
||||
regs->fp = gdb_regs[BFIN_FP];
|
||||
regs->i0 = gdb_regs[BFIN_I0];
|
||||
regs->i1 = gdb_regs[BFIN_I1];
|
||||
regs->i2 = gdb_regs[BFIN_I2];
|
||||
regs->i3 = gdb_regs[BFIN_I3];
|
||||
regs->m0 = gdb_regs[BFIN_M0];
|
||||
regs->m1 = gdb_regs[BFIN_M1];
|
||||
regs->m2 = gdb_regs[BFIN_M2];
|
||||
regs->m3 = gdb_regs[BFIN_M3];
|
||||
regs->b0 = gdb_regs[BFIN_B0];
|
||||
regs->b1 = gdb_regs[BFIN_B1];
|
||||
regs->b2 = gdb_regs[BFIN_B2];
|
||||
regs->b3 = gdb_regs[BFIN_B3];
|
||||
regs->l0 = gdb_regs[BFIN_L0];
|
||||
regs->l1 = gdb_regs[BFIN_L1];
|
||||
regs->l2 = gdb_regs[BFIN_L2];
|
||||
regs->l3 = gdb_regs[BFIN_L3];
|
||||
regs->a0x = gdb_regs[BFIN_A0_DOT_X];
|
||||
regs->a0w = gdb_regs[BFIN_A0_DOT_W];
|
||||
regs->a1x = gdb_regs[BFIN_A1_DOT_X];
|
||||
regs->a1w = gdb_regs[BFIN_A1_DOT_W];
|
||||
regs->rets = gdb_regs[BFIN_RETS];
|
||||
regs->lc0 = gdb_regs[BFIN_LC0];
|
||||
regs->lt0 = gdb_regs[BFIN_LT0];
|
||||
regs->lb0 = gdb_regs[BFIN_LB0];
|
||||
regs->lc1 = gdb_regs[BFIN_LC1];
|
||||
regs->lt1 = gdb_regs[BFIN_LT1];
|
||||
regs->lb1 = gdb_regs[BFIN_LB1];
|
||||
regs->usp = gdb_regs[BFIN_USP];
|
||||
regs->syscfg = gdb_regs[BFIN_SYSCFG];
|
||||
regs->retx = gdb_regs[BFIN_PC];
|
||||
regs->retn = gdb_regs[BFIN_RETN];
|
||||
regs->rete = gdb_regs[BFIN_RETE];
|
||||
regs->pc = gdb_regs[BFIN_PC];
|
||||
|
||||
#if 0 /* can't change these */
|
||||
regs->astat = gdb_regs[BFIN_ASTAT];
|
||||
regs->seqstat = gdb_regs[BFIN_SEQSTAT];
|
||||
regs->ipend = gdb_regs[BFIN_IPEND];
|
||||
#endif
|
||||
}
|
||||
|
||||
struct hw_breakpoint {
|
||||
unsigned int occupied:1;
|
||||
unsigned int skip:1;
|
||||
unsigned int enabled:1;
|
||||
unsigned int type:1;
|
||||
unsigned int dataacc:2;
|
||||
unsigned short count;
|
||||
unsigned int addr;
|
||||
} breakinfo[HW_BREAKPOINT_NUM];
|
||||
|
||||
int kgdb_arch_init(void)
|
||||
{
|
||||
kgdb_remove_all_hw_break();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgdb_set_hw_break(unsigned long addr)
|
||||
{
|
||||
int breakno;
|
||||
for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
|
||||
if (!breakinfo[breakno].occupied) {
|
||||
breakinfo[breakno].occupied = 1;
|
||||
breakinfo[breakno].enabled = 1;
|
||||
breakinfo[breakno].type = 1;
|
||||
breakinfo[breakno].addr = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
int kgdb_remove_hw_break(unsigned long addr)
|
||||
{
|
||||
int breakno;
|
||||
for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++)
|
||||
if (breakinfo[breakno].addr == addr)
|
||||
memset(&(breakinfo[breakno]), 0, sizeof(struct hw_breakpoint));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kgdb_remove_all_hw_break(void)
|
||||
{
|
||||
memset(breakinfo, 0, sizeof(struct hw_breakpoint)*8);
|
||||
}
|
||||
|
||||
/*
|
||||
void kgdb_show_info(void)
|
||||
{
|
||||
printk(KERN_DEBUG "hwd: wpia0=0x%x, wpiacnt0=%d, wpiactl=0x%x, wpstat=0x%x\n",
|
||||
bfin_read_WPIA0(), bfin_read_WPIACNT0(),
|
||||
bfin_read_WPIACTL(), bfin_read_WPSTAT());
|
||||
}
|
||||
*/
|
||||
|
||||
void kgdb_correct_hw_break(void)
|
||||
{
|
||||
int breakno;
|
||||
int correctit;
|
||||
uint32_t wpdactl = bfin_read_WPDACTL();
|
||||
|
||||
correctit = 0;
|
||||
for (breakno = 0; breakno < HW_BREAKPOINT_NUM; breakno++) {
|
||||
if (breakinfo[breakno].type == 1) {
|
||||
switch (breakno) {
|
||||
case 0:
|
||||
if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN0)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~(WPIREN01|EMUSW0);
|
||||
wpdactl |= WPIAEN0|WPICNTEN0;
|
||||
bfin_write_WPIA0(breakinfo[breakno].addr);
|
||||
bfin_write_WPIACNT0(breakinfo[breakno].skip);
|
||||
} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN0)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~WPIAEN0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN1)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~(WPIREN01|EMUSW1);
|
||||
wpdactl |= WPIAEN1|WPICNTEN1;
|
||||
bfin_write_WPIA1(breakinfo[breakno].addr);
|
||||
bfin_write_WPIACNT1(breakinfo[breakno].skip);
|
||||
} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN1)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~WPIAEN1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN2)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~(WPIREN23|EMUSW2);
|
||||
wpdactl |= WPIAEN2|WPICNTEN2;
|
||||
bfin_write_WPIA2(breakinfo[breakno].addr);
|
||||
bfin_write_WPIACNT2(breakinfo[breakno].skip);
|
||||
} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN2)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~WPIAEN2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN3)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~(WPIREN23|EMUSW3);
|
||||
wpdactl |= WPIAEN3|WPICNTEN3;
|
||||
bfin_write_WPIA3(breakinfo[breakno].addr);
|
||||
bfin_write_WPIACNT3(breakinfo[breakno].skip);
|
||||
} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN3)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~WPIAEN3;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN4)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~(WPIREN45|EMUSW4);
|
||||
wpdactl |= WPIAEN4|WPICNTEN4;
|
||||
bfin_write_WPIA4(breakinfo[breakno].addr);
|
||||
bfin_write_WPIACNT4(breakinfo[breakno].skip);
|
||||
} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN4)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~WPIAEN4;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (breakinfo[breakno].enabled && !(wpdactl & WPIAEN5)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~(WPIREN45|EMUSW5);
|
||||
wpdactl |= WPIAEN5|WPICNTEN5;
|
||||
bfin_write_WPIA5(breakinfo[breakno].addr);
|
||||
bfin_write_WPIACNT5(breakinfo[breakno].skip);
|
||||
} else if (!breakinfo[breakno].enabled && (wpdactl & WPIAEN5)) {
|
||||
correctit = 1;
|
||||
wpdactl &= ~WPIAEN5;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (correctit) {
|
||||
wpdactl &= ~WPAND;
|
||||
wpdactl |= WPPWR;
|
||||
/*printk("correct_hw_break: wpdactl=0x%x\n", wpdactl);*/
|
||||
bfin_write_WPDACTL(wpdactl);
|
||||
CSYNC();
|
||||
/*kgdb_show_info();*/
|
||||
}
|
||||
}
|
||||
|
||||
void kgdb_disable_hw_debug(struct pt_regs *regs)
|
||||
{
|
||||
/* Disable hardware debugging while we are in kgdb */
|
||||
bfin_write_WPIACTL(bfin_read_WPIACTL() & ~0x1);
|
||||
CSYNC();
|
||||
}
|
||||
|
||||
void kgdb_post_master_code(struct pt_regs *regs, int eVector, int err_code)
|
||||
{
|
||||
/* Master processor is completely in the debugger */
|
||||
gdb_bf533vector = eVector;
|
||||
gdb_bf533errcode = err_code;
|
||||
}
|
||||
|
||||
int kgdb_arch_handle_exception(int exceptionVector, int signo,
|
||||
int err_code, char *remcom_in_buffer,
|
||||
char *remcom_out_buffer,
|
||||
struct pt_regs *linux_regs)
|
||||
{
|
||||
long addr;
|
||||
long breakno;
|
||||
char *ptr;
|
||||
int newPC;
|
||||
int wp_status;
|
||||
|
||||
switch (remcom_in_buffer[0]) {
|
||||
case 'c':
|
||||
case 's':
|
||||
if (kgdb_contthread && kgdb_contthread != current) {
|
||||
strcpy(remcom_out_buffer, "E00");
|
||||
break;
|
||||
}
|
||||
|
||||
kgdb_contthread = NULL;
|
||||
|
||||
/* try to read optional parameter, pc unchanged if no parm */
|
||||
ptr = &remcom_in_buffer[1];
|
||||
if (kgdb_hex2long(&ptr, &addr)) {
|
||||
linux_regs->retx = addr;
|
||||
}
|
||||
newPC = linux_regs->retx;
|
||||
|
||||
/* clear the trace bit */
|
||||
linux_regs->syscfg &= 0xfffffffe;
|
||||
|
||||
/* set the trace bit if we're stepping */
|
||||
if (remcom_in_buffer[0] == 's') {
|
||||
linux_regs->syscfg |= 0x1;
|
||||
debugger_step = 1;
|
||||
}
|
||||
|
||||
wp_status = bfin_read_WPSTAT();
|
||||
CSYNC();
|
||||
|
||||
if (exceptionVector == VEC_WATCH) {
|
||||
for (breakno = 0; breakno < 6; ++breakno) {
|
||||
if (wp_status & (1 << breakno)) {
|
||||
breakinfo->skip = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
kgdb_correct_hw_break();
|
||||
|
||||
bfin_write_WPSTAT(0);
|
||||
|
||||
return 0;
|
||||
} /* switch */
|
||||
return -1; /* this means that we do not want to exit from the handler */
|
||||
}
|
||||
|
||||
struct kgdb_arch arch_kgdb_ops = {
|
||||
.gdb_bpt_instr = {0xa1},
|
||||
.flags = KGDB_HW_BREAKPOINT,
|
||||
};
|
||||
@@ -165,8 +165,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
||||
|
||||
for (s = sechdrs; s < sechdrs_end; ++s) {
|
||||
if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) ||
|
||||
((strcmp(".text", secstrings + s->sh_name)==0) &&
|
||||
(hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
|
||||
((strcmp(".text", secstrings + s->sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) {
|
||||
mod->arch.text_l1 = s;
|
||||
dest = l1_inst_sram_alloc(s->sh_size);
|
||||
if (dest == NULL) {
|
||||
@@ -179,9 +179,9 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
||||
s->sh_flags &= ~SHF_ALLOC;
|
||||
s->sh_addr = (unsigned long)dest;
|
||||
}
|
||||
if ((strcmp(".l1.data", secstrings + s->sh_name) == 0)||
|
||||
((strcmp(".data", secstrings + s->sh_name)==0) &&
|
||||
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
|
||||
if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) ||
|
||||
((strcmp(".data", secstrings + s->sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
|
||||
mod->arch.data_a_l1 = s;
|
||||
dest = l1_data_sram_alloc(s->sh_size);
|
||||
if (dest == NULL) {
|
||||
@@ -195,8 +195,8 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs,
|
||||
s->sh_addr = (unsigned long)dest;
|
||||
}
|
||||
if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 ||
|
||||
((strcmp(".bss", secstrings + s->sh_name)==0) &&
|
||||
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
|
||||
((strcmp(".bss", secstrings + s->sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) {
|
||||
mod->arch.bss_a_l1 = s;
|
||||
dest = l1_data_sram_alloc(s->sh_size);
|
||||
if (dest == NULL) {
|
||||
@@ -326,7 +326,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
|
||||
pr_debug("before %x after %x\n", *location16,
|
||||
(value & 0xffff));
|
||||
tmp = (value & 0xffff);
|
||||
if((unsigned long)location16 >= L1_CODE_START) {
|
||||
if ((unsigned long)location16 >= L1_CODE_START) {
|
||||
dma_memcpy(location16, &tmp, 2);
|
||||
} else
|
||||
*location16 = tmp;
|
||||
@@ -335,7 +335,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab,
|
||||
pr_debug("before %x after %x\n", *location16,
|
||||
((value >> 16) & 0xffff));
|
||||
tmp = ((value >> 16) & 0xffff);
|
||||
if((unsigned long)location16 >= L1_CODE_START) {
|
||||
if ((unsigned long)location16 >= L1_CODE_START) {
|
||||
dma_memcpy(location16, &tmp, 2);
|
||||
} else
|
||||
*location16 = tmp;
|
||||
@@ -404,8 +404,8 @@ module_finalize(const Elf_Ehdr * hdr,
|
||||
continue;
|
||||
|
||||
if ((sechdrs[i].sh_type == SHT_RELA) &&
|
||||
((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0)||
|
||||
((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
|
||||
((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) ||
|
||||
((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) &&
|
||||
(hdr->e_flags & FLG_CODE_IN_L1)))) {
|
||||
apply_relocate_add((Elf_Shdr *) sechdrs, strtab,
|
||||
symindex, i, mod);
|
||||
@@ -417,13 +417,13 @@ module_finalize(const Elf_Ehdr * hdr,
|
||||
void module_arch_cleanup(struct module *mod)
|
||||
{
|
||||
if ((mod->arch.text_l1) && (mod->arch.text_l1->sh_addr))
|
||||
l1_inst_sram_free((void*)mod->arch.text_l1->sh_addr);
|
||||
l1_inst_sram_free((void *)mod->arch.text_l1->sh_addr);
|
||||
if ((mod->arch.data_a_l1) && (mod->arch.data_a_l1->sh_addr))
|
||||
l1_data_sram_free((void*)mod->arch.data_a_l1->sh_addr);
|
||||
l1_data_sram_free((void *)mod->arch.data_a_l1->sh_addr);
|
||||
if ((mod->arch.bss_a_l1) && (mod->arch.bss_a_l1->sh_addr))
|
||||
l1_data_sram_free((void*)mod->arch.bss_a_l1->sh_addr);
|
||||
l1_data_sram_free((void *)mod->arch.bss_a_l1->sh_addr);
|
||||
if ((mod->arch.data_b_l1) && (mod->arch.data_b_l1->sh_addr))
|
||||
l1_data_B_sram_free((void*)mod->arch.data_b_l1->sh_addr);
|
||||
l1_data_B_sram_free((void *)mod->arch.data_b_l1->sh_addr);
|
||||
if ((mod->arch.bss_b_l1) && (mod->arch.bss_b_l1->sh_addr))
|
||||
l1_data_B_sram_free((void*)mod->arch.bss_b_l1->sh_addr);
|
||||
l1_data_B_sram_free((void *)mod->arch.bss_b_l1->sh_addr);
|
||||
}
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/a.out.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/blackfin.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/fixed_code.h>
|
||||
|
||||
#define LED_ON 0
|
||||
#define LED_OFF 1
|
||||
@@ -173,8 +174,8 @@ void show_regs(struct pt_regs *regs)
|
||||
printk(KERN_NOTICE "R4: %08lx R5: %08lx R6: %08lx R7: %08lx\n",
|
||||
regs->r4, regs->r5, regs->r6, regs->r7);
|
||||
|
||||
if (!(regs->ipend))
|
||||
printk("USP: %08lx\n", rdusp());
|
||||
if (!regs->ipend)
|
||||
printk(KERN_NOTICE "USP: %08lx\n", rdusp());
|
||||
}
|
||||
|
||||
/* Fill in the fpu structure for a core dump. */
|
||||
@@ -322,7 +323,7 @@ asmlinkage int sys_execve(char *name, char **argv, char **envp)
|
||||
goto out;
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
out:
|
||||
unlock_kernel();
|
||||
return error;
|
||||
}
|
||||
@@ -350,13 +351,77 @@ unsigned long get_wchan(struct task_struct *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void finish_atomic_sections (struct pt_regs *regs)
|
||||
{
|
||||
if (regs->pc < ATOMIC_SEQS_START || regs->pc >= ATOMIC_SEQS_END)
|
||||
return;
|
||||
|
||||
switch (regs->pc) {
|
||||
case ATOMIC_XCHG32 + 2:
|
||||
put_user(regs->r1, (int *)regs->p0);
|
||||
regs->pc += 2;
|
||||
break;
|
||||
|
||||
case ATOMIC_CAS32 + 2:
|
||||
case ATOMIC_CAS32 + 4:
|
||||
if (regs->r0 == regs->r1)
|
||||
put_user(regs->r2, (int *)regs->p0);
|
||||
regs->pc = ATOMIC_CAS32 + 8;
|
||||
break;
|
||||
case ATOMIC_CAS32 + 6:
|
||||
put_user(regs->r2, (int *)regs->p0);
|
||||
regs->pc += 2;
|
||||
break;
|
||||
|
||||
case ATOMIC_ADD32 + 2:
|
||||
regs->r0 = regs->r1 + regs->r0;
|
||||
/* fall through */
|
||||
case ATOMIC_ADD32 + 4:
|
||||
put_user(regs->r0, (int *)regs->p0);
|
||||
regs->pc = ATOMIC_ADD32 + 6;
|
||||
break;
|
||||
|
||||
case ATOMIC_SUB32 + 2:
|
||||
regs->r0 = regs->r1 - regs->r0;
|
||||
/* fall through */
|
||||
case ATOMIC_SUB32 + 4:
|
||||
put_user(regs->r0, (int *)regs->p0);
|
||||
regs->pc = ATOMIC_SUB32 + 6;
|
||||
break;
|
||||
|
||||
case ATOMIC_IOR32 + 2:
|
||||
regs->r0 = regs->r1 | regs->r0;
|
||||
/* fall through */
|
||||
case ATOMIC_IOR32 + 4:
|
||||
put_user(regs->r0, (int *)regs->p0);
|
||||
regs->pc = ATOMIC_IOR32 + 6;
|
||||
break;
|
||||
|
||||
case ATOMIC_AND32 + 2:
|
||||
regs->r0 = regs->r1 & regs->r0;
|
||||
/* fall through */
|
||||
case ATOMIC_AND32 + 4:
|
||||
put_user(regs->r0, (int *)regs->p0);
|
||||
regs->pc = ATOMIC_AND32 + 6;
|
||||
break;
|
||||
|
||||
case ATOMIC_XOR32 + 2:
|
||||
regs->r0 = regs->r1 ^ regs->r0;
|
||||
/* fall through */
|
||||
case ATOMIC_XOR32 + 4:
|
||||
put_user(regs->r0, (int *)regs->p0);
|
||||
regs->pc = ATOMIC_XOR32 + 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ACCESS_CHECK)
|
||||
int _access_ok(unsigned long addr, unsigned long size)
|
||||
{
|
||||
|
||||
if (addr > (addr + size))
|
||||
return 0;
|
||||
if (segment_eq(get_fs(),KERNEL_DS))
|
||||
if (segment_eq(get_fs(), KERNEL_DS))
|
||||
return 1;
|
||||
#ifdef CONFIG_MTD_UCLINUX
|
||||
if (addr >= memory_start && (addr + size) <= memory_end)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user