aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 17:23:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-17 17:23:42 -0500
commitb0f0c26a2ed49eccf98a011b86fe24fb9f2b35f6 (patch)
treead2efaa0ab0459257948127c56d4a7747cbefa11
parent99fa0ad92c4fd8b529c89b3640b42323984be761 (diff)
parentd16d2be111a61baf3a4696f07bfc7a8e36697cec (diff)
Merge tag 'nios2-v3.20-rc1' of git://git.rocketboards.org/linux-socfpga-next
Pull arch/nios2 update from Ley Foon Tan: "Here is the nios2 update for 3.20: - add early printk support - add kgdb support - add compressed kernel support - bugfixes" * tag 'nios2-v3.20-rc1' of git://git.rocketboards.org/linux-socfpga-next: nios2: add kgdb support MAINTAINERS: update arch/nios2 git tree nios2: default CONFIG_NIOS2_BOOT_LINK_OFFSET to 8MB nios2: Add support for compressed kernel nios2: add early printk support nios2: Port OOM changes to do_page_fault() nios2: Remove unused prepare_to_copy()
-rw-r--r--MAINTAINERS2
-rw-r--r--arch/nios2/Kconfig9
-rw-r--r--arch/nios2/Kconfig.debug11
-rw-r--r--arch/nios2/boot/Makefile7
-rw-r--r--arch/nios2/boot/compressed/Makefile19
-rw-r--r--arch/nios2/boot/compressed/console.c125
-rw-r--r--arch/nios2/boot/compressed/head.S117
-rw-r--r--arch/nios2/boot/compressed/misc.c187
-rw-r--r--arch/nios2/boot/compressed/vmlinux.lds.S58
-rw-r--r--arch/nios2/boot/compressed/vmlinux.scr28
-rw-r--r--arch/nios2/configs/3c120_defconfig1
-rw-r--r--arch/nios2/include/asm/kgdb.h93
-rw-r--r--arch/nios2/include/asm/processor.h3
-rw-r--r--arch/nios2/include/asm/prom.h22
-rw-r--r--arch/nios2/kernel/Makefile2
-rw-r--r--arch/nios2/kernel/early_printk.c118
-rw-r--r--arch/nios2/kernel/entry.S12
-rw-r--r--arch/nios2/kernel/kgdb.c171
-rw-r--r--arch/nios2/kernel/prom.c52
-rw-r--r--arch/nios2/kernel/setup.c4
-rw-r--r--arch/nios2/mm/fault.c37
21 files changed, 1067 insertions, 11 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 85024e23309f..3eee4c7739ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6876,7 +6876,7 @@ F: drivers/scsi/nsp32*
6876NIOS2 ARCHITECTURE 6876NIOS2 ARCHITECTURE
6877M: Ley Foon Tan <lftan@altera.com> 6877M: Ley Foon Tan <lftan@altera.com>
6878L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) 6878L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
6879T: git git://git.rocketboards.org/linux-socfpga.git 6879T: git git://git.rocketboards.org/linux-socfpga-next.git
6880S: Maintained 6880S: Maintained
6881F: arch/nios2/ 6881F: arch/nios2/
6882 6882
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index 2361acf6d2b1..437555424bda 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -8,6 +8,7 @@ config NIOS2
8 select GENERIC_IRQ_PROBE 8 select GENERIC_IRQ_PROBE
9 select GENERIC_IRQ_SHOW 9 select GENERIC_IRQ_SHOW
10 select HAVE_ARCH_TRACEHOOK 10 select HAVE_ARCH_TRACEHOOK
11 select HAVE_ARCH_KGDB
11 select IRQ_DOMAIN 12 select IRQ_DOMAIN
12 select MODULES_USE_ELF_RELA 13 select MODULES_USE_ELF_RELA
13 select OF 14 select OF
@@ -134,6 +135,14 @@ config NIOS2_PASS_CMDLINE
134 will override "Default kernel command string". 135 will override "Default kernel command string".
135 Say N if you are unsure. 136 Say N if you are unsure.
136 137
138config NIOS2_BOOT_LINK_OFFSET
139 hex "Link address offset for booting"
140 default "0x00500000"
141 help
142 This option allows you to set the link address offset of the zImage.
143 This can be useful if you are on a board which has a small amount of
144 memory.
145
137endmenu 146endmenu
138 147
139menu "Advanced setup" 148menu "Advanced setup"
diff --git a/arch/nios2/Kconfig.debug b/arch/nios2/Kconfig.debug
index 8d4e6bacd997..2fd08cbfdddb 100644
--- a/arch/nios2/Kconfig.debug
+++ b/arch/nios2/Kconfig.debug
@@ -14,4 +14,15 @@ config DEBUG_STACK_USAGE
14 14
15 This option will slow down process creation somewhat. 15 This option will slow down process creation somewhat.
16 16
17config EARLY_PRINTK
18 bool "Activate early kernel debugging"
19 default y
20 select SERIAL_CORE_CONSOLE
21 depends on SERIAL_ALTERA_JTAGUART_CONSOLE || SERIAL_ALTERA_UART_CONSOLE
22 help
23 Enable early printk on console
24 This is useful for kernel debugging when your machine crashes very
25 early before the console code is initialized.
26 You should normally say N here, unless you want to debug such a crash.
27
17endmenu 28endmenu
diff --git a/arch/nios2/boot/Makefile b/arch/nios2/boot/Makefile
index 59392dc0bdcb..c899876320df 100644
--- a/arch/nios2/boot/Makefile
+++ b/arch/nios2/boot/Makefile
@@ -24,6 +24,13 @@ $(obj)/vmImage: $(obj)/vmlinux.gz
24 $(call if_changed,uimage) 24 $(call if_changed,uimage)
25 @$(kecho) 'Kernel: $@ is ready' 25 @$(kecho) 'Kernel: $@ is ready'
26 26
27$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
28 $(call if_changed,objcopy)
29 @$(kecho) 'Kernel: $@ is ready'
30
31$(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE
32 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
33
27# Rule to build device tree blobs 34# Rule to build device tree blobs
28DTB_SRC := $(patsubst "%",%,$(CONFIG_NIOS2_DTB_SOURCE)) 35DTB_SRC := $(patsubst "%",%,$(CONFIG_NIOS2_DTB_SOURCE))
29 36
diff --git a/arch/nios2/boot/compressed/Makefile b/arch/nios2/boot/compressed/Makefile
new file mode 100644
index 000000000000..5b0fb346d888
--- /dev/null
+++ b/arch/nios2/boot/compressed/Makefile
@@ -0,0 +1,19 @@
1#
2# create a compressed vmlinux image from the original vmlinux
3#
4
5targets := vmlinux head.o misc.o piggy.o vmlinux.lds
6asflags-y :=
7
8OBJECTS = $(obj)/head.o $(obj)/misc.o
9
10LDFLAGS_vmlinux := -T
11
12$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
13 $(call if_changed,ld)
14 @:
15
16LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T
17
18$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/../vmlinux.gz FORCE
19 $(call if_changed,ld)
diff --git a/arch/nios2/boot/compressed/console.c b/arch/nios2/boot/compressed/console.c
new file mode 100644
index 000000000000..2675e879b85a
--- /dev/null
+++ b/arch/nios2/boot/compressed/console.c
@@ -0,0 +1,125 @@
1/*
2 * Copyright (C) 2008-2010 Thomas Chou <thomas@wytron.com.tw>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19#include <linux/io.h>
20
21#if (defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE))\
22 || (defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE))
23static void *my_ioremap(unsigned long physaddr)
24{
25 return (void *)(physaddr | CONFIG_NIOS2_IO_REGION_BASE);
26}
27#endif
28
29#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE)
30
31#define ALTERA_JTAGUART_SIZE 8
32#define ALTERA_JTAGUART_DATA_REG 0
33#define ALTERA_JTAGUART_CONTROL_REG 4
34#define ALTERA_JTAGUART_CONTROL_AC_MSK (0x00000400)
35#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK (0xFFFF0000)
36static void *uartbase;
37
38#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
39static void jtag_putc(int ch)
40{
41 if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
42 ALTERA_JTAGUART_CONTROL_WSPACE_MSK)
43 writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
44}
45#else
46static void jtag_putc(int ch)
47{
48 while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
49 ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0)
50 ;
51 writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
52}
53#endif
54
55static int putchar(int ch)
56{
57 jtag_putc(ch);
58 return ch;
59}
60
61static void console_init(void)
62{
63 uartbase = my_ioremap((unsigned long) JTAG_UART_BASE);
64 writel(ALTERA_JTAGUART_CONTROL_AC_MSK,
65 uartbase + ALTERA_JTAGUART_CONTROL_REG);
66}
67
68#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE)
69
70#define ALTERA_UART_SIZE 32
71#define ALTERA_UART_TXDATA_REG 4
72#define ALTERA_UART_STATUS_REG 8
73#define ALTERA_UART_DIVISOR_REG 16
74#define ALTERA_UART_STATUS_TRDY_MSK (0x40)
75static unsigned uartbase;
76
77static void uart_putc(int ch)
78{
79 int i;
80
81 for (i = 0; (i < 0x10000); i++) {
82 if (readw(uartbase + ALTERA_UART_STATUS_REG) &
83 ALTERA_UART_STATUS_TRDY_MSK)
84 break;
85 }
86 writeb(ch, uartbase + ALTERA_UART_TXDATA_REG);
87}
88
89static int putchar(int ch)
90{
91 uart_putc(ch);
92 if (ch == '\n')
93 uart_putc('\r');
94 return ch;
95}
96
97static void console_init(void)
98{
99 unsigned int baud, baudclk;
100
101 uartbase = (unsigned long) my_ioremap((unsigned long) UART0_BASE);
102 baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
103 baudclk = UART0_FREQ / baud;
104 writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG);
105}
106
107#else
108
109static int putchar(int ch)
110{
111 return ch;
112}
113
114static void console_init(void)
115{
116}
117
118#endif
119
120static int puts(const char *s)
121{
122 while (*s)
123 putchar(*s++);
124 return 0;
125}
diff --git a/arch/nios2/boot/compressed/head.S b/arch/nios2/boot/compressed/head.S
new file mode 100644
index 000000000000..15c6c48dd909
--- /dev/null
+++ b/arch/nios2/boot/compressed/head.S
@@ -0,0 +1,117 @@
1/*
2 * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
3 *
4 * Based on arch/nios2/kernel/head.S
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 */
11
12/*
13 * This code can be loaded anywhere, eg FLASH ROM as reset vector,
14 * as long as output does not overlap it.
15 */
16
17#include <linux/linkage.h>
18#include <asm/cache.h>
19
20 .text
21 .set noat
22ENTRY(_start)
23 wrctl status, r0 /* disable interrupt */
24 /* invalidate all instruction cache */
25 movia r1, NIOS2_ICACHE_SIZE
26 movui r2, NIOS2_ICACHE_LINE_SIZE
271: initi r1
28 sub r1, r1, r2
29 bgt r1, r0, 1b
30 /* invalidate all data cache */
31 movia r1, NIOS2_DCACHE_SIZE
32 movui r2, NIOS2_DCACHE_LINE_SIZE
331: initd 0(r1)
34 sub r1, r1, r2
35 bgt r1, r0, 1b
36
37 nextpc r1 /* Find out where we are */
38chkadr:
39 movia r2, chkadr
40 beq r1, r2, finish_move /* We are running in correct address,
41 done */
42 /* move code, r1: src, r2: dest, r3: last dest */
43 addi r1, r1, (_start - chkadr) /* Source */
44 movia r2, _start /* Destination */
45 movia r3, __bss_start /* End of copy */
461: ldw r8, 0(r1) /* load a word from [r1] */
47 stw r8, 0(r2) /* stort a word to dest [r2] */
48 addi r1, r1, 4 /* inc the src addr */
49 addi r2, r2, 4 /* inc the dest addr */
50 blt r2, r3, 1b
51 /* flush the data cache after moving */
52 movia r1, NIOS2_DCACHE_SIZE
53 movui r2, NIOS2_DCACHE_LINE_SIZE
541: flushd 0(r1)
55 sub r1, r1, r2
56 bgt r1, r0, 1b
57 movia r1, finish_move
58 jmp r1 /* jmp to linked address */
59
60finish_move:
61 /* zero out the .bss segment (uninitialized common data) */
62 movia r2, __bss_start /* presume nothing is between */
63 movia r1, _end /* the .bss and _end. */
641: stb r0, 0(r2)
65 addi r2, r2, 1
66 bne r1, r2, 1b
67 /*
68 * set up the stack pointer, some where higher than _end.
69 * The stack space must be greater than 32K for decompress.
70 */
71 movia sp, 0x10000
72 add sp, sp, r1
73 /* save args passed from u-boot, maybe */
74 addi sp, sp, -16
75 stw r4, 0(sp)
76 stw r5, 4(sp)
77 stw r6, 8(sp)
78 stw r7, 12(sp)
79 /* decompress the kernel */
80 call decompress_kernel
81 /* pass saved args to kernel */
82 ldw r4, 0(sp)
83 ldw r5, 4(sp)
84 ldw r6, 8(sp)
85 ldw r7, 12(sp)
86
87 /* flush all data cache after decompressing */
88 movia r1, NIOS2_DCACHE_SIZE
89 movui r2, NIOS2_DCACHE_LINE_SIZE
901: flushd 0(r1)
91 sub r1, r1, r2
92 bgt r1, r0, 1b
93 /* flush all instruction cache */
94 movia r1, NIOS2_ICACHE_SIZE
95 movui r2, NIOS2_ICACHE_LINE_SIZE
961: flushi r1
97 sub r1, r1, r2
98 bgt r1, r0, 1b
99 flushp
100 /* jump to start real kernel */
101 movia r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE)
102 jmp r1
103
104 .balign 512
105fake_headers_as_bzImage:
106 .short 0
107 .ascii "HdrS"
108 .short 0x0202
109 .short 0
110 .short 0
111 .byte 0x00, 0x10
112 .short 0
113 .byte 0
114 .byte 1
115 .byte 0x00, 0x80
116 .long 0
117 .long 0
diff --git a/arch/nios2/boot/compressed/misc.c b/arch/nios2/boot/compressed/misc.c
new file mode 100644
index 000000000000..84377825ef1a
--- /dev/null
+++ b/arch/nios2/boot/compressed/misc.c
@@ -0,0 +1,187 @@
1/*
2 * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 *
9 * Adapted for SH by Stuart Menefy, Aug 1999
10 *
11 * Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
12 *
13 * Based on arch/sh/boot/compressed/misc.c
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 *
28 */
29
30#include <linux/string.h>
31
32/*
33 * gzip declarations
34 */
35#define OF(args) args
36#define STATIC static
37
38#undef memset
39#undef memcpy
40#define memzero(s, n) memset((s), 0, (n))
41
42typedef unsigned char uch;
43typedef unsigned short ush;
44typedef unsigned long ulg;
45#define WSIZE 0x8000 /* Window size must be at least 32k, */
46 /* and a power of two */
47
48static uch *inbuf; /* input buffer */
49static uch window[WSIZE]; /* Sliding window buffer */
50
51static unsigned insize; /* valid bytes in inbuf */
52static unsigned inptr; /* index of next byte to be processed in inbuf */
53static unsigned outcnt; /* bytes in output buffer */
54
55/* gzip flag byte */
56#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
57#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip
58 file */
59#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
60#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
61#define COMMENT 0x10 /* bit 4 set: file comment present */
62#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
63#define RESERVED 0xC0 /* bit 6,7: reserved */
64
65#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
66
67#ifdef DEBUG
68# define Assert(cond, msg) {if (!(cond)) error(msg); }
69# define Trace(x) fprintf x
70# define Tracev(x) {if (verbose) fprintf x ; }
71# define Tracevv(x) {if (verbose > 1) fprintf x ; }
72# define Tracec(c, x) {if (verbose && (c)) fprintf x ; }
73# define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; }
74#else
75# define Assert(cond, msg)
76# define Trace(x)
77# define Tracev(x)
78# define Tracevv(x)
79# define Tracec(c, x)
80# define Tracecv(c, x)
81#endif
82static int fill_inbuf(void);
83static void flush_window(void);
84static void error(char *m);
85
86extern char input_data[];
87extern int input_len;
88
89static long bytes_out;
90static uch *output_data;
91static unsigned long output_ptr;
92
93#include "console.c"
94
95static void error(char *m);
96
97int puts(const char *);
98
99extern int _end;
100static unsigned long free_mem_ptr;
101static unsigned long free_mem_end_ptr;
102
103#define HEAP_SIZE 0x10000
104
105#include "../../../../lib/inflate.c"
106
107void *memset(void *s, int c, size_t n)
108{
109 int i;
110 char *ss = (char *)s;
111
112 for (i = 0; i < n; i++)
113 ss[i] = c;
114 return s;
115}
116
117void *memcpy(void *__dest, __const void *__src, size_t __n)
118{
119 int i;
120 char *d = (char *)__dest, *s = (char *)__src;
121
122 for (i = 0; i < __n; i++)
123 d[i] = s[i];
124 return __dest;
125}
126
127/*
128 * Fill the input buffer. This is called only when the buffer is empty
129 * and at least one byte is really needed.
130 */
131static int fill_inbuf(void)
132{
133 if (insize != 0)
134 error("ran out of input data");
135
136 inbuf = input_data;
137 insize = input_len;
138 inptr = 1;
139 return inbuf[0];
140}
141
142/*
143 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
144 * (Used for the decompressed data only.)
145 */
146static void flush_window(void)
147{
148 ulg c = crc; /* temporary variable */
149 unsigned n;
150 uch *in, *out, ch;
151
152 in = window;
153 out = &output_data[output_ptr];
154 for (n = 0; n < outcnt; n++) {
155 ch = *out++ = *in++;
156 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
157 }
158 crc = c;
159 bytes_out += (ulg)outcnt;
160 output_ptr += (ulg)outcnt;
161 outcnt = 0;
162}
163
164static void error(char *x)
165{
166 puts("\nERROR\n");
167 puts(x);
168 puts("\n\n -- System halted");
169
170 while (1) /* Halt */
171 ;
172}
173
174void decompress_kernel(void)
175{
176 output_data = (void *) (CONFIG_NIOS2_MEM_BASE |
177 CONFIG_NIOS2_KERNEL_REGION_BASE);
178 output_ptr = 0;
179 free_mem_ptr = (unsigned long)&_end;
180 free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
181
182 console_init();
183 makecrc();
184 puts("Uncompressing Linux... ");
185 gunzip();
186 puts("Ok, booting the kernel.\n");
187}
diff --git a/arch/nios2/boot/compressed/vmlinux.lds.S b/arch/nios2/boot/compressed/vmlinux.lds.S
new file mode 100644
index 000000000000..e867b3756059
--- /dev/null
+++ b/arch/nios2/boot/compressed/vmlinux.lds.S
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19#include <asm-generic/vmlinux.lds.h>
20
21OUTPUT_FORMAT("elf32-littlenios2", "elf32-littlenios2", "elf32-littlenios2")
22
23OUTPUT_ARCH(nios)
24ENTRY(_start) /* Defined in head.S */
25
26SECTIONS
27{
28 . = (CONFIG_NIOS2_MEM_BASE + CONFIG_NIOS2_BOOT_LINK_OFFSET) | \
29 CONFIG_NIOS2_KERNEL_REGION_BASE;
30
31 _text = .;
32 .text : { *(.text) } = 0
33 .rodata : { *(.rodata) *(.rodata.*) }
34 _etext = .;
35
36 . = ALIGN(32 / 8);
37 .data : { *(.data) }
38 . = ALIGN(32 / 8);
39 _got = .;
40 .got : {
41 *(.got.plt)
42 *(.igot.plt)
43 *(.got)
44 *(.igot)
45 }
46 _egot = .;
47 _edata = .;
48
49 . = ALIGN(32 / 8);
50 __bss_start = .;
51 .bss : { *(.bss) *(.sbss) }
52 . = ALIGN(32 / 8);
53 _ebss = .;
54 end = . ;
55 _end = . ;
56
57 got_len = (_egot - _got);
58}
diff --git a/arch/nios2/boot/compressed/vmlinux.scr b/arch/nios2/boot/compressed/vmlinux.scr
new file mode 100644
index 000000000000..28c42f1d127e
--- /dev/null
+++ b/arch/nios2/boot/compressed/vmlinux.scr
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19SECTIONS
20{
21 .data : {
22 input_len = .;
23 LONG(input_data_end - input_data) input_data = .;
24 *(.data)
25 . = ALIGN(4);
26 input_data_end = .;
27 }
28}
diff --git a/arch/nios2/configs/3c120_defconfig b/arch/nios2/configs/3c120_defconfig
index 87541f0a5d6e..9451940678a0 100644
--- a/arch/nios2/configs/3c120_defconfig
+++ b/arch/nios2/configs/3c120_defconfig
@@ -22,6 +22,7 @@ CONFIG_NIOS2_DCACHE_SIZE=0x8000
22CONFIG_NIOS2_ICACHE_SIZE=0x8000 22CONFIG_NIOS2_ICACHE_SIZE=0x8000
23# CONFIG_NIOS2_CMDLINE_IGNORE_DTB is not set 23# CONFIG_NIOS2_CMDLINE_IGNORE_DTB is not set
24CONFIG_NIOS2_PASS_CMDLINE=y 24CONFIG_NIOS2_PASS_CMDLINE=y
25CONFIG_NIOS2_BOOT_LINK_OFFSET=0x00800000
25CONFIG_NET=y 26CONFIG_NET=y
26CONFIG_PACKET=y 27CONFIG_PACKET=y
27CONFIG_UNIX=y 28CONFIG_UNIX=y
diff --git a/arch/nios2/include/asm/kgdb.h b/arch/nios2/include/asm/kgdb.h
new file mode 100644
index 000000000000..8fd5e3b66c57
--- /dev/null
+++ b/arch/nios2/include/asm/kgdb.h
@@ -0,0 +1,93 @@
1/*
2 * Copyright (C) 2015 Altera Corporation
3 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
4 *
5 * Based on the code posted by Kazuyasu on the Altera Forum at:
6 * http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23#ifndef _ASM_NIOS2_KGDB_H
24#define _ASM_NIOS2_KGDB_H
25
26#define CACHE_FLUSH_IS_SAFE 1
27#define BUFMAX 2048
28
29enum regnames {
30 GDB_R0 = 0,
31 GDB_AT,
32 GDB_R2,
33 GDB_R3,
34 GDB_R4,
35 GDB_R5,
36 GDB_R6,
37 GDB_R7,
38 GDB_R8,
39 GDB_R9,
40 GDB_R10,
41 GDB_R11,
42 GDB_R12,
43 GDB_R13,
44 GDB_R14,
45 GDB_R15,
46 GDB_R16,
47 GDB_R17,
48 GDB_R18,
49 GDB_R19,
50 GDB_R20,
51 GDB_R21,
52 GDB_R22,
53 GDB_R23,
54 GDB_ET,
55 GDB_BT,
56 GDB_GP,
57 GDB_SP,
58 GDB_FP,
59 GDB_EA,
60 GDB_BA,
61 GDB_RA,
62 GDB_PC,
63 GDB_STATUS,
64 GDB_ESTATUS,
65 GDB_BSTATUS,
66 GDB_IENABLE,
67 GDB_IPENDING,
68 GDB_CPUID,
69 GDB_CTL6,
70 GDB_EXCEPTION,
71 GDB_PTEADDR,
72 GDB_TLBACC,
73 GDB_TLBMISC,
74 GDB_ECCINJ,
75 GDB_BADADDR,
76 GDB_CONFIG,
77 GDB_MPUBASE,
78 GDB_MPUACC,
79 /* do not change the last entry or anything below! */
80 GDB_NUMREGBYTES /* number of registers */
81};
82
83#define GDB_SIZEOF_REG sizeof(u32)
84#define DBG_MAX_REG_NUM (49)
85#define NUMREGBYTES (DBG_MAX_REG_NUM * sizeof(GDB_SIZEOF_REG))
86
87#define BREAK_INSTR_SIZE 4
88static inline void arch_kgdb_breakpoint(void)
89{
90 __asm__ __volatile__("trap 30\n");
91}
92
93#endif /* _ASM_NIOS2_KGDB_H */
diff --git a/arch/nios2/include/asm/processor.h b/arch/nios2/include/asm/processor.h
index 3bd349473b06..c2ba45c159c7 100644
--- a/arch/nios2/include/asm/processor.h
+++ b/arch/nios2/include/asm/processor.h
@@ -85,9 +85,6 @@ static inline void exit_thread(void)
85 85
86extern unsigned long get_wchan(struct task_struct *p); 86extern unsigned long get_wchan(struct task_struct *p);
87 87
88/* Prepare to copy thread state - unlazy all lazy status */
89#define prepare_to_copy(tsk) do { } while (0)
90
91#define task_pt_regs(p) \ 88#define task_pt_regs(p) \
92 ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1) 89 ((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
93 90
diff --git a/arch/nios2/include/asm/prom.h b/arch/nios2/include/asm/prom.h
new file mode 100644
index 000000000000..75fffb42cfa5
--- /dev/null
+++ b/arch/nios2/include/asm/prom.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright Altera Corporation (C) <2015>. All rights reserved
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __ASM_NIOS2_PROM_H__
18#define __ASM_NIOS2_PROM_H__
19
20extern unsigned long __init of_early_console(void);
21
22#endif
diff --git a/arch/nios2/kernel/Makefile b/arch/nios2/kernel/Makefile
index 8ae76823ff93..1aae25703657 100644
--- a/arch/nios2/kernel/Makefile
+++ b/arch/nios2/kernel/Makefile
@@ -20,5 +20,7 @@ obj-y += syscall_table.o
20obj-y += time.o 20obj-y += time.o
21obj-y += traps.o 21obj-y += traps.o
22 22
23obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
24obj-$(CONFIG_KGDB) += kgdb.o
23obj-$(CONFIG_MODULES) += module.o 25obj-$(CONFIG_MODULES) += module.o
24obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o 26obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o
diff --git a/arch/nios2/kernel/early_printk.c b/arch/nios2/kernel/early_printk.c
new file mode 100644
index 000000000000..c08e4c1486fc
--- /dev/null
+++ b/arch/nios2/kernel/early_printk.c
@@ -0,0 +1,118 @@
1/*
2 * Early printk for Nios2.
3 *
4 * Copyright (C) 2015, Altera Corporation
5 * Copyright (C) 2010, Tobias Klauser <tklauser@distanz.ch>
6 * Copyright (C) 2009, Wind River Systems Inc
7 * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/console.h>
15#include <linux/init.h>
16#include <linux/kernel.h>
17#include <linux/io.h>
18
19#include <asm/prom.h>
20
21static unsigned long base_addr;
22
23#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE)
24
25#define ALTERA_JTAGUART_DATA_REG 0
26#define ALTERA_JTAGUART_CONTROL_REG 4
27#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000
28#define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400
29
30#define JUART_GET_CR() \
31 __builtin_ldwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG))
32#define JUART_SET_CR(v) \
33 __builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG), v)
34#define JUART_SET_TX(v) \
35 __builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_DATA_REG), v)
36
37static void early_console_write(struct console *con, const char *s, unsigned n)
38{
39 unsigned long status;
40
41 while (n-- && *s) {
42 while (((status = JUART_GET_CR())
43 & ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) {
44#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
45 if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0)
46 return; /* no connection activity */
47#endif
48 }
49 JUART_SET_TX(*s);
50 s++;
51 }
52}
53
54#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
55
56#define ALTERA_UART_TXDATA_REG 4
57#define ALTERA_UART_STATUS_REG 8
58#define ALTERA_UART_STATUS_TRDY 0x0040
59
60#define UART_GET_SR() \
61 __builtin_ldwio((void *)(base_addr + ALTERA_UART_STATUS_REG))
62#define UART_SET_TX(v) \
63 __builtin_stwio((void *)(base_addr + ALTERA_UART_TXDATA_REG), v)
64
65static void early_console_putc(char c)
66{
67 while (!(UART_GET_SR() & ALTERA_UART_STATUS_TRDY))
68 ;
69
70 UART_SET_TX(c);
71}
72
73static void early_console_write(struct console *con, const char *s, unsigned n)
74{
75 while (n-- && *s) {
76 early_console_putc(*s);
77 if (*s == '\n')
78 early_console_putc('\r');
79 s++;
80 }
81}
82
83#else
84# error Neither SERIAL_ALTERA_JTAGUART_CONSOLE nor SERIAL_ALTERA_UART_CONSOLE \
85selected
86#endif
87
88static struct console early_console_prom = {
89 .name = "early",
90 .write = early_console_write,
91 .flags = CON_PRINTBUFFER | CON_BOOT,
92 .index = -1
93};
94
95void __init setup_early_printk(void)
96{
97#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) || \
98 defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
99 base_addr = of_early_console();
100#else
101 base_addr = 0;
102#endif
103
104 if (!base_addr)
105 return;
106
107#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
108 /* Clear activity bit so BYPASS doesn't stall if we've used JTAG for
109 * downloading the kernel. This might cause early data to be lost even
110 * if the JTAG terminal is running.
111 */
112 JUART_SET_CR(JUART_GET_CR() | ALTERA_JTAGUART_CONTROL_AC_MSK);
113#endif
114
115 early_console = &early_console_prom;
116 register_console(early_console);
117 pr_info("early_console initialized at 0x%08lx\n", base_addr);
118}
diff --git a/arch/nios2/kernel/entry.S b/arch/nios2/kernel/entry.S
index 0bdfd13ff98b..7729bd3f2e79 100644
--- a/arch/nios2/kernel/entry.S
+++ b/arch/nios2/kernel/entry.S
@@ -121,7 +121,11 @@ trap_table:
121 .word instruction_trap /* 27 */ 121 .word instruction_trap /* 27 */
122 .word instruction_trap /* 28 */ 122 .word instruction_trap /* 28 */
123 .word instruction_trap /* 29 */ 123 .word instruction_trap /* 29 */
124 .word instruction_trap /* 30 */ 124#ifdef CONFIG_KGDB
125 .word handle_kgdb_breakpoint /* 30 KGDB breakpoint */
126#else
127 .word instruction_trap /* 30 */
128#endif
125 .word handle_breakpoint /* 31 */ 129 .word handle_breakpoint /* 31 */
126 130
127.text 131.text
@@ -445,6 +449,12 @@ handle_diverror:
445 call handle_diverror_c 449 call handle_diverror_c
446 br ret_from_exception 450 br ret_from_exception
447 451
452#ifdef CONFIG_KGDB
453handle_kgdb_breakpoint:
454 call kgdb_breakpoint_c
455 br ret_from_exception
456#endif
457
448/* 458/*
449 * Beware - when entering resume, prev (the current task) is 459 * Beware - when entering resume, prev (the current task) is
450 * in r4, next (the new task) is in r5, don't change these 460 * in r4, next (the new task) is in r5, don't change these
diff --git a/arch/nios2/kernel/kgdb.c b/arch/nios2/kernel/kgdb.c
new file mode 100644
index 000000000000..117859122d1c
--- /dev/null
+++ b/arch/nios2/kernel/kgdb.c
@@ -0,0 +1,171 @@
1/*
2 * Nios2 KGDB support
3 *
4 * Copyright (C) 2015 Altera Corporation
5 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
6 *
7 * Based on the code posted by Kazuyasu on the Altera Forum at:
8 * http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24#include <linux/ptrace.h>
25#include <linux/kgdb.h>
26#include <linux/kdebug.h>
27#include <linux/io.h>
28
29static int wait_for_remote_debugger;
30
31struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
32{
33 { "zero", GDB_SIZEOF_REG, -1 },
34 { "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, r1) },
35 { "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, r2) },
36 { "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, r3) },
37 { "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, r4) },
38 { "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, r5) },
39 { "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, r6) },
40 { "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, r7) },
41 { "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, r8) },
42 { "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, r9) },
43 { "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, r10) },
44 { "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, r11) },
45 { "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, r12) },
46 { "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, r13) },
47 { "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, r14) },
48 { "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, r15) },
49 { "r16", GDB_SIZEOF_REG, -1 },
50 { "r17", GDB_SIZEOF_REG, -1 },
51 { "r18", GDB_SIZEOF_REG, -1 },
52 { "r19", GDB_SIZEOF_REG, -1 },
53 { "r20", GDB_SIZEOF_REG, -1 },
54 { "r21", GDB_SIZEOF_REG, -1 },
55 { "r22", GDB_SIZEOF_REG, -1 },
56 { "r23", GDB_SIZEOF_REG, -1 },
57 { "et", GDB_SIZEOF_REG, -1 },
58 { "bt", GDB_SIZEOF_REG, -1 },
59 { "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp) },
60 { "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
61 { "fp", GDB_SIZEOF_REG, offsetof(struct pt_regs, fp) },
62 { "ea", GDB_SIZEOF_REG, -1 },
63 { "ba", GDB_SIZEOF_REG, -1 },
64 { "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, ra) },
65 { "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, ea) },
66 { "status", GDB_SIZEOF_REG, -1 },
67 { "estatus", GDB_SIZEOF_REG, offsetof(struct pt_regs, estatus) },
68 { "bstatus", GDB_SIZEOF_REG, -1 },
69 { "ienable", GDB_SIZEOF_REG, -1 },
70 { "ipending", GDB_SIZEOF_REG, -1},
71 { "cpuid", GDB_SIZEOF_REG, -1 },
72 { "ctl6", GDB_SIZEOF_REG, -1 },
73 { "exception", GDB_SIZEOF_REG, -1 },
74 { "pteaddr", GDB_SIZEOF_REG, -1 },
75 { "tlbacc", GDB_SIZEOF_REG, -1 },
76 { "tlbmisc", GDB_SIZEOF_REG, -1 },
77 { "eccinj", GDB_SIZEOF_REG, -1 },
78 { "badaddr", GDB_SIZEOF_REG, -1 },
79 { "config", GDB_SIZEOF_REG, -1 },
80 { "mpubase", GDB_SIZEOF_REG, -1 },
81 { "mpuacc", GDB_SIZEOF_REG, -1 },
82};
83
84char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
85{
86 if (regno >= DBG_MAX_REG_NUM || regno < 0)
87 return NULL;
88
89 if (dbg_reg_def[regno].offset != -1)
90 memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
91 dbg_reg_def[regno].size);
92 else
93 memset(mem, 0, dbg_reg_def[regno].size);
94
95 return dbg_reg_def[regno].name;
96}
97
98int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
99{
100 if (regno >= DBG_MAX_REG_NUM || regno < 0)
101 return -EINVAL;
102
103 if (dbg_reg_def[regno].offset != -1)
104 memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
105 dbg_reg_def[regno].size);
106
107 return 0;
108}
109
110void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
111{
112 memset((char *)gdb_regs, 0, NUMREGBYTES);
113 gdb_regs[GDB_SP] = p->thread.kregs->sp;
114 gdb_regs[GDB_PC] = p->thread.kregs->ea;
115}
116
117void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
118{
119 regs->ea = pc;
120}
121
122int kgdb_arch_handle_exception(int vector, int signo, int err_code,
123 char *remcom_in_buffer, char *remcom_out_buffer,
124 struct pt_regs *regs)
125{
126 char *ptr;
127 unsigned long addr;
128
129 switch (remcom_in_buffer[0]) {
130 case 's':
131 case 'c':
132 /* handle the optional parameters */
133 ptr = &remcom_in_buffer[1];
134 if (kgdb_hex2long(&ptr, &addr))
135 regs->ea = addr;
136
137 return 0;
138 }
139
140 return -1; /* this means that we do not want to exit from the handler */
141}
142
143asmlinkage void kgdb_breakpoint_c(struct pt_regs *regs)
144{
145 /*
146 * The breakpoint entry code has moved the PC on by 4 bytes, so we must
147 * move it back. This could be done on the host but we do it here
148 */
149 if (!wait_for_remote_debugger)
150 regs->ea -= 4;
151 else /* pass the first trap 30 code */
152 wait_for_remote_debugger = 0;
153
154 kgdb_handle_exception(30, SIGTRAP, 0, regs);
155}
156
157int kgdb_arch_init(void)
158{
159 wait_for_remote_debugger = 1;
160 return 0;
161}
162
163void kgdb_arch_exit(void)
164{
165 /* Nothing to do */
166}
167
168struct kgdb_arch arch_kgdb_ops = {
169 /* Breakpoint instruction: trap 30 */
170 .gdb_bpt_instr = { 0xba, 0x6f, 0x3b, 0x00 },
171};
diff --git a/arch/nios2/kernel/prom.c b/arch/nios2/kernel/prom.c
index 0522d3378e3f..718dd197909f 100644
--- a/arch/nios2/kernel/prom.c
+++ b/arch/nios2/kernel/prom.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Device tree support 2 * Device tree support
3 * 3 *
4 * Copyright (C) 2013 Altera Corporation 4 * Copyright (C) 2013, 2015 Altera Corporation
5 * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> 5 * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
6 * 6 *
7 * Based on MIPS support for CONFIG_OF device tree support 7 * Based on MIPS support for CONFIG_OF device tree support
@@ -30,6 +30,7 @@
30#include <linux/of_fdt.h> 30#include <linux/of_fdt.h>
31#include <linux/io.h> 31#include <linux/io.h>
32 32
33#include <asm/prom.h>
33#include <asm/sections.h> 34#include <asm/sections.h>
34 35
35void __init early_init_dt_add_memory_arch(u64 base, u64 size) 36void __init early_init_dt_add_memory_arch(u64 base, u64 size)
@@ -63,3 +64,52 @@ void __init early_init_devtree(void *params)
63 64
64 early_init_dt_scan(params); 65 early_init_dt_scan(params);
65} 66}
67
68#ifdef CONFIG_EARLY_PRINTK
69static int __init early_init_dt_scan_serial(unsigned long node,
70 const char *uname, int depth, void *data)
71{
72 u64 *addr64 = (u64 *) data;
73 const char *p;
74
75 /* only consider serial nodes */
76 if (strncmp(uname, "serial", 6) != 0)
77 return 0;
78
79 p = of_get_flat_dt_prop(node, "compatible", NULL);
80 if (!p)
81 return 0;
82
83 /*
84 * We found an altera_jtaguart but it wasn't configured for console, so
85 * skip it.
86 */
87#ifndef CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE
88 if (strncmp(p, "altr,juart", 10) == 0)
89 return 0;
90#endif
91
92 /*
93 * Same for altera_uart.
94 */
95#ifndef CONFIG_SERIAL_ALTERA_UART_CONSOLE
96 if (strncmp(p, "altr,uart", 9) == 0)
97 return 0;
98#endif
99
100 *addr64 = fdt_translate_address((const void *)initial_boot_params,
101 node);
102
103 return *addr64 == OF_BAD_ADDR ? 0 : 1;
104}
105
106unsigned long __init of_early_console(void)
107{
108 u64 base = 0;
109
110 if (of_scan_flat_dt(early_init_dt_scan_serial, &base))
111 return (u32)ioremap(base, 32);
112 else
113 return 0;
114}
115#endif /* CONFIG_EARLY_PRINTK */
diff --git a/arch/nios2/kernel/setup.c b/arch/nios2/kernel/setup.c
index cb3121f975d4..b101a43d3c5a 100644
--- a/arch/nios2/kernel/setup.c
+++ b/arch/nios2/kernel/setup.c
@@ -139,6 +139,10 @@ void __init setup_arch(char **cmdline_p)
139 139
140 console_verbose(); 140 console_verbose();
141 141
142#ifdef CONFIG_EARLY_PRINTK
143 setup_early_printk();
144#endif
145
142 memory_start = PAGE_ALIGN((unsigned long)__pa(_end)); 146 memory_start = PAGE_ALIGN((unsigned long)__pa(_end));
143 memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size; 147 memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size;
144 148
diff --git a/arch/nios2/mm/fault.c b/arch/nios2/mm/fault.c
index d194c0427b26..0d231adfe576 100644
--- a/arch/nios2/mm/fault.c
+++ b/arch/nios2/mm/fault.c
@@ -47,7 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
47 struct mm_struct *mm = tsk->mm; 47 struct mm_struct *mm = tsk->mm;
48 int code = SEGV_MAPERR; 48 int code = SEGV_MAPERR;
49 int fault; 49 int fault;
50 unsigned int flags = 0; 50 unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
51 51
52 cause >>= 2; 52 cause >>= 2;
53 53
@@ -86,6 +86,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
86 if (!down_read_trylock(&mm->mmap_sem)) { 86 if (!down_read_trylock(&mm->mmap_sem)) {
87 if (!user_mode(regs) && !search_exception_tables(regs->ea)) 87 if (!user_mode(regs) && !search_exception_tables(regs->ea))
88 goto bad_area_nosemaphore; 88 goto bad_area_nosemaphore;
89retry:
89 down_read(&mm->mmap_sem); 90 down_read(&mm->mmap_sem);
90 } 91 }
91 92
@@ -132,6 +133,10 @@ survive:
132 * the fault. 133 * the fault.
133 */ 134 */
134 fault = handle_mm_fault(mm, vma, address, flags); 135 fault = handle_mm_fault(mm, vma, address, flags);
136
137 if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
138 return;
139
135 if (unlikely(fault & VM_FAULT_ERROR)) { 140 if (unlikely(fault & VM_FAULT_ERROR)) {
136 if (fault & VM_FAULT_OOM) 141 if (fault & VM_FAULT_OOM)
137 goto out_of_memory; 142 goto out_of_memory;
@@ -141,10 +146,32 @@ survive:
141 goto do_sigbus; 146 goto do_sigbus;
142 BUG(); 147 BUG();
143 } 148 }
144 if (fault & VM_FAULT_MAJOR) 149
145 tsk->maj_flt++; 150 /*
146 else 151 * Major/minor page fault accounting is only done on the
147 tsk->min_flt++; 152 * initial attempt. If we go through a retry, it is extremely
153 * likely that the page will be found in page cache at that point.
154 */
155 if (flags & FAULT_FLAG_ALLOW_RETRY) {
156 if (fault & VM_FAULT_MAJOR)
157 current->maj_flt++;
158 else
159 current->min_flt++;
160 if (fault & VM_FAULT_RETRY) {
161 /* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
162 * of starvation. */
163 flags &= ~FAULT_FLAG_ALLOW_RETRY;
164 flags |= FAULT_FLAG_TRIED;
165
166 /*
167 * No need to up_read(&mm->mmap_sem) as we would
168 * have already released it in __lock_page_or_retry
169 * in mm/filemap.c.
170 */
171
172 goto retry;
173 }
174 }
148 175
149 up_read(&mm->mmap_sem); 176 up_read(&mm->mmap_sem);
150 return; 177 return;