aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/microblaze/kernel
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/Makefile1
-rw-r--r--arch/microblaze/kernel/cpu/Makefile2
-rw-r--r--arch/microblaze/kernel/cpu/cache.c18
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo-static.c1
-rw-r--r--arch/microblaze/kernel/cpu/cpuinfo.c4
-rw-r--r--arch/microblaze/kernel/cpu/mb.c3
-rw-r--r--arch/microblaze/kernel/cpu/pvr.c4
-rw-r--r--arch/microblaze/kernel/dma.c1
-rw-r--r--arch/microblaze/kernel/early_printk.c87
-rw-r--r--arch/microblaze/kernel/entry-nommu.S4
-rw-r--r--arch/microblaze/kernel/entry.S368
-rw-r--r--arch/microblaze/kernel/exceptions.c30
-rw-r--r--arch/microblaze/kernel/ftrace.c10
-rw-r--r--arch/microblaze/kernel/head.S45
-rw-r--r--arch/microblaze/kernel/heartbeat.c11
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S61
-rw-r--r--arch/microblaze/kernel/intc.c73
-rw-r--r--arch/microblaze/kernel/irq.c40
-rw-r--r--arch/microblaze/kernel/kgdb.c7
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c44
-rw-r--r--arch/microblaze/kernel/process.c2
-rw-r--r--arch/microblaze/kernel/prom.c56
-rw-r--r--arch/microblaze/kernel/prom_parse.c115
-rw-r--r--arch/microblaze/kernel/ptrace.c8
-rw-r--r--arch/microblaze/kernel/setup.c22
-rw-r--r--arch/microblaze/kernel/signal.c8
-rw-r--r--arch/microblaze/kernel/sys_microblaze.c3
-rw-r--r--arch/microblaze/kernel/syscall_table.S8
-rw-r--r--arch/microblaze/kernel/timer.c47
-rw-r--r--arch/microblaze/kernel/unwind.c2
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S26
32 files changed, 556 insertions, 556 deletions
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index f0cb5c26c81c..494b63b72dd7 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -10,6 +10,7 @@ CFLAGS_REMOVE_early_printk.o = -pg
10CFLAGS_REMOVE_selfmod.o = -pg 10CFLAGS_REMOVE_selfmod.o = -pg
11CFLAGS_REMOVE_heartbeat.o = -pg 11CFLAGS_REMOVE_heartbeat.o = -pg
12CFLAGS_REMOVE_ftrace.o = -pg 12CFLAGS_REMOVE_ftrace.o = -pg
13CFLAGS_REMOVE_process.o = -pg
13endif 14endif
14 15
15extra-y := head.o vmlinux.lds 16extra-y := head.o vmlinux.lds
diff --git a/arch/microblaze/kernel/cpu/Makefile b/arch/microblaze/kernel/cpu/Makefile
index 59cc7bceaf8c..fceed4edea41 100644
--- a/arch/microblaze/kernel/cpu/Makefile
+++ b/arch/microblaze/kernel/cpu/Makefile
@@ -6,7 +6,7 @@ ifdef CONFIG_FUNCTION_TRACER
6CFLAGS_REMOVE_cache.o = -pg 6CFLAGS_REMOVE_cache.o = -pg
7endif 7endif
8 8
9EXTRA_CFLAGS += -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \ 9ccflags-y := -DCPU_MAJOR=$(CPU_MAJOR) -DCPU_MINOR=$(CPU_MINOR) \
10 -DCPU_REV=$(CPU_REV) 10 -DCPU_REV=$(CPU_REV)
11 11
12obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o 12obj-y += cache.o cpuinfo.o cpuinfo-pvr-full.o cpuinfo-static.o mb.o pvr.o
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index 109876e8d643..4b7d8a3f4aef 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -129,7 +129,7 @@ do { \
129 * to use for simple wdc or wic. 129 * to use for simple wdc or wic.
130 * 130 *
131 * start address is cache aligned 131 * start address is cache aligned
132 * end address is not aligned, if end is aligned then I have to substract 132 * end address is not aligned, if end is aligned then I have to subtract
133 * cacheline length because I can't flush/invalidate the next cacheline. 133 * cacheline length because I can't flush/invalidate the next cacheline.
134 * If is not, I align it because I will flush/invalidate whole line. 134 * If is not, I align it because I will flush/invalidate whole line.
135 */ 135 */
@@ -519,7 +519,7 @@ static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
519struct scache *mbc; 519struct scache *mbc;
520 520
521/* new wb cache model */ 521/* new wb cache model */
522const struct scache wb_msr = { 522static const struct scache wb_msr = {
523 .ie = __enable_icache_msr, 523 .ie = __enable_icache_msr,
524 .id = __disable_icache_msr, 524 .id = __disable_icache_msr,
525 .ifl = __flush_icache_all_noirq, 525 .ifl = __flush_icache_all_noirq,
@@ -535,7 +535,7 @@ const struct scache wb_msr = {
535}; 535};
536 536
537/* There is only difference in ie, id, de, dd functions */ 537/* There is only difference in ie, id, de, dd functions */
538const struct scache wb_nomsr = { 538static const struct scache wb_nomsr = {
539 .ie = __enable_icache_nomsr, 539 .ie = __enable_icache_nomsr,
540 .id = __disable_icache_nomsr, 540 .id = __disable_icache_nomsr,
541 .ifl = __flush_icache_all_noirq, 541 .ifl = __flush_icache_all_noirq,
@@ -551,7 +551,7 @@ const struct scache wb_nomsr = {
551}; 551};
552 552
553/* Old wt cache model with disabling irq and turn off cache */ 553/* Old wt cache model with disabling irq and turn off cache */
554const struct scache wt_msr = { 554static const struct scache wt_msr = {
555 .ie = __enable_icache_msr, 555 .ie = __enable_icache_msr,
556 .id = __disable_icache_msr, 556 .id = __disable_icache_msr,
557 .ifl = __flush_icache_all_msr_irq, 557 .ifl = __flush_icache_all_msr_irq,
@@ -566,7 +566,7 @@ const struct scache wt_msr = {
566 .dinr = __invalidate_dcache_range_msr_irq_wt, 566 .dinr = __invalidate_dcache_range_msr_irq_wt,
567}; 567};
568 568
569const struct scache wt_nomsr = { 569static const struct scache wt_nomsr = {
570 .ie = __enable_icache_nomsr, 570 .ie = __enable_icache_nomsr,
571 .id = __disable_icache_nomsr, 571 .id = __disable_icache_nomsr,
572 .ifl = __flush_icache_all_nomsr_irq, 572 .ifl = __flush_icache_all_nomsr_irq,
@@ -582,7 +582,7 @@ const struct scache wt_nomsr = {
582}; 582};
583 583
584/* New wt cache model for newer Microblaze versions */ 584/* New wt cache model for newer Microblaze versions */
585const struct scache wt_msr_noirq = { 585static const struct scache wt_msr_noirq = {
586 .ie = __enable_icache_msr, 586 .ie = __enable_icache_msr,
587 .id = __disable_icache_msr, 587 .id = __disable_icache_msr,
588 .ifl = __flush_icache_all_noirq, 588 .ifl = __flush_icache_all_noirq,
@@ -597,7 +597,7 @@ const struct scache wt_msr_noirq = {
597 .dinr = __invalidate_dcache_range_nomsr_wt, 597 .dinr = __invalidate_dcache_range_nomsr_wt,
598}; 598};
599 599
600const struct scache wt_nomsr_noirq = { 600static const struct scache wt_nomsr_noirq = {
601 .ie = __enable_icache_nomsr, 601 .ie = __enable_icache_nomsr,
602 .id = __disable_icache_nomsr, 602 .id = __disable_icache_nomsr,
603 .ifl = __flush_icache_all_noirq, 603 .ifl = __flush_icache_all_noirq,
@@ -624,7 +624,7 @@ void microblaze_cache_init(void)
624 if (cpuinfo.dcache_wb) { 624 if (cpuinfo.dcache_wb) {
625 INFO("wb_msr"); 625 INFO("wb_msr");
626 mbc = (struct scache *)&wb_msr; 626 mbc = (struct scache *)&wb_msr;
627 if (cpuinfo.ver_code < CPUVER_7_20_D) { 627 if (cpuinfo.ver_code <= CPUVER_7_20_D) {
628 /* MS: problem with signal handling - hw bug */ 628 /* MS: problem with signal handling - hw bug */
629 INFO("WB won't work properly"); 629 INFO("WB won't work properly");
630 } 630 }
@@ -641,7 +641,7 @@ void microblaze_cache_init(void)
641 if (cpuinfo.dcache_wb) { 641 if (cpuinfo.dcache_wb) {
642 INFO("wb_nomsr"); 642 INFO("wb_nomsr");
643 mbc = (struct scache *)&wb_nomsr; 643 mbc = (struct scache *)&wb_nomsr;
644 if (cpuinfo.ver_code < CPUVER_7_20_D) { 644 if (cpuinfo.ver_code <= CPUVER_7_20_D) {
645 /* MS: problem with signal handling - hw bug */ 645 /* MS: problem with signal handling - hw bug */
646 INFO("WB won't work properly"); 646 INFO("WB won't work properly");
647 } 647 }
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
index f72dbd66c844..f70a6047f08e 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-pvr-full.c
@@ -72,6 +72,7 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu)
72 CI(pvr_user2, USER2); 72 CI(pvr_user2, USER2);
73 73
74 CI(mmu, USE_MMU); 74 CI(mmu, USE_MMU);
75 CI(endian, ENDIAN);
75 76
76 CI(use_icache, USE_ICACHE); 77 CI(use_icache, USE_ICACHE);
77 CI(icache_tagbits, ICACHE_ADDR_TAG_BITS); 78 CI(icache_tagbits, ICACHE_ADDR_TAG_BITS);
diff --git a/arch/microblaze/kernel/cpu/cpuinfo-static.c b/arch/microblaze/kernel/cpu/cpuinfo-static.c
index 6095aa6b5c88..b16b994ca3d2 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo-static.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo-static.c
@@ -119,6 +119,7 @@ void __init set_cpuinfo_static(struct cpuinfo *ci, struct device_node *cpu)
119 ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2"); 119 ci->pvr_user2 = fcpu(cpu, "xlnx,pvr-user2");
120 120
121 ci->mmu = fcpu(cpu, "xlnx,use-mmu"); 121 ci->mmu = fcpu(cpu, "xlnx,use-mmu");
122 ci->endian = fcpu(cpu, "xlnx,endianness");
122 123
123 ci->ver_code = 0; 124 ci->ver_code = 0;
124 ci->fpga_family_code = 0; 125 ci->fpga_family_code = 0;
diff --git a/arch/microblaze/kernel/cpu/cpuinfo.c b/arch/microblaze/kernel/cpu/cpuinfo.c
index 255ef880351e..c1640c52711f 100644
--- a/arch/microblaze/kernel/cpu/cpuinfo.c
+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
@@ -30,6 +30,10 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
30 {"7.20.c", 0x0e}, 30 {"7.20.c", 0x0e},
31 {"7.20.d", 0x0f}, 31 {"7.20.d", 0x0f},
32 {"7.30.a", 0x10}, 32 {"7.30.a", 0x10},
33 {"7.30.b", 0x11},
34 {"8.00.a", 0x12},
35 {"8.00.b", 0x13},
36 {"8.10.a", 0x14},
33 {NULL, 0}, 37 {NULL, 0},
34}; 38};
35 39
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
index 7086e3564281..b4048af02615 100644
--- a/arch/microblaze/kernel/cpu/mb.c
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -51,11 +51,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
51 count = seq_printf(m, 51 count = seq_printf(m,
52 "CPU-Family: MicroBlaze\n" 52 "CPU-Family: MicroBlaze\n"
53 "FPGA-Arch: %s\n" 53 "FPGA-Arch: %s\n"
54 "CPU-Ver: %s\n" 54 "CPU-Ver: %s, %s endian\n"
55 "CPU-MHz: %d.%02d\n" 55 "CPU-MHz: %d.%02d\n"
56 "BogoMips: %lu.%02lu\n", 56 "BogoMips: %lu.%02lu\n",
57 fpga_family, 57 fpga_family,
58 cpu_ver, 58 cpu_ver,
59 cpuinfo.endian ? "little" : "big",
59 cpuinfo.cpu_clock_freq / 60 cpuinfo.cpu_clock_freq /
60 1000000, 61 1000000,
61 cpuinfo.cpu_clock_freq % 62 cpuinfo.cpu_clock_freq %
diff --git a/arch/microblaze/kernel/cpu/pvr.c b/arch/microblaze/kernel/cpu/pvr.c
index 9bee9382bf74..488c1ed24e38 100644
--- a/arch/microblaze/kernel/cpu/pvr.c
+++ b/arch/microblaze/kernel/cpu/pvr.c
@@ -27,7 +27,7 @@
27 register unsigned tmp __asm__("r3"); \ 27 register unsigned tmp __asm__("r3"); \
28 tmp = 0x0; /* Prevent warning about unused */ \ 28 tmp = 0x0; /* Prevent warning about unused */ \
29 __asm__ __volatile__ ( \ 29 __asm__ __volatile__ ( \
30 ".byte 0x94,0x60,0xa0, " #pvrid "\n\t" \ 30 "mfs %0, rpvr" #pvrid ";" \
31 : "=r" (tmp) : : "memory"); \ 31 : "=r" (tmp) : : "memory"); \
32 val = tmp; \ 32 val = tmp; \
33} 33}
@@ -54,7 +54,7 @@ int cpu_has_pvr(void)
54 if (!(flags & PVR_MSR_BIT)) 54 if (!(flags & PVR_MSR_BIT))
55 return 0; 55 return 0;
56 56
57 get_single_pvr(0x00, pvr0); 57 get_single_pvr(0, pvr0);
58 pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0); 58 pr_debug("%s: pvr0 is 0x%08x\n", __func__, pvr0);
59 59
60 if (pvr0 & PVR0_PVR_FULL_MASK) 60 if (pvr0 & PVR0_PVR_FULL_MASK)
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index 79c74659f204..393e6b2db688 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -26,6 +26,7 @@ static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
26{ 26{
27 switch (direction) { 27 switch (direction) {
28 case DMA_TO_DEVICE: 28 case DMA_TO_DEVICE:
29 case DMA_BIDIRECTIONAL:
29 flush_dcache_range(paddr + offset, paddr + offset + size); 30 flush_dcache_range(paddr + offset, paddr + offset + size);
30 break; 31 break;
31 case DMA_FROM_DEVICE: 32 case DMA_FROM_DEVICE:
diff --git a/arch/microblaze/kernel/early_printk.c b/arch/microblaze/kernel/early_printk.c
index 7de84923ba07..c3616a080ebf 100644
--- a/arch/microblaze/kernel/early_printk.c
+++ b/arch/microblaze/kernel/early_printk.c
@@ -24,7 +24,8 @@
24static u32 early_console_initialized; 24static u32 early_console_initialized;
25static u32 base_addr; 25static u32 base_addr;
26 26
27static void early_printk_putc(char c) 27#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
28static void early_printk_uartlite_putc(char c)
28{ 29{
29 /* 30 /*
30 * Limit how many times we'll spin waiting for TX FIFO status. 31 * Limit how many times we'll spin waiting for TX FIFO status.
@@ -45,25 +46,70 @@ static void early_printk_putc(char c)
45 out_be32(base_addr + 4, c & 0xff); 46 out_be32(base_addr + 4, c & 0xff);
46} 47}
47 48
48static void early_printk_write(struct console *unused, 49static void early_printk_uartlite_write(struct console *unused,
49 const char *s, unsigned n) 50 const char *s, unsigned n)
50{ 51{
51 while (*s && n-- > 0) { 52 while (*s && n-- > 0) {
52 early_printk_putc(*s); 53 early_printk_uartlite_putc(*s);
53 if (*s == '\n') 54 if (*s == '\n')
54 early_printk_putc('\r'); 55 early_printk_uartlite_putc('\r');
55 s++; 56 s++;
56 } 57 }
57} 58}
58 59
59static struct console early_serial_console = { 60static struct console early_serial_uartlite_console = {
60 .name = "earlyser", 61 .name = "earlyser",
61 .write = early_printk_write, 62 .write = early_printk_uartlite_write,
62 .flags = CON_PRINTBUFFER, 63 .flags = CON_PRINTBUFFER,
63 .index = -1, 64 .index = -1,
64}; 65};
66#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
65 67
66static struct console *early_console = &early_serial_console; 68#ifdef CONFIG_SERIAL_8250_CONSOLE
69static void early_printk_uart16550_putc(char c)
70{
71 /*
72 * Limit how many times we'll spin waiting for TX FIFO status.
73 * This will prevent lockups if the base address is incorrectly
74 * set, or any other issue on the UARTLITE.
75 * This limit is pretty arbitrary, unless we are at about 10 baud
76 * we'll never timeout on a working UART.
77 */
78
79 #define UART_LSR_TEMT 0x40 /* Transmitter empty */
80 #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
81 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
82
83 unsigned retries = 10000;
84
85 while (--retries &&
86 !((in_be32(base_addr + 0x14) & BOTH_EMPTY) == BOTH_EMPTY))
87 ;
88
89 if (retries)
90 out_be32(base_addr, c & 0xff);
91}
92
93static void early_printk_uart16550_write(struct console *unused,
94 const char *s, unsigned n)
95{
96 while (*s && n-- > 0) {
97 early_printk_uart16550_putc(*s);
98 if (*s == '\n')
99 early_printk_uart16550_putc('\r');
100 s++;
101 }
102}
103
104static struct console early_serial_uart16550_console = {
105 .name = "earlyser",
106 .write = early_printk_uart16550_write,
107 .flags = CON_PRINTBUFFER,
108 .index = -1,
109};
110#endif /* CONFIG_SERIAL_8250_CONSOLE */
111
112static struct console *early_console;
67 113
68void early_printk(const char *fmt, ...) 114void early_printk(const char *fmt, ...)
69{ 115{
@@ -84,20 +130,43 @@ int __init setup_early_printk(char *opt)
84 if (early_console_initialized) 130 if (early_console_initialized)
85 return 1; 131 return 1;
86 132
133#ifdef CONFIG_SERIAL_UARTLITE_CONSOLE
87 base_addr = early_uartlite_console(); 134 base_addr = early_uartlite_console();
88 if (base_addr) { 135 if (base_addr) {
89 early_console_initialized = 1; 136 early_console_initialized = 1;
90#ifdef CONFIG_MMU 137#ifdef CONFIG_MMU
91 early_console_reg_tlb_alloc(base_addr); 138 early_console_reg_tlb_alloc(base_addr);
92#endif 139#endif
140 early_console = &early_serial_uartlite_console;
93 early_printk("early_printk_console is enabled at 0x%08x\n", 141 early_printk("early_printk_console is enabled at 0x%08x\n",
94 base_addr); 142 base_addr);
95 143
96 /* register_console(early_console); */ 144 /* register_console(early_console); */
97 145
98 return 0; 146 return 0;
99 } else 147 }
100 return 1; 148#endif /* CONFIG_SERIAL_UARTLITE_CONSOLE */
149
150#ifdef CONFIG_SERIAL_8250_CONSOLE
151 base_addr = early_uart16550_console();
152 base_addr &= ~3; /* clear register offset */
153 if (base_addr) {
154 early_console_initialized = 1;
155#ifdef CONFIG_MMU
156 early_console_reg_tlb_alloc(base_addr);
157#endif
158 early_console = &early_serial_uart16550_console;
159
160 early_printk("early_printk_console is enabled at 0x%08x\n",
161 base_addr);
162
163 /* register_console(early_console); */
164
165 return 0;
166 }
167#endif /* CONFIG_SERIAL_8250_CONSOLE */
168
169 return 1;
101} 170}
102 171
103void __init disable_early_printk(void) 172void __init disable_early_printk(void)
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index ca84368570b6..34b526f59b43 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -115,7 +115,7 @@ ENTRY(_interrupt)
115 /* restore r31 */ 115 /* restore r31 */
116 lwi r31, r0, PER_CPU(CURRENT_SAVE) 116 lwi r31, r0, PER_CPU(CURRENT_SAVE)
117 /* prepare the link register, the argument and jump */ 117 /* prepare the link register, the argument and jump */
118 la r15, r0, ret_from_intr - 8 118 addik r15, r0, ret_from_intr - 8
119 addk r6, r0, r15 119 addk r6, r0, r15
120 braid do_IRQ 120 braid do_IRQ
121 add r5, r0, r1 121 add r5, r0, r1
@@ -283,7 +283,7 @@ ENTRY(_user_exception)
283 add r12, r12, r12 /* convert num -> ptr */ 283 add r12, r12, r12 /* convert num -> ptr */
284 add r12, r12, r12 284 add r12, r12, r12
285 lwi r12, r12, sys_call_table /* Get function pointer */ 285 lwi r12, r12, sys_call_table /* Get function pointer */
286 la r15, r0, ret_to_user-8 /* set return address */ 286 addik r15, r0, ret_to_user-8 /* set return address */
287 bra r12 /* Make the system call. */ 287 bra r12 /* Make the system call. */
288 bri 0 /* won't reach here */ 288 bri 0 /* won't reach here */
2891: 2891:
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index 304882e56459..ca15bc5c7449 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -33,11 +33,14 @@
33 33
34#undef DEBUG 34#undef DEBUG
35 35
36/* The size of a state save frame. */ 36#ifdef DEBUG
37#define STATE_SAVE_SIZE (PT_SIZE + STATE_SAVE_ARG_SPACE) 37/* Create space for syscalls counting. */
38 38.section .data
39/* The offset of the struct pt_regs in a `state save frame' on the stack. */ 39.global syscall_debug_table
40#define PTO STATE_SAVE_ARG_SPACE /* 24 the space for args */ 40.align 4
41syscall_debug_table:
42 .space (__NR_syscalls * 4)
43#endif /* DEBUG */
41 44
42#define C_ENTRY(name) .globl name; .align 4; name 45#define C_ENTRY(name) .globl name; .align 4; name
43 46
@@ -172,68 +175,72 @@
1721: 1751:
173 176
174#define SAVE_REGS \ 177#define SAVE_REGS \
175 swi r2, r1, PTO+PT_R2; /* Save SDA */ \ 178 swi r2, r1, PT_R2; /* Save SDA */ \
176 swi r3, r1, PTO+PT_R3; \ 179 swi r3, r1, PT_R3; \
177 swi r4, r1, PTO+PT_R4; \ 180 swi r4, r1, PT_R4; \
178 swi r5, r1, PTO+PT_R5; \ 181 swi r5, r1, PT_R5; \
179 swi r6, r1, PTO+PT_R6; \ 182 swi r6, r1, PT_R6; \
180 swi r7, r1, PTO+PT_R7; \ 183 swi r7, r1, PT_R7; \
181 swi r8, r1, PTO+PT_R8; \ 184 swi r8, r1, PT_R8; \
182 swi r9, r1, PTO+PT_R9; \ 185 swi r9, r1, PT_R9; \
183 swi r10, r1, PTO+PT_R10; \ 186 swi r10, r1, PT_R10; \
184 swi r11, r1, PTO+PT_R11; /* save clobbered regs after rval */\ 187 swi r11, r1, PT_R11; /* save clobbered regs after rval */\
185 swi r12, r1, PTO+PT_R12; \ 188 swi r12, r1, PT_R12; \
186 swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \ 189 swi r13, r1, PT_R13; /* Save SDA2 */ \
187 swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \ 190 swi r14, r1, PT_PC; /* PC, before IRQ/trap */ \
188 swi r15, r1, PTO+PT_R15; /* Save LP */ \ 191 swi r15, r1, PT_R15; /* Save LP */ \
189 swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \ 192 swi r16, r1, PT_R16; \
190 swi r19, r1, PTO+PT_R19; \ 193 swi r17, r1, PT_R17; \
191 swi r20, r1, PTO+PT_R20; \ 194 swi r18, r1, PT_R18; /* Save asm scratch reg */ \
192 swi r21, r1, PTO+PT_R21; \ 195 swi r19, r1, PT_R19; \
193 swi r22, r1, PTO+PT_R22; \ 196 swi r20, r1, PT_R20; \
194 swi r23, r1, PTO+PT_R23; \ 197 swi r21, r1, PT_R21; \
195 swi r24, r1, PTO+PT_R24; \ 198 swi r22, r1, PT_R22; \
196 swi r25, r1, PTO+PT_R25; \ 199 swi r23, r1, PT_R23; \
197 swi r26, r1, PTO+PT_R26; \ 200 swi r24, r1, PT_R24; \
198 swi r27, r1, PTO+PT_R27; \ 201 swi r25, r1, PT_R25; \
199 swi r28, r1, PTO+PT_R28; \ 202 swi r26, r1, PT_R26; \
200 swi r29, r1, PTO+PT_R29; \ 203 swi r27, r1, PT_R27; \
201 swi r30, r1, PTO+PT_R30; \ 204 swi r28, r1, PT_R28; \
202 swi r31, r1, PTO+PT_R31; /* Save current task reg */ \ 205 swi r29, r1, PT_R29; \
206 swi r30, r1, PT_R30; \
207 swi r31, r1, PT_R31; /* Save current task reg */ \
203 mfs r11, rmsr; /* save MSR */ \ 208 mfs r11, rmsr; /* save MSR */ \
204 swi r11, r1, PTO+PT_MSR; 209 swi r11, r1, PT_MSR;
205 210
206#define RESTORE_REGS \ 211#define RESTORE_REGS \
207 lwi r11, r1, PTO+PT_MSR; \ 212 lwi r11, r1, PT_MSR; \
208 mts rmsr , r11; \ 213 mts rmsr , r11; \
209 lwi r2, r1, PTO+PT_R2; /* restore SDA */ \ 214 lwi r2, r1, PT_R2; /* restore SDA */ \
210 lwi r3, r1, PTO+PT_R3; \ 215 lwi r3, r1, PT_R3; \
211 lwi r4, r1, PTO+PT_R4; \ 216 lwi r4, r1, PT_R4; \
212 lwi r5, r1, PTO+PT_R5; \ 217 lwi r5, r1, PT_R5; \
213 lwi r6, r1, PTO+PT_R6; \ 218 lwi r6, r1, PT_R6; \
214 lwi r7, r1, PTO+PT_R7; \ 219 lwi r7, r1, PT_R7; \
215 lwi r8, r1, PTO+PT_R8; \ 220 lwi r8, r1, PT_R8; \
216 lwi r9, r1, PTO+PT_R9; \ 221 lwi r9, r1, PT_R9; \
217 lwi r10, r1, PTO+PT_R10; \ 222 lwi r10, r1, PT_R10; \
218 lwi r11, r1, PTO+PT_R11; /* restore clobbered regs after rval */\ 223 lwi r11, r1, PT_R11; /* restore clobbered regs after rval */\
219 lwi r12, r1, PTO+PT_R12; \ 224 lwi r12, r1, PT_R12; \
220 lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \ 225 lwi r13, r1, PT_R13; /* restore SDA2 */ \
221 lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\ 226 lwi r14, r1, PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
222 lwi r15, r1, PTO+PT_R15; /* restore LP */ \ 227 lwi r15, r1, PT_R15; /* restore LP */ \
223 lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \ 228 lwi r16, r1, PT_R16; \
224 lwi r19, r1, PTO+PT_R19; \ 229 lwi r17, r1, PT_R17; \
225 lwi r20, r1, PTO+PT_R20; \ 230 lwi r18, r1, PT_R18; /* restore asm scratch reg */ \
226 lwi r21, r1, PTO+PT_R21; \ 231 lwi r19, r1, PT_R19; \
227 lwi r22, r1, PTO+PT_R22; \ 232 lwi r20, r1, PT_R20; \
228 lwi r23, r1, PTO+PT_R23; \ 233 lwi r21, r1, PT_R21; \
229 lwi r24, r1, PTO+PT_R24; \ 234 lwi r22, r1, PT_R22; \
230 lwi r25, r1, PTO+PT_R25; \ 235 lwi r23, r1, PT_R23; \
231 lwi r26, r1, PTO+PT_R26; \ 236 lwi r24, r1, PT_R24; \
232 lwi r27, r1, PTO+PT_R27; \ 237 lwi r25, r1, PT_R25; \
233 lwi r28, r1, PTO+PT_R28; \ 238 lwi r26, r1, PT_R26; \
234 lwi r29, r1, PTO+PT_R29; \ 239 lwi r27, r1, PT_R27; \
235 lwi r30, r1, PTO+PT_R30; \ 240 lwi r28, r1, PT_R28; \
236 lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */ 241 lwi r29, r1, PT_R29; \
242 lwi r30, r1, PT_R30; \
243 lwi r31, r1, PT_R31; /* Restore cur task reg */
237 244
238#define SAVE_STATE \ 245#define SAVE_STATE \
239 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \ 246 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
@@ -246,11 +253,11 @@
246 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ 253 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
247 /* FIXME: I can add these two lines to one */ \ 254 /* FIXME: I can add these two lines to one */ \
248 /* tophys(r1,r1); */ \ 255 /* tophys(r1,r1); */ \
249 /* addik r1, r1, -STATE_SAVE_SIZE; */ \ 256 /* addik r1, r1, -PT_SIZE; */ \
250 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ 257 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
251 SAVE_REGS \ 258 SAVE_REGS \
252 brid 2f; \ 259 brid 2f; \
253 swi r1, r1, PTO+PT_MODE; \ 260 swi r1, r1, PT_MODE; \
2541: /* User-mode state save. */ \ 2611: /* User-mode state save. */ \
255 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\ 262 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
256 tophys(r1,r1); \ 263 tophys(r1,r1); \
@@ -258,12 +265,12 @@
258 /* MS these three instructions can be added to one */ \ 265 /* MS these three instructions can be added to one */ \
259 /* addik r1, r1, THREAD_SIZE; */ \ 266 /* addik r1, r1, THREAD_SIZE; */ \
260 /* tophys(r1,r1); */ \ 267 /* tophys(r1,r1); */ \
261 /* addik r1, r1, -STATE_SAVE_SIZE; */ \ 268 /* addik r1, r1, -PT_SIZE; */ \
262 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \ 269 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
263 SAVE_REGS \ 270 SAVE_REGS \
264 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \ 271 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
265 swi r11, r1, PTO+PT_R1; /* Store user SP. */ \ 272 swi r11, r1, PT_R1; /* Store user SP. */ \
266 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ \ 273 swi r0, r1, PT_MODE; /* Was in user-mode. */ \
267 /* MS: I am clearing UMS even in case when I come from kernel space */ \ 274 /* MS: I am clearing UMS even in case when I come from kernel space */ \
268 clear_ums; \ 275 clear_ums; \
2692: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 2762: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
@@ -283,25 +290,46 @@
283 * are masked. This is nice, means we don't have to CLI before state save 290 * are masked. This is nice, means we don't have to CLI before state save
284 */ 291 */
285C_ENTRY(_user_exception): 292C_ENTRY(_user_exception):
286 addi r14, r14, 4 /* return address is 4 byte after call */
287 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ 293 swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */
294 addi r14, r14, 4 /* return address is 4 byte after call */
295
296 mfs r1, rmsr
297 nop
298 andi r1, r1, MSR_UMS
299 bnei r1, 1f
288 300
301/* Kernel-mode state save - kernel execve */
302 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
303 tophys(r1,r1);
304
305 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
306 SAVE_REGS
307
308 swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
309 brid 2f;
310 nop; /* Fill delay slot */
311
312/* User-mode state save. */
3131:
289 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ 314 lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */
290 tophys(r1,r1); 315 tophys(r1,r1);
291 lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ 316 lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */
292 /* MS these three instructions can be added to one */ 317/* calculate kernel stack pointer from task struct 8k */
293 /* addik r1, r1, THREAD_SIZE; */ 318 addik r1, r1, THREAD_SIZE;
294 /* tophys(r1,r1); */ 319 tophys(r1,r1);
295 /* addik r1, r1, -STATE_SAVE_SIZE; */ 320
296 addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 321 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
297 SAVE_REGS 322 SAVE_REGS
323 swi r0, r1, PT_R3
324 swi r0, r1, PT_R4
298 325
326 swi r0, r1, PT_MODE; /* Was in user-mode. */
299 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 327 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
300 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 328 swi r11, r1, PT_R1; /* Store user SP. */
301 clear_ums; 329 clear_ums;
302 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 3302: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
303 /* Save away the syscall number. */ 331 /* Save away the syscall number. */
304 swi r12, r1, PTO+PT_R0; 332 swi r12, r1, PT_R0;
305 tovirt(r1,r1) 333 tovirt(r1,r1)
306 334
307/* where the trap should return need -8 to adjust for rtsd r15, 8*/ 335/* where the trap should return need -8 to adjust for rtsd r15, 8*/
@@ -320,18 +348,18 @@ C_ENTRY(_user_exception):
320 beqi r11, 4f 348 beqi r11, 4f
321 349
322 addik r3, r0, -ENOSYS 350 addik r3, r0, -ENOSYS
323 swi r3, r1, PTO + PT_R3 351 swi r3, r1, PT_R3
324 brlid r15, do_syscall_trace_enter 352 brlid r15, do_syscall_trace_enter
325 addik r5, r1, PTO + PT_R0 353 addik r5, r1, PT_R0
326 354
327 # do_syscall_trace_enter returns the new syscall nr. 355 # do_syscall_trace_enter returns the new syscall nr.
328 addk r12, r0, r3 356 addk r12, r0, r3
329 lwi r5, r1, PTO+PT_R5; 357 lwi r5, r1, PT_R5;
330 lwi r6, r1, PTO+PT_R6; 358 lwi r6, r1, PT_R6;
331 lwi r7, r1, PTO+PT_R7; 359 lwi r7, r1, PT_R7;
332 lwi r8, r1, PTO+PT_R8; 360 lwi r8, r1, PT_R8;
333 lwi r9, r1, PTO+PT_R9; 361 lwi r9, r1, PT_R9;
334 lwi r10, r1, PTO+PT_R10; 362 lwi r10, r1, PT_R10;
3354: 3634:
336/* Jump to the appropriate function for the system call number in r12 364/* Jump to the appropriate function for the system call number in r12
337 * (r12 is not preserved), or return an error if r12 is not valid. 365 * (r12 is not preserved), or return an error if r12 is not valid.
@@ -346,10 +374,14 @@ C_ENTRY(_user_exception):
346 add r12, r12, r12; 374 add r12, r12, r12;
347 375
348#ifdef DEBUG 376#ifdef DEBUG
349 /* Trac syscalls and stored them to r0_ram */ 377 /* Trac syscalls and stored them to syscall_debug_table */
350 lwi r3, r12, 0x400 + r0_ram 378 /* The first syscall location stores total syscall number */
379 lwi r3, r0, syscall_debug_table
380 addi r3, r3, 1
381 swi r3, r0, syscall_debug_table
382 lwi r3, r12, syscall_debug_table
351 addi r3, r3, 1 383 addi r3, r3, 1
352 swi r3, r12, 0x400 + r0_ram 384 swi r3, r12, syscall_debug_table
353#endif 385#endif
354 386
355 # Find and jump into the syscall handler. 387 # Find and jump into the syscall handler.
@@ -366,9 +398,12 @@ C_ENTRY(_user_exception):
366/* Entry point used to return from a syscall/trap */ 398/* Entry point used to return from a syscall/trap */
367/* We re-enable BIP bit before state restore */ 399/* We re-enable BIP bit before state restore */
368C_ENTRY(ret_from_trap): 400C_ENTRY(ret_from_trap):
369 swi r3, r1, PTO + PT_R3 401 swi r3, r1, PT_R3
370 swi r4, r1, PTO + PT_R4 402 swi r4, r1, PT_R4
371 403
404 lwi r11, r1, PT_MODE;
405/* See if returning to kernel mode, if so, skip resched &c. */
406 bnei r11, 2f;
372 /* We're returning to user mode, so check for various conditions that 407 /* We're returning to user mode, so check for various conditions that
373 * trigger rescheduling. */ 408 * trigger rescheduling. */
374 /* FIXME: Restructure all these flag checks. */ 409 /* FIXME: Restructure all these flag checks. */
@@ -378,7 +413,7 @@ C_ENTRY(ret_from_trap):
378 beqi r11, 1f 413 beqi r11, 1f
379 414
380 brlid r15, do_syscall_trace_leave 415 brlid r15, do_syscall_trace_leave
381 addik r5, r1, PTO + PT_R0 416 addik r5, r1, PT_R0
3821: 4171:
383 /* We're returning to user mode, so check for various conditions that 418 /* We're returning to user mode, so check for various conditions that
384 * trigger rescheduling. */ 419 * trigger rescheduling. */
@@ -398,7 +433,7 @@ C_ENTRY(ret_from_trap):
398 andi r11, r11, _TIF_SIGPENDING; 433 andi r11, r11, _TIF_SIGPENDING;
399 beqi r11, 1f; /* Signals to handle, handle them */ 434 beqi r11, 1f; /* Signals to handle, handle them */
400 435
401 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 436 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
402 addi r7, r0, 1; /* Arg 3: int in_syscall */ 437 addi r7, r0, 1; /* Arg 3: int in_syscall */
403 bralid r15, do_signal; /* Handle any signals */ 438 bralid r15, do_signal; /* Handle any signals */
404 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 439 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -409,8 +444,18 @@ C_ENTRY(ret_from_trap):
409 VM_OFF; 444 VM_OFF;
410 tophys(r1,r1); 445 tophys(r1,r1);
411 RESTORE_REGS; 446 RESTORE_REGS;
412 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 447 addik r1, r1, PT_SIZE /* Clean up stack space. */
413 lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */ 448 lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */
449 bri 6f;
450
451/* Return to kernel state. */
4522: set_bip; /* Ints masked for state restore */
453 VM_OFF;
454 tophys(r1,r1);
455 RESTORE_REGS;
456 addik r1, r1, PT_SIZE /* Clean up stack space. */
457 tovirt(r1,r1);
4586:
414TRAP_return: /* Make global symbol for debugging */ 459TRAP_return: /* Make global symbol for debugging */
415 rtbd r14, 0; /* Instructions to return from an IRQ */ 460 rtbd r14, 0; /* Instructions to return from an IRQ */
416 nop; 461 nop;
@@ -421,8 +466,8 @@ TRAP_return: /* Make global symbol for debugging */
421 466
422C_ENTRY(sys_fork_wrapper): 467C_ENTRY(sys_fork_wrapper):
423 addi r5, r0, SIGCHLD /* Arg 0: flags */ 468 addi r5, r0, SIGCHLD /* Arg 0: flags */
424 lwi r6, r1, PTO+PT_R1 /* Arg 1: child SP (use parent's) */ 469 lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
425 addik r7, r1, PTO /* Arg 2: parent context */ 470 addik r7, r1, 0 /* Arg 2: parent context */
426 add r8. r0, r0 /* Arg 3: (unused) */ 471 add r8. r0, r0 /* Arg 3: (unused) */
427 add r9, r0, r0; /* Arg 4: (unused) */ 472 add r9, r0, r0; /* Arg 4: (unused) */
428 brid do_fork /* Do real work (tail-call) */ 473 brid do_fork /* Do real work (tail-call) */
@@ -442,12 +487,12 @@ C_ENTRY(ret_from_fork):
442 487
443C_ENTRY(sys_vfork): 488C_ENTRY(sys_vfork):
444 brid microblaze_vfork /* Do real work (tail-call) */ 489 brid microblaze_vfork /* Do real work (tail-call) */
445 addik r5, r1, PTO 490 addik r5, r1, 0
446 491
447C_ENTRY(sys_clone): 492C_ENTRY(sys_clone):
448 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */ 493 bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
449 lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */ 494 lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
4501: addik r7, r1, PTO; /* Arg 2: parent context */ 4951: addik r7, r1, 0; /* Arg 2: parent context */
451 add r8, r0, r0; /* Arg 3: (unused) */ 496 add r8, r0, r0; /* Arg 3: (unused) */
452 add r9, r0, r0; /* Arg 4: (unused) */ 497 add r9, r0, r0; /* Arg 4: (unused) */
453 brid do_fork /* Do real work (tail-call) */ 498 brid do_fork /* Do real work (tail-call) */
@@ -455,17 +500,11 @@ C_ENTRY(sys_clone):
455 500
456C_ENTRY(sys_execve): 501C_ENTRY(sys_execve):
457 brid microblaze_execve; /* Do real work (tail-call).*/ 502 brid microblaze_execve; /* Do real work (tail-call).*/
458 addik r8, r1, PTO; /* add user context as 4th arg */ 503 addik r8, r1, 0; /* add user context as 4th arg */
459 504
460C_ENTRY(sys_rt_sigreturn_wrapper): 505C_ENTRY(sys_rt_sigreturn_wrapper):
461 swi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */ 506 brid sys_rt_sigreturn /* Do real work */
462 swi r4, r1, PTO+PT_R4; 507 addik r5, r1, 0; /* add user context as 1st arg */
463 brlid r15, sys_rt_sigreturn /* Do real work */
464 addik r5, r1, PTO; /* add user context as 1st arg */
465 lwi r3, r1, PTO+PT_R3; /* restore saved r3, r4 registers */
466 lwi r4, r1, PTO+PT_R4;
467 bri ret_from_trap /* fall through will not work here due to align */
468 nop;
469 508
470/* 509/*
471 * HW EXCEPTION rutine start 510 * HW EXCEPTION rutine start
@@ -476,7 +515,7 @@ C_ENTRY(full_exception_trap):
476 addik r17, r17, -4 515 addik r17, r17, -4
477 SAVE_STATE /* Save registers */ 516 SAVE_STATE /* Save registers */
478 /* PC, before IRQ/trap - this is one instruction above */ 517 /* PC, before IRQ/trap - this is one instruction above */
479 swi r17, r1, PTO+PT_PC; 518 swi r17, r1, PT_PC;
480 tovirt(r1,r1) 519 tovirt(r1,r1)
481 /* FIXME this can be store directly in PT_ESR reg. 520 /* FIXME this can be store directly in PT_ESR reg.
482 * I tested it but there is a fault */ 521 * I tested it but there is a fault */
@@ -486,7 +525,7 @@ C_ENTRY(full_exception_trap):
486 mfs r7, rfsr; /* save FSR */ 525 mfs r7, rfsr; /* save FSR */
487 mts rfsr, r0; /* Clear sticky fsr */ 526 mts rfsr, r0; /* Clear sticky fsr */
488 rted r0, full_exception 527 rted r0, full_exception
489 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 528 addik r5, r1, 0 /* parameter struct pt_regs * regs */
490 529
491/* 530/*
492 * Unaligned data trap. 531 * Unaligned data trap.
@@ -512,14 +551,14 @@ C_ENTRY(unaligned_data_trap):
512 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 551 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
513 SAVE_STATE /* Save registers.*/ 552 SAVE_STATE /* Save registers.*/
514 /* PC, before IRQ/trap - this is one instruction above */ 553 /* PC, before IRQ/trap - this is one instruction above */
515 swi r17, r1, PTO+PT_PC; 554 swi r17, r1, PT_PC;
516 tovirt(r1,r1) 555 tovirt(r1,r1)
517 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 556 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
518 addik r15, r0, ret_from_exc-8 557 addik r15, r0, ret_from_exc-8
519 mfs r3, resr /* ESR */ 558 mfs r3, resr /* ESR */
520 mfs r4, rear /* EAR */ 559 mfs r4, rear /* EAR */
521 rtbd r0, _unaligned_data_exception 560 rtbd r0, _unaligned_data_exception
522 addik r7, r1, PTO /* parameter struct pt_regs * regs */ 561 addik r7, r1, 0 /* parameter struct pt_regs * regs */
523 562
524/* 563/*
525 * Page fault traps. 564 * Page fault traps.
@@ -542,30 +581,30 @@ C_ENTRY(unaligned_data_trap):
542C_ENTRY(page_fault_data_trap): 581C_ENTRY(page_fault_data_trap):
543 SAVE_STATE /* Save registers.*/ 582 SAVE_STATE /* Save registers.*/
544 /* PC, before IRQ/trap - this is one instruction above */ 583 /* PC, before IRQ/trap - this is one instruction above */
545 swi r17, r1, PTO+PT_PC; 584 swi r17, r1, PT_PC;
546 tovirt(r1,r1) 585 tovirt(r1,r1)
547 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 586 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
548 addik r15, r0, ret_from_exc-8 587 addik r15, r0, ret_from_exc-8
549 mfs r6, rear /* parameter unsigned long address */ 588 mfs r6, rear /* parameter unsigned long address */
550 mfs r7, resr /* parameter unsigned long error_code */ 589 mfs r7, resr /* parameter unsigned long error_code */
551 rted r0, do_page_fault 590 rted r0, do_page_fault
552 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 591 addik r5, r1, 0 /* parameter struct pt_regs * regs */
553 592
554C_ENTRY(page_fault_instr_trap): 593C_ENTRY(page_fault_instr_trap):
555 SAVE_STATE /* Save registers.*/ 594 SAVE_STATE /* Save registers.*/
556 /* PC, before IRQ/trap - this is one instruction above */ 595 /* PC, before IRQ/trap - this is one instruction above */
557 swi r17, r1, PTO+PT_PC; 596 swi r17, r1, PT_PC;
558 tovirt(r1,r1) 597 tovirt(r1,r1)
559 /* where the trap should return need -8 to adjust for rtsd r15, 8 */ 598 /* where the trap should return need -8 to adjust for rtsd r15, 8 */
560 addik r15, r0, ret_from_exc-8 599 addik r15, r0, ret_from_exc-8
561 mfs r6, rear /* parameter unsigned long address */ 600 mfs r6, rear /* parameter unsigned long address */
562 ori r7, r0, 0 /* parameter unsigned long error_code */ 601 ori r7, r0, 0 /* parameter unsigned long error_code */
563 rted r0, do_page_fault 602 rted r0, do_page_fault
564 addik r5, r1, PTO /* parameter struct pt_regs * regs */ 603 addik r5, r1, 0 /* parameter struct pt_regs * regs */
565 604
566/* Entry point used to return from an exception. */ 605/* Entry point used to return from an exception. */
567C_ENTRY(ret_from_exc): 606C_ENTRY(ret_from_exc):
568 lwi r11, r1, PTO + PT_MODE; 607 lwi r11, r1, PT_MODE;
569 bnei r11, 2f; /* See if returning to kernel mode, */ 608 bnei r11, 2f; /* See if returning to kernel mode, */
570 /* ... if so, skip resched &c. */ 609 /* ... if so, skip resched &c. */
571 610
@@ -597,7 +636,7 @@ C_ENTRY(ret_from_exc):
597 * complete register state. Here we save anything not saved by 636 * complete register state. Here we save anything not saved by
598 * the normal entry sequence, so that it may be safely restored 637 * the normal entry sequence, so that it may be safely restored
599 * (in a possibly modified form) after do_signal returns. */ 638 * (in a possibly modified form) after do_signal returns. */
600 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 639 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
601 addi r7, r0, 0; /* Arg 3: int in_syscall */ 640 addi r7, r0, 0; /* Arg 3: int in_syscall */
602 bralid r15, do_signal; /* Handle any signals */ 641 bralid r15, do_signal; /* Handle any signals */
603 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 642 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -609,7 +648,7 @@ C_ENTRY(ret_from_exc):
609 tophys(r1,r1); 648 tophys(r1,r1);
610 649
611 RESTORE_REGS; 650 RESTORE_REGS;
612 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 651 addik r1, r1, PT_SIZE /* Clean up stack space. */
613 652
614 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */ 653 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */
615 bri 6f; 654 bri 6f;
@@ -618,7 +657,7 @@ C_ENTRY(ret_from_exc):
618 VM_OFF; 657 VM_OFF;
619 tophys(r1,r1); 658 tophys(r1,r1);
620 RESTORE_REGS; 659 RESTORE_REGS;
621 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ 660 addik r1, r1, PT_SIZE /* Clean up stack space. */
622 661
623 tovirt(r1,r1); 662 tovirt(r1,r1);
6246: 6636:
@@ -651,10 +690,10 @@ C_ENTRY(_interrupt):
651 tophys(r1,r1); /* MS: I have in r1 physical address where stack is */ 690 tophys(r1,r1); /* MS: I have in r1 physical address where stack is */
652 /* save registers */ 691 /* save registers */
653/* MS: Make room on the stack -> activation record */ 692/* MS: Make room on the stack -> activation record */
654 addik r1, r1, -STATE_SAVE_SIZE; 693 addik r1, r1, -PT_SIZE;
655 SAVE_REGS 694 SAVE_REGS
656 brid 2f; 695 brid 2f;
657 swi r1, r1, PTO + PT_MODE; /* 0 - user mode, 1 - kernel mode */ 696 swi r1, r1, PT_MODE; /* 0 - user mode, 1 - kernel mode */
6581: 6971:
659/* User-mode state save. */ 698/* User-mode state save. */
660 /* MS: get the saved current */ 699 /* MS: get the saved current */
@@ -664,23 +703,23 @@ C_ENTRY(_interrupt):
664 addik r1, r1, THREAD_SIZE; 703 addik r1, r1, THREAD_SIZE;
665 tophys(r1,r1); 704 tophys(r1,r1);
666 /* save registers */ 705 /* save registers */
667 addik r1, r1, -STATE_SAVE_SIZE; 706 addik r1, r1, -PT_SIZE;
668 SAVE_REGS 707 SAVE_REGS
669 /* calculate mode */ 708 /* calculate mode */
670 swi r0, r1, PTO + PT_MODE; 709 swi r0, r1, PT_MODE;
671 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 710 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
672 swi r11, r1, PTO+PT_R1; 711 swi r11, r1, PT_R1;
673 clear_ums; 712 clear_ums;
6742: 7132:
675 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 714 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
676 tovirt(r1,r1) 715 tovirt(r1,r1)
677 addik r15, r0, irq_call; 716 addik r15, r0, irq_call;
678irq_call:rtbd r0, do_IRQ; 717irq_call:rtbd r0, do_IRQ;
679 addik r5, r1, PTO; 718 addik r5, r1, 0;
680 719
681/* MS: we are in virtual mode */ 720/* MS: we are in virtual mode */
682ret_from_irq: 721ret_from_irq:
683 lwi r11, r1, PTO + PT_MODE; 722 lwi r11, r1, PT_MODE;
684 bnei r11, 2f; 723 bnei r11, 2f;
685 724
686 lwi r11, CURRENT_TASK, TS_THREAD_INFO; 725 lwi r11, CURRENT_TASK, TS_THREAD_INFO;
@@ -697,7 +736,7 @@ ret_from_irq:
697 beqid r11, no_intr_resched 736 beqid r11, no_intr_resched
698/* Handle a signal return; Pending signals should be in r18. */ 737/* Handle a signal return; Pending signals should be in r18. */
699 addi r7, r0, 0; /* Arg 3: int in_syscall */ 738 addi r7, r0, 0; /* Arg 3: int in_syscall */
700 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 739 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
701 bralid r15, do_signal; /* Handle any signals */ 740 bralid r15, do_signal; /* Handle any signals */
702 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 741 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
703 742
@@ -709,7 +748,7 @@ no_intr_resched:
709 VM_OFF; 748 VM_OFF;
710 tophys(r1,r1); 749 tophys(r1,r1);
711 RESTORE_REGS 750 RESTORE_REGS
712 addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ 751 addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
713 lwi r1, r1, PT_R1 - PT_SIZE; 752 lwi r1, r1, PT_R1 - PT_SIZE;
714 bri 6f; 753 bri 6f;
715/* MS: Return to kernel state. */ 754/* MS: Return to kernel state. */
@@ -737,7 +776,7 @@ restore:
737 VM_OFF /* MS: turn off MMU */ 776 VM_OFF /* MS: turn off MMU */
738 tophys(r1,r1) 777 tophys(r1,r1)
739 RESTORE_REGS 778 RESTORE_REGS
740 addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */ 779 addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
741 tovirt(r1,r1); 780 tovirt(r1,r1);
7426: 7816:
743IRQ_return: /* MS: Make global symbol for debugging */ 782IRQ_return: /* MS: Make global symbol for debugging */
@@ -760,31 +799,29 @@ C_ENTRY(_debug_exception):
760 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ 799 lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
761 800
762 /* BIP bit is set on entry, no interrupts can occur */ 801 /* BIP bit is set on entry, no interrupts can occur */
763 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; 802 addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE;
764 SAVE_REGS; 803 SAVE_REGS;
765 /* save all regs to pt_reg structure */ 804 /* save all regs to pt_reg structure */
766 swi r0, r1, PTO+PT_R0; /* R0 must be saved too */ 805 swi r0, r1, PT_R0; /* R0 must be saved too */
767 swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */ 806 swi r14, r1, PT_R14 /* rewrite saved R14 value */
768 swi r16, r1, PTO+PT_R16 807 swi r16, r1, PT_PC; /* PC and r16 are the same */
769 swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
770 swi r17, r1, PTO+PT_R17
771 /* save special purpose registers to pt_regs */ 808 /* save special purpose registers to pt_regs */
772 mfs r11, rear; 809 mfs r11, rear;
773 swi r11, r1, PTO+PT_EAR; 810 swi r11, r1, PT_EAR;
774 mfs r11, resr; 811 mfs r11, resr;
775 swi r11, r1, PTO+PT_ESR; 812 swi r11, r1, PT_ESR;
776 mfs r11, rfsr; 813 mfs r11, rfsr;
777 swi r11, r1, PTO+PT_FSR; 814 swi r11, r1, PT_FSR;
778 815
779 /* stack pointer is in physical address at it is decrease 816 /* stack pointer is in physical address at it is decrease
780 * by STATE_SAVE_SIZE but we need to get correct R1 value */ 817 * by PT_SIZE but we need to get correct R1 value */
781 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE; 818 addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + PT_SIZE;
782 swi r11, r1, PTO+PT_R1 819 swi r11, r1, PT_R1
783 /* MS: r31 - current pointer isn't changed */ 820 /* MS: r31 - current pointer isn't changed */
784 tovirt(r1,r1) 821 tovirt(r1,r1)
785#ifdef CONFIG_KGDB 822#ifdef CONFIG_KGDB
786 addi r5, r1, PTO /* pass pt_reg address as the first arg */ 823 addi r5, r1, 0 /* pass pt_reg address as the first arg */
787 la r15, r0, dbtrap_call; /* return address */ 824 addik r15, r0, dbtrap_call; /* return address */
788 rtbd r0, microblaze_kgdb_break 825 rtbd r0, microblaze_kgdb_break
789 nop; 826 nop;
790#endif 827#endif
@@ -799,18 +836,16 @@ C_ENTRY(_debug_exception):
799 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */ 836 addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */
800 tophys(r1,r1); 837 tophys(r1,r1);
801 838
802 addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ 839 addik r1, r1, -PT_SIZE; /* Make room on the stack. */
803 SAVE_REGS; 840 SAVE_REGS;
804 swi r17, r1, PTO+PT_R17; 841 swi r16, r1, PT_PC; /* Save LP */
805 swi r16, r1, PTO+PT_R16; 842 swi r0, r1, PT_MODE; /* Was in user-mode. */
806 swi r16, r1, PTO+PT_PC; /* Save LP */
807 swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
808 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); 843 lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
809 swi r11, r1, PTO+PT_R1; /* Store user SP. */ 844 swi r11, r1, PT_R1; /* Store user SP. */
810 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); 845 lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
811 tovirt(r1,r1) 846 tovirt(r1,r1)
812 set_vms; 847 set_vms;
813 addik r5, r1, PTO; 848 addik r5, r1, 0;
814 addik r15, r0, dbtrap_call; 849 addik r15, r0, dbtrap_call;
815dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */ 850dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
816 rtbd r0, sw_exception 851 rtbd r0, sw_exception
@@ -818,7 +853,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
818 853
819 /* MS: The first instruction for the second part of the gdb/kgdb */ 854 /* MS: The first instruction for the second part of the gdb/kgdb */
820 set_bip; /* Ints masked for state restore */ 855 set_bip; /* Ints masked for state restore */
821 lwi r11, r1, PTO + PT_MODE; 856 lwi r11, r1, PT_MODE;
822 bnei r11, 2f; 857 bnei r11, 2f;
823/* MS: Return to user space - gdb */ 858/* MS: Return to user space - gdb */
824 /* Get current task ptr into r11 */ 859 /* Get current task ptr into r11 */
@@ -837,7 +872,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
837 andi r11, r11, _TIF_SIGPENDING; 872 andi r11, r11, _TIF_SIGPENDING;
838 beqi r11, 1f; /* Signals to handle, handle them */ 873 beqi r11, 1f; /* Signals to handle, handle them */
839 874
840 addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */ 875 addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
841 addi r7, r0, 0; /* Arg 3: int in_syscall */ 876 addi r7, r0, 0; /* Arg 3: int in_syscall */
842 bralid r15, do_signal; /* Handle any signals */ 877 bralid r15, do_signal; /* Handle any signals */
843 add r6, r0, r0; /* Arg 2: sigset_t *oldset */ 878 add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@@ -848,9 +883,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
848 tophys(r1,r1); 883 tophys(r1,r1);
849 /* MS: Restore all regs */ 884 /* MS: Restore all regs */
850 RESTORE_REGS 885 RESTORE_REGS
851 lwi r17, r1, PTO+PT_R17; 886 addik r1, r1, PT_SIZE /* Clean up stack space */
852 lwi r16, r1, PTO+PT_R16;
853 addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
854 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */ 887 lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
855DBTRAP_return_user: /* MS: Make global symbol for debugging */ 888DBTRAP_return_user: /* MS: Make global symbol for debugging */
856 rtbd r16, 0; /* MS: Instructions to return from a debug trap */ 889 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@@ -861,10 +894,9 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
861 tophys(r1,r1); 894 tophys(r1,r1);
862 /* MS: Restore all regs */ 895 /* MS: Restore all regs */
863 RESTORE_REGS 896 RESTORE_REGS
864 lwi r14, r1, PTO+PT_R14; 897 lwi r14, r1, PT_R14;
865 lwi r16, r1, PTO+PT_PC; 898 lwi r16, r1, PT_PC;
866 lwi r17, r1, PTO+PT_R17; 899 addik r1, r1, PT_SIZE; /* MS: Clean up stack space */
867 addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
868 tovirt(r1,r1); 900 tovirt(r1,r1);
869DBTRAP_return_kernel: /* MS: Make global symbol for debugging */ 901DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
870 rtbd r16, 0; /* MS: Instructions to return from a debug trap */ 902 rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@@ -956,20 +988,22 @@ ENTRY(_switch_to)
956 nop 988 nop
957 989
958ENTRY(_reset) 990ENTRY(_reset)
959 brai 0x70; /* Jump back to FS-boot */ 991 brai 0; /* Jump to reset vector */
960 992
961 /* These are compiled and loaded into high memory, then 993 /* These are compiled and loaded into high memory, then
962 * copied into place in mach_early_setup */ 994 * copied into place in mach_early_setup */
963 .section .init.ivt, "ax" 995 .section .init.ivt, "ax"
996#if CONFIG_MANUAL_RESET_VECTOR
964 .org 0x0 997 .org 0x0
965 /* this is very important - here is the reset vector */ 998 brai CONFIG_MANUAL_RESET_VECTOR
966 /* in current MMU branch you don't care what is here - it is 999#endif
967 * used from bootloader site - but this is correct for FS-BOOT */ 1000 .org 0x8
968 brai 0x70
969 nop
970 brai TOPHYS(_user_exception); /* syscall handler */ 1001 brai TOPHYS(_user_exception); /* syscall handler */
1002 .org 0x10
971 brai TOPHYS(_interrupt); /* Interrupt handler */ 1003 brai TOPHYS(_interrupt); /* Interrupt handler */
1004 .org 0x18
972 brai TOPHYS(_debug_exception); /* debug trap handler */ 1005 brai TOPHYS(_debug_exception); /* debug trap handler */
1006 .org 0x20
973 brai TOPHYS(_hw_exception_handler); /* HW exception handler */ 1007 brai TOPHYS(_hw_exception_handler); /* HW exception handler */
974 1008
975.section .rodata,"a" 1009.section .rodata,"a"
diff --git a/arch/microblaze/kernel/exceptions.c b/arch/microblaze/kernel/exceptions.c
index b98ee8d0c1cd..66fad2301221 100644
--- a/arch/microblaze/kernel/exceptions.c
+++ b/arch/microblaze/kernel/exceptions.c
@@ -25,6 +25,7 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/ptrace.h> 26#include <linux/ptrace.h>
27#include <asm/current.h> 27#include <asm/current.h>
28#include <asm/cacheflush.h>
28 29
29#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02 30#define MICROBLAZE_ILL_OPCODE_EXCEPTION 0x02
30#define MICROBLAZE_IBUS_EXCEPTION 0x03 31#define MICROBLAZE_IBUS_EXCEPTION 0x03
@@ -49,9 +50,11 @@ void die(const char *str, struct pt_regs *fp, long err)
49} 50}
50 51
51/* for user application debugging */ 52/* for user application debugging */
52void sw_exception(struct pt_regs *regs) 53asmlinkage void sw_exception(struct pt_regs *regs)
53{ 54{
54 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16); 55 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16);
56 flush_dcache_range(regs->r16, regs->r16 + 0x4);
57 flush_icache_range(regs->r16, regs->r16 + 0x4);
55} 58}
56 59
57void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) 60void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
@@ -72,7 +75,6 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
72 int fsr, int addr) 75 int fsr, int addr)
73{ 76{
74#ifdef CONFIG_MMU 77#ifdef CONFIG_MMU
75 int code;
76 addr = regs->pc; 78 addr = regs->pc;
77#endif 79#endif
78 80
@@ -86,8 +88,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
86 switch (type & 0x1F) { 88 switch (type & 0x1F) {
87 case MICROBLAZE_ILL_OPCODE_EXCEPTION: 89 case MICROBLAZE_ILL_OPCODE_EXCEPTION:
88 if (user_mode(regs)) { 90 if (user_mode(regs)) {
89 pr_debug(KERN_WARNING "Illegal opcode exception " \ 91 pr_debug("Illegal opcode exception in user mode\n");
90 "in user mode.\n");
91 _exception(SIGILL, regs, ILL_ILLOPC, addr); 92 _exception(SIGILL, regs, ILL_ILLOPC, addr);
92 return; 93 return;
93 } 94 }
@@ -97,8 +98,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
97 break; 98 break;
98 case MICROBLAZE_IBUS_EXCEPTION: 99 case MICROBLAZE_IBUS_EXCEPTION:
99 if (user_mode(regs)) { 100 if (user_mode(regs)) {
100 pr_debug(KERN_WARNING "Instruction bus error " \ 101 pr_debug("Instruction bus error exception in user mode\n");
101 "exception in user mode.\n");
102 _exception(SIGBUS, regs, BUS_ADRERR, addr); 102 _exception(SIGBUS, regs, BUS_ADRERR, addr);
103 return; 103 return;
104 } 104 }
@@ -108,8 +108,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
108 break; 108 break;
109 case MICROBLAZE_DBUS_EXCEPTION: 109 case MICROBLAZE_DBUS_EXCEPTION:
110 if (user_mode(regs)) { 110 if (user_mode(regs)) {
111 pr_debug(KERN_WARNING "Data bus error exception " \ 111 pr_debug("Data bus error exception in user mode\n");
112 "in user mode.\n");
113 _exception(SIGBUS, regs, BUS_ADRERR, addr); 112 _exception(SIGBUS, regs, BUS_ADRERR, addr);
114 return; 113 return;
115 } 114 }
@@ -119,8 +118,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
119 break; 118 break;
120 case MICROBLAZE_DIV_ZERO_EXCEPTION: 119 case MICROBLAZE_DIV_ZERO_EXCEPTION:
121 if (user_mode(regs)) { 120 if (user_mode(regs)) {
122 pr_debug(KERN_WARNING "Divide by zero exception " \ 121 pr_debug("Divide by zero exception in user mode\n");
123 "in user mode\n");
124 _exception(SIGILL, regs, FPE_INTDIV, addr); 122 _exception(SIGILL, regs, FPE_INTDIV, addr);
125 return; 123 return;
126 } 124 }
@@ -129,7 +127,7 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
129 die("Divide by zero exception", regs, SIGBUS); 127 die("Divide by zero exception", regs, SIGBUS);
130 break; 128 break;
131 case MICROBLAZE_FPU_EXCEPTION: 129 case MICROBLAZE_FPU_EXCEPTION:
132 pr_debug(KERN_WARNING "FPU exception\n"); 130 pr_debug("FPU exception\n");
133 /* IEEE FP exception */ 131 /* IEEE FP exception */
134 /* I removed fsr variable and use code var for storing fsr */ 132 /* I removed fsr variable and use code var for storing fsr */
135 if (fsr & FSR_IO) 133 if (fsr & FSR_IO)
@@ -147,14 +145,8 @@ asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
147 145
148#ifdef CONFIG_MMU 146#ifdef CONFIG_MMU
149 case MICROBLAZE_PRIVILEGED_EXCEPTION: 147 case MICROBLAZE_PRIVILEGED_EXCEPTION:
150 pr_debug(KERN_WARNING "Privileged exception\n"); 148 pr_debug("Privileged exception\n");
151 /* "brk r0,r0" - used as debug breakpoint - old toolchain */ 149 _exception(SIGILL, regs, ILL_PRVOPC, addr);
152 if (get_user(code, (unsigned long *)regs->pc) == 0
153 && code == 0x980c0000) {
154 _exception(SIGTRAP, regs, TRAP_BRKPT, addr);
155 } else {
156 _exception(SIGILL, regs, ILL_PRVOPC, addr);
157 }
158 break; 150 break;
159#endif 151#endif
160 default: 152 default:
diff --git a/arch/microblaze/kernel/ftrace.c b/arch/microblaze/kernel/ftrace.c
index 515feb404555..357d56abe24a 100644
--- a/arch/microblaze/kernel/ftrace.c
+++ b/arch/microblaze/kernel/ftrace.c
@@ -51,6 +51,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
51 : "r" (parent), "r" (return_hooker) 51 : "r" (parent), "r" (return_hooker)
52 ); 52 );
53 53
54 flush_dcache_range((u32)parent, (u32)parent + 4);
55 flush_icache_range((u32)parent, (u32)parent + 4);
56
54 if (unlikely(faulted)) { 57 if (unlikely(faulted)) {
55 ftrace_graph_stop(); 58 ftrace_graph_stop();
56 WARN_ON(1); 59 WARN_ON(1);
@@ -95,6 +98,9 @@ static int ftrace_modify_code(unsigned long addr, unsigned int value)
95 if (unlikely(faulted)) 98 if (unlikely(faulted))
96 return -EFAULT; 99 return -EFAULT;
97 100
101 flush_dcache_range(addr, addr + 4);
102 flush_icache_range(addr, addr + 4);
103
98 return 0; 104 return 0;
99} 105}
100 106
@@ -195,8 +201,6 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
195 ret += ftrace_modify_code((unsigned long)&ftrace_caller, 201 ret += ftrace_modify_code((unsigned long)&ftrace_caller,
196 MICROBLAZE_NOP); 202 MICROBLAZE_NOP);
197 203
198 /* All changes are done - lets do caches consistent */
199 flush_icache();
200 return ret; 204 return ret;
201} 205}
202 206
@@ -210,7 +214,6 @@ int ftrace_enable_ftrace_graph_caller(void)
210 214
211 old_jump = *(unsigned int *)ip; /* save jump over instruction */ 215 old_jump = *(unsigned int *)ip; /* save jump over instruction */
212 ret = ftrace_modify_code(ip, MICROBLAZE_NOP); 216 ret = ftrace_modify_code(ip, MICROBLAZE_NOP);
213 flush_icache();
214 217
215 pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump); 218 pr_debug("%s: Replace instruction: 0x%x\n", __func__, old_jump);
216 return ret; 219 return ret;
@@ -222,7 +225,6 @@ int ftrace_disable_ftrace_graph_caller(void)
222 unsigned long ip = (unsigned long)(&ftrace_call_graph); 225 unsigned long ip = (unsigned long)(&ftrace_call_graph);
223 226
224 ret = ftrace_modify_code(ip, old_jump); 227 ret = ftrace_modify_code(ip, old_jump);
225 flush_icache();
226 228
227 pr_debug("%s\n", __func__); 229 pr_debug("%s\n", __func__);
228 return ret; 230 return ret;
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 42434008209e..77320b8fc16a 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -39,7 +39,7 @@
39#include <asm/mmu.h> 39#include <asm/mmu.h>
40#include <asm/processor.h> 40#include <asm/processor.h>
41 41
42.data 42.section .data
43.global empty_zero_page 43.global empty_zero_page
44.align 12 44.align 12
45empty_zero_page: 45empty_zero_page:
@@ -50,6 +50,11 @@ swapper_pg_dir:
50 50
51#endif /* CONFIG_MMU */ 51#endif /* CONFIG_MMU */
52 52
53.section .rodata
54.align 4
55endian_check:
56 .word 1
57
53 __HEAD 58 __HEAD
54ENTRY(_start) 59ENTRY(_start)
55#if CONFIG_KERNEL_BASE_ADDR == 0 60#if CONFIG_KERNEL_BASE_ADDR == 0
@@ -62,23 +67,29 @@ real_start:
62 andi r1, r1, ~2 67 andi r1, r1, ~2
63 mts rmsr, r1 68 mts rmsr, r1
64/* 69/*
65 * Here is checking mechanism which check if Microblaze has msr instructions 70 * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc'
66 * We load msr and compare it with previous r1 value - if is the same, 71 * if the msrclr instruction is not enabled. We use this to detect
67 * msr instructions works if not - cpu don't have them. 72 * if the opcode is available, by issuing msrclr and then testing the result.
73 * r8 == 0 - msr instructions are implemented
74 * r8 != 0 - msr instructions are not implemented
68 */ 75 */
69 /* r8=0 - I have msr instr, 1 - I don't have them */ 76 msrclr r8, 0 /* clear nothing - just read msr for test */
70 rsubi r0, r0, 1 /* set the carry bit */ 77 cmpu r8, r8, r1 /* r1 must contain msr reg content */
71 msrclr r0, 0x4 /* try to clear it */
72 /* read the carry bit, r8 will be '0' if msrclr exists */
73 addik r8, r0, 0
74 78
75/* r7 may point to an FDT, or there may be one linked in. 79/* r7 may point to an FDT, or there may be one linked in.
76 if it's in r7, we've got to save it away ASAP. 80 if it's in r7, we've got to save it away ASAP.
77 We ensure r7 points to a valid FDT, just in case the bootloader 81 We ensure r7 points to a valid FDT, just in case the bootloader
78 is broken or non-existent */ 82 is broken or non-existent */
79 beqi r7, no_fdt_arg /* NULL pointer? don't copy */ 83 beqi r7, no_fdt_arg /* NULL pointer? don't copy */
80 lw r11, r0, r7 /* Does r7 point to a */ 84/* Does r7 point to a valid FDT? Load HEADER magic number */
81 rsubi r11, r11, OF_DT_HEADER /* valid FDT? */ 85 /* Run time Big/Little endian platform */
86 /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */
87 lbui r11, r0, TOPHYS(endian_check)
88 beqid r11, big_endian /* DO NOT break delay stop dependency */
89 lw r11, r0, r7 /* Big endian load in delay slot */
90 lwr r11, r0, r7 /* Little endian load */
91big_endian:
92 rsubi r11, r11, OF_DT_HEADER /* Check FDT header */
82 beqi r11, _prepare_copy_fdt 93 beqi r11, _prepare_copy_fdt
83 or r7, r0, r0 /* clear R7 when not valid DTB */ 94 or r7, r0, r0 /* clear R7 when not valid DTB */
84 bnei r11, no_fdt_arg /* No - get out of here */ 95 bnei r11, no_fdt_arg /* No - get out of here */
@@ -213,26 +224,26 @@ start_here:
213#endif /* CONFIG_MMU */ 224#endif /* CONFIG_MMU */
214 225
215 /* Initialize small data anchors */ 226 /* Initialize small data anchors */
216 la r13, r0, _KERNEL_SDA_BASE_ 227 addik r13, r0, _KERNEL_SDA_BASE_
217 la r2, r0, _KERNEL_SDA2_BASE_ 228 addik r2, r0, _KERNEL_SDA2_BASE_
218 229
219 /* Initialize stack pointer */ 230 /* Initialize stack pointer */
220 la r1, r0, init_thread_union + THREAD_SIZE - 4 231 addik r1, r0, init_thread_union + THREAD_SIZE - 4
221 232
222 /* Initialize r31 with current task address */ 233 /* Initialize r31 with current task address */
223 la r31, r0, init_task 234 addik r31, r0, init_task
224 235
225 /* 236 /*
226 * Call platform dependent initialize function. 237 * Call platform dependent initialize function.
227 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for 238 * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
228 * the function. 239 * the function.
229 */ 240 */
230 la r9, r0, machine_early_init 241 addik r9, r0, machine_early_init
231 brald r15, r9 242 brald r15, r9
232 nop 243 nop
233 244
234#ifndef CONFIG_MMU 245#ifndef CONFIG_MMU
235 la r15, r0, machine_halt 246 addik r15, r0, machine_halt
236 braid start_kernel 247 braid start_kernel
237 nop 248 nop
238#else 249#else
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 522751737cfa..154756f3c694 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -47,11 +47,10 @@ void setup_heartbeat(void)
47 struct device_node *gpio = NULL; 47 struct device_node *gpio = NULL;
48 int *prop; 48 int *prop;
49 int j; 49 int j;
50 char *gpio_list[] = { 50 const char * const gpio_list[] = {
51 "xlnx,xps-gpio-1.00.a", 51 "xlnx,xps-gpio-1.00.a",
52 "xlnx,opb-gpio-1.00.a", 52 NULL
53 NULL 53 };
54 };
55 54
56 for (j = 0; gpio_list[j] != NULL; j++) { 55 for (j = 0; gpio_list[j] != NULL; j++) {
57 gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]); 56 gpio = of_find_compatible_node(NULL, NULL, gpio_list[j]);
@@ -60,7 +59,7 @@ void setup_heartbeat(void)
60 } 59 }
61 60
62 if (gpio) { 61 if (gpio) {
63 base_addr = *(int *) of_get_property(gpio, "reg", NULL); 62 base_addr = be32_to_cpup(of_get_property(gpio, "reg", NULL));
64 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE); 63 base_addr = (unsigned long) ioremap(base_addr, PAGE_SIZE);
65 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr); 64 printk(KERN_NOTICE "Heartbeat GPIO at 0x%x\n", base_addr);
66 65
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 781195438ee6..56572e923a83 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -77,6 +77,8 @@
77#include <asm/signal.h> 77#include <asm/signal.h>
78#include <asm/asm-offsets.h> 78#include <asm/asm-offsets.h>
79 79
80#undef DEBUG
81
80/* Helpful Macros */ 82/* Helpful Macros */
81#define NUM_TO_REG(num) r ## num 83#define NUM_TO_REG(num) r ## num
82 84
@@ -91,7 +93,7 @@
91 lwi r6, r1, PT_R6; \ 93 lwi r6, r1, PT_R6; \
92 lwi r11, r1, PT_R11; \ 94 lwi r11, r1, PT_R11; \
93 lwi r31, r1, PT_R31; \ 95 lwi r31, r1, PT_R31; \
94 lwi r1, r0, TOPHYS(r0_ram + 0); 96 lwi r1, r1, PT_R1;
95#endif /* CONFIG_MMU */ 97#endif /* CONFIG_MMU */
96 98
97#define LWREG_NOP \ 99#define LWREG_NOP \
@@ -147,10 +149,6 @@
147 #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0 149 #if CONFIG_XILINX_MICROBLAZE0_USE_BARREL > 0
148 #define BSRLI(rD, rA, imm) \ 150 #define BSRLI(rD, rA, imm) \
149 bsrli rD, rA, imm 151 bsrli rD, rA, imm
150 #elif CONFIG_XILINX_MICROBLAZE0_USE_DIV > 0
151 #define BSRLI(rD, rA, imm) \
152 ori rD, r0, (1 << imm); \
153 idivu rD, rD, rA
154 #else 152 #else
155 #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA) 153 #define BSRLI(rD, rA, imm) BSRLI ## imm (rD, rA)
156 /* Only the used shift constants defined here - add more if needed */ 154 /* Only the used shift constants defined here - add more if needed */
@@ -210,8 +208,8 @@
210 * | . | 208 * | . |
211 * | . | 209 * | . |
212 * 210 *
213 * NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S 211 * MMU kernel uses the same 'pt_pool_space' pointed space
214 * which is used for storing register values - old style was, that value were 212 * which is used for storing register values - noMMu style was, that values were
215 * stored in stack but in case of failure you lost information about register. 213 * stored in stack but in case of failure you lost information about register.
216 * Currently you can see register value in memory in specific place. 214 * Currently you can see register value in memory in specific place.
217 * In compare to with previous solution the speed should be the same. 215 * In compare to with previous solution the speed should be the same.
@@ -230,8 +228,22 @@
230 */ 228 */
231 229
232/* wrappers to restore state before coming to entry.S */ 230/* wrappers to restore state before coming to entry.S */
233
234#ifdef CONFIG_MMU 231#ifdef CONFIG_MMU
232.section .data
233.align 4
234pt_pool_space:
235 .space PT_SIZE
236
237#ifdef DEBUG
238/* Create space for exception counting. */
239.section .data
240.global exception_debug_table
241.align 4
242exception_debug_table:
243 /* Look at exception vector table. There is 32 exceptions * word size */
244 .space (32 * 4)
245#endif /* DEBUG */
246
235.section .rodata 247.section .rodata
236.align 4 248.align 4
237_MB_HW_ExceptionVectorTable: 249_MB_HW_ExceptionVectorTable:
@@ -291,10 +303,10 @@ _hw_exception_handler:
291#ifndef CONFIG_MMU 303#ifndef CONFIG_MMU
292 addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */ 304 addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
293#else 305#else
294 swi r1, r0, TOPHYS(r0_ram + 0); /* GET_SP */ 306 swi r1, r0, TOPHYS(pt_pool_space + PT_R1); /* GET_SP */
295 /* Save date to kernel memory. Here is the problem 307 /* Save date to kernel memory. Here is the problem
296 * when you came from user space */ 308 * when you came from user space */
297 ori r1, r0, TOPHYS(r0_ram + 28); 309 ori r1, r0, TOPHYS(pt_pool_space);
298#endif 310#endif
299 swi r3, r1, PT_R3 311 swi r3, r1, PT_R3
300 swi r4, r1, PT_R4 312 swi r4, r1, PT_R4
@@ -333,12 +345,12 @@ not_in_delay_slot:
333 345
334#ifdef DEBUG 346#ifdef DEBUG
335/* counting which exception happen */ 347/* counting which exception happen */
336 lwi r5, r0, 0x200 + TOPHYS(r0_ram) 348 lwi r5, r0, TOPHYS(exception_debug_table)
337 addi r5, r5, 1 349 addi r5, r5, 1
338 swi r5, r0, 0x200 + TOPHYS(r0_ram) 350 swi r5, r0, TOPHYS(exception_debug_table)
339 lwi r5, r6, 0x200 + TOPHYS(r0_ram) 351 lwi r5, r6, TOPHYS(exception_debug_table)
340 addi r5, r5, 1 352 addi r5, r5, 1
341 swi r5, r6, 0x200 + TOPHYS(r0_ram) 353 swi r5, r6, TOPHYS(exception_debug_table)
342#endif 354#endif
343/* end */ 355/* end */
344 /* Load the HW Exception vector */ 356 /* Load the HW Exception vector */
@@ -478,7 +490,7 @@ ex_lw_tail:
478 /* Get the destination register number into r5 */ 490 /* Get the destination register number into r5 */
479 lbui r5, r0, TOPHYS(ex_reg_op); 491 lbui r5, r0, TOPHYS(ex_reg_op);
480 /* Form load_word jump table offset (lw_table + (8 * regnum)) */ 492 /* Form load_word jump table offset (lw_table + (8 * regnum)) */
481 la r6, r0, TOPHYS(lw_table); 493 addik r6, r0, TOPHYS(lw_table);
482 addk r5, r5, r5; 494 addk r5, r5, r5;
483 addk r5, r5, r5; 495 addk r5, r5, r5;
484 addk r5, r5, r5; 496 addk r5, r5, r5;
@@ -489,7 +501,7 @@ ex_sw:
489 /* Get the destination register number into r5 */ 501 /* Get the destination register number into r5 */
490 lbui r5, r0, TOPHYS(ex_reg_op); 502 lbui r5, r0, TOPHYS(ex_reg_op);
491 /* Form store_word jump table offset (sw_table + (8 * regnum)) */ 503 /* Form store_word jump table offset (sw_table + (8 * regnum)) */
492 la r6, r0, TOPHYS(sw_table); 504 addik r6, r0, TOPHYS(sw_table);
493 add r5, r5, r5; 505 add r5, r5, r5;
494 add r5, r5, r5; 506 add r5, r5, r5;
495 add r5, r5, r5; 507 add r5, r5, r5;
@@ -900,7 +912,7 @@ ex_lw_vm:
900 beqid r6, ex_lhw_vm; 912 beqid r6, ex_lhw_vm;
901load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */ 913load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */
902/* Load a word, byte-by-byte from destination address and save it in tmp space*/ 914/* Load a word, byte-by-byte from destination address and save it in tmp space*/
903 la r6, r0, ex_tmp_data_loc_0; 915 addik r6, r0, ex_tmp_data_loc_0;
904 sbi r5, r6, 0; 916 sbi r5, r6, 0;
905load2: lbui r5, r4, 1; 917load2: lbui r5, r4, 1;
906 sbi r5, r6, 1; 918 sbi r5, r6, 1;
@@ -914,7 +926,7 @@ load4: lbui r5, r4, 3;
914ex_lhw_vm: 926ex_lhw_vm:
915 /* Load a half-word, byte-by-byte from destination address and 927 /* Load a half-word, byte-by-byte from destination address and
916 * save it in tmp space */ 928 * save it in tmp space */
917 la r6, r0, ex_tmp_data_loc_0; 929 addik r6, r0, ex_tmp_data_loc_0;
918 sbi r5, r6, 0; 930 sbi r5, r6, 0;
919load5: lbui r5, r4, 1; 931load5: lbui r5, r4, 1;
920 sbi r5, r6, 1; 932 sbi r5, r6, 1;
@@ -930,7 +942,7 @@ ex_sw_vm:
930 addik r5, r8, sw_table_vm; 942 addik r5, r8, sw_table_vm;
931 bra r5; 943 bra r5;
932ex_sw_tail_vm: 944ex_sw_tail_vm:
933 la r5, r0, ex_tmp_data_loc_0; 945 addik r5, r0, ex_tmp_data_loc_0;
934 beqid r6, ex_shw_vm; 946 beqid r6, ex_shw_vm;
935 swi r3, r5, 0; /* Get the word - delay slot */ 947 swi r3, r5, 0; /* Get the word - delay slot */
936 /* Store the word, byte-by-byte into destination address */ 948 /* Store the word, byte-by-byte into destination address */
@@ -945,11 +957,20 @@ store3: sbi r3, r4, 2;
945store4: sbi r3, r4, 3; /* Delay slot */ 957store4: sbi r3, r4, 3; /* Delay slot */
946ex_shw_vm: 958ex_shw_vm:
947 /* Store the lower half-word, byte-by-byte into destination address */ 959 /* Store the lower half-word, byte-by-byte into destination address */
960#ifdef __MICROBLAZEEL__
961 lbui r3, r5, 0;
962store5: sbi r3, r4, 0;
963 lbui r3, r5, 1;
964 brid ret_from_exc;
965store6: sbi r3, r4, 1; /* Delay slot */
966#else
948 lbui r3, r5, 2; 967 lbui r3, r5, 2;
949store5: sbi r3, r4, 0; 968store5: sbi r3, r4, 0;
950 lbui r3, r5, 3; 969 lbui r3, r5, 3;
951 brid ret_from_exc; 970 brid ret_from_exc;
952store6: sbi r3, r4, 1; /* Delay slot */ 971store6: sbi r3, r4, 1; /* Delay slot */
972#endif
973
953ex_sw_end_vm: /* Exception handling of store word, ends. */ 974ex_sw_end_vm: /* Exception handling of store word, ends. */
954 975
955/* We have to prevent cases that get/put_user macros get unaligned pointer 976/* We have to prevent cases that get/put_user macros get unaligned pointer
@@ -964,7 +985,7 @@ ex_unaligned_fixup:
964 addik r7, r0, SIGSEGV 985 addik r7, r0, SIGSEGV
965 /* call bad_page_fault for finding aligned fixup, fixup address is saved 986 /* call bad_page_fault for finding aligned fixup, fixup address is saved
966 * in PT_PC which is used as return address from exception */ 987 * in PT_PC which is used as return address from exception */
967 la r15, r0, ret_from_exc-8 /* setup return address */ 988 addik r15, r0, ret_from_exc-8 /* setup return address */
968 brid bad_page_fault 989 brid bad_page_fault
969 nop 990 nop
970 991
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 03172c1da770..c88f066f41bd 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -40,59 +40,46 @@ unsigned int nr_irq;
40#define MER_ME (1<<0) 40#define MER_ME (1<<0)
41#define MER_HIE (1<<1) 41#define MER_HIE (1<<1)
42 42
43static void intc_enable_or_unmask(unsigned int irq) 43static void intc_enable_or_unmask(struct irq_data *d)
44{ 44{
45 unsigned long mask = 1 << irq; 45 unsigned long mask = 1 << d->irq;
46 pr_debug("enable_or_unmask: %d\n", irq); 46 pr_debug("enable_or_unmask: %d\n", d->irq);
47 out_be32(INTC_BASE + SIE, mask); 47 out_be32(INTC_BASE + SIE, mask);
48 48
49 /* ack level irqs because they can't be acked during 49 /* ack level irqs because they can't be acked during
50 * ack function since the handle_level_irq function 50 * ack function since the handle_level_irq function
51 * acks the irq before calling the interrupt handler 51 * acks the irq before calling the interrupt handler
52 */ 52 */
53 if (irq_desc[irq].status & IRQ_LEVEL) 53 if (irqd_is_level_type(d))
54 out_be32(INTC_BASE + IAR, mask); 54 out_be32(INTC_BASE + IAR, mask);
55} 55}
56 56
57static void intc_disable_or_mask(unsigned int irq) 57static void intc_disable_or_mask(struct irq_data *d)
58{ 58{
59 pr_debug("disable: %d\n", irq); 59 pr_debug("disable: %d\n", d->irq);
60 out_be32(INTC_BASE + CIE, 1 << irq); 60 out_be32(INTC_BASE + CIE, 1 << d->irq);
61} 61}
62 62
63static void intc_ack(unsigned int irq) 63static void intc_ack(struct irq_data *d)
64{ 64{
65 pr_debug("ack: %d\n", irq); 65 pr_debug("ack: %d\n", d->irq);
66 out_be32(INTC_BASE + IAR, 1 << irq); 66 out_be32(INTC_BASE + IAR, 1 << d->irq);
67} 67}
68 68
69static void intc_mask_ack(unsigned int irq) 69static void intc_mask_ack(struct irq_data *d)
70{ 70{
71 unsigned long mask = 1 << irq; 71 unsigned long mask = 1 << d->irq;
72 pr_debug("disable_and_ack: %d\n", irq); 72 pr_debug("disable_and_ack: %d\n", d->irq);
73 out_be32(INTC_BASE + CIE, mask); 73 out_be32(INTC_BASE + CIE, mask);
74 out_be32(INTC_BASE + IAR, mask); 74 out_be32(INTC_BASE + IAR, mask);
75} 75}
76 76
77static void intc_end(unsigned int irq)
78{
79 unsigned long mask = 1 << irq;
80 pr_debug("end: %d\n", irq);
81 if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
82 out_be32(INTC_BASE + SIE, mask);
83 /* ack level sensitive intr */
84 if (irq_desc[irq].status & IRQ_LEVEL)
85 out_be32(INTC_BASE + IAR, mask);
86 }
87}
88
89static struct irq_chip intc_dev = { 77static struct irq_chip intc_dev = {
90 .name = "Xilinx INTC", 78 .name = "Xilinx INTC",
91 .unmask = intc_enable_or_unmask, 79 .irq_unmask = intc_enable_or_unmask,
92 .mask = intc_disable_or_mask, 80 .irq_mask = intc_disable_or_mask,
93 .ack = intc_ack, 81 .irq_ack = intc_ack,
94 .mask_ack = intc_mask_ack, 82 .irq_mask_ack = intc_mask_ack,
95 .end = intc_end,
96}; 83};
97 84
98unsigned int get_irq(struct pt_regs *regs) 85unsigned int get_irq(struct pt_regs *regs)
@@ -126,11 +113,8 @@ void __init init_IRQ(void)
126 0 113 0
127 }; 114 };
128#endif 115#endif
129 static char *intc_list[] = { 116 const char * const intc_list[] = {
130 "xlnx,xps-intc-1.00.a", 117 "xlnx,xps-intc-1.00.a",
131 "xlnx,opb-intc-1.00.c",
132 "xlnx,opb-intc-1.00.b",
133 "xlnx,opb-intc-1.00.a",
134 NULL 118 NULL
135 }; 119 };
136 120
@@ -141,12 +125,15 @@ void __init init_IRQ(void)
141 } 125 }
142 BUG_ON(!intc); 126 BUG_ON(!intc);
143 127
144 intc_baseaddr = *(int *) of_get_property(intc, "reg", NULL); 128 intc_baseaddr = be32_to_cpup(of_get_property(intc,
129 "reg", NULL));
145 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE); 130 intc_baseaddr = (unsigned long) ioremap(intc_baseaddr, PAGE_SIZE);
146 nr_irq = *(int *) of_get_property(intc, "xlnx,num-intr-inputs", NULL); 131 nr_irq = be32_to_cpup(of_get_property(intc,
132 "xlnx,num-intr-inputs", NULL));
147 133
148 intr_type = 134 intr_type =
149 *(int *) of_get_property(intc, "xlnx,kind-of-intr", NULL); 135 be32_to_cpup(of_get_property(intc,
136 "xlnx,kind-of-intr", NULL));
150 if (intr_type >= (1 << (nr_irq + 1))) 137 if (intr_type >= (1 << (nr_irq + 1)))
151 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n"); 138 printk(KERN_INFO " ERROR: Mismatch in kind-of-intr param\n");
152 139
@@ -170,13 +157,13 @@ void __init init_IRQ(void)
170 157
171 for (i = 0; i < nr_irq; ++i) { 158 for (i = 0; i < nr_irq; ++i) {
172 if (intr_type & (0x00000001 << i)) { 159 if (intr_type & (0x00000001 << i)) {
173 set_irq_chip_and_handler_name(i, &intc_dev, 160 irq_set_chip_and_handler_name(i, &intc_dev,
174 handle_edge_irq, intc_dev.name); 161 handle_edge_irq, "edge");
175 irq_desc[i].status &= ~IRQ_LEVEL; 162 irq_clear_status_flags(i, IRQ_LEVEL);
176 } else { 163 } else {
177 set_irq_chip_and_handler_name(i, &intc_dev, 164 irq_set_chip_and_handler_name(i, &intc_dev,
178 handle_level_irq, intc_dev.name); 165 handle_level_irq, "level");
179 irq_desc[i].status |= IRQ_LEVEL; 166 irq_set_status_flags(i, IRQ_LEVEL);
180 } 167 }
181 } 168 }
182} 169}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index a9345fb4906a..ce7ac8435d5c 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -47,46 +47,6 @@ next_irq:
47 trace_hardirqs_on(); 47 trace_hardirqs_on();
48} 48}
49 49
50int show_interrupts(struct seq_file *p, void *v)
51{
52 int i = *(loff_t *) v, j;
53 struct irqaction *action;
54 unsigned long flags;
55
56 if (i == 0) {
57 seq_printf(p, " ");
58 for_each_online_cpu(j)
59 seq_printf(p, "CPU%-8d", j);
60 seq_putc(p, '\n');
61 }
62
63 if (i < nr_irq) {
64 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
65 action = irq_desc[i].action;
66 if (!action)
67 goto skip;
68 seq_printf(p, "%3d: ", i);
69#ifndef CONFIG_SMP
70 seq_printf(p, "%10u ", kstat_irqs(i));
71#else
72 for_each_online_cpu(j)
73 seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
74#endif
75 seq_printf(p, " %8s", irq_desc[i].status &
76 IRQ_LEVEL ? "level" : "edge");
77 seq_printf(p, " %8s", irq_desc[i].chip->name);
78 seq_printf(p, " %s", action->name);
79
80 for (action = action->next; action; action = action->next)
81 seq_printf(p, ", %s", action->name);
82
83 seq_putc(p, '\n');
84skip:
85 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
86 }
87 return 0;
88}
89
90/* MS: There is no any advance mapping mechanism. We are using simple 32bit 50/* MS: There is no any advance mapping mechanism. We are using simple 32bit
91 intc without any cascades or any connection that's why mapping is 1:1 */ 51 intc without any cascades or any connection that's why mapping is 1:1 */
92unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq) 52unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
diff --git a/arch/microblaze/kernel/kgdb.c b/arch/microblaze/kernel/kgdb.c
index bfc006b7f2d8..09a5e8286137 100644
--- a/arch/microblaze/kernel/kgdb.c
+++ b/arch/microblaze/kernel/kgdb.c
@@ -80,7 +80,7 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
80void microblaze_kgdb_break(struct pt_regs *regs) 80void microblaze_kgdb_break(struct pt_regs *regs)
81{ 81{
82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0) 82 if (kgdb_handle_exception(1, SIGTRAP, 0, regs) != 0)
83 return 0; 83 return;
84 84
85 /* Jump over the first arch_kgdb_breakpoint which is barrier to 85 /* Jump over the first arch_kgdb_breakpoint which is barrier to
86 * get kgdb work. The same solution is used for powerpc */ 86 * get kgdb work. The same solution is used for powerpc */
@@ -114,7 +114,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
114{ 114{
115 char *ptr; 115 char *ptr;
116 unsigned long address; 116 unsigned long address;
117 int cpu = smp_processor_id();
118 117
119 switch (remcom_in_buffer[0]) { 118 switch (remcom_in_buffer[0]) {
120 case 'c': 119 case 'c':
@@ -143,5 +142,9 @@ void kgdb_arch_exit(void)
143 * Global data 142 * Global data
144 */ 143 */
145struct kgdb_arch arch_kgdb_ops = { 144struct kgdb_arch arch_kgdb_ops = {
145#ifdef __MICROBLAZEEL__
146 .gdb_bpt_instr = {0x18, 0x00, 0x0c, 0xba}, /* brki r16, 0x18 */
147#else
146 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */ 148 .gdb_bpt_instr = {0xba, 0x0c, 0x00, 0x18}, /* brki r16, 0x18 */
149#endif
147}; 150};
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index ff85f7718035..49faeb429599 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -15,39 +15,16 @@
15#include <linux/syscalls.h> 15#include <linux/syscalls.h>
16 16
17#include <asm/checksum.h> 17#include <asm/checksum.h>
18#include <asm/cacheflush.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <asm/page.h> 20#include <asm/page.h>
20#include <asm/system.h> 21#include <asm/system.h>
21#include <linux/ftrace.h> 22#include <linux/ftrace.h>
22#include <linux/uaccess.h> 23#include <linux/uaccess.h>
23 24
24/*
25 * libgcc functions - functions that are used internally by the
26 * compiler... (prototypes are not correct though, but that
27 * doesn't really matter since they're not versioned).
28 */
29extern void __ashldi3(void);
30EXPORT_SYMBOL(__ashldi3);
31extern void __ashrdi3(void);
32EXPORT_SYMBOL(__ashrdi3);
33extern void __divsi3(void);
34EXPORT_SYMBOL(__divsi3);
35extern void __lshrdi3(void);
36EXPORT_SYMBOL(__lshrdi3);
37extern void __modsi3(void);
38EXPORT_SYMBOL(__modsi3);
39extern void __mulsi3(void);
40EXPORT_SYMBOL(__mulsi3);
41extern void __muldi3(void);
42EXPORT_SYMBOL(__muldi3);
43extern void __ucmpdi2(void);
44EXPORT_SYMBOL(__ucmpdi2);
45extern void __udivsi3(void);
46EXPORT_SYMBOL(__udivsi3);
47extern void __umodsi3(void);
48EXPORT_SYMBOL(__umodsi3);
49extern char *_ebss; 25extern char *_ebss;
50EXPORT_SYMBOL_GPL(_ebss); 26EXPORT_SYMBOL_GPL(_ebss);
27
51#ifdef CONFIG_FUNCTION_TRACER 28#ifdef CONFIG_FUNCTION_TRACER
52extern void _mcount(void); 29extern void _mcount(void);
53EXPORT_SYMBOL(_mcount); 30EXPORT_SYMBOL(_mcount);
@@ -63,3 +40,20 @@ EXPORT_SYMBOL(__strncpy_user);
63EXPORT_SYMBOL(memcpy); 40EXPORT_SYMBOL(memcpy);
64EXPORT_SYMBOL(memmove); 41EXPORT_SYMBOL(memmove);
65#endif 42#endif
43
44#ifdef CONFIG_MMU
45EXPORT_SYMBOL(empty_zero_page);
46#endif
47
48EXPORT_SYMBOL(mbc);
49
50extern void __divsi3(void);
51EXPORT_SYMBOL(__divsi3);
52extern void __modsi3(void);
53EXPORT_SYMBOL(__modsi3);
54extern void __mulsi3(void);
55EXPORT_SYMBOL(__mulsi3);
56extern void __udivsi3(void);
57EXPORT_SYMBOL(__udivsi3);
58extern void __umodsi3(void);
59EXPORT_SYMBOL(__umodsi3);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index ba7c4b16ed35..968648a81c1e 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -159,7 +159,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
159 } 159 }
160 160
161 /* FIXME STATE_SAVE_PT_OFFSET; */ 161 /* FIXME STATE_SAVE_PT_OFFSET; */
162 ti->cpu_context.r1 = (unsigned long)childregs - STATE_SAVE_ARG_SPACE; 162 ti->cpu_context.r1 = (unsigned long)childregs;
163 /* we should consider the fact that childregs is a copy of the parent 163 /* we should consider the fact that childregs is a copy of the parent
164 * regs which were saved immediately after entering the kernel state 164 * regs which were saved immediately after entering the kernel state
165 * before enabling VM. This MSR will be restored in switch_to and 165 * before enabling VM. This MSR will be restored in switch_to and
diff --git a/arch/microblaze/kernel/prom.c b/arch/microblaze/kernel/prom.c
index 427b13b4740f..b15cc219b1d9 100644
--- a/arch/microblaze/kernel/prom.c
+++ b/arch/microblaze/kernel/prom.c
@@ -42,19 +42,14 @@
42#include <asm/sections.h> 42#include <asm/sections.h>
43#include <asm/pci-bridge.h> 43#include <asm/pci-bridge.h>
44 44
45void __init early_init_dt_scan_chosen_arch(unsigned long node)
46{
47 /* No Microblaze specific code here */
48}
49
50void __init early_init_dt_add_memory_arch(u64 base, u64 size) 45void __init early_init_dt_add_memory_arch(u64 base, u64 size)
51{ 46{
52 memblock_add(base, size); 47 memblock_add(base, size);
53} 48}
54 49
55u64 __init early_init_dt_alloc_memory_arch(u64 size, u64 align) 50void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
56{ 51{
57 return memblock_alloc(size, align); 52 return __va(memblock_alloc(size, align));
58} 53}
59 54
60#ifdef CONFIG_EARLY_PRINTK 55#ifdef CONFIG_EARLY_PRINTK
@@ -64,24 +59,23 @@ static int __init early_init_dt_scan_serial(unsigned long node,
64{ 59{
65 unsigned long l; 60 unsigned long l;
66 char *p; 61 char *p;
67 int *addr; 62 const __be32 *addr;
68 63
69 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname); 64 pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname);
70 65
71/* find all serial nodes */ 66/* find all serial nodes */
72 if (strncmp(uname, "serial", 6) != 0) 67 if (strncmp(uname, "serial", 6) != 0)
73 return 0; 68 return 0;
74 69
75 early_init_dt_check_for_initrd(node);
76
77/* find compatible node with uartlite */ 70/* find compatible node with uartlite */
78 p = of_get_flat_dt_prop(node, "compatible", &l); 71 p = of_get_flat_dt_prop(node, "compatible", &l);
79 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) && 72 if ((strncmp(p, "xlnx,xps-uartlite", 17) != 0) &&
80 (strncmp(p, "xlnx,opb-uartlite", 17) != 0)) 73 (strncmp(p, "xlnx,opb-uartlite", 17) != 0) &&
74 (strncmp(p, "xlnx,axi-uartlite", 17) != 0))
81 return 0; 75 return 0;
82 76
83 addr = of_get_flat_dt_prop(node, "reg", &l); 77 addr = of_get_flat_dt_prop(node, "reg", &l);
84 return *addr; /* return address */ 78 return be32_to_cpup(addr); /* return address */
85} 79}
86 80
87/* this function is looking for early uartlite console - Microblaze specific */ 81/* this function is looking for early uartlite console - Microblaze specific */
@@ -89,6 +83,40 @@ int __init early_uartlite_console(void)
89{ 83{
90 return of_scan_flat_dt(early_init_dt_scan_serial, NULL); 84 return of_scan_flat_dt(early_init_dt_scan_serial, NULL);
91} 85}
86
87/* MS this is Microblaze specifig function */
88static int __init early_init_dt_scan_serial_full(unsigned long node,
89 const char *uname, int depth, void *data)
90{
91 unsigned long l;
92 char *p;
93 unsigned int addr;
94
95 pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
96
97/* find all serial nodes */
98 if (strncmp(uname, "serial", 6) != 0)
99 return 0;
100
101 early_init_dt_check_for_initrd(node);
102
103/* find compatible node with uartlite */
104 p = of_get_flat_dt_prop(node, "compatible", &l);
105
106 if ((strncmp(p, "xlnx,xps-uart16550", 18) != 0) &&
107 (strncmp(p, "xlnx,axi-uart16550", 18) != 0))
108 return 0;
109
110 addr = *(u32 *)of_get_flat_dt_prop(node, "reg", &l);
111 addr += *(u32 *)of_get_flat_dt_prop(node, "reg-offset", &l);
112 return be32_to_cpu(addr); /* return address */
113}
114
115/* this function is looking for early uartlite console - Microblaze specific */
116int __init early_uart16550_console(void)
117{
118 return of_scan_flat_dt(early_init_dt_scan_serial_full, NULL);
119}
92#endif 120#endif
93 121
94void __init early_init_devtree(void *params) 122void __init early_init_devtree(void *params)
@@ -102,7 +130,7 @@ void __init early_init_devtree(void *params)
102 * device-tree, including the platform type, initrd location and 130 * device-tree, including the platform type, initrd location and
103 * size, TCE reserve, and more ... 131 * size, TCE reserve, and more ...
104 */ 132 */
105 of_scan_flat_dt(early_init_dt_scan_chosen, NULL); 133 of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
106 134
107 /* Scan memory nodes and rebuild MEMBLOCKs */ 135 /* Scan memory nodes and rebuild MEMBLOCKs */
108 memblock_init(); 136 memblock_init();
diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c
index 99d9b61cccb5..47187cc2cf00 100644
--- a/arch/microblaze/kernel/prom_parse.c
+++ b/arch/microblaze/kernel/prom_parse.c
@@ -2,88 +2,11 @@
2 2
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/string.h> 4#include <linux/string.h>
5#include <linux/pci_regs.h>
6#include <linux/module.h> 5#include <linux/module.h>
7#include <linux/ioport.h> 6#include <linux/ioport.h>
8#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
9#include <linux/of_address.h> 8#include <linux/of_address.h>
10#include <asm/prom.h> 9#include <asm/prom.h>
11#include <asm/pci-bridge.h>
12
13#ifdef CONFIG_PCI
14int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
15{
16 struct device_node *dn, *ppnode;
17 struct pci_dev *ppdev;
18 u32 lspec;
19 u32 laddr[3];
20 u8 pin;
21 int rc;
22
23 /* Check if we have a device node, if yes, fallback to standard OF
24 * parsing
25 */
26 dn = pci_device_to_OF_node(pdev);
27 if (dn)
28 return of_irq_map_one(dn, 0, out_irq);
29
30 /* Ok, we don't, time to have fun. Let's start by building up an
31 * interrupt spec. we assume #interrupt-cells is 1, which is standard
32 * for PCI. If you do different, then don't use that routine.
33 */
34 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
35 if (rc != 0)
36 return rc;
37 /* No pin, exit */
38 if (pin == 0)
39 return -ENODEV;
40
41 /* Now we walk up the PCI tree */
42 lspec = pin;
43 for (;;) {
44 /* Get the pci_dev of our parent */
45 ppdev = pdev->bus->self;
46
47 /* Ouch, it's a host bridge... */
48 if (ppdev == NULL) {
49 struct pci_controller *host;
50 host = pci_bus_to_host(pdev->bus);
51 ppnode = host ? host->dn : NULL;
52 /* No node for host bridge ? give up */
53 if (ppnode == NULL)
54 return -EINVAL;
55 } else
56 /* We found a P2P bridge, check if it has a node */
57 ppnode = pci_device_to_OF_node(ppdev);
58
59 /* Ok, we have found a parent with a device-node, hand over to
60 * the OF parsing code.
61 * We build a unit address from the linux device to be used for
62 * resolution. Note that we use the linux bus number which may
63 * not match your firmware bus numbering.
64 * Fortunately, in most cases, interrupt-map-mask doesn't
65 * include the bus number as part of the matching.
66 * You should still be careful about that though if you intend
67 * to rely on this function (you ship a firmware that doesn't
68 * create device nodes for all PCI devices).
69 */
70 if (ppnode)
71 break;
72
73 /* We can only get here if we hit a P2P bridge with no node,
74 * let's do standard swizzling and try again
75 */
76 lspec = pci_swizzle_interrupt_pin(pdev, lspec);
77 pdev = ppdev;
78 }
79
80 laddr[0] = (pdev->bus->number << 16)
81 | (pdev->devfn << 8);
82 laddr[1] = laddr[2] = 0;
83 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
84}
85EXPORT_SYMBOL_GPL(of_irq_map_pci);
86#endif /* CONFIG_PCI */
87 10
88void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 11void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
89 unsigned long *busno, unsigned long *phys, unsigned long *size) 12 unsigned long *busno, unsigned long *phys, unsigned long *size)
@@ -110,41 +33,3 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
110 cells = prop ? *(u32 *)prop : of_n_size_cells(dn); 33 cells = prop ? *(u32 *)prop : of_n_size_cells(dn);
111 *size = of_read_number(dma_window, cells); 34 *size = of_read_number(dma_window, cells);
112} 35}
113
114/**
115 * Search the device tree for the best MAC address to use. 'mac-address' is
116 * checked first, because that is supposed to contain to "most recent" MAC
117 * address. If that isn't set, then 'local-mac-address' is checked next,
118 * because that is the default address. If that isn't set, then the obsolete
119 * 'address' is checked, just in case we're using an old device tree.
120 *
121 * Note that the 'address' property is supposed to contain a virtual address of
122 * the register set, but some DTS files have redefined that property to be the
123 * MAC address.
124 *
125 * All-zero MAC addresses are rejected, because those could be properties that
126 * exist in the device tree, but were not set by U-Boot. For example, the
127 * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
128 * addresses. Some older U-Boots only initialized 'local-mac-address'. In
129 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
130 * but is all zeros.
131*/
132const void *of_get_mac_address(struct device_node *np)
133{
134 struct property *pp;
135
136 pp = of_find_property(np, "mac-address", NULL);
137 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
138 return pp->value;
139
140 pp = of_find_property(np, "local-mac-address", NULL);
141 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
142 return pp->value;
143
144 pp = of_find_property(np, "address", NULL);
145 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
146 return pp->value;
147
148 return NULL;
149}
150EXPORT_SYMBOL(of_get_mac_address);
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index dc03ffc8174a..6a8e0cc5c57d 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -39,6 +39,7 @@
39#include <linux/uaccess.h> 39#include <linux/uaccess.h>
40#include <asm/asm-offsets.h> 40#include <asm/asm-offsets.h>
41#include <asm/cacheflush.h> 41#include <asm/cacheflush.h>
42#include <asm/syscall.h>
42#include <asm/io.h> 43#include <asm/io.h>
43 44
44/* Returns the address where the register at REG_OFFS in P is stashed away. */ 45/* Returns the address where the register at REG_OFFS in P is stashed away. */
@@ -73,7 +74,8 @@ static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
73 return (microblaze_reg_t *)((char *)regs + reg_offs); 74 return (microblaze_reg_t *)((char *)regs + reg_offs);
74} 75}
75 76
76long arch_ptrace(struct task_struct *child, long request, long addr, long data) 77long arch_ptrace(struct task_struct *child, long request,
78 unsigned long addr, unsigned long data)
77{ 79{
78 int rval; 80 int rval;
79 unsigned long val = 0; 81 unsigned long val = 0;
@@ -99,7 +101,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
99 } else { 101 } else {
100 rval = -EIO; 102 rval = -EIO;
101 } 103 }
102 } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) { 104 } else if (addr < PT_SIZE && (addr & 0x3) == 0) {
103 microblaze_reg_t *reg_addr = reg_save_addr(addr, child); 105 microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
104 if (request == PTRACE_PEEKUSR) 106 if (request == PTRACE_PEEKUSR)
105 val = *reg_addr; 107 val = *reg_addr;
@@ -122,7 +124,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
122 rval = -EIO; 124 rval = -EIO;
123 125
124 if (rval == 0 && request == PTRACE_PEEKUSR) 126 if (rval == 0 && request == PTRACE_PEEKUSR)
125 rval = put_user(val, (unsigned long *)data); 127 rval = put_user(val, (unsigned long __user *)data);
126 break; 128 break;
127 default: 129 default:
128 rval = ptrace_request(child, request, addr, data); 130 rval = ptrace_request(child, request, addr, data);
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index f5f768842354..8e2c09b7ff26 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -92,16 +92,11 @@ inline unsigned get_romfs_len(unsigned *addr)
92} 92}
93#endif /* CONFIG_MTD_UCLINUX_EBSS */ 93#endif /* CONFIG_MTD_UCLINUX_EBSS */
94 94
95#if defined(CONFIG_EARLY_PRINTK) && defined(CONFIG_SERIAL_UARTLITE_CONSOLE)
96#define eprintk early_printk
97#else
98#define eprintk printk
99#endif
100
101void __init machine_early_init(const char *cmdline, unsigned int ram, 95void __init machine_early_init(const char *cmdline, unsigned int ram,
102 unsigned int fdt, unsigned int msr) 96 unsigned int fdt, unsigned int msr)
103{ 97{
104 unsigned long *src, *dst = (unsigned long *)0x0; 98 unsigned long *src, *dst;
99 unsigned int offset = 0;
105 100
106 /* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the 101 /* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the
107 * end of kernel. There are two position which we want to check. 102 * end of kernel. There are two position which we want to check.
@@ -167,14 +162,21 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
167#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR 162#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
168 if (msr) 163 if (msr)
169 eprintk("!!!Your kernel has setup MSR instruction but " 164 eprintk("!!!Your kernel has setup MSR instruction but "
170 "CPU don't have it %d\n", msr); 165 "CPU don't have it %x\n", msr);
171#else 166#else
172 if (!msr) 167 if (!msr)
173 eprintk("!!!Your kernel not setup MSR instruction but " 168 eprintk("!!!Your kernel not setup MSR instruction but "
174 "CPU have it %d\n", msr); 169 "CPU have it %x\n", msr);
175#endif 170#endif
176 171
177 for (src = __ivt_start; src < __ivt_end; src++, dst++) 172 /* Do not copy reset vectors. offset = 0x2 means skip the first
173 * two instructions. dst is pointer to MB vectors which are placed
174 * in block ram. If you want to copy reset vector setup offset to 0x0 */
175#if !CONFIG_MANUAL_RESET_VECTOR
176 offset = 0x2;
177#endif
178 dst = (unsigned long *) (offset * sizeof(u32));
179 for (src = __ivt_start + offset; src < __ivt_end; src++, dst++)
178 *dst = *src; 180 *dst = *src;
179 181
180 /* Initialize global data */ 182 /* Initialize global data */
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index d8d3bb396cd6..599671168980 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -93,7 +93,7 @@ static int restore_sigcontext(struct pt_regs *regs,
93asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) 93asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
94{ 94{
95 struct rt_sigframe __user *frame = 95 struct rt_sigframe __user *frame =
96 (struct rt_sigframe __user *)(regs->r1 + STATE_SAVE_ARG_SPACE); 96 (struct rt_sigframe __user *)(regs->r1);
97 97
98 sigset_t set; 98 sigset_t set;
99 int rval; 99 int rval;
@@ -197,8 +197,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
197 197
198 /* Create the ucontext. */ 198 /* Create the ucontext. */
199 err |= __put_user(0, &frame->uc.uc_flags); 199 err |= __put_user(0, &frame->uc.uc_flags);
200 err |= __put_user(0, &frame->uc.uc_link); 200 err |= __put_user(NULL, &frame->uc.uc_link);
201 err |= __put_user((void *)current->sas_ss_sp, 201 err |= __put_user((void __user *)current->sas_ss_sp,
202 &frame->uc.uc_stack.ss_sp); 202 &frame->uc.uc_stack.ss_sp);
203 err |= __put_user(sas_ss_flags(regs->r1), 203 err |= __put_user(sas_ss_flags(regs->r1),
204 &frame->uc.uc_stack.ss_flags); 204 &frame->uc.uc_stack.ss_flags);
@@ -247,7 +247,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
247 goto give_sigsegv; 247 goto give_sigsegv;
248 248
249 /* Set up registers for signal handler */ 249 /* Set up registers for signal handler */
250 regs->r1 = (unsigned long) frame - STATE_SAVE_ARG_SPACE; 250 regs->r1 = (unsigned long) frame;
251 251
252 /* Signal handler args: */ 252 /* Signal handler args: */
253 regs->r5 = signal; /* arg 0: signum */ 253 regs->r5 = signal; /* arg 0: signum */
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c
index 2250fe9d269b..e5b154f24f85 100644
--- a/arch/microblaze/kernel/sys_microblaze.c
+++ b/arch/microblaze/kernel/sys_microblaze.c
@@ -40,7 +40,8 @@ asmlinkage long microblaze_vfork(struct pt_regs *regs)
40 regs, 0, NULL, NULL); 40 regs, 0, NULL, NULL);
41} 41}
42 42
43asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs *regs) 43asmlinkage long microblaze_clone(int flags, unsigned long stack,
44 struct pt_regs *regs)
44{ 45{
45 if (!stack) 46 if (!stack)
46 stack = regs->r1; 47 stack = regs->r1;
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index 03376dc814c9..d915a122c865 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -372,3 +372,11 @@ ENTRY(sys_call_table)
372 .long sys_rt_tgsigqueueinfo /* 365 */ 372 .long sys_rt_tgsigqueueinfo /* 365 */
373 .long sys_perf_event_open 373 .long sys_perf_event_open
374 .long sys_recvmmsg 374 .long sys_recvmmsg
375 .long sys_fanotify_init
376 .long sys_fanotify_mark
377 .long sys_prlimit64 /* 370 */
378 .long sys_name_to_handle_at
379 .long sys_open_by_handle_at
380 .long sys_clock_adjtime
381 .long sys_syncfs
382 .long sys_setns /* 375 */
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index b1380ae93ae1..e5550ce4e0eb 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -38,6 +38,9 @@ static unsigned int timer_baseaddr;
38#define TIMER_BASE timer_baseaddr 38#define TIMER_BASE timer_baseaddr
39#endif 39#endif
40 40
41static unsigned int freq_div_hz;
42static unsigned int timer_clock_freq;
43
41#define TCSR0 (0x00) 44#define TCSR0 (0x00)
42#define TLR0 (0x04) 45#define TLR0 (0x04)
43#define TCR0 (0x08) 46#define TCR0 (0x08)
@@ -115,7 +118,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
115 switch (mode) { 118 switch (mode) {
116 case CLOCK_EVT_MODE_PERIODIC: 119 case CLOCK_EVT_MODE_PERIODIC:
117 printk(KERN_INFO "%s: periodic\n", __func__); 120 printk(KERN_INFO "%s: periodic\n", __func__);
118 microblaze_timer0_start_periodic(cpuinfo.freq_div_hz); 121 microblaze_timer0_start_periodic(freq_div_hz);
119 break; 122 break;
120 case CLOCK_EVT_MODE_ONESHOT: 123 case CLOCK_EVT_MODE_ONESHOT:
121 printk(KERN_INFO "%s: oneshot\n", __func__); 124 printk(KERN_INFO "%s: oneshot\n", __func__);
@@ -168,7 +171,7 @@ static struct irqaction timer_irqaction = {
168static __init void microblaze_clockevent_init(void) 171static __init void microblaze_clockevent_init(void)
169{ 172{
170 clockevent_microblaze_timer.mult = 173 clockevent_microblaze_timer.mult =
171 div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 174 div_sc(timer_clock_freq, NSEC_PER_SEC,
172 clockevent_microblaze_timer.shift); 175 clockevent_microblaze_timer.shift);
173 clockevent_microblaze_timer.max_delta_ns = 176 clockevent_microblaze_timer.max_delta_ns =
174 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer); 177 clockevent_delta2ns((u32)~0, &clockevent_microblaze_timer);
@@ -199,9 +202,9 @@ static struct cyclecounter microblaze_cc = {
199 .shift = 8, 202 .shift = 8,
200}; 203};
201 204
202int __init init_microblaze_timecounter(void) 205static int __init init_microblaze_timecounter(void)
203{ 206{
204 microblaze_cc.mult = div_sc(cpuinfo.cpu_clock_freq, NSEC_PER_SEC, 207 microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
205 microblaze_cc.shift); 208 microblaze_cc.shift);
206 209
207 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock()); 210 timecounter_init(&microblaze_tc, &microblaze_cc, sched_clock());
@@ -214,16 +217,12 @@ static struct clocksource clocksource_microblaze = {
214 .rating = 300, 217 .rating = 300,
215 .read = microblaze_read, 218 .read = microblaze_read,
216 .mask = CLOCKSOURCE_MASK(32), 219 .mask = CLOCKSOURCE_MASK(32),
217 .shift = 8, /* I can shift it */
218 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 220 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
219}; 221};
220 222
221static int __init microblaze_clocksource_init(void) 223static int __init microblaze_clocksource_init(void)
222{ 224{
223 clocksource_microblaze.mult = 225 if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq))
224 clocksource_hz2mult(cpuinfo.cpu_clock_freq,
225 clocksource_microblaze.shift);
226 if (clocksource_register(&clocksource_microblaze))
227 panic("failed to register clocksource"); 226 panic("failed to register clocksource");
228 227
229 /* stop timer1 */ 228 /* stop timer1 */
@@ -247,6 +246,7 @@ void __init time_init(void)
247 u32 irq, i = 0; 246 u32 irq, i = 0;
248 u32 timer_num = 1; 247 u32 timer_num = 1;
249 struct device_node *timer = NULL; 248 struct device_node *timer = NULL;
249 const void *prop;
250#ifdef CONFIG_SELFMOD_TIMER 250#ifdef CONFIG_SELFMOD_TIMER
251 unsigned int timer_baseaddr = 0; 251 unsigned int timer_baseaddr = 0;
252 int arr_func[] = { 252 int arr_func[] = {
@@ -258,12 +258,10 @@ void __init time_init(void)
258 0 258 0
259 }; 259 };
260#endif 260#endif
261 char *timer_list[] = { 261 const char * const timer_list[] = {
262 "xlnx,xps-timer-1.00.a", 262 "xlnx,xps-timer-1.00.a",
263 "xlnx,opb-timer-1.00.b", 263 NULL
264 "xlnx,opb-timer-1.00.a", 264 };
265 NULL
266 };
267 265
268 for (i = 0; timer_list[i] != NULL; i++) { 266 for (i = 0; timer_list[i] != NULL; i++) {
269 timer = of_find_compatible_node(NULL, NULL, timer_list[i]); 267 timer = of_find_compatible_node(NULL, NULL, timer_list[i]);
@@ -272,13 +270,13 @@ void __init time_init(void)
272 } 270 }
273 BUG_ON(!timer); 271 BUG_ON(!timer);
274 272
275 timer_baseaddr = *(int *) of_get_property(timer, "reg", NULL); 273 timer_baseaddr = be32_to_cpup(of_get_property(timer, "reg", NULL));
276 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE); 274 timer_baseaddr = (unsigned long) ioremap(timer_baseaddr, PAGE_SIZE);
277 irq = *(int *) of_get_property(timer, "interrupts", NULL); 275 irq = be32_to_cpup(of_get_property(timer, "interrupts", NULL));
278 timer_num = 276 timer_num = be32_to_cpup(of_get_property(timer,
279 *(int *) of_get_property(timer, "xlnx,one-timer-only", NULL); 277 "xlnx,one-timer-only", NULL));
280 if (timer_num) { 278 if (timer_num) {
281 printk(KERN_EMERG "Please enable two timers in HW\n"); 279 eprintk(KERN_EMERG "Please enable two timers in HW\n");
282 BUG(); 280 BUG();
283 } 281 }
284 282
@@ -288,7 +286,14 @@ void __init time_init(void)
288 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n", 286 printk(KERN_INFO "%s #0 at 0x%08x, irq=%d\n",
289 timer_list[i], timer_baseaddr, irq); 287 timer_list[i], timer_baseaddr, irq);
290 288
291 cpuinfo.freq_div_hz = cpuinfo.cpu_clock_freq / HZ; 289 /* If there is clock-frequency property than use it */
290 prop = of_get_property(timer, "clock-frequency", NULL);
291 if (prop)
292 timer_clock_freq = be32_to_cpup(prop);
293 else
294 timer_clock_freq = cpuinfo.cpu_clock_freq;
295
296 freq_div_hz = timer_clock_freq / HZ;
292 297
293 setup_irq(irq, &timer_irqaction); 298 setup_irq(irq, &timer_irqaction);
294#ifdef CONFIG_HEART_BEAT 299#ifdef CONFIG_HEART_BEAT
diff --git a/arch/microblaze/kernel/unwind.c b/arch/microblaze/kernel/unwind.c
index fefac5c33586..9781a528cfc9 100644
--- a/arch/microblaze/kernel/unwind.c
+++ b/arch/microblaze/kernel/unwind.c
@@ -183,7 +183,7 @@ static inline void unwind_trap(struct task_struct *task, unsigned long pc,
183 * @trace : Where to store stack backtrace (PC values). 183 * @trace : Where to store stack backtrace (PC values).
184 * NULL == print backtrace to kernel log 184 * NULL == print backtrace to kernel log
185 */ 185 */
186void microblaze_unwind_inner(struct task_struct *task, 186static void microblaze_unwind_inner(struct task_struct *task,
187 unsigned long pc, unsigned long fp, 187 unsigned long pc, unsigned long fp,
188 unsigned long leaf_return, 188 unsigned long leaf_return,
189 struct stack_trace *trace) 189 struct stack_trace *trace)
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index a09f2962fbec..ac0e1a5d4782 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -8,7 +8,6 @@
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
12OUTPUT_ARCH(microblaze) 11OUTPUT_ARCH(microblaze)
13ENTRY(microblaze_start) 12ENTRY(microblaze_start)
14 13
@@ -16,7 +15,11 @@ ENTRY(microblaze_start)
16#include <asm-generic/vmlinux.lds.h> 15#include <asm-generic/vmlinux.lds.h>
17#include <asm/thread_info.h> 16#include <asm/thread_info.h>
18 17
18#ifdef __MICROBLAZEEL__
19jiffies = jiffies_64;
20#else
19jiffies = jiffies_64 + 4; 21jiffies = jiffies_64 + 4;
22#endif
20 23
21SECTIONS { 24SECTIONS {
22 . = CONFIG_KERNEL_START; 25 . = CONFIG_KERNEL_START;
@@ -67,11 +70,6 @@ SECTIONS {
67 RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE) 70 RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
68 _edata = . ; 71 _edata = . ;
69 72
70 /* Reserve some low RAM for r0 based memory references */
71 . = ALIGN(0x4) ;
72 r0_ram = . ;
73 . = . + PAGE_SIZE; /* a page should be enough */
74
75 /* Under the microblaze ABI, .sdata and .sbss must be contiguous */ 73 /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
76 . = ALIGN(8); 74 . = ALIGN(8);
77 .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) { 75 .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) {
@@ -120,20 +118,10 @@ SECTIONS {
120 118
121 __init_end_before_initramfs = .; 119 __init_end_before_initramfs = .;
122 120
123 .init.ramfs ALIGN(PAGE_SIZE) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { 121 .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
124 __initramfs_start = .; 122 INIT_RAM_FS
125 *(.init.ramfs)
126 __initramfs_end = .;
127 . = ALIGN(4);
128 LONG(0);
129/*
130 * FIXME this can break initramfs for MMU.
131 * Pad init.ramfs up to page boundary,
132 * so that __init_end == __bss_start. This will make image.elf
133 * consistent with the image.bin
134 */
135 /* . = ALIGN(PAGE_SIZE); */
136 } 123 }
124
137 __init_end = .; 125 __init_end = .;
138 126
139 .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) { 127 .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) {