diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 16:23:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 16:23:17 -0400 |
commit | 7f268a2ba7c884a239713696238dd4207a57dd9a (patch) | |
tree | fdc02fecda32f5df8de3ddc2c01c29ba68e6a42b /arch/blackfin/kernel | |
parent | 689796a141cea79d745a4689c65dd01c39e5e100 (diff) | |
parent | 2d2009806dd843f3adc0cbbb5d2204980f28111a (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/blackfin-2.6: (30 commits)
Blackfin arch: If we double fault, rather than hang forever, reset
Blackfin arch: When icache is off, make sure people know it
Blackfin arch: Fix bug - skip single step in high priority interrupt handler instead of disabling all interrupts in single step debugging.
Blackfin arch: cache the values of vco/sclk/cclk as the overhead of doing so (~24 bytes) is worth avoiding the software mult/div routines
Blackfin arch: fix bug - IMDMA is not type struct dma_register
Blackfin arch: check the EXTBANKS field of the DDRCTL1 register to see if we are using both memory banks
Blackfin arch: Apply Bluetechnix CM-BF527 board support patch
Blackfin arch: Add unwinding for stack info, and a little more detail on trace buffer
Blackfin arch: Add ISP1760 board resources to BF548-EZKIT
Blackfin arch: fix bug - detect 0.1 silicon revision BF527-EZKIT as 0.0 version
Blackfin arch: add missing IORESOURCE_MEM flags to UART3
Blackfin arch: Add return value check in bfin_sir_probe(), remove SSYNC().
Blackfin arch: Extend sram malloc to handle L2 SRAM.
Blackfin arch: Remove useless config option.
Blackfin arch: change L1 malloc to base on slab cache and lists.
Blackfin arch: use local labels and ENDPROC() markings
Blackfin arch: Do not need this dualcore test module in kernel.
Blackfin arch: Allow ptrace to peek and poke application data in L1 data SRAM.
Blackfin arch: Add ANOMALY_05000368 workaround
Blackfin arch: Functional power management support
...
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_dma_5xx.c | 34 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 118 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbhdlr.S | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbinit.c | 6 | ||||
-rw-r--r-- | arch/blackfin/kernel/dualcore_test.c | 49 | ||||
-rw-r--r-- | arch/blackfin/kernel/entry.S | 5 | ||||
-rw-r--r-- | arch/blackfin/kernel/kgdb.c | 16 | ||||
-rw-r--r-- | arch/blackfin/kernel/module.c | 74 | ||||
-rw-r--r-- | arch/blackfin/kernel/ptrace.c | 28 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 90 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 296 | ||||
-rw-r--r-- | arch/blackfin/kernel/vmlinux.lds.S | 40 |
13 files changed, 597 insertions, 162 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 6140cd69c782..606adc78aa85 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile | |||
@@ -18,6 +18,5 @@ endif | |||
18 | obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o | 18 | obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o |
19 | obj-$(CONFIG_MODULES) += module.o | 19 | obj-$(CONFIG_MODULES) += module.o |
20 | obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o | 20 | obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o |
21 | obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o | ||
22 | obj-$(CONFIG_KGDB) += kgdb.o | 21 | obj-$(CONFIG_KGDB) += kgdb.o |
23 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 22 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index d54f19085f37..93229b3d6e3e 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -472,6 +472,40 @@ unsigned long get_dma_curr_addr(unsigned int channel) | |||
472 | } | 472 | } |
473 | EXPORT_SYMBOL(get_dma_curr_addr); | 473 | EXPORT_SYMBOL(get_dma_curr_addr); |
474 | 474 | ||
475 | #ifdef CONFIG_PM | ||
476 | int blackfin_dma_suspend(void) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | #ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ | ||
481 | for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) { | ||
482 | #else | ||
483 | for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) { | ||
484 | #endif | ||
485 | if (dma_ch[i].chan_status == DMA_CHANNEL_ENABLED) { | ||
486 | printk(KERN_ERR "DMA Channel %d failed to suspend\n", i); | ||
487 | return -EBUSY; | ||
488 | } | ||
489 | |||
490 | dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map; | ||
491 | } | ||
492 | |||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | void blackfin_dma_resume(void) | ||
497 | { | ||
498 | int i; | ||
499 | |||
500 | #ifdef CONFIG_BF561 /* IMDMA channels doesn't have a PERIPHERAL_MAP */ | ||
501 | for (i = 0; i <= CH_MEM_STREAM3_SRC; i++) | ||
502 | #else | ||
503 | for (i = 0; i < MAX_BLACKFIN_DMA_CHANNEL; i++) | ||
504 | #endif | ||
505 | dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; | ||
506 | } | ||
507 | #endif | ||
508 | |||
475 | static void *__dma_memcpy(void *dest, const void *src, size_t size) | 509 | static void *__dma_memcpy(void *dest, const void *src, size_t size) |
476 | { | 510 | { |
477 | int direction; /* 1 - address decrease, 0 - address increase */ | 511 | int direction; /* 1 - address decrease, 0 - address increase */ |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index b6d89d1644cc..ecbd141e0ef2 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -186,7 +186,10 @@ static struct str_ident { | |||
186 | char name[RESOURCE_LABEL_SIZE]; | 186 | char name[RESOURCE_LABEL_SIZE]; |
187 | } str_ident[MAX_RESOURCES]; | 187 | } str_ident[MAX_RESOURCES]; |
188 | 188 | ||
189 | #if defined(CONFIG_PM) && !defined(CONFIG_BF54x) | 189 | #if defined(CONFIG_PM) |
190 | #if defined(CONFIG_BF54x) | ||
191 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; | ||
192 | #else | ||
190 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 193 | static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
191 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; | 194 | static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; |
192 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; | 195 | static struct gpio_port_s gpio_bank_saved[gpio_bank(MAX_BLACKFIN_GPIOS)]; |
@@ -206,7 +209,7 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PORTF_INT | |||
206 | #ifdef BF561_FAMILY | 209 | #ifdef BF561_FAMILY |
207 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; | 210 | static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; |
208 | #endif | 211 | #endif |
209 | 212 | #endif | |
210 | #endif /* CONFIG_PM */ | 213 | #endif /* CONFIG_PM */ |
211 | 214 | ||
212 | #if defined(BF548_FAMILY) | 215 | #if defined(BF548_FAMILY) |
@@ -667,7 +670,7 @@ static int bfin_gpio_wakeup_type(unsigned gpio, unsigned char type) | |||
667 | return 0; | 670 | return 0; |
668 | } | 671 | } |
669 | 672 | ||
670 | u32 bfin_pm_setup(void) | 673 | u32 bfin_pm_standby_setup(void) |
671 | { | 674 | { |
672 | u16 bank, mask, i, gpio; | 675 | u16 bank, mask, i, gpio; |
673 | 676 | ||
@@ -679,7 +682,7 @@ u32 bfin_pm_setup(void) | |||
679 | gpio_bankb[bank]->maskb = 0; | 682 | gpio_bankb[bank]->maskb = 0; |
680 | 683 | ||
681 | if (mask) { | 684 | if (mask) { |
682 | #ifdef BF537_FAMILY | 685 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) |
683 | gpio_bank_saved[bank].fer = *port_fer[bank]; | 686 | gpio_bank_saved[bank].fer = *port_fer[bank]; |
684 | #endif | 687 | #endif |
685 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | 688 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; |
@@ -715,7 +718,7 @@ u32 bfin_pm_setup(void) | |||
715 | return 0; | 718 | return 0; |
716 | } | 719 | } |
717 | 720 | ||
718 | void bfin_pm_restore(void) | 721 | void bfin_pm_standby_restore(void) |
719 | { | 722 | { |
720 | u16 bank, mask, i; | 723 | u16 bank, mask, i; |
721 | 724 | ||
@@ -724,7 +727,7 @@ void bfin_pm_restore(void) | |||
724 | bank = gpio_bank(i); | 727 | bank = gpio_bank(i); |
725 | 728 | ||
726 | if (mask) { | 729 | if (mask) { |
727 | #ifdef BF537_FAMILY | 730 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) |
728 | *port_fer[bank] = gpio_bank_saved[bank].fer; | 731 | *port_fer[bank] = gpio_bank_saved[bank].fer; |
729 | #endif | 732 | #endif |
730 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | 733 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; |
@@ -743,8 +746,111 @@ void bfin_pm_restore(void) | |||
743 | AWA_DUMMY_READ(maskb); | 746 | AWA_DUMMY_READ(maskb); |
744 | } | 747 | } |
745 | 748 | ||
749 | void bfin_gpio_pm_hibernate_suspend(void) | ||
750 | { | ||
751 | int i, bank; | ||
752 | |||
753 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
754 | bank = gpio_bank(i); | ||
755 | |||
756 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) | ||
757 | gpio_bank_saved[bank].fer = *port_fer[bank]; | ||
758 | #ifdef BF527_FAMILY | ||
759 | gpio_bank_saved[bank].mux = *port_mux[bank]; | ||
760 | #else | ||
761 | if (bank == 0) | ||
762 | gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); | ||
763 | #endif | ||
764 | #endif | ||
765 | gpio_bank_saved[bank].data = gpio_bankb[bank]->data; | ||
766 | gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; | ||
767 | gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; | ||
768 | gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; | ||
769 | gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; | ||
770 | gpio_bank_saved[bank].both = gpio_bankb[bank]->both; | ||
771 | gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; | ||
772 | } | ||
773 | |||
774 | AWA_DUMMY_READ(maska); | ||
775 | } | ||
776 | |||
777 | void bfin_gpio_pm_hibernate_restore(void) | ||
778 | { | ||
779 | int i, bank; | ||
780 | |||
781 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
782 | bank = gpio_bank(i); | ||
783 | |||
784 | #if defined(BF527_FAMILY) || defined(BF537_FAMILY) | ||
785 | #ifdef BF527_FAMILY | ||
786 | *port_mux[bank] = gpio_bank_saved[bank].mux; | ||
787 | #else | ||
788 | if (bank == 0) | ||
789 | bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); | ||
790 | #endif | ||
791 | *port_fer[bank] = gpio_bank_saved[bank].fer; | ||
792 | #endif | ||
793 | gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; | ||
794 | gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; | ||
795 | gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; | ||
796 | gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; | ||
797 | gpio_bankb[bank]->both = gpio_bank_saved[bank].both; | ||
798 | |||
799 | gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data | ||
800 | | gpio_bank_saved[bank].dir; | ||
801 | |||
802 | gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; | ||
803 | } | ||
804 | AWA_DUMMY_READ(maska); | ||
805 | } | ||
806 | |||
807 | |||
746 | #endif | 808 | #endif |
747 | #else /* BF548_FAMILY */ | 809 | #else /* BF548_FAMILY */ |
810 | #ifdef CONFIG_PM | ||
811 | |||
812 | u32 bfin_pm_standby_setup(void) | ||
813 | { | ||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | void bfin_pm_standby_restore(void) | ||
818 | { | ||
819 | |||
820 | } | ||
821 | |||
822 | void bfin_gpio_pm_hibernate_suspend(void) | ||
823 | { | ||
824 | int i, bank; | ||
825 | |||
826 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
827 | bank = gpio_bank(i); | ||
828 | |||
829 | gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; | ||
830 | gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; | ||
831 | gpio_bank_saved[bank].data = gpio_array[bank]->port_data; | ||
832 | gpio_bank_saved[bank].data = gpio_array[bank]->port_data; | ||
833 | gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; | ||
834 | gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; | ||
835 | } | ||
836 | } | ||
837 | |||
838 | void bfin_gpio_pm_hibernate_restore(void) | ||
839 | { | ||
840 | int i, bank; | ||
841 | |||
842 | for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { | ||
843 | bank = gpio_bank(i); | ||
844 | |||
845 | gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; | ||
846 | gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; | ||
847 | gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; | ||
848 | gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; | ||
849 | gpio_array[bank]->port_set = gpio_bank_saved[bank].data | ||
850 | | gpio_bank_saved[bank].dir; | ||
851 | } | ||
852 | } | ||
853 | #endif | ||
748 | 854 | ||
749 | unsigned short get_gpio_dir(unsigned gpio) | 855 | unsigned short get_gpio_dir(unsigned gpio) |
750 | { | 856 | { |
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S index 2788532de72b..ecbabc0a1fed 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S +++ b/arch/blackfin/kernel/cplb-nompu/cplbhdlr.S | |||
@@ -125,6 +125,6 @@ ENTRY(__cplb_hdr) | |||
125 | SP += -12; | 125 | SP += -12; |
126 | call _panic_cplb_error; | 126 | call _panic_cplb_error; |
127 | SP += 12; | 127 | SP += 12; |
128 | JUMP _handle_bad_cplb; | 128 | JUMP.L _handle_bad_cplb; |
129 | 129 | ||
130 | ENDPROC(__cplb_hdr) | 130 | ENDPROC(__cplb_hdr) |
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c index 6be0c50122e8..224e7cc30bc5 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c | |||
@@ -26,11 +26,7 @@ | |||
26 | #include <asm/cplb.h> | 26 | #include <asm/cplb.h> |
27 | #include <asm/cplbinit.h> | 27 | #include <asm/cplbinit.h> |
28 | 28 | ||
29 | #ifdef CONFIG_MAX_MEM_SIZE | 29 | #define CPLB_MEM CONFIG_MAX_MEM_SIZE |
30 | # define CPLB_MEM CONFIG_MAX_MEM_SIZE | ||
31 | #else | ||
32 | # define CPLB_MEM CONFIG_MEM_SIZE | ||
33 | #endif | ||
34 | 30 | ||
35 | /* | 31 | /* |
36 | * Number of required data CPLB switchtable entries | 32 | * Number of required data CPLB switchtable entries |
diff --git a/arch/blackfin/kernel/dualcore_test.c b/arch/blackfin/kernel/dualcore_test.c deleted file mode 100644 index 0fcba74840b7..000000000000 --- a/arch/blackfin/kernel/dualcore_test.c +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | /* | ||
2 | * File: arch/blackfin/kernel/dualcore_test.c | ||
3 | * Based on: | ||
4 | * Author: | ||
5 | * | ||
6 | * Created: | ||
7 | * Description: Small test code for CoreB on a BF561 | ||
8 | * | ||
9 | * Modified: | ||
10 | * Copyright 2004-2006 Analog Devices Inc. | ||
11 | * | ||
12 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify | ||
15 | * it under the terms of the GNU General Public License as published by | ||
16 | * the Free Software Foundation; either version 2 of the License, or | ||
17 | * (at your option) any later version. | ||
18 | * | ||
19 | * This program is distributed in the hope that it will be useful, | ||
20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
22 | * GNU General Public License for more details. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License | ||
25 | * along with this program; if not, see the file COPYING, or write | ||
26 | * to the Free Software Foundation, Inc., | ||
27 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
28 | */ | ||
29 | |||
30 | #include <linux/init.h> | ||
31 | #include <linux/module.h> | ||
32 | |||
33 | static int *testarg = (int *)0xfeb00000; | ||
34 | |||
35 | static int test_init(void) | ||
36 | { | ||
37 | *testarg = 1; | ||
38 | printk(KERN_INFO "Dual core test module inserted: set testarg = [%d]\n @ [%p]\n", | ||
39 | *testarg, testarg); | ||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static void test_exit(void) | ||
44 | { | ||
45 | printk(KERN_INFO "Dual core test module removed: testarg = [%d]\n", *testarg); | ||
46 | } | ||
47 | |||
48 | module_init(test_init); | ||
49 | module_exit(test_exit); | ||
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S index 65f4e67a65c4..31bd9bf3efae 100644 --- a/arch/blackfin/kernel/entry.S +++ b/arch/blackfin/kernel/entry.S | |||
@@ -64,6 +64,11 @@ ENDPROC(_ret_from_fork) | |||
64 | 64 | ||
65 | ENTRY(_sys_fork) | 65 | ENTRY(_sys_fork) |
66 | r0 = -EINVAL; | 66 | r0 = -EINVAL; |
67 | #if (ANOMALY_05000371) | ||
68 | nop; | ||
69 | nop; | ||
70 | nop; | ||
71 | #endif | ||
67 | rts; | 72 | rts; |
68 | ENDPROC(_sys_fork) | 73 | ENDPROC(_sys_fork) |
69 | 74 | ||
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index a9c15515bfd7..a1f9641a6425 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c | |||
@@ -203,6 +203,8 @@ struct hw_breakpoint { | |||
203 | 203 | ||
204 | int kgdb_arch_init(void) | 204 | int kgdb_arch_init(void) |
205 | { | 205 | { |
206 | debugger_step = 0; | ||
207 | |||
206 | kgdb_remove_all_hw_break(); | 208 | kgdb_remove_all_hw_break(); |
207 | return 0; | 209 | return 0; |
208 | } | 210 | } |
@@ -368,6 +370,7 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo, | |||
368 | char *ptr; | 370 | char *ptr; |
369 | int newPC; | 371 | int newPC; |
370 | int wp_status; | 372 | int wp_status; |
373 | int i; | ||
371 | 374 | ||
372 | switch (remcom_in_buffer[0]) { | 375 | switch (remcom_in_buffer[0]) { |
373 | case 'c': | 376 | case 'c': |
@@ -392,7 +395,18 @@ int kgdb_arch_handle_exception(int exceptionVector, int signo, | |||
392 | /* set the trace bit if we're stepping */ | 395 | /* set the trace bit if we're stepping */ |
393 | if (remcom_in_buffer[0] == 's') { | 396 | if (remcom_in_buffer[0] == 's') { |
394 | linux_regs->syscfg |= 0x1; | 397 | linux_regs->syscfg |= 0x1; |
395 | debugger_step = 1; | 398 | debugger_step = linux_regs->ipend; |
399 | debugger_step >>= 6; | ||
400 | for (i = 10; i > 0; i--, debugger_step >>= 1) | ||
401 | if (debugger_step & 1) | ||
402 | break; | ||
403 | /* i indicate event priority of current stopped instruction | ||
404 | * user space instruction is 0, IVG15 is 1, IVTMR is 10. | ||
405 | * debugger_step > 0 means in single step mode | ||
406 | */ | ||
407 | debugger_step = i + 1; | ||
408 | } else { | ||
409 | debugger_step = 0; | ||
396 | } | 410 | } |
397 | 411 | ||
398 | wp_status = bfin_read_WPSTAT(); | 412 | wp_status = bfin_read_WPSTAT(); |
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 14a42848f37f..e1bebc80a5bf 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c | |||
@@ -173,7 +173,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
173 | for (s = sechdrs; s < sechdrs_end; ++s) { | 173 | for (s = sechdrs; s < sechdrs_end; ++s) { |
174 | if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || | 174 | if ((strcmp(".l1.text", secstrings + s->sh_name) == 0) || |
175 | ((strcmp(".text", secstrings + s->sh_name) == 0) && | 175 | ((strcmp(".text", secstrings + s->sh_name) == 0) && |
176 | (hdr->e_flags & FLG_CODE_IN_L1) && (s->sh_size > 0))) { | 176 | (hdr->e_flags & EF_BFIN_CODE_IN_L1) && (s->sh_size > 0))) { |
177 | dest = l1_inst_sram_alloc(s->sh_size); | 177 | dest = l1_inst_sram_alloc(s->sh_size); |
178 | mod->arch.text_l1 = dest; | 178 | mod->arch.text_l1 = dest; |
179 | if (dest == NULL) { | 179 | if (dest == NULL) { |
@@ -188,7 +188,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
188 | } | 188 | } |
189 | if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || | 189 | if ((strcmp(".l1.data", secstrings + s->sh_name) == 0) || |
190 | ((strcmp(".data", secstrings + s->sh_name) == 0) && | 190 | ((strcmp(".data", secstrings + s->sh_name) == 0) && |
191 | (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { | 191 | (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { |
192 | dest = l1_data_sram_alloc(s->sh_size); | 192 | dest = l1_data_sram_alloc(s->sh_size); |
193 | mod->arch.data_a_l1 = dest; | 193 | mod->arch.data_a_l1 = dest; |
194 | if (dest == NULL) { | 194 | if (dest == NULL) { |
@@ -203,7 +203,7 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
203 | } | 203 | } |
204 | if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || | 204 | if (strcmp(".l1.bss", secstrings + s->sh_name) == 0 || |
205 | ((strcmp(".bss", secstrings + s->sh_name) == 0) && | 205 | ((strcmp(".bss", secstrings + s->sh_name) == 0) && |
206 | (hdr->e_flags & FLG_DATA_IN_L1) && (s->sh_size > 0))) { | 206 | (hdr->e_flags & EF_BFIN_DATA_IN_L1) && (s->sh_size > 0))) { |
207 | dest = l1_data_sram_alloc(s->sh_size); | 207 | dest = l1_data_sram_alloc(s->sh_size); |
208 | mod->arch.bss_a_l1 = dest; | 208 | mod->arch.bss_a_l1 = dest; |
209 | if (dest == NULL) { | 209 | if (dest == NULL) { |
@@ -242,6 +242,51 @@ module_frob_arch_sections(Elf_Ehdr * hdr, Elf_Shdr * sechdrs, | |||
242 | s->sh_flags &= ~SHF_ALLOC; | 242 | s->sh_flags &= ~SHF_ALLOC; |
243 | s->sh_addr = (unsigned long)dest; | 243 | s->sh_addr = (unsigned long)dest; |
244 | } | 244 | } |
245 | if ((strcmp(".l2.text", secstrings + s->sh_name) == 0) || | ||
246 | ((strcmp(".text", secstrings + s->sh_name) == 0) && | ||
247 | (hdr->e_flags & EF_BFIN_CODE_IN_L2) && (s->sh_size > 0))) { | ||
248 | dest = l2_sram_alloc(s->sh_size); | ||
249 | mod->arch.text_l2 = dest; | ||
250 | if (dest == NULL) { | ||
251 | printk(KERN_ERR | ||
252 | "module %s: L2 SRAM allocation failed\n", | ||
253 | mod->name); | ||
254 | return -1; | ||
255 | } | ||
256 | memcpy(dest, (void *)s->sh_addr, s->sh_size); | ||
257 | s->sh_flags &= ~SHF_ALLOC; | ||
258 | s->sh_addr = (unsigned long)dest; | ||
259 | } | ||
260 | if ((strcmp(".l2.data", secstrings + s->sh_name) == 0) || | ||
261 | ((strcmp(".data", secstrings + s->sh_name) == 0) && | ||
262 | (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { | ||
263 | dest = l2_sram_alloc(s->sh_size); | ||
264 | mod->arch.data_l2 = dest; | ||
265 | if (dest == NULL) { | ||
266 | printk(KERN_ERR | ||
267 | "module %s: L2 SRAM allocation failed\n", | ||
268 | mod->name); | ||
269 | return -1; | ||
270 | } | ||
271 | memcpy(dest, (void *)s->sh_addr, s->sh_size); | ||
272 | s->sh_flags &= ~SHF_ALLOC; | ||
273 | s->sh_addr = (unsigned long)dest; | ||
274 | } | ||
275 | if (strcmp(".l2.bss", secstrings + s->sh_name) == 0 || | ||
276 | ((strcmp(".bss", secstrings + s->sh_name) == 0) && | ||
277 | (hdr->e_flags & EF_BFIN_DATA_IN_L2) && (s->sh_size > 0))) { | ||
278 | dest = l2_sram_alloc(s->sh_size); | ||
279 | mod->arch.bss_l2 = dest; | ||
280 | if (dest == NULL) { | ||
281 | printk(KERN_ERR | ||
282 | "module %s: L2 SRAM allocation failed\n", | ||
283 | mod->name); | ||
284 | return -1; | ||
285 | } | ||
286 | memset(dest, 0, s->sh_size); | ||
287 | s->sh_flags &= ~SHF_ALLOC; | ||
288 | s->sh_addr = (unsigned long)dest; | ||
289 | } | ||
245 | } | 290 | } |
246 | return 0; | 291 | return 0; |
247 | } | 292 | } |
@@ -411,9 +456,10 @@ module_finalize(const Elf_Ehdr * hdr, | |||
411 | continue; | 456 | continue; |
412 | 457 | ||
413 | if ((sechdrs[i].sh_type == SHT_RELA) && | 458 | if ((sechdrs[i].sh_type == SHT_RELA) && |
414 | ((strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || | 459 | ((strcmp(".rela.l2.text", secstrings + sechdrs[i].sh_name) == 0) || |
460 | (strcmp(".rela.l1.text", secstrings + sechdrs[i].sh_name) == 0) || | ||
415 | ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && | 461 | ((strcmp(".rela.text", secstrings + sechdrs[i].sh_name) == 0) && |
416 | (hdr->e_flags & FLG_CODE_IN_L1)))) { | 462 | (hdr->e_flags & (EF_BFIN_CODE_IN_L1|EF_BFIN_CODE_IN_L2))))) { |
417 | apply_relocate_add((Elf_Shdr *) sechdrs, strtab, | 463 | apply_relocate_add((Elf_Shdr *) sechdrs, strtab, |
418 | symindex, i, mod); | 464 | symindex, i, mod); |
419 | } | 465 | } |
@@ -423,14 +469,12 @@ module_finalize(const Elf_Ehdr * hdr, | |||
423 | 469 | ||
424 | void module_arch_cleanup(struct module *mod) | 470 | void module_arch_cleanup(struct module *mod) |
425 | { | 471 | { |
426 | if (mod->arch.text_l1) | 472 | l1_inst_sram_free(mod->arch.text_l1); |
427 | l1_inst_sram_free((void *)mod->arch.text_l1); | 473 | l1_data_A_sram_free(mod->arch.data_a_l1); |
428 | if (mod->arch.data_a_l1) | 474 | l1_data_A_sram_free(mod->arch.bss_a_l1); |
429 | l1_data_sram_free((void *)mod->arch.data_a_l1); | 475 | l1_data_B_sram_free(mod->arch.data_b_l1); |
430 | if (mod->arch.bss_a_l1) | 476 | l1_data_B_sram_free(mod->arch.bss_b_l1); |
431 | l1_data_sram_free((void *)mod->arch.bss_a_l1); | 477 | l2_sram_free(mod->arch.text_l2); |
432 | if (mod->arch.data_b_l1) | 478 | l2_sram_free(mod->arch.data_l2); |
433 | l1_data_B_sram_free((void *)mod->arch.data_b_l1); | 479 | l2_sram_free(mod->arch.bss_l2); |
434 | if (mod->arch.bss_b_l1) | ||
435 | l1_data_B_sram_free((void *)mod->arch.bss_b_l1); | ||
436 | } | 480 | } |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index f51ab088098e..bf1a51d8e608 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -220,6 +220,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
220 | copied = sizeof(tmp); | 220 | copied = sizeof(tmp); |
221 | } else | 221 | } else |
222 | #endif | 222 | #endif |
223 | #if L1_DATA_A_LENGTH != 0 | ||
224 | if (addr + add >= L1_DATA_A_START | ||
225 | && addr + add + sizeof(tmp) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { | ||
226 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); | ||
227 | copied = sizeof(tmp); | ||
228 | } else | ||
229 | #endif | ||
230 | #if L1_DATA_B_LENGTH != 0 | ||
231 | if (addr + add >= L1_DATA_B_START | ||
232 | && addr + add + sizeof(tmp) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { | ||
233 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); | ||
234 | copied = sizeof(tmp); | ||
235 | } else | ||
236 | #endif | ||
223 | if (addr + add >= FIXED_CODE_START | 237 | if (addr + add >= FIXED_CODE_START |
224 | && addr + add + sizeof(tmp) <= FIXED_CODE_END) { | 238 | && addr + add + sizeof(tmp) <= FIXED_CODE_END) { |
225 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); | 239 | memcpy(&tmp, (const void *)(addr + add), sizeof(tmp)); |
@@ -290,6 +304,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
290 | copied = sizeof(data); | 304 | copied = sizeof(data); |
291 | } else | 305 | } else |
292 | #endif | 306 | #endif |
307 | #if L1_DATA_A_LENGTH != 0 | ||
308 | if (addr + add >= L1_DATA_A_START | ||
309 | && addr + add + sizeof(data) <= L1_DATA_A_START + L1_DATA_A_LENGTH) { | ||
310 | memcpy((void *)(addr + add), &data, sizeof(data)); | ||
311 | copied = sizeof(data); | ||
312 | } else | ||
313 | #endif | ||
314 | #if L1_DATA_B_LENGTH != 0 | ||
315 | if (addr + add >= L1_DATA_B_START | ||
316 | && addr + add + sizeof(data) <= L1_DATA_B_START + L1_DATA_B_LENGTH) { | ||
317 | memcpy((void *)(addr + add), &data, sizeof(data)); | ||
318 | copied = sizeof(data); | ||
319 | } else | ||
320 | #endif | ||
293 | if (addr + add >= FIXED_CODE_START | 321 | if (addr + add >= FIXED_CODE_START |
294 | && addr + add + sizeof(data) <= FIXED_CODE_END) { | 322 | && addr + add + sizeof(data) <= FIXED_CODE_END) { |
295 | memcpy((void *)(addr + add), &data, sizeof(data)); | 323 | memcpy((void *)(addr + add), &data, sizeof(data)); |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index 8efea004aecb..23e637eb78da 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -104,6 +104,7 @@ void __init bf53x_relocate_l1_mem(void) | |||
104 | unsigned long l1_code_length; | 104 | unsigned long l1_code_length; |
105 | unsigned long l1_data_a_length; | 105 | unsigned long l1_data_a_length; |
106 | unsigned long l1_data_b_length; | 106 | unsigned long l1_data_b_length; |
107 | unsigned long l2_length; | ||
107 | 108 | ||
108 | l1_code_length = _etext_l1 - _stext_l1; | 109 | l1_code_length = _etext_l1 - _stext_l1; |
109 | if (l1_code_length > L1_CODE_LENGTH) | 110 | if (l1_code_length > L1_CODE_LENGTH) |
@@ -129,6 +130,15 @@ void __init bf53x_relocate_l1_mem(void) | |||
129 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ | 130 | /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ |
130 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + | 131 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + |
131 | l1_data_a_length, l1_data_b_length); | 132 | l1_data_a_length, l1_data_b_length); |
133 | |||
134 | #ifdef L2_LENGTH | ||
135 | l2_length = _ebss_l2 - _stext_l2; | ||
136 | if (l2_length > L2_LENGTH) | ||
137 | panic("L2 SRAM Overflow\n"); | ||
138 | |||
139 | /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
140 | dma_memcpy(_stext_l2, _l2_lma_start, l2_length); | ||
141 | #endif | ||
132 | } | 142 | } |
133 | 143 | ||
134 | /* add_memory_region to memmap */ | 144 | /* add_memory_region to memmap */ |
@@ -664,11 +674,8 @@ static __init void setup_bootmem_allocator(void) | |||
664 | }) | 674 | }) |
665 | static inline int __init get_mem_size(void) | 675 | static inline int __init get_mem_size(void) |
666 | { | 676 | { |
667 | #ifdef CONFIG_MEM_SIZE | 677 | #if defined(EBIU_SDBCTL) |
668 | return CONFIG_MEM_SIZE; | 678 | # if defined(BF561_FAMILY) |
669 | #else | ||
670 | # if defined(EBIU_SDBCTL) | ||
671 | # if defined(BF561_FAMILY) | ||
672 | int ret = 0; | 679 | int ret = 0; |
673 | u32 sdbctl = bfin_read_EBIU_SDBCTL(); | 680 | u32 sdbctl = bfin_read_EBIU_SDBCTL(); |
674 | ret += EBSZ_TO_MEG(sdbctl >> 0); | 681 | ret += EBSZ_TO_MEG(sdbctl >> 0); |
@@ -676,10 +683,10 @@ static inline int __init get_mem_size(void) | |||
676 | ret += EBSZ_TO_MEG(sdbctl >> 16); | 683 | ret += EBSZ_TO_MEG(sdbctl >> 16); |
677 | ret += EBSZ_TO_MEG(sdbctl >> 24); | 684 | ret += EBSZ_TO_MEG(sdbctl >> 24); |
678 | return ret; | 685 | return ret; |
679 | # else | 686 | # else |
680 | return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); | 687 | return EBSZ_TO_MEG(bfin_read_EBIU_SDBCTL()); |
681 | # endif | 688 | # endif |
682 | # elif defined(EBIU_DDRCTL1) | 689 | #elif defined(EBIU_DDRCTL1) |
683 | u32 ddrctl = bfin_read_EBIU_DDRCTL1(); | 690 | u32 ddrctl = bfin_read_EBIU_DDRCTL1(); |
684 | int ret = 0; | 691 | int ret = 0; |
685 | switch (ddrctl & 0xc0000) { | 692 | switch (ddrctl & 0xc0000) { |
@@ -693,8 +700,9 @@ static inline int __init get_mem_size(void) | |||
693 | case DEVWD_8: ret *= 2; | 700 | case DEVWD_8: ret *= 2; |
694 | case DEVWD_16: break; | 701 | case DEVWD_16: break; |
695 | } | 702 | } |
703 | if ((ddrctl & 0xc000) == 0x4000) | ||
704 | ret *= 2; | ||
696 | return ret; | 705 | return ret; |
697 | # endif | ||
698 | #endif | 706 | #endif |
699 | BUG(); | 707 | BUG(); |
700 | } | 708 | } |
@@ -763,6 +771,9 @@ void __init setup_arch(char **cmdline_p) | |||
763 | 771 | ||
764 | _bfin_swrst = bfin_read_SWRST(); | 772 | _bfin_swrst = bfin_read_SWRST(); |
765 | 773 | ||
774 | /* If we double fault, reset the system - otherwise we hang forever */ | ||
775 | bfin_write_SWRST(DOUBLE_FAULT); | ||
776 | |||
766 | if (_bfin_swrst & RESET_DOUBLE) | 777 | if (_bfin_swrst & RESET_DOUBLE) |
767 | printk(KERN_INFO "Recovering from Double Fault event\n"); | 778 | printk(KERN_INFO "Recovering from Double Fault event\n"); |
768 | else if (_bfin_swrst & RESET_WDOG) | 779 | else if (_bfin_swrst & RESET_WDOG) |
@@ -842,38 +853,55 @@ static int __init topology_init(void) | |||
842 | 853 | ||
843 | subsys_initcall(topology_init); | 854 | subsys_initcall(topology_init); |
844 | 855 | ||
856 | /* Get the voltage input multiplier */ | ||
857 | static u_long cached_vco_pll_ctl, cached_vco; | ||
845 | static u_long get_vco(void) | 858 | static u_long get_vco(void) |
846 | { | 859 | { |
847 | u_long msel; | 860 | u_long msel; |
848 | u_long vco; | ||
849 | 861 | ||
850 | msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; | 862 | u_long pll_ctl = bfin_read_PLL_CTL(); |
863 | if (pll_ctl == cached_vco_pll_ctl) | ||
864 | return cached_vco; | ||
865 | else | ||
866 | cached_vco_pll_ctl = pll_ctl; | ||
867 | |||
868 | msel = (pll_ctl >> 9) & 0x3F; | ||
851 | if (0 == msel) | 869 | if (0 == msel) |
852 | msel = 64; | 870 | msel = 64; |
853 | 871 | ||
854 | vco = CONFIG_CLKIN_HZ; | 872 | cached_vco = CONFIG_CLKIN_HZ; |
855 | vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ | 873 | cached_vco >>= (1 & pll_ctl); /* DF bit */ |
856 | vco = msel * vco; | 874 | cached_vco *= msel; |
857 | return vco; | 875 | return cached_vco; |
858 | } | 876 | } |
859 | 877 | ||
860 | /* Get the Core clock */ | 878 | /* Get the Core clock */ |
879 | static u_long cached_cclk_pll_div, cached_cclk; | ||
861 | u_long get_cclk(void) | 880 | u_long get_cclk(void) |
862 | { | 881 | { |
863 | u_long csel, ssel; | 882 | u_long csel, ssel; |
883 | |||
864 | if (bfin_read_PLL_STAT() & 0x1) | 884 | if (bfin_read_PLL_STAT() & 0x1) |
865 | return CONFIG_CLKIN_HZ; | 885 | return CONFIG_CLKIN_HZ; |
866 | 886 | ||
867 | ssel = bfin_read_PLL_DIV(); | 887 | ssel = bfin_read_PLL_DIV(); |
888 | if (ssel == cached_cclk_pll_div) | ||
889 | return cached_cclk; | ||
890 | else | ||
891 | cached_cclk_pll_div = ssel; | ||
892 | |||
868 | csel = ((ssel >> 4) & 0x03); | 893 | csel = ((ssel >> 4) & 0x03); |
869 | ssel &= 0xf; | 894 | ssel &= 0xf; |
870 | if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ | 895 | if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ |
871 | return get_vco() / ssel; | 896 | cached_cclk = get_vco() / ssel; |
872 | return get_vco() >> csel; | 897 | else |
898 | cached_cclk = get_vco() >> csel; | ||
899 | return cached_cclk; | ||
873 | } | 900 | } |
874 | EXPORT_SYMBOL(get_cclk); | 901 | EXPORT_SYMBOL(get_cclk); |
875 | 902 | ||
876 | /* Get the System clock */ | 903 | /* Get the System clock */ |
904 | static u_long cached_sclk_pll_div, cached_sclk; | ||
877 | u_long get_sclk(void) | 905 | u_long get_sclk(void) |
878 | { | 906 | { |
879 | u_long ssel; | 907 | u_long ssel; |
@@ -881,13 +909,20 @@ u_long get_sclk(void) | |||
881 | if (bfin_read_PLL_STAT() & 0x1) | 909 | if (bfin_read_PLL_STAT() & 0x1) |
882 | return CONFIG_CLKIN_HZ; | 910 | return CONFIG_CLKIN_HZ; |
883 | 911 | ||
884 | ssel = (bfin_read_PLL_DIV() & 0xf); | 912 | ssel = bfin_read_PLL_DIV(); |
913 | if (ssel == cached_sclk_pll_div) | ||
914 | return cached_sclk; | ||
915 | else | ||
916 | cached_sclk_pll_div = ssel; | ||
917 | |||
918 | ssel &= 0xf; | ||
885 | if (0 == ssel) { | 919 | if (0 == ssel) { |
886 | printk(KERN_WARNING "Invalid System Clock\n"); | 920 | printk(KERN_WARNING "Invalid System Clock\n"); |
887 | ssel = 1; | 921 | ssel = 1; |
888 | } | 922 | } |
889 | 923 | ||
890 | return get_vco() / ssel; | 924 | cached_sclk = get_vco() / ssel; |
925 | return cached_sclk; | ||
891 | } | 926 | } |
892 | EXPORT_SYMBOL(get_sclk); | 927 | EXPORT_SYMBOL(get_sclk); |
893 | 928 | ||
@@ -916,7 +951,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
916 | uint32_t revid; | 951 | uint32_t revid; |
917 | 952 | ||
918 | u_long cclk = 0, sclk = 0; | 953 | u_long cclk = 0, sclk = 0; |
919 | u_int dcache_size = 0, dsup_banks = 0; | 954 | u_int icache_size = BFIN_ICACHESIZE / 1024, dcache_size = 0, dsup_banks = 0; |
920 | 955 | ||
921 | cpu = CPU; | 956 | cpu = CPU; |
922 | mmu = "none"; | 957 | mmu = "none"; |
@@ -985,12 +1020,15 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
985 | } | 1020 | } |
986 | 1021 | ||
987 | /* Is it turned on? */ | 1022 | /* Is it turned on? */ |
988 | if (!((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))) | 1023 | if ((bfin_read_DMEM_CONTROL() & (ENDCPLB | DMC_ENABLE)) != (ENDCPLB | DMC_ENABLE)) |
989 | dcache_size = 0; | 1024 | dcache_size = 0; |
990 | 1025 | ||
1026 | if ((bfin_read_IMEM_CONTROL() & (IMC | ENICPLB)) == (IMC | ENICPLB)) | ||
1027 | icache_size = 0; | ||
1028 | |||
991 | seq_printf(m, "cache size\t: %d KB(L1 icache) " | 1029 | seq_printf(m, "cache size\t: %d KB(L1 icache) " |
992 | "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", | 1030 | "%d KB(L1 dcache-%s) %d KB(L2 cache)\n", |
993 | BFIN_ICACHESIZE / 1024, dcache_size, | 1031 | icache_size, dcache_size, |
994 | #if defined CONFIG_BFIN_WB | 1032 | #if defined CONFIG_BFIN_WB |
995 | "wb" | 1033 | "wb" |
996 | #elif defined CONFIG_BFIN_WT | 1034 | #elif defined CONFIG_BFIN_WT |
@@ -1000,8 +1038,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1000 | 1038 | ||
1001 | seq_printf(m, "%s\n", cache); | 1039 | seq_printf(m, "%s\n", cache); |
1002 | 1040 | ||
1003 | seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", | 1041 | if (icache_size) |
1004 | BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); | 1042 | seq_printf(m, "icache setup\t: %d Sub-banks/%d Ways, %d Lines/Way\n", |
1043 | BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES); | ||
1044 | else | ||
1045 | seq_printf(m, "icache setup\t: off\n"); | ||
1046 | |||
1005 | seq_printf(m, | 1047 | seq_printf(m, |
1006 | "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", | 1048 | "dcache setup\t: %d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", |
1007 | dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, | 1049 | dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS, |
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index f061f5181623..ad922ab91543 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -69,8 +69,6 @@ void __init trap_init(void) | |||
69 | 69 | ||
70 | unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; | 70 | unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; |
71 | 71 | ||
72 | int kstack_depth_to_print = 48; | ||
73 | |||
74 | static void decode_address(char *buf, unsigned long address) | 72 | static void decode_address(char *buf, unsigned long address) |
75 | { | 73 | { |
76 | struct vm_list_struct *vml; | 74 | struct vm_list_struct *vml; |
@@ -163,6 +161,9 @@ static void decode_address(char *buf, unsigned long address) | |||
163 | if (!in_atomic) | 161 | if (!in_atomic) |
164 | mmput(mm); | 162 | mmput(mm); |
165 | 163 | ||
164 | if (!strlen(buf)) | ||
165 | sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); | ||
166 | |||
166 | goto done; | 167 | goto done; |
167 | } | 168 | } |
168 | 169 | ||
@@ -173,7 +174,7 @@ static void decode_address(char *buf, unsigned long address) | |||
173 | } | 174 | } |
174 | 175 | ||
175 | /* we were unable to find this address anywhere */ | 176 | /* we were unable to find this address anywhere */ |
176 | sprintf(buf, "<0x%p> /* unknown address */", (void *)address); | 177 | sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); |
177 | 178 | ||
178 | done: | 179 | done: |
179 | write_unlock_irqrestore(&tasklist_lock, flags); | 180 | write_unlock_irqrestore(&tasklist_lock, flags); |
@@ -494,7 +495,7 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
494 | BUG_ON(sig == 0); | 495 | BUG_ON(sig == 0); |
495 | 496 | ||
496 | if (sig != SIGTRAP) { | 497 | if (sig != SIGTRAP) { |
497 | unsigned long stack; | 498 | unsigned long *stack; |
498 | dump_bfin_process(fp); | 499 | dump_bfin_process(fp); |
499 | dump_bfin_mem(fp); | 500 | dump_bfin_mem(fp); |
500 | show_regs(fp); | 501 | show_regs(fp); |
@@ -508,14 +509,23 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
508 | else | 509 | else |
509 | #endif | 510 | #endif |
510 | dump_bfin_trace_buffer(); | 511 | dump_bfin_trace_buffer(); |
511 | show_stack(current, &stack); | 512 | |
512 | if (oops_in_progress) { | 513 | if (oops_in_progress) { |
514 | /* Dump the current kernel stack */ | ||
515 | printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); | ||
516 | show_stack(current, NULL); | ||
517 | |||
513 | print_modules(); | 518 | print_modules(); |
514 | #ifndef CONFIG_ACCESS_CHECK | 519 | #ifndef CONFIG_ACCESS_CHECK |
515 | printk(KERN_EMERG "Please turn on " | 520 | printk(KERN_EMERG "Please turn on " |
516 | "CONFIG_ACCESS_CHECK\n"); | 521 | "CONFIG_ACCESS_CHECK\n"); |
517 | #endif | 522 | #endif |
518 | panic("Kernel exception"); | 523 | panic("Kernel exception"); |
524 | } else { | ||
525 | /* Dump the user space stack */ | ||
526 | stack = (unsigned long *)rdusp(); | ||
527 | printk(KERN_NOTICE "Userspace Stack\n"); | ||
528 | show_stack(NULL, stack); | ||
519 | } | 529 | } |
520 | } | 530 | } |
521 | 531 | ||
@@ -532,11 +542,71 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
532 | 542 | ||
533 | #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) | 543 | #define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) |
534 | 544 | ||
545 | /* | ||
546 | * Similar to get_user, do some address checking, then dereference | ||
547 | * Return true on sucess, false on bad address | ||
548 | */ | ||
549 | bool get_instruction(unsigned short *val, unsigned short *address) | ||
550 | { | ||
551 | |||
552 | unsigned long addr; | ||
553 | |||
554 | addr = (unsigned long)address; | ||
555 | |||
556 | /* Check for odd addresses */ | ||
557 | if (addr & 0x1) | ||
558 | return false; | ||
559 | |||
560 | /* Check that things do not wrap around */ | ||
561 | if (addr > (addr + 2)) | ||
562 | return false; | ||
563 | |||
564 | /* | ||
565 | * Since we are in exception context, we need to do a little address checking | ||
566 | * We need to make sure we are only accessing valid memory, and | ||
567 | * we don't read something in the async space that can hang forever | ||
568 | */ | ||
569 | if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || | ||
570 | #ifdef L2_START | ||
571 | (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || | ||
572 | #endif | ||
573 | (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || | ||
574 | #if L1_DATA_A_LENGTH != 0 | ||
575 | (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || | ||
576 | #endif | ||
577 | #if L1_DATA_B_LENGTH != 0 | ||
578 | (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || | ||
579 | #endif | ||
580 | (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || | ||
581 | (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && | ||
582 | addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || | ||
583 | (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && | ||
584 | addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || | ||
585 | (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && | ||
586 | addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || | ||
587 | (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && | ||
588 | addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { | ||
589 | *val = *address; | ||
590 | return true; | ||
591 | } | ||
592 | |||
593 | #if L1_CODE_LENGTH != 0 | ||
594 | if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { | ||
595 | dma_memcpy(val, address, 2); | ||
596 | return true; | ||
597 | } | ||
598 | #endif | ||
599 | |||
600 | |||
601 | return false; | ||
602 | } | ||
603 | |||
535 | void dump_bfin_trace_buffer(void) | 604 | void dump_bfin_trace_buffer(void) |
536 | { | 605 | { |
537 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | 606 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON |
538 | int tflags, i = 0; | 607 | int tflags, i = 0; |
539 | char buf[150]; | 608 | char buf[150]; |
609 | unsigned short val = 0, *addr; | ||
540 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND | 610 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND |
541 | int j, index; | 611 | int j, index; |
542 | #endif | 612 | #endif |
@@ -549,8 +619,42 @@ void dump_bfin_trace_buffer(void) | |||
549 | for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { | 619 | for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { |
550 | decode_address(buf, (unsigned long)bfin_read_TBUF()); | 620 | decode_address(buf, (unsigned long)bfin_read_TBUF()); |
551 | printk(KERN_NOTICE "%4i Target : %s\n", i, buf); | 621 | printk(KERN_NOTICE "%4i Target : %s\n", i, buf); |
552 | decode_address(buf, (unsigned long)bfin_read_TBUF()); | 622 | addr = (unsigned short *)bfin_read_TBUF(); |
553 | printk(KERN_NOTICE " Source : %s\n", buf); | 623 | decode_address(buf, (unsigned long)addr); |
624 | printk(KERN_NOTICE " Source : %s ", buf); | ||
625 | if (get_instruction(&val, addr)) { | ||
626 | if (val == 0x0010) | ||
627 | printk("RTS"); | ||
628 | else if (val == 0x0011) | ||
629 | printk("RTI"); | ||
630 | else if (val == 0x0012) | ||
631 | printk("RTX"); | ||
632 | else if (val >= 0x0050 && val <= 0x0057) | ||
633 | printk("JUMP (P%i)", val & 7); | ||
634 | else if (val >= 0x0060 && val <= 0x0067) | ||
635 | printk("CALL (P%i)", val & 7); | ||
636 | else if (val >= 0x0070 && val <= 0x0077) | ||
637 | printk("CALL (PC+P%i)", val & 7); | ||
638 | else if (val >= 0x0080 && val <= 0x0087) | ||
639 | printk("JUMP (PC+P%i)", val & 7); | ||
640 | else if ((val >= 0x1000 && val <= 0x13FF) || | ||
641 | (val >= 0x1800 && val <= 0x1BFF)) | ||
642 | printk("IF !CC JUMP"); | ||
643 | else if ((val >= 0x1400 && val <= 0x17ff) || | ||
644 | (val >= 0x1c00 && val <= 0x1fff)) | ||
645 | printk("IF CC JUMP"); | ||
646 | else if (val >= 0x2000 && val <= 0x2fff) | ||
647 | printk("JUMP.S"); | ||
648 | else if (val >= 0xe080 && val <= 0xe0ff) | ||
649 | printk("LSETUP"); | ||
650 | else if (val >= 0xe200 && val <= 0xe2ff) | ||
651 | printk("JUMP.L"); | ||
652 | else if (val >= 0xe300 && val <= 0xe3ff) | ||
653 | printk("CALL pcrel"); | ||
654 | else | ||
655 | printk("0x%04x", val); | ||
656 | } | ||
657 | printk("\n"); | ||
554 | } | 658 | } |
555 | } | 659 | } |
556 | 660 | ||
@@ -582,59 +686,151 @@ void dump_bfin_trace_buffer(void) | |||
582 | } | 686 | } |
583 | EXPORT_SYMBOL(dump_bfin_trace_buffer); | 687 | EXPORT_SYMBOL(dump_bfin_trace_buffer); |
584 | 688 | ||
585 | static void show_trace(struct task_struct *tsk, unsigned long *sp) | 689 | /* |
690 | * Checks to see if the address pointed to is either a | ||
691 | * 16-bit CALL instruction, or a 32-bit CALL instruction | ||
692 | */ | ||
693 | bool is_bfin_call(unsigned short *addr) | ||
586 | { | 694 | { |
587 | unsigned long addr; | 695 | unsigned short opcode = 0, *ins_addr; |
696 | ins_addr = (unsigned short *)addr; | ||
588 | 697 | ||
589 | printk(KERN_NOTICE "\n" KERN_NOTICE "Call Trace:\n"); | 698 | if (!get_instruction(&opcode, ins_addr)) |
590 | 699 | return false; | |
591 | while (!kstack_end(sp)) { | ||
592 | addr = *sp++; | ||
593 | /* | ||
594 | * If the address is either in the text segment of the | ||
595 | * kernel, or in the region which contains vmalloc'ed | ||
596 | * memory, it *may* be the address of a calling | ||
597 | * routine; if so, print it so that someone tracing | ||
598 | * down the cause of the crash will be able to figure | ||
599 | * out the call path that was taken. | ||
600 | */ | ||
601 | if (kernel_text_address(addr)) | ||
602 | print_ip_sym(addr); | ||
603 | } | ||
604 | 700 | ||
605 | printk(KERN_NOTICE "\n"); | 701 | if ((opcode >= 0x0060 && opcode <= 0x0067) || |
606 | } | 702 | (opcode >= 0x0070 && opcode <= 0x0077)) |
703 | return true; | ||
704 | |||
705 | ins_addr--; | ||
706 | if (!get_instruction(&opcode, ins_addr)) | ||
707 | return false; | ||
607 | 708 | ||
709 | if (opcode >= 0xE300 && opcode <= 0xE3FF) | ||
710 | return true; | ||
711 | |||
712 | return false; | ||
713 | |||
714 | } | ||
608 | void show_stack(struct task_struct *task, unsigned long *stack) | 715 | void show_stack(struct task_struct *task, unsigned long *stack) |
609 | { | 716 | { |
610 | unsigned long *endstack, addr; | 717 | unsigned int *addr, *endstack, *fp = 0, *frame; |
611 | int i; | 718 | unsigned short *ins_addr; |
719 | char buf[150]; | ||
720 | unsigned int i, j, ret_addr, frame_no = 0; | ||
612 | 721 | ||
613 | /* Cannot call dump_bfin_trace_buffer() here as show_stack() is | 722 | /* |
614 | * called externally in some places in the kernel. | 723 | * If we have been passed a specific stack, use that one otherwise |
724 | * if we have been passed a task structure, use that, otherwise | ||
725 | * use the stack of where the variable "stack" exists | ||
615 | */ | 726 | */ |
616 | 727 | ||
617 | if (!stack) { | 728 | if (stack == NULL) { |
618 | if (task) | 729 | if (task) { |
730 | /* We know this is a kernel stack, so this is the start/end */ | ||
619 | stack = (unsigned long *)task->thread.ksp; | 731 | stack = (unsigned long *)task->thread.ksp; |
620 | else | 732 | endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); |
733 | } else { | ||
734 | /* print out the existing stack info */ | ||
621 | stack = (unsigned long *)&stack; | 735 | stack = (unsigned long *)&stack; |
736 | endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); | ||
737 | } | ||
738 | } else | ||
739 | endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); | ||
740 | |||
741 | decode_address(buf, (unsigned int)stack); | ||
742 | printk(KERN_NOTICE "Stack info:\n" KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); | ||
743 | addr = (unsigned int *)((unsigned int)stack & ~0x3F); | ||
744 | |||
745 | /* First thing is to look for a frame pointer */ | ||
746 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; | ||
747 | addr < endstack; addr++, i++) { | ||
748 | if (*addr & 0x1) | ||
749 | continue; | ||
750 | ins_addr = (unsigned short *)*addr; | ||
751 | ins_addr--; | ||
752 | if (is_bfin_call(ins_addr)) | ||
753 | fp = addr - 1; | ||
754 | |||
755 | if (fp) { | ||
756 | /* Let's check to see if it is a frame pointer */ | ||
757 | while (fp >= (addr - 1) && fp < endstack && fp) | ||
758 | fp = (unsigned int *)*fp; | ||
759 | if (fp == 0 || fp == endstack) { | ||
760 | fp = addr - 1; | ||
761 | break; | ||
762 | } | ||
763 | fp = 0; | ||
764 | } | ||
622 | } | 765 | } |
766 | if (fp) { | ||
767 | frame = fp; | ||
768 | printk(" FP: (0x%p)\n", fp); | ||
769 | } else | ||
770 | frame = 0; | ||
623 | 771 | ||
624 | addr = (unsigned long)stack; | 772 | /* |
625 | endstack = (unsigned long *)PAGE_ALIGN(addr); | 773 | * Now that we think we know where things are, we |
774 | * walk the stack again, this time printing things out | ||
775 | * incase there is no frame pointer, we still look for | ||
776 | * valid return addresses | ||
777 | */ | ||
626 | 778 | ||
627 | printk(KERN_NOTICE "Stack from %08lx:", (unsigned long)stack); | 779 | /* First time print out data, next time, print out symbols */ |
628 | for (i = 0; i < kstack_depth_to_print; i++) { | 780 | for (j = 0; j <= 1; j++) { |
629 | if (stack + 1 > endstack) | 781 | if (j) |
630 | break; | 782 | printk(KERN_NOTICE "Return addresses in stack:\n"); |
631 | if (i % 8 == 0) | 783 | else |
632 | printk("\n" KERN_NOTICE " "); | 784 | printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); |
633 | printk(" %08lx", *stack++); | 785 | |
786 | fp = frame; | ||
787 | frame_no = 0; | ||
788 | |||
789 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; | ||
790 | addr <= endstack; addr++, i++) { | ||
791 | |||
792 | ret_addr = 0; | ||
793 | if (!j && i % 8 == 0) | ||
794 | printk("\n" KERN_NOTICE "%p:",addr); | ||
795 | |||
796 | /* if it is an odd address, or zero, just skip it */ | ||
797 | if (*addr & 0x1 || !*addr) | ||
798 | goto print; | ||
799 | |||
800 | ins_addr = (unsigned short *)*addr; | ||
801 | |||
802 | /* Go back one instruction, and see if it is a CALL */ | ||
803 | ins_addr--; | ||
804 | ret_addr = is_bfin_call(ins_addr); | ||
805 | print: | ||
806 | if (!j && stack == (unsigned long *)addr) | ||
807 | printk("[%08x]", *addr); | ||
808 | else if (ret_addr) | ||
809 | if (j) { | ||
810 | decode_address(buf, (unsigned int)*addr); | ||
811 | if (frame == addr) { | ||
812 | printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); | ||
813 | continue; | ||
814 | } | ||
815 | printk(KERN_NOTICE " address : %s\n", buf); | ||
816 | } else | ||
817 | printk("<%08x>", *addr); | ||
818 | else if (fp == addr) { | ||
819 | if (j) | ||
820 | frame = addr+1; | ||
821 | else | ||
822 | printk("(%08x)", *addr); | ||
823 | |||
824 | fp = (unsigned int *)*addr; | ||
825 | frame_no++; | ||
826 | |||
827 | } else if (!j) | ||
828 | printk(" %08x ", *addr); | ||
829 | } | ||
830 | if (!j) | ||
831 | printk("\n"); | ||
634 | } | 832 | } |
635 | printk("\n"); | ||
636 | 833 | ||
637 | show_trace(task, stack); | ||
638 | } | 834 | } |
639 | 835 | ||
640 | void dump_stack(void) | 836 | void dump_stack(void) |
@@ -715,19 +911,9 @@ void dump_bfin_mem(struct pt_regs *fp) | |||
715 | if (!((unsigned long)addr & 0xF)) | 911 | if (!((unsigned long)addr & 0xF)) |
716 | printk("\n" KERN_NOTICE "0x%p: ", addr); | 912 | printk("\n" KERN_NOTICE "0x%p: ", addr); |
717 | 913 | ||
718 | if (get_user(val, addr)) { | 914 | if (get_instruction(&val, addr)) { |
719 | if (addr >= (unsigned short *)L1_CODE_START && | ||
720 | addr < (unsigned short *)(L1_CODE_START + L1_CODE_LENGTH)) { | ||
721 | dma_memcpy(&val, addr, sizeof(val)); | ||
722 | sprintf(buf, "%04x", val); | ||
723 | } else if (addr >= (unsigned short *)FIXED_CODE_START && | ||
724 | addr <= (unsigned short *)memory_start) { | ||
725 | val = bfin_read16(addr); | ||
726 | sprintf(buf, "%04x", val); | ||
727 | } else { | ||
728 | val = 0; | 915 | val = 0; |
729 | sprintf(buf, "????"); | 916 | sprintf(buf, "????"); |
730 | } | ||
731 | } else | 917 | } else |
732 | sprintf(buf, "%04x", val); | 918 | sprintf(buf, "%04x", val); |
733 | 919 | ||
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 3ecc64cab3be..0896e38d6108 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S | |||
@@ -101,6 +101,11 @@ SECTIONS | |||
101 | #if !L1_DATA_B_LENGTH | 101 | #if !L1_DATA_B_LENGTH |
102 | *(.l1.data.B) | 102 | *(.l1.data.B) |
103 | #endif | 103 | #endif |
104 | #ifndef L2_LENGTH | ||
105 | . = ALIGN(32); | ||
106 | *(.data_l2.cacheline_aligned) | ||
107 | *(.l2.data) | ||
108 | #endif | ||
104 | 109 | ||
105 | DATA_DATA | 110 | DATA_DATA |
106 | *(.data.*) | 111 | *(.data.*) |
@@ -182,14 +187,13 @@ SECTIONS | |||
182 | *(.l1.data) | 187 | *(.l1.data) |
183 | __edata_l1 = .; | 188 | __edata_l1 = .; |
184 | 189 | ||
185 | . = ALIGN(4); | ||
186 | __sbss_l1 = .; | ||
187 | *(.l1.bss) | ||
188 | |||
189 | . = ALIGN(32); | 190 | . = ALIGN(32); |
190 | *(.data_l1.cacheline_aligned) | 191 | *(.data_l1.cacheline_aligned) |
191 | 192 | ||
192 | . = ALIGN(4); | 193 | . = ALIGN(4); |
194 | __sbss_l1 = .; | ||
195 | *(.l1.bss) | ||
196 | . = ALIGN(4); | ||
193 | __ebss_l1 = .; | 197 | __ebss_l1 = .; |
194 | } | 198 | } |
195 | 199 | ||
@@ -203,11 +207,37 @@ SECTIONS | |||
203 | . = ALIGN(4); | 207 | . = ALIGN(4); |
204 | __sbss_b_l1 = .; | 208 | __sbss_b_l1 = .; |
205 | *(.l1.bss.B) | 209 | *(.l1.bss.B) |
206 | |||
207 | . = ALIGN(4); | 210 | . = ALIGN(4); |
208 | __ebss_b_l1 = .; | 211 | __ebss_b_l1 = .; |
209 | } | 212 | } |
210 | 213 | ||
214 | #ifdef L2_LENGTH | ||
215 | __l2_lma_start = .; | ||
216 | |||
217 | .text_data_l2 L2_START : AT(LOADADDR(.data_b_l1) + SIZEOF(.data_b_l1)) | ||
218 | { | ||
219 | . = ALIGN(4); | ||
220 | __stext_l2 = .; | ||
221 | *(.l1.text) | ||
222 | . = ALIGN(4); | ||
223 | __etext_l2 = .; | ||
224 | |||
225 | . = ALIGN(4); | ||
226 | __sdata_l2 = .; | ||
227 | *(.l1.data) | ||
228 | __edata_l2 = .; | ||
229 | |||
230 | . = ALIGN(32); | ||
231 | *(.data_l2.cacheline_aligned) | ||
232 | |||
233 | . = ALIGN(4); | ||
234 | __sbss_l2 = .; | ||
235 | *(.l1.bss) | ||
236 | . = ALIGN(4); | ||
237 | __ebss_l2 = .; | ||
238 | } | ||
239 | #endif | ||
240 | |||
211 | /* Force trailing alignment of our init section so that when we | 241 | /* Force trailing alignment of our init section so that when we |
212 | * free our init memory, we don't leave behind a partial page. | 242 | * free our init memory, we don't leave behind a partial page. |
213 | */ | 243 | */ |