aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/Makefile1
-rw-r--r--arch/mips/kernel/asm-offsets.c4
-rw-r--r--arch/mips/kernel/cpu-bugs64.c2
-rw-r--r--arch/mips/kernel/irixsig.c2
-rw-r--r--arch/mips/kernel/irq_txx9.c192
-rw-r--r--arch/mips/kernel/machine_kexec.c5
-rw-r--r--arch/mips/kernel/mips-mt.c7
-rw-r--r--arch/mips/kernel/smp-mt.c6
-rw-r--r--arch/mips/kernel/smtc.c2
-rw-r--r--arch/mips/kernel/traps.c31
-rw-r--r--arch/mips/kernel/vmlinux.lds.S7
11 files changed, 231 insertions, 28 deletions
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 07344cb37596..2fd96d95a39c 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_IRQ_CPU) += irq_cpu.o
50obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o 50obj-$(CONFIG_IRQ_CPU_RM7K) += irq-rm7000.o
51obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o 51obj-$(CONFIG_IRQ_CPU_RM9K) += irq-rm9000.o
52obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o 52obj-$(CONFIG_MIPS_BOARDS_GEN) += irq-msc01.o
53obj-$(CONFIG_IRQ_TXX9) += irq_txx9.o
53 54
54obj-$(CONFIG_32BIT) += scall32-o32.o 55obj-$(CONFIG_32BIT) += scall32-o32.o
55obj-$(CONFIG_64BIT) += scall64-64.o 56obj-$(CONFIG_64BIT) += scall64-64.o
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 013327286c26..ca136298acdc 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -232,6 +232,10 @@ void output_mm_defines(void)
232 constant("#define _PMD_T_LOG2 ", PMD_T_LOG2); 232 constant("#define _PMD_T_LOG2 ", PMD_T_LOG2);
233 constant("#define _PTE_T_LOG2 ", PTE_T_LOG2); 233 constant("#define _PTE_T_LOG2 ", PTE_T_LOG2);
234 linefeed; 234 linefeed;
235 constant("#define _PGD_ORDER ", PGD_ORDER);
236 constant("#define _PMD_ORDER ", PMD_ORDER);
237 constant("#define _PTE_ORDER ", PTE_ORDER);
238 linefeed;
235 constant("#define _PMD_SHIFT ", PMD_SHIFT); 239 constant("#define _PMD_SHIFT ", PMD_SHIFT);
236 constant("#define _PGDIR_SHIFT ", PGDIR_SHIFT); 240 constant("#define _PGDIR_SHIFT ", PGDIR_SHIFT);
237 linefeed; 241 linefeed;
diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c
index c09337b947b9..ac04f0adc408 100644
--- a/arch/mips/kernel/cpu-bugs64.c
+++ b/arch/mips/kernel/cpu-bugs64.c
@@ -29,7 +29,7 @@ static inline void align_mod(const int align, const int mod)
29 ".endr\n\t" 29 ".endr\n\t"
30 ".set pop" 30 ".set pop"
31 : 31 :
32 : "n" (align), "n" (mod)); 32 : "rn" (align), "rn" (mod));
33} 33}
34 34
35static inline void mult_sh_align_mod(long *v1, long *v2, long *w, 35static inline void mult_sh_align_mod(long *v1, long *v2, long *w,
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 6980deb6dced..28b2a8f00911 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -725,7 +725,7 @@ asmlinkage int irix_getcontext(struct pt_regs *regs)
725 current->comm, current->pid, ctx); 725 current->comm, current->pid, ctx);
726#endif 726#endif
727 727
728 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))); 728 if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx)))
729 return -EFAULT; 729 return -EFAULT;
730 730
731 error = __put_user(current->thread.irix_oldctx, &ctx->link); 731 error = __put_user(current->thread.irix_oldctx, &ctx->link);
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c
new file mode 100644
index 000000000000..a4d1462c27f7
--- /dev/null
+++ b/arch/mips/kernel/irq_txx9.c
@@ -0,0 +1,192 @@
1/*
2 * linux/arch/mips/kernel/irq_txx9.c
3 *
4 * Based on linux/arch/mips/jmr3927/rbhma3100/irq.c,
5 * linux/arch/mips/tx4927/common/tx4927_irq.c,
6 * linux/arch/mips/tx4938/common/irq.c
7 *
8 * Copyright 2001, 2003-2005 MontaVista Software Inc.
9 * Author: MontaVista Software, Inc.
10 * ahennessy@mvista.com
11 * source@mvista.com
12 * Copyright (C) 2000-2001 Toshiba Corporation
13 *
14 * This file is subject to the terms and conditions of the GNU General Public
15 * License. See the file "COPYING" in the main directory of this archive
16 * for more details.
17 */
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/types.h>
21#include <asm/txx9irq.h>
22
23struct txx9_irc_reg {
24 u32 cer;
25 u32 cr[2];
26 u32 unused0;
27 u32 ilr[8];
28 u32 unused1[4];
29 u32 imr;
30 u32 unused2[7];
31 u32 scr;
32 u32 unused3[7];
33 u32 ssr;
34 u32 unused4[7];
35 u32 csr;
36};
37
38/* IRCER : Int. Control Enable */
39#define TXx9_IRCER_ICE 0x00000001
40
41/* IRCR : Int. Control */
42#define TXx9_IRCR_LOW 0x00000000
43#define TXx9_IRCR_HIGH 0x00000001
44#define TXx9_IRCR_DOWN 0x00000002
45#define TXx9_IRCR_UP 0x00000003
46#define TXx9_IRCR_EDGE(cr) ((cr) & 0x00000002)
47
48/* IRSCR : Int. Status Control */
49#define TXx9_IRSCR_EIClrE 0x00000100
50#define TXx9_IRSCR_EIClr_MASK 0x0000000f
51
52/* IRCSR : Int. Current Status */
53#define TXx9_IRCSR_IF 0x00010000
54#define TXx9_IRCSR_ILV_MASK 0x00000700
55#define TXx9_IRCSR_IVL_MASK 0x0000001f
56
57#define irc_dlevel 0
58#define irc_elevel 1
59
60static struct txx9_irc_reg __iomem *txx9_ircptr __read_mostly;
61
62static struct {
63 unsigned char level;
64 unsigned char mode;
65} txx9irq[TXx9_MAX_IR] __read_mostly;
66
67static void txx9_irq_unmask(unsigned int irq)
68{
69 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
70 u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16 ) / 2];
71 int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
72
73 __raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
74 | (txx9irq[irq_nr].level << ofs),
75 ilrp);
76#ifdef CONFIG_CPU_TX39XX
77 /* update IRCSR */
78 __raw_writel(0, &txx9_ircptr->imr);
79 __raw_writel(irc_elevel, &txx9_ircptr->imr);
80#endif
81}
82
83static inline void txx9_irq_mask(unsigned int irq)
84{
85 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
86 u32 __iomem *ilrp = &txx9_ircptr->ilr[(irq_nr % 16) / 2];
87 int ofs = irq_nr / 16 * 16 + (irq_nr & 1) * 8;
88
89 __raw_writel((__raw_readl(ilrp) & ~(0xff << ofs))
90 | (irc_dlevel << ofs),
91 ilrp);
92#ifdef CONFIG_CPU_TX39XX
93 /* update IRCSR */
94 __raw_writel(0, &txx9_ircptr->imr);
95 __raw_writel(irc_elevel, &txx9_ircptr->imr);
96 /* flush write buffer */
97 __raw_readl(&txx9_ircptr->ssr);
98#else
99 mmiowb();
100#endif
101}
102
103static void txx9_irq_mask_ack(unsigned int irq)
104{
105 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
106
107 txx9_irq_mask(irq);
108 /* clear edge detection */
109 if (unlikely(TXx9_IRCR_EDGE(txx9irq[irq_nr].mode)))
110 __raw_writel(TXx9_IRSCR_EIClrE | irq_nr, &txx9_ircptr->scr);
111}
112
113static int txx9_irq_set_type(unsigned int irq, unsigned int flow_type)
114{
115 unsigned int irq_nr = irq - TXX9_IRQ_BASE;
116 u32 cr;
117 u32 __iomem *crp;
118 int ofs;
119 int mode;
120
121 if (flow_type & IRQF_TRIGGER_PROBE)
122 return 0;
123 switch (flow_type & IRQF_TRIGGER_MASK) {
124 case IRQF_TRIGGER_RISING: mode = TXx9_IRCR_UP; break;
125 case IRQF_TRIGGER_FALLING: mode = TXx9_IRCR_DOWN; break;
126 case IRQF_TRIGGER_HIGH: mode = TXx9_IRCR_HIGH; break;
127 case IRQF_TRIGGER_LOW: mode = TXx9_IRCR_LOW; break;
128 default:
129 return -EINVAL;
130 }
131 crp = &txx9_ircptr->cr[(unsigned int)irq_nr / 8];
132 cr = __raw_readl(crp);
133 ofs = (irq_nr & (8 - 1)) * 2;
134 cr &= ~(0x3 << ofs);
135 cr |= (mode & 0x3) << ofs;
136 __raw_writel(cr, crp);
137 txx9irq[irq_nr].mode = mode;
138 return 0;
139}
140
141static struct irq_chip txx9_irq_chip = {
142 .name = "TXX9",
143 .ack = txx9_irq_mask_ack,
144 .mask = txx9_irq_mask,
145 .mask_ack = txx9_irq_mask_ack,
146 .unmask = txx9_irq_unmask,
147 .set_type = txx9_irq_set_type,
148};
149
150void __init txx9_irq_init(unsigned long baseaddr)
151{
152 int i;
153
154 txx9_ircptr = ioremap(baseaddr, sizeof(struct txx9_irc_reg));
155 for (i = 0; i < TXx9_MAX_IR; i++) {
156 txx9irq[i].level = 4; /* middle level */
157 txx9irq[i].mode = TXx9_IRCR_LOW;
158 set_irq_chip_and_handler(TXX9_IRQ_BASE + i,
159 &txx9_irq_chip, handle_level_irq);
160 }
161
162 /* mask all IRC interrupts */
163 __raw_writel(0, &txx9_ircptr->imr);
164 for (i = 0; i < 8; i++)
165 __raw_writel(0, &txx9_ircptr->ilr[i]);
166 /* setup IRC interrupt mode (Low Active) */
167 for (i = 0; i < 2; i++)
168 __raw_writel(0, &txx9_ircptr->cr[i]);
169 /* enable interrupt control */
170 __raw_writel(TXx9_IRCER_ICE, &txx9_ircptr->cer);
171 __raw_writel(irc_elevel, &txx9_ircptr->imr);
172}
173
174int __init txx9_irq_set_pri(int irc_irq, int new_pri)
175{
176 int old_pri;
177
178 if ((unsigned int)irc_irq >= TXx9_MAX_IR)
179 return 0;
180 old_pri = txx9irq[irc_irq].level;
181 txx9irq[irc_irq].level = new_pri;
182 return old_pri;
183}
184
185int txx9_irq(void)
186{
187 u32 csr = __raw_readl(&txx9_ircptr->csr);
188
189 if (likely(!(csr & TXx9_IRCSR_IF)))
190 return TXX9_IRQ_BASE + (csr & (TXx9_MAX_IR - 1));
191 return -1;
192}
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index 22960d67cf07..85beb9b0b2d0 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -78,11 +78,8 @@ machine_kexec(struct kimage *image)
78 */ 78 */
79 local_irq_disable(); 79 local_irq_disable();
80 80
81 flush_icache_range(reboot_code_buffer,
82 reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
83
84 printk("Will call new kernel at %08lx\n", image->start); 81 printk("Will call new kernel at %08lx\n", image->start);
85 printk("Bye ...\n"); 82 printk("Bye ...\n");
86 flush_cache_all(); 83 __flush_cache_all();
87 ((noretfun_t) reboot_code_buffer)(); 84 ((noretfun_t) reboot_code_buffer)();
88} 85}
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c
index 7169a4db37b8..56750b02ab40 100644
--- a/arch/mips/kernel/mips-mt.c
+++ b/arch/mips/kernel/mips-mt.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include <linux/device.h> 6#include <linux/device.h>
7#include <linux/kallsyms.h>
7#include <linux/kernel.h> 8#include <linux/kernel.h>
8#include <linux/sched.h> 9#include <linux/sched.h>
9#include <linux/module.h> 10#include <linux/module.h>
@@ -84,8 +85,9 @@ void mips_mt_regdump(unsigned long mvpctl)
84 read_vpe_c0_vpeconf0()); 85 read_vpe_c0_vpeconf0());
85 printk(" VPE%d.Status : %08lx\n", 86 printk(" VPE%d.Status : %08lx\n",
86 i, read_vpe_c0_status()); 87 i, read_vpe_c0_status());
87 printk(" VPE%d.EPC : %08lx\n", 88 printk(" VPE%d.EPC : %08lx ",
88 i, read_vpe_c0_epc()); 89 i, read_vpe_c0_epc());
90 print_symbol("%s\n", read_vpe_c0_epc());
89 printk(" VPE%d.Cause : %08lx\n", 91 printk(" VPE%d.Cause : %08lx\n",
90 i, read_vpe_c0_cause()); 92 i, read_vpe_c0_cause());
91 printk(" VPE%d.Config7 : %08lx\n", 93 printk(" VPE%d.Config7 : %08lx\n",
@@ -110,7 +112,8 @@ void mips_mt_regdump(unsigned long mvpctl)
110 } 112 }
111 printk(" TCStatus : %08lx\n", tcstatval); 113 printk(" TCStatus : %08lx\n", tcstatval);
112 printk(" TCBind : %08lx\n", read_tc_c0_tcbind()); 114 printk(" TCBind : %08lx\n", read_tc_c0_tcbind());
113 printk(" TCRestart : %08lx\n", read_tc_c0_tcrestart()); 115 printk(" TCRestart : %08lx ", read_tc_c0_tcrestart());
116 print_symbol("%s\n", read_tc_c0_tcrestart());
114 printk(" TCHalt : %08lx\n", haltval); 117 printk(" TCHalt : %08lx\n", haltval);
115 printk(" TCContext : %08lx\n", read_tc_c0_tccontext()); 118 printk(" TCContext : %08lx\n", read_tc_c0_tccontext());
116 if (!haltval) 119 if (!haltval)
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c
index 19b30d6f1727..05dcce416325 100644
--- a/arch/mips/kernel/smp-mt.c
+++ b/arch/mips/kernel/smp-mt.c
@@ -287,7 +287,7 @@ void __init plat_prepare_cpus(unsigned int max_cpus)
287 * (unsigned long)idle->thread_info the gp 287 * (unsigned long)idle->thread_info the gp
288 * assumes a 1:1 mapping of TC => VPE 288 * assumes a 1:1 mapping of TC => VPE
289 */ 289 */
290void prom_boot_secondary(int cpu, struct task_struct *idle) 290void __cpuinit prom_boot_secondary(int cpu, struct task_struct *idle)
291{ 291{
292 struct thread_info *gp = task_thread_info(idle); 292 struct thread_info *gp = task_thread_info(idle);
293 dvpe(); 293 dvpe();
@@ -321,7 +321,7 @@ void prom_boot_secondary(int cpu, struct task_struct *idle)
321 evpe(EVPE_ENABLE); 321 evpe(EVPE_ENABLE);
322} 322}
323 323
324void prom_init_secondary(void) 324void __cpuinit prom_init_secondary(void)
325{ 325{
326 /* Enable per-cpu interrupts */ 326 /* Enable per-cpu interrupts */
327 327
@@ -330,7 +330,7 @@ void prom_init_secondary(void)
330 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7)); 330 (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP6 | STATUSF_IP7));
331} 331}
332 332
333void prom_smp_finish(void) 333void __cpuinit prom_smp_finish(void)
334{ 334{
335 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); 335 write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ));
336 336
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 16aa5d37117c..43826c16101d 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -28,8 +28,6 @@
28 * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. 28 * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set.
29 */ 29 */
30 30
31#define MIPS_CPU_IPI_IRQ 1
32
33#define LOCK_MT_PRA() \ 31#define LOCK_MT_PRA() \
34 local_irq_save(flags); \ 32 local_irq_save(flags); \
35 mtflags = dmt() 33 mtflags = dmt()
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index c8e291c83057..6379003f9d8d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -606,6 +606,8 @@ asmlinkage void do_ov(struct pt_regs *regs)
606 */ 606 */
607asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) 607asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
608{ 608{
609 siginfo_t info;
610
609 die_if_kernel("FP exception in kernel code", regs); 611 die_if_kernel("FP exception in kernel code", regs);
610 612
611 if (fcr31 & FPU_CSR_UNI_X) { 613 if (fcr31 & FPU_CSR_UNI_X) {
@@ -641,9 +643,22 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
641 force_sig(sig, current); 643 force_sig(sig, current);
642 644
643 return; 645 return;
644 } 646 } else if (fcr31 & FPU_CSR_INV_X)
645 647 info.si_code = FPE_FLTINV;
646 force_sig(SIGFPE, current); 648 else if (fcr31 & FPU_CSR_DIV_X)
649 info.si_code = FPE_FLTDIV;
650 else if (fcr31 & FPU_CSR_OVF_X)
651 info.si_code = FPE_FLTOVF;
652 else if (fcr31 & FPU_CSR_UDF_X)
653 info.si_code = FPE_FLTUND;
654 else if (fcr31 & FPU_CSR_INE_X)
655 info.si_code = FPE_FLTRES;
656 else
657 info.si_code = __SI_FAULT;
658 info.si_signo = SIGFPE;
659 info.si_errno = 0;
660 info.si_addr = (void __user *) regs->cp0_epc;
661 force_sig_info(SIGFPE, &info, current);
647} 662}
648 663
649asmlinkage void do_bp(struct pt_regs *regs) 664asmlinkage void do_bp(struct pt_regs *regs)
@@ -1035,19 +1050,11 @@ void ejtag_exception_handler(struct pt_regs *regs)
1035/* 1050/*
1036 * NMI exception handler. 1051 * NMI exception handler.
1037 */ 1052 */
1038void nmi_exception_handler(struct pt_regs *regs) 1053NORET_TYPE void ATTRIB_NORET nmi_exception_handler(struct pt_regs *regs)
1039{ 1054{
1040#ifdef CONFIG_MIPS_MT_SMTC
1041 unsigned long dvpret = dvpe();
1042 bust_spinlocks(1);
1043 printk("NMI taken!!!!\n");
1044 mips_mt_regdump(dvpret);
1045#else
1046 bust_spinlocks(1); 1055 bust_spinlocks(1);
1047 printk("NMI taken!!!!\n"); 1056 printk("NMI taken!!!!\n");
1048#endif /* CONFIG_MIPS_MT_SMTC */
1049 die("NMI", regs); 1057 die("NMI", regs);
1050 while(1) ;
1051} 1058}
1052 1059
1053#define VECTORSPACING 0x100 /* for EI/VI mode */ 1060#define VECTORSPACING 0x100 /* for EI/VI mode */
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index bc9bae2a73f4..60bbaecde187 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -142,15 +142,16 @@ SECTIONS
142 *(.exitcall.exit) 142 *(.exitcall.exit)
143 143
144 /* ABI crap starts here */ 144 /* ABI crap starts here */
145 *(.comment)
146 *(.MIPS.options) 145 *(.MIPS.options)
147 *(.note)
148 *(.options) 146 *(.options)
149 *(.pdr) 147 *(.pdr)
150 *(.reginfo) 148 *(.reginfo)
151 *(.mdebug*)
152 } 149 }
153 150
151 /* These mark the ABI of the kernel for debuggers. */
152 .mdebug.abi32 : { KEEP(*(.mdebug.abi32)) }
153 .mdebug.abi64 : { KEEP(*(.mdebug.abi64)) }
154
154 /* This is the MIPS specific mdebug section. */ 155 /* This is the MIPS specific mdebug section. */
155 .mdebug : { *(.mdebug) } 156 .mdebug : { *(.mdebug) }
156 157