Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nios2: add early printk support

Signed-off-by: Ley Foon Tan <lftan@altera.com>

+207 -1
+11
arch/nios2/Kconfig.debug
··· 14 14 15 15 This option will slow down process creation somewhat. 16 16 17 + config 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 + 17 28 endmenu
+22
arch/nios2/include/asm/prom.h
··· 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 + 20 + extern unsigned long __init of_early_console(void); 21 + 22 + #endif
+1
arch/nios2/kernel/Makefile
··· 20 20 obj-y += time.o 21 21 obj-y += traps.o 22 22 23 + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 23 24 obj-$(CONFIG_MODULES) += module.o 24 25 obj-$(CONFIG_NIOS2_ALIGNMENT_TRAP) += misaligned.o
+118
arch/nios2/kernel/early_printk.c
··· 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 + 21 + static 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 + 37 + static 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 + 65 + static 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 + 73 + static 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 \ 85 + selected 86 + #endif 87 + 88 + static struct console early_console_prom = { 89 + .name = "early", 90 + .write = early_console_write, 91 + .flags = CON_PRINTBUFFER | CON_BOOT, 92 + .index = -1 93 + }; 94 + 95 + void __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 + }
+51 -1
arch/nios2/kernel/prom.c
··· 1 1 /* 2 2 * Device tree support 3 3 * 4 - * Copyright (C) 2013 Altera Corporation 4 + * Copyright (C) 2013, 2015 Altera Corporation 5 5 * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> 6 6 * 7 7 * Based on MIPS support for CONFIG_OF device tree support ··· 30 30 #include <linux/of_fdt.h> 31 31 #include <linux/io.h> 32 32 33 + #include <asm/prom.h> 33 34 #include <asm/sections.h> 34 35 35 36 void __init early_init_dt_add_memory_arch(u64 base, u64 size) ··· 64 63 65 64 early_init_dt_scan(params); 66 65 } 66 + 67 + #ifdef CONFIG_EARLY_PRINTK 68 + static int __init early_init_dt_scan_serial(unsigned long node, 69 + const char *uname, int depth, void *data) 70 + { 71 + u64 *addr64 = (u64 *) data; 72 + const char *p; 73 + 74 + /* only consider serial nodes */ 75 + if (strncmp(uname, "serial", 6) != 0) 76 + return 0; 77 + 78 + p = of_get_flat_dt_prop(node, "compatible", NULL); 79 + if (!p) 80 + return 0; 81 + 82 + /* 83 + * We found an altera_jtaguart but it wasn't configured for console, so 84 + * skip it. 85 + */ 86 + #ifndef CONFIG_SERIAL_ALTERA_JTAGUART_CONSOLE 87 + if (strncmp(p, "altr,juart", 10) == 0) 88 + return 0; 89 + #endif 90 + 91 + /* 92 + * Same for altera_uart. 93 + */ 94 + #ifndef CONFIG_SERIAL_ALTERA_UART_CONSOLE 95 + if (strncmp(p, "altr,uart", 9) == 0) 96 + return 0; 97 + #endif 98 + 99 + *addr64 = fdt_translate_address((const void *)initial_boot_params, 100 + node); 101 + 102 + return *addr64 == OF_BAD_ADDR ? 0 : 1; 103 + } 104 + 105 + unsigned long __init of_early_console(void) 106 + { 107 + u64 base = 0; 108 + 109 + if (of_scan_flat_dt(early_init_dt_scan_serial, &base)) 110 + return (u32)ioremap(base, 32); 111 + else 112 + return 0; 113 + } 114 + #endif /* CONFIG_EARLY_PRINTK */
+4
arch/nios2/kernel/setup.c
··· 139 139 140 140 console_verbose(); 141 141 142 + #ifdef CONFIG_EARLY_PRINTK 143 + setup_early_printk(); 144 + #endif 145 + 142 146 memory_start = PAGE_ALIGN((unsigned long)__pa(_end)); 143 147 memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size; 144 148