mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 07:01:32 +00:00
nios2 for v3.20
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (GNU/Linux) iQIVAwUAVOHU+1WoEK+e3syCAQJOKQ//cMvDMVZkLK6/XddsX+KpBePbqjeBv4tB n+GTBsSV3RKNX27k6ZfA5AReFtFKQpXgFfB2aUjBLnVWHwM5sCU/wXwNAGhX8md4 TgDQqVId3B5+n31lkwgeuTH86zqaObZO5JBfPEiKg8B0tJFifimrtEoFM2tuiDMt uAsHzYgsP/r9L/aBgCyJ4AJMmkXxNFSMw1ivvDB2IajRHI+zXK1HahMUHo+hLyMq UwHhLmeAu0MEW+GQ7yTS+UMIRYMG87VYP5gD/g+91c7buv8MCxDRUtRkK1uTQAMl tZ+067raQhw/UcnF5ZJtoDvDsKtYhcaYGgtiQq9ywTThoUGxuLvJHqW485DinF9Y o2ntK9h/d3NNRudFhinKyI3/gxDOQYZNUg/uCfCIofHaHET5xYk1+KmmOd5vdDaD rC9yLkQMF5/4vBi0ygULh9+f0C1kinyVH479EsOrf2KewsjhukCGKdSmjKIdsevT tZ6LrSp4G83kfOPAb6jot5UdX+XMwGVVBCiy6dJI1SHGmnmyn6UT3MmVocRbS9Kx 2BTjOnC7c+wmTWxkVDHyy3MwykekqJZNgCRLo0Px1v+FWl5g/iwrEIpkhEjhRivL 01VC/07P/0PunIv8OnI369CuIWHS9B/fPz6oPHQbLO+n16JqakFWDLS6s1wqu/jM 1EBvneZNPFc= =u6dr -----END PGP SIGNATURE----- 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()
This commit is contained in:
commit
b0f0c26a2e
@ -6876,7 +6876,7 @@ F: drivers/scsi/nsp32*
|
||||
NIOS2 ARCHITECTURE
|
||||
M: Ley Foon Tan <lftan@altera.com>
|
||||
L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers)
|
||||
T: git git://git.rocketboards.org/linux-socfpga.git
|
||||
T: git git://git.rocketboards.org/linux-socfpga-next.git
|
||||
S: Maintained
|
||||
F: arch/nios2/
|
||||
|
||||
|
@ -8,6 +8,7 @@ config NIOS2
|
||||
select GENERIC_IRQ_PROBE
|
||||
select GENERIC_IRQ_SHOW
|
||||
select HAVE_ARCH_TRACEHOOK
|
||||
select HAVE_ARCH_KGDB
|
||||
select IRQ_DOMAIN
|
||||
select MODULES_USE_ELF_RELA
|
||||
select OF
|
||||
@ -134,6 +135,14 @@ config NIOS2_PASS_CMDLINE
|
||||
will override "Default kernel command string".
|
||||
Say N if you are unsure.
|
||||
|
||||
config NIOS2_BOOT_LINK_OFFSET
|
||||
hex "Link address offset for booting"
|
||||
default "0x00500000"
|
||||
help
|
||||
This option allows you to set the link address offset of the zImage.
|
||||
This can be useful if you are on a board which has a small amount of
|
||||
memory.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Advanced setup"
|
||||
|
@ -14,4 +14,15 @@ config DEBUG_STACK_USAGE
|
||||
|
||||
This option will slow down process creation somewhat.
|
||||
|
||||
config EARLY_PRINTK
|
||||
bool "Activate early kernel debugging"
|
||||
default y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
depends on SERIAL_ALTERA_JTAGUART_CONSOLE || SERIAL_ALTERA_UART_CONSOLE
|
||||
help
|
||||
Enable early printk on console
|
||||
This is useful for kernel debugging when your machine crashes very
|
||||
early before the console code is initialized.
|
||||
You should normally say N here, unless you want to debug such a crash.
|
||||
|
||||
endmenu
|
||||
|
@ -24,6 +24,13 @@ $(obj)/vmImage: $(obj)/vmlinux.gz
|
||||
$(call if_changed,uimage)
|
||||
@$(kecho) 'Kernel: $@ is ready'
|
||||
|
||||
$(obj)/zImage: $(obj)/compressed/vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
||||
@$(kecho) 'Kernel: $@ is ready'
|
||||
|
||||
$(obj)/compressed/vmlinux: $(obj)/vmlinux.gz FORCE
|
||||
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
|
||||
|
||||
# Rule to build device tree blobs
|
||||
DTB_SRC := $(patsubst "%",%,$(CONFIG_NIOS2_DTB_SOURCE))
|
||||
|
||||
|
19
arch/nios2/boot/compressed/Makefile
Normal file
19
arch/nios2/boot/compressed/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
#
|
||||
# create a compressed vmlinux image from the original vmlinux
|
||||
#
|
||||
|
||||
targets := vmlinux head.o misc.o piggy.o vmlinux.lds
|
||||
asflags-y :=
|
||||
|
||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||
|
||||
LDFLAGS_vmlinux := -T
|
||||
|
||||
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(obj)/piggy.o FORCE
|
||||
$(call if_changed,ld)
|
||||
@:
|
||||
|
||||
LDFLAGS_piggy.o := -r --format binary --oformat elf32-littlenios2 -T
|
||||
|
||||
$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/../vmlinux.gz FORCE
|
||||
$(call if_changed,ld)
|
125
arch/nios2/boot/compressed/console.c
Normal file
125
arch/nios2/boot/compressed/console.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2010 Thomas Chou <thomas@wytron.com.tw>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#if (defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE))\
|
||||
|| (defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE))
|
||||
static void *my_ioremap(unsigned long physaddr)
|
||||
{
|
||||
return (void *)(physaddr | CONFIG_NIOS2_IO_REGION_BASE);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) && defined(JTAG_UART_BASE)
|
||||
|
||||
#define ALTERA_JTAGUART_SIZE 8
|
||||
#define ALTERA_JTAGUART_DATA_REG 0
|
||||
#define ALTERA_JTAGUART_CONTROL_REG 4
|
||||
#define ALTERA_JTAGUART_CONTROL_AC_MSK (0x00000400)
|
||||
#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK (0xFFFF0000)
|
||||
static void *uartbase;
|
||||
|
||||
#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
|
||||
static void jtag_putc(int ch)
|
||||
{
|
||||
if (readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
|
||||
ALTERA_JTAGUART_CONTROL_WSPACE_MSK)
|
||||
writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
|
||||
}
|
||||
#else
|
||||
static void jtag_putc(int ch)
|
||||
{
|
||||
while ((readl(uartbase + ALTERA_JTAGUART_CONTROL_REG) &
|
||||
ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0)
|
||||
;
|
||||
writeb(ch, uartbase + ALTERA_JTAGUART_DATA_REG);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int putchar(int ch)
|
||||
{
|
||||
jtag_putc(ch);
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void console_init(void)
|
||||
{
|
||||
uartbase = my_ioremap((unsigned long) JTAG_UART_BASE);
|
||||
writel(ALTERA_JTAGUART_CONTROL_AC_MSK,
|
||||
uartbase + ALTERA_JTAGUART_CONTROL_REG);
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE) && defined(UART0_BASE)
|
||||
|
||||
#define ALTERA_UART_SIZE 32
|
||||
#define ALTERA_UART_TXDATA_REG 4
|
||||
#define ALTERA_UART_STATUS_REG 8
|
||||
#define ALTERA_UART_DIVISOR_REG 16
|
||||
#define ALTERA_UART_STATUS_TRDY_MSK (0x40)
|
||||
static unsigned uartbase;
|
||||
|
||||
static void uart_putc(int ch)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < 0x10000); i++) {
|
||||
if (readw(uartbase + ALTERA_UART_STATUS_REG) &
|
||||
ALTERA_UART_STATUS_TRDY_MSK)
|
||||
break;
|
||||
}
|
||||
writeb(ch, uartbase + ALTERA_UART_TXDATA_REG);
|
||||
}
|
||||
|
||||
static int putchar(int ch)
|
||||
{
|
||||
uart_putc(ch);
|
||||
if (ch == '\n')
|
||||
uart_putc('\r');
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void console_init(void)
|
||||
{
|
||||
unsigned int baud, baudclk;
|
||||
|
||||
uartbase = (unsigned long) my_ioremap((unsigned long) UART0_BASE);
|
||||
baud = CONFIG_SERIAL_ALTERA_UART_BAUDRATE;
|
||||
baudclk = UART0_FREQ / baud;
|
||||
writew(baudclk, uartbase + ALTERA_UART_DIVISOR_REG);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int putchar(int ch)
|
||||
{
|
||||
return ch;
|
||||
}
|
||||
|
||||
static void console_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int puts(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
putchar(*s++);
|
||||
return 0;
|
||||
}
|
117
arch/nios2/boot/compressed/head.S
Normal file
117
arch/nios2/boot/compressed/head.S
Normal file
@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
|
||||
*
|
||||
* Based on arch/nios2/kernel/head.S
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code can be loaded anywhere, eg FLASH ROM as reset vector,
|
||||
* as long as output does not overlap it.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
.text
|
||||
.set noat
|
||||
ENTRY(_start)
|
||||
wrctl status, r0 /* disable interrupt */
|
||||
/* invalidate all instruction cache */
|
||||
movia r1, NIOS2_ICACHE_SIZE
|
||||
movui r2, NIOS2_ICACHE_LINE_SIZE
|
||||
1: initi r1
|
||||
sub r1, r1, r2
|
||||
bgt r1, r0, 1b
|
||||
/* invalidate all data cache */
|
||||
movia r1, NIOS2_DCACHE_SIZE
|
||||
movui r2, NIOS2_DCACHE_LINE_SIZE
|
||||
1: initd 0(r1)
|
||||
sub r1, r1, r2
|
||||
bgt r1, r0, 1b
|
||||
|
||||
nextpc r1 /* Find out where we are */
|
||||
chkadr:
|
||||
movia r2, chkadr
|
||||
beq r1, r2, finish_move /* We are running in correct address,
|
||||
done */
|
||||
/* move code, r1: src, r2: dest, r3: last dest */
|
||||
addi r1, r1, (_start - chkadr) /* Source */
|
||||
movia r2, _start /* Destination */
|
||||
movia r3, __bss_start /* End of copy */
|
||||
1: ldw r8, 0(r1) /* load a word from [r1] */
|
||||
stw r8, 0(r2) /* stort a word to dest [r2] */
|
||||
addi r1, r1, 4 /* inc the src addr */
|
||||
addi r2, r2, 4 /* inc the dest addr */
|
||||
blt r2, r3, 1b
|
||||
/* flush the data cache after moving */
|
||||
movia r1, NIOS2_DCACHE_SIZE
|
||||
movui r2, NIOS2_DCACHE_LINE_SIZE
|
||||
1: flushd 0(r1)
|
||||
sub r1, r1, r2
|
||||
bgt r1, r0, 1b
|
||||
movia r1, finish_move
|
||||
jmp r1 /* jmp to linked address */
|
||||
|
||||
finish_move:
|
||||
/* zero out the .bss segment (uninitialized common data) */
|
||||
movia r2, __bss_start /* presume nothing is between */
|
||||
movia r1, _end /* the .bss and _end. */
|
||||
1: stb r0, 0(r2)
|
||||
addi r2, r2, 1
|
||||
bne r1, r2, 1b
|
||||
/*
|
||||
* set up the stack pointer, some where higher than _end.
|
||||
* The stack space must be greater than 32K for decompress.
|
||||
*/
|
||||
movia sp, 0x10000
|
||||
add sp, sp, r1
|
||||
/* save args passed from u-boot, maybe */
|
||||
addi sp, sp, -16
|
||||
stw r4, 0(sp)
|
||||
stw r5, 4(sp)
|
||||
stw r6, 8(sp)
|
||||
stw r7, 12(sp)
|
||||
/* decompress the kernel */
|
||||
call decompress_kernel
|
||||
/* pass saved args to kernel */
|
||||
ldw r4, 0(sp)
|
||||
ldw r5, 4(sp)
|
||||
ldw r6, 8(sp)
|
||||
ldw r7, 12(sp)
|
||||
|
||||
/* flush all data cache after decompressing */
|
||||
movia r1, NIOS2_DCACHE_SIZE
|
||||
movui r2, NIOS2_DCACHE_LINE_SIZE
|
||||
1: flushd 0(r1)
|
||||
sub r1, r1, r2
|
||||
bgt r1, r0, 1b
|
||||
/* flush all instruction cache */
|
||||
movia r1, NIOS2_ICACHE_SIZE
|
||||
movui r2, NIOS2_ICACHE_LINE_SIZE
|
||||
1: flushi r1
|
||||
sub r1, r1, r2
|
||||
bgt r1, r0, 1b
|
||||
flushp
|
||||
/* jump to start real kernel */
|
||||
movia r1, (CONFIG_NIOS2_MEM_BASE | CONFIG_NIOS2_KERNEL_REGION_BASE)
|
||||
jmp r1
|
||||
|
||||
.balign 512
|
||||
fake_headers_as_bzImage:
|
||||
.short 0
|
||||
.ascii "HdrS"
|
||||
.short 0x0202
|
||||
.short 0
|
||||
.short 0
|
||||
.byte 0x00, 0x10
|
||||
.short 0
|
||||
.byte 0
|
||||
.byte 1
|
||||
.byte 0x00, 0x80
|
||||
.long 0
|
||||
.long 0
|
187
arch/nios2/boot/compressed/misc.c
Normal file
187
arch/nios2/boot/compressed/misc.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
|
||||
*
|
||||
* This is a collection of several routines from gzip-1.0.3
|
||||
* adapted for Linux.
|
||||
*
|
||||
* malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
|
||||
*
|
||||
* Adapted for SH by Stuart Menefy, Aug 1999
|
||||
*
|
||||
* Modified to use standard LinuxSH BIOS by Greg Banks 7Jul2000
|
||||
*
|
||||
* Based on arch/sh/boot/compressed/misc.c
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/string.h>
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
*/
|
||||
#define OF(args) args
|
||||
#define STATIC static
|
||||
|
||||
#undef memset
|
||||
#undef memcpy
|
||||
#define memzero(s, n) memset((s), 0, (n))
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef unsigned short ush;
|
||||
typedef unsigned long ulg;
|
||||
#define WSIZE 0x8000 /* Window size must be at least 32k, */
|
||||
/* and a power of two */
|
||||
|
||||
static uch *inbuf; /* input buffer */
|
||||
static uch window[WSIZE]; /* Sliding window buffer */
|
||||
|
||||
static unsigned insize; /* valid bytes in inbuf */
|
||||
static unsigned inptr; /* index of next byte to be processed in inbuf */
|
||||
static unsigned outcnt; /* bytes in output buffer */
|
||||
|
||||
/* gzip flag byte */
|
||||
#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */
|
||||
#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip
|
||||
file */
|
||||
#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
|
||||
#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
|
||||
#define COMMENT 0x10 /* bit 4 set: file comment present */
|
||||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||
|
||||
#ifdef DEBUG
|
||||
# define Assert(cond, msg) {if (!(cond)) error(msg); }
|
||||
# define Trace(x) fprintf x
|
||||
# define Tracev(x) {if (verbose) fprintf x ; }
|
||||
# define Tracevv(x) {if (verbose > 1) fprintf x ; }
|
||||
# define Tracec(c, x) {if (verbose && (c)) fprintf x ; }
|
||||
# define Tracecv(c, x) {if (verbose > 1 && (c)) fprintf x ; }
|
||||
#else
|
||||
# define Assert(cond, msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c, x)
|
||||
# define Tracecv(c, x)
|
||||
#endif
|
||||
static int fill_inbuf(void);
|
||||
static void flush_window(void);
|
||||
static void error(char *m);
|
||||
|
||||
extern char input_data[];
|
||||
extern int input_len;
|
||||
|
||||
static long bytes_out;
|
||||
static uch *output_data;
|
||||
static unsigned long output_ptr;
|
||||
|
||||
#include "console.c"
|
||||
|
||||
static void error(char *m);
|
||||
|
||||
int puts(const char *);
|
||||
|
||||
extern int _end;
|
||||
static unsigned long free_mem_ptr;
|
||||
static unsigned long free_mem_end_ptr;
|
||||
|
||||
#define HEAP_SIZE 0x10000
|
||||
|
||||
#include "../../../../lib/inflate.c"
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
int i;
|
||||
char *ss = (char *)s;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
ss[i] = c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i;
|
||||
char *d = (char *)__dest, *s = (char *)__src;
|
||||
|
||||
for (i = 0; i < __n; i++)
|
||||
d[i] = s[i];
|
||||
return __dest;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the input buffer. This is called only when the buffer is empty
|
||||
* and at least one byte is really needed.
|
||||
*/
|
||||
static int fill_inbuf(void)
|
||||
{
|
||||
if (insize != 0)
|
||||
error("ran out of input data");
|
||||
|
||||
inbuf = input_data;
|
||||
insize = input_len;
|
||||
inptr = 1;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the output window window[0..outcnt-1] and update crc and bytes_out.
|
||||
* (Used for the decompressed data only.)
|
||||
*/
|
||||
static void flush_window(void)
|
||||
{
|
||||
ulg c = crc; /* temporary variable */
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out++ = *in++;
|
||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg)outcnt;
|
||||
output_ptr += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
static void error(char *x)
|
||||
{
|
||||
puts("\nERROR\n");
|
||||
puts(x);
|
||||
puts("\n\n -- System halted");
|
||||
|
||||
while (1) /* Halt */
|
||||
;
|
||||
}
|
||||
|
||||
void decompress_kernel(void)
|
||||
{
|
||||
output_data = (void *) (CONFIG_NIOS2_MEM_BASE |
|
||||
CONFIG_NIOS2_KERNEL_REGION_BASE);
|
||||
output_ptr = 0;
|
||||
free_mem_ptr = (unsigned long)&_end;
|
||||
free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
|
||||
|
||||
console_init();
|
||||
makecrc();
|
||||
puts("Uncompressing Linux... ");
|
||||
gunzip();
|
||||
puts("Ok, booting the kernel.\n");
|
||||
}
|
58
arch/nios2/boot/compressed/vmlinux.lds.S
Normal file
58
arch/nios2/boot/compressed/vmlinux.lds.S
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlenios2", "elf32-littlenios2", "elf32-littlenios2")
|
||||
|
||||
OUTPUT_ARCH(nios)
|
||||
ENTRY(_start) /* Defined in head.S */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = (CONFIG_NIOS2_MEM_BASE + CONFIG_NIOS2_BOOT_LINK_OFFSET) | \
|
||||
CONFIG_NIOS2_KERNEL_REGION_BASE;
|
||||
|
||||
_text = .;
|
||||
.text : { *(.text) } = 0
|
||||
.rodata : { *(.rodata) *(.rodata.*) }
|
||||
_etext = .;
|
||||
|
||||
. = ALIGN(32 / 8);
|
||||
.data : { *(.data) }
|
||||
. = ALIGN(32 / 8);
|
||||
_got = .;
|
||||
.got : {
|
||||
*(.got.plt)
|
||||
*(.igot.plt)
|
||||
*(.got)
|
||||
*(.igot)
|
||||
}
|
||||
_egot = .;
|
||||
_edata = .;
|
||||
|
||||
. = ALIGN(32 / 8);
|
||||
__bss_start = .;
|
||||
.bss : { *(.bss) *(.sbss) }
|
||||
. = ALIGN(32 / 8);
|
||||
_ebss = .;
|
||||
end = . ;
|
||||
_end = . ;
|
||||
|
||||
got_len = (_egot - _got);
|
||||
}
|
28
arch/nios2/boot/compressed/vmlinux.scr
Normal file
28
arch/nios2/boot/compressed/vmlinux.scr
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Thomas Chou <thomas@wytron.com.tw>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.data : {
|
||||
input_len = .;
|
||||
LONG(input_data_end - input_data) input_data = .;
|
||||
*(.data)
|
||||
. = ALIGN(4);
|
||||
input_data_end = .;
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ CONFIG_NIOS2_DCACHE_SIZE=0x8000
|
||||
CONFIG_NIOS2_ICACHE_SIZE=0x8000
|
||||
# CONFIG_NIOS2_CMDLINE_IGNORE_DTB is not set
|
||||
CONFIG_NIOS2_PASS_CMDLINE=y
|
||||
CONFIG_NIOS2_BOOT_LINK_OFFSET=0x00800000
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
93
arch/nios2/include/asm/kgdb.h
Normal file
93
arch/nios2/include/asm/kgdb.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Altera Corporation
|
||||
* Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
|
||||
*
|
||||
* Based on the code posted by Kazuyasu on the Altera Forum at:
|
||||
* http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _ASM_NIOS2_KGDB_H
|
||||
#define _ASM_NIOS2_KGDB_H
|
||||
|
||||
#define CACHE_FLUSH_IS_SAFE 1
|
||||
#define BUFMAX 2048
|
||||
|
||||
enum regnames {
|
||||
GDB_R0 = 0,
|
||||
GDB_AT,
|
||||
GDB_R2,
|
||||
GDB_R3,
|
||||
GDB_R4,
|
||||
GDB_R5,
|
||||
GDB_R6,
|
||||
GDB_R7,
|
||||
GDB_R8,
|
||||
GDB_R9,
|
||||
GDB_R10,
|
||||
GDB_R11,
|
||||
GDB_R12,
|
||||
GDB_R13,
|
||||
GDB_R14,
|
||||
GDB_R15,
|
||||
GDB_R16,
|
||||
GDB_R17,
|
||||
GDB_R18,
|
||||
GDB_R19,
|
||||
GDB_R20,
|
||||
GDB_R21,
|
||||
GDB_R22,
|
||||
GDB_R23,
|
||||
GDB_ET,
|
||||
GDB_BT,
|
||||
GDB_GP,
|
||||
GDB_SP,
|
||||
GDB_FP,
|
||||
GDB_EA,
|
||||
GDB_BA,
|
||||
GDB_RA,
|
||||
GDB_PC,
|
||||
GDB_STATUS,
|
||||
GDB_ESTATUS,
|
||||
GDB_BSTATUS,
|
||||
GDB_IENABLE,
|
||||
GDB_IPENDING,
|
||||
GDB_CPUID,
|
||||
GDB_CTL6,
|
||||
GDB_EXCEPTION,
|
||||
GDB_PTEADDR,
|
||||
GDB_TLBACC,
|
||||
GDB_TLBMISC,
|
||||
GDB_ECCINJ,
|
||||
GDB_BADADDR,
|
||||
GDB_CONFIG,
|
||||
GDB_MPUBASE,
|
||||
GDB_MPUACC,
|
||||
/* do not change the last entry or anything below! */
|
||||
GDB_NUMREGBYTES /* number of registers */
|
||||
};
|
||||
|
||||
#define GDB_SIZEOF_REG sizeof(u32)
|
||||
#define DBG_MAX_REG_NUM (49)
|
||||
#define NUMREGBYTES (DBG_MAX_REG_NUM * sizeof(GDB_SIZEOF_REG))
|
||||
|
||||
#define BREAK_INSTR_SIZE 4
|
||||
static inline void arch_kgdb_breakpoint(void)
|
||||
{
|
||||
__asm__ __volatile__("trap 30\n");
|
||||
}
|
||||
|
||||
#endif /* _ASM_NIOS2_KGDB_H */
|
@ -85,9 +85,6 @@ static inline void exit_thread(void)
|
||||
|
||||
extern unsigned long get_wchan(struct task_struct *p);
|
||||
|
||||
/* Prepare to copy thread state - unlazy all lazy status */
|
||||
#define prepare_to_copy(tsk) do { } while (0)
|
||||
|
||||
#define task_pt_regs(p) \
|
||||
((struct pt_regs *)(THREAD_SIZE + task_stack_page(p)) - 1)
|
||||
|
||||
|
22
arch/nios2/include/asm/prom.h
Normal file
22
arch/nios2/include/asm/prom.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright Altera Corporation (C) <2015>. All rights reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_NIOS2_PROM_H__
|
||||
#define __ASM_NIOS2_PROM_H__
|
||||
|
||||
extern unsigned long __init of_early_console(void);
|
||||
|
||||
#endif
|
@ -20,5 +20,7 @@ obj-y += syscall_table.o
|
||||
obj-y += time.o
|
||||
obj-y += traps.o
|
||||
|
||||
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
|
||||
obj-$(CONFIG_KGDB) += kgdb.o
|
||||
obj-$(CONFIG_MODULES) += module.o
|
||||
obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o
|
||||
|
118
arch/nios2/kernel/early_printk.c
Normal file
118
arch/nios2/kernel/early_printk.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Early printk for Nios2.
|
||||
*
|
||||
* Copyright (C) 2015, Altera Corporation
|
||||
* Copyright (C) 2010, Tobias Klauser <tklauser@distanz.ch>
|
||||
* Copyright (C) 2009, Wind River Systems Inc
|
||||
* Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General Public
|
||||
* License. See the file "COPYING" in the main directory of this archive
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <linux/console.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
|
||||
static unsigned long base_addr;
|
||||
|
||||
#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE)
|
||||
|
||||
#define ALTERA_JTAGUART_DATA_REG 0
|
||||
#define ALTERA_JTAGUART_CONTROL_REG 4
|
||||
#define ALTERA_JTAGUART_CONTROL_WSPACE_MSK 0xFFFF0000
|
||||
#define ALTERA_JTAGUART_CONTROL_AC_MSK 0x00000400
|
||||
|
||||
#define JUART_GET_CR() \
|
||||
__builtin_ldwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG))
|
||||
#define JUART_SET_CR(v) \
|
||||
__builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_CONTROL_REG), v)
|
||||
#define JUART_SET_TX(v) \
|
||||
__builtin_stwio((void *)(base_addr + ALTERA_JTAGUART_DATA_REG), v)
|
||||
|
||||
static void early_console_write(struct console *con, const char *s, unsigned n)
|
||||
{
|
||||
unsigned long status;
|
||||
|
||||
while (n-- && *s) {
|
||||
while (((status = JUART_GET_CR())
|
||||
& ALTERA_JTAGUART_CONTROL_WSPACE_MSK) == 0) {
|
||||
#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
|
||||
if ((status & ALTERA_JTAGUART_CONTROL_AC_MSK) == 0)
|
||||
return; /* no connection activity */
|
||||
#endif
|
||||
}
|
||||
JUART_SET_TX(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
|
||||
|
||||
#define ALTERA_UART_TXDATA_REG 4
|
||||
#define ALTERA_UART_STATUS_REG 8
|
||||
#define ALTERA_UART_STATUS_TRDY 0x0040
|
||||
|
||||
#define UART_GET_SR() \
|
||||
__builtin_ldwio((void *)(base_addr + ALTERA_UART_STATUS_REG))
|
||||
#define UART_SET_TX(v) \
|
||||
__builtin_stwio((void *)(base_addr + ALTERA_UART_TXDATA_REG), v)
|
||||
|
||||
static void early_console_putc(char c)
|
||||
{
|
||||
while (!(UART_GET_SR() & ALTERA_UART_STATUS_TRDY))
|
||||
;
|
||||
|
||||
UART_SET_TX(c);
|
||||
}
|
||||
|
||||
static void early_console_write(struct console *con, const char *s, unsigned n)
|
||||
{
|
||||
while (n-- && *s) {
|
||||
early_console_putc(*s);
|
||||
if (*s == '\n')
|
||||
early_console_putc('\r');
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
# error Neither SERIAL_ALTERA_JTAGUART_CONSOLE nor SERIAL_ALTERA_UART_CONSOLE \
|
||||
selected
|
||||
#endif
|
||||
|
||||
static struct console early_console_prom = {
|
||||
.name = "early",
|
||||
.write = early_console_write,
|
||||
.flags = CON_PRINTBUFFER | CON_BOOT,
|
||||
.index = -1
|
||||
};
|
||||
|
||||
void __init setup_early_printk(void)
|
||||
{
|
||||
#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE) || \
|
||||
defined(CONFIG_SERIAL_ALTERA_UART_CONSOLE)
|
||||
base_addr = of_early_console();
|
||||
#else
|
||||
base_addr = 0;
|
||||
#endif
|
||||
|
||||
if (!base_addr)
|
||||
return;
|
||||
|
||||
#if defined(CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE_BYPASS)
|
||||
/* Clear activity bit so BYPASS doesn't stall if we've used JTAG for
|
||||
* downloading the kernel. This might cause early data to be lost even
|
||||
* if the JTAG terminal is running.
|
||||
*/
|
||||
JUART_SET_CR(JUART_GET_CR() | ALTERA_JTAGUART_CONTROL_AC_MSK);
|
||||
#endif
|
||||
|
||||
early_console = &early_console_prom;
|
||||
register_console(early_console);
|
||||
pr_info("early_console initialized at 0x%08lx\n", base_addr);
|
||||
}
|
@ -121,7 +121,11 @@ trap_table:
|
||||
.word instruction_trap /* 27 */
|
||||
.word instruction_trap /* 28 */
|
||||
.word instruction_trap /* 29 */
|
||||
.word instruction_trap /* 30 */
|
||||
#ifdef CONFIG_KGDB
|
||||
.word handle_kgdb_breakpoint /* 30 KGDB breakpoint */
|
||||
#else
|
||||
.word instruction_trap /* 30 */
|
||||
#endif
|
||||
.word handle_breakpoint /* 31 */
|
||||
|
||||
.text
|
||||
@ -445,6 +449,12 @@ handle_diverror:
|
||||
call handle_diverror_c
|
||||
br ret_from_exception
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
handle_kgdb_breakpoint:
|
||||
call kgdb_breakpoint_c
|
||||
br ret_from_exception
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Beware - when entering resume, prev (the current task) is
|
||||
* in r4, next (the new task) is in r5, don't change these
|
||||
|
171
arch/nios2/kernel/kgdb.c
Normal file
171
arch/nios2/kernel/kgdb.c
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Nios2 KGDB support
|
||||
*
|
||||
* Copyright (C) 2015 Altera Corporation
|
||||
* Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
|
||||
*
|
||||
* Based on the code posted by Kazuyasu on the Altera Forum at:
|
||||
* http://www.alteraforum.com/forum/showpost.php?p=77003&postcount=20
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
static int wait_for_remote_debugger;
|
||||
|
||||
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
|
||||
{
|
||||
{ "zero", GDB_SIZEOF_REG, -1 },
|
||||
{ "at", GDB_SIZEOF_REG, offsetof(struct pt_regs, r1) },
|
||||
{ "r2", GDB_SIZEOF_REG, offsetof(struct pt_regs, r2) },
|
||||
{ "r3", GDB_SIZEOF_REG, offsetof(struct pt_regs, r3) },
|
||||
{ "r4", GDB_SIZEOF_REG, offsetof(struct pt_regs, r4) },
|
||||
{ "r5", GDB_SIZEOF_REG, offsetof(struct pt_regs, r5) },
|
||||
{ "r6", GDB_SIZEOF_REG, offsetof(struct pt_regs, r6) },
|
||||
{ "r7", GDB_SIZEOF_REG, offsetof(struct pt_regs, r7) },
|
||||
{ "r8", GDB_SIZEOF_REG, offsetof(struct pt_regs, r8) },
|
||||
{ "r9", GDB_SIZEOF_REG, offsetof(struct pt_regs, r9) },
|
||||
{ "r10", GDB_SIZEOF_REG, offsetof(struct pt_regs, r10) },
|
||||
{ "r11", GDB_SIZEOF_REG, offsetof(struct pt_regs, r11) },
|
||||
{ "r12", GDB_SIZEOF_REG, offsetof(struct pt_regs, r12) },
|
||||
{ "r13", GDB_SIZEOF_REG, offsetof(struct pt_regs, r13) },
|
||||
{ "r14", GDB_SIZEOF_REG, offsetof(struct pt_regs, r14) },
|
||||
{ "r15", GDB_SIZEOF_REG, offsetof(struct pt_regs, r15) },
|
||||
{ "r16", GDB_SIZEOF_REG, -1 },
|
||||
{ "r17", GDB_SIZEOF_REG, -1 },
|
||||
{ "r18", GDB_SIZEOF_REG, -1 },
|
||||
{ "r19", GDB_SIZEOF_REG, -1 },
|
||||
{ "r20", GDB_SIZEOF_REG, -1 },
|
||||
{ "r21", GDB_SIZEOF_REG, -1 },
|
||||
{ "r22", GDB_SIZEOF_REG, -1 },
|
||||
{ "r23", GDB_SIZEOF_REG, -1 },
|
||||
{ "et", GDB_SIZEOF_REG, -1 },
|
||||
{ "bt", GDB_SIZEOF_REG, -1 },
|
||||
{ "gp", GDB_SIZEOF_REG, offsetof(struct pt_regs, gp) },
|
||||
{ "sp", GDB_SIZEOF_REG, offsetof(struct pt_regs, sp) },
|
||||
{ "fp", GDB_SIZEOF_REG, offsetof(struct pt_regs, fp) },
|
||||
{ "ea", GDB_SIZEOF_REG, -1 },
|
||||
{ "ba", GDB_SIZEOF_REG, -1 },
|
||||
{ "ra", GDB_SIZEOF_REG, offsetof(struct pt_regs, ra) },
|
||||
{ "pc", GDB_SIZEOF_REG, offsetof(struct pt_regs, ea) },
|
||||
{ "status", GDB_SIZEOF_REG, -1 },
|
||||
{ "estatus", GDB_SIZEOF_REG, offsetof(struct pt_regs, estatus) },
|
||||
{ "bstatus", GDB_SIZEOF_REG, -1 },
|
||||
{ "ienable", GDB_SIZEOF_REG, -1 },
|
||||
{ "ipending", GDB_SIZEOF_REG, -1},
|
||||
{ "cpuid", GDB_SIZEOF_REG, -1 },
|
||||
{ "ctl6", GDB_SIZEOF_REG, -1 },
|
||||
{ "exception", GDB_SIZEOF_REG, -1 },
|
||||
{ "pteaddr", GDB_SIZEOF_REG, -1 },
|
||||
{ "tlbacc", GDB_SIZEOF_REG, -1 },
|
||||
{ "tlbmisc", GDB_SIZEOF_REG, -1 },
|
||||
{ "eccinj", GDB_SIZEOF_REG, -1 },
|
||||
{ "badaddr", GDB_SIZEOF_REG, -1 },
|
||||
{ "config", GDB_SIZEOF_REG, -1 },
|
||||
{ "mpubase", GDB_SIZEOF_REG, -1 },
|
||||
{ "mpuacc", GDB_SIZEOF_REG, -1 },
|
||||
};
|
||||
|
||||
char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs)
|
||||
{
|
||||
if (regno >= DBG_MAX_REG_NUM || regno < 0)
|
||||
return NULL;
|
||||
|
||||
if (dbg_reg_def[regno].offset != -1)
|
||||
memcpy(mem, (void *)regs + dbg_reg_def[regno].offset,
|
||||
dbg_reg_def[regno].size);
|
||||
else
|
||||
memset(mem, 0, dbg_reg_def[regno].size);
|
||||
|
||||
return dbg_reg_def[regno].name;
|
||||
}
|
||||
|
||||
int dbg_set_reg(int regno, void *mem, struct pt_regs *regs)
|
||||
{
|
||||
if (regno >= DBG_MAX_REG_NUM || regno < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (dbg_reg_def[regno].offset != -1)
|
||||
memcpy((void *)regs + dbg_reg_def[regno].offset, mem,
|
||||
dbg_reg_def[regno].size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
|
||||
{
|
||||
memset((char *)gdb_regs, 0, NUMREGBYTES);
|
||||
gdb_regs[GDB_SP] = p->thread.kregs->sp;
|
||||
gdb_regs[GDB_PC] = p->thread.kregs->ea;
|
||||
}
|
||||
|
||||
void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
|
||||
{
|
||||
regs->ea = pc;
|
||||
}
|
||||
|
||||
int kgdb_arch_handle_exception(int vector, int signo, int err_code,
|
||||
char *remcom_in_buffer, char *remcom_out_buffer,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
char *ptr;
|
||||
unsigned long addr;
|
||||
|
||||
switch (remcom_in_buffer[0]) {
|
||||
case 's':
|
||||
case 'c':
|
||||
/* handle the optional parameters */
|
||||
ptr = &remcom_in_buffer[1];
|
||||
if (kgdb_hex2long(&ptr, &addr))
|
||||
regs->ea = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1; /* this means that we do not want to exit from the handler */
|
||||
}
|
||||
|
||||
asmlinkage void kgdb_breakpoint_c(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* The breakpoint entry code has moved the PC on by 4 bytes, so we must
|
||||
* move it back. This could be done on the host but we do it here
|
||||
*/
|
||||
if (!wait_for_remote_debugger)
|
||||
regs->ea -= 4;
|
||||
else /* pass the first trap 30 code */
|
||||
wait_for_remote_debugger = 0;
|
||||
|
||||
kgdb_handle_exception(30, SIGTRAP, 0, regs);
|
||||
}
|
||||
|
||||
int kgdb_arch_init(void)
|
||||
{
|
||||
wait_for_remote_debugger = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kgdb_arch_exit(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
struct kgdb_arch arch_kgdb_ops = {
|
||||
/* Breakpoint instruction: trap 30 */
|
||||
.gdb_bpt_instr = { 0xba, 0x6f, 0x3b, 0x00 },
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Device tree support
|
||||
*
|
||||
* Copyright (C) 2013 Altera Corporation
|
||||
* Copyright (C) 2013, 2015 Altera Corporation
|
||||
* Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
|
||||
*
|
||||
* Based on MIPS support for CONFIG_OF device tree support
|
||||
@ -30,6 +30,7 @@
|
||||
#include <linux/of_fdt.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/sections.h>
|
||||
|
||||
void __init early_init_dt_add_memory_arch(u64 base, u64 size)
|
||||
@ -63,3 +64,52 @@ void __init early_init_devtree(void *params)
|
||||
|
||||
early_init_dt_scan(params);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
static int __init early_init_dt_scan_serial(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
{
|
||||
u64 *addr64 = (u64 *) data;
|
||||
const char *p;
|
||||
|
||||
/* only consider serial nodes */
|
||||
if (strncmp(uname, "serial", 6) != 0)
|
||||
return 0;
|
||||
|
||||
p = of_get_flat_dt_prop(node, "compatible", NULL);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We found an altera_jtaguart but it wasn't configured for console, so
|
||||
* skip it.
|
||||
*/
|
||||
#ifndef CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE
|
||||
if (strncmp(p, "altr,juart", 10) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Same for altera_uart.
|
||||
*/
|
||||
#ifndef CONFIG_SERIAL_ALTERA_UART_CONSOLE
|
||||
if (strncmp(p, "altr,uart", 9) == 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*addr64 = fdt_translate_address((const void *)initial_boot_params,
|
||||
node);
|
||||
|
||||
return *addr64 == OF_BAD_ADDR ? 0 : 1;
|
||||
}
|
||||
|
||||
unsigned long __init of_early_console(void)
|
||||
{
|
||||
u64 base = 0;
|
||||
|
||||
if (of_scan_flat_dt(early_init_dt_scan_serial, &base))
|
||||
return (u32)ioremap(base, 32);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_EARLY_PRINTK */
|
||||
|
@ -139,6 +139,10 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
console_verbose();
|
||||
|
||||
#ifdef CONFIG_EARLY_PRINTK
|
||||
setup_early_printk();
|
||||
#endif
|
||||
|
||||
memory_start = PAGE_ALIGN((unsigned long)__pa(_end));
|
||||
memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size;
|
||||
|
||||
|
@ -47,7 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
|
||||
struct mm_struct *mm = tsk->mm;
|
||||
int code = SEGV_MAPERR;
|
||||
int fault;
|
||||
unsigned int flags = 0;
|
||||
unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
|
||||
|
||||
cause >>= 2;
|
||||
|
||||
@ -86,6 +86,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long cause,
|
||||
if (!down_read_trylock(&mm->mmap_sem)) {
|
||||
if (!user_mode(regs) && !search_exception_tables(regs->ea))
|
||||
goto bad_area_nosemaphore;
|
||||
retry:
|
||||
down_read(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
@ -132,6 +133,10 @@ survive:
|
||||
* the fault.
|
||||
*/
|
||||
fault = handle_mm_fault(mm, vma, address, flags);
|
||||
|
||||
if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
|
||||
return;
|
||||
|
||||
if (unlikely(fault & VM_FAULT_ERROR)) {
|
||||
if (fault & VM_FAULT_OOM)
|
||||
goto out_of_memory;
|
||||
@ -141,10 +146,32 @@ survive:
|
||||
goto do_sigbus;
|
||||
BUG();
|
||||
}
|
||||
if (fault & VM_FAULT_MAJOR)
|
||||
tsk->maj_flt++;
|
||||
else
|
||||
tsk->min_flt++;
|
||||
|
||||
/*
|
||||
* Major/minor page fault accounting is only done on the
|
||||
* initial attempt. If we go through a retry, it is extremely
|
||||
* likely that the page will be found in page cache at that point.
|
||||
*/
|
||||
if (flags & FAULT_FLAG_ALLOW_RETRY) {
|
||||
if (fault & VM_FAULT_MAJOR)
|
||||
current->maj_flt++;
|
||||
else
|
||||
current->min_flt++;
|
||||
if (fault & VM_FAULT_RETRY) {
|
||||
/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
|
||||
* of starvation. */
|
||||
flags &= ~FAULT_FLAG_ALLOW_RETRY;
|
||||
flags |= FAULT_FLAG_TRIED;
|
||||
|
||||
/*
|
||||
* No need to up_read(&mm->mmap_sem) as we would
|
||||
* have already released it in __lock_page_or_retry
|
||||
* in mm/filemap.c.
|
||||
*/
|
||||
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
up_read(&mm->mmap_sem);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user