2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 2012 MIPS Technologies, Inc. All rights reserved.
8 #include <linux/init.h>
11 #include <asm/bootinfo.h>
12 #include <asm/cacheflush.h>
13 #include <asm/traps.h>
14 #include <asm/mips-boards/generic.h>
15 #include <asm/fw/fw.h>
17 extern char except_vec_nmi;
18 extern char except_vec_ejtag_debug;
20 static void __init mips_nmi_setup(void)
25 (void *)(CAC_BASE + 0xa80) :
26 (void *)(CAC_BASE + 0x380);
27 #ifdef CONFIG_CPU_MICROMIPS
29 * Decrement the exception vector address by one for microMIPS.
31 memcpy(base, (&except_vec_nmi - 1), 0x80);
34 * This is a hack. We do not know if the boot loader was built with
35 * microMIPS instructions or not. If it was not, the NMI exception
36 * code at 0x80000a80 will be taken in MIPS32 mode. The hand coded
37 * assembly below forces us into microMIPS mode if we are a pure
38 * microMIPS kernel. The assembly instructions are:
40 * 3C1A8000 lui k0,0x8000
41 * 375A0381 ori k0,k0,0x381
45 * The mode switch occurs by jumping to the unaligned exception
46 * vector address at 0x80000381 which would have been 0x80000380
47 * in MIPS32 mode. The jump to the unaligned address transitions
48 * us into microMIPS mode.
51 void *base2 = (void *)(CAC_BASE + 0xa80);
52 *((unsigned int *)base2) = 0x3c1a8000;
53 *((unsigned int *)base2 + 1) = 0x375a0381;
54 *((unsigned int *)base2 + 2) = 0x03400008;
55 *((unsigned int *)base2 + 3) = 0x00000000;
56 flush_icache_range((unsigned long)base2,
57 (unsigned long)base2 + 0x10);
60 memcpy(base, &except_vec_nmi, 0x80);
62 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
65 static void __init mips_ejtag_setup(void)
70 (void *)(CAC_BASE + 0xa00) :
71 (void *)(CAC_BASE + 0x300);
72 #ifdef CONFIG_CPU_MICROMIPS
74 memcpy(base, (&except_vec_ejtag_debug - 1), 0x80);
76 void *base2 = (void *)(CAC_BASE + 0xa00);
77 *((unsigned int *)base2) = 0x3c1a8000;
78 *((unsigned int *)base2 + 1) = 0x375a0301;
79 *((unsigned int *)base2 + 2) = 0x03400008;
80 *((unsigned int *)base2 + 3) = 0x00000000;
81 flush_icache_range((unsigned long)base2,
82 (unsigned long)base2 + 0x10);
85 memcpy(base, &except_vec_ejtag_debug, 0x80);
87 flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
90 void __init prom_init(void)
92 board_nmi_handler_setup = mips_nmi_setup;
93 board_ejtag_handler_setup = mips_ejtag_setup;
96 #ifdef CONFIG_EARLY_PRINTK
97 if ((strstr(fw_getcmdline(), "console=ttyS0")) != NULL)
98 fw_init_early_console(0);
99 else if ((strstr(fw_getcmdline(), "console=ttyS1")) != NULL)
100 fw_init_early_console(1);
104 void __init prom_free_prom_memory(void)