Introduce machine_early_init() which clears the BSS section and sets up the commandline. The assembly startup code then only have to care about setting up the stack pointer.
Signed-off-by: Michael Walle <mich...@walle.cc> --- arch/lm32/Kconfig.debug | 29 +++++++-- arch/lm32/include/asm/setup.h | 43 +------------ arch/lm32/kernel/head.S | 119 ++++------------------------------ arch/lm32/kernel/setup.c | 42 ++++++++----- arch/lm32/kernel/time.c | 6 +- arch/lm32/kernel/vmlinux.lds.S | 2 +- arch/lm32/mm/init.c | 14 ++--- drivers/tty/serial/milkymist_uart.c | 4 +- 8 files changed, 77 insertions(+), 182 deletions(-) diff --git a/arch/lm32/Kconfig.debug b/arch/lm32/Kconfig.debug index cde44a8..1d23243 100644 --- a/arch/lm32/Kconfig.debug +++ b/arch/lm32/Kconfig.debug @@ -2,12 +2,29 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config BOOTPARAM - bool 'Compiled-in Kernel Boot Parameter' +config CMDLINE_BOOL + bool "Built-in kernel command line" + default n + help + For most systems, it is firmware or second stage bootloader that + by default specifies the kernel command line options. However, + it might be necessary or advantageous to override the default kernel + command line. For such cases, this option allows you to hardcode + your own command line options directly into the kernel. For that, + you should choose 'Y' here, and fill in the extra boot arguments in + CONFIG_CMDLINE. -config BOOTPARAM_STRING - string 'Kernel Boot Parameter' - default 'console=ttyS0,19200' - depends on BOOTPARAM +config CMDLINE + string "Default kernel command string" + depends on CMDLINE_BOOL + default "" + help + On some platforms, there is currently no way for the boot loader to + pass arguments to the kernel. For these platforms you can supply + some command-line options at build time by entering them here. In + other cases you can specify kernel args so that you don't have to set + them up in board prom initialization routines. + + For more information, see the CMDLINE_BOOL option. endmenu diff --git a/arch/lm32/include/asm/setup.h b/arch/lm32/include/asm/setup.h index 6aba7e6..552df83 100644 --- a/arch/lm32/include/asm/setup.h +++ b/arch/lm32/include/asm/setup.h @@ -1,42 +1 @@ -/* - * (C) Copyright 2007 - * Theobroma Systems <www.theobroma-systems.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#ifndef _LM32_ASM_SETUP_H -#define _LM32_ASM_SETUP_H - -#ifndef __ASSEMBLY__ - -#ifdef __KERNEL__ - -extern unsigned int kernel_mode; -extern unsigned int cpu_frequency; -extern unsigned int sdram_start; -extern unsigned int sdram_size; -extern struct platform_device* milkymistuart_default_console_device; - -#endif /* __KERNEL__ */ -#endif /* #ifndef __ASSEMBLY__ */ - -#define COMMAND_LINE_SIZE 256 - -#endif +#include <asm-generic/setup.h> diff --git a/arch/lm32/kernel/head.S b/arch/lm32/kernel/head.S index e461e68..17d4778 100644 --- a/arch/lm32/kernel/head.S +++ b/arch/lm32/kernel/head.S @@ -1,111 +1,20 @@ -/* - * linux/arch/arm/kernel/head.S - * - * Copyright (c) 2007 Theobroma Systems. - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Kernel startup code for the Lattice Mico 32 architecture - */ -#include <linux/linkage.h> #include <linux/init.h> -#include <linux/threads.h> - -#include <asm/ptrace.h> -#include <asm/asm-offsets.h> +#include <linux/linkage.h> #include <asm/thread_info.h> -#include <asm/system.h> - -/* - * Kernel startup entry point. - * --------------------------- - * - * This is normally called from the decompressor code or boot-loader. - * The requirements are: - * r1 = hardware parameters (list of structs from hwsetup_kernel.h) - * r2 = kernel commandline (zero terminated) - * r3 = initrd start - * r4 = initrd end - * - * We currently clobber r23, r24 and r25 - * - * Note: This code is not (yet) position-independent (position - * independence will require some additional magic to - * correct the __bss_start, _end and _init_thread_union - * addresses). - */ - - .section ".text.head" - .type stext, %function -ENTRY(stext) - xor r0, r0, r0 /* make sure that r0 is set to 0. */ - wcsr IE, r0 /* disable interrupts */ - wcsr IM, r0 /* disable each maskable interrupt */ - calli setup_stack - calli clear_bss - calli save_args - calli setup_exception_vectors - calli start_kernel - /* should never get here */ -hang: - be r0, r0, hang /* how did we get here? */ - -save_args: - /* TODO: make this PIC */ - mvhi r23, hi(_kernel_arg_cmdline) - ori r23, r23, lo(_kernel_arg_cmdline) - sw (r23+0), r1 /* store commandline parameter into _kernel_arg_cmdline */ - /* store initrd parameters */ - mvhi r23, hi(_kernel_arg_initrd_start) - ori r23, r23, lo(_kernel_arg_initrd_start) - sw (r23+0), r2 - mvhi r23, hi(_kernel_arg_initrd_end) - ori r23, r23, lo(_kernel_arg_initrd_end) - sw (r23+0), r3 - ret - -setup_exception_vectors: - /* TODO: implement me */ - /* TODO: irq handler has to call asm_do_IRQ */ - /* activate watchpoint on write to address 0 */ - wcsr WP0, r0 - rcsr r23, DC - ori r23, r23, 0x8 - /*wcsr DC, r23*/ - /*mvhi r23, 0x1000*/ - /*wcsr DEBA, r23*/ - ret -clear_bss: - addi sp, sp, -8 - mv r25, ra - calli clear_bss_1 +__INIT +ENTRY(_stext) + xor r0, r0, r0 /* clear r0 */ + wcsr IE, r0 /* disable interrupts */ + wcsr IM, r0 - .global __bss_start - .word __bss_start - .global _end - .word _end -clear_bss_1: - lw r23, (ra + 0) /* load _bss_start */ - lw r24, (ra + 4) /* load _end */ - /* TODO: correct the BSS addresses for position independence */ -clear_bss_2: - sw (r23 + 0), r0 - addi r23, r23, 4 - bgu r24, r23, clear_bss_2 + /* init stack pointer */ + mvhi sp, hi(init_thread_union) + ori sp, sp, lo(init_thread_union) + addi sp, sp, THREAD_SIZE - 4 - mv ra, r25 - ret + /* terminate frame pointer */ + mvi fp, 0 -setup_stack: - /* TODO: make this PIC */ - mvhi r23, hi(init_thread_union) - ori r23, r23, lo(init_thread_union) - mvi sp, THREAD_SIZE - 32 - add sp, sp, r23 - /* init the stack pointer */ - addi sp, sp, -32 /* SZREGS */ - ret + calli machine_early_init + bi start_kernel diff --git a/arch/lm32/kernel/setup.c b/arch/lm32/kernel/setup.c index 85102c0..664db2b 100644 --- a/arch/lm32/kernel/setup.c +++ b/arch/lm32/kernel/setup.c @@ -56,6 +56,7 @@ #include <asm/page.h> #include <asm/pgtable.h> #include <asm/thread_info.h> +#include <asm/sections.h> #ifdef CONFIG_PLAT_MILKYMIST #include <asm/hw/milkymist.h> @@ -69,7 +70,7 @@ unsigned long asmlinkage _kernel_arg_cmdline; /* address of the commandline para unsigned long asmlinkage _kernel_arg_initrd_start; unsigned long asmlinkage _kernel_arg_initrd_end; -char __initdata command_line[COMMAND_LINE_SIZE]; +static char __initdata cmd_line[COMMAND_LINE_SIZE]; /* from mm/init.c */ @@ -77,8 +78,25 @@ extern void bootmem_init(void); extern void paging_init(void); unsigned int cpu_frequency; -unsigned int sdram_start; -unsigned int sdram_size; +//unsigned int sdram_start; +//unsigned int sdram_size; + +void __init machine_early_init(char *cmdline, unsigned long p_initrd_start, + unsigned long p_initrd_end) +{ + /* clear bss section */ + memset(__bss_start, 0, __bss_stop - __bss_start); + +#ifndef CONFIG_CMDLINE_BOOL + if (cmdline) { + strlcpy(cmd_line, cmdline, COMMAND_LINE_SIZE); + } +#else + strlcpy(cmd_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE); +#endif + initrd_start = p_initrd_start; + initrd_end = p_initrd_end; +} void __init setup_arch(char **cmdline_p) { @@ -88,23 +106,15 @@ void __init setup_arch(char **cmdline_p) lm32_current_thread = (struct thread_info*)&init_thread_union; cpu_frequency = (unsigned long)CONFIG_CPU_CLOCK; - sdram_start = (unsigned long)CONFIG_MEMORY_START; - sdram_size = (unsigned long)CONFIG_MEMORY_SIZE; - - /* Keep a copy of command line */ - *cmdline_p = (char*)_kernel_arg_cmdline; - - -#if defined(CONFIG_BOOTPARAM) - /* CONFIG_CMDLINE should override all */ - strncpy(*cmdline_p, CONFIG_BOOTPARAM_STRING, COMMAND_LINE_SIZE); -#endif + //sdram_start = (unsigned long)CONFIG_MEMORY_START; + //sdram_size = (unsigned long)CONFIG_MEMORY_SIZE; + /* Save unparsed command line copy for /proc/cmdline */ memcpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE); - boot_command_line[COMMAND_LINE_SIZE-1] = 0; + *cmdline_p = cmd_line; #ifdef CONFIG_DUMMY_CONSOLE - conswitchp = &dummy_con; + conswitchp = &dummy_con; #endif #ifdef CONFIG_EARLY_PRINTK diff --git a/arch/lm32/kernel/time.c b/arch/lm32/kernel/time.c index 7761f5e..0353f23 100644 --- a/arch/lm32/kernel/time.c +++ b/arch/lm32/kernel/time.c @@ -142,9 +142,9 @@ void __init time_init(void) { int ret; - milkymist_ticks_per_jiffy = DIV_ROUND_CLOSEST(cpu_frequency, HZ); + milkymist_ticks_per_jiffy = DIV_ROUND_CLOSEST(CONFIG_CPU_CLOCK, HZ); - clockevents_calc_mult_shift(&milkymist_clockevent, cpu_frequency, 5); + clockevents_calc_mult_shift(&milkymist_clockevent, CONFIG_CPU_CLOCK, 5); milkymist_clockevent.min_delta_ns = clockevent_delta2ns(100, &milkymist_clockevent); milkymist_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &milkymist_clockevent); milkymist_clockevent.cpumask = cpumask_of(0); @@ -156,7 +156,7 @@ void __init time_init(void) clockevents_register_device(&milkymist_clockevent); - ret = clocksource_register_hz(&milkymist_clocksource, cpu_frequency); + ret = clocksource_register_hz(&milkymist_clocksource, CONFIG_CPU_CLOCK); if (ret) printk(KERN_ERR "Failed to register clocksource: %d\n", ret); diff --git a/arch/lm32/kernel/vmlinux.lds.S b/arch/lm32/kernel/vmlinux.lds.S index f77e2ef..767e0fa 100644 --- a/arch/lm32/kernel/vmlinux.lds.S +++ b/arch/lm32/kernel/vmlinux.lds.S @@ -9,7 +9,7 @@ #include <asm/page.h> OUTPUT_ARCH(lm32) -ENTRY(stext) +ENTRY(_stext) #define TEXT_OFFSET CONFIG_TEXT_OFFSET diff --git a/arch/lm32/mm/init.c b/arch/lm32/mm/init.c index 362c209..3a5bc84 100644 --- a/arch/lm32/mm/init.c +++ b/arch/lm32/mm/init.c @@ -62,8 +62,8 @@ void __init bootmem_init(void) /* * Init memory */ - physical_memory_start = sdram_start; - physical_memory_end = sdram_start+sdram_size; + physical_memory_start = CONFIG_MEMORY_START; + physical_memory_end = CONFIG_MEMORY_START + CONFIG_MEMORY_SIZE; if( ((unsigned long)_end < physical_memory_start) || ((unsigned long)_end > physical_memory_end) ) printk("BUG: your kernel is not located in the ddr sdram"); /* start after kernel code */ @@ -99,11 +99,9 @@ void __init bootmem_init(void) * reserve initrd boot memory */ #ifdef CONFIG_BLK_DEV_INITRD - if(_kernel_arg_initrd_start) { - unsigned long reserve_start = _kernel_arg_initrd_start & PAGE_MASK; - unsigned long reserve_end = (_kernel_arg_initrd_end + PAGE_SIZE-1) & PAGE_MASK; - initrd_start = _kernel_arg_initrd_start; - initrd_end = _kernel_arg_initrd_end; + if (initrd_start) { + unsigned long reserve_start = initrd_start & PAGE_MASK; + unsigned long reserve_end = (initrd_end + PAGE_SIZE-1) & PAGE_MASK; printk("reserving initrd memory: %lx size %lx\n", reserve_start, reserve_end-reserve_start); reserve_bootmem(reserve_start, reserve_end-reserve_start, BOOTMEM_DEFAULT); } @@ -160,7 +158,7 @@ void __init mem_init(void) unsigned long start_mem = memory_start; unsigned long end_mem = memory_end; /* TODO: use more of hardware setup to initialize memory */ - unsigned long ramlen = sdram_size; + unsigned long ramlen = CONFIG_MEMORY_SIZE; #ifdef DEBUG printk(KERN_DEBUG "Mem_init: start=%lx, end=%lx\n", start_mem, end_mem); diff --git a/drivers/tty/serial/milkymist_uart.c b/drivers/tty/serial/milkymist_uart.c index b4ef457..9025fb9 100644 --- a/drivers/tty/serial/milkymist_uart.c +++ b/drivers/tty/serial/milkymist_uart.c @@ -358,6 +358,8 @@ static struct console milkymist_console = { /* * Early console initialization */ +/* TODO remove this extern */ +extern struct platform_device* milkymistuart_default_console_device; static int __init milkymist_early_console_init(void) { add_preferred_console(MILKYMISTUART_DEVICENAME, milkymistuart_default_console_device->id, NULL); @@ -405,7 +407,7 @@ static struct uart_port* __devinit milkymistuart_init_port(struct platform_devic port->iobase = 0x0; port->membase = (void __iomem*)CSR_UART_RXTX; port->irq = IRQ_UARTRX; - port->uartclk = cpu_frequency; + port->uartclk = CONFIG_CPU_CLOCK; port->flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; // TODO perhaps this is not completely correct port->iotype = UPIO_PORT; // TODO perhaps this is not completely correct port->regshift = 0; -- 1.7.2.3 _______________________________________________ http://lists.milkymist.org/listinfo.cgi/devel-milkymist.org IRC: #milkymist@Freenode Twitter: www.twitter.com/milkymistvj Ideas? http://milkymist.uservoice.com