aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mn10300/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mn10300/kernel')
-rw-r--r--arch/mn10300/kernel/Makefile29
-rw-r--r--arch/mn10300/kernel/asm-offsets.c108
-rw-r--r--arch/mn10300/kernel/cevt-mn10300.c137
-rw-r--r--arch/mn10300/kernel/csrc-mn10300.c34
-rw-r--r--arch/mn10300/kernel/entry.S772
-rw-r--r--arch/mn10300/kernel/fpu-low.S258
-rw-r--r--arch/mn10300/kernel/fpu-nofpu-low.S39
-rw-r--r--arch/mn10300/kernel/fpu-nofpu.c31
-rw-r--r--arch/mn10300/kernel/fpu.c177
-rw-r--r--arch/mn10300/kernel/gdb-io-serial-low.S91
-rw-r--r--arch/mn10300/kernel/gdb-io-serial.c174
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm-low.S93
-rw-r--r--arch/mn10300/kernel/gdb-io-ttysm.c303
-rw-r--r--arch/mn10300/kernel/gdb-low.S115
-rw-r--r--arch/mn10300/kernel/gdb-stub.c1924
-rw-r--r--arch/mn10300/kernel/head.S442
-rw-r--r--arch/mn10300/kernel/internal.h40
-rw-r--r--arch/mn10300/kernel/io.c30
-rw-r--r--arch/mn10300/kernel/irq.c356
-rw-r--r--arch/mn10300/kernel/kgdb.c502
-rw-r--r--arch/mn10300/kernel/kprobes.c656
-rw-r--r--arch/mn10300/kernel/mn10300-debug.c58
-rw-r--r--arch/mn10300/kernel/mn10300-serial-low.S194
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c1790
-rw-r--r--arch/mn10300/kernel/mn10300-serial.h130
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog-low.S66
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog.c205
-rw-r--r--arch/mn10300/kernel/mn10300_ksyms.c39
-rw-r--r--arch/mn10300/kernel/module.c156
-rw-r--r--arch/mn10300/kernel/process.c175
-rw-r--r--arch/mn10300/kernel/profile-low.S72
-rw-r--r--arch/mn10300/kernel/profile.c51
-rw-r--r--arch/mn10300/kernel/ptrace.c386
-rw-r--r--arch/mn10300/kernel/rtc.c46
-rw-r--r--arch/mn10300/kernel/setup.c283
-rw-r--r--arch/mn10300/kernel/sigframe.h33
-rw-r--r--arch/mn10300/kernel/signal.c431
-rw-r--r--arch/mn10300/kernel/smp-low.S97
-rw-r--r--arch/mn10300/kernel/smp.c1186
-rw-r--r--arch/mn10300/kernel/switch_to.S179
-rw-r--r--arch/mn10300/kernel/sys_mn10300.c33
-rw-r--r--arch/mn10300/kernel/time.c125
-rw-r--r--arch/mn10300/kernel/traps.c615
-rw-r--r--arch/mn10300/kernel/vmlinux.lds.S94
44 files changed, 0 insertions, 12755 deletions
diff --git a/arch/mn10300/kernel/Makefile b/arch/mn10300/kernel/Makefile
deleted file mode 100644
index de32af0e4b6e..000000000000
--- a/arch/mn10300/kernel/Makefile
+++ /dev/null
@@ -1,29 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the MN10300-specific core kernel code
-#
-extra-y := head.o vmlinux.lds
-
-fpu-obj-y := fpu-nofpu.o fpu-nofpu-low.o
-fpu-obj-$(CONFIG_FPU) := fpu.o fpu-low.o
-
-obj-y := process.o signal.o entry.o traps.o irq.o \
- ptrace.o setup.o time.o sys_mn10300.o io.o \
- switch_to.o mn10300_ksyms.o $(fpu-obj-y) \
- csrc-mn10300.o cevt-mn10300.o
-
-obj-$(CONFIG_SMP) += smp.o smp-low.o
-
-obj-$(CONFIG_MN10300_WD_TIMER) += mn10300-watchdog.o mn10300-watchdog-low.o
-
-obj-$(CONFIG_MN10300_TTYSM) += mn10300-serial.o mn10300-serial-low.o \
- mn10300-debug.o
-obj-$(CONFIG_GDBSTUB) += gdb-stub.o gdb-low.o
-obj-$(CONFIG_GDBSTUB_ON_TTYSx) += gdb-io-serial.o gdb-io-serial-low.o
-obj-$(CONFIG_GDBSTUB_ON_TTYSMx) += gdb-io-ttysm.o gdb-io-ttysm-low.o
-
-obj-$(CONFIG_MN10300_RTC) += rtc.o
-obj-$(CONFIG_PROFILE) += profile.o profile-low.o
-obj-$(CONFIG_MODULES) += module.o
-obj-$(CONFIG_KPROBES) += kprobes.o
-obj-$(CONFIG_KGDB) += kgdb.o
diff --git a/arch/mn10300/kernel/asm-offsets.c b/arch/mn10300/kernel/asm-offsets.c
deleted file mode 100644
index 57e6cc96267b..000000000000
--- a/arch/mn10300/kernel/asm-offsets.c
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Generate definitions needed by assembly language modules.
- * This code generates raw asm output which is post-processed
- * to extract and format the required data.
- */
-
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/personality.h>
-#include <linux/kbuild.h>
-#include <asm/ucontext.h>
-#include <asm/processor.h>
-#include <asm/thread_info.h>
-#include <asm/ptrace.h>
-#include "sigframe.h"
-#include "mn10300-serial.h"
-
-void foo(void)
-{
- OFFSET(SIGCONTEXT_d0, sigcontext, d0);
- OFFSET(SIGCONTEXT_d1, sigcontext, d1);
- BLANK();
-
- OFFSET(TI_task, thread_info, task);
- OFFSET(TI_frame, thread_info, frame);
- OFFSET(TI_flags, thread_info, flags);
- OFFSET(TI_cpu, thread_info, cpu);
- OFFSET(TI_preempt_count, thread_info, preempt_count);
- OFFSET(TI_addr_limit, thread_info, addr_limit);
- BLANK();
-
- OFFSET(REG_D0, pt_regs, d0);
- OFFSET(REG_D1, pt_regs, d1);
- OFFSET(REG_D2, pt_regs, d2);
- OFFSET(REG_D3, pt_regs, d3);
- OFFSET(REG_A0, pt_regs, a0);
- OFFSET(REG_A1, pt_regs, a1);
- OFFSET(REG_A2, pt_regs, a2);
- OFFSET(REG_A3, pt_regs, a3);
- OFFSET(REG_E0, pt_regs, e0);
- OFFSET(REG_E1, pt_regs, e1);
- OFFSET(REG_E2, pt_regs, e2);
- OFFSET(REG_E3, pt_regs, e3);
- OFFSET(REG_E4, pt_regs, e4);
- OFFSET(REG_E5, pt_regs, e5);
- OFFSET(REG_E6, pt_regs, e6);
- OFFSET(REG_E7, pt_regs, e7);
- OFFSET(REG_SP, pt_regs, sp);
- OFFSET(REG_EPSW, pt_regs, epsw);
- OFFSET(REG_PC, pt_regs, pc);
- OFFSET(REG_LAR, pt_regs, lar);
- OFFSET(REG_LIR, pt_regs, lir);
- OFFSET(REG_MDR, pt_regs, mdr);
- OFFSET(REG_MCVF, pt_regs, mcvf);
- OFFSET(REG_MCRL, pt_regs, mcrl);
- OFFSET(REG_MCRH, pt_regs, mcrh);
- OFFSET(REG_MDRQ, pt_regs, mdrq);
- OFFSET(REG_ORIG_D0, pt_regs, orig_d0);
- OFFSET(REG_NEXT, pt_regs, next);
- DEFINE(REG__END, sizeof(struct pt_regs));
- BLANK();
-
- OFFSET(THREAD_UREGS, thread_struct, uregs);
- OFFSET(THREAD_PC, thread_struct, pc);
- OFFSET(THREAD_SP, thread_struct, sp);
- OFFSET(THREAD_A3, thread_struct, a3);
- OFFSET(THREAD_USP, thread_struct, usp);
-#ifdef CONFIG_FPU
- OFFSET(THREAD_FPU_FLAGS, thread_struct, fpu_flags);
- OFFSET(THREAD_FPU_STATE, thread_struct, fpu_state);
- DEFINE(__THREAD_USING_FPU, THREAD_USING_FPU);
- DEFINE(__THREAD_HAS_FPU, THREAD_HAS_FPU);
-#endif /* CONFIG_FPU */
- BLANK();
-
- OFFSET(TASK_THREAD, task_struct, thread);
- BLANK();
-
- DEFINE(CLONE_VM_asm, CLONE_VM);
- DEFINE(CLONE_FS_asm, CLONE_FS);
- DEFINE(CLONE_FILES_asm, CLONE_FILES);
- DEFINE(CLONE_SIGHAND_asm, CLONE_SIGHAND);
- DEFINE(CLONE_UNTRACED_asm, CLONE_UNTRACED);
- DEFINE(SIGCHLD_asm, SIGCHLD);
- BLANK();
-
- OFFSET(RT_SIGFRAME_sigcontext, rt_sigframe, uc.uc_mcontext);
-
- DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
-
- OFFSET(__rx_buffer, mn10300_serial_port, rx_buffer);
- OFFSET(__rx_inp, mn10300_serial_port, rx_inp);
- OFFSET(__rx_outp, mn10300_serial_port, rx_outp);
- OFFSET(__uart_state, mn10300_serial_port, uart.state);
- OFFSET(__tx_xchar, mn10300_serial_port, tx_xchar);
- OFFSET(__tx_flags, mn10300_serial_port, tx_flags);
- OFFSET(__intr_flags, mn10300_serial_port, intr_flags);
- OFFSET(__rx_icr, mn10300_serial_port, rx_icr);
- OFFSET(__tx_icr, mn10300_serial_port, tx_icr);
- OFFSET(__tm_icr, mn10300_serial_port, _tmicr);
- OFFSET(__iobase, mn10300_serial_port, _iobase);
-
- DEFINE(__UART_XMIT_SIZE, UART_XMIT_SIZE);
- OFFSET(__xmit_buffer, uart_state, xmit.buf);
- OFFSET(__xmit_head, uart_state, xmit.head);
- OFFSET(__xmit_tail, uart_state, xmit.tail);
-}
diff --git a/arch/mn10300/kernel/cevt-mn10300.c b/arch/mn10300/kernel/cevt-mn10300.c
deleted file mode 100644
index 2b21bbc9efa4..000000000000
--- a/arch/mn10300/kernel/cevt-mn10300.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* MN10300 clockevents
- *
- * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/clockchips.h>
-#include <linux/interrupt.h>
-#include <linux/percpu.h>
-#include <linux/smp.h>
-#include <asm/timex.h>
-#include "internal.h"
-
-#ifdef CONFIG_SMP
-#if (CONFIG_NR_CPUS > 2) && !defined(CONFIG_GEENERIC_CLOCKEVENTS_BROADCAST)
-#error "This doesn't scale well! Need per-core local timers."
-#endif
-#else /* CONFIG_SMP */
-#define stop_jiffies_counter1()
-#define reload_jiffies_counter1(x)
-#define TMJC1IRQ TMJCIRQ
-#endif
-
-
-static int next_event(unsigned long delta,
- struct clock_event_device *evt)
-{
- unsigned int cpu = smp_processor_id();
-
- if (cpu == 0) {
- stop_jiffies_counter();
- reload_jiffies_counter(delta - 1);
- } else {
- stop_jiffies_counter1();
- reload_jiffies_counter1(delta - 1);
- }
- return 0;
-}
-
-static DEFINE_PER_CPU(struct clock_event_device, mn10300_clockevent_device);
-static DEFINE_PER_CPU(struct irqaction, timer_irq);
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *cd;
- unsigned int cpu = smp_processor_id();
-
- if (cpu == 0)
- stop_jiffies_counter();
- else
- stop_jiffies_counter1();
-
- cd = &per_cpu(mn10300_clockevent_device, cpu);
- cd->event_handler(cd);
-
- return IRQ_HANDLED;
-}
-
-static void event_handler(struct clock_event_device *dev)
-{
-}
-
-static inline void setup_jiffies_interrupt(int irq,
- struct irqaction *action)
-{
- u16 tmp;
- setup_irq(irq, action);
- set_intr_level(irq, NUM2GxICR_LEVEL(CONFIG_TIMER_IRQ_LEVEL));
- GxICR(irq) |= GxICR_ENABLE | GxICR_DETECT | GxICR_REQUEST;
- tmp = GxICR(irq);
-}
-
-int __init init_clockevents(void)
-{
- struct clock_event_device *cd;
- struct irqaction *iact;
- unsigned int cpu = smp_processor_id();
-
- cd = &per_cpu(mn10300_clockevent_device, cpu);
-
- if (cpu == 0) {
- stop_jiffies_counter();
- cd->irq = TMJCIRQ;
- } else {
- stop_jiffies_counter1();
- cd->irq = TMJC1IRQ;
- }
-
- cd->name = "Timestamp";
- cd->features = CLOCK_EVT_FEAT_ONESHOT;
-
- /* Calculate shift/mult. We want to spawn at least 1 second */
- clockevents_calc_mult_shift(cd, MN10300_JCCLK, 1);
-
- /* Calculate the min / max delta */
- cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd);
- cd->max_delta_ticks = TMJCBR_MAX;
- cd->min_delta_ns = clockevent_delta2ns(100, cd);
- cd->min_delta_ticks = 100;
-
- cd->rating = 200;
- cd->cpumask = cpumask_of(smp_processor_id());
- cd->event_handler = event_handler;
- cd->set_next_event = next_event;
-
- iact = &per_cpu(timer_irq, cpu);
- iact->flags = IRQF_SHARED | IRQF_TIMER;
- iact->handler = timer_interrupt;
-
- clockevents_register_device(cd);
-
-#if defined(CONFIG_SMP) && !defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
- /* setup timer irq affinity so it only runs on this cpu */
- {
- struct irq_data *data;
- data = irq_get_irq_data(cd->irq);
- cpumask_copy(irq_data_get_affinity_mask(data), cpumask_of(cpu));
- iact->flags |= IRQF_NOBALANCING;
- }
-#endif
-
- if (cpu == 0) {
- reload_jiffies_counter(MN10300_JC_PER_HZ - 1);
- iact->name = "CPU0 Timer";
- } else {
- reload_jiffies_counter1(MN10300_JC_PER_HZ - 1);
- iact->name = "CPU1 Timer";
- }
-
- setup_jiffies_interrupt(cd->irq, iact);
-
- return 0;
-}
diff --git a/arch/mn10300/kernel/csrc-mn10300.c b/arch/mn10300/kernel/csrc-mn10300.c
deleted file mode 100644
index 6b74df3661f2..000000000000
--- a/arch/mn10300/kernel/csrc-mn10300.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* MN10300 clocksource
- *
- * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/clocksource.h>
-#include <linux/init.h>
-#include <asm/timex.h>
-#include "internal.h"
-
-static u64 mn10300_read(struct clocksource *cs)
-{
- return read_timestamp_counter();
-}
-
-static struct clocksource clocksource_mn10300 = {
- .name = "TSC",
- .rating = 200,
- .read = mn10300_read,
- .mask = CLOCKSOURCE_MASK(32),
- .flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-int __init init_clocksource(void)
-{
- startup_timestamp_counter();
- clocksource_register_hz(&clocksource_mn10300, MN10300_TSCCLK);
- return 0;
-}
diff --git a/arch/mn10300/kernel/entry.S b/arch/mn10300/kernel/entry.S
deleted file mode 100644
index 177d61de51c9..000000000000
--- a/arch/mn10300/kernel/entry.S
+++ /dev/null
@@ -1,772 +0,0 @@
-###############################################################################
-#
-# MN10300 Exception and interrupt entry points
-#
-# Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Modified by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/irqflags.h>
-#include <asm/thread_info.h>
-#include <asm/intctl-regs.h>
-#include <asm/busctl-regs.h>
-#include <asm/timer-regs.h>
-#include <unit/leds.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/errno.h>
-#include <asm/asm-offsets.h>
-#include <asm/frame.inc>
-
-#if defined(CONFIG_SMP) && defined(CONFIG_GDBSTUB)
-#include <asm/gdb-stub.h>
-#endif /* CONFIG_SMP && CONFIG_GDBSTUB */
-
-#ifdef CONFIG_PREEMPT
-#define preempt_stop LOCAL_IRQ_DISABLE
-#else
-#define preempt_stop
-#define resume_kernel restore_all
-#endif
-
- .am33_2
-
-###############################################################################
-#
-# the return path for a forked child
-# - on entry, D0 holds the address of the previous task to run
-#
-###############################################################################
-ENTRY(ret_from_fork)
- call schedule_tail[],0
- GET_THREAD_INFO a2
-
- # return 0 to indicate child process
- clr d0
- mov d0,(REG_D0,fp)
- jmp syscall_exit
-
-ENTRY(ret_from_kernel_thread)
- call schedule_tail[],0
- mov (REG_D0,fp),d0
- mov (REG_A0,fp),a0
- calls (a0)
- GET_THREAD_INFO a2 # A2 must be set on return from sys_exit()
- clr d0
- mov d0,(REG_D0,fp)
- jmp syscall_exit
-
-###############################################################################
-#
-# system call handler
-#
-###############################################################################
-ENTRY(system_call)
- add -4,sp
- SAVE_ALL
- mov d0,(REG_ORIG_D0,fp)
- GET_THREAD_INFO a2
- cmp nr_syscalls,d0
- bcc syscall_badsys
- btst _TIF_SYSCALL_TRACE,(TI_flags,a2)
- bne syscall_entry_trace
-syscall_call:
- add d0,d0,a1
- add a1,a1
- mov (REG_A0,fp),d0
- mov (sys_call_table,a1),a0
- calls (a0)
- mov d0,(REG_D0,fp)
-syscall_exit:
- # make sure we don't miss an interrupt setting need_resched or
- # sigpending between sampling and the rti
- LOCAL_IRQ_DISABLE
- mov (TI_flags,a2),d2
- btst _TIF_ALLWORK_MASK,d2
- bne syscall_exit_work
-restore_all:
- RESTORE_ALL
-
-###############################################################################
-#
-# perform work that needs to be done immediately before resumption and syscall
-# tracing
-#
-###############################################################################
- ALIGN
-syscall_exit_work:
- mov (REG_EPSW,fp),d0
- and EPSW_nSL,d0
- beq resume_kernel # returning to supervisor mode
-
- LOCAL_IRQ_ENABLE # could let syscall_trace_exit() call
- # schedule() instead
- btst _TIF_SYSCALL_TRACE,d2
- beq work_pending
- mov fp,d0
- call syscall_trace_exit[],0 # do_syscall_trace(regs)
- jmp resume_userspace
-
- ALIGN
-work_pending:
- btst _TIF_NEED_RESCHED,d2
- beq work_notifysig
-
-work_resched:
- call schedule[],0
-
-resume_userspace:
- # make sure we don't miss an interrupt setting need_resched or
- # sigpending between sampling and the rti
- LOCAL_IRQ_DISABLE
-
- # is there any work to be done other than syscall tracing?
- mov (TI_flags,a2),d2
- btst _TIF_WORK_MASK,d2
- beq restore_all
-
- LOCAL_IRQ_ENABLE
- btst _TIF_NEED_RESCHED,d2
- bne work_resched
-
- # deal with pending signals and notify-resume requests
-work_notifysig:
- mov fp,d0
- mov d2,d1
- call do_notify_resume[],0
- jmp resume_userspace
-
- # perform syscall entry tracing
-syscall_entry_trace:
- mov -ENOSYS,d0
- mov d0,(REG_D0,fp)
- mov fp,d0
- call syscall_trace_entry[],0 # returns the syscall number to actually use
- mov (REG_D1,fp),d1
- cmp nr_syscalls,d0
- bcs syscall_call
- jmp syscall_exit
-
-syscall_badsys:
- mov -ENOSYS,d0
- mov d0,(REG_D0,fp)
- jmp resume_userspace
-
- # userspace resumption stub bypassing syscall exit tracing
- .globl ret_from_exception, ret_from_intr
- ALIGN
-ret_from_exception:
- preempt_stop
-ret_from_intr:
- GET_THREAD_INFO a2
- mov (REG_EPSW,fp),d0 # need to deliver signals before
- # returning to userspace
- and EPSW_nSL,d0
- bne resume_userspace # returning to userspace
-
-#ifdef CONFIG_PREEMPT
-resume_kernel:
- LOCAL_IRQ_DISABLE
- mov (TI_preempt_count,a2),d0 # non-zero preempt_count ?
- cmp 0,d0
- bne restore_all
-
-need_resched:
- btst _TIF_NEED_RESCHED,(TI_flags,a2)
- beq restore_all
- mov (REG_EPSW,fp),d0
- and EPSW_IM,d0
- cmp EPSW_IM_7,d0 # interrupts off (exception path) ?
- bne restore_all
- call preempt_schedule_irq[],0
- jmp need_resched
-#else
- jmp resume_kernel
-#endif
-
-
-###############################################################################
-#
-# IRQ handler entry point
-# - intended to be entered at multiple priorities
-#
-###############################################################################
-ENTRY(irq_handler)
- add -4,sp
- SAVE_ALL
-
- # it's not a syscall
- mov 0xffffffff,d0
- mov d0,(REG_ORIG_D0,fp)
-
- mov fp,d0
- call do_IRQ[],0 # do_IRQ(regs)
-
- jmp ret_from_intr
-
-###############################################################################
-#
-# Double Fault handler entry point
-# - note that there will not be a stack, D0/A0 will hold EPSW/PC as were
-#
-###############################################################################
- .section .bss
- .balign THREAD_SIZE
- .space THREAD_SIZE
-__df_stack:
- .previous
-
-ENTRY(double_fault)
- mov a0,(__df_stack-4) # PC as was
- mov d0,(__df_stack-8) # EPSW as was
- mn10300_set_dbfleds # display 'db-f' on the LEDs
- mov 0xaa55aa55,d0
- mov d0,(__df_stack-12) # no ORIG_D0
- mov sp,a0 # save corrupted SP
- mov __df_stack-12,sp # emergency supervisor stack
- SAVE_ALL
- mov a0,(REG_A0,fp) # save corrupted SP as A0 (which got
- # clobbered by the CPU)
- mov fp,d0
- calls do_double_fault
-double_fault_loop:
- bra double_fault_loop
-
-###############################################################################
-#
-# Bus Error handler entry point
-# - handle external (async) bus errors separately
-#
-###############################################################################
-ENTRY(raw_bus_error)
- add -4,sp
- mov d0,(sp)
-#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
- mov (MMUCTR),d0
- mov d0,(MMUCTR)
-#endif
- mov (BCBERR),d0 # what
- btst BCBERR_BEMR_DMA,d0 # see if it was an external bus error
- beq __common_exception_aux # it wasn't
-
- SAVE_ALL
- mov (BCBEAR),d1 # destination of erroneous access
-
- mov (REG_ORIG_D0,fp),d2
- mov d2,(REG_D0,fp)
- mov -1,d2
- mov d2,(REG_ORIG_D0,fp)
-
- add -4,sp
- mov fp,(12,sp) # frame pointer
- call io_bus_error[],0
- jmp restore_all
-
-###############################################################################
-#
-# NMI exception entry points
-#
-# This is used by ordinary interrupt channels that have the GxICR_NMI bit set
-# in addition to the main NMI and Watchdog channels. SMP NMI IPIs use this
-# facility.
-#
-###############################################################################
-ENTRY(nmi_handler)
- add -4,sp
- mov d0,(sp)
- mov (TBR),d0
-
-#ifdef CONFIG_SMP
- add -4,sp
- mov d0,(sp) # save d0(TBR)
- movhu (NMIAGR),d0
- and NMIAGR_GN,d0
- lsr 0x2,d0
- cmp CALL_FUNCTION_NMI_IPI,d0
- bne nmi_not_smp_callfunc # if not call function, jump
-
- # function call nmi ipi
- add 4,sp # no need to store TBR
- mov GxICR_DETECT,d0 # clear NMI request
- movbu d0,(GxICR(CALL_FUNCTION_NMI_IPI))
- movhu (GxICR(CALL_FUNCTION_NMI_IPI)),d0
- and ~EPSW_NMID,epsw # enable NMI
-
- mov (sp),d0 # restore d0
- SAVE_ALL
- call smp_nmi_call_function_interrupt[],0
- RESTORE_ALL
-
-nmi_not_smp_callfunc:
-#ifdef CONFIG_KERNEL_DEBUGGER
- cmp DEBUGGER_NMI_IPI,d0
- bne nmi_not_debugger # if not kernel debugger NMI IPI, jump
-
- # kernel debugger NMI IPI
- add 4,sp # no need to store TBR
- mov GxICR_DETECT,d0 # clear NMI
- movbu d0,(GxICR(DEBUGGER_NMI_IPI))
- movhu (GxICR(DEBUGGER_NMI_IPI)),d0
- and ~EPSW_NMID,epsw # enable NMI
-
- mov (sp),d0
- SAVE_ALL
- mov fp,d0 # arg 0: stacked register file
- mov a2,d1 # arg 1: exception number
- call debugger_nmi_interrupt[],0
- RESTORE_ALL
-
-nmi_not_debugger:
-#endif /* CONFIG_KERNEL_DEBUGGER */
- mov (sp),d0 # restore TBR to d0
- add 4,sp
-#endif /* CONFIG_SMP */
-
- bra __common_exception_nonmi
-
-###############################################################################
-#
-# General exception entry point
-#
-###############################################################################
-ENTRY(__common_exception)
- add -4,sp
- mov d0,(sp)
-#if defined(CONFIG_ERRATUM_NEED_TO_RELOAD_MMUCTR)
- mov (MMUCTR),d0
- mov d0,(MMUCTR)
-#endif
-
-__common_exception_aux:
- mov (TBR),d0
- and ~EPSW_NMID,epsw # turn NMIs back on if not NMI
- or EPSW_IE,epsw
-
-__common_exception_nonmi:
- and 0x0000FFFF,d0 # turn the exception code into a vector
- # table index
-
- btst 0x00000007,d0
- bne 1f
- cmp 0x00000400,d0
- bge 1f
-
- SAVE_ALL # build the stack frame
-
- mov (REG_D0,fp),a2 # get the exception number
- mov (REG_ORIG_D0,fp),d0
- mov d0,(REG_D0,fp)
- mov -1,d0
- mov d0,(REG_ORIG_D0,fp)
-
-#ifdef CONFIG_GDBSTUB
-#ifdef CONFIG_SMP
- call gdbstub_busy_check[],0
- and d0,d0 # check return value
- beq 2f
-#else /* CONFIG_SMP */
- btst 0x01,(gdbstub_busy)
- beq 2f
-#endif /* CONFIG_SMP */
- and ~EPSW_IE,epsw
- mov fp,d0
- mov a2,d1
- call gdbstub_exception[],0 # gdbstub itself caused an exception
- bra restore_all
-2:
-#endif /* CONFIG_GDBSTUB */
-
- mov fp,d0 # arg 0: stacked register file
- mov a2,d1 # arg 1: exception number
- lsr 1,a2
-
- mov (exception_table,a2),a2
- calls (a2)
- jmp ret_from_exception
-
-1: pi # BUG() equivalent
-
-###############################################################################
-#
-# Exception handler functions table
-#
-###############################################################################
- .data
-ENTRY(exception_table)
- .rept 0x400>>1
- .long uninitialised_exception
- .endr
- .previous
-
-###############################################################################
-#
-# Change an entry in the exception table
-# - D0 exception code, D1 handler
-#
-###############################################################################
-ENTRY(set_excp_vector)
- lsr 1,d0
- add exception_table,d0
- mov d1,(d0)
- mov 4,d1
- ret [],0
-
-###############################################################################
-#
-# System call table
-#
-###############################################################################
- .data
-ENTRY(sys_call_table)
- .long sys_restart_syscall /* 0 */
- .long sys_exit
- .long sys_fork
- .long sys_read
- .long sys_write
- .long sys_open /* 5 */
- .long sys_close
- .long sys_waitpid
- .long sys_creat
- .long sys_link
- .long sys_unlink /* 10 */
- .long sys_execve
- .long sys_chdir
- .long sys_time
- .long sys_mknod
- .long sys_chmod /* 15 */
- .long sys_lchown16
- .long sys_ni_syscall /* old break syscall holder */
- .long sys_stat
- .long sys_lseek
- .long sys_getpid /* 20 */
- .long sys_mount
- .long sys_oldumount
- .long sys_setuid16
- .long sys_getuid16
- .long sys_stime /* 25 */
- .long sys_ptrace
- .long sys_alarm
- .long sys_fstat
- .long sys_pause
- .long sys_utime /* 30 */
- .long sys_ni_syscall /* old stty syscall holder */
- .long sys_ni_syscall /* old gtty syscall holder */
- .long sys_access
- .long sys_nice
- .long sys_ni_syscall /* 35 - old ftime syscall holder */
- .long sys_sync
- .long sys_kill
- .long sys_rename
- .long sys_mkdir
- .long sys_rmdir /* 40 */
- .long sys_dup
- .long sys_pipe
- .long sys_times
- .long sys_ni_syscall /* old prof syscall holder */
- .long sys_brk /* 45 */
- .long sys_setgid16
- .long sys_getgid16
- .long sys_signal
- .long sys_geteuid16
- .long sys_getegid16 /* 50 */
- .long sys_acct
- .long sys_umount /* recycled never used phys() */
- .long sys_ni_syscall /* old lock syscall holder */
- .long sys_ioctl
- .long sys_fcntl /* 55 */
- .long sys_ni_syscall /* old mpx syscall holder */
- .long sys_setpgid
- .long sys_ni_syscall /* old ulimit syscall holder */
- .long sys_ni_syscall /* old sys_olduname */
- .long sys_umask /* 60 */
- .long sys_chroot
- .long sys_ustat
- .long sys_dup2
- .long sys_getppid
- .long sys_getpgrp /* 65 */
- .long sys_setsid
- .long sys_sigaction
- .long sys_sgetmask
- .long sys_ssetmask
- .long sys_setreuid16 /* 70 */
- .long sys_setregid16
- .long sys_sigsuspend
- .long sys_sigpending
- .long sys_sethostname
- .long sys_setrlimit /* 75 */
- .long sys_old_getrlimit
- .long sys_getrusage
- .long sys_gettimeofday
- .long sys_settimeofday
- .long sys_getgroups16 /* 80 */
- .long sys_setgroups16
- .long sys_old_select
- .long sys_symlink
- .long sys_lstat
- .long sys_readlink /* 85 */
- .long sys_uselib
- .long sys_swapon
- .long sys_reboot
- .long sys_old_readdir
- .long old_mmap /* 90 */
- .long sys_munmap
- .long sys_truncate
- .long sys_ftruncate
- .long sys_fchmod
- .long sys_fchown16 /* 95 */
- .long sys_getpriority
- .long sys_setpriority
- .long sys_ni_syscall /* old profil syscall holder */
- .long sys_statfs
- .long sys_fstatfs /* 100 */
- .long sys_ni_syscall /* ioperm */
- .long sys_socketcall
- .long sys_syslog
- .long sys_setitimer
- .long sys_getitimer /* 105 */
- .long sys_newstat
- .long sys_newlstat
- .long sys_newfstat
- .long sys_ni_syscall /* old sys_uname */
- .long sys_ni_syscall /* 110 - iopl */
- .long sys_vhangup
- .long sys_ni_syscall /* old "idle" system call */
- .long sys_ni_syscall /* vm86old */
- .long sys_wait4
- .long sys_swapoff /* 115 */
- .long sys_sysinfo
- .long sys_ipc
- .long sys_fsync
- .long sys_sigreturn
- .long sys_clone /* 120 */
- .long sys_setdomainname
- .long sys_newuname
- .long sys_ni_syscall /* modify_ldt */
- .long sys_adjtimex
- .long sys_mprotect /* 125 */
- .long sys_sigprocmask
- .long sys_ni_syscall /* old "create_module" */
- .long sys_init_module
- .long sys_delete_module
- .long sys_ni_syscall /* 130: old "get_kernel_syms" */
- .long sys_quotactl
- .long sys_getpgid
- .long sys_fchdir
- .long sys_bdflush
- .long sys_sysfs /* 135 */
- .long sys_personality
- .long sys_ni_syscall /* reserved for afs_syscall */
- .long sys_setfsuid16
- .long sys_setfsgid16
- .long sys_llseek /* 140 */
- .long sys_getdents
- .long sys_select
- .long sys_flock
- .long sys_msync
- .long sys_readv /* 145 */
- .long sys_writev
- .long sys_getsid
- .long sys_fdatasync
- .long sys_sysctl
- .long sys_mlock /* 150 */
- .long sys_munlock
- .long sys_mlockall
- .long sys_munlockall
- .long sys_sched_setparam
- .long sys_sched_getparam /* 155 */
- .long sys_sched_setscheduler
- .long sys_sched_getscheduler
- .long sys_sched_yield
- .long sys_sched_get_priority_max
- .long sys_sched_get_priority_min /* 160 */
- .long sys_sched_rr_get_interval
- .long sys_nanosleep
- .long sys_mremap
- .long sys_setresuid16
- .long sys_getresuid16 /* 165 */
- .long sys_ni_syscall /* vm86 */
- .long sys_ni_syscall /* Old sys_query_module */
- .long sys_poll
- .long sys_ni_syscall /* was nfsservctl */
- .long sys_setresgid16 /* 170 */
- .long sys_getresgid16
- .long sys_prctl
- .long sys_rt_sigreturn
- .long sys_rt_sigaction
- .long sys_rt_sigprocmask /* 175 */
- .long sys_rt_sigpending
- .long sys_rt_sigtimedwait
- .long sys_rt_sigqueueinfo
- .long sys_rt_sigsuspend
- .long sys_pread64 /* 180 */
- .long sys_pwrite64
- .long sys_chown16
- .long sys_getcwd
- .long sys_capget
- .long sys_capset /* 185 */
- .long sys_sigaltstack
- .long sys_sendfile
- .long sys_ni_syscall /* reserved for streams1 */
- .long sys_ni_syscall /* reserved for streams2 */
- .long sys_vfork /* 190 */
- .long sys_getrlimit
- .long sys_mmap_pgoff
- .long sys_truncate64
- .long sys_ftruncate64
- .long sys_stat64 /* 195 */
- .long sys_lstat64
- .long sys_fstat64
- .long sys_lchown
- .long sys_getuid
- .long sys_getgid /* 200 */
- .long sys_geteuid
- .long sys_getegid
- .long sys_setreuid
- .long sys_setregid
- .long sys_getgroups /* 205 */
- .long sys_setgroups
- .long sys_fchown
- .long sys_setresuid
- .long sys_getresuid
- .long sys_setresgid /* 210 */
- .long sys_getresgid
- .long sys_chown
- .long sys_setuid
- .long sys_setgid
- .long sys_setfsuid /* 215 */
- .long sys_setfsgid
- .long sys_pivot_root
- .long sys_mincore
- .long sys_madvise
- .long sys_getdents64 /* 220 */
- .long sys_fcntl64
- .long sys_ni_syscall /* reserved for TUX */
- .long sys_ni_syscall
- .long sys_gettid
- .long sys_readahead /* 225 */
- .long sys_setxattr
- .long sys_lsetxattr
- .long sys_fsetxattr
- .long sys_getxattr
- .long sys_lgetxattr /* 230 */
- .long sys_fgetxattr
- .long sys_listxattr
- .long sys_llistxattr
- .long sys_flistxattr
- .long sys_removexattr /* 235 */
- .long sys_lremovexattr
- .long sys_fremovexattr
- .long sys_tkill
- .long sys_sendfile64
- .long sys_futex /* 240 */
- .long sys_sched_setaffinity
- .long sys_sched_getaffinity
- .long sys_ni_syscall /* sys_set_thread_area */
- .long sys_ni_syscall /* sys_get_thread_area */
- .long sys_io_setup /* 245 */
- .long sys_io_destroy
- .long sys_io_getevents
- .long sys_io_submit
- .long sys_io_cancel
- .long sys_fadvise64 /* 250 */
- .long sys_ni_syscall
- .long sys_exit_group
- .long sys_lookup_dcookie
- .long sys_epoll_create
- .long sys_epoll_ctl /* 255 */
- .long sys_epoll_wait
- .long sys_remap_file_pages
- .long sys_set_tid_address
- .long sys_timer_create
- .long sys_timer_settime /* 260 */
- .long sys_timer_gettime
- .long sys_timer_getoverrun
- .long sys_timer_delete
- .long sys_clock_settime
- .long sys_clock_gettime /* 265 */
- .long sys_clock_getres
- .long sys_clock_nanosleep
- .long sys_statfs64
- .long sys_fstatfs64
- .long sys_tgkill /* 270 */
- .long sys_utimes
- .long sys_fadvise64_64
- .long sys_ni_syscall /* sys_vserver */
- .long sys_mbind
- .long sys_get_mempolicy /* 275 */
- .long sys_set_mempolicy
- .long sys_mq_open
- .long sys_mq_unlink
- .long sys_mq_timedsend
- .long sys_mq_timedreceive /* 280 */
- .long sys_mq_notify
- .long sys_mq_getsetattr
- .long sys_kexec_load
- .long sys_waitid
- .long sys_ni_syscall /* 285 */ /* available */
- .long sys_add_key
- .long sys_request_key
- .long sys_keyctl
- .long sys_cacheflush
- .long sys_ioprio_set /* 290 */
- .long sys_ioprio_get
- .long sys_inotify_init
- .long sys_inotify_add_watch
- .long sys_inotify_rm_watch
- .long sys_migrate_pages /* 295 */
- .long sys_openat
- .long sys_mkdirat
- .long sys_mknodat
- .long sys_fchownat
- .long sys_futimesat /* 300 */
- .long sys_fstatat64
- .long sys_unlinkat
- .long sys_renameat
- .long sys_linkat
- .long sys_symlinkat /* 305 */
- .long sys_readlinkat
- .long sys_fchmodat
- .long sys_faccessat
- .long sys_pselect6
- .long sys_ppoll /* 310 */
- .long sys_unshare
- .long sys_set_robust_list
- .long sys_get_robust_list
- .long sys_splice
- .long sys_sync_file_range /* 315 */
- .long sys_tee
- .long sys_vmsplice
- .long sys_move_pages
- .long sys_getcpu
- .long sys_epoll_pwait /* 320 */
- .long sys_utimensat
- .long sys_signalfd
- .long sys_timerfd_create
- .long sys_eventfd
- .long sys_fallocate /* 325 */
- .long sys_timerfd_settime
- .long sys_timerfd_gettime
- .long sys_signalfd4
- .long sys_eventfd2
- .long sys_epoll_create1 /* 330 */
- .long sys_dup3
- .long sys_pipe2
- .long sys_inotify_init1
- .long sys_preadv
- .long sys_pwritev /* 335 */
- .long sys_rt_tgsigqueueinfo
- .long sys_perf_event_open
- .long sys_recvmmsg
- .long sys_setns
-
-
-nr_syscalls=(.-sys_call_table)/4
diff --git a/arch/mn10300/kernel/fpu-low.S b/arch/mn10300/kernel/fpu-low.S
deleted file mode 100644
index 78df25cfae29..000000000000
--- a/arch/mn10300/kernel/fpu-low.S
+++ /dev/null
@@ -1,258 +0,0 @@
-/* MN10300 Low level FPU management operations
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/linkage.h>
-#include <asm/cpu-regs.h>
-#include <asm/smp.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-#include <asm/frame.inc>
-
-.macro FPU_INIT_STATE_ALL
- fmov 0,fs0
- fmov fs0,fs1
- fmov fs0,fs2
- fmov fs0,fs3
- fmov fs0,fs4
- fmov fs0,fs5
- fmov fs0,fs6
- fmov fs0,fs7
- fmov fs0,fs8
- fmov fs0,fs9
- fmov fs0,fs10
- fmov fs0,fs11
- fmov fs0,fs12
- fmov fs0,fs13
- fmov fs0,fs14
- fmov fs0,fs15
- fmov fs0,fs16
- fmov fs0,fs17
- fmov fs0,fs18
- fmov fs0,fs19
- fmov fs0,fs20
- fmov fs0,fs21
- fmov fs0,fs22
- fmov fs0,fs23
- fmov fs0,fs24
- fmov fs0,fs25
- fmov fs0,fs26
- fmov fs0,fs27
- fmov fs0,fs28
- fmov fs0,fs29
- fmov fs0,fs30
- fmov fs0,fs31
- fmov FPCR_INIT,fpcr
-.endm
-
-.macro FPU_SAVE_ALL areg,dreg
- fmov fs0,(\areg+)
- fmov fs1,(\areg+)
- fmov fs2,(\areg+)
- fmov fs3,(\areg+)
- fmov fs4,(\areg+)
- fmov fs5,(\areg+)
- fmov fs6,(\areg+)
- fmov fs7,(\areg+)
- fmov fs8,(\areg+)
- fmov fs9,(\areg+)
- fmov fs10,(\areg+)
- fmov fs11,(\areg+)
- fmov fs12,(\areg+)
- fmov fs13,(\areg+)
- fmov fs14,(\areg+)
- fmov fs15,(\areg+)
- fmov fs16,(\areg+)
- fmov fs17,(\areg+)
- fmov fs18,(\areg+)
- fmov fs19,(\areg+)
- fmov fs20,(\areg+)
- fmov fs21,(\areg+)
- fmov fs22,(\areg+)
- fmov fs23,(\areg+)
- fmov fs24,(\areg+)
- fmov fs25,(\areg+)
- fmov fs26,(\areg+)
- fmov fs27,(\areg+)
- fmov fs28,(\areg+)
- fmov fs29,(\areg+)
- fmov fs30,(\areg+)
- fmov fs31,(\areg+)
- fmov fpcr,\dreg
- mov \dreg,(\areg)
-.endm
-
-.macro FPU_RESTORE_ALL areg,dreg
- fmov (\areg+),fs0
- fmov (\areg+),fs1
- fmov (\areg+),fs2
- fmov (\areg+),fs3
- fmov (\areg+),fs4
- fmov (\areg+),fs5
- fmov (\areg+),fs6
- fmov (\areg+),fs7
- fmov (\areg+),fs8
- fmov (\areg+),fs9
- fmov (\areg+),fs10
- fmov (\areg+),fs11
- fmov (\areg+),fs12
- fmov (\areg+),fs13
- fmov (\areg+),fs14
- fmov (\areg+),fs15
- fmov (\areg+),fs16
- fmov (\areg+),fs17
- fmov (\areg+),fs18
- fmov (\areg+),fs19
- fmov (\areg+),fs20
- fmov (\areg+),fs21
- fmov (\areg+),fs22
- fmov (\areg+),fs23
- fmov (\areg+),fs24
- fmov (\areg+),fs25
- fmov (\areg+),fs26
- fmov (\areg+),fs27
- fmov (\areg+),fs28
- fmov (\areg+),fs29
- fmov (\areg+),fs30
- fmov (\areg+),fs31
- mov (\areg),\dreg
- fmov \dreg,fpcr
-.endm
-
-###############################################################################
-#
-# void fpu_init_state(void)
-# - initialise the FPU
-#
-###############################################################################
- .globl fpu_init_state
- .type fpu_init_state,@function
-fpu_init_state:
- mov epsw,d0
- or EPSW_FE,epsw
-
-#ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- nop
-#endif
- FPU_INIT_STATE_ALL
-#ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
- nop
-#endif
- mov d0,epsw
- ret [],0
-
- .size fpu_init_state,.-fpu_init_state
-
-###############################################################################
-#
-# void fpu_save(struct fpu_state_struct *)
-# - save the fpu state
-# - note that an FPU Operational exception might occur during this process
-#
-###############################################################################
- .globl fpu_save
- .type fpu_save,@function
-fpu_save:
- mov epsw,d1
- or EPSW_FE,epsw /* enable the FPU so we can access it */
-
-#ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
-#endif
- mov d0,a0
- FPU_SAVE_ALL a0,d0
-#ifdef CONFIG_MN10300_PROC_MN103E010
- nop
- nop
-#endif
-
- mov d1,epsw
- ret [],0
-
- .size fpu_save,.-fpu_save
-
-###############################################################################
-#
-# void fpu_disabled(void)
-# - handle an exception due to the FPU being disabled
-# when CONFIG_FPU is enabled
-#
-###############################################################################
- .type fpu_disabled,@function
- .globl fpu_disabled
-fpu_disabled:
- or EPSW_nAR|EPSW_FE,epsw
- nop
- nop
- nop
-
- mov sp,a1
- mov (a1),d1 /* get epsw of user context */
- and ~(THREAD_SIZE-1),a1 /* a1: (thread_info *ti) */
- mov (TI_task,a1),a2 /* a2: (task_struct *tsk) */
- btst EPSW_nSL,d1
- beq fpu_used_in_kernel
-
- or EPSW_FE,d1
- mov d1,(sp)
- mov (TASK_THREAD+THREAD_FPU_FLAGS,a2),d1
-#ifndef CONFIG_LAZY_SAVE_FPU
- or __THREAD_HAS_FPU,d1
- mov d1,(TASK_THREAD+THREAD_FPU_FLAGS,a2)
-#else /* !CONFIG_LAZY_SAVE_FPU */
- mov (fpu_state_owner),a0
- cmp 0,a0
- beq fpu_regs_save_end
-
- mov (TASK_THREAD+THREAD_UREGS,a0),a1
- add TASK_THREAD+THREAD_FPU_STATE,a0
- FPU_SAVE_ALL a0,d0
-
- mov (REG_EPSW,a1),d0
- and ~EPSW_FE,d0
- mov d0,(REG_EPSW,a1)
-
-fpu_regs_save_end:
- mov a2,(fpu_state_owner)
-#endif /* !CONFIG_LAZY_SAVE_FPU */
-
- btst __THREAD_USING_FPU,d1
- beq fpu_regs_init
- add TASK_THREAD+THREAD_FPU_STATE,a2
- FPU_RESTORE_ALL a2,d0
- rti
-
-fpu_regs_init:
- FPU_INIT_STATE_ALL
- add TASK_THREAD+THREAD_FPU_FLAGS,a2
- bset __THREAD_USING_FPU,(0,a2)
- rti
-
-fpu_used_in_kernel:
- and ~(EPSW_nAR|EPSW_FE),epsw
- nop
- nop
-
- add -4,sp
- SAVE_ALL
- mov -1,d0
- mov d0,(REG_ORIG_D0,fp)
-
- and ~EPSW_NMID,epsw
-
- mov fp,d0
- call fpu_disabled_in_kernel[],0
- jmp ret_from_exception
-
- .size fpu_disabled,.-fpu_disabled
diff --git a/arch/mn10300/kernel/fpu-nofpu-low.S b/arch/mn10300/kernel/fpu-nofpu-low.S
deleted file mode 100644
index 7ea087a549f4..000000000000
--- a/arch/mn10300/kernel/fpu-nofpu-low.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/* MN10300 Low level FPU management operations
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/linkage.h>
-#include <asm/cpu-regs.h>
-#include <asm/smp.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-#include <asm/frame.inc>
-
-###############################################################################
-#
-# void fpu_disabled(void)
-# - handle an exception due to the FPU being disabled
-# when CONFIG_FPU is disabled
-#
-###############################################################################
- .type fpu_disabled,@function
- .globl fpu_disabled
-fpu_disabled:
- add -4,sp
- SAVE_ALL
- mov -1,d0
- mov d0,(REG_ORIG_D0,fp)
-
- and ~EPSW_NMID,epsw
-
- mov fp,d0
- call unexpected_fpu_exception[],0
- jmp ret_from_exception
-
- .size fpu_disabled,.-fpu_disabled
diff --git a/arch/mn10300/kernel/fpu-nofpu.c b/arch/mn10300/kernel/fpu-nofpu.c
deleted file mode 100644
index 8d0e041aa798..000000000000
--- a/arch/mn10300/kernel/fpu-nofpu.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* MN10300 FPU management
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <asm/fpu.h>
-#include <asm/elf.h>
-
-/*
- * handle an FPU operational exception
- * - there's a possibility that if the FPU is asynchronous, the signal might
- * be meant for a process other than the current one
- */
-asmlinkage
-void unexpected_fpu_exception(struct pt_regs *regs, enum exception_code code)
-{
- panic("An FPU exception was received, but there's no FPU enabled.");
-}
-
-/*
- * fill in the FPU structure for a core dump
- */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpreg)
-{
- return 0; /* not valid */
-}
diff --git a/arch/mn10300/kernel/fpu.c b/arch/mn10300/kernel/fpu.c
deleted file mode 100644
index 50ce7b447fed..000000000000
--- a/arch/mn10300/kernel/fpu.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* MN10300 FPU management
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/uaccess.h>
-#include <linux/sched/signal.h>
-
-#include <asm/fpu.h>
-#include <asm/elf.h>
-#include <asm/exceptions.h>
-
-#ifdef CONFIG_LAZY_SAVE_FPU
-struct task_struct *fpu_state_owner;
-#endif
-
-/*
- * error functions in FPU disabled exception
- */
-asmlinkage void fpu_disabled_in_kernel(struct pt_regs *regs)
-{
- die_if_no_fixup("An FPU Disabled exception happened in kernel space\n",
- regs, EXCEP_FPU_DISABLED);
-}
-
-/*
- * handle an FPU operational exception
- * - there's a possibility that if the FPU is asynchronous, the signal might
- * be meant for a process other than the current one
- */
-asmlinkage void fpu_exception(struct pt_regs *regs, enum exception_code code)
-{
- struct task_struct *tsk = current;
- siginfo_t info;
- u32 fpcr;
-
- if (!user_mode(regs))
- die_if_no_fixup("An FPU Operation exception happened in"
- " kernel space\n",
- regs, code);
-
- if (!is_using_fpu(tsk))
- die_if_no_fixup("An FPU Operation exception happened,"
- " but the FPU is not in use",
- regs, code);
-
- info.si_signo = SIGFPE;
- info.si_errno = 0;
- info.si_addr = (void *) tsk->thread.uregs->pc;
- info.si_code = FPE_FLTINV;
-
- unlazy_fpu(tsk);
-
- fpcr = tsk->thread.fpu_state.fpcr;
-
- if (fpcr & FPCR_EC_Z)
- info.si_code = FPE_FLTDIV;
- else if (fpcr & FPCR_EC_O)
- info.si_code = FPE_FLTOVF;
- else if (fpcr & FPCR_EC_U)
- info.si_code = FPE_FLTUND;
- else if (fpcr & FPCR_EC_I)
- info.si_code = FPE_FLTRES;
-
- force_sig_info(SIGFPE, &info, tsk);
-}
-
-/*
- * save the FPU state to a signal context
- */
-int fpu_setup_sigcontext(struct fpucontext *fpucontext)
-{
- struct task_struct *tsk = current;
-
- if (!is_using_fpu(tsk))
- return 0;
-
- /* transfer the current FPU state to memory and cause fpu_init() to be
- * triggered by the next attempted FPU operation by the current
- * process.
- */
- preempt_disable();
-
-#ifndef CONFIG_LAZY_SAVE_FPU
- if (tsk->thread.fpu_flags & THREAD_HAS_FPU) {
- fpu_save(&tsk->thread.fpu_state);
- tsk->thread.uregs->epsw &= ~EPSW_FE;
- tsk->thread.fpu_flags &= ~THREAD_HAS_FPU;
- }
-#else /* !CONFIG_LAZY_SAVE_FPU */
- if (fpu_state_owner == tsk) {
- fpu_save(&tsk->thread.fpu_state);
- fpu_state_owner->thread.uregs->epsw &= ~EPSW_FE;
- fpu_state_owner = NULL;
- }
-#endif /* !CONFIG_LAZY_SAVE_FPU */
-
- preempt_enable();
-
- /* we no longer have a valid current FPU state */
- clear_using_fpu(tsk);
-
- /* transfer the saved FPU state onto the userspace stack */
- if (copy_to_user(fpucontext,
- &tsk->thread.fpu_state,
- min(sizeof(struct fpu_state_struct),
- sizeof(struct fpucontext))))
- return -1;
-
- return 1;
-}
-
-/*
- * kill a process's FPU state during restoration after signal handling
- */
-void fpu_kill_state(struct task_struct *tsk)
-{
- /* disown anything left in the FPU */
- preempt_disable();
-
-#ifndef CONFIG_LAZY_SAVE_FPU
- if (tsk->thread.fpu_flags & THREAD_HAS_FPU) {
- tsk->thread.uregs->epsw &= ~EPSW_FE;
- tsk->thread.fpu_flags &= ~THREAD_HAS_FPU;
- }
-#else /* !CONFIG_LAZY_SAVE_FPU */
- if (fpu_state_owner == tsk) {
- fpu_state_owner->thread.uregs->epsw &= ~EPSW_FE;
- fpu_state_owner = NULL;
- }
-#endif /* !CONFIG_LAZY_SAVE_FPU */
-
- preempt_enable();
-
- /* we no longer have a valid current FPU state */
- clear_using_fpu(tsk);
-}
-
-/*
- * restore the FPU state from a signal context
- */
-int fpu_restore_sigcontext(struct fpucontext *fpucontext)
-{
- struct task_struct *tsk = current;
- int ret;
-
- /* load up the old FPU state */
- ret = copy_from_user(&tsk->thread.fpu_state, fpucontext,
- min(sizeof(struct fpu_state_struct),
- sizeof(struct fpucontext)));
- if (!ret)
- set_using_fpu(tsk);
-
- return ret;
-}
-
-/*
- * fill in the FPU structure for a core dump
- */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpreg)
-{
- struct task_struct *tsk = current;
- int fpvalid;
-
- fpvalid = is_using_fpu(tsk);
- if (fpvalid) {
- unlazy_fpu(tsk);
- memcpy(fpreg, &tsk->thread.fpu_state, sizeof(*fpreg));
- }
-
- return fpvalid;
-}
diff --git a/arch/mn10300/kernel/gdb-io-serial-low.S b/arch/mn10300/kernel/gdb-io-serial-low.S
deleted file mode 100644
index b1d0152e96cb..000000000000
--- a/arch/mn10300/kernel/gdb-io-serial-low.S
+++ /dev/null
@@ -1,91 +0,0 @@
-###############################################################################
-#
-# 16550 serial Rx interrupt handler for gdbstub I/O
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/cpu-regs.h>
-#include <asm/thread_info.h>
-#include <asm/frame.inc>
-#include <asm/intctl-regs.h>
-#include <asm/irqflags.h>
-#include <unit/serial.h>
-
- .text
-
-###############################################################################
-#
-# GDB stub serial receive interrupt entry point
-# - intended to run at interrupt priority 0
-#
-###############################################################################
- .globl gdbstub_io_rx_handler
- .type gdbstub_io_rx_handler,@function
-gdbstub_io_rx_handler:
- movm [d2,d3,a2,a3],(sp)
-
-#if 1
- movbu (GDBPORT_SERIAL_IIR),d2
-#endif
-
- mov (gdbstub_rx_inp),a3
-gdbstub_io_rx_more:
- mov a3,a2
- add 2,a3
- and 0x00000fff,a3
- mov (gdbstub_rx_outp),d3
- cmp a3,d3
- beq gdbstub_io_rx_overflow
-
- movbu (GDBPORT_SERIAL_LSR),d3
- btst UART_LSR_DR,d3
- beq gdbstub_io_rx_done
- movbu (GDBPORT_SERIAL_RX),d2
- movbu d3,(gdbstub_rx_buffer+1,a2)
- movbu d2,(gdbstub_rx_buffer,a2)
- mov a3,(gdbstub_rx_inp)
- bra gdbstub_io_rx_more
-
-gdbstub_io_rx_done:
- mov GxICR_DETECT,d2
- movbu d2,(XIRQxICR(GDBPORT_SERIAL_IRQ)) # ACK the interrupt
- movhu (XIRQxICR(GDBPORT_SERIAL_IRQ)),d2 # flush
- movm (sp),[d2,d3,a2,a3]
- bset 0x01,(gdbstub_busy)
- beq gdbstub_io_rx_enter
- rti
-
-gdbstub_io_rx_overflow:
- bset 0x01,(gdbstub_rx_overflow)
- bra gdbstub_io_rx_done
-
-gdbstub_io_rx_enter:
- LOCAL_CHANGE_INTR_MASK_LEVEL(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL+1))
- add -4,sp
- SAVE_ALL
-
- mov 0xffffffff,d0
- mov d0,(REG_ORIG_D0,fp)
- mov 0x280,d1
-
- mov fp,d0
- call gdbstub_rx_irq[],0 # gdbstub_rx_irq(regs,excep)
-
- LOCAL_CLI
- bclr 0x01,(gdbstub_busy)
-
- .globl gdbstub_return
-gdbstub_return:
- RESTORE_ALL
-
- .size gdbstub_io_rx_handler,.-gdbstub_io_rx_handler
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c
deleted file mode 100644
index df51242744cc..000000000000
--- a/arch/mn10300/kernel/gdb-io-serial.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* 16550 serial driver for gdbstub I/O
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/nmi.h>
-
-#include <asm/pgtable.h>
-#include <asm/gdb-stub.h>
-#include <asm/exceptions.h>
-#include <asm/serial-regs.h>
-#include <unit/serial.h>
-#include <asm/smp.h>
-
-/*
- * initialise the GDB stub
- */
-void gdbstub_io_init(void)
-{
- u16 tmp;
-
- /* set up the serial port */
- GDBPORT_SERIAL_LCR = UART_LCR_WLEN8; /* 1N8 */
- GDBPORT_SERIAL_FCR = (UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
- UART_FCR_CLEAR_XMIT);
-
- FLOWCTL_CLEAR(DTR);
- FLOWCTL_SET(RTS);
-
- gdbstub_io_set_baud(115200);
-
- /* we want to get serial receive interrupts */
- XIRQxICR(GDBPORT_SERIAL_IRQ) = 0;
- tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
-
-#if CONFIG_GDBSTUB_IRQ_LEVEL == 0
- IVAR0 = EXCEP_IRQ_LEVEL0;
-#elif CONFIG_GDBSTUB_IRQ_LEVEL == 1
- IVAR1 = EXCEP_IRQ_LEVEL1;
-#elif CONFIG_GDBSTUB_IRQ_LEVEL == 2
- IVAR2 = EXCEP_IRQ_LEVEL2;
-#elif CONFIG_GDBSTUB_IRQ_LEVEL == 3
- IVAR3 = EXCEP_IRQ_LEVEL3;
-#elif CONFIG_GDBSTUB_IRQ_LEVEL == 4
- IVAR4 = EXCEP_IRQ_LEVEL4;
-#elif CONFIG_GDBSTUB_IRQ_LEVEL == 5
- IVAR5 = EXCEP_IRQ_LEVEL5;
-#else
-#error "Unknown irq level for gdbstub."
-#endif
-
- set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL),
- gdbstub_io_rx_handler);
-
- XIRQxICR(GDBPORT_SERIAL_IRQ) &= ~GxICR_REQUEST;
- XIRQxICR(GDBPORT_SERIAL_IRQ) =
- GxICR_ENABLE | NUM2GxICR_LEVEL(CONFIG_GDBSTUB_IRQ_LEVEL);
- tmp = XIRQxICR(GDBPORT_SERIAL_IRQ);
-
- GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI;
-
- /* permit level 0 IRQs to take place */
- arch_local_change_intr_mask_level(
- NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1));
-}
-
-/*
- * set up the GDB stub serial port baud rate timers
- */
-void gdbstub_io_set_baud(unsigned baud)
-{
- unsigned value;
- u8 lcr;
-
- value = 18432000 / 16 / baud;
-
- lcr = GDBPORT_SERIAL_LCR;
- GDBPORT_SERIAL_LCR |= UART_LCR_DLAB;
- GDBPORT_SERIAL_DLL = value & 0xff;
- GDBPORT_SERIAL_DLM = (value >> 8) & 0xff;
- GDBPORT_SERIAL_LCR = lcr;
-}
-
-/*
- * wait for a character to come from the debugger
- */
-int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
-{
- unsigned ix;
- u8 ch, st;
-#if defined(CONFIG_MN10300_WD_TIMER)
- int cpu;
-#endif
-
- *_ch = 0xff;
-
- if (gdbstub_rx_unget) {
- *_ch = gdbstub_rx_unget;
- gdbstub_rx_unget = 0;
- return 0;
- }
-
- try_again:
- /* pull chars out of the buffer */
- ix = gdbstub_rx_outp;
- barrier();
- if (ix == gdbstub_rx_inp) {
- if (nonblock)
- return -EAGAIN;
-#ifdef CONFIG_MN10300_WD_TIMER
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- watchdog_alert_counter[cpu] = 0;
-#endif
- goto try_again;
- }
-
- ch = gdbstub_rx_buffer[ix++];
- st = gdbstub_rx_buffer[ix++];
- barrier();
- gdbstub_rx_outp = ix & 0x00000fff;
-
- if (st & UART_LSR_BI) {
- gdbstub_proto("### GDB Rx Break Detected ###\n");
- return -EINTR;
- } else if (st & (UART_LSR_FE | UART_LSR_OE | UART_LSR_PE)) {
- gdbstub_proto("### GDB Rx Error (st=%02x) ###\n", st);
- return -EIO;
- } else {
- gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n", ch, st);
- *_ch = ch & 0x7f;
- return 0;
- }
-}
-
-/*
- * send a character to the debugger
- */
-void gdbstub_io_tx_char(unsigned char ch)
-{
- FLOWCTL_SET(DTR);
- LSR_WAIT_FOR(THRE);
- /* FLOWCTL_WAIT_FOR(CTS); */
-
- if (ch == 0x0a) {
- GDBPORT_SERIAL_TX = 0x0d;
- LSR_WAIT_FOR(THRE);
- /* FLOWCTL_WAIT_FOR(CTS); */
- }
- GDBPORT_SERIAL_TX = ch;
-
- FLOWCTL_CLEAR(DTR);
-}
-
-/*
- * send a character to the debugger
- */
-void gdbstub_io_tx_flush(void)
-{
- LSR_WAIT_FOR(TEMT);
- LSR_WAIT_FOR(THRE);
- FLOWCTL_CLEAR(DTR);
-}
diff --git a/arch/mn10300/kernel/gdb-io-ttysm-low.S b/arch/mn10300/kernel/gdb-io-ttysm-low.S
deleted file mode 100644
index 060b7cca735d..000000000000
--- a/arch/mn10300/kernel/gdb-io-ttysm-low.S
+++ /dev/null
@@ -1,93 +0,0 @@
-###############################################################################
-#
-# MN10300 On-chip serial Rx interrupt handler for GDB stub I/O
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/thread_info.h>
-#include <asm/cpu-regs.h>
-#include <asm/frame.inc>
-#include <asm/intctl-regs.h>
-#include <unit/serial.h>
-#include "mn10300-serial.h"
-
- .text
-
-###############################################################################
-#
-# GDB stub serial receive interrupt entry point
-# - intended to run at interrupt priority 0
-#
-###############################################################################
- .globl gdbstub_io_rx_handler
- .type gdbstub_io_rx_handler,@function
-gdbstub_io_rx_handler:
- movm [d2,d3,a2,a3],(sp)
-
- mov (gdbstub_rx_inp),a3
-gdbstub_io_rx_more:
- mov a3,a2
- add 2,a3
- and PAGE_SIZE_asm-1,a3
- mov (gdbstub_rx_outp),d3
- cmp a3,d3
- beq gdbstub_io_rx_overflow
-
- movbu (SCgSTR),d3
- btst SC01STR_RBF,d3
- beq gdbstub_io_rx_done
- movbu (SCgRXB),d2
- movbu d3,(gdbstub_rx_buffer+1,a2)
- movbu d2,(gdbstub_rx_buffer,a2)
- mov a3,(gdbstub_rx_inp)
- bra gdbstub_io_rx_more
-
-gdbstub_io_rx_done:
- mov GxICR_DETECT,d2
- movbu d2,(GxICR(SCgRXIRQ)) # ACK the interrupt
- movhu (GxICR(SCgRXIRQ)),d2 # flush
-
- movm (sp),[d2,d3,a2,a3]
- bset 0x01,(gdbstub_busy)
- beq gdbstub_io_rx_enter
- rti
-
-gdbstub_io_rx_overflow:
- bset 0x01,(gdbstub_rx_overflow)
- bra gdbstub_io_rx_done
-
-###############################################################################
-#
-# debugging interrupt - enter the GDB stub proper
-#
-###############################################################################
-gdbstub_io_rx_enter:
- or EPSW_IE|EPSW_IM_1,epsw
- add -4,sp
- SAVE_ALL
-
- mov 0xffffffff,d0
- mov d0,(REG_ORIG_D0,fp)
- mov 0x280,d1
-
- mov fp,d0
- call gdbstub_rx_irq[],0 # gdbstub_io_rx_irq(regs,excep)
-
- and ~EPSW_IE,epsw
- bclr 0x01,(gdbstub_busy)
-
- .globl gdbstub_return
-gdbstub_return:
- RESTORE_ALL
-
- .size gdbstub_io_rx_handler,.-gdbstub_io_rx_handler
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c
deleted file mode 100644
index caae8cac9db1..000000000000
--- a/arch/mn10300/kernel/gdb-io-ttysm.c
+++ /dev/null
@@ -1,303 +0,0 @@
-/* MN10300 On-chip serial driver for gdbstub I/O
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/tty.h>
-#include <asm/pgtable.h>
-#include <asm/gdb-stub.h>
-#include <asm/exceptions.h>
-#include <unit/clock.h>
-#include "mn10300-serial.h"
-
-#if defined(CONFIG_GDBSTUB_ON_TTYSM0)
-struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif0;
-#elif defined(CONFIG_GDBSTUB_ON_TTYSM1)
-struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif1;
-#else
-struct mn10300_serial_port *const gdbstub_port = &mn10300_serial_port_sif2;
-#endif
-
-
-/*
- * initialise the GDB stub I/O routines
- */
-void __init gdbstub_io_init(void)
-{
- uint16_t scxctr;
- int tmp;
-
- switch (gdbstub_port->clock_src) {
- case MNSCx_CLOCK_SRC_IOCLK:
- gdbstub_port->ioclk = MN10300_IOCLK;
- break;
-
-#ifdef MN10300_IOBCLK
- case MNSCx_CLOCK_SRC_IOBCLK:
- gdbstub_port->ioclk = MN10300_IOBCLK;
- break;
-#endif
- default:
- BUG();
- }
-
- /* set up the serial port */
- gdbstub_io_set_baud(115200);
-
- /* we want to get serial receive interrupts */
- set_intr_level(gdbstub_port->rx_irq,
- NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
- set_intr_level(gdbstub_port->tx_irq,
- NUM2GxICR_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL));
- set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_DEBUGGER_IRQ_LEVEL),
- gdbstub_io_rx_handler);
-
- *gdbstub_port->rx_icr |= GxICR_ENABLE;
- tmp = *gdbstub_port->rx_icr;
-
- /* enable the device */
- scxctr = SC01CTR_CLN_8BIT; /* 1N8 */
- switch (gdbstub_port->div_timer) {
- case MNSCx_DIV_TIMER_16BIT:
- scxctr |= SC0CTR_CK_TM8UFLOW_8; /* == SC1CTR_CK_TM9UFLOW_8
- == SC2CTR_CK_TM10UFLOW_8 */
- break;
-
- case MNSCx_DIV_TIMER_8BIT:
- scxctr |= SC0CTR_CK_TM2UFLOW_8;
- break;
- }
-
- scxctr |= SC01CTR_TXE | SC01CTR_RXE;
-
- *gdbstub_port->_control = scxctr;
- tmp = *gdbstub_port->_control;
-
- /* permit level 0 IRQs only */
- arch_local_change_intr_mask_level(
- NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
-}
-
-/*
- * set up the GDB stub serial port baud rate timers
- */
-void gdbstub_io_set_baud(unsigned baud)
-{
- const unsigned bits = 10; /* 1 [start] + 8 [data] + 0 [parity] +
- * 1 [stop] */
- unsigned long ioclk = gdbstub_port->ioclk;
- unsigned xdiv, tmp;
- uint16_t tmxbr;
- uint8_t tmxmd;
-
- if (!baud) {
- baud = 9600;
- } else if (baud == 134) {
- baud = 269; /* 134 is really 134.5 */
- xdiv = 2;
- }
-
-try_alternative:
- xdiv = 1;
-
- switch (gdbstub_port->div_timer) {
- case MNSCx_DIV_TIMER_16BIT:
- tmxmd = TM8MD_SRC_IOCLK;
- tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 65535)
- goto timer_okay;
-
- tmxmd = TM8MD_SRC_IOCLK_8;
- tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 65535)
- goto timer_okay;
-
- tmxmd = TM8MD_SRC_IOCLK_32;
- tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 65535)
- goto timer_okay;
-
- break;
-
- case MNSCx_DIV_TIMER_8BIT:
- tmxmd = TM2MD_SRC_IOCLK;
- tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 255)
- goto timer_okay;
-
- tmxmd = TM2MD_SRC_IOCLK_8;
- tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 255)
- goto timer_okay;
-
- tmxmd = TM2MD_SRC_IOCLK_32;
- tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 255)
- goto timer_okay;
- break;
- }
-
- /* as a last resort, if the quotient is zero, default to 9600 bps */
- baud = 9600;
- goto try_alternative;
-
-timer_okay:
- gdbstub_port->uart.timeout = (2 * bits * HZ) / baud;
- gdbstub_port->uart.timeout += HZ / 50;
-
- /* set the timer to produce the required baud rate */
- switch (gdbstub_port->div_timer) {
- case MNSCx_DIV_TIMER_16BIT:
- *gdbstub_port->_tmxmd = 0;
- *gdbstub_port->_tmxbr = tmxbr;
- *gdbstub_port->_tmxmd = TM8MD_INIT_COUNTER;
- *gdbstub_port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;
- break;
-
- case MNSCx_DIV_TIMER_8BIT:
- *gdbstub_port->_tmxmd = 0;
- *(volatile u8 *) gdbstub_port->_tmxbr = (u8)tmxbr;
- *gdbstub_port->_tmxmd = TM2MD_INIT_COUNTER;
- *gdbstub_port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;
- break;
- }
-}
-
-/*
- * wait for a character to come from the debugger
- */
-int gdbstub_io_rx_char(unsigned char *_ch, int nonblock)
-{
- unsigned ix;
- u8 ch, st;
-#if defined(CONFIG_MN10300_WD_TIMER)
- int cpu;
-#endif
-
- *_ch = 0xff;
-
- if (gdbstub_rx_unget) {
- *_ch = gdbstub_rx_unget;
- gdbstub_rx_unget = 0;
- return 0;
- }
-
-try_again:
- /* pull chars out of the buffer */
- ix = gdbstub_rx_outp;
- barrier();
- if (ix == gdbstub_rx_inp) {
- if (nonblock)
- return -EAGAIN;
-#ifdef CONFIG_MN10300_WD_TIMER
- for (cpu = 0; cpu < NR_CPUS; cpu++)
- watchdog_alert_counter[cpu] = 0;
-#endif
- goto try_again;
- }
-
- ch = gdbstub_rx_buffer[ix++];
- st = gdbstub_rx_buffer[ix++];
- barrier();
- gdbstub_rx_outp = ix & (PAGE_SIZE - 1);
-
- st &= SC01STR_RXF | SC01STR_RBF | SC01STR_FEF | SC01STR_PEF |
- SC01STR_OEF;
-
- /* deal with what we've got
- * - note that the UART doesn't do BREAK-detection for us
- */
- if (st & SC01STR_FEF && ch == 0) {
- switch (gdbstub_port->rx_brk) {
- case 0: gdbstub_port->rx_brk = 1; goto try_again;
- case 1: gdbstub_port->rx_brk = 2; goto try_again;
- case 2:
- gdbstub_port->rx_brk = 3;
- gdbstub_proto("### GDB MNSERIAL Rx Break Detected"
- " ###\n");
- return -EINTR;
- default:
- goto try_again;
- }
- } else if (st & SC01STR_FEF) {
- if (gdbstub_port->rx_brk)
- goto try_again;
-
- gdbstub_proto("### GDB MNSERIAL Framing Error ###\n");
- return -EIO;
- } else if (st & SC01STR_OEF) {
- if (gdbstub_port->rx_brk)
- goto try_again;
-
- gdbstub_proto("### GDB MNSERIAL Overrun Error ###\n");
- return -EIO;
- } else if (st & SC01STR_PEF) {
- if (gdbstub_port->rx_brk)
- goto try_again;
-
- gdbstub_proto("### GDB MNSERIAL Parity Error ###\n");
- return -EIO;
- } else {
- /* look for the tail-end char on a break run */
- if (gdbstub_port->rx_brk == 3) {
- switch (ch) {
- case 0xFF:
- case 0xFE:
- case 0xFC:
- case 0xF8:
- case 0xF0:
- case 0xE0:
- case 0xC0:
- case 0x80:
- case 0x00:
- gdbstub_port->rx_brk = 0;
- goto try_again;
- default:
- break;
- }
- }
-
- gdbstub_port->rx_brk = 0;
- gdbstub_io("### GDB Rx %02x (st=%02x) ###\n", ch, st);
- *_ch = ch & 0x7f;
- return 0;
- }
-}
-
-/*
- * send a character to the debugger
- */
-void gdbstub_io_tx_char(unsigned char ch)
-{
- while (*gdbstub_port->_status & SC01STR_TBF)
- continue;
-
- if (ch == 0x0a) {
- *(u8 *) gdbstub_port->_txb = 0x0d;
- while (*gdbstub_port->_status & SC01STR_TBF)
- continue;
- }
-
- *(u8 *) gdbstub_port->_txb = ch;
-}
-
-/*
- * flush the transmission buffers
- */
-void gdbstub_io_tx_flush(void)
-{
- while (*gdbstub_port->_status & (SC01STR_TBF | SC01STR_TXF))
- continue;
-}
diff --git a/arch/mn10300/kernel/gdb-low.S b/arch/mn10300/kernel/gdb-low.S
deleted file mode 100644
index e2725552cd82..000000000000
--- a/arch/mn10300/kernel/gdb-low.S
+++ /dev/null
@@ -1,115 +0,0 @@
-###############################################################################
-#
-# MN10300 Low-level gdbstub routines
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/cache.h>
-#include <asm/cpu-regs.h>
-#include <asm/exceptions.h>
-#include <asm/frame.inc>
-#include <asm/serial-regs.h>
-
- .text
-
-###############################################################################
-#
-# GDB stub read memory with guard
-# - D0 holds the memory address to read
-# - D1 holds the address to store the byte into
-#
-###############################################################################
- .globl gdbstub_read_byte_guard
- .globl gdbstub_read_byte_cont
-ENTRY(gdbstub_read_byte)
- mov d0,a0
- mov d1,a1
- clr d0
-gdbstub_read_byte_guard:
- movbu (a0),d1
-gdbstub_read_byte_cont:
- movbu d1,(a1)
- ret [],0
-
- .globl gdbstub_read_word_guard
- .globl gdbstub_read_word_cont
-ENTRY(gdbstub_read_word)
- mov d0,a0
- mov d1,a1
- clr d0
-gdbstub_read_word_guard:
- movhu (a0),d1
-gdbstub_read_word_cont:
- movhu d1,(a1)
- ret [],0
-
- .globl gdbstub_read_dword_guard
- .globl gdbstub_read_dword_cont
-ENTRY(gdbstub_read_dword)
- mov d0,a0
- mov d1,a1
- clr d0
-gdbstub_read_dword_guard:
- mov (a0),d1
-gdbstub_read_dword_cont:
- mov d1,(a1)
- ret [],0
-
-###############################################################################
-#
-# GDB stub write memory with guard
-# - D0 holds the byte to store
-# - D1 holds the memory address to write
-#
-###############################################################################
- .globl gdbstub_write_byte_guard
- .globl gdbstub_write_byte_cont
-ENTRY(gdbstub_write_byte)
- mov d0,a0
- mov d1,a1
- clr d0
-gdbstub_write_byte_guard:
- movbu a0,(a1)
-gdbstub_write_byte_cont:
- ret [],0
-
- .globl gdbstub_write_word_guard
- .globl gdbstub_write_word_cont
-ENTRY(gdbstub_write_word)
- mov d0,a0
- mov d1,a1
- clr d0
-gdbstub_write_word_guard:
- movhu a0,(a1)
-gdbstub_write_word_cont:
- ret [],0
-
- .globl gdbstub_write_dword_guard
- .globl gdbstub_write_dword_cont
-ENTRY(gdbstub_write_dword)
- mov d0,a0
- mov d1,a1
- clr d0
-gdbstub_write_dword_guard:
- mov a0,(a1)
-gdbstub_write_dword_cont:
- ret [],0
-
-###############################################################################
-#
-# GDB stub BUG() trap
-#
-###############################################################################
-ENTRY(__gdbstub_bug_trap)
- .byte 0xF7,0xF7 # don't use 0xFF as the JTAG unit preempts that
- ret [],0
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c
deleted file mode 100644
index 3399d5699804..000000000000
--- a/arch/mn10300/kernel/gdb-stub.c
+++ /dev/null
@@ -1,1924 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* MN10300 GDB stub
- *
- * Originally written by Glenn Engel, Lake Stevens Instrument Division
- *
- * Contributed by HP Systems
- *
- * Modified for SPARC by Stu Grossman, Cygnus Support.
- *
- * Modified for Linux/MIPS (and MIPS in general) by Andreas Busse
- * Send complaints, suggestions etc. to <andy@waldorf-gmbh.de>
- *
- * Copyright (C) 1995 Andreas Busse
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Modified for Linux/mn10300 by David Howells <dhowells@redhat.com>
- */
-
-/*
- * To enable debugger support, two things need to happen. One, a
- * call to set_debug_traps() is necessary in order to allow any breakpoints
- * or error conditions to be properly intercepted and reported to gdb.
- * Two, a breakpoint needs to be generated to begin communication. This
- * is most easily accomplished by a call to breakpoint(). Breakpoint()
- * simulates a breakpoint by executing a BREAK instruction.
- *
- *
- * The following gdb commands are supported:
- *
- * command function Return value
- *
- * g return the value of the CPU registers hex data or ENN
- * G set the value of the CPU registers OK or ENN
- *
- * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN
- * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN
- *
- * c Resume at current address SNN ( signal NN)
- * cAA..AA Continue at address AA..AA SNN
- *
- * s Step one instruction SNN
- * sAA..AA Step one instruction from AA..AA SNN
- *
- * k kill
- *
- * ? What was the last sigval ? SNN (signal NN)
- *
- * bBB..BB Set baud rate to BB..BB OK or BNN, then sets
- * baud rate
- *
- * All commands and responses are sent with a packet which includes a
- * checksum. A packet consists of
- *
- * $<packet info>#<checksum>.
- *
- * where
- * <packet info> :: <characters representing the command or response>
- * <checksum> :: < two hex digits computed as modulo 256 sum of <packetinfo>>
- *
- * When a packet is received, it is first acknowledged with either '+' or '-'.
- * '+' indicates a successful transfer. '-' indicates a failed transfer.
- *
- * Example:
- *
- * Host: Reply:
- * $m0,10#2a +$00010203040506070809101112131415#42
- *
- *
- * ==============
- * MORE EXAMPLES:
- * ==============
- *
- * For reference -- the following are the steps that one
- * company took (RidgeRun Inc) to get remote gdb debugging
- * going. In this scenario the host machine was a PC and the
- * target platform was a Galileo EVB64120A MIPS evaluation
- * board.
- *
- * Step 1:
- * First download gdb-5.0.tar.gz from the internet.
- * and then build/install the package.
- *
- * Example:
- * $ tar zxf gdb-5.0.tar.gz
- * $ cd gdb-5.0
- * $ ./configure --target=am33_2.0-linux-gnu
- * $ make
- * $ install
- * am33_2.0-linux-gnu-gdb
- *
- * Step 2:
- * Configure linux for remote debugging and build it.
- *
- * Example:
- * $ cd ~/linux
- * $ make menuconfig <go to "Kernel Hacking" and turn on remote debugging>
- * $ make dep; make vmlinux
- *
- * Step 3:
- * Download the kernel to the remote target and start
- * the kernel running. It will promptly halt and wait
- * for the host gdb session to connect. It does this
- * since the "Kernel Hacking" option has defined
- * CONFIG_REMOTE_DEBUG which in turn enables your calls
- * to:
- * set_debug_traps();
- * breakpoint();
- *
- * Step 4:
- * Start the gdb session on the host.
- *
- * Example:
- * $ am33_2.0-linux-gnu-gdb vmlinux
- * (gdb) set remotebaud 115200
- * (gdb) target remote /dev/ttyS1
- * ...at this point you are connected to
- * the remote target and can use gdb
- * in the normal fasion. Setting
- * breakpoints, single stepping,
- * printing variables, etc.
- *
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/bug.h>
-
-#include <asm/pgtable.h>
-#include <asm/gdb-stub.h>
-#include <asm/exceptions.h>
-#include <asm/debugger.h>
-#include <asm/serial-regs.h>
-#include <asm/busctl-regs.h>
-#include <unit/leds.h>
-#include <unit/serial.h>
-
-/* define to use F7F7 rather than FF which is subverted by JTAG debugger */
-#undef GDBSTUB_USE_F7F7_AS_BREAKPOINT
-
-/*
- * BUFMAX defines the maximum number of characters in inbound/outbound buffers
- * at least NUMREGBYTES*2 are needed for register packets
- */
-#define BUFMAX 2048
-
-static const char gdbstub_banner[] =
- "Linux/MN10300 GDB Stub (c) RedHat 2007\n";
-
-u8 gdbstub_rx_buffer[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE)));
-u32 gdbstub_rx_inp;
-u32 gdbstub_rx_outp;
-u8 gdbstub_busy;
-u8 gdbstub_rx_overflow;
-u8 gdbstub_rx_unget;
-
-static u8 gdbstub_flush_caches;
-static char input_buffer[BUFMAX];
-static char output_buffer[BUFMAX];
-static char trans_buffer[BUFMAX];
-
-struct gdbstub_bkpt {
- u8 *addr; /* address of breakpoint */
- u8 len; /* size of breakpoint */
- u8 origbytes[7]; /* original bytes */
-};
-
-static struct gdbstub_bkpt gdbstub_bkpts[256];
-
-/*
- * local prototypes
- */
-static void getpacket(char *buffer);
-static int putpacket(char *buffer);
-static int computeSignal(enum exception_code excep);
-static int hex(unsigned char ch);
-static int hexToInt(char **ptr, int *intValue);
-static unsigned char *mem2hex(const void *mem, char *buf, int count,
- int may_fault);
-static const char *hex2mem(const char *buf, void *_mem, int count,
- int may_fault);
-
-/*
- * Convert ch from a hex digit to an int
- */
-static int hex(unsigned char ch)
-{
- if (ch >= 'a' && ch <= 'f')
- return ch - 'a' + 10;
- if (ch >= '0' && ch <= '9')
- return ch - '0';
- if (ch >= 'A' && ch <= 'F')
- return ch - 'A' + 10;
- return -1;
-}
-
-#ifdef CONFIG_GDBSTUB_DEBUGGING
-
-void debug_to_serial(const char *p, int n)
-{
- __debug_to_serial(p, n);
- /* gdbstub_console_write(NULL, p, n); */
-}
-
-void gdbstub_printk(const char *fmt, ...)
-{
- va_list args;
- int len;
-
- /* Emit the output into the temporary buffer */
- va_start(args, fmt);
- len = vsnprintf(trans_buffer, sizeof(trans_buffer), fmt, args);
- va_end(args);
- debug_to_serial(trans_buffer, len);
-}
-
-#endif
-
-static inline char *gdbstub_strcpy(char *dst, const char *src)
-{
- int loop = 0;
- while ((dst[loop] = src[loop]))
- loop++;
- return dst;
-}
-
-/*
- * scan for the sequence $<data>#<checksum>
- */
-static void getpacket(char *buffer)
-{
- unsigned char checksum;
- unsigned char xmitcsum;
- unsigned char ch;
- int count, i, ret, error;
-
- for (;;) {
- /*
- * wait around for the start character,
- * ignore all other characters
- */
- do {
- gdbstub_io_rx_char(&ch, 0);
- } while (ch != '$');
-
- checksum = 0;
- xmitcsum = -1;
- count = 0;
- error = 0;
-
- /*
- * now, read until a # or end of buffer is found
- */
- while (count < BUFMAX) {
- ret = gdbstub_io_rx_char(&ch, 0);
- if (ret < 0)
- error = ret;
-
- if (ch == '#')
- break;
- checksum += ch;
- buffer[count] = ch;
- count++;
- }
-
- if (error == -EIO) {
- gdbstub_proto("### GDB Rx Error - Skipping packet"
- " ###\n");
- gdbstub_proto("### GDB Tx NAK\n");
- gdbstub_io_tx_char('-');
- continue;
- }
-
- if (count >= BUFMAX || error)
- continue;
-
- buffer[count] = 0;
-
- /* read the checksum */
- ret = gdbstub_io_rx_char(&ch, 0);
- if (ret < 0)
- error = ret;
- xmitcsum = hex(ch) << 4;
-
- ret = gdbstub_io_rx_char(&ch, 0);
- if (ret < 0)
- error = ret;
- xmitcsum |= hex(ch);
-
- if (error) {
- if (error == -EIO)
- gdbstub_io("### GDB Rx Error -"
- " Skipping packet\n");
- gdbstub_io("### GDB Tx NAK\n");
- gdbstub_io_tx_char('-');
- continue;
- }
-
- /* check the checksum */
- if (checksum != xmitcsum) {
- gdbstub_io("### GDB Tx NAK\n");
- gdbstub_io_tx_char('-'); /* failed checksum */
- continue;
- }
-
- gdbstub_proto("### GDB Rx '$%s#%02x' ###\n", buffer, checksum);
- gdbstub_io("### GDB Tx ACK\n");
- gdbstub_io_tx_char('+'); /* successful transfer */
-
- /*
- * if a sequence char is present,
- * reply the sequence ID
- */
- if (buffer[2] == ':') {
- gdbstub_io_tx_char(buffer[0]);
- gdbstub_io_tx_char(buffer[1]);
-
- /*
- * remove sequence chars from buffer
- */
- count = 0;
- while (buffer[count])
- count++;
- for (i = 3; i <= count; i++)
- buffer[i - 3] = buffer[i];
- }
-
- break;
- }
-}
-
-/*
- * send the packet in buffer.
- * - return 0 if successfully ACK'd
- * - return 1 if abandoned due to new incoming packet
- */
-static int putpacket(char *buffer)
-{
- unsigned char checksum;
- unsigned char ch;
- int count;
-
- /*
- * $<packet info>#<checksum>.
- */
- gdbstub_proto("### GDB Tx $'%s'#?? ###\n", buffer);
-
- do {
- gdbstub_io_tx_char('$');
- checksum = 0;
- count = 0;
-
- while ((ch = buffer[count]) != 0) {
- gdbstub_io_tx_char(ch);
- checksum += ch;
- count += 1;
- }
-
- gdbstub_io_tx_char('#');
- gdbstub_io_tx_char(hex_asc_hi(checksum));
- gdbstub_io_tx_char(hex_asc_lo(checksum));
-
- } while (gdbstub_io_rx_char(&ch, 0),
- ch == '-' && (gdbstub_io("### GDB Rx NAK\n"), 0),
- ch != '-' && ch != '+' &&
- (gdbstub_io("### GDB Rx ??? %02x\n", ch), 0),
- ch != '+' && ch != '$');
-
- if (ch == '+') {
- gdbstub_io("### GDB Rx ACK\n");
- return 0;
- }
-
- gdbstub_io("### GDB Tx Abandoned\n");
- gdbstub_rx_unget = ch;
- return 1;
-}
-
-/*
- * While we find nice hex chars, build an int.
- * Return number of chars processed.
- */
-static int hexToInt(char **ptr, int *intValue)
-{
- int numChars = 0;
- int hexValue;
-
- *intValue = 0;
-
- while (**ptr) {
- hexValue = hex(**ptr);
- if (hexValue < 0)
- break;
-
- *intValue = (*intValue << 4) | hexValue;
- numChars++;
-
- (*ptr)++;
- }
-
- return (numChars);
-}
-
-#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
-/*
- * We single-step by setting breakpoints. When an exception
- * is handled, we need to restore the instructions hoisted
- * when the breakpoints were set.
- *
- * This is where we save the original instructions.
- */
-static struct gdb_bp_save {
- u8 *addr;
- u8 opcode[2];
-} step_bp[2];
-
-static const unsigned char gdbstub_insn_sizes[256] =
-{
- /* 1 2 3 4 5 6 7 8 9 a b c d e f */
- 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
- 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
- 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
- 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */
-};
-
-static int __gdbstub_mark_bp(u8 *addr, int ix)
-{
- /* vmalloc area */
- if (((u8 *) VMALLOC_START <= addr) && (addr < (u8 *) VMALLOC_END))
- goto okay;
- /* SRAM, SDRAM */
- if (((u8 *) 0x80000000UL <= addr) && (addr < (u8 *) 0xa0000000UL))
- goto okay;
- return 0;
-
-okay:
- if (gdbstub_read_byte(addr + 0, &step_bp[ix].opcode[0]) < 0 ||
- gdbstub_read_byte(addr + 1, &step_bp[ix].opcode[1]) < 0)
- return 0;
-
- step_bp[ix].addr = addr;
- return 1;
-}
-
-static inline void __gdbstub_restore_bp(void)
-{
-#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
- if (step_bp[0].addr) {
- gdbstub_write_byte(step_bp[0].opcode[0], step_bp[0].addr + 0);
- gdbstub_write_byte(step_bp[0].opcode[1], step_bp[0].addr + 1);
- }
- if (step_bp[1].addr) {
- gdbstub_write_byte(step_bp[1].opcode[0], step_bp[1].addr + 0);
- gdbstub_write_byte(step_bp[1].opcode[1], step_bp[1].addr + 1);
- }
-#else
- if (step_bp[0].addr)
- gdbstub_write_byte(step_bp[0].opcode[0], step_bp[0].addr + 0);
- if (step_bp[1].addr)
- gdbstub_write_byte(step_bp[1].opcode[0], step_bp[1].addr + 0);
-#endif
-
- gdbstub_flush_caches = 1;
-
- step_bp[0].addr = NULL;
- step_bp[0].opcode[0] = 0;
- step_bp[0].opcode[1] = 0;
- step_bp[1].addr = NULL;
- step_bp[1].opcode[0] = 0;
- step_bp[1].opcode[1] = 0;
-}
-
-/*
- * emulate single stepping by means of breakpoint instructions
- */
-static int gdbstub_single_step(struct pt_regs *regs)
-{
- unsigned size;
- uint32_t x;
- uint8_t cur, *pc, *sp;
-
- step_bp[0].addr = NULL;
- step_bp[0].opcode[0] = 0;
- step_bp[0].opcode[1] = 0;
- step_bp[1].addr = NULL;
- step_bp[1].opcode[0] = 0;
- step_bp[1].opcode[1] = 0;
- x = 0;
-
- pc = (u8 *) regs->pc;
- sp = (u8 *) (regs + 1);
- if (gdbstub_read_byte(pc, &cur) < 0)
- return -EFAULT;
-
- gdbstub_bkpt("Single Step from %p { %02x }\n", pc, cur);
-
- gdbstub_flush_caches = 1;
-
- size = gdbstub_insn_sizes[cur];
- if (size > 0) {
- if (!__gdbstub_mark_bp(pc + size, 0))
- goto fault;
- } else {
- switch (cur) {
- /* Bxx (d8,PC) */
- case 0xc0 ... 0xca:
- if (gdbstub_read_byte(pc + 1, (u8 *) &x) < 0)
- goto fault;
- if (!__gdbstub_mark_bp(pc + 2, 0))
- goto fault;
- if ((x < 0 || x > 2) &&
- !__gdbstub_mark_bp(pc + (s8) x, 1))
- goto fault;
- break;
-
- /* LXX (d8,PC) */
- case 0xd0 ... 0xda:
- if (!__gdbstub_mark_bp(pc + 1, 0))
- goto fault;
- if (regs->pc != regs->lar &&
- !__gdbstub_mark_bp((u8 *) regs->lar, 1))
- goto fault;
- break;
-
- /* SETLB - loads the next for bytes into the LIR
- * register */
- case 0xdb:
- if (!__gdbstub_mark_bp(pc + 1, 0))
- goto fault;
- break;
-
- /* JMP (d16,PC) or CALL (d16,PC) */
- case 0xcc:
- case 0xcd:
- if (gdbstub_read_byte(pc + 1, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(pc + 2, ((u8 *) &x) + 1) < 0)
- goto fault;
- if (!__gdbstub_mark_bp(pc + (s16) x, 0))
- goto fault;
- break;
-
- /* JMP (d32,PC) or CALL (d32,PC) */
- case 0xdc:
- case 0xdd:
- if (gdbstub_read_byte(pc + 1, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(pc + 2, ((u8 *) &x) + 1) < 0 ||
- gdbstub_read_byte(pc + 3, ((u8 *) &x) + 2) < 0 ||
- gdbstub_read_byte(pc + 4, ((u8 *) &x) + 3) < 0)
- goto fault;
- if (!__gdbstub_mark_bp(pc + (s32) x, 0))
- goto fault;
- break;
-
- /* RETF */
- case 0xde:
- if (!__gdbstub_mark_bp((u8 *) regs->mdr, 0))
- goto fault;
- break;
-
- /* RET */
- case 0xdf:
- if (gdbstub_read_byte(pc + 2, (u8 *) &x) < 0)
- goto fault;
- sp += (s8)x;
- if (gdbstub_read_byte(sp + 0, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(sp + 1, ((u8 *) &x) + 1) < 0 ||
- gdbstub_read_byte(sp + 2, ((u8 *) &x) + 2) < 0 ||
- gdbstub_read_byte(sp + 3, ((u8 *) &x) + 3) < 0)
- goto fault;
- if (!__gdbstub_mark_bp((u8 *) x, 0))
- goto fault;
- break;
-
- case 0xf0:
- if (gdbstub_read_byte(pc + 1, &cur) < 0)
- goto fault;
-
- if (cur >= 0xf0 && cur <= 0xf7) {
- /* JMP (An) / CALLS (An) */
- switch (cur & 3) {
- case 0: x = regs->a0; break;
- case 1: x = regs->a1; break;
- case 2: x = regs->a2; break;
- case 3: x = regs->a3; break;
- }
- if (!__gdbstub_mark_bp((u8 *) x, 0))
- goto fault;
- } else if (cur == 0xfc) {
- /* RETS */
- if (gdbstub_read_byte(
- sp + 0, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(
- sp + 1, ((u8 *) &x) + 1) < 0 ||
- gdbstub_read_byte(
- sp + 2, ((u8 *) &x) + 2) < 0 ||
- gdbstub_read_byte(
- sp + 3, ((u8 *) &x) + 3) < 0)
- goto fault;
- if (!__gdbstub_mark_bp((u8 *) x, 0))
- goto fault;
- } else if (cur == 0xfd) {
- /* RTI */
- if (gdbstub_read_byte(
- sp + 4, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(
- sp + 5, ((u8 *) &x) + 1) < 0 ||
- gdbstub_read_byte(
- sp + 6, ((u8 *) &x) + 2) < 0 ||
- gdbstub_read_byte(
- sp + 7, ((u8 *) &x) + 3) < 0)
- goto fault;
- if (!__gdbstub_mark_bp((u8 *) x, 0))
- goto fault;
- } else {
- if (!__gdbstub_mark_bp(pc + 2, 0))
- goto fault;
- }
-
- break;
-
- /* potential 3-byte conditional branches */
- case 0xf8:
- if (gdbstub_read_byte(pc + 1, &cur) < 0)
- goto fault;
- if (!__gdbstub_mark_bp(pc + 3, 0))
- goto fault;
-
- if (cur >= 0xe8 && cur <= 0xeb) {
- if (gdbstub_read_byte(
- pc + 2, ((u8 *) &x) + 0) < 0)
- goto fault;
- if ((x < 0 || x > 3) &&
- !__gdbstub_mark_bp(pc + (s8) x, 1))
- goto fault;
- }
- break;
-
- case 0xfa:
- if (gdbstub_read_byte(pc + 1, &cur) < 0)
- goto fault;
-
- if (cur == 0xff) {
- /* CALLS (d16,PC) */
- if (gdbstub_read_byte(
- pc + 2, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(
- pc + 3, ((u8 *) &x) + 1) < 0)
- goto fault;
- if (!__gdbstub_mark_bp(pc + (s16) x, 0))
- goto fault;
- } else {
- if (!__gdbstub_mark_bp(pc + 4, 0))
- goto fault;
- }
- break;
-
- case 0xfc:
- if (gdbstub_read_byte(pc + 1, &cur) < 0)
- goto fault;
- if (cur == 0xff) {
- /* CALLS (d32,PC) */
- if (gdbstub_read_byte(
- pc + 2, ((u8 *) &x) + 0) < 0 ||
- gdbstub_read_byte(
- pc + 3, ((u8 *) &x) + 1) < 0 ||
- gdbstub_read_byte(
- pc + 4, ((u8 *) &x) + 2) < 0 ||
- gdbstub_read_byte(
- pc + 5, ((u8 *) &x) + 3) < 0)
- goto fault;
- if (!__gdbstub_mark_bp(
- pc + (s32) x, 0))
- goto fault;
- } else {
- if (!__gdbstub_mark_bp(
- pc + 6, 0))
- goto fault;
- }
- break;
-
- }
- }
-
- gdbstub_bkpt("Step: %02x at %p; %02x at %p\n",
- step_bp[0].opcode[0], step_bp[0].addr,
- step_bp[1].opcode[0], step_bp[1].addr);
-
- if (step_bp[0].addr) {
-#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
- if (gdbstub_write_byte(0xF7, step_bp[0].addr + 0) < 0 ||
- gdbstub_write_byte(0xF7, step_bp[0].addr + 1) < 0)
- goto fault;
-#else
- if (gdbstub_write_byte(0xFF, step_bp[0].addr + 0) < 0)
- goto fault;
-#endif
- }
-
- if (step_bp[1].addr) {
-#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
- if (gdbstub_write_byte(0xF7, step_bp[1].addr + 0) < 0 ||
- gdbstub_write_byte(0xF7, step_bp[1].addr + 1) < 0)
- goto fault;
-#else
- if (gdbstub_write_byte(0xFF, step_bp[1].addr + 0) < 0)
- goto fault;
-#endif
- }
-
- return 0;
-
- fault:
- /* uh-oh - silly address alert, try and restore things */
- __gdbstub_restore_bp();
- return -EFAULT;
-}
-#endif /* CONFIG_GDBSTUB_ALLOW_SINGLE_STEP */
-
-#ifdef CONFIG_GDBSTUB_CONSOLE
-
-void gdbstub_console_write(struct console *con, const char *p, unsigned n)
-{
- static const char gdbstub_cr[] = { 0x0d };
- char outbuf[26];
- int qty;
- u8 busy;
-
- busy = gdbstub_busy;
- gdbstub_busy = 1;
-
- outbuf[0] = 'O';
-
- while (n > 0) {
- qty = 1;
-
- while (n > 0 && qty < 20) {
- mem2hex(p, outbuf + qty, 2, 0);
- qty += 2;
- if (*p == 0x0a) {
- mem2hex(gdbstub_cr, outbuf + qty, 2, 0);
- qty += 2;
- }
- p++;
- n--;
- }
-
- outbuf[qty] = 0;
- putpacket(outbuf);
- }
-
- gdbstub_busy = busy;
-}
-
-static kdev_t gdbstub_console_dev(struct console *con)
-{
- return MKDEV(1, 3); /* /dev/null */
-}
-
-static struct console gdbstub_console = {
- .name = "gdb",
- .write = gdbstub_console_write,
- .device = gdbstub_console_dev,
- .flags = CON_PRINTBUFFER,
- .index = -1,
-};
-
-#endif
-
-/*
- * Convert the memory pointed to by mem into hex, placing result in buf.
- * - if successful, return a pointer to the last char put in buf (NUL)
- * - in case of mem fault, return NULL
- * may_fault is non-zero if we are reading from arbitrary memory, but is
- * currently not used.
- */
-static
-unsigned char *mem2hex(const void *_mem, char *buf, int count, int may_fault)
-{
- const u8 *mem = _mem;
- u8 ch[4];
-
- if ((u32) mem & 1 && count >= 1) {
- if (gdbstub_read_byte(mem, ch) != 0)
- return 0;
- buf = hex_byte_pack(buf, ch[0]);
- mem++;
- count--;
- }
-
- if ((u32) mem & 3 && count >= 2) {
- if (gdbstub_read_word(mem, ch) != 0)
- return 0;
- buf = hex_byte_pack(buf, ch[0]);
- buf = hex_byte_pack(buf, ch[1]);
- mem += 2;
- count -= 2;
- }
-
- while (count >= 4) {
- if (gdbstub_read_dword(mem, ch) != 0)
- return 0;
- buf = hex_byte_pack(buf, ch[0]);
- buf = hex_byte_pack(buf, ch[1]);
- buf = hex_byte_pack(buf, ch[2]);
- buf = hex_byte_pack(buf, ch[3]);
- mem += 4;
- count -= 4;
- }
-
- if (count >= 2) {
- if (gdbstub_read_word(mem, ch) != 0)
- return 0;
- buf = hex_byte_pack(buf, ch[0]);
- buf = hex_byte_pack(buf, ch[1]);
- mem += 2;
- count -= 2;
- }
-
- if (count >= 1) {
- if (gdbstub_read_byte(mem, ch) != 0)
- return 0;
- buf = hex_byte_pack(buf, ch[0]);
- }
-
- *buf = 0;
- return buf;
-}
-
-/*
- * convert the hex array pointed to by buf into binary to be placed in mem
- * return a pointer to the character AFTER the last byte written
- * may_fault is non-zero if we are reading from arbitrary memory, but is
- * currently not used.
- */
-static
-const char *hex2mem(const char *buf, void *_mem, int count, int may_fault)
-{
- u8 *mem = _mem;
- union {
- u32 val;
- u8 b[4];
- } ch;
-
- if ((u32) mem & 1 && count >= 1) {
- ch.b[0] = hex(*buf++) << 4;
- ch.b[0] |= hex(*buf++);
- if (gdbstub_write_byte(ch.val, mem) != 0)
- return 0;
- mem++;
- count--;
- }
-
- if ((u32) mem & 3 && count >= 2) {
- ch.b[0] = hex(*buf++) << 4;
- ch.b[0] |= hex(*buf++);
- ch.b[1] = hex(*buf++) << 4;
- ch.b[1] |= hex(*buf++);
- if (gdbstub_write_word(ch.val, mem) != 0)
- return 0;
- mem += 2;
- count -= 2;
- }
-
- while (count >= 4) {
- ch.b[0] = hex(*buf++) << 4;
- ch.b[0] |= hex(*buf++);
- ch.b[1] = hex(*buf++) << 4;
- ch.b[1] |= hex(*buf++);
- ch.b[2] = hex(*buf++) << 4;
- ch.b[2] |= hex(*buf++);
- ch.b[3] = hex(*buf++) << 4;
- ch.b[3] |= hex(*buf++);
- if (gdbstub_write_dword(ch.val, mem) != 0)
- return 0;
- mem += 4;
- count -= 4;
- }
-
- if (count >= 2) {
- ch.b[0] = hex(*buf++) << 4;
- ch.b[0] |= hex(*buf++);
- ch.b[1] = hex(*buf++) << 4;
- ch.b[1] |= hex(*buf++);
- if (gdbstub_write_word(ch.val, mem) != 0)
- return 0;
- mem += 2;
- count -= 2;
- }
-
- if (count >= 1) {
- ch.b[0] = hex(*buf++) << 4;
- ch.b[0] |= hex(*buf++);
- if (gdbstub_write_byte(ch.val, mem) != 0)
- return 0;
- }
-
- return buf;
-}
-
-/*
- * This table contains the mapping between MN10300 exception codes, and
- * signals, which are primarily what GDB understands. It also indicates
- * which hardware traps we need to commandeer when initializing the stub.
- */
-static const struct excep_to_sig_map {
- enum exception_code excep; /* MN10300 exception code */
- unsigned char signo; /* Signal that we map this into */
-} excep_to_sig_map[] = {
- { EXCEP_ITLBMISS, SIGSEGV },
- { EXCEP_DTLBMISS, SIGSEGV },
- { EXCEP_TRAP, SIGTRAP },
- { EXCEP_ISTEP, SIGTRAP },
- { EXCEP_IBREAK, SIGTRAP },
- { EXCEP_OBREAK, SIGTRAP },
- { EXCEP_UNIMPINS, SIGILL },
- { EXCEP_UNIMPEXINS, SIGILL },
- { EXCEP_MEMERR, SIGSEGV },
- { EXCEP_MISALIGN, SIGSEGV },
- { EXCEP_BUSERROR, SIGBUS },
- { EXCEP_ILLINSACC, SIGSEGV },
- { EXCEP_ILLDATACC, SIGSEGV },
- { EXCEP_IOINSACC, SIGSEGV },
- { EXCEP_PRIVINSACC, SIGSEGV },
- { EXCEP_PRIVDATACC, SIGSEGV },
- { EXCEP_FPU_DISABLED, SIGFPE },
- { EXCEP_FPU_UNIMPINS, SIGFPE },
- { EXCEP_FPU_OPERATION, SIGFPE },
- { EXCEP_WDT, SIGALRM },
- { EXCEP_NMI, SIGQUIT },
- { EXCEP_IRQ_LEVEL0, SIGINT },
- { EXCEP_IRQ_LEVEL1, SIGINT },
- { EXCEP_IRQ_LEVEL2, SIGINT },
- { EXCEP_IRQ_LEVEL3, SIGINT },
- { EXCEP_IRQ_LEVEL4, SIGINT },
- { EXCEP_IRQ_LEVEL5, SIGINT },
- { EXCEP_IRQ_LEVEL6, SIGINT },
- { 0, 0}
-};
-
-/*
- * convert the MN10300 exception code into a UNIX signal number
- */
-static int computeSignal(enum exception_code excep)
-{
- const struct excep_to_sig_map *map;
-
- for (map = excep_to_sig_map; map->signo; map++)
- if (map->excep == excep)
- return map->signo;
-
- return SIGHUP; /* default for things we don't know about */
-}
-
-static u32 gdbstub_fpcr, gdbstub_fpufs_array[32];
-
-/*
- *
- */
-static void gdbstub_store_fpu(void)
-{
-#ifdef CONFIG_FPU
-
- asm volatile(
- "or %2,epsw\n"
-#ifdef CONFIG_MN10300_PROC_MN103E010
- "nop\n"
- "nop\n"
-#endif
- "mov %1, a1\n"
- "fmov fs0, (a1+)\n"
- "fmov fs1, (a1+)\n"
- "fmov fs2, (a1+)\n"
- "fmov fs3, (a1+)\n"
- "fmov fs4, (a1+)\n"
- "fmov fs5, (a1+)\n"
- "fmov fs6, (a1+)\n"
- "fmov fs7, (a1+)\n"
- "fmov fs8, (a1+)\n"
- "fmov fs9, (a1+)\n"
- "fmov fs10, (a1+)\n"
- "fmov fs11, (a1+)\n"
- "fmov fs12, (a1+)\n"
- "fmov fs13, (a1+)\n"
- "fmov fs14, (a1+)\n"
- "fmov fs15, (a1+)\n"
- "fmov fs16, (a1+)\n"
- "fmov fs17, (a1+)\n"
- "fmov fs18, (a1+)\n"
- "fmov fs19, (a1+)\n"
- "fmov fs20, (a1+)\n"
- "fmov fs21, (a1+)\n"
- "fmov fs22, (a1+)\n"
- "fmov fs23, (a1+)\n"
- "fmov fs24, (a1+)\n"
- "fmov fs25, (a1+)\n"
- "fmov fs26, (a1+)\n"
- "fmov fs27, (a1+)\n"
- "fmov fs28, (a1+)\n"
- "fmov fs29, (a1+)\n"
- "fmov fs30, (a1+)\n"
- "fmov fs31, (a1+)\n"
- "fmov fpcr, %0\n"
- : "=d"(gdbstub_fpcr)
- : "g" (&gdbstub_fpufs_array), "i"(EPSW_FE)
- : "a1"
- );
-#endif
-}
-
-/*
- *
- */
-static void gdbstub_load_fpu(void)
-{
-#ifdef CONFIG_FPU
-
- asm volatile(
- "or %1,epsw\n"
-#ifdef CONFIG_MN10300_PROC_MN103E010
- "nop\n"
- "nop\n"
-#endif
- "mov %0, a1\n"
- "fmov (a1+), fs0\n"
- "fmov (a1+), fs1\n"
- "fmov (a1+), fs2\n"
- "fmov (a1+), fs3\n"
- "fmov (a1+), fs4\n"
- "fmov (a1+), fs5\n"
- "fmov (a1+), fs6\n"
- "fmov (a1+), fs7\n"
- "fmov (a1+), fs8\n"
- "fmov (a1+), fs9\n"
- "fmov (a1+), fs10\n"
- "fmov (a1+), fs11\n"
- "fmov (a1+), fs12\n"
- "fmov (a1+), fs13\n"
- "fmov (a1+), fs14\n"
- "fmov (a1+), fs15\n"
- "fmov (a1+), fs16\n"
- "fmov (a1+), fs17\n"
- "fmov (a1+), fs18\n"
- "fmov (a1+), fs19\n"
- "fmov (a1+), fs20\n"
- "fmov (a1+), fs21\n"
- "fmov (a1+), fs22\n"
- "fmov (a1+), fs23\n"
- "fmov (a1+), fs24\n"
- "fmov (a1+), fs25\n"
- "fmov (a1+), fs26\n"
- "fmov (a1+), fs27\n"
- "fmov (a1+), fs28\n"
- "fmov (a1+), fs29\n"
- "fmov (a1+), fs30\n"
- "fmov (a1+), fs31\n"
- "fmov %2, fpcr\n"
- :
- : "g" (&gdbstub_fpufs_array), "i"(EPSW_FE), "d"(gdbstub_fpcr)
- : "a1"
- );
-#endif
-}
-
-/*
- * set a software breakpoint
- */
-int gdbstub_set_breakpoint(u8 *addr, int len)
-{
- int bkpt, loop, xloop;
-
-#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
- len = (len + 1) & ~1;
-#endif
-
- gdbstub_bkpt("setbkpt(%p,%d)\n", addr, len);
-
- for (bkpt = 255; bkpt >= 0; bkpt--)
- if (!gdbstub_bkpts[bkpt].addr)
- break;
- if (bkpt < 0)
- return -ENOSPC;
-
- for (loop = 0; loop < len; loop++)
- if (gdbstub_read_byte(&addr[loop],
- &gdbstub_bkpts[bkpt].origbytes[loop]
- ) < 0)
- return -EFAULT;
-
- gdbstub_flush_caches = 1;
-
-#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
- for (loop = 0; loop < len; loop++)
- if (gdbstub_write_byte(0xF7, &addr[loop]) < 0)
- goto restore;
-#else
- for (loop = 0; loop < len; loop++)
- if (gdbstub_write_byte(0xFF, &addr[loop]) < 0)
- goto restore;
-#endif
-
- gdbstub_bkpts[bkpt].addr = addr;
- gdbstub_bkpts[bkpt].len = len;
-
- gdbstub_bkpt("Set BKPT[%02x]: %p-%p {%02x%02x%02x%02x%02x%02x%02x}\n",
- bkpt,
- gdbstub_bkpts[bkpt].addr,
- gdbstub_bkpts[bkpt].addr + gdbstub_bkpts[bkpt].len - 1,
- gdbstub_bkpts[bkpt].origbytes[0],
- gdbstub_bkpts[bkpt].origbytes[1],
- gdbstub_bkpts[bkpt].origbytes[2],
- gdbstub_bkpts[bkpt].origbytes[3],
- gdbstub_bkpts[bkpt].origbytes[4],
- gdbstub_bkpts[bkpt].origbytes[5],
- gdbstub_bkpts[bkpt].origbytes[6]
- );
-
- return 0;
-
-restore:
- for (xloop = 0; xloop < loop; xloop++)
- gdbstub_write_byte(gdbstub_bkpts[bkpt].origbytes[xloop],
- addr + xloop);
- return -EFAULT;
-}
-
-/*
- * clear a software breakpoint
- */
-int gdbstub_clear_breakpoint(u8 *addr, int len)
-{
- int bkpt, loop;
-
-#ifdef GDBSTUB_USE_F7F7_AS_BREAKPOINT
- len = (len + 1) & ~1;
-#endif
-
- gdbstub_bkpt("clearbkpt(%p,%d)\n", addr, len);
-
- for (bkpt = 255; bkpt >= 0; bkpt--)
- if (gdbstub_bkpts[bkpt].addr == addr &&
- gdbstub_bkpts[bkpt].len == len)
- break;
- if (bkpt < 0)
- return -ENOENT;
-
- gdbstub_bkpts[bkpt].addr = NULL;
-
- gdbstub_flush_caches = 1;
-
- for (loop = 0; loop < len; loop++)
- if (gdbstub_write_byte(gdbstub_bkpts[bkpt].origbytes[loop],
- addr + loop) < 0)
- return -EFAULT;
-
- return 0;
-}
-
-/*
- * This function does all command processing for interfacing to gdb
- * - returns 0 if the exception should be skipped, -ERROR otherwise.
- */
-static int gdbstub(struct pt_regs *regs, enum exception_code excep)
-{
- unsigned long *stack;
- unsigned long epsw, mdr;
- uint32_t zero, ssp;
- uint8_t broke;
- char *ptr;
- int sigval;
- int addr;
- int length;
- int loop;
-
- if (excep == EXCEP_FPU_DISABLED)
- return -ENOTSUPP;
-
- gdbstub_flush_caches = 0;
-
- mn10300_set_gdbleds(1);
-
- asm volatile("mov mdr,%0" : "=d"(mdr));
- local_save_flags(epsw);
- arch_local_change_intr_mask_level(
- NUM2EPSW_IM(CONFIG_DEBUGGER_IRQ_LEVEL + 1));
-
- gdbstub_store_fpu();
-
-#ifdef CONFIG_GDBSTUB_IMMEDIATE
- /* skip the initial pause loop */
- if (regs->pc == (unsigned long) __gdbstub_pause)
- regs->pc = (unsigned long) start_kernel;
-#endif
-
- /* if we were single stepping, restore the opcodes hoisted for the
- * breakpoint[s] */
- broke = 0;
-#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
- if ((step_bp[0].addr && step_bp[0].addr == (u8 *) regs->pc) ||
- (step_bp[1].addr && step_bp[1].addr == (u8 *) regs->pc))
- broke = 1;
-
- __gdbstub_restore_bp();
-#endif
-
- if (gdbstub_rx_unget) {
- sigval = SIGINT;
- if (gdbstub_rx_unget != 3)
- goto packet_waiting;
- gdbstub_rx_unget = 0;
- }
-
- stack = (unsigned long *) regs->sp;
- sigval = broke ? SIGTRAP : computeSignal(excep);
-
- /* send information about a BUG() */
- if (!user_mode(regs) && excep == EXCEP_SYSCALL15) {
- const struct bug_entry *bug;
-
- bug = find_bug(regs->pc);
- if (bug)
- goto found_bug;
- length = snprintf(trans_buffer, sizeof(trans_buffer),
- "BUG() at address %lx\n", regs->pc);
- goto send_bug_pkt;
-
- found_bug:
- length = snprintf(trans_buffer, sizeof(trans_buffer),
- "BUG() at address %lx (%s:%d)\n",
- regs->pc, bug->file, bug->line);
-
- send_bug_pkt:
- ptr = output_buffer;
- *ptr++ = 'O';
- ptr = mem2hex(trans_buffer, ptr, length, 0);
- *ptr = 0;
- putpacket(output_buffer);
-
- regs->pc -= 2;
- sigval = SIGABRT;
- } else if (regs->pc == (unsigned long) __gdbstub_bug_trap) {
- regs->pc = regs->mdr;
- sigval = SIGABRT;
- }
-
- /*
- * send a message to the debugger's user saying what happened if it may
- * not be clear cut (we can't map exceptions onto signals properly)
- */
- if (sigval != SIGINT && sigval != SIGTRAP && sigval != SIGILL) {
- static const char title[] = "Excep ", tbcberr[] = "BCBERR ";
- static const char crlf[] = "\r\n";
- char hx;
- u32 bcberr = BCBERR;
-
- ptr = output_buffer;
- *ptr++ = 'O';
- ptr = mem2hex(title, ptr, sizeof(title) - 1, 0);
-
- hx = hex_asc_hi(excep >> 8);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_lo(excep >> 8);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_hi(excep);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_lo(excep);
- ptr = hex_byte_pack(ptr, hx);
-
- ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);
- *ptr = 0;
- putpacket(output_buffer); /* send it off... */
-
- /* BCBERR */
- ptr = output_buffer;
- *ptr++ = 'O';
- ptr = mem2hex(tbcberr, ptr, sizeof(tbcberr) - 1, 0);
-
- hx = hex_asc_hi(bcberr >> 24);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_lo(bcberr >> 24);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_hi(bcberr >> 16);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_lo(bcberr >> 16);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_hi(bcberr >> 8);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_lo(bcberr >> 8);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_hi(bcberr);
- ptr = hex_byte_pack(ptr, hx);
- hx = hex_asc_lo(bcberr);
- ptr = hex_byte_pack(ptr, hx);
-
- ptr = mem2hex(crlf, ptr, sizeof(crlf) - 1, 0);
- *ptr = 0;
- putpacket(output_buffer); /* send it off... */
- }
-
- /*
- * tell the debugger that an exception has occurred
- */
- ptr = output_buffer;
-
- /*
- * Send trap type (converted to signal)
- */
- *ptr++ = 'T';
- ptr = hex_byte_pack(ptr, sigval);
-
- /*
- * Send Error PC
- */
- ptr = hex_byte_pack(ptr, GDB_REGID_PC);
- *ptr++ = ':';
- ptr = mem2hex(&regs->pc, ptr, 4, 0);
- *ptr++ = ';';
-
- /*
- * Send frame pointer
- */
- ptr = hex_byte_pack(ptr, GDB_REGID_FP);
- *ptr++ = ':';
- ptr = mem2hex(&regs->a3, ptr, 4, 0);
- *ptr++ = ';';
-
- /*
- * Send stack pointer
- */
- ssp = (unsigned long) (regs + 1);
- ptr = hex_byte_pack(ptr, GDB_REGID_SP);
- *ptr++ = ':';
- ptr = mem2hex(&ssp, ptr, 4, 0);
- *ptr++ = ';';
-
- *ptr++ = 0;
- putpacket(output_buffer); /* send it off... */
-
-packet_waiting:
- /*
- * Wait for input from remote GDB
- */
- while (1) {
- output_buffer[0] = 0;
- getpacket(input_buffer);
-
- switch (input_buffer[0]) {
- /* request repeat of last signal number */
- case '?':
- output_buffer[0] = 'S';
- output_buffer[1] = hex_asc_hi(sigval);
- output_buffer[2] = hex_asc_lo(sigval);
- output_buffer[3] = 0;
- break;
-
- case 'd':
- /* toggle debug flag */
- break;
-
- /*
- * Return the value of the CPU registers
- */
- case 'g':
- zero = 0;
- ssp = (u32) (regs + 1);
- ptr = output_buffer;
- ptr = mem2hex(&regs->d0, ptr, 4, 0);
- ptr = mem2hex(&regs->d1, ptr, 4, 0);
- ptr = mem2hex(&regs->d2, ptr, 4, 0);
- ptr = mem2hex(&regs->d3, ptr, 4, 0);
- ptr = mem2hex(&regs->a0, ptr, 4, 0);
- ptr = mem2hex(&regs->a1, ptr, 4, 0);
- ptr = mem2hex(&regs->a2, ptr, 4, 0);
- ptr = mem2hex(&regs->a3, ptr, 4, 0);
-
- ptr = mem2hex(&ssp, ptr, 4, 0); /* 8 */
- ptr = mem2hex(&regs->pc, ptr, 4, 0);
- ptr = mem2hex(&regs->mdr, ptr, 4, 0);
- ptr = mem2hex(&regs->epsw, ptr, 4, 0);
- ptr = mem2hex(&regs->lir, ptr, 4, 0);
- ptr = mem2hex(&regs->lar, ptr, 4, 0);
- ptr = mem2hex(&regs->mdrq, ptr, 4, 0);
-
- ptr = mem2hex(&regs->e0, ptr, 4, 0); /* 15 */
- ptr = mem2hex(&regs->e1, ptr, 4, 0);
- ptr = mem2hex(&regs->e2, ptr, 4, 0);
- ptr = mem2hex(&regs->e3, ptr, 4, 0);
- ptr = mem2hex(&regs->e4, ptr, 4, 0);
- ptr = mem2hex(&regs->e5, ptr, 4, 0);
- ptr = mem2hex(&regs->e6, ptr, 4, 0);
- ptr = mem2hex(&regs->e7, ptr, 4, 0);
-
- ptr = mem2hex(&ssp, ptr, 4, 0);
- ptr = mem2hex(&regs, ptr, 4, 0);
- ptr = mem2hex(&regs->sp, ptr, 4, 0);
- ptr = mem2hex(&regs->mcrh, ptr, 4, 0); /* 26 */
- ptr = mem2hex(&regs->mcrl, ptr, 4, 0);
- ptr = mem2hex(&regs->mcvf, ptr, 4, 0);
-
- ptr = mem2hex(&gdbstub_fpcr, ptr, 4, 0); /* 29 - FPCR */
- ptr = mem2hex(&zero, ptr, 4, 0);
- ptr = mem2hex(&zero, ptr, 4, 0);
- for (loop = 0; loop < 32; loop++)
- ptr = mem2hex(&gdbstub_fpufs_array[loop],
- ptr, 4, 0); /* 32 - FS0-31 */
-
- break;
-
- /*
- * set the value of the CPU registers - return OK
- */
- case 'G':
- {
- const char *ptr;
-
- ptr = &input_buffer[1];
- ptr = hex2mem(ptr, &regs->d0, 4, 0);
- ptr = hex2mem(ptr, &regs->d1, 4, 0);
- ptr = hex2mem(ptr, &regs->d2, 4, 0);
- ptr = hex2mem(ptr, &regs->d3, 4, 0);
- ptr = hex2mem(ptr, &regs->a0, 4, 0);
- ptr = hex2mem(ptr, &regs->a1, 4, 0);
- ptr = hex2mem(ptr, &regs->a2, 4, 0);
- ptr = hex2mem(ptr, &regs->a3, 4, 0);
-
- ptr = hex2mem(ptr, &ssp, 4, 0); /* 8 */
- ptr = hex2mem(ptr, &regs->pc, 4, 0);
- ptr = hex2mem(ptr, &regs->mdr, 4, 0);
- ptr = hex2mem(ptr, &regs->epsw, 4, 0);
- ptr = hex2mem(ptr, &regs->lir, 4, 0);
- ptr = hex2mem(ptr, &regs->lar, 4, 0);
- ptr = hex2mem(ptr, &regs->mdrq, 4, 0);
-
- ptr = hex2mem(ptr, &regs->e0, 4, 0); /* 15 */
- ptr = hex2mem(ptr, &regs->e1, 4, 0);
- ptr = hex2mem(ptr, &regs->e2, 4, 0);
- ptr = hex2mem(ptr, &regs->e3, 4, 0);
- ptr = hex2mem(ptr, &regs->e4, 4, 0);
- ptr = hex2mem(ptr, &regs->e5, 4, 0);
- ptr = hex2mem(ptr, &regs->e6, 4, 0);
- ptr = hex2mem(ptr, &regs->e7, 4, 0);
-
- ptr = hex2mem(ptr, &ssp, 4, 0);
- ptr = hex2mem(ptr, &zero, 4, 0);
- ptr = hex2mem(ptr, &regs->sp, 4, 0);
- ptr = hex2mem(ptr, &regs->mcrh, 4, 0); /* 26 */
- ptr = hex2mem(ptr, &regs->mcrl, 4, 0);
- ptr = hex2mem(ptr, &regs->mcvf, 4, 0);
-
- ptr = hex2mem(ptr, &zero, 4, 0); /* 29 - FPCR */
- ptr = hex2mem(ptr, &zero, 4, 0);
- ptr = hex2mem(ptr, &zero, 4, 0);
- for (loop = 0; loop < 32; loop++) /* 32 - FS0-31 */
- ptr = hex2mem(ptr, &zero, 4, 0);
-
-#if 0
- /*
- * See if the stack pointer has moved. If so, then copy
- * the saved locals and ins to the new location.
- */
- unsigned long *newsp = (unsigned long *) registers[SP];
- if (sp != newsp)
- sp = memcpy(newsp, sp, 16 * 4);
-#endif
-
- gdbstub_strcpy(output_buffer, "OK");
- }
- break;
-
- /*
- * mAA..AA,LLLL Read LLLL bytes at address AA..AA
- */
- case 'm':
- ptr = &input_buffer[1];
-
- if (hexToInt(&ptr, &addr) &&
- *ptr++ == ',' &&
- hexToInt(&ptr, &length)
- ) {
- if (mem2hex((char *) addr, output_buffer,
- length, 1))
- break;
- gdbstub_strcpy(output_buffer, "E03");
- } else {
- gdbstub_strcpy(output_buffer, "E01");
- }
- break;
-
- /*
- * MAA..AA,LLLL: Write LLLL bytes at address AA.AA
- * return OK
- */
- case 'M':
- ptr = &input_buffer[1];
-
- if (hexToInt(&ptr, &addr) &&
- *ptr++ == ',' &&
- hexToInt(&ptr, &length) &&
- *ptr++ == ':'
- ) {
- if (hex2mem(ptr, (char *) addr, length, 1))
- gdbstub_strcpy(output_buffer, "OK");
- else
- gdbstub_strcpy(output_buffer, "E03");
-
- gdbstub_flush_caches = 1;
- } else {
- gdbstub_strcpy(output_buffer, "E02");
- }
- break;
-
- /*
- * cAA..AA Continue at address AA..AA(optional)
- */
- case 'c':
- /* try to read optional parameter, pc unchanged if no
- * parm */
-
- ptr = &input_buffer[1];
- if (hexToInt(&ptr, &addr))
- regs->pc = addr;
- goto done;
-
- /*
- * kill the program
- */
- case 'k' :
- goto done; /* just continue */
-
- /*
- * Reset the whole machine (FIXME: system dependent)
- */
- case 'r':
- break;
-
- /*
- * Step to next instruction
- */
- case 's':
- /* Using the T flag doesn't seem to perform single
- * stepping (it seems to wind up being caught by the
- * JTAG unit), so we have to use breakpoints and
- * continue instead.
- */
-#ifdef CONFIG_GDBSTUB_ALLOW_SINGLE_STEP
- if (gdbstub_single_step(regs) < 0)
- /* ignore any fault error for now */
- gdbstub_printk("unable to set single-step"
- " bp\n");
- goto done;
-#else
- gdbstub_strcpy(output_buffer, "E01");
- break;
-#endif
-
- /*
- * Set baud rate (bBB)
- */
- case 'b':
- do {
- int baudrate;
-
- ptr = &input_buffer[1];
- if (!hexToInt(&ptr, &baudrate)) {
- gdbstub_strcpy(output_buffer, "B01");
- break;
- }
-
- if (baudrate) {
- /* ACK before changing speed */
- putpacket("OK");
- gdbstub_io_set_baud(baudrate);
- }
- } while (0);
- break;
-
- /*
- * Set breakpoint
- */
- case 'Z':
- ptr = &input_buffer[1];
-
- if (!hexToInt(&ptr, &loop) || *ptr++ != ',' ||
- !hexToInt(&ptr, &addr) || *ptr++ != ',' ||
- !hexToInt(&ptr, &length)
- ) {
- gdbstub_strcpy(output_buffer, "E01");
- break;
- }
-
- /* only support software breakpoints */
- gdbstub_strcpy(output_buffer, "E03");
- if (loop != 0 ||
- length < 1 ||
- length > 7 ||
- (unsigned long) addr < 4096)
- break;
-
- if (gdbstub_set_breakpoint((u8 *) addr, length) < 0)
- break;
-
- gdbstub_strcpy(output_buffer, "OK");
- break;
-
- /*
- * Clear breakpoint
- */
- case 'z':
- ptr = &input_buffer[1];
-
- if (!hexToInt(&ptr, &loop) || *ptr++ != ',' ||
- !hexToInt(&ptr, &addr) || *ptr++ != ',' ||
- !hexToInt(&ptr, &length)
- ) {
- gdbstub_strcpy(output_buffer, "E01");
- break;
- }
-
- /* only support software breakpoints */
- gdbstub_strcpy(output_buffer, "E03");
- if (loop != 0 ||
- length < 1 ||
- length > 7 ||
- (unsigned long) addr < 4096)
- break;
-
- if (gdbstub_clear_breakpoint((u8 *) addr, length) < 0)
- break;
-
- gdbstub_strcpy(output_buffer, "OK");
- break;
-
- default:
- gdbstub_proto("### GDB Unsupported Cmd '%s'\n",
- input_buffer);
- break;
- }
-
- /* reply to the request */
- putpacket(output_buffer);
- }
-
-done:
- /*
- * Need to flush the instruction cache here, as we may
- * have deposited a breakpoint, and the icache probably
- * has no way of knowing that a data ref to some location
- * may have changed something that is in the instruction
- * cache.
- * NB: We flush both caches, just to be sure...
- */
- if (gdbstub_flush_caches)
- debugger_local_cache_flushinv();
-
- gdbstub_load_fpu();
- mn10300_set_gdbleds(0);
- if (excep == EXCEP_NMI)
- NMICR = NMICR_NMIF;
-
- touch_softlockup_watchdog();
-
- local_irq_restore(epsw);
- return 0;
-}
-
-/*
- * Determine if we hit a debugger special breakpoint that needs skipping over
- * automatically.
- */
-int at_debugger_breakpoint(struct pt_regs *regs)
-{
- return 0;
-}
-
-/*
- * handle event interception
- */
-asmlinkage int debugger_intercept(enum exception_code excep,
- int signo, int si_code, struct pt_regs *regs)
-{
- static u8 notfirst = 1;
- int ret;
-
- if (gdbstub_busy)
- gdbstub_printk("--> gdbstub reentered itself\n");
- gdbstub_busy = 1;
-
- if (notfirst) {
- unsigned long mdr;
- asm("mov mdr,%0" : "=d"(mdr));
-
- gdbstub_entry(
- "--> debugger_intercept(%p,%04x) [MDR=%lx PC=%lx]\n",
- regs, excep, mdr, regs->pc);
-
- gdbstub_entry(
- "PC: %08lx EPSW: %08lx SSP: %08lx mode: %s\n",
- regs->pc, regs->epsw, (unsigned long) &ret,
- user_mode(regs) ? "User" : "Super");
- gdbstub_entry(
- "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
- regs->d0, regs->d1, regs->d2, regs->d3);
- gdbstub_entry(
- "a0: %08lx a1: %08lx a2: %08lx a3: %08lx\n",
- regs->a0, regs->a1, regs->a2, regs->a3);
- gdbstub_entry(
- "e0: %08lx e1: %08lx e2: %08lx e3: %08lx\n",
- regs->e0, regs->e1, regs->e2, regs->e3);
- gdbstub_entry(
- "e4: %08lx e5: %08lx e6: %08lx e7: %08lx\n",
- regs->e4, regs->e5, regs->e6, regs->e7);
- gdbstub_entry(
- "lar: %08lx lir: %08lx mdr: %08lx usp: %08lx\n",
- regs->lar, regs->lir, regs->mdr, regs->sp);
- gdbstub_entry(
- "cvf: %08lx crl: %08lx crh: %08lx drq: %08lx\n",
- regs->mcvf, regs->mcrl, regs->mcrh, regs->mdrq);
- gdbstub_entry(
- "threadinfo=%p task=%p)\n",
- current_thread_info(), current);
- } else {
- notfirst = 1;
- }
-
- ret = gdbstub(regs, excep);
-
- gdbstub_entry("<-- debugger_intercept()\n");
- gdbstub_busy = 0;
- return ret;
-}
-
-/*
- * handle the GDB stub itself causing an exception
- */
-asmlinkage void gdbstub_exception(struct pt_regs *regs,
- enum exception_code excep)
-{
- unsigned long mdr;
-
- asm("mov mdr,%0" : "=d"(mdr));
- gdbstub_entry("--> gdbstub exception({%p},%04x) [MDR=%lx]\n",
- regs, excep, mdr);
-
- while ((unsigned long) regs == 0xffffffff) {}
-
- /* handle guarded memory accesses where we know it might fault */
- if (regs->pc == (unsigned) gdbstub_read_byte_guard) {
- regs->pc = (unsigned) gdbstub_read_byte_cont;
- goto fault;
- }
-
- if (regs->pc == (unsigned) gdbstub_read_word_guard) {
- regs->pc = (unsigned) gdbstub_read_word_cont;
- goto fault;
- }
-
- if (regs->pc == (unsigned) gdbstub_read_dword_guard) {
- regs->pc = (unsigned) gdbstub_read_dword_cont;
- goto fault;
- }
-
- if (regs->pc == (unsigned) gdbstub_write_byte_guard) {
- regs->pc = (unsigned) gdbstub_write_byte_cont;
- goto fault;
- }
-
- if (regs->pc == (unsigned) gdbstub_write_word_guard) {
- regs->pc = (unsigned) gdbstub_write_word_cont;
- goto fault;
- }
-
- if (regs->pc == (unsigned) gdbstub_write_dword_guard) {
- regs->pc = (unsigned) gdbstub_write_dword_cont;
- goto fault;
- }
-
- gdbstub_printk("\n### GDB stub caused an exception ###\n");
-
- /* something went horribly wrong */
- console_verbose();
- show_registers(regs);
-
- panic("GDB Stub caused an unexpected exception - can't continue\n");
-
- /* we caught an attempt by the stub to access silly memory */
-fault:
- gdbstub_entry("<-- gdbstub exception() = EFAULT\n");
- regs->d0 = -EFAULT;
- return;
-}
-
-/*
- * send an exit message to GDB
- */
-void gdbstub_exit(int status)
-{
- unsigned char checksum;
- unsigned char ch;
- int count;
-
- gdbstub_busy = 1;
- output_buffer[0] = 'W';
- output_buffer[1] = hex_asc_hi(status);
- output_buffer[2] = hex_asc_lo(status);
- output_buffer[3] = 0;
-
- gdbstub_io_tx_char('$');
- checksum = 0;
- count = 0;
-
- while ((ch = output_buffer[count]) != 0) {
- gdbstub_io_tx_char(ch);
- checksum += ch;
- count += 1;
- }
-
- gdbstub_io_tx_char('#');
- gdbstub_io_tx_char(hex_asc_hi(checksum));
- gdbstub_io_tx_char(hex_asc_lo(checksum));
-
- /* make sure the output is flushed, or else RedBoot might clobber it */
- gdbstub_io_tx_flush();
-
- gdbstub_busy = 0;
-}
-
-/*
- * initialise the GDB stub
- */
-asmlinkage void __init gdbstub_init(void)
-{
-#ifdef CONFIG_GDBSTUB_IMMEDIATE
- unsigned char ch;
- int ret;
-#endif
-
- gdbstub_busy = 1;
-
- printk(KERN_INFO "%s", gdbstub_banner);
-
- gdbstub_io_init();
-
- gdbstub_entry("--> gdbstub_init\n");
-
- /* try to talk to GDB (or anyone insane enough to want to type GDB
- * protocol by hand) */
- gdbstub_io("### GDB Tx ACK\n");
- gdbstub_io_tx_char('+'); /* 'hello world' */
-
-#ifdef CONFIG_GDBSTUB_IMMEDIATE
- gdbstub_printk("GDB Stub waiting for packet\n");
-
- /* in case GDB is started before us, ACK any packets that are already
- * sitting there (presumably "$?#xx")
- */
- do { gdbstub_io_rx_char(&ch, 0); } while (ch != '$');
- do { gdbstub_io_rx_char(&ch, 0); } while (ch != '#');
- /* eat first csum byte */
- do { ret = gdbstub_io_rx_char(&ch, 0); } while (ret != 0);
- /* eat second csum byte */
- do { ret = gdbstub_io_rx_char(&ch, 0); } while (ret != 0);
-
- gdbstub_io("### GDB Tx NAK\n");
- gdbstub_io_tx_char('-'); /* NAK it */
-
-#else
- printk("GDB Stub ready\n");
-#endif
-
- gdbstub_busy = 0;
- gdbstub_entry("<-- gdbstub_init\n");
-}
-
-/*
- * register the console at a more appropriate time
- */
-#ifdef CONFIG_GDBSTUB_CONSOLE
-static int __init gdbstub_postinit(void)
-{
- printk(KERN_NOTICE "registering console\n");
- register_console(&gdbstub_console);
- return 0;
-}
-
-__initcall(gdbstub_postinit);
-#endif
-
-/*
- * handle character reception on GDB serial port
- * - jump into the GDB stub if BREAK is detected on the serial line
- */
-asmlinkage void gdbstub_rx_irq(struct pt_regs *regs, enum exception_code excep)
-{
- char ch;
- int ret;
-
- gdbstub_entry("--> gdbstub_rx_irq\n");
-
- do {
- ret = gdbstub_io_rx_char(&ch, 1);
- if (ret != -EIO && ret != -EAGAIN) {
- if (ret != -EINTR)
- gdbstub_rx_unget = ch;
- gdbstub(regs, excep);
- }
- } while (ret != -EAGAIN);
-
- gdbstub_entry("<-- gdbstub_rx_irq\n");
-}
diff --git a/arch/mn10300/kernel/head.S b/arch/mn10300/kernel/head.S
deleted file mode 100644
index 0b15f759e0d2..000000000000
--- a/arch/mn10300/kernel/head.S
+++ /dev/null
@@ -1,442 +0,0 @@
-/* Boot entry point for MN10300 kernel
- *
- * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/linkage.h>
-#include <linux/serial_reg.h>
-#include <asm/thread_info.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/frame.inc>
-#include <asm/param.h>
-#include <unit/serial.h>
-#ifdef CONFIG_SMP
-#include <asm/smp.h>
-#include <asm/intctl-regs.h>
-#include <asm/cpu-regs.h>
-#include <proc/smp-regs.h>
-#endif /* CONFIG_SMP */
-
- __HEAD
-
-###############################################################################
-#
-# bootloader entry point
-#
-###############################################################################
- .globl _start
- .type _start,@function
-_start:
-#ifdef CONFIG_SMP
- #
- # If this is a secondary CPU (AP), then deal with that elsewhere
- #
- mov (CPUID),d3
- and CPUID_MASK,d3
- bne startup_secondary
-
- #
- # We're dealing with the primary CPU (BP) here, then.
- # Keep BP's D0,D1,D2 register for boot check.
- #
-
- # Set up the Boot IPI for each secondary CPU
- mov 0x1,a0
-loop_set_secondary_icr:
- mov a0,a1
- asl CROSS_ICR_CPU_SHIFT,a1
- add CROSS_GxICR(SMP_BOOT_IRQ,0),a1
- movhu (a1),d3
- or GxICR_ENABLE|GxICR_LEVEL_0,d3
- movhu d3,(a1)
- movhu (a1),d3 # flush
- inc a0
- cmp NR_CPUS,a0
- bne loop_set_secondary_icr
-#endif /* CONFIG_SMP */
-
- # save commandline pointer
- mov d0,a3
-
- # preload the PGD pointer register
- mov swapper_pg_dir,d0
- mov d0,(PTBR)
- clr d0
- movbu d0,(PIDR)
-
- # turn on the TLBs
- mov MMUCTR_IIV|MMUCTR_DIV,d0
- mov d0,(MMUCTR)
-#ifdef CONFIG_AM34_2
- mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
-#else
- mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
-#endif
- mov d0,(MMUCTR)
-
- # turn on AM33v2 exception handling mode and set the trap table base
- movhu (CPUP),d0
- or CPUP_EXM_AM33V2,d0
- movhu d0,(CPUP)
- mov CONFIG_INTERRUPT_VECTOR_BASE,d0
- mov d0,(TBR)
-
- # invalidate and enable both of the caches
-#ifdef CONFIG_SMP
- mov ECHCTR,a0
- clr d0
- mov d0,(a0)
-#endif
- mov CHCTR,a0
- clr d0
- movhu d0,(a0) # turn off first
- mov CHCTR_ICINV|CHCTR_DCINV,d0
- movhu d0,(a0)
- setlb
- mov (a0),d0
- btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy
- lne
-
-#ifdef CONFIG_MN10300_CACHE_ENABLED
-#ifdef CONFIG_MN10300_CACHE_WBACK
-#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
-#else
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
-#endif /* NOWRALLOC */
-#else
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
-#endif /* WBACK */
- movhu d0,(a0) # enable
-#endif /* ENABLED */
-
- # turn on RTS on the debug serial port if applicable
-#ifdef CONFIG_MN10300_UNIT_ASB2305
- bset UART_MCR_RTS,(ASB2305_DEBUG_MCR)
-#endif
-
- # clear the BSS area
- mov __bss_start,a0
- mov __bss_stop,a1
- clr d0
-bssclear:
- cmp a1,a0
- bge bssclear_end
- mov d0,(a0)
- inc4 a0
- bra bssclear
-bssclear_end:
-
- # retrieve the parameters (including command line) before we overwrite
- # them
- cmp 0xabadcafe,d1
- bne __no_parameters
-
-__copy_parameters:
- mov redboot_command_line,a0
- mov a0,a1
- add COMMAND_LINE_SIZE,a1
-1:
- movbu (a3),d0
- inc a3
- movbu d0,(a0)
- inc a0
- cmp a1,a0
- blt 1b
-
- mov redboot_platform_name,a0
- mov a0,a1
- add COMMAND_LINE_SIZE,a1
- mov d2,a3
-1:
- movbu (a3),d0
- inc a3
- movbu d0,(a0)
- inc a0
- cmp a1,a0
- blt 1b
-
-__no_parameters:
-
- # set up the registers with recognisable rubbish in them
- mov init_thread_union+THREAD_SIZE-12,sp
-
- mov 0xea01eaea,d0
- mov d0,(4,sp) # EPSW save area
- mov 0xea02eaea,d0
- mov d0,(8,sp) # PC save area
-
- mov 0xeb0060ed,d0
- mov d0,mdr
- mov 0xeb0061ed,d0
- mov d0,mdrq
- mov 0xeb0062ed,d0
- mov d0,mcrh
- mov 0xeb0063ed,d0
- mov d0,mcrl
- mov 0xeb0064ed,d0
- mov d0,mcvf
- mov 0xed0065ed,a3
- mov a3,usp
-
- mov 0xed00e0ed,e0
- mov 0xed00e1ed,e1
- mov 0xed00e2ed,e2
- mov 0xed00e3ed,e3
- mov 0xed00e4ed,e4
- mov 0xed00e5ed,e5
- mov 0xed00e6ed,e6
- mov 0xed00e7ed,e7
-
- mov 0xed00d0ed,d0
- mov 0xed00d1ed,d1
- mov 0xed00d2ed,d2
- mov 0xed00d3ed,d3
- mov 0xed00a0ed,a0
- mov 0xed00a1ed,a1
- mov 0xed00a2ed,a2
- mov 0,a3
-
- # set up the initial kernel stack
- SAVE_ALL
- mov 0xffffffff,d0
- mov d0,(REG_ORIG_D0,fp)
-
- # put different recognisable rubbish in the regs
- mov 0xfb0060ed,d0
- mov d0,mdr
- mov 0xfb0061ed,d0
- mov d0,mdrq
- mov 0xfb0062ed,d0
- mov d0,mcrh
- mov 0xfb0063ed,d0
- mov d0,mcrl
- mov 0xfb0064ed,d0
- mov d0,mcvf
- mov 0xfd0065ed,a0
- mov a0,usp
-
- mov 0xfd00e0ed,e0
- mov 0xfd00e1ed,e1
- mov 0xfd00e2ed,e2
- mov 0xfd00e3ed,e3
- mov 0xfd00e4ed,e4
- mov 0xfd00e5ed,e5
- mov 0xfd00e6ed,e6
- mov 0xfd00e7ed,e7
-
- mov 0xfd00d0ed,d0
- mov 0xfd00d1ed,d1
- mov 0xfd00d2ed,d2
- mov 0xfd00d3ed,d3
- mov 0xfd00a0ed,a0
- mov 0xfd00a1ed,a1
- mov 0xfd00a2ed,a2
-
- # we may be holding current in E2
-#ifdef CONFIG_MN10300_CURRENT_IN_E2
- mov init_task,e2
-#endif
-
- # initialise the processor and the unit
- call processor_init[],0
- call unit_init[],0
-
-#ifdef CONFIG_SMP
- # mark the primary CPU in cpu_boot_map
- mov cpu_boot_map,a0
- mov 0x1,d0
- mov d0,(a0)
-
- # signal each secondary CPU to begin booting
- mov 0x1,d2 # CPU ID
-
-loop_request_boot_secondary:
- mov d2,a0
- # send SMP_BOOT_IPI to secondary CPU
- asl CROSS_ICR_CPU_SHIFT,a0
- add CROSS_GxICR(SMP_BOOT_IRQ,0),a0
- movhu (a0),d0
- or GxICR_REQUEST|GxICR_DETECT,d0
- movhu d0,(a0)
- movhu (a0),d0 # flush
-
- # wait up to 100ms for AP's IPI to be received
- clr d3
-wait_on_secondary_boot:
- mov DELAY_TIME_BOOT_IPI,d0
- call __delay[],0
- inc d3
- mov cpu_boot_map,a0
- mov (a0),d0
- lsr d2,d0
- btst 0x1,d0
- bne 1f
- cmp TIME_OUT_COUNT_BOOT_IPI,d3
- bne wait_on_secondary_boot
-1:
- inc d2
- cmp NR_CPUS,d2
- bne loop_request_boot_secondary
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_GDBSTUB
- call gdbstub_init[],0
-
-#ifdef CONFIG_GDBSTUB_IMMEDIATE
- .globl __gdbstub_pause
-__gdbstub_pause:
- bra __gdbstub_pause
-#endif
-#endif
-
- jmp start_kernel
- .size _start,.-_start
-
-###############################################################################
-#
-# Secondary CPU boot point
-#
-###############################################################################
-#ifdef CONFIG_SMP
-startup_secondary:
- # preload the PGD pointer register
- mov swapper_pg_dir,d0
- mov d0,(PTBR)
- clr d0
- movbu d0,(PIDR)
-
- # turn on the TLBs
- mov MMUCTR_IIV|MMUCTR_DIV,d0
- mov d0,(MMUCTR)
-#ifdef CONFIG_AM34_2
- mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
-#else
- mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
-#endif
- mov d0,(MMUCTR)
-
- # turn on AM33v2 exception handling mode and set the trap table base
- movhu (CPUP),d0
- or CPUP_EXM_AM33V2,d0
- movhu d0,(CPUP)
-
- # set the interrupt vector table
- mov CONFIG_INTERRUPT_VECTOR_BASE,d0
- mov d0,(TBR)
-
- # invalidate and enable both of the caches
- mov ECHCTR,a0
- clr d0
- mov d0,(a0)
- mov CHCTR,a0
- clr d0
- movhu d0,(a0) # turn off first
- mov CHCTR_ICINV|CHCTR_DCINV,d0
- movhu d0,(a0)
- setlb
- mov (a0),d0
- btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
- lne
-
-#ifdef CONFIG_MN10300_CACHE_ENABLED
-#ifdef CONFIG_MN10300_CACHE_WBACK
-#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
-#else
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
-#endif /* !NOWRALLOC */
-#else
- mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
-#endif /* WBACK */
- movhu d0,(a0) # enable
-#endif /* ENABLED */
-
- # Clear the boot IPI interrupt for this CPU
- movhu (GxICR(SMP_BOOT_IRQ)),d0
- and ~GxICR_REQUEST,d0
- movhu d0,(GxICR(SMP_BOOT_IRQ))
- movhu (GxICR(SMP_BOOT_IRQ)),d0 # flush
-
- /* get stack */
- mov CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
- mov (CPUID),d0
- and CPUID_MASK,d0
- mulu CONFIG_BOOT_STACK_SIZE,d0
- sub d0,a0
- mov a0,sp
-
- # init interrupt for AP
- call smp_prepare_cpu_init[],0
-
- # mark this secondary CPU in cpu_boot_map
- mov (CPUID),d0
- mov 0x1,d1
- asl d0,d1
- mov cpu_boot_map,a0
- bset d1,(a0)
-
- or EPSW_IE|EPSW_IM_1,epsw # permit level 0 interrupts
- nop
- nop
-#ifdef CONFIG_MN10300_CACHE_WBACK
- # flush the local cache if it's in writeback mode
- call mn10300_local_dcache_flush_inv[],0
- setlb
- mov (CHCTR),d0
- btst CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
- lne
-#endif
-
- # now sleep waiting for further instructions
-secondary_sleep:
- mov CPUM_SLEEP,d0
- movhu d0,(CPUM)
- nop
- nop
- bra secondary_sleep
- .size startup_secondary,.-startup_secondary
-#endif /* CONFIG_SMP */
-
-###############################################################################
-#
-#
-#
-###############################################################################
-ENTRY(__head_end)
-
-/*
- * This is initialized to disallow all access to the low 2G region
- * - the high 2G region is managed directly by the MMU
- * - range 0x70000000-0x7C000000 are initialised for use by VMALLOC
- */
- .section .bss
- .balign PAGE_SIZE
-ENTRY(swapper_pg_dir)
- .space PTRS_PER_PGD*4
-
-/*
- * The page tables are initialized to only 8MB here - the final page
- * tables are set up later depending on memory size.
- */
-
- .balign PAGE_SIZE
-ENTRY(empty_zero_page)
- .space PAGE_SIZE
-
- .balign PAGE_SIZE
-ENTRY(large_page_table)
- .space PAGE_SIZE
-
- .balign PAGE_SIZE
-ENTRY(kernel_vmalloc_ptes)
- .space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4
diff --git a/arch/mn10300/kernel/internal.h b/arch/mn10300/kernel/internal.h
deleted file mode 100644
index 561785581f6c..000000000000
--- a/arch/mn10300/kernel/internal.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Internal definitions for the arch part of the core kernel
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <linux/irqreturn.h>
-
-struct clocksource;
-struct clock_event_device;
-
-/*
- * entry.S
- */
-extern void ret_from_fork(struct task_struct *) __attribute__((noreturn));
-extern void ret_from_kernel_thread(struct task_struct *) __attribute__((noreturn));
-
-/*
- * smp-low.S
- */
-#ifdef CONFIG_SMP
-extern void mn10300_low_ipi_handler(void);
-#endif
-
-/*
- * smp.c
- */
-#ifdef CONFIG_SMP
-extern void smp_jump_to_debugger(void);
-#endif
-
-/*
- * time.c
- */
-extern irqreturn_t local_timer_interrupt(void);
diff --git a/arch/mn10300/kernel/io.c b/arch/mn10300/kernel/io.c
deleted file mode 100644
index e96fdf6bb542..000000000000
--- a/arch/mn10300/kernel/io.c
+++ /dev/null
@@ -1,30 +0,0 @@
-/* MN10300 Misaligned multibyte-word I/O
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/io.h>
-
-/*
- * output data from a potentially misaligned buffer
- */
-void __outsl(unsigned long addr, const void *buffer, int count)
-{
- const unsigned char *buf = buffer;
- unsigned long val;
-
- while (count--) {
- memcpy(&val, buf, 4);
- outl(val, addr);
- buf += 4;
- }
-}
-EXPORT_SYMBOL(__outsl);
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
deleted file mode 100644
index c716437baa2c..000000000000
--- a/arch/mn10300/kernel/irq.c
+++ /dev/null
@@ -1,356 +0,0 @@
-/* MN10300 Arch-specific interrupt handling
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/seq_file.h>
-#include <linux/cpumask.h>
-#include <asm/setup.h>
-#include <asm/serial-regs.h>
-
-unsigned long __mn10300_irq_enabled_epsw[NR_CPUS] __cacheline_aligned_in_smp = {
- [0 ... NR_CPUS - 1] = EPSW_IE | EPSW_IM_7
-};
-EXPORT_SYMBOL(__mn10300_irq_enabled_epsw);
-
-#ifdef CONFIG_SMP
-static char irq_affinity_online[NR_IRQS] = {
- [0 ... NR_IRQS - 1] = 0
-};
-
-#define NR_IRQ_WORDS ((NR_IRQS + 31) / 32)
-static unsigned long irq_affinity_request[NR_IRQ_WORDS] = {
- [0 ... NR_IRQ_WORDS - 1] = 0
-};
-#endif /* CONFIG_SMP */
-
-atomic_t irq_err_count;
-
-/*
- * MN10300 interrupt controller operations
- */
-static void mn10300_cpupic_ack(struct irq_data *d)
-{
- unsigned int irq = d->irq;
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
- GxICR_u8(irq) = GxICR_DETECT;
- tmp = GxICR(irq);
- arch_local_irq_restore(flags);
-}
-
-static void __mask_and_set_icr(unsigned int irq,
- unsigned int mask, unsigned int set)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & mask) | set;
- tmp = GxICR(irq);
- arch_local_irq_restore(flags);
-}
-
-static void mn10300_cpupic_mask(struct irq_data *d)
-{
- __mask_and_set_icr(d->irq, GxICR_LEVEL, 0);
-}
-
-static void mn10300_cpupic_mask_ack(struct irq_data *d)
-{
- unsigned int irq = d->irq;
-#ifdef CONFIG_SMP
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
-
- if (!test_and_clear_bit(irq, irq_affinity_request)) {
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
- tmp = GxICR(irq);
- } else {
- u16 tmp2;
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL);
- tmp2 = GxICR(irq);
-
- irq_affinity_online[irq] =
- cpumask_any_and(irq_data_get_affinity_mask(d),
- cpu_online_mask);
- CROSS_GxICR(irq, irq_affinity_online[irq]) =
- (tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT;
- tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
- }
-
- arch_local_irq_restore(flags);
-#else /* CONFIG_SMP */
- __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_DETECT);
-#endif /* CONFIG_SMP */
-}
-
-static void mn10300_cpupic_unmask(struct irq_data *d)
-{
- __mask_and_set_icr(d->irq, GxICR_LEVEL, GxICR_ENABLE);
-}
-
-static void mn10300_cpupic_unmask_clear(struct irq_data *d)
-{
- unsigned int irq = d->irq;
- /* the MN10300 PIC latches its interrupt request bit, even after the
- * device has ceased to assert its interrupt line and the interrupt
- * channel has been disabled in the PIC, so for level-triggered
- * interrupts we need to clear the request bit when we re-enable */
-#ifdef CONFIG_SMP
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
-
- if (!test_and_clear_bit(irq, irq_affinity_request)) {
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
- tmp = GxICR(irq);
- } else {
- tmp = GxICR(irq);
-
- irq_affinity_online[irq] = cpumask_any_and(irq_data_get_affinity_mask(d),
- cpu_online_mask);
- CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
- tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
- }
-
- arch_local_irq_restore(flags);
-#else /* CONFIG_SMP */
- __mask_and_set_icr(irq, GxICR_LEVEL, GxICR_ENABLE | GxICR_DETECT);
-#endif /* CONFIG_SMP */
-}
-
-#ifdef CONFIG_SMP
-static int
-mn10300_cpupic_setaffinity(struct irq_data *d, const struct cpumask *mask,
- bool force)
-{
- unsigned long flags;
-
- flags = arch_local_cli_save();
- set_bit(d->irq, irq_affinity_request);
- arch_local_irq_restore(flags);
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * MN10300 PIC level-triggered IRQ handling.
- *
- * The PIC has no 'ACK' function per se. It is possible to clear individual
- * channel latches, but each latch relatches whether or not the channel is
- * masked, so we need to clear the latch when we unmask the channel.
- *
- * Also for this reason, we don't supply an ack() op (it's unused anyway if
- * mask_ack() is provided), and mask_ack() just masks.
- */
-static struct irq_chip mn10300_cpu_pic_level = {
- .name = "cpu_l",
- .irq_disable = mn10300_cpupic_mask,
- .irq_enable = mn10300_cpupic_unmask_clear,
- .irq_ack = NULL,
- .irq_mask = mn10300_cpupic_mask,
- .irq_mask_ack = mn10300_cpupic_mask,
- .irq_unmask = mn10300_cpupic_unmask_clear,
-#ifdef CONFIG_SMP
- .irq_set_affinity = mn10300_cpupic_setaffinity,
-#endif
-};
-
-/*
- * MN10300 PIC edge-triggered IRQ handling.
- *
- * We use the latch clearing function of the PIC as the 'ACK' function.
- */
-static struct irq_chip mn10300_cpu_pic_edge = {
- .name = "cpu_e",
- .irq_disable = mn10300_cpupic_mask,
- .irq_enable = mn10300_cpupic_unmask,
- .irq_ack = mn10300_cpupic_ack,
- .irq_mask = mn10300_cpupic_mask,
- .irq_mask_ack = mn10300_cpupic_mask_ack,
- .irq_unmask = mn10300_cpupic_unmask,
-#ifdef CONFIG_SMP
- .irq_set_affinity = mn10300_cpupic_setaffinity,
-#endif
-};
-
-/*
- * 'what should we do if we get a hw irq event on an illegal vector'.
- * each architecture has to answer this themselves.
- */
-void ack_bad_irq(int irq)
-{
- printk(KERN_WARNING "unexpected IRQ trap at vector %02x\n", irq);
-}
-
-/*
- * change the level at which an IRQ executes
- * - must not be called whilst interrupts are being processed!
- */
-void set_intr_level(int irq, u16 level)
-{
- BUG_ON(in_interrupt());
-
- __mask_and_set_icr(irq, GxICR_ENABLE, level);
-}
-
-/*
- * mark an interrupt to be ACK'd after interrupt handlers have been run rather
- * than before
- */
-void mn10300_set_lateack_irq_type(int irq)
-{
- irq_set_chip_and_handler(irq, &mn10300_cpu_pic_level,
- handle_level_irq);
-}
-
-/*
- * initialise the interrupt system
- */
-void __init init_IRQ(void)
-{
- int irq;
-
- for (irq = 0; irq < NR_IRQS; irq++)
- if (irq_get_chip(irq) == &no_irq_chip)
- /* due to the PIC latching interrupt requests, even
- * when the IRQ is disabled, IRQ_PENDING is superfluous
- * and we can use handle_level_irq() for edge-triggered
- * interrupts */
- irq_set_chip_and_handler(irq, &mn10300_cpu_pic_edge,
- handle_level_irq);
-
- unit_init_IRQ();
-}
-
-/*
- * handle normal device IRQs
- */
-asmlinkage void do_IRQ(void)
-{
- unsigned long sp, epsw, irq_disabled_epsw, old_irq_enabled_epsw;
- unsigned int cpu_id = smp_processor_id();
- int irq;
-
- sp = current_stack_pointer();
- BUG_ON(sp - (sp & ~(THREAD_SIZE - 1)) < STACK_WARN);
-
- /* make sure local_irq_enable() doesn't muck up the interrupt priority
- * setting in EPSW */
- old_irq_enabled_epsw = __mn10300_irq_enabled_epsw[cpu_id];
- local_save_flags(epsw);
- __mn10300_irq_enabled_epsw[cpu_id] = EPSW_IE | (EPSW_IM & epsw);
- irq_disabled_epsw = EPSW_IE | MN10300_CLI_LEVEL;
-
-#ifdef CONFIG_MN10300_WD_TIMER
- __IRQ_STAT(cpu_id, __irq_count)++;
-#endif
-
- irq_enter();
-
- for (;;) {
- /* ask the interrupt controller for the next IRQ to process
- * - the result we get depends on EPSW.IM
- */
- irq = IAGR & IAGR_GN;
- if (!irq)
- break;
-
- local_irq_restore(irq_disabled_epsw);
-
- generic_handle_irq(irq >> 2);
-
- /* restore IRQ controls for IAGR access */
- local_irq_restore(epsw);
- }
-
- __mn10300_irq_enabled_epsw[cpu_id] = old_irq_enabled_epsw;
-
- irq_exit();
-}
-
-/*
- * Display interrupt management information through /proc/interrupts
- */
-int arch_show_interrupts(struct seq_file *p, int prec)
-{
-#ifdef CONFIG_MN10300_WD_TIMER
- int j;
-
- seq_printf(p, "%*s: ", prec, "NMI");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", nmi_count(j));
- seq_putc(p, '\n');
-#endif
-
- seq_printf(p, "%*s: ", prec, "ERR");
- seq_printf(p, "%10u\n", atomic_read(&irq_err_count));
- return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-void migrate_irqs(void)
-{
- int irq;
- unsigned int self, new;
- unsigned long flags;
-
- self = smp_processor_id();
- for (irq = 0; irq < NR_IRQS; irq++) {
- struct irq_data *data = irq_get_irq_data(irq);
- struct cpumask *mask = irq_data_get_affinity_mask(data);
-
- if (irqd_is_per_cpu(data))
- continue;
-
- if (cpumask_test_cpu(self, mask) &&
- !cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
- int cpu_id;
- cpu_id = cpumask_first(cpu_online_mask);
- cpumask_set_cpu(cpu_id, mask);
- }
- /* We need to operate irq_affinity_online atomically. */
- arch_local_cli_save(flags);
- if (irq_affinity_online[irq] == self) {
- u16 x, tmp;
-
- x = GxICR(irq);
- GxICR(irq) = x & GxICR_LEVEL;
- tmp = GxICR(irq);
-
- new = cpumask_any_and(mask, cpu_online_mask);
- irq_affinity_online[irq] = new;
-
- CROSS_GxICR(irq, new) =
- (x & GxICR_LEVEL) | GxICR_DETECT;
- tmp = CROSS_GxICR(irq, new);
-
- x &= GxICR_LEVEL | GxICR_ENABLE;
- if (GxICR(irq) & GxICR_REQUEST)
- x |= GxICR_REQUEST | GxICR_DETECT;
- CROSS_GxICR(irq, new) = x;
- tmp = CROSS_GxICR(irq, new);
- }
- arch_local_irq_restore(flags);
- }
-}
-#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mn10300/kernel/kgdb.c b/arch/mn10300/kernel/kgdb.c
deleted file mode 100644
index 2d7986c386fe..000000000000
--- a/arch/mn10300/kernel/kgdb.c
+++ /dev/null
@@ -1,502 +0,0 @@
-/* kgdb support for MN10300
- *
- * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <linux/slab.h>
-#include <linux/ptrace.h>
-#include <linux/kgdb.h>
-#include <linux/uaccess.h>
-#include <unit/leds.h>
-#include <unit/serial.h>
-#include <asm/debugger.h>
-#include <asm/serial-regs.h>
-#include "internal.h"
-
-/*
- * Software single-stepping breakpoint save (used by __switch_to())
- */
-static struct thread_info *kgdb_sstep_thread;
-u8 *kgdb_sstep_bp_addr[2];
-u8 kgdb_sstep_bp[2];
-
-/*
- * Copy kernel exception frame registers to the GDB register file
- */
-void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
- unsigned long ssp = (unsigned long) (regs + 1);
-
- gdb_regs[GDB_FR_D0] = regs->d0;
- gdb_regs[GDB_FR_D1] = regs->d1;
- gdb_regs[GDB_FR_D2] = regs->d2;
- gdb_regs[GDB_FR_D3] = regs->d3;
- gdb_regs[GDB_FR_A0] = regs->a0;
- gdb_regs[GDB_FR_A1] = regs->a1;
- gdb_regs[GDB_FR_A2] = regs->a2;
- gdb_regs[GDB_FR_A3] = regs->a3;
- gdb_regs[GDB_FR_SP] = (regs->epsw & EPSW_nSL) ? regs->sp : ssp;
- gdb_regs[GDB_FR_PC] = regs->pc;
- gdb_regs[GDB_FR_MDR] = regs->mdr;
- gdb_regs[GDB_FR_EPSW] = regs->epsw;
- gdb_regs[GDB_FR_LIR] = regs->lir;
- gdb_regs[GDB_FR_LAR] = regs->lar;
- gdb_regs[GDB_FR_MDRQ] = regs->mdrq;
- gdb_regs[GDB_FR_E0] = regs->e0;
- gdb_regs[GDB_FR_E1] = regs->e1;
- gdb_regs[GDB_FR_E2] = regs->e2;
- gdb_regs[GDB_FR_E3] = regs->e3;
- gdb_regs[GDB_FR_E4] = regs->e4;
- gdb_regs[GDB_FR_E5] = regs->e5;
- gdb_regs[GDB_FR_E6] = regs->e6;
- gdb_regs[GDB_FR_E7] = regs->e7;
- gdb_regs[GDB_FR_SSP] = ssp;
- gdb_regs[GDB_FR_MSP] = 0;
- gdb_regs[GDB_FR_USP] = regs->sp;
- gdb_regs[GDB_FR_MCRH] = regs->mcrh;
- gdb_regs[GDB_FR_MCRL] = regs->mcrl;
- gdb_regs[GDB_FR_MCVF] = regs->mcvf;
- gdb_regs[GDB_FR_DUMMY0] = 0;
- gdb_regs[GDB_FR_DUMMY1] = 0;
- gdb_regs[GDB_FR_FS0] = 0;
-}
-
-/*
- * Extracts kernel SP/PC values understandable by gdb from the values
- * saved by switch_to().
- */
-void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
-{
- gdb_regs[GDB_FR_SSP] = p->thread.sp;
- gdb_regs[GDB_FR_PC] = p->thread.pc;
- gdb_regs[GDB_FR_A3] = p->thread.a3;
- gdb_regs[GDB_FR_USP] = p->thread.usp;
- gdb_regs[GDB_FR_FPCR] = p->thread.fpu_state.fpcr;
-}
-
-/*
- * Fill kernel exception frame registers from the GDB register file
- */
-void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
-{
- regs->d0 = gdb_regs[GDB_FR_D0];
- regs->d1 = gdb_regs[GDB_FR_D1];
- regs->d2 = gdb_regs[GDB_FR_D2];
- regs->d3 = gdb_regs[GDB_FR_D3];
- regs->a0 = gdb_regs[GDB_FR_A0];
- regs->a1 = gdb_regs[GDB_FR_A1];
- regs->a2 = gdb_regs[GDB_FR_A2];
- regs->a3 = gdb_regs[GDB_FR_A3];
- regs->sp = gdb_regs[GDB_FR_SP];
- regs->pc = gdb_regs[GDB_FR_PC];
- regs->mdr = gdb_regs[GDB_FR_MDR];
- regs->epsw = gdb_regs[GDB_FR_EPSW];
- regs->lir = gdb_regs[GDB_FR_LIR];
- regs->lar = gdb_regs[GDB_FR_LAR];
- regs->mdrq = gdb_regs[GDB_FR_MDRQ];
- regs->e0 = gdb_regs[GDB_FR_E0];
- regs->e1 = gdb_regs[GDB_FR_E1];
- regs->e2 = gdb_regs[GDB_FR_E2];
- regs->e3 = gdb_regs[GDB_FR_E3];
- regs->e4 = gdb_regs[GDB_FR_E4];
- regs->e5 = gdb_regs[GDB_FR_E5];
- regs->e6 = gdb_regs[GDB_FR_E6];
- regs->e7 = gdb_regs[GDB_FR_E7];
- regs->sp = gdb_regs[GDB_FR_SSP];
- /* gdb_regs[GDB_FR_MSP]; */
- // regs->usp = gdb_regs[GDB_FR_USP];
- regs->mcrh = gdb_regs[GDB_FR_MCRH];
- regs->mcrl = gdb_regs[GDB_FR_MCRL];
- regs->mcvf = gdb_regs[GDB_FR_MCVF];
- /* gdb_regs[GDB_FR_DUMMY0]; */
- /* gdb_regs[GDB_FR_DUMMY1]; */
-
- // regs->fpcr = gdb_regs[GDB_FR_FPCR];
- // regs->fs0 = gdb_regs[GDB_FR_FS0];
-}
-
-struct kgdb_arch arch_kgdb_ops = {
- .gdb_bpt_instr = { 0xff },
- .flags = KGDB_HW_BREAKPOINT,
-};
-
-static const unsigned char mn10300_kgdb_insn_sizes[256] =
-{
- /* 1 2 3 4 5 6 7 8 9 a b c d e f */
- 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
- 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
- 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
- 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */
-};
-
-/*
- * Attempt to emulate single stepping by means of breakpoint instructions.
- * Although there is a single-step trace flag in EPSW, its use is not
- * sufficiently documented and is only intended for use with the JTAG debugger.
- */
-static int kgdb_arch_do_singlestep(struct pt_regs *regs)
-{
- unsigned long arg;
- unsigned size;
- u8 *pc = (u8 *)regs->pc, *sp = (u8 *)(regs + 1), cur;
- u8 *x = NULL, *y = NULL;
- int ret;
-
- ret = probe_kernel_read(&cur, pc, 1);
- if (ret < 0)
- return ret;
-
- size = mn10300_kgdb_insn_sizes[cur];
- if (size > 0) {
- x = pc + size;
- goto set_x;
- }
-
- switch (cur) {
- /* Bxx (d8,PC) */
- case 0xc0 ... 0xca:
- ret = probe_kernel_read(&arg, pc + 1, 1);
- if (ret < 0)
- return ret;
- x = pc + 2;
- if (arg >= 0 && arg <= 2)
- goto set_x;
- y = pc + (s8)arg;
- goto set_x_and_y;
-
- /* LXX (d8,PC) */
- case 0xd0 ... 0xda:
- x = pc + 1;
- if (regs->pc == regs->lar)
- goto set_x;
- y = (u8 *)regs->lar;
- goto set_x_and_y;
-
- /* SETLB - loads the next four bytes into the LIR register
- * (which mustn't include a breakpoint instruction) */
- case 0xdb:
- x = pc + 5;
- goto set_x;
-
- /* JMP (d16,PC) or CALL (d16,PC) */
- case 0xcc:
- case 0xcd:
- ret = probe_kernel_read(&arg, pc + 1, 2);
- if (ret < 0)
- return ret;
- x = pc + (s16)arg;
- goto set_x;
-
- /* JMP (d32,PC) or CALL (d32,PC) */
- case 0xdc:
- case 0xdd:
- ret = probe_kernel_read(&arg, pc + 1, 4);
- if (ret < 0)
- return ret;
- x = pc + (s32)arg;
- goto set_x;
-
- /* RETF */
- case 0xde:
- x = (u8 *)regs->mdr;
- goto set_x;
-
- /* RET */
- case 0xdf:
- ret = probe_kernel_read(&arg, pc + 2, 1);
- if (ret < 0)
- return ret;
- ret = probe_kernel_read(&x, sp + (s8)arg, 4);
- if (ret < 0)
- return ret;
- goto set_x;
-
- case 0xf0:
- ret = probe_kernel_read(&cur, pc + 1, 1);
- if (ret < 0)
- return ret;
-
- if (cur >= 0xf0 && cur <= 0xf7) {
- /* JMP (An) / CALLS (An) */
- switch (cur & 3) {
- case 0: x = (u8 *)regs->a0; break;
- case 1: x = (u8 *)regs->a1; break;
- case 2: x = (u8 *)regs->a2; break;
- case 3: x = (u8 *)regs->a3; break;
- }
- goto set_x;
- } else if (cur == 0xfc) {
- /* RETS */
- ret = probe_kernel_read(&x, sp, 4);
- if (ret < 0)
- return ret;
- goto set_x;
- } else if (cur == 0xfd) {
- /* RTI */
- ret = probe_kernel_read(&x, sp + 4, 4);
- if (ret < 0)
- return ret;
- goto set_x;
- } else {
- x = pc + 2;
- goto set_x;
- }
- break;
-
- /* potential 3-byte conditional branches */
- case 0xf8:
- ret = probe_kernel_read(&cur, pc + 1, 1);
- if (ret < 0)
- return ret;
- x = pc + 3;
-
- if (cur >= 0xe8 && cur <= 0xeb) {
- ret = probe_kernel_read(&arg, pc + 2, 1);
- if (ret < 0)
- return ret;
- if (arg >= 0 && arg <= 3)
- goto set_x;
- y = pc + (s8)arg;
- goto set_x_and_y;
- }
- goto set_x;
-
- case 0xfa:
- ret = probe_kernel_read(&cur, pc + 1, 1);
- if (ret < 0)
- return ret;
-
- if (cur == 0xff) {
- /* CALLS (d16,PC) */
- ret = probe_kernel_read(&arg, pc + 2, 2);
- if (ret < 0)
- return ret;
- x = pc + (s16)arg;
- goto set_x;
- }
-
- x = pc + 4;
- goto set_x;
-
- case 0xfc:
- ret = probe_kernel_read(&cur, pc + 1, 1);
- if (ret < 0)
- return ret;
-
- if (cur == 0xff) {
- /* CALLS (d32,PC) */
- ret = probe_kernel_read(&arg, pc + 2, 4);
- if (ret < 0)
- return ret;
- x = pc + (s32)arg;
- goto set_x;
- }
-
- x = pc + 6;
- goto set_x;
- }
-
- return 0;
-
-set_x:
- kgdb_sstep_bp_addr[0] = x;
- kgdb_sstep_bp_addr[1] = NULL;
- ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
- if (ret < 0)
- return ret;
- ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
- if (ret < 0)
- return ret;
- kgdb_sstep_thread = current_thread_info();
- debugger_local_cache_flushinv_one(x);
- return ret;
-
-set_x_and_y:
- kgdb_sstep_bp_addr[0] = x;
- kgdb_sstep_bp_addr[1] = y;
- ret = probe_kernel_read(&kgdb_sstep_bp[0], x, 1);
- if (ret < 0)
- return ret;
- ret = probe_kernel_read(&kgdb_sstep_bp[1], y, 1);
- if (ret < 0)
- return ret;
- ret = probe_kernel_write(x, &arch_kgdb_ops.gdb_bpt_instr, 1);
- if (ret < 0)
- return ret;
- ret = probe_kernel_write(y, &arch_kgdb_ops.gdb_bpt_instr, 1);
- if (ret < 0) {
- probe_kernel_write(kgdb_sstep_bp_addr[0],
- &kgdb_sstep_bp[0], 1);
- } else {
- kgdb_sstep_thread = current_thread_info();
- }
- debugger_local_cache_flushinv_one(x);
- debugger_local_cache_flushinv_one(y);
- return ret;
-}
-
-/*
- * Remove emplaced single-step breakpoints, returning true if we hit one of
- * them.
- */
-static bool kgdb_arch_undo_singlestep(struct pt_regs *regs)
-{
- bool hit = false;
- u8 *x = kgdb_sstep_bp_addr[0], *y = kgdb_sstep_bp_addr[1];
- u8 opcode;
-
- if (kgdb_sstep_thread == current_thread_info()) {
- if (x) {
- if (x == (u8 *)regs->pc)
- hit = true;
- if (probe_kernel_read(&opcode, x,
- 1) < 0 ||
- opcode != 0xff)
- BUG();
- probe_kernel_write(x, &kgdb_sstep_bp[0], 1);
- debugger_local_cache_flushinv_one(x);
- }
- if (y) {
- if (y == (u8 *)regs->pc)
- hit = true;
- if (probe_kernel_read(&opcode, y,
- 1) < 0 ||
- opcode != 0xff)
- BUG();
- probe_kernel_write(y, &kgdb_sstep_bp[1], 1);
- debugger_local_cache_flushinv_one(y);
- }
- }
-
- kgdb_sstep_bp_addr[0] = NULL;
- kgdb_sstep_bp_addr[1] = NULL;
- kgdb_sstep_thread = NULL;
- return hit;
-}
-
-/*
- * Catch a single-step-pending thread being deleted and make sure the global
- * single-step state is cleared. At this point the breakpoints should have
- * been removed by __switch_to().
- */
-void arch_release_thread_stack(unsigned long *stack)
-{
- struct thread_info *ti = (void *)stack;
- if (kgdb_sstep_thread == ti) {
- kgdb_sstep_thread = NULL;
-
- /* However, we may now be running in degraded mode, with most
- * of the CPUs disabled until such a time as KGDB is reentered,
- * so force immediate reentry */
- kgdb_breakpoint();
- }
-}
-
-/*
- * Handle unknown packets and [CcsDk] packets
- * - at this point breakpoints have been installed
- */
-int kgdb_arch_handle_exception(int vector, int signo, int err_code,
- char *remcom_in_buffer, char *remcom_out_buffer,
- struct pt_regs *regs)
-{
- long addr;
- char *ptr;
-
- switch (remcom_in_buffer[0]) {
- case 'c':
- case 's':
- /* try to read optional parameter, pc unchanged if no parm */
- ptr = &remcom_in_buffer[1];
- if (kgdb_hex2long(&ptr, &addr))
- regs->pc = addr;
- case 'D':
- case 'k':
- atomic_set(&kgdb_cpu_doing_single_step, -1);
-
- if (remcom_in_buffer[0] == 's') {
- kgdb_arch_do_singlestep(regs);
- kgdb_single_step = 1;
- atomic_set(&kgdb_cpu_doing_single_step,
- raw_smp_processor_id());
- }
- return 0;
- }
- return -1; /* this means that we do not want to exit from the handler */
-}
-
-/*
- * Handle event interception
- * - returns 0 if the exception should be skipped, -ERROR otherwise.
- */
-int debugger_intercept(enum exception_code excep, int signo, int si_code,
- struct pt_regs *regs)
-{
- int ret;
-
- if (kgdb_arch_undo_singlestep(regs)) {
- excep = EXCEP_TRAP;
- signo = SIGTRAP;
- si_code = TRAP_TRACE;
- }
-
- ret = kgdb_handle_exception(excep, signo, si_code, regs);
-
- debugger_local_cache_flushinv();
-
- return ret;
-}
-
-/*
- * Determine if we've hit a debugger special breakpoint
- */
-int at_debugger_breakpoint(struct pt_regs *regs)
-{
- return regs->pc == (unsigned long)&__arch_kgdb_breakpoint;
-}
-
-/*
- * Initialise kgdb
- */
-int kgdb_arch_init(void)
-{
- return 0;
-}
-
-/*
- * Do something, perhaps, but don't know what.
- */
-void kgdb_arch_exit(void)
-{
-}
-
-#ifdef CONFIG_SMP
-void debugger_nmi_interrupt(struct pt_regs *regs, enum exception_code code)
-{
- kgdb_nmicallback(arch_smp_processor_id(), regs);
- debugger_local_cache_flushinv();
-}
-
-void kgdb_roundup_cpus(unsigned long flags)
-{
- smp_jump_to_debugger();
-}
-#endif
diff --git a/arch/mn10300/kernel/kprobes.c b/arch/mn10300/kernel/kprobes.c
deleted file mode 100644
index 0311a7fcea16..000000000000
--- a/arch/mn10300/kernel/kprobes.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/* MN10300 Kernel probes implementation
- *
- * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Licence as published by
- * the Free Software Foundation; either version 2 of the Licence, 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 Licence for more details.
- *
- * You should have received a copy of the GNU General Public Licence
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-#include <linux/kprobes.h>
-#include <linux/ptrace.h>
-#include <linux/spinlock.h>
-#include <linux/preempt.h>
-#include <linux/kdebug.h>
-#include <asm/cacheflush.h>
-
-struct kretprobe_blackpoint kretprobe_blacklist[] = { { NULL, NULL } };
-const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
-
-/* kprobe_status settings */
-#define KPROBE_HIT_ACTIVE 0x00000001
-#define KPROBE_HIT_SS 0x00000002
-
-static struct kprobe *cur_kprobe;
-static unsigned long cur_kprobe_orig_pc;
-static unsigned long cur_kprobe_next_pc;
-static int cur_kprobe_ss_flags;
-static unsigned long kprobe_status;
-static kprobe_opcode_t cur_kprobe_ss_buf[MAX_INSN_SIZE + 2];
-static unsigned long cur_kprobe_bp_addr;
-
-DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
-
-
-/* singlestep flag bits */
-#define SINGLESTEP_BRANCH 1
-#define SINGLESTEP_PCREL 2
-
-#define READ_BYTE(p, valp) \
- do { *(u8 *)(valp) = *(u8 *)(p); } while (0)
-
-#define READ_WORD16(p, valp) \
- do { \
- READ_BYTE((p), (valp)); \
- READ_BYTE((u8 *)(p) + 1, (u8 *)(valp) + 1); \
- } while (0)
-
-#define READ_WORD32(p, valp) \
- do { \
- READ_BYTE((p), (valp)); \
- READ_BYTE((u8 *)(p) + 1, (u8 *)(valp) + 1); \
- READ_BYTE((u8 *)(p) + 2, (u8 *)(valp) + 2); \
- READ_BYTE((u8 *)(p) + 3, (u8 *)(valp) + 3); \
- } while (0)
-
-
-static const u8 mn10300_insn_sizes[256] =
-{
- /* 1 2 3 4 5 6 7 8 9 a b c d e f */
- 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, /* 0 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 1 */
- 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, /* 2 */
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, /* 3 */
- 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, /* 4 */
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, /* 5 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6 */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 8 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* 9 */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* a */
- 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, /* b */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, /* c */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d */
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* e */
- 0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1 /* f */
-};
-
-#define LT (1 << 0)
-#define GT (1 << 1)
-#define GE (1 << 2)
-#define LE (1 << 3)
-#define CS (1 << 4)
-#define HI (1 << 5)
-#define CC (1 << 6)
-#define LS (1 << 7)
-#define EQ (1 << 8)
-#define NE (1 << 9)
-#define RA (1 << 10)
-#define VC (1 << 11)
-#define VS (1 << 12)
-#define NC (1 << 13)
-#define NS (1 << 14)
-
-static const u16 cond_table[] = {
- /* V C N Z */
- /* 0 0 0 0 */ (NE | NC | CC | VC | GE | GT | HI),
- /* 0 0 0 1 */ (EQ | NC | CC | VC | GE | LE | LS),
- /* 0 0 1 0 */ (NE | NS | CC | VC | LT | LE | HI),
- /* 0 0 1 1 */ (EQ | NS | CC | VC | LT | LE | LS),
- /* 0 1 0 0 */ (NE | NC | CS | VC | GE | GT | LS),
- /* 0 1 0 1 */ (EQ | NC | CS | VC | GE | LE | LS),
- /* 0 1 1 0 */ (NE | NS | CS | VC | LT | LE | LS),
- /* 0 1 1 1 */ (EQ | NS | CS | VC | LT | LE | LS),
- /* 1 0 0 0 */ (NE | NC | CC | VS | LT | LE | HI),
- /* 1 0 0 1 */ (EQ | NC | CC | VS | LT | LE | LS),
- /* 1 0 1 0 */ (NE | NS | CC | VS | GE | GT | HI),
- /* 1 0 1 1 */ (EQ | NS | CC | VS | GE | LE | LS),
- /* 1 1 0 0 */ (NE | NC | CS | VS | LT | LE | LS),
- /* 1 1 0 1 */ (EQ | NC | CS | VS | LT | LE | LS),
- /* 1 1 1 0 */ (NE | NS | CS | VS | GE | GT | LS),
- /* 1 1 1 1 */ (EQ | NS | CS | VS | GE | LE | LS),
-};
-
-/*
- * Calculate what the PC will be after executing next instruction
- */
-static unsigned find_nextpc(struct pt_regs *regs, int *flags)
-{
- unsigned size;
- s8 x8;
- s16 x16;
- s32 x32;
- u8 opc, *pc, *sp, *next;
-
- next = 0;
- *flags = SINGLESTEP_PCREL;
-
- pc = (u8 *) regs->pc;
- sp = (u8 *) (regs + 1);
- opc = *pc;
-
- size = mn10300_insn_sizes[opc];
- if (size > 0) {
- next = pc + size;
- } else {
- switch (opc) {
- /* Bxx (d8,PC) */
- case 0xc0 ... 0xca:
- x8 = 2;
- if (cond_table[regs->epsw & 0xf] & (1 << (opc & 0xf)))
- x8 = (s8)pc[1];
- next = pc + x8;
- *flags |= SINGLESTEP_BRANCH;
- break;
-
- /* JMP (d16,PC) or CALL (d16,PC) */
- case 0xcc:
- case 0xcd:
- READ_WORD16(pc + 1, &x16);
- next = pc + x16;
- *flags |= SINGLESTEP_BRANCH;
- break;
-
- /* JMP (d32,PC) or CALL (d32,PC) */
- case 0xdc:
- case 0xdd:
- READ_WORD32(pc + 1, &x32);
- next = pc + x32;
- *flags |= SINGLESTEP_BRANCH;
- break;
-
- /* RETF */
- case 0xde:
- next = (u8 *)regs->mdr;
- *flags &= ~SINGLESTEP_PCREL;
- *flags |= SINGLESTEP_BRANCH;
- break;
-
- /* RET */
- case 0xdf:
- sp += pc[2];
- READ_WORD32(sp, &x32);
- next = (u8 *)x32;
- *flags &= ~SINGLESTEP_PCREL;
- *flags |= SINGLESTEP_BRANCH;
- break;
-
- case 0xf0:
- next = pc + 2;
- opc = pc[1];
- if (opc >= 0xf0 && opc <= 0xf7) {
- /* JMP (An) / CALLS (An) */
- switch (opc & 3) {
- case 0:
- next = (u8 *)regs->a0;
- break;
- case 1:
- next = (u8 *)regs->a1;
- break;
- case 2:
- next = (u8 *)regs->a2;
- break;
- case 3:
- next = (u8 *)regs->a3;
- break;
- }
- *flags &= ~SINGLESTEP_PCREL;
- *flags |= SINGLESTEP_BRANCH;
- } else if (opc == 0xfc) {
- /* RETS */
- READ_WORD32(sp, &x32);
- next = (u8 *)x32;
- *flags &= ~SINGLESTEP_PCREL;
- *flags |= SINGLESTEP_BRANCH;
- } else if (opc == 0xfd) {
- /* RTI */
- READ_WORD32(sp + 4, &x32);
- next = (u8 *)x32;
- *flags &= ~SINGLESTEP_PCREL;
- *flags |= SINGLESTEP_BRANCH;
- }
- break;
-
- /* potential 3-byte conditional branches */
- case 0xf8:
- next = pc + 3;
- opc = pc[1];
- if (opc >= 0xe8 && opc <= 0xeb &&
- (cond_table[regs->epsw & 0xf] &
- (1 << ((opc & 0xf) + 3)))
- ) {
- READ_BYTE(pc+2, &x8);
- next = pc + x8;
- *flags |= SINGLESTEP_BRANCH;
- }
- break;
-
- case 0xfa:
- if (pc[1] == 0xff) {
- /* CALLS (d16,PC) */
- READ_WORD16(pc + 2, &x16);
- next = pc + x16;
- } else
- next = pc + 4;
- *flags |= SINGLESTEP_BRANCH;
- break;
-
- case 0xfc:
- x32 = 6;
- if (pc[1] == 0xff) {
- /* CALLS (d32,PC) */
- READ_WORD32(pc + 2, &x32);
- }
- next = pc + x32;
- *flags |= SINGLESTEP_BRANCH;
- break;
- /* LXX (d8,PC) */
- /* SETLB - loads the next four bytes into the LIR reg */
- case 0xd0 ... 0xda:
- case 0xdb:
- panic("Can't singlestep Lxx/SETLB\n");
- break;
- }
- }
- return (unsigned)next;
-
-}
-
-/*
- * set up out of place singlestep of some branching instructions
- */
-static unsigned __kprobes singlestep_branch_setup(struct pt_regs *regs)
-{
- u8 opc, *pc, *sp, *next;
-
- next = NULL;
- pc = (u8 *) regs->pc;
- sp = (u8 *) (regs + 1);
-
- switch (pc[0]) {
- case 0xc0 ... 0xca: /* Bxx (d8,PC) */
- case 0xcc: /* JMP (d16,PC) */
- case 0xdc: /* JMP (d32,PC) */
- case 0xf8: /* Bxx (d8,PC) 3-byte version */
- /* don't really need to do anything except cause trap */
- next = pc;
- break;
-
- case 0xcd: /* CALL (d16,PC) */
- pc[1] = 5;
- pc[2] = 0;
- next = pc + 5;
- break;
-
- case 0xdd: /* CALL (d32,PC) */
- pc[1] = 7;
- pc[2] = 0;
- pc[3] = 0;
- pc[4] = 0;
- next = pc + 7;
- break;
-
- case 0xde: /* RETF */
- next = pc + 3;
- regs->mdr = (unsigned) next;
- break;
-
- case 0xdf: /* RET */
- sp += pc[2];
- next = pc + 3;
- *(unsigned *)sp = (unsigned) next;
- break;
-
- case 0xf0:
- next = pc + 2;
- opc = pc[1];
- if (opc >= 0xf0 && opc <= 0xf3) {
- /* CALLS (An) */
- /* use CALLS (d16,PC) to avoid mucking with An */
- pc[0] = 0xfa;
- pc[1] = 0xff;
- pc[2] = 4;
- pc[3] = 0;
- next = pc + 4;
- } else if (opc >= 0xf4 && opc <= 0xf7) {
- /* JMP (An) */
- next = pc;
- } else if (opc == 0xfc) {
- /* RETS */
- next = pc + 2;
- *(unsigned *) sp = (unsigned) next;
- } else if (opc == 0xfd) {
- /* RTI */
- next = pc + 2;
- *(unsigned *)(sp + 4) = (unsigned) next;
- }
- break;
-
- case 0xfa: /* CALLS (d16,PC) */
- pc[2] = 4;
- pc[3] = 0;
- next = pc + 4;
- break;
-
- case 0xfc: /* CALLS (d32,PC) */
- pc[2] = 6;
- pc[3] = 0;
- pc[4] = 0;
- pc[5] = 0;
- next = pc + 6;
- break;
-
- case 0xd0 ... 0xda: /* LXX (d8,PC) */
- case 0xdb: /* SETLB */
- panic("Can't singlestep Lxx/SETLB\n");
- }
-
- return (unsigned) next;
-}
-
-int __kprobes arch_prepare_kprobe(struct kprobe *p)
-{
- return 0;
-}
-
-void __kprobes arch_copy_kprobe(struct kprobe *p)
-{
- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
-}
-
-void __kprobes arch_arm_kprobe(struct kprobe *p)
-{
- *p->addr = BREAKPOINT_INSTRUCTION;
- flush_icache_range((unsigned long) p->addr,
- (unsigned long) p->addr + sizeof(kprobe_opcode_t));
-}
-
-void __kprobes arch_disarm_kprobe(struct kprobe *p)
-{
-#ifndef CONFIG_MN10300_CACHE_SNOOP
- mn10300_dcache_flush();
- mn10300_icache_inv();
-#endif
-}
-
-void arch_remove_kprobe(struct kprobe *p)
-{
-}
-
-static inline
-void __kprobes disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
-{
- *p->addr = p->opcode;
- regs->pc = (unsigned long) p->addr;
-#ifndef CONFIG_MN10300_CACHE_SNOOP
- mn10300_dcache_flush();
- mn10300_icache_inv();
-#endif
-}
-
-static inline
-void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
-{
- unsigned long nextpc;
-
- cur_kprobe_orig_pc = regs->pc;
- memcpy(cur_kprobe_ss_buf, &p->ainsn.insn[0], MAX_INSN_SIZE);
- regs->pc = (unsigned long) cur_kprobe_ss_buf;
-
- nextpc = find_nextpc(regs, &cur_kprobe_ss_flags);
- if (cur_kprobe_ss_flags & SINGLESTEP_PCREL)
- cur_kprobe_next_pc = cur_kprobe_orig_pc + (nextpc - regs->pc);
- else
- cur_kprobe_next_pc = nextpc;
-
- /* branching instructions need special handling */
- if (cur_kprobe_ss_flags & SINGLESTEP_BRANCH)
- nextpc = singlestep_branch_setup(regs);
-
- cur_kprobe_bp_addr = nextpc;
-
- *(u8 *) nextpc = BREAKPOINT_INSTRUCTION;
- mn10300_dcache_flush_range2((unsigned) cur_kprobe_ss_buf,
- sizeof(cur_kprobe_ss_buf));
- mn10300_icache_inv();
-}
-
-static inline int __kprobes kprobe_handler(struct pt_regs *regs)
-{
- struct kprobe *p;
- int ret = 0;
- unsigned int *addr = (unsigned int *) regs->pc;
-
- /* We're in an interrupt, but this is clear and BUG()-safe. */
- preempt_disable();
-
- /* Check we're not actually recursing */
- if (kprobe_running()) {
- /* We *are* holding lock here, so this is safe.
- Disarm the probe we just hit, and ignore it. */
- p = get_kprobe(addr);
- if (p) {
- disarm_kprobe(p, regs);
- ret = 1;
- } else {
- p = cur_kprobe;
- if (p->break_handler && p->break_handler(p, regs))
- goto ss_probe;
- }
- /* If it's not ours, can't be delete race, (we hold lock). */
- goto no_kprobe;
- }
-
- p = get_kprobe(addr);
- if (!p) {
- if (*addr != BREAKPOINT_INSTRUCTION) {
- /* The breakpoint instruction was removed right after
- * we hit it. Another cpu has removed either a
- * probepoint or a debugger breakpoint at this address.
- * In either case, no further handling of this
- * interrupt is appropriate.
- */
- ret = 1;
- }
- /* Not one of ours: let kernel handle it */
- goto no_kprobe;
- }
-
- kprobe_status = KPROBE_HIT_ACTIVE;
- cur_kprobe = p;
- if (p->pre_handler(p, regs)) {
- /* handler has already set things up, so skip ss setup */
- return 1;
- }
-
-ss_probe:
- prepare_singlestep(p, regs);
- kprobe_status = KPROBE_HIT_SS;
- return 1;
-
-no_kprobe:
- preempt_enable_no_resched();
- return ret;
-}
-
-/*
- * Called after single-stepping. p->addr is the address of the
- * instruction whose first byte has been replaced by the "breakpoint"
- * instruction. To avoid the SMP problems that can occur when we
- * temporarily put back the original opcode to single-step, we
- * single-stepped a copy of the instruction. The address of this
- * copy is p->ainsn.insn.
- */
-static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
-{
- /* we may need to fixup regs/stack after singlestepping a call insn */
- if (cur_kprobe_ss_flags & SINGLESTEP_BRANCH) {
- regs->pc = cur_kprobe_orig_pc;
- switch (p->ainsn.insn[0]) {
- case 0xcd: /* CALL (d16,PC) */
- *(unsigned *) regs->sp = regs->mdr = regs->pc + 5;
- break;
- case 0xdd: /* CALL (d32,PC) */
- /* fixup mdr and return address on stack */
- *(unsigned *) regs->sp = regs->mdr = regs->pc + 7;
- break;
- case 0xf0:
- if (p->ainsn.insn[1] >= 0xf0 &&
- p->ainsn.insn[1] <= 0xf3) {
- /* CALLS (An) */
- /* fixup MDR and return address on stack */
- regs->mdr = regs->pc + 2;
- *(unsigned *) regs->sp = regs->mdr;
- }
- break;
-
- case 0xfa: /* CALLS (d16,PC) */
- /* fixup MDR and return address on stack */
- *(unsigned *) regs->sp = regs->mdr = regs->pc + 4;
- break;
-
- case 0xfc: /* CALLS (d32,PC) */
- /* fixup MDR and return address on stack */
- *(unsigned *) regs->sp = regs->mdr = regs->pc + 6;
- break;
- }
- }
-
- regs->pc = cur_kprobe_next_pc;
- cur_kprobe_bp_addr = 0;
-}
-
-static inline int __kprobes post_kprobe_handler(struct pt_regs *regs)
-{
- if (!kprobe_running())
- return 0;
-
- if (cur_kprobe->post_handler)
- cur_kprobe->post_handler(cur_kprobe, regs, 0);
-
- resume_execution(cur_kprobe, regs);
- reset_current_kprobe();
- preempt_enable_no_resched();
- return 1;
-}
-
-/* Interrupts disabled, kprobe_lock held. */
-static inline
-int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
-{
- if (cur_kprobe->fault_handler &&
- cur_kprobe->fault_handler(cur_kprobe, regs, trapnr))
- return 1;
-
- if (kprobe_status & KPROBE_HIT_SS) {
- resume_execution(cur_kprobe, regs);
- reset_current_kprobe();
- preempt_enable_no_resched();
- }
- return 0;
-}
-
-/*
- * Wrapper routine to for handling exceptions.
- */
-int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
- unsigned long val, void *data)
-{
- struct die_args *args = data;
-
- switch (val) {
- case DIE_BREAKPOINT:
- if (cur_kprobe_bp_addr != args->regs->pc) {
- if (kprobe_handler(args->regs))
- return NOTIFY_STOP;
- } else {
- if (post_kprobe_handler(args->regs))
- return NOTIFY_STOP;
- }
- break;
- case DIE_GPF:
- if (kprobe_running() &&
- kprobe_fault_handler(args->regs, args->trapnr))
- return NOTIFY_STOP;
- break;
- default:
- break;
- }
- return NOTIFY_DONE;
-}
-
-/* Jprobes support. */
-static struct pt_regs jprobe_saved_regs;
-static struct pt_regs *jprobe_saved_regs_location;
-static kprobe_opcode_t jprobe_saved_stack[MAX_STACK_SIZE];
-
-int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
-{
- struct jprobe *jp = container_of(p, struct jprobe, kp);
-
- jprobe_saved_regs_location = regs;
- memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
-
- /* Save a whole stack frame, this gets arguments
- * pushed onto the stack after using up all the
- * arg registers.
- */
- memcpy(&jprobe_saved_stack, regs + 1, sizeof(jprobe_saved_stack));
-
- /* setup return addr to the jprobe handler routine */
- regs->pc = (unsigned long) jp->entry;
- return 1;
-}
-
-void __kprobes jprobe_return(void)
-{
- void *orig_sp = jprobe_saved_regs_location + 1;
-
- preempt_enable_no_resched();
- asm volatile(" mov %0,sp\n"
- ".globl jprobe_return_bp_addr\n"
- "jprobe_return_bp_addr:\n\t"
- " .byte 0xff\n"
- : : "d" (orig_sp));
-}
-
-extern void jprobe_return_bp_addr(void);
-
-int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
-{
- u8 *addr = (u8 *) regs->pc;
-
- if (addr == (u8 *) jprobe_return_bp_addr) {
- if (jprobe_saved_regs_location != regs) {
- printk(KERN_ERR"JPROBE:"
- " Current regs (%p) does not match saved regs"
- " (%p).\n",
- regs, jprobe_saved_regs_location);
- BUG();
- }
-
- /* Restore old register state.
- */
- memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
-
- memcpy(regs + 1, &jprobe_saved_stack,
- sizeof(jprobe_saved_stack));
- return 1;
- }
- return 0;
-}
-
-int __init arch_init_kprobes(void)
-{
- return 0;
-}
diff --git a/arch/mn10300/kernel/mn10300-debug.c b/arch/mn10300/kernel/mn10300-debug.c
deleted file mode 100644
index bd8196478cbc..000000000000
--- a/arch/mn10300/kernel/mn10300-debug.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Debugging stuff for the MN10300-based processors
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/sched.h>
-#include <asm/serial-regs.h>
-
-#undef MN10300_CONSOLE_ON_SERIO
-
-/*
- * write a string directly through one of the serial ports on-board the MN10300
- */
-#ifdef MN10300_CONSOLE_ON_SERIO
-void debug_to_serial_mnser(const char *p, int n)
-{
- char ch;
-
- for (; n > 0; n--) {
- ch = *p++;
-
-#if MN10300_CONSOLE_ON_SERIO == 0
- while (SC0STR & (SC01STR_TBF)) continue;
- SC0TXB = ch;
- while (SC0STR & (SC01STR_TBF)) continue;
- if (ch == 0x0a) {
- SC0TXB = 0x0d;
- while (SC0STR & (SC01STR_TBF)) continue;
- }
-
-#elif MN10300_CONSOLE_ON_SERIO == 1
- while (SC1STR & (SC01STR_TBF)) continue;
- SC1TXB = ch;
- while (SC1STR & (SC01STR_TBF)) continue;
- if (ch == 0x0a) {
- SC1TXB = 0x0d;
- while (SC1STR & (SC01STR_TBF)) continue;
- }
-
-#elif MN10300_CONSOLE_ON_SERIO == 2
- while (SC2STR & (SC2STR_TBF)) continue;
- SC2TXB = ch;
- while (SC2STR & (SC2STR_TBF)) continue;
- if (ch == 0x0a) {
- SC2TXB = 0x0d;
- while (SC2STR & (SC2STR_TBF)) continue;
- }
-
-#endif
- }
-}
-#endif
-
diff --git a/arch/mn10300/kernel/mn10300-serial-low.S b/arch/mn10300/kernel/mn10300-serial-low.S
deleted file mode 100644
index b95e76caf4fa..000000000000
--- a/arch/mn10300/kernel/mn10300-serial-low.S
+++ /dev/null
@@ -1,194 +0,0 @@
-###############################################################################
-#
-# Virtual DMA driver for MN10300 serial ports
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/page.h>
-#include <asm/smp.h>
-#include <asm/cpu-regs.h>
-#include <asm/frame.inc>
-#include <asm/timer-regs.h>
-#include <proc/cache.h>
-#include <unit/timex.h>
-#include "mn10300-serial.h"
-
-#define SCxCTR 0x00
-#define SCxICR 0x04
-#define SCxTXB 0x08
-#define SCxRXB 0x09
-#define SCxSTR 0x0c
-#define SCxTIM 0x0d
-
- .text
-
-###############################################################################
-#
-# serial port interrupt virtual DMA entry point
-# - intended to run at interrupt priority 1 (not affected by local_irq_disable)
-#
-###############################################################################
- .balign L1_CACHE_BYTES
-ENTRY(mn10300_serial_vdma_interrupt)
-# or EPSW_IE,psw # permit overriding by
- # debugging interrupts
- movm [d2,d3,a2,a3,exreg0],(sp)
-
- movhu (IAGR),a2 # see if which interrupt is
- # pending
- and IAGR_GN,a2
- add a2,a2
- add mn10300_serial_int_tbl,a2
-
- mov (a2+),a3
- mov (__iobase,a3),e2
- mov (a2),a2
- jmp (a2)
-
-###############################################################################
-#
-# serial port receive interrupt virtual DMA entry point
-# - intended to run at interrupt priority 1 (not affected by local_irq_disable)
-# - stores data/status byte pairs in the ring buffer
-# - induces a scheduler tick timer interrupt when done, which we then subvert
-# on entry:
-# A3 struct mn10300_serial_port *
-# E2 I/O port base
-#
-###############################################################################
-ENTRY(mn10300_serial_vdma_rx_handler)
- mov (__rx_icr,a3),e3
- mov GxICR_DETECT,d2
- movbu d2,(e3) # ACK the interrupt
- movhu (e3),d2 # flush
-
- mov (__rx_inp,a3),d3
- mov d3,a2
- add 2,d3
- and MNSC_BUFFER_SIZE-1,d3
- mov (__rx_outp,a3),d2
- cmp d3,d2
- beq mnsc_vdma_rx_overflow
-
- mov (__rx_buffer,a3),d2
- add d2,a2
- movhu (SCxSTR,e2),d2
- movbu d2,(1,a2)
- movbu (SCxRXB,e2),d2
- movbu d2,(a2)
- mov d3,(__rx_inp,a3)
- bset MNSCx_RX_AVAIL,(__intr_flags,a3)
-
-mnsc_vdma_rx_done:
- mov (__tm_icr,a3),a2
- mov GxICR_LEVEL_6|GxICR_ENABLE|GxICR_REQUEST|GxICR_DETECT,d2
- movhu d2,(a2) # request a slow interrupt
- movhu (a2),d2 # flush
-
- movm (sp),[d2,d3,a2,a3,exreg0]
- rti
-
-mnsc_vdma_rx_overflow:
- bset MNSCx_RX_OVERF,(__intr_flags,a3)
- bra mnsc_vdma_rx_done
-
-###############################################################################
-#
-# serial port transmit interrupt virtual DMA entry point
-# - intended to run at interrupt priority 1 (not affected by local_irq_disable)
-# - retrieves data bytes from the ring buffer and passes them to the serial port
-# - induces a scheduler tick timer interrupt when done, which we then subvert
-# A3 struct mn10300_serial_port *
-# E2 I/O port base
-#
-###############################################################################
- .balign L1_CACHE_BYTES
-ENTRY(mn10300_serial_vdma_tx_handler)
- mov (__tx_icr,a3),e3
- mov GxICR_DETECT,d2
- movbu d2,(e3) # ACK the interrupt
- movhu (e3),d2 # flush
-
- btst 0xFF,(__tx_flags,a3) # handle transmit flags
- bne mnsc_vdma_tx_flags
-
- movbu (SCxSTR,e2),d2 # don't try and transmit a char if the
- # buffer is not empty
- btst SC01STR_TBF,d2 # (may have tried to jumpstart)
- bne mnsc_vdma_tx_noint
-
- movbu (__tx_xchar,a3),d2 # handle hi-pri XON/XOFF
- or d2,d2
- bne mnsc_vdma_tx_xchar
-
- mov (__uart_state,a3),a2 # see if the TTY Tx queue has anything in it
- mov (__xmit_tail,a2),d3
- mov (__xmit_head,a2),d2
- cmp d3,d2
- beq mnsc_vdma_tx_empty
-
- mov (__xmit_buffer,a2),d2 # get a char from the buffer and
- # transmit it
- movbu (d3,d2),d2
- movbu d2,(SCxTXB,e2) # Tx
-
- inc d3 # advance the buffer pointer
- and __UART_XMIT_SIZE-1,d3
- mov (__xmit_head,a2),d2
- mov d3,(__xmit_tail,a2)
-
- sub d3,d2 # see if we've written everything
- beq mnsc_vdma_tx_empty
-
- and __UART_XMIT_SIZE-1,d2 # see if we just made a hole
- cmp __UART_XMIT_SIZE-2,d2
- beq mnsc_vdma_tx_made_hole
-
-mnsc_vdma_tx_done:
- mov (__tm_icr,a3),a2
- mov GxICR_LEVEL_6|GxICR_ENABLE|GxICR_REQUEST|GxICR_DETECT,d2
- movhu d2,(a2) # request a slow interrupt
- movhu (a2),d2 # flush
-
-mnsc_vdma_tx_noint:
- movm (sp),[d2,d3,a2,a3,exreg0]
- rti
-
-mnsc_vdma_tx_empty:
- mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
- movhu d2,(e3) # disable the interrupt
- movhu (e3),d2 # flush
-
- bset MNSCx_TX_EMPTY,(__intr_flags,a3)
- bra mnsc_vdma_tx_done
-
-mnsc_vdma_tx_flags:
- btst MNSCx_TX_STOP,(__tx_flags,a3)
- bne mnsc_vdma_tx_stop
- movhu (SCxCTR,e2),d2 # turn on break mode
- or SC01CTR_BKE,d2
- movhu d2,(SCxCTR,e2)
-mnsc_vdma_tx_stop:
- mov +(NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL)|GxICR_DETECT),d2
- movhu d2,(e3) # disable transmit interrupts on this
- # channel
- movhu (e3),d2 # flush
- bra mnsc_vdma_tx_noint
-
-mnsc_vdma_tx_xchar:
- bclr 0xff,(__tx_xchar,a3)
- movbu d2,(SCxTXB,e2)
- bra mnsc_vdma_tx_done
-
-mnsc_vdma_tx_made_hole:
- bset MNSCx_TX_SPACE,(__intr_flags,a3)
- bra mnsc_vdma_tx_done
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
deleted file mode 100644
index 4994b570dfd9..000000000000
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ /dev/null
@@ -1,1790 +0,0 @@
-/* MN10300 On-chip serial port UART driver
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-static const char serial_name[] = "MN10300 Serial driver";
-static const char serial_version[] = "mn10300_serial-1.0";
-static const char serial_revdate[] = "2007-11-06";
-
-#if defined(CONFIG_MN10300_TTYSM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-#define SUPPORT_SYSRQ
-#endif
-
-#include <linux/module.h>
-#include <linux/serial.h>
-#include <linux/circ_buf.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/console.h>
-#include <linux/sysrq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/bitops.h>
-#include <asm/serial-regs.h>
-#include <unit/timex.h>
-#include "mn10300-serial.h"
-
-#ifdef CONFIG_SMP
-#undef GxICR
-#define GxICR(X) CROSS_GxICR(X, 0)
-#endif /* CONFIG_SMP */
-
-#define kenter(FMT, ...) \
- printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__)
-#define _enter(FMT, ...) \
- no_printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__)
-#define kdebug(FMT, ...) \
- printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__)
-#define _debug(FMT, ...) \
- no_printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__)
-#define kproto(FMT, ...) \
- printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__)
-#define _proto(FMT, ...) \
- no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__)
-
-#ifndef CODMSB
-/* c_cflag bit meaning */
-#define CODMSB 004000000000 /* change Transfer bit-order */
-#endif
-
-#define NR_UARTS 3
-
-#ifdef CONFIG_MN10300_TTYSM_CONSOLE
-static void mn10300_serial_console_write(struct console *co,
- const char *s, unsigned count);
-static int __init mn10300_serial_console_setup(struct console *co,
- char *options);
-
-static struct uart_driver mn10300_serial_driver;
-static struct console mn10300_serial_console = {
- .name = "ttySM",
- .write = mn10300_serial_console_write,
- .device = uart_console_device,
- .setup = mn10300_serial_console_setup,
- .flags = CON_PRINTBUFFER,
- .index = -1,
- .data = &mn10300_serial_driver,
-};
-#endif
-
-static struct uart_driver mn10300_serial_driver = {
- .owner = NULL,
- .driver_name = "mn10300-serial",
- .dev_name = "ttySM",
- .major = TTY_MAJOR,
- .minor = 128,
- .nr = NR_UARTS,
-#ifdef CONFIG_MN10300_TTYSM_CONSOLE
- .cons = &mn10300_serial_console,
-#endif
-};
-
-static unsigned int mn10300_serial_tx_empty(struct uart_port *);
-static void mn10300_serial_set_mctrl(struct uart_port *, unsigned int mctrl);
-static unsigned int mn10300_serial_get_mctrl(struct uart_port *);
-static void mn10300_serial_stop_tx(struct uart_port *);
-static void mn10300_serial_start_tx(struct uart_port *);
-static void mn10300_serial_send_xchar(struct uart_port *, char ch);
-static void mn10300_serial_stop_rx(struct uart_port *);
-static void mn10300_serial_enable_ms(struct uart_port *);
-static void mn10300_serial_break_ctl(struct uart_port *, int ctl);
-static int mn10300_serial_startup(struct uart_port *);
-static void mn10300_serial_shutdown(struct uart_port *);
-static void mn10300_serial_set_termios(struct uart_port *,
- struct ktermios *new,
- struct ktermios *old);
-static const char *mn10300_serial_type(struct uart_port *);
-static void mn10300_serial_release_port(struct uart_port *);
-static int mn10300_serial_request_port(struct uart_port *);
-static void mn10300_serial_config_port(struct uart_port *, int);
-static int mn10300_serial_verify_port(struct uart_port *,
- struct serial_struct *);
-#ifdef CONFIG_CONSOLE_POLL
-static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char);
-static int mn10300_serial_poll_get_char(struct uart_port *);
-#endif
-
-static const struct uart_ops mn10300_serial_ops = {
- .tx_empty = mn10300_serial_tx_empty,
- .set_mctrl = mn10300_serial_set_mctrl,
- .get_mctrl = mn10300_serial_get_mctrl,
- .stop_tx = mn10300_serial_stop_tx,
- .start_tx = mn10300_serial_start_tx,
- .send_xchar = mn10300_serial_send_xchar,
- .stop_rx = mn10300_serial_stop_rx,
- .enable_ms = mn10300_serial_enable_ms,
- .break_ctl = mn10300_serial_break_ctl,
- .startup = mn10300_serial_startup,
- .shutdown = mn10300_serial_shutdown,
- .set_termios = mn10300_serial_set_termios,
- .type = mn10300_serial_type,
- .release_port = mn10300_serial_release_port,
- .request_port = mn10300_serial_request_port,
- .config_port = mn10300_serial_config_port,
- .verify_port = mn10300_serial_verify_port,
-#ifdef CONFIG_CONSOLE_POLL
- .poll_put_char = mn10300_serial_poll_put_char,
- .poll_get_char = mn10300_serial_poll_get_char,
-#endif
-};
-
-static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id);
-
-/*
- * the first on-chip serial port: ttySM0 (aka SIF0)
- */
-#ifdef CONFIG_MN10300_TTYSM0
-struct mn10300_serial_port mn10300_serial_port_sif0 = {
- .uart.ops = &mn10300_serial_ops,
- .uart.membase = (void __iomem *) &SC0CTR,
- .uart.mapbase = (unsigned long) &SC0CTR,
- .uart.iotype = UPIO_MEM,
- .uart.irq = 0,
- .uart.uartclk = 0, /* MN10300_IOCLK, */
- .uart.fifosize = 1,
- .uart.flags = UPF_BOOT_AUTOCONF,
- .uart.line = 0,
- .uart.type = PORT_MN10300,
- .uart.lock =
- __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif0.uart.lock),
- .name = "ttySM0",
- ._iobase = &SC0CTR,
- ._control = &SC0CTR,
- ._status = (volatile u8 *)&SC0STR,
- ._intr = &SC0ICR,
- ._rxb = &SC0RXB,
- ._txb = &SC0TXB,
- .rx_name = "ttySM0:Rx",
- .tx_name = "ttySM0:Tx",
-#if defined(CONFIG_MN10300_TTYSM0_TIMER8)
- .tm_name = "ttySM0:Timer8",
- ._tmxmd = &TM8MD,
- ._tmxbr = &TM8BR,
- ._tmicr = &TM8ICR,
- .tm_irq = TM8IRQ,
- .div_timer = MNSCx_DIV_TIMER_16BIT,
-#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)
- .tm_name = "ttySM0:Timer0",
- ._tmxmd = &TM0MD,
- ._tmxbr = (volatile u16 *)&TM0BR,
- ._tmicr = &TM0ICR,
- .tm_irq = TM0IRQ,
- .div_timer = MNSCx_DIV_TIMER_8BIT,
-#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)
- .tm_name = "ttySM0:Timer2",
- ._tmxmd = &TM2MD,
- ._tmxbr = (volatile u16 *)&TM2BR,
- ._tmicr = &TM2ICR,
- .tm_irq = TM2IRQ,
- .div_timer = MNSCx_DIV_TIMER_8BIT,
-#else
-#error "Unknown config for ttySM0"
-#endif
- .rx_irq = SC0RXIRQ,
- .tx_irq = SC0TXIRQ,
- .rx_icr = &GxICR(SC0RXIRQ),
- .tx_icr = &GxICR(SC0TXIRQ),
- .clock_src = MNSCx_CLOCK_SRC_IOCLK,
- .options = 0,
-#ifdef CONFIG_GDBSTUB_ON_TTYSM0
- .gdbstub = 1,
-#endif
-};
-#endif /* CONFIG_MN10300_TTYSM0 */
-
-/*
- * the second on-chip serial port: ttySM1 (aka SIF1)
- */
-#ifdef CONFIG_MN10300_TTYSM1
-struct mn10300_serial_port mn10300_serial_port_sif1 = {
- .uart.ops = &mn10300_serial_ops,
- .uart.membase = (void __iomem *) &SC1CTR,
- .uart.mapbase = (unsigned long) &SC1CTR,
- .uart.iotype = UPIO_MEM,
- .uart.irq = 0,
- .uart.uartclk = 0, /* MN10300_IOCLK, */
- .uart.fifosize = 1,
- .uart.flags = UPF_BOOT_AUTOCONF,
- .uart.line = 1,
- .uart.type = PORT_MN10300,
- .uart.lock =
- __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif1.uart.lock),
- .name = "ttySM1",
- ._iobase = &SC1CTR,
- ._control = &SC1CTR,
- ._status = (volatile u8 *)&SC1STR,
- ._intr = &SC1ICR,
- ._rxb = &SC1RXB,
- ._txb = &SC1TXB,
- .rx_name = "ttySM1:Rx",
- .tx_name = "ttySM1:Tx",
-#if defined(CONFIG_MN10300_TTYSM1_TIMER9)
- .tm_name = "ttySM1:Timer9",
- ._tmxmd = &TM9MD,
- ._tmxbr = &TM9BR,
- ._tmicr = &TM9ICR,
- .tm_irq = TM9IRQ,
- .div_timer = MNSCx_DIV_TIMER_16BIT,
-#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
- .tm_name = "ttySM1:Timer3",
- ._tmxmd = &TM3MD,
- ._tmxbr = (volatile u16 *)&TM3BR,
- ._tmicr = &TM3ICR,
- .tm_irq = TM3IRQ,
- .div_timer = MNSCx_DIV_TIMER_8BIT,
-#elif defined(CONFIG_MN10300_TTYSM1_TIMER12)
- .tm_name = "ttySM1/Timer12",
- ._tmxmd = &TM12MD,
- ._tmxbr = &TM12BR,
- ._tmicr = &TM12ICR,
- .tm_irq = TM12IRQ,
- .div_timer = MNSCx_DIV_TIMER_16BIT,
-#else
-#error "Unknown config for ttySM1"
-#endif
- .rx_irq = SC1RXIRQ,
- .tx_irq = SC1TXIRQ,
- .rx_icr = &GxICR(SC1RXIRQ),
- .tx_icr = &GxICR(SC1TXIRQ),
- .clock_src = MNSCx_CLOCK_SRC_IOCLK,
- .options = 0,
-#ifdef CONFIG_GDBSTUB_ON_TTYSM1
- .gdbstub = 1,
-#endif
-};
-#endif /* CONFIG_MN10300_TTYSM1 */
-
-/*
- * the third on-chip serial port: ttySM2 (aka SIF2)
- */
-#ifdef CONFIG_MN10300_TTYSM2
-struct mn10300_serial_port mn10300_serial_port_sif2 = {
- .uart.ops = &mn10300_serial_ops,
- .uart.membase = (void __iomem *) &SC2CTR,
- .uart.mapbase = (unsigned long) &SC2CTR,
- .uart.iotype = UPIO_MEM,
- .uart.irq = 0,
- .uart.uartclk = 0, /* MN10300_IOCLK, */
- .uart.fifosize = 1,
- .uart.flags = UPF_BOOT_AUTOCONF,
- .uart.line = 2,
-#ifdef CONFIG_MN10300_TTYSM2_CTS
- .uart.type = PORT_MN10300_CTS,
-#else
- .uart.type = PORT_MN10300,
-#endif
- .uart.lock =
- __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock),
- .name = "ttySM2",
- ._iobase = &SC2CTR,
- ._control = &SC2CTR,
- ._status = (volatile u8 *)&SC2STR,
- ._intr = &SC2ICR,
- ._rxb = &SC2RXB,
- ._txb = &SC2TXB,
- .rx_name = "ttySM2:Rx",
- .tx_name = "ttySM2:Tx",
-#if defined(CONFIG_MN10300_TTYSM2_TIMER10)
- .tm_name = "ttySM2/Timer10",
- ._tmxmd = &TM10MD,
- ._tmxbr = &TM10BR,
- ._tmicr = &TM10ICR,
- .tm_irq = TM10IRQ,
- .div_timer = MNSCx_DIV_TIMER_16BIT,
-#elif defined(CONFIG_MN10300_TTYSM2_TIMER9)
- .tm_name = "ttySM2/Timer9",
- ._tmxmd = &TM9MD,
- ._tmxbr = &TM9BR,
- ._tmicr = &TM9ICR,
- .tm_irq = TM9IRQ,
- .div_timer = MNSCx_DIV_TIMER_16BIT,
-#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)
- .tm_name = "ttySM2/Timer1",
- ._tmxmd = &TM1MD,
- ._tmxbr = (volatile u16 *)&TM1BR,
- ._tmicr = &TM1ICR,
- .tm_irq = TM1IRQ,
- .div_timer = MNSCx_DIV_TIMER_8BIT,
-#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)
- .tm_name = "ttySM2/Timer3",
- ._tmxmd = &TM3MD,
- ._tmxbr = (volatile u16 *)&TM3BR,
- ._tmicr = &TM3ICR,
- .tm_irq = TM3IRQ,
- .div_timer = MNSCx_DIV_TIMER_8BIT,
-#else
-#error "Unknown config for ttySM2"
-#endif
- .rx_irq = SC2RXIRQ,
- .tx_irq = SC2TXIRQ,
- .rx_icr = &GxICR(SC2RXIRQ),
- .tx_icr = &GxICR(SC2TXIRQ),
- .clock_src = MNSCx_CLOCK_SRC_IOCLK,
-#ifdef CONFIG_MN10300_TTYSM2_CTS
- .options = MNSCx_OPT_CTS,
-#else
- .options = 0,
-#endif
-#ifdef CONFIG_GDBSTUB_ON_TTYSM2
- .gdbstub = 1,
-#endif
-};
-#endif /* CONFIG_MN10300_TTYSM2 */
-
-
-/*
- * list of available serial ports
- */
-struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = {
-#ifdef CONFIG_MN10300_TTYSM0
- [0] = &mn10300_serial_port_sif0,
-#endif
-#ifdef CONFIG_MN10300_TTYSM1
- [1] = &mn10300_serial_port_sif1,
-#endif
-#ifdef CONFIG_MN10300_TTYSM2
- [2] = &mn10300_serial_port_sif2,
-#endif
- [NR_UARTS] = NULL,
-};
-
-
-/*
- * we abuse the serial ports' baud timers' interrupt lines to get the ability
- * to deliver interrupts to userspace as we use the ports' interrupt lines to
- * do virtual DMA on account of the ports having no hardware FIFOs
- *
- * we can generate an interrupt manually in the assembly stubs by writing to
- * the enable and detect bits in the interrupt control register, so all we need
- * to do here is disable the interrupt line
- *
- * note that we can't just leave the line enabled as the baud rate timer *also*
- * generates interrupts
- */
-static void mn10300_serial_mask_ack(unsigned int irq)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
- GxICR(irq) = GxICR_LEVEL_6;
- tmp = GxICR(irq); /* flush write buffer */
- arch_local_irq_restore(flags);
-}
-
-static void mn10300_serial_chip_mask_ack(struct irq_data *d)
-{
- mn10300_serial_mask_ack(d->irq);
-}
-
-static void mn10300_serial_nop(struct irq_data *d)
-{
-}
-
-static struct irq_chip mn10300_serial_pic = {
- .name = "mnserial",
- .irq_ack = mn10300_serial_chip_mask_ack,
- .irq_mask = mn10300_serial_chip_mask_ack,
- .irq_mask_ack = mn10300_serial_chip_mask_ack,
- .irq_unmask = mn10300_serial_nop,
-};
-
-static void mn10300_serial_low_mask(struct irq_data *d)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
- GxICR(d->irq) = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
- tmp = GxICR(d->irq); /* flush write buffer */
- arch_local_irq_restore(flags);
-}
-
-static void mn10300_serial_low_unmask(struct irq_data *d)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
- GxICR(d->irq) =
- NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE;
- tmp = GxICR(d->irq); /* flush write buffer */
- arch_local_irq_restore(flags);
-}
-
-static struct irq_chip mn10300_serial_low_pic = {
- .name = "mnserial-low",
- .irq_mask = mn10300_serial_low_mask,
- .irq_unmask = mn10300_serial_low_unmask,
-};
-
-/*
- * serial virtual DMA interrupt jump table
- */
-struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS];
-
-static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port)
-{
- int retries = 100;
- u16 x;
-
- /* nothing to do if irq isn't set up */
- if (!mn10300_serial_int_tbl[port->tx_irq].port)
- return;
-
- port->tx_flags |= MNSCx_TX_STOP;
- mb();
-
- /*
- * Here we wait for the irq to be disabled. Either it already is
- * disabled or we wait some number of retries for the VDMA handler
- * to disable it. The retries give the VDMA handler enough time to
- * run to completion if it was already in progress. If the VDMA IRQ
- * is enabled but the handler is not yet running when arrive here,
- * the STOP flag will prevent the handler from conflicting with the
- * driver code following this loop.
- */
- while ((*port->tx_icr & GxICR_ENABLE) && retries-- > 0)
- ;
- if (retries <= 0) {
- *port->tx_icr =
- NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
- x = *port->tx_icr;
- }
-}
-
-static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port)
-{
- u16 x;
-
- /* nothing to do if irq isn't set up */
- if (!mn10300_serial_int_tbl[port->tx_irq].port)
- return;
-
- /* stop vdma irq if not already stopped */
- if (!(port->tx_flags & MNSCx_TX_STOP))
- mn10300_serial_dis_tx_intr(port);
-
- port->tx_flags &= ~MNSCx_TX_STOP;
- mb();
-
- *port->tx_icr =
- NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) |
- GxICR_ENABLE | GxICR_REQUEST | GxICR_DETECT;
- x = *port->tx_icr;
-}
-
-static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port)
-{
- unsigned long flags;
- u16 x;
-
- flags = arch_local_cli_save();
- *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
- x = *port->rx_icr;
- arch_local_irq_restore(flags);
-}
-
-/*
- * multi-bit equivalent of test_and_clear_bit()
- */
-static int mask_test_and_clear(volatile u8 *ptr, u8 mask)
-{
- u32 epsw;
- asm volatile(" bclr %1,(%2) \n"
- " mov epsw,%0 \n"
- : "=d"(epsw) : "d"(mask), "a"(ptr)
- : "cc", "memory");
- return !(epsw & EPSW_FLAG_Z);
-}
-
-/*
- * receive chars from the ring buffer for this serial port
- * - must do break detection here (not done in the UART)
- */
-static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port)
-{
- struct uart_icount *icount = &port->uart.icount;
- struct tty_port *tport = &port->uart.state->port;
- unsigned ix;
- int count;
- u8 st, ch, push, status, overrun;
-
- _enter("%s", port->name);
-
- push = 0;
-
- count = CIRC_CNT(port->rx_inp, port->rx_outp, MNSC_BUFFER_SIZE);
- count = tty_buffer_request_room(tport, count);
- if (count == 0) {
- if (!tport->low_latency)
- tty_flip_buffer_push(tport);
- return;
- }
-
-try_again:
- /* pull chars out of the hat */
- ix = READ_ONCE(port->rx_outp);
- if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) {
- if (push && !tport->low_latency)
- tty_flip_buffer_push(tport);
- return;
- }
-
- /* READ_ONCE() enforces dependency, but dangerous through integer!!! */
- ch = port->rx_buffer[ix++];
- st = port->rx_buffer[ix++];
- smp_mb();
- port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
- port->uart.icount.rx++;
-
- st &= SC01STR_FEF | SC01STR_PEF | SC01STR_OEF;
- status = 0;
- overrun = 0;
-
- /* the UART doesn't detect BREAK, so we have to do that ourselves
- * - it starts as a framing error on a NUL character
- * - then we count another two NUL characters before issuing TTY_BREAK
- * - then we end on a normal char or one that has all the bottom bits
- * zero and the top bits set
- */
- switch (port->rx_brk) {
- case 0:
- /* not breaking at the moment */
- break;
-
- case 1:
- if (st & SC01STR_FEF && ch == 0) {
- port->rx_brk = 2;
- goto try_again;
- }
- goto not_break;
-
- case 2:
- if (st & SC01STR_FEF && ch == 0) {
- port->rx_brk = 3;
- _proto("Rx Break Detected");
- icount->brk++;
- if (uart_handle_break(&port->uart))
- goto ignore_char;
- status |= 1 << TTY_BREAK;
- goto insert;
- }
- goto not_break;
-
- default:
- if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF))
- goto try_again; /* still breaking */
-
- port->rx_brk = 0; /* end of the break */
-
- switch (ch) {
- case 0xFF:
- case 0xFE:
- case 0xFC:
- case 0xF8:
- case 0xF0:
- case 0xE0:
- case 0xC0:
- case 0x80:
- case 0x00:
- /* discard char at probable break end */
- goto try_again;
- }
- break;
- }
-
-process_errors:
- /* handle framing error */
- if (st & SC01STR_FEF) {
- if (ch == 0) {
- /* framing error with NUL char is probably a BREAK */
- port->rx_brk = 1;
- goto try_again;
- }
-
- _proto("Rx Framing Error");
- icount->frame++;
- status |= 1 << TTY_FRAME;
- }
-
- /* handle parity error */
- if (st & SC01STR_PEF) {
- _proto("Rx Parity Error");
- icount->parity++;
- status = TTY_PARITY;
- }
-
- /* handle normal char */
- if (status == 0) {
- if (uart_handle_sysrq_char(&port->uart, ch))
- goto ignore_char;
- status = (1 << TTY_NORMAL);
- }
-
- /* handle overrun error */
- if (st & SC01STR_OEF) {
- if (port->rx_brk)
- goto try_again;
-
- _proto("Rx Overrun Error");
- icount->overrun++;
- overrun = 1;
- }
-
-insert:
- status &= port->uart.read_status_mask;
-
- if (!overrun && !(status & port->uart.ignore_status_mask)) {
- int flag;
-
- if (status & (1 << TTY_BREAK))
- flag = TTY_BREAK;
- else if (status & (1 << TTY_PARITY))
- flag = TTY_PARITY;
- else if (status & (1 << TTY_FRAME))
- flag = TTY_FRAME;
- else
- flag = TTY_NORMAL;
-
- tty_insert_flip_char(tport, ch, flag);
- }
-
- /* overrun is special, since it's reported immediately, and doesn't
- * affect the current character
- */
- if (overrun)
- tty_insert_flip_char(tport, 0, TTY_OVERRUN);
-
- count--;
- if (count <= 0) {
- if (!tport->low_latency)
- tty_flip_buffer_push(tport);
- return;
- }
-
-ignore_char:
- push = 1;
- goto try_again;
-
-not_break:
- port->rx_brk = 0;
- goto process_errors;
-}
-
-/*
- * handle an interrupt from the serial transmission "virtual DMA" driver
- * - note: the interrupt routine will disable its own interrupts when the Tx
- * buffer is empty
- */
-static void mn10300_serial_transmit_interrupt(struct mn10300_serial_port *port)
-{
- _enter("%s", port->name);
-
- if (!port->uart.state || !port->uart.state->port.tty) {
- mn10300_serial_dis_tx_intr(port);
- return;
- }
-
- if (uart_tx_stopped(&port->uart) ||
- uart_circ_empty(&port->uart.state->xmit))
- mn10300_serial_dis_tx_intr(port);
-
- if (uart_circ_chars_pending(&port->uart.state->xmit) < WAKEUP_CHARS)
- uart_write_wakeup(&port->uart);
-}
-
-/*
- * deal with a change in the status of the CTS line
- */
-static void mn10300_serial_cts_changed(struct mn10300_serial_port *port, u8 st)
-{
- u16 ctr;
-
- port->tx_cts = st;
- port->uart.icount.cts++;
-
- /* flip the CTS state selector flag to interrupt when it changes
- * back */
- ctr = *port->_control;
- ctr ^= SC2CTR_TWS;
- *port->_control = ctr;
-
- uart_handle_cts_change(&port->uart, st & SC2STR_CTS);
- wake_up_interruptible(&port->uart.state->port.delta_msr_wait);
-}
-
-/*
- * handle a virtual interrupt generated by the lower level "virtual DMA"
- * routines (irq is the baud timer interrupt)
- */
-static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id)
-{
- struct mn10300_serial_port *port = dev_id;
- u8 st;
-
- spin_lock(&port->uart.lock);
-
- if (port->intr_flags) {
- _debug("INT %s: %x", port->name, port->intr_flags);
-
- if (mask_test_and_clear(&port->intr_flags, MNSCx_RX_AVAIL))
- mn10300_serial_receive_interrupt(port);
-
- if (mask_test_and_clear(&port->intr_flags,
- MNSCx_TX_SPACE | MNSCx_TX_EMPTY))
- mn10300_serial_transmit_interrupt(port);
- }
-
- /* the only modem control line amongst the whole lot is CTS on
- * serial port 2 */
- if (port->type == PORT_MN10300_CTS) {
- st = *port->_status;
- if ((port->tx_cts ^ st) & SC2STR_CTS)
- mn10300_serial_cts_changed(port, st);
- }
-
- spin_unlock(&port->uart.lock);
-
- return IRQ_HANDLED;
-}
-
-/*
- * return indication of whether the hardware transmit buffer is empty
- */
-static unsigned int mn10300_serial_tx_empty(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- return (*port->_status & (SC01STR_TXF | SC01STR_TBF)) ?
- 0 : TIOCSER_TEMT;
-}
-
-/*
- * set the modem control lines (we don't have any)
- */
-static void mn10300_serial_set_mctrl(struct uart_port *_port,
- unsigned int mctrl)
-{
- struct mn10300_serial_port *port __attribute__ ((unused)) =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s,%x", port->name, mctrl);
-}
-
-/*
- * get the modem control line statuses
- */
-static unsigned int mn10300_serial_get_mctrl(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- if (port->type == PORT_MN10300_CTS && !(*port->_status & SC2STR_CTS))
- return TIOCM_CAR | TIOCM_DSR;
-
- return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR;
-}
-
-/*
- * stop transmitting characters
- */
-static void mn10300_serial_stop_tx(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- /* disable the virtual DMA */
- mn10300_serial_dis_tx_intr(port);
-}
-
-/*
- * start transmitting characters
- * - jump-start transmission if it has stalled
- * - enable the serial Tx interrupt (used by the virtual DMA controller)
- * - force an interrupt to happen if necessary
- */
-static void mn10300_serial_start_tx(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s{%lu}",
- port->name,
- CIRC_CNT(&port->uart.state->xmit.head,
- &port->uart.state->xmit.tail,
- UART_XMIT_SIZE));
-
- /* kick the virtual DMA controller */
- mn10300_serial_en_tx_intr(port);
-
- _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx",
- *port->_control, *port->_intr, *port->_status,
- *port->_tmxmd,
- (port->div_timer == MNSCx_DIV_TIMER_8BIT) ?
- *(volatile u8 *)port->_tmxbr : *port->_tmxbr,
- *port->tx_icr);
-}
-
-/*
- * transmit a high-priority XON/XOFF character
- */
-static void mn10300_serial_send_xchar(struct uart_port *_port, char ch)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
- unsigned long flags;
-
- _enter("%s,%02x", port->name, ch);
-
- if (likely(port->gdbstub)) {
- port->tx_xchar = ch;
- if (ch) {
- spin_lock_irqsave(&port->uart.lock, flags);
- mn10300_serial_en_tx_intr(port);
- spin_unlock_irqrestore(&port->uart.lock, flags);
- }
- }
-}
-
-/*
- * stop receiving characters
- * - called whilst the port is being closed
- */
-static void mn10300_serial_stop_rx(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- u16 ctr;
-
- _enter("%s", port->name);
-
- ctr = *port->_control;
- ctr &= ~SC01CTR_RXE;
- *port->_control = ctr;
-
- mn10300_serial_dis_rx_intr(port);
-}
-
-/*
- * enable modem status interrupts
- */
-static void mn10300_serial_enable_ms(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- u16 ctr, cts;
-
- _enter("%s", port->name);
-
- if (port->type == PORT_MN10300_CTS) {
- /* want to interrupt when CTS goes low if CTS is now high and
- * vice versa
- */
- port->tx_cts = *port->_status;
-
- cts = (port->tx_cts & SC2STR_CTS) ?
- SC2CTR_TWE : SC2CTR_TWE | SC2CTR_TWS;
-
- ctr = *port->_control;
- ctr &= ~SC2CTR_TWS;
- ctr |= cts;
- *port->_control = ctr;
-
- mn10300_serial_en_tx_intr(port);
- }
-}
-
-/*
- * transmit or cease transmitting a break signal
- */
-static void mn10300_serial_break_ctl(struct uart_port *_port, int ctl)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
- unsigned long flags;
-
- _enter("%s,%d", port->name, ctl);
-
- spin_lock_irqsave(&port->uart.lock, flags);
- if (ctl) {
- /* tell the virtual DMA handler to assert BREAK */
- port->tx_flags |= MNSCx_TX_BREAK;
- mn10300_serial_en_tx_intr(port);
- } else {
- port->tx_flags &= ~MNSCx_TX_BREAK;
- *port->_control &= ~SC01CTR_BKE;
- mn10300_serial_en_tx_intr(port);
- }
- spin_unlock_irqrestore(&port->uart.lock, flags);
-}
-
-/*
- * grab the interrupts and enable the port for reception
- */
-static int mn10300_serial_startup(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
- struct mn10300_serial_int *pint;
-
- _enter("%s{%d}", port->name, port->gdbstub);
-
- if (unlikely(port->gdbstub))
- return -EBUSY;
-
- /* allocate an Rx buffer for the virtual DMA handler */
- port->rx_buffer = kmalloc(MNSC_BUFFER_SIZE, GFP_KERNEL);
- if (!port->rx_buffer)
- return -ENOMEM;
-
- port->rx_inp = port->rx_outp = 0;
- port->tx_flags = 0;
-
- /* finally, enable the device */
- *port->_intr = SC01ICR_TI;
- *port->_control |= SC01CTR_TXE | SC01CTR_RXE;
-
- pint = &mn10300_serial_int_tbl[port->rx_irq];
- pint->port = port;
- pint->vdma = mn10300_serial_vdma_rx_handler;
- pint = &mn10300_serial_int_tbl[port->tx_irq];
- pint->port = port;
- pint->vdma = mn10300_serial_vdma_tx_handler;
-
- irq_set_chip(port->rx_irq, &mn10300_serial_low_pic);
- irq_set_chip(port->tx_irq, &mn10300_serial_low_pic);
- irq_set_chip(port->tm_irq, &mn10300_serial_pic);
-
- if (request_irq(port->rx_irq, mn10300_serial_interrupt,
- IRQF_NOBALANCING,
- port->rx_name, port) < 0)
- goto error;
-
- if (request_irq(port->tx_irq, mn10300_serial_interrupt,
- IRQF_NOBALANCING,
- port->tx_name, port) < 0)
- goto error2;
-
- if (request_irq(port->tm_irq, mn10300_serial_interrupt,
- IRQF_NOBALANCING,
- port->tm_name, port) < 0)
- goto error3;
- mn10300_serial_mask_ack(port->tm_irq);
-
- return 0;
-
-error3:
- free_irq(port->tx_irq, port);
-error2:
- free_irq(port->rx_irq, port);
-error:
- kfree(port->rx_buffer);
- port->rx_buffer = NULL;
- return -EBUSY;
-}
-
-/*
- * shutdown the port and release interrupts
- */
-static void mn10300_serial_shutdown(struct uart_port *_port)
-{
- unsigned long flags;
- u16 x;
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- spin_lock_irqsave(&_port->lock, flags);
- mn10300_serial_dis_tx_intr(port);
-
- *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL);
- x = *port->rx_icr;
- port->tx_flags = 0;
- spin_unlock_irqrestore(&_port->lock, flags);
-
- /* disable the serial port and its baud rate timer */
- *port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE);
- *port->_tmxmd = 0;
-
- if (port->rx_buffer) {
- void *buf = port->rx_buffer;
- port->rx_buffer = NULL;
- kfree(buf);
- }
-
- /* disable all intrs */
- free_irq(port->tm_irq, port);
- free_irq(port->rx_irq, port);
- free_irq(port->tx_irq, port);
-
- mn10300_serial_int_tbl[port->tx_irq].port = NULL;
- mn10300_serial_int_tbl[port->rx_irq].port = NULL;
-}
-
-/*
- * this routine is called to set the UART divisor registers to match the
- * specified baud rate for a serial port.
- */
-static void mn10300_serial_change_speed(struct mn10300_serial_port *port,
- struct ktermios *new,
- struct ktermios *old)
-{
- unsigned long flags;
- unsigned long ioclk = port->ioclk;
- unsigned cflag;
- int baud, bits, xdiv, tmp;
- u16 tmxbr, scxctr;
- u8 tmxmd, battempt;
- u8 div_timer = port->div_timer;
-
- _enter("%s{%lu}", port->name, ioclk);
-
- /* byte size and parity */
- cflag = new->c_cflag;
- switch (cflag & CSIZE) {
- case CS7: scxctr = SC01CTR_CLN_7BIT; bits = 9; break;
- case CS8: scxctr = SC01CTR_CLN_8BIT; bits = 10; break;
- default: scxctr = SC01CTR_CLN_8BIT; bits = 10; break;
- }
-
- if (cflag & CSTOPB) {
- scxctr |= SC01CTR_STB_2BIT;
- bits++;
- }
-
- if (cflag & PARENB) {
- bits++;
- if (cflag & PARODD)
- scxctr |= SC01CTR_PB_ODD;
-#ifdef CMSPAR
- else if (cflag & CMSPAR)
- scxctr |= SC01CTR_PB_FIXED0;
-#endif
- else
- scxctr |= SC01CTR_PB_EVEN;
- }
-
- /* Determine divisor based on baud rate */
- battempt = 0;
-
- switch (port->uart.line) {
-#ifdef CONFIG_MN10300_TTYSM0
- case 0: /* ttySM0 */
-#if defined(CONFIG_MN10300_TTYSM0_TIMER8)
- scxctr |= SC0CTR_CK_TM8UFLOW_8;
-#elif defined(CONFIG_MN10300_TTYSM0_TIMER0)
- scxctr |= SC0CTR_CK_TM0UFLOW_8;
-#elif defined(CONFIG_MN10300_TTYSM0_TIMER2)
- scxctr |= SC0CTR_CK_TM2UFLOW_8;
-#else
-#error "Unknown config for ttySM0"
-#endif
- break;
-#endif /* CONFIG_MN10300_TTYSM0 */
-
-#ifdef CONFIG_MN10300_TTYSM1
- case 1: /* ttySM1 */
-#if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3)
-#if defined(CONFIG_MN10300_TTYSM1_TIMER9)
- scxctr |= SC1CTR_CK_TM9UFLOW_8;
-#elif defined(CONFIG_MN10300_TTYSM1_TIMER3)
- scxctr |= SC1CTR_CK_TM3UFLOW_8;
-#else
-#error "Unknown config for ttySM1"
-#endif
-#else /* CONFIG_AM33_2 || CONFIG_AM33_3 */
-#if defined(CONFIG_MN10300_TTYSM1_TIMER12)
- scxctr |= SC1CTR_CK_TM12UFLOW_8;
-#else
-#error "Unknown config for ttySM1"
-#endif
-#endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */
- break;
-#endif /* CONFIG_MN10300_TTYSM1 */
-
-#ifdef CONFIG_MN10300_TTYSM2
- case 2: /* ttySM2 */
-#if defined(CONFIG_AM33_2)
-#if defined(CONFIG_MN10300_TTYSM2_TIMER10)
- scxctr |= SC2CTR_CK_TM10UFLOW;
-#else
-#error "Unknown config for ttySM2"
-#endif
-#else /* CONFIG_AM33_2 */
-#if defined(CONFIG_MN10300_TTYSM2_TIMER9)
- scxctr |= SC2CTR_CK_TM9UFLOW_8;
-#elif defined(CONFIG_MN10300_TTYSM2_TIMER1)
- scxctr |= SC2CTR_CK_TM1UFLOW_8;
-#elif defined(CONFIG_MN10300_TTYSM2_TIMER3)
- scxctr |= SC2CTR_CK_TM3UFLOW_8;
-#else
-#error "Unknown config for ttySM2"
-#endif
-#endif /* CONFIG_AM33_2 */
- break;
-#endif /* CONFIG_MN10300_TTYSM2 */
-
- default:
- break;
- }
-
-try_alternative:
- baud = uart_get_baud_rate(&port->uart, new, old, 0,
- port->ioclk / 8);
-
- _debug("ALT %d [baud %d]", battempt, baud);
-
- if (!baud)
- baud = 9600; /* B0 transition handled in rs_set_termios */
- xdiv = 1;
- if (baud == 134) {
- baud = 269; /* 134 is really 134.5 */
- xdiv = 2;
- }
-
- if (baud == 38400 &&
- (port->uart.flags & UPF_SPD_MASK) == UPF_SPD_CUST
- ) {
- _debug("CUSTOM %u", port->uart.custom_divisor);
-
- if (div_timer == MNSCx_DIV_TIMER_16BIT) {
- if (port->uart.custom_divisor <= 65535) {
- tmxmd = TM8MD_SRC_IOCLK;
- tmxbr = port->uart.custom_divisor;
- port->uart.uartclk = ioclk;
- goto timer_okay;
- }
- if (port->uart.custom_divisor / 8 <= 65535) {
- tmxmd = TM8MD_SRC_IOCLK_8;
- tmxbr = port->uart.custom_divisor / 8;
- port->uart.custom_divisor = tmxbr * 8;
- port->uart.uartclk = ioclk / 8;
- goto timer_okay;
- }
- if (port->uart.custom_divisor / 32 <= 65535) {
- tmxmd = TM8MD_SRC_IOCLK_32;
- tmxbr = port->uart.custom_divisor / 32;
- port->uart.custom_divisor = tmxbr * 32;
- port->uart.uartclk = ioclk / 32;
- goto timer_okay;
- }
-
- } else if (div_timer == MNSCx_DIV_TIMER_8BIT) {
- if (port->uart.custom_divisor <= 255) {
- tmxmd = TM2MD_SRC_IOCLK;
- tmxbr = port->uart.custom_divisor;
- port->uart.uartclk = ioclk;
- goto timer_okay;
- }
- if (port->uart.custom_divisor / 8 <= 255) {
- tmxmd = TM2MD_SRC_IOCLK_8;
- tmxbr = port->uart.custom_divisor / 8;
- port->uart.custom_divisor = tmxbr * 8;
- port->uart.uartclk = ioclk / 8;
- goto timer_okay;
- }
- if (port->uart.custom_divisor / 32 <= 255) {
- tmxmd = TM2MD_SRC_IOCLK_32;
- tmxbr = port->uart.custom_divisor / 32;
- port->uart.custom_divisor = tmxbr * 32;
- port->uart.uartclk = ioclk / 32;
- goto timer_okay;
- }
- }
- }
-
- switch (div_timer) {
- case MNSCx_DIV_TIMER_16BIT:
- port->uart.uartclk = ioclk;
- tmxmd = TM8MD_SRC_IOCLK;
- tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 65535)
- goto timer_okay;
-
- port->uart.uartclk = ioclk / 8;
- tmxmd = TM8MD_SRC_IOCLK_8;
- tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 65535)
- goto timer_okay;
-
- port->uart.uartclk = ioclk / 32;
- tmxmd = TM8MD_SRC_IOCLK_32;
- tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 65535)
- goto timer_okay;
- break;
-
- case MNSCx_DIV_TIMER_8BIT:
- port->uart.uartclk = ioclk;
- tmxmd = TM2MD_SRC_IOCLK;
- tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 255)
- goto timer_okay;
-
- port->uart.uartclk = ioclk / 8;
- tmxmd = TM2MD_SRC_IOCLK_8;
- tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 255)
- goto timer_okay;
-
- port->uart.uartclk = ioclk / 32;
- tmxmd = TM2MD_SRC_IOCLK_32;
- tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1;
- if (tmp > 0 && tmp <= 255)
- goto timer_okay;
- break;
-
- default:
- BUG();
- return;
- }
-
- /* refuse to change to a baud rate we can't support */
- _debug("CAN'T SUPPORT");
-
- switch (battempt) {
- case 0:
- if (old) {
- new->c_cflag &= ~CBAUD;
- new->c_cflag |= (old->c_cflag & CBAUD);
- battempt = 1;
- goto try_alternative;
- }
-
- case 1:
- /* as a last resort, if the quotient is zero, default to 9600
- * bps */
- new->c_cflag &= ~CBAUD;
- new->c_cflag |= B9600;
- battempt = 2;
- goto try_alternative;
-
- default:
- /* hmmm... can't seem to support 9600 either
- * - we could try iterating through the speeds we know about to
- * find the lowest
- */
- new->c_cflag &= ~CBAUD;
- new->c_cflag |= B0;
-
- if (div_timer == MNSCx_DIV_TIMER_16BIT)
- tmxmd = TM8MD_SRC_IOCLK_32;
- else if (div_timer == MNSCx_DIV_TIMER_8BIT)
- tmxmd = TM2MD_SRC_IOCLK_32;
- tmxbr = 1;
-
- port->uart.uartclk = ioclk / 32;
- break;
- }
-timer_okay:
-
- _debug("UARTCLK: %u / %hu", port->uart.uartclk, tmxbr);
-
- /* make the changes */
- spin_lock_irqsave(&port->uart.lock, flags);
-
- uart_update_timeout(&port->uart, new->c_cflag, baud);
-
- /* set the timer to produce the required baud rate */
- switch (div_timer) {
- case MNSCx_DIV_TIMER_16BIT:
- *port->_tmxmd = 0;
- *port->_tmxbr = tmxbr;
- *port->_tmxmd = TM8MD_INIT_COUNTER;
- *port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;
- break;
-
- case MNSCx_DIV_TIMER_8BIT:
- *port->_tmxmd = 0;
- *(volatile u8 *) port->_tmxbr = (u8) tmxbr;
- *port->_tmxmd = TM2MD_INIT_COUNTER;
- *port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;
- break;
- }
-
- /* CTS flow control flag and modem status interrupts */
- scxctr &= ~(SC2CTR_TWE | SC2CTR_TWS);
-
- if (port->type == PORT_MN10300_CTS && cflag & CRTSCTS) {
- /* want to interrupt when CTS goes low if CTS is now
- * high and vice versa
- */
- port->tx_cts = *port->_status;
-
- if (port->tx_cts & SC2STR_CTS)
- scxctr |= SC2CTR_TWE;
- else
- scxctr |= SC2CTR_TWE | SC2CTR_TWS;
- }
-
- /* set up parity check flag */
- port->uart.read_status_mask = (1 << TTY_NORMAL) | (1 << TTY_OVERRUN);
- if (new->c_iflag & INPCK)
- port->uart.read_status_mask |=
- (1 << TTY_PARITY) | (1 << TTY_FRAME);
- if (new->c_iflag & (BRKINT | PARMRK))
- port->uart.read_status_mask |= (1 << TTY_BREAK);
-
- /* characters to ignore */
- port->uart.ignore_status_mask = 0;
- if (new->c_iflag & IGNPAR)
- port->uart.ignore_status_mask |=
- (1 << TTY_PARITY) | (1 << TTY_FRAME);
- if (new->c_iflag & IGNBRK) {
- port->uart.ignore_status_mask |= (1 << TTY_BREAK);
- /*
- * If we're ignoring parity and break indicators,
- * ignore overruns to (for real raw support).
- */
- if (new->c_iflag & IGNPAR)
- port->uart.ignore_status_mask |= (1 << TTY_OVERRUN);
- }
-
- /* Ignore all characters if CREAD is not set */
- if ((new->c_cflag & CREAD) == 0)
- port->uart.ignore_status_mask |= (1 << TTY_NORMAL);
-
- scxctr |= SC01CTR_TXE | SC01CTR_RXE;
- scxctr |= *port->_control & SC01CTR_BKE;
- *port->_control = scxctr;
-
- spin_unlock_irqrestore(&port->uart.lock, flags);
-}
-
-/*
- * set the terminal I/O parameters
- */
-static void mn10300_serial_set_termios(struct uart_port *_port,
- struct ktermios *new,
- struct ktermios *old)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s,%p,%p", port->name, new, old);
-
- mn10300_serial_change_speed(port, new, old);
-
- /* handle turning off CRTSCTS */
- if (!(new->c_cflag & CRTSCTS)) {
- u16 ctr = *port->_control;
- ctr &= ~SC2CTR_TWE;
- *port->_control = ctr;
- }
-
- /* change Transfer bit-order (LSB/MSB) */
- if (new->c_cflag & CODMSB)
- *port->_control |= SC01CTR_OD_MSBFIRST; /* MSB MODE */
- else
- *port->_control &= ~SC01CTR_OD_MSBFIRST; /* LSB MODE */
-}
-
-/*
- * return description of port type
- */
-static const char *mn10300_serial_type(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- if (port->uart.type == PORT_MN10300_CTS)
- return "MN10300 SIF_CTS";
-
- return "MN10300 SIF";
-}
-
-/*
- * release I/O and memory regions in use by port
- */
-static void mn10300_serial_release_port(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- release_mem_region((unsigned long) port->_iobase, 16);
-}
-
-/*
- * request I/O and memory regions for port
- */
-static int mn10300_serial_request_port(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- request_mem_region((unsigned long) port->_iobase, 16, port->name);
- return 0;
-}
-
-/*
- * configure the type and reserve the ports
- */
-static void mn10300_serial_config_port(struct uart_port *_port, int type)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
-
- _enter("%s", port->name);
-
- port->uart.type = PORT_MN10300;
-
- if (port->options & MNSCx_OPT_CTS)
- port->uart.type = PORT_MN10300_CTS;
-
- mn10300_serial_request_port(_port);
-}
-
-/*
- * verify serial parameters are suitable for this port type
- */
-static int mn10300_serial_verify_port(struct uart_port *_port,
- struct serial_struct *ss)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
- void *mapbase = (void *) (unsigned long) port->uart.mapbase;
-
- _enter("%s", port->name);
-
- /* these things may not be changed */
- if (ss->irq != port->uart.irq ||
- ss->port != port->uart.iobase ||
- ss->io_type != port->uart.iotype ||
- ss->iomem_base != mapbase ||
- ss->iomem_reg_shift != port->uart.regshift ||
- ss->hub6 != port->uart.hub6 ||
- ss->xmit_fifo_size != port->uart.fifosize)
- return -EINVAL;
-
- /* type may be changed on a port that supports CTS */
- if (ss->type != port->uart.type) {
- if (!(port->options & MNSCx_OPT_CTS))
- return -EINVAL;
-
- if (ss->type != PORT_MN10300 &&
- ss->type != PORT_MN10300_CTS)
- return -EINVAL;
- }
-
- return 0;
-}
-
-/*
- * initialise the MN10300 on-chip UARTs
- */
-static int __init mn10300_serial_init(void)
-{
- struct mn10300_serial_port *port;
- int ret, i;
-
- printk(KERN_INFO "%s version %s (%s)\n",
- serial_name, serial_version, serial_revdate);
-
-#if defined(CONFIG_MN10300_TTYSM2) && defined(CONFIG_AM33_2)
- {
- int tmp;
- SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */
- tmp = SC2TIM;
- }
-#endif
-
- set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL),
- mn10300_serial_vdma_interrupt);
-
- ret = uart_register_driver(&mn10300_serial_driver);
- if (!ret) {
- for (i = 0 ; i < NR_PORTS ; i++) {
- port = mn10300_serial_ports[i];
- if (!port || port->gdbstub)
- continue;
-
- switch (port->clock_src) {
- case MNSCx_CLOCK_SRC_IOCLK:
- port->ioclk = MN10300_IOCLK;
- break;
-
-#ifdef MN10300_IOBCLK
- case MNSCx_CLOCK_SRC_IOBCLK:
- port->ioclk = MN10300_IOBCLK;
- break;
-#endif
- default:
- BUG();
- }
-
- ret = uart_add_one_port(&mn10300_serial_driver,
- &port->uart);
-
- if (ret < 0) {
- _debug("ERROR %d", -ret);
- break;
- }
- }
-
- if (ret)
- uart_unregister_driver(&mn10300_serial_driver);
- }
-
- return ret;
-}
-
-__initcall(mn10300_serial_init);
-
-
-#ifdef CONFIG_MN10300_TTYSM_CONSOLE
-
-/*
- * print a string to the serial port without disturbing the real user of the
- * port too much
- * - the console must be locked by the caller
- */
-static void mn10300_serial_console_write(struct console *co,
- const char *s, unsigned count)
-{
- struct mn10300_serial_port *port;
- unsigned i;
- u16 scxctr;
- u8 tmxmd;
- unsigned long flags;
- int locked = 1;
-
- port = mn10300_serial_ports[co->index];
-
- local_irq_save(flags);
- if (port->uart.sysrq) {
- /* mn10300_serial_interrupt() already took the lock */
- locked = 0;
- } else if (oops_in_progress) {
- locked = spin_trylock(&port->uart.lock);
- } else
- spin_lock(&port->uart.lock);
-
- /* firstly hijack the serial port from the "virtual DMA" controller */
- mn10300_serial_dis_tx_intr(port);
-
- /* the transmitter may be disabled */
- scxctr = *port->_control;
- if (!(scxctr & SC01CTR_TXE)) {
- /* restart the UART clock */
- tmxmd = *port->_tmxmd;
-
- switch (port->div_timer) {
- case MNSCx_DIV_TIMER_16BIT:
- *port->_tmxmd = 0;
- *port->_tmxmd = TM8MD_INIT_COUNTER;
- *port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE;
- break;
-
- case MNSCx_DIV_TIMER_8BIT:
- *port->_tmxmd = 0;
- *port->_tmxmd = TM2MD_INIT_COUNTER;
- *port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE;
- break;
- }
-
- /* enable the transmitter */
- *port->_control = (scxctr & ~SC01CTR_BKE) | SC01CTR_TXE;
-
- } else if (scxctr & SC01CTR_BKE) {
- /* stop transmitting BREAK */
- *port->_control = (scxctr & ~SC01CTR_BKE);
- }
-
- /* send the chars into the serial port (with LF -> LFCR conversion) */
- for (i = 0; i < count; i++) {
- char ch = *s++;
-
- while (*port->_status & SC01STR_TBF)
- continue;
- *port->_txb = ch;
-
- if (ch == 0x0a) {
- while (*port->_status & SC01STR_TBF)
- continue;
- *port->_txb = 0xd;
- }
- }
-
- /* can't let the transmitter be turned off if it's actually
- * transmitting */
- while (*port->_status & (SC01STR_TXF | SC01STR_TBF))
- continue;
-
- /* disable the transmitter if we re-enabled it */
- if (!(scxctr & SC01CTR_TXE))
- *port->_control = scxctr;
-
- mn10300_serial_en_tx_intr(port);
-
- if (locked)
- spin_unlock(&port->uart.lock);
- local_irq_restore(flags);
-}
-
-/*
- * set up a serial port as a console
- * - construct a cflag setting for the first rs_open()
- * - initialize the serial port
- * - return non-zero if we didn't find a serial port.
- */
-static int __init mn10300_serial_console_setup(struct console *co,
- char *options)
-{
- struct mn10300_serial_port *port;
- int i, parity = 'n', baud = 9600, bits = 8, flow = 0;
-
- for (i = 0 ; i < NR_PORTS ; i++) {
- port = mn10300_serial_ports[i];
- if (port && !port->gdbstub && port->uart.line == co->index)
- goto found_device;
- }
-
- return -ENODEV;
-
-found_device:
- switch (port->clock_src) {
- case MNSCx_CLOCK_SRC_IOCLK:
- port->ioclk = MN10300_IOCLK;
- break;
-
-#ifdef MN10300_IOBCLK
- case MNSCx_CLOCK_SRC_IOBCLK:
- port->ioclk = MN10300_IOBCLK;
- break;
-#endif
- default:
- BUG();
- }
-
- if (options)
- uart_parse_options(options, &baud, &parity, &bits, &flow);
-
- return uart_set_options(&port->uart, co, baud, parity, bits, flow);
-}
-
-/*
- * register console
- */
-static int __init mn10300_serial_console_init(void)
-{
- register_console(&mn10300_serial_console);
- return 0;
-}
-
-console_initcall(mn10300_serial_console_init);
-#endif
-
-#ifdef CONFIG_CONSOLE_POLL
-/*
- * Polled character reception for the kernel debugger
- */
-static int mn10300_serial_poll_get_char(struct uart_port *_port)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
- unsigned ix;
- u8 st, ch;
-
- _enter("%s", port->name);
-
- if (mn10300_serial_int_tbl[port->rx_irq].port != NULL) {
- do {
- /* pull chars out of the hat */
- ix = READ_ONCE(port->rx_outp);
- if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0)
- return NO_POLL_CHAR;
-
- /*
- * READ_ONCE() enforces dependency, but dangerous
- * through integer!!!
- */
- ch = port->rx_buffer[ix++];
- st = port->rx_buffer[ix++];
- smp_mb();
- port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1);
-
- } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF));
- } else {
- do {
- st = *port->_status;
- if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF))
- continue;
- } while (!(st & SC01STR_RBF));
-
- ch = *port->_rxb;
- }
-
- return ch;
-}
-
-
-/*
- * Polled character transmission for the kernel debugger
- */
-static void mn10300_serial_poll_put_char(struct uart_port *_port,
- unsigned char ch)
-{
- struct mn10300_serial_port *port =
- container_of(_port, struct mn10300_serial_port, uart);
- u8 intr, tmp;
-
- /* wait for the transmitter to finish anything it might be doing (and
- * this includes the virtual DMA handler, so it might take a while) */
- while (*port->_status & (SC01STR_TBF | SC01STR_TXF))
- continue;
-
- /* disable the Tx ready interrupt */
- intr = *port->_intr;
- *port->_intr = intr & ~SC01ICR_TI;
- tmp = *port->_intr;
-
- if (ch == 0x0a) {
- *port->_txb = 0x0d;
- while (*port->_status & SC01STR_TBF)
- continue;
- }
-
- *port->_txb = ch;
- while (*port->_status & SC01STR_TBF)
- continue;
-
- /* restore the Tx interrupt flag */
- *port->_intr = intr;
- tmp = *port->_intr;
-}
-
-#endif /* CONFIG_CONSOLE_POLL */
diff --git a/arch/mn10300/kernel/mn10300-serial.h b/arch/mn10300/kernel/mn10300-serial.h
deleted file mode 100644
index 01791c68ea1f..000000000000
--- a/arch/mn10300/kernel/mn10300-serial.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* MN10300 On-chip serial port driver definitions
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#ifndef _MN10300_SERIAL_H
-#define _MN10300_SERIAL_H
-
-#ifndef __ASSEMBLY__
-#include <linux/serial_core.h>
-#include <linux/termios.h>
-#endif
-
-#include <asm/page.h>
-#include <asm/serial-regs.h>
-
-#define NR_PORTS 3 /* should be set 3 or 9 or 16 */
-
-#define MNSC_BUFFER_SIZE +(PAGE_SIZE / 2)
-
-/* intr_flags bits */
-#define MNSCx_RX_AVAIL 0x01
-#define MNSCx_RX_OVERF 0x02
-#define MNSCx_TX_SPACE 0x04
-#define MNSCx_TX_EMPTY 0x08
-
-/* tx_flags bits */
-#define MNSCx_TX_BREAK 0x01
-#define MNSCx_TX_STOP 0x02
-
-#ifndef __ASSEMBLY__
-
-struct mn10300_serial_port {
- char *rx_buffer; /* reception buffer base */
- unsigned rx_inp; /* pointer to rx input offset */
- unsigned rx_outp; /* pointer to rx output offset */
- u8 tx_xchar; /* high-priority XON/XOFF buffer */
- u8 tx_flags; /* transmit break/stop request */
- u8 intr_flags; /* interrupt flags */
- volatile u16 *rx_icr; /* Rx interrupt control register */
- volatile u16 *tx_icr; /* Tx interrupt control register */
- int rx_irq; /* reception IRQ */
- int tx_irq; /* transmission IRQ */
- int tm_irq; /* timer IRQ */
-
- const char *name; /* name of serial port */
- const char *rx_name; /* Rx interrupt handler name of serial port */
- const char *tx_name; /* Tx interrupt handler name of serial port */
- const char *tm_name; /* Timer interrupt handler name */
- unsigned short type; /* type of serial port */
- unsigned char isconsole; /* T if it's a console */
- volatile void *_iobase; /* pointer to base of I/O control regs */
- volatile u16 *_control; /* control register pointer */
- volatile u8 *_status; /* status register pointer */
- volatile u8 *_intr; /* interrupt register pointer */
- volatile u8 *_rxb; /* receive buffer register pointer */
- volatile u8 *_txb; /* transmit buffer register pointer */
- volatile u16 *_tmicr; /* timer interrupt control register */
- volatile u8 *_tmxmd; /* baud rate timer mode register */
- volatile u16 *_tmxbr; /* baud rate timer base register */
-
- /* this must come down here so that assembly can use BSET to access the
- * above fields */
- struct uart_port uart;
-
- unsigned short rx_brk; /* current break reception status */
- u16 tx_cts; /* current CTS status */
- int gdbstub; /* preemptively stolen by GDB stub */
-
- u8 clock_src; /* clock source */
-#define MNSCx_CLOCK_SRC_IOCLK 0
-#define MNSCx_CLOCK_SRC_IOBCLK 1
-
- u8 div_timer; /* timer used as divisor */
-#define MNSCx_DIV_TIMER_16BIT 0
-#define MNSCx_DIV_TIMER_8BIT 1
-
- u16 options; /* options */
-#define MNSCx_OPT_CTS 0x0001
-
- unsigned long ioclk; /* base clock rate */
-};
-
-#ifdef CONFIG_MN10300_TTYSM0
-extern struct mn10300_serial_port mn10300_serial_port_sif0;
-#endif
-
-#ifdef CONFIG_MN10300_TTYSM1
-extern struct mn10300_serial_port mn10300_serial_port_sif1;
-#endif
-
-#ifdef CONFIG_MN10300_TTYSM2
-extern struct mn10300_serial_port mn10300_serial_port_sif2;
-#endif
-
-extern struct mn10300_serial_port *mn10300_serial_ports[];
-
-struct mn10300_serial_int {
- struct mn10300_serial_port *port;
- asmlinkage void (*vdma)(void);
-};
-
-extern struct mn10300_serial_int mn10300_serial_int_tbl[];
-
-extern asmlinkage void mn10300_serial_vdma_interrupt(void);
-extern asmlinkage void mn10300_serial_vdma_rx_handler(void);
-extern asmlinkage void mn10300_serial_vdma_tx_handler(void);
-
-#endif /* __ASSEMBLY__ */
-
-#if defined(CONFIG_GDBSTUB_ON_TTYSM0)
-#define SCgSTR SC0STR
-#define SCgRXB SC0RXB
-#define SCgRXIRQ SC0RXIRQ
-#elif defined(CONFIG_GDBSTUB_ON_TTYSM1)
-#define SCgSTR SC1STR
-#define SCgRXB SC1RXB
-#define SCgRXIRQ SC1RXIRQ
-#elif defined(CONFIG_GDBSTUB_ON_TTYSM2)
-#define SCgSTR SC2STR
-#define SCgRXB SC2RXB
-#define SCgRXIRQ SC2RXIRQ
-#endif
-
-#endif /* _MN10300_SERIAL_H */
diff --git a/arch/mn10300/kernel/mn10300-watchdog-low.S b/arch/mn10300/kernel/mn10300-watchdog-low.S
deleted file mode 100644
index 34f8773de7d0..000000000000
--- a/arch/mn10300/kernel/mn10300-watchdog-low.S
+++ /dev/null
@@ -1,66 +0,0 @@
-###############################################################################
-#
-# MN10300 Watchdog interrupt handler
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/intctl-regs.h>
-#include <asm/timer-regs.h>
-#include <asm/frame.inc>
-#include <linux/threads.h>
-
- .text
-
-###############################################################################
-#
-# Watchdog handler entry point
-# - special non-maskable interrupt
-#
-###############################################################################
- .globl watchdog_handler
- .type watchdog_handler,@function
-watchdog_handler:
- add -4,sp
- SAVE_ALL
-
- mov 0xffffffff,d0
- mov d0,(REG_ORIG_D0,fp)
-
- mov fp,d0
- lsr 2,d1
- call watchdog_interrupt[],0 # watchdog_interrupt(regs,irq)
-
- jmp ret_from_intr
-
- .size watchdog_handler,.-watchdog_handler
-
-###############################################################################
-#
-# Watchdog touch entry point
-# - kept to absolute minimum (unfortunately, it's prototyped in linux/nmi.h so
-# we can't inline it)
-#
-###############################################################################
- .globl arch_touch_nmi_watchdog
- .type arch_touch_nmi_watchdog,@function
-arch_touch_nmi_watchdog:
- clr d0
- clr d1
- mov watchdog_alert_counter, a0
- setlb
- mov d0, (a0+)
- inc d1
- cmp NR_CPUS, d1
- lne
- ret [],0
-
- .size arch_touch_nmi_watchdog,.-arch_touch_nmi_watchdog
diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c
deleted file mode 100644
index 0d5641beadf5..000000000000
--- a/arch/mn10300/kernel/mn10300-watchdog.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* MN10300 Watchdog timer
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- * - Derived from arch/i386/kernel/nmi.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/nmi.h>
-#include <asm/processor.h>
-#include <linux/atomic.h>
-#include <asm/intctl-regs.h>
-#include <asm/rtc-regs.h>
-#include <asm/div64.h>
-#include <asm/smp.h>
-#include <asm/gdb-stub.h>
-#include <proc/clock.h>
-
-static DEFINE_SPINLOCK(watchdog_print_lock);
-static unsigned int watchdog;
-static unsigned int watchdog_hz = 1;
-unsigned int watchdog_alert_counter[NR_CPUS];
-
-EXPORT_SYMBOL(arch_touch_nmi_watchdog);
-
-/*
- * the best way to detect whether a CPU has a 'hard lockup' problem
- * is to check its timer makes IRQ counts. If they are not
- * changing then that CPU has some problem.
- *
- * since NMIs dont listen to _any_ locks, we have to be extremely
- * careful not to rely on unsafe variables. The printk might lock
- * up though, so we have to break up any console locks first ...
- * [when there will be more tty-related locks, break them up
- * here too!]
- */
-static unsigned int last_irq_sums[NR_CPUS];
-
-int __init check_watchdog(void)
-{
- irq_cpustat_t tmp[1];
-
- printk(KERN_INFO "Testing Watchdog... ");
-
- memcpy(tmp, irq_stat, sizeof(tmp));
- local_irq_enable();
- mdelay((10 * 1000) / watchdog_hz); /* wait 10 ticks */
- local_irq_disable();
-
- if (nmi_count(0) - tmp[0].__nmi_count <= 5) {
- printk(KERN_WARNING "CPU#%d: Watchdog appears to be stuck!\n",
- 0);
- return -1;
- }
-
- printk(KERN_INFO "OK.\n");
-
- /* now that we know it works we can reduce NMI frequency to something
- * more reasonable; makes a difference in some configs
- */
- watchdog_hz = 1;
-
- return 0;
-}
-
-static int __init setup_watchdog(char *str)
-{
- unsigned tmp;
- int opt;
- u8 ctr;
-
- get_option(&str, &opt);
- if (opt != 1)
- return 0;
-
- watchdog = opt;
- if (watchdog) {
- set_intr_stub(EXCEP_WDT, watchdog_handler);
- ctr = WDCTR_WDCK_65536th;
- WDCTR = WDCTR_WDRST | ctr;
- WDCTR = ctr;
- tmp = WDCTR;
-
- tmp = __muldiv64u(1 << (16 + ctr * 2), 1000000, MN10300_WDCLK);
- tmp = 1000000000 / tmp;
- watchdog_hz = (tmp + 500) / 1000;
- }
-
- return 1;
-}
-
-__setup("watchdog=", setup_watchdog);
-
-void __init watchdog_go(void)
-{
- u8 wdt;
-
- if (watchdog) {
- printk(KERN_INFO "Watchdog: running at %uHz\n", watchdog_hz);
- wdt = WDCTR & ~WDCTR_WDCNE;
- WDCTR = wdt | WDCTR_WDRST;
- wdt = WDCTR;
- WDCTR = wdt | WDCTR_WDCNE;
- wdt = WDCTR;
-
- check_watchdog();
- }
-}
-
-#ifdef CONFIG_SMP
-static void watchdog_dump_register(void *dummy)
-{
- printk(KERN_ERR "--- Register Dump (CPU%d) ---\n", CPUID);
- show_registers(current_frame());
-}
-#endif
-
-asmlinkage
-void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
-{
- /*
- * Since current-> is always on the stack, and we always switch
- * the stack NMI-atomically, it's safe to use smp_processor_id().
- */
- int sum, cpu;
- int irq = NMIIRQ;
- u8 wdt, tmp;
-
- wdt = WDCTR & ~WDCTR_WDCNE;
- WDCTR = wdt;
- tmp = WDCTR;
- NMICR = NMICR_WDIF;
-
- nmi_count(smp_processor_id())++;
- kstat_incr_irq_this_cpu(irq);
-
- for_each_online_cpu(cpu) {
-
- sum = irq_stat[cpu].__irq_count;
-
- if ((last_irq_sums[cpu] == sum)
-#if defined(CONFIG_GDBSTUB) && defined(CONFIG_SMP)
- && !(CHK_GDBSTUB_BUSY()
- || atomic_read(&cpu_doing_single_step))
-#endif
- ) {
- /*
- * Ayiee, looks like this CPU is stuck ...
- * wait a few IRQs (5 seconds) before doing the oops ...
- */
- watchdog_alert_counter[cpu]++;
- if (watchdog_alert_counter[cpu] == 5 * watchdog_hz) {
- spin_lock(&watchdog_print_lock);
- /*
- * We are in trouble anyway, lets at least try
- * to get a message out.
- */
- bust_spinlocks(1);
- printk(KERN_ERR
- "NMI Watchdog detected LOCKUP on CPU%d,"
- " pc %08lx, registers:\n",
- cpu, regs->pc);
-#ifdef CONFIG_SMP
- printk(KERN_ERR
- "--- Register Dump (CPU%d) ---\n",
- CPUID);
-#endif
- show_registers(regs);
-#ifdef CONFIG_SMP
- smp_nmi_call_function(watchdog_dump_register,
- NULL, 1);
-#endif
- printk(KERN_NOTICE "console shuts up ...\n");
- console_silent();
- spin_unlock(&watchdog_print_lock);
- bust_spinlocks(0);
-#ifdef CONFIG_GDBSTUB
- if (CHK_GDBSTUB_BUSY_AND_ACTIVE())
- gdbstub_exception(regs, excep);
- else
- gdbstub_intercept(regs, excep);
-#endif
- do_exit(SIGSEGV);
- }
- } else {
- last_irq_sums[cpu] = sum;
- watchdog_alert_counter[cpu] = 0;
- }
- }
-
- WDCTR = wdt | WDCTR_WDRST;
- tmp = WDCTR;
- WDCTR = wdt | WDCTR_WDCNE;
- tmp = WDCTR;
-}
diff --git a/arch/mn10300/kernel/mn10300_ksyms.c b/arch/mn10300/kernel/mn10300_ksyms.c
deleted file mode 100644
index 66fb68d0ca8a..000000000000
--- a/arch/mn10300/kernel/mn10300_ksyms.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* MN10300 Miscellaneous and library kernel exports
- *
- * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/uaccess.h>
-#include <asm/pgtable.h>
-
-
-EXPORT_SYMBOL(empty_zero_page);
-
-EXPORT_SYMBOL(change_bit);
-EXPORT_SYMBOL(test_and_change_bit);
-
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(memset);
-
-EXPORT_SYMBOL(strncpy_from_user);
-EXPORT_SYMBOL(clear_user);
-EXPORT_SYMBOL(__clear_user);
-EXPORT_SYMBOL(strnlen_user);
-
-extern u64 __ashrdi3(u64, unsigned);
-extern u64 __ashldi3(u64, unsigned);
-extern u64 __lshrdi3(u64, unsigned);
-extern s64 __negdi2(s64);
-extern int __ucmpdi2(u64, u64);
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__negdi2);
-EXPORT_SYMBOL(__ucmpdi2);
diff --git a/arch/mn10300/kernel/module.c b/arch/mn10300/kernel/module.c
deleted file mode 100644
index 216ad23c9570..000000000000
--- a/arch/mn10300/kernel/module.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* MN10300 Kernel module helper routines
- *
- * Copyright (C) 2007, 2008, 2009 Red Hat, Inc. All Rights Reserved.
- * Written by Mark Salter (msalter@redhat.com)
- * - Derived from arch/i386/kernel/module.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Licence as published by
- * the Free Software Foundation; either version 2 of the Licence, 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 Licence for more details.
- *
- * You should have received a copy of the GNU General Public Licence
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/moduleloader.h>
-#include <linux/elf.h>
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/bug.h>
-
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt, ...)
-#endif
-
-static void reloc_put16(uint8_t *p, uint32_t val)
-{
- p[0] = val & 0xff;
- p[1] = (val >> 8) & 0xff;
-}
-
-static void reloc_put24(uint8_t *p, uint32_t val)
-{
- reloc_put16(p, val);
- p[2] = (val >> 16) & 0xff;
-}
-
-static void reloc_put32(uint8_t *p, uint32_t val)
-{
- reloc_put16(p, val);
- reloc_put16(p+2, val >> 16);
-}
-
-/*
- * apply a RELA relocation
- */
-int apply_relocate_add(Elf32_Shdr *sechdrs,
- const char *strtab,
- unsigned int symindex,
- unsigned int relsec,
- struct module *me)
-{
- unsigned int i, sym_diff_seen = 0;
- Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
- Elf32_Sym *sym;
- Elf32_Addr relocation, sym_diff_val = 0;
- uint8_t *location;
- uint32_t value;
-
- DEBUGP("Applying relocate section %u to %u\n",
- relsec, sechdrs[relsec].sh_info);
-
- for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
- /* this is where to make the change */
- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
- + rel[i].r_offset;
-
- /* this is the symbol the relocation is referring to (note that
- * all undefined symbols have been resolved by the caller) */
- sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
- + ELF32_R_SYM(rel[i].r_info);
-
- /* this is the adjustment to be made */
- relocation = sym->st_value + rel[i].r_addend;
-
- if (sym_diff_seen) {
- switch (ELF32_R_TYPE(rel[i].r_info)) {
- case R_MN10300_32:
- case R_MN10300_24:
- case R_MN10300_16:
- case R_MN10300_8:
- relocation -= sym_diff_val;
- sym_diff_seen = 0;
- break;
- default:
- printk(KERN_ERR "module %s: Unexpected SYM_DIFF relocation: %u\n",
- me->name, ELF32_R_TYPE(rel[i].r_info));
- return -ENOEXEC;
- }
- }
-
- switch (ELF32_R_TYPE(rel[i].r_info)) {
- /* for the first four relocation types, we simply
- * store the adjustment at the location given */
- case R_MN10300_32:
- reloc_put32(location, relocation);
- break;
- case R_MN10300_24:
- reloc_put24(location, relocation);
- break;
- case R_MN10300_16:
- reloc_put16(location, relocation);
- break;
- case R_MN10300_8:
- *location = relocation;
- break;
-
- /* for the next three relocation types, we write the
- * adjustment with the address subtracted over the
- * value at the location given */
- case R_MN10300_PCREL32:
- value = relocation - (uint32_t) location;
- reloc_put32(location, value);
- break;
- case R_MN10300_PCREL16:
- value = relocation - (uint32_t) location;
- reloc_put16(location, value);
- break;
- case R_MN10300_PCREL8:
- *location = relocation - (uint32_t) location;
- break;
-
- case R_MN10300_SYM_DIFF:
- /* This is used to adjust the next reloc as required
- * by relaxation. */
- sym_diff_seen = 1;
- sym_diff_val = sym->st_value;
- break;
-
- case R_MN10300_ALIGN:
- /* Just ignore the ALIGN relocs.
- * Only interesting if kernel performed relaxation. */
- continue;
-
- default:
- printk(KERN_ERR "module %s: Unknown relocation: %u\n",
- me->name, ELF32_R_TYPE(rel[i].r_info));
- return -ENOEXEC;
- }
- }
- if (sym_diff_seen) {
- printk(KERN_ERR "module %s: Nothing follows SYM_DIFF relocation: %u\n",
- me->name, ELF32_R_TYPE(rel[i].r_info));
- return -ENOEXEC;
- }
- return 0;
-}
diff --git a/arch/mn10300/kernel/process.c b/arch/mn10300/kernel/process.c
deleted file mode 100644
index 7c475fd99c46..000000000000
--- a/arch/mn10300/kernel/process.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* MN10300 Process handling code
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/sched/debug.h>
-#include <linux/sched/task.h>
-#include <linux/sched/task_stack.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/percpu.h>
-#include <linux/err.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/rcupdate.h>
-#include <linux/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/processor.h>
-#include <asm/mmu_context.h>
-#include <asm/fpu.h>
-#include <asm/reset-regs.h>
-#include <asm/gdb-stub.h>
-#include "internal.h"
-
-/*
- * power off function, if any
- */
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-/*
- * On SMP it's slightly faster (but much more power-consuming!)
- * to poll the ->work.need_resched flag instead of waiting for the
- * cross-CPU IPI to arrive. Use this option with caution.
- *
- * tglx: No idea why this depends on HOTPLUG_CPU !?!
- */
-#if !defined(CONFIG_SMP) || defined(CONFIG_HOTPLUG_CPU)
-void arch_cpu_idle(void)
-{
- safe_halt();
-}
-#endif
-
-void machine_restart(char *cmd)
-{
-#ifdef CONFIG_KERNEL_DEBUGGER
- gdbstub_exit(0);
-#endif
-
-#ifdef mn10300_unit_hard_reset
- mn10300_unit_hard_reset();
-#else
- mn10300_proc_hard_reset();
-#endif
-}
-
-void machine_halt(void)
-{
-#ifdef CONFIG_KERNEL_DEBUGGER
- gdbstub_exit(0);
-#endif
-}
-
-void machine_power_off(void)
-{
-#ifdef CONFIG_KERNEL_DEBUGGER
- gdbstub_exit(0);
-#endif
-}
-
-void show_regs(struct pt_regs *regs)
-{
- show_regs_print_info(KERN_DEFAULT);
-}
-
-/*
- * free current thread data structures etc..
- */
-void exit_thread(struct task_struct *tsk)
-{
- exit_fpu(tsk);
-}
-
-void flush_thread(void)
-{
- flush_fpu();
-}
-
-void release_thread(struct task_struct *dead_task)
-{
-}
-
-/*
- * this gets called so that we can store lazy state into memory and copy the
- * current task into the new thread.
- */
-int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
-{
- unlazy_fpu(src);
- *dst = *src;
- return 0;
-}
-
-/*
- * set up the kernel stack for a new thread and copy arch-specific thread
- * control information
- */
-int copy_thread(unsigned long clone_flags,
- unsigned long c_usp, unsigned long ustk_size,
- struct task_struct *p)
-{
- struct thread_info *ti = task_thread_info(p);
- struct pt_regs *c_regs;
- unsigned long c_ksp;
-
- c_ksp = (unsigned long) task_stack_page(p) + THREAD_SIZE;
-
- /* allocate the userspace exception frame and set it up */
- c_ksp -= sizeof(struct pt_regs);
- c_regs = (struct pt_regs *) c_ksp;
- c_ksp -= 12; /* allocate function call ABI slack */
-
- /* set up things up so the scheduler can start the new task */
- p->thread.uregs = c_regs;
- ti->frame = c_regs;
- p->thread.a3 = (unsigned long) c_regs;
- p->thread.sp = c_ksp;
- p->thread.wchan = p->thread.pc;
- p->thread.usp = c_usp;
-
- if (unlikely(p->flags & PF_KTHREAD)) {
- memset(c_regs, 0, sizeof(struct pt_regs));
- c_regs->a0 = c_usp; /* function */
- c_regs->d0 = ustk_size; /* argument */
- local_save_flags(c_regs->epsw);
- c_regs->epsw |= EPSW_IE | EPSW_IM_7;
- p->thread.pc = (unsigned long) ret_from_kernel_thread;
- return 0;
- }
- *c_regs = *current_pt_regs();
- if (c_usp)
- c_regs->sp = c_usp;
- c_regs->epsw &= ~EPSW_FE; /* my FPU */
-
- /* the new TLS pointer is passed in as arg #5 to sys_clone() */
- if (clone_flags & CLONE_SETTLS)
- c_regs->e2 = current_frame()->d3;
-
- p->thread.pc = (unsigned long) ret_from_fork;
-
- return 0;
-}
-
-unsigned long get_wchan(struct task_struct *p)
-{
- return p->thread.wchan;
-}
diff --git a/arch/mn10300/kernel/profile-low.S b/arch/mn10300/kernel/profile-low.S
deleted file mode 100644
index 94ffac12d02d..000000000000
--- a/arch/mn10300/kernel/profile-low.S
+++ /dev/null
@@ -1,72 +0,0 @@
-###############################################################################
-#
-# Fast profiling interrupt handler
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/segment.h>
-#include <asm/smp.h>
-#include <asm/intctl-regs.h>
-#include <asm/timer-regs.h>
-
-#define pi break
-
- .balign 4
-counter:
- .long -1
-
-###############################################################################
-#
-# Profiling interrupt entry point
-# - intended to run at interrupt priority 1
-#
-###############################################################################
-ENTRY(profile_handler)
- movm [d2,d3,a2],(sp)
-
- # ignore userspace
- mov (12,sp),d2
- and EPSW_nSL,d2
- bne out
-
- # do nothing if there's no buffer
- mov (prof_buffer),a2
- and a2,a2
- beq out
- or 0x20000000,a2
-
- # calculate relative position in text segment
- mov (16,sp),d2
- sub _stext,d2
- mov (prof_shift),d3
- lsr d3,d2
- mov (prof_len),d3
- cmp d3,d2
- bcc outside_text
-
- # increment the appropriate profile bucket
-do_inc:
- asl2 d2
- mov (a2,d2),d3
- inc d3
- mov d3,(a2,d2)
-out:
- mov GxICR_DETECT,d2
- movbu d2,(TM11ICR) # ACK the interrupt
- movbu (TM11ICR),d2
- movm (sp),[d2,d3,a2]
- rti
-
-outside_text:
- sub 1,d3
- mov d3,d2
- bra do_inc
diff --git a/arch/mn10300/kernel/profile.c b/arch/mn10300/kernel/profile.c
deleted file mode 100644
index 4f342f75d00c..000000000000
--- a/arch/mn10300/kernel/profile.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* MN10300 Profiling setup
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-/*
- * initialise the profiling if enabled
- * - using with gdbstub will give anomalous results
- * - can't be used with gdbstub if running at IRQ priority 0
- */
-static __init int profile_init(void)
-{
- u16 tmp;
-
- if (!prof_buffer)
- return 0;
-
- /* use timer 11 to drive the profiling interrupts */
- set_intr_stub(EXCEP_IRQ_LEVEL0, profile_handler);
-
- /* set IRQ priority at which to run */
- set_intr_level(TM11IRQ, GxICR_LEVEL_0);
-
- /* set up timer 11
- * - source: (IOCLK 33MHz)*2 = 66MHz
- * - frequency: (33330000*2) / 8 / 20625 = 202Hz
- */
- TM11BR = 20625 - 1;
- TM11MD = TM8MD_SRC_IOCLK_8;
- TM11MD |= TM8MD_INIT_COUNTER;
- TM11MD &= ~TM8MD_INIT_COUNTER;
- TM11MD |= TM8MD_COUNT_ENABLE;
-
- TM11ICR |= GxICR_ENABLE;
- tmp = TM11ICR;
-
- printk(KERN_INFO "Profiling initiated on timer 11, priority 0, %uHz\n",
- MN10300_IOCLK / 8 / (TM11BR + 1));
- printk(KERN_INFO "Profile histogram stored %p-%p\n",
- prof_buffer, (u8 *)(prof_buffer + prof_len) - 1);
-
- return 0;
-}
-
-__initcall(profile_init);
diff --git a/arch/mn10300/kernel/ptrace.c b/arch/mn10300/kernel/ptrace.c
deleted file mode 100644
index 8009876a7ac4..000000000000
--- a/arch/mn10300/kernel/ptrace.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/* MN10300 Process tracing
- *
- * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Modified by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/sched/task_stack.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/regset.h>
-#include <linux/elf.h>
-#include <linux/tracehook.h>
-#include <linux/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/cacheflush.h>
-#include <asm/fpu.h>
-#include <asm/asm-offsets.h>
-
-/*
- * translate ptrace register IDs into struct pt_regs offsets
- */
-static const u8 ptrace_regid_to_frame[] = {
- [PT_A3 << 2] = REG_A3,
- [PT_A2 << 2] = REG_A2,
- [PT_D3 << 2] = REG_D3,
- [PT_D2 << 2] = REG_D2,
- [PT_MCVF << 2] = REG_MCVF,
- [PT_MCRL << 2] = REG_MCRL,
- [PT_MCRH << 2] = REG_MCRH,
- [PT_MDRQ << 2] = REG_MDRQ,
- [PT_E1 << 2] = REG_E1,
- [PT_E0 << 2] = REG_E0,
- [PT_E7 << 2] = REG_E7,
- [PT_E6 << 2] = REG_E6,
- [PT_E5 << 2] = REG_E5,
- [PT_E4 << 2] = REG_E4,
- [PT_E3 << 2] = REG_E3,
- [PT_E2 << 2] = REG_E2,
- [PT_SP << 2] = REG_SP,
- [PT_LAR << 2] = REG_LAR,
- [PT_LIR << 2] = REG_LIR,
- [PT_MDR << 2] = REG_MDR,
- [PT_A1 << 2] = REG_A1,
- [PT_A0 << 2] = REG_A0,
- [PT_D1 << 2] = REG_D1,
- [PT_D0 << 2] = REG_D0,
- [PT_ORIG_D0 << 2] = REG_ORIG_D0,
- [PT_EPSW << 2] = REG_EPSW,
- [PT_PC << 2] = REG_PC,
-};
-
-static inline int get_stack_long(struct task_struct *task, int offset)
-{
- return *(unsigned long *)
- ((unsigned long) task->thread.uregs + offset);
-}
-
-static inline
-int put_stack_long(struct task_struct *task, int offset, unsigned long data)
-{
- unsigned long stack;
-
- stack = (unsigned long) task->thread.uregs + offset;
- *(unsigned long *) stack = data;
- return 0;
-}
-
-/*
- * retrieve the contents of MN10300 userspace general registers
- */
-static int genregs_get(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
-{
- const struct pt_regs *regs = task_pt_regs(target);
- int ret;
-
- /* we need to skip regs->next */
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- regs, 0, PT_ORIG_D0 * sizeof(long));
- if (ret < 0)
- return ret;
-
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &regs->orig_d0, PT_ORIG_D0 * sizeof(long),
- NR_PTREGS * sizeof(long));
- if (ret < 0)
- return ret;
-
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- NR_PTREGS * sizeof(long), -1);
-}
-
-/*
- * update the contents of the MN10300 userspace general registers
- */
-static int genregs_set(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user *ubuf)
-{
- struct pt_regs *regs = task_pt_regs(target);
- unsigned long tmp;
- int ret;
-
- /* we need to skip regs->next */
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- regs, 0, PT_ORIG_D0 * sizeof(long));
- if (ret < 0)
- return ret;
-
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &regs->orig_d0, PT_ORIG_D0 * sizeof(long),
- PT_EPSW * sizeof(long));
- if (ret < 0)
- return ret;
-
- /* we need to mask off changes to EPSW */
- tmp = regs->epsw;
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &tmp, PT_EPSW * sizeof(long),
- PT_PC * sizeof(long));
- tmp &= EPSW_FLAG_V | EPSW_FLAG_C | EPSW_FLAG_N | EPSW_FLAG_Z;
- tmp |= regs->epsw & ~(EPSW_FLAG_V | EPSW_FLAG_C | EPSW_FLAG_N |
- EPSW_FLAG_Z);
- regs->epsw = tmp;
-
- if (ret < 0)
- return ret;
-
- /* and finally load the PC */
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &regs->pc, PT_PC * sizeof(long),
- NR_PTREGS * sizeof(long));
-
- if (ret < 0)
- return ret;
-
- return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
- NR_PTREGS * sizeof(long), -1);
-}
-
-/*
- * retrieve the contents of MN10300 userspace FPU registers
- */
-static int fpuregs_get(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
-{
- const struct fpu_state_struct *fpregs = &target->thread.fpu_state;
- int ret;
-
- unlazy_fpu(target);
-
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- fpregs, 0, sizeof(*fpregs));
- if (ret < 0)
- return ret;
-
- return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- sizeof(*fpregs), -1);
-}
-
-/*
- * update the contents of the MN10300 userspace FPU registers
- */
-static int fpuregs_set(struct task_struct *target,
- const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- const void *kbuf, const void __user *ubuf)
-{
- struct fpu_state_struct fpu_state = target->thread.fpu_state;
- int ret;
-
- ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
- &fpu_state, 0, sizeof(fpu_state));
- if (ret < 0)
- return ret;
-
- fpu_kill_state(target);
- target->thread.fpu_state = fpu_state;
- set_using_fpu(target);
-
- return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
- sizeof(fpu_state), -1);
-}
-
-/*
- * determine if the FPU registers have actually been used
- */
-static int fpuregs_active(struct task_struct *target,
- const struct user_regset *regset)
-{
- return is_using_fpu(target) ? regset->n : 0;
-}
-
-/*
- * Define the register sets available on the MN10300 under Linux
- */
-enum mn10300_regset {
- REGSET_GENERAL,
- REGSET_FPU,
-};
-
-static const struct user_regset mn10300_regsets[] = {
- /*
- * General register format is:
- * A3, A2, D3, D2, MCVF, MCRL, MCRH, MDRQ
- * E1, E0, E7...E2, SP, LAR, LIR, MDR
- * A1, A0, D1, D0, ORIG_D0, EPSW, PC
- */
- [REGSET_GENERAL] = {
- .core_note_type = NT_PRSTATUS,
- .n = ELF_NGREG,
- .size = sizeof(long),
- .align = sizeof(long),
- .get = genregs_get,
- .set = genregs_set,
- },
- /*
- * FPU register format is:
- * FS0-31, FPCR
- */
- [REGSET_FPU] = {
- .core_note_type = NT_PRFPREG,
- .n = sizeof(struct fpu_state_struct) / sizeof(long),
- .size = sizeof(long),
- .align = sizeof(long),
- .get = fpuregs_get,
- .set = fpuregs_set,
- .active = fpuregs_active,
- },
-};
-
-static const struct user_regset_view user_mn10300_native_view = {
- .name = "mn10300",
- .e_machine = EM_MN10300,
- .regsets = mn10300_regsets,
- .n = ARRAY_SIZE(mn10300_regsets),
-};
-
-const struct user_regset_view *task_user_regset_view(struct task_struct *task)
-{
- return &user_mn10300_native_view;
-}
-
-/*
- * set the single-step bit
- */
-void user_enable_single_step(struct task_struct *child)
-{
-#ifndef CONFIG_MN10300_USING_JTAG
- struct user *dummy = NULL;
- long tmp;
-
- tmp = get_stack_long(child, (unsigned long) &dummy->regs.epsw);
- tmp |= EPSW_T;
- put_stack_long(child, (unsigned long) &dummy->regs.epsw, tmp);
-#endif
-}
-
-/*
- * make sure the single-step bit is not set
- */
-void user_disable_single_step(struct task_struct *child)
-{
-#ifndef CONFIG_MN10300_USING_JTAG
- struct user *dummy = NULL;
- long tmp;
-
- tmp = get_stack_long(child, (unsigned long) &dummy->regs.epsw);
- tmp &= ~EPSW_T;
- put_stack_long(child, (unsigned long) &dummy->regs.epsw, tmp);
-#endif
-}
-
-void ptrace_disable(struct task_struct *child)
-{
- user_disable_single_step(child);
-}
-
-/*
- * handle the arch-specific side of process tracing
- */
-long arch_ptrace(struct task_struct *child, long request,
- unsigned long addr, unsigned long data)
-{
- unsigned long tmp;
- int ret;
- unsigned long __user *datap = (unsigned long __user *) data;
-
- switch (request) {
- /* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR:
- ret = -EIO;
- if ((addr & 3) || addr > sizeof(struct user) - 3)
- break;
-
- tmp = 0; /* Default return condition */
- if (addr < NR_PTREGS << 2)
- tmp = get_stack_long(child,
- ptrace_regid_to_frame[addr]);
- ret = put_user(tmp, datap);
- break;
-
- /* write the word at location addr in the USER area */
- case PTRACE_POKEUSR:
- ret = -EIO;
- if ((addr & 3) || addr > sizeof(struct user) - 3)
- break;
-
- ret = 0;
- if (addr < NR_PTREGS << 2)
- ret = put_stack_long(child, ptrace_regid_to_frame[addr],
- data);
- break;
-
- case PTRACE_GETREGS: /* Get all integer regs from the child. */
- return copy_regset_to_user(child, &user_mn10300_native_view,
- REGSET_GENERAL,
- 0, NR_PTREGS * sizeof(long),
- datap);
-
- case PTRACE_SETREGS: /* Set all integer regs in the child. */
- return copy_regset_from_user(child, &user_mn10300_native_view,
- REGSET_GENERAL,
- 0, NR_PTREGS * sizeof(long),
- datap);
-
- case PTRACE_GETFPREGS: /* Get the child FPU state. */
- return copy_regset_to_user(child, &user_mn10300_native_view,
- REGSET_FPU,
- 0, sizeof(struct fpu_state_struct),
- datap);
-
- case PTRACE_SETFPREGS: /* Set the child FPU state. */
- return copy_regset_from_user(child, &user_mn10300_native_view,
- REGSET_FPU,
- 0, sizeof(struct fpu_state_struct),
- datap);
-
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
- }
-
- return ret;
-}
-
-/*
- * handle tracing of system call entry
- * - return the revised system call number or ULONG_MAX to cause ENOSYS
- */
-asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs)
-{
- if (tracehook_report_syscall_entry(regs))
- /* tracing decided this syscall should not happen, so
- * We'll return a bogus call number to get an ENOSYS
- * error, but leave the original number in
- * regs->orig_d0
- */
- return ULONG_MAX;
-
- return regs->orig_d0;
-}
-
-/*
- * handle tracing of system call exit
- */
-asmlinkage void syscall_trace_exit(struct pt_regs *regs)
-{
- tracehook_report_syscall_exit(regs, 0);
-}
diff --git a/arch/mn10300/kernel/rtc.c b/arch/mn10300/kernel/rtc.c
deleted file mode 100644
index f81f37025072..000000000000
--- a/arch/mn10300/kernel/rtc.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* MN10300 RTC management
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/mc146818rtc.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-
-#include <asm/rtc-regs.h>
-#include <asm/rtc.h>
-
-DEFINE_SPINLOCK(rtc_lock);
-EXPORT_SYMBOL(rtc_lock);
-
-static const __initdata struct resource res[] = {
- DEFINE_RES_IO(RTC_PORT(0), RTC_IO_EXTENT),
- DEFINE_RES_IRQ(RTC_IRQ),
-};
-
-/*
- * calibrate the TSC clock against the RTC
- */
-void __init calibrate_clock(void)
-{
- unsigned char status;
-
- /* make sure the RTC is running and is set to operate in 24hr mode */
- status = RTSRC;
- RTCRB |= RTCRB_SET;
- RTCRB |= RTCRB_TM_24HR;
- RTCRB &= ~RTCRB_DM_BINARY;
- RTCRA |= RTCRA_DVR;
- RTCRA &= ~RTCRA_DVR;
- RTCRB &= ~RTCRB_SET;
-
- platform_device_register_simple("rtc_cmos", -1, res, ARRAY_SIZE(res));
-}
diff --git a/arch/mn10300/kernel/setup.c b/arch/mn10300/kernel/setup.c
deleted file mode 100644
index 1b3d80d8a171..000000000000
--- a/arch/mn10300/kernel/setup.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/* MN10300 Arch-specific initialisation
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/tty.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/seq_file.h>
-#include <linux/cpu.h>
-#include <asm/processor.h>
-#include <linux/console.h>
-#include <linux/uaccess.h>
-#include <asm/setup.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <proc/proc.h>
-#include <asm/fpu.h>
-#include <asm/sections.h>
-
-struct mn10300_cpuinfo boot_cpu_data;
-
-static char __initdata cmd_line[COMMAND_LINE_SIZE];
-char redboot_command_line[COMMAND_LINE_SIZE] =
- "console=ttyS0,115200 root=/dev/mtdblock3 rw";
-
-char __initdata redboot_platform_name[COMMAND_LINE_SIZE];
-
-static struct resource code_resource = {
- .start = 0x100000,
- .end = 0,
- .name = "Kernel code",
-};
-
-static struct resource data_resource = {
- .start = 0,
- .end = 0,
- .name = "Kernel data",
-};
-
-static unsigned long __initdata phys_memory_base;
-static unsigned long __initdata phys_memory_end;
-static unsigned long __initdata memory_end;
-unsigned long memory_size;
-
-struct thread_info *__current_ti = &init_thread_union.thread_info;
-struct task_struct *__current = &init_task;
-
-#define mn10300_known_cpus 5
-static const char *const mn10300_cputypes[] = {
- "am33-1",
- "am33-2",
- "am34-1",
- "am33-3",
- "am34-2",
- "unknown"
-};
-
-/*
- * Pick out the memory size. We look for mem=size,
- * where size is "size[KkMm]"
- */
-static int __init early_mem(char *p)
-{
- memory_size = memparse(p, &p);
-
- if (memory_size == 0)
- panic("Memory size not known\n");
-
- return 0;
-}
-early_param("mem", early_mem);
-
-/*
- * architecture specific setup
- */
-void __init setup_arch(char **cmdline_p)
-{
- unsigned long bootmap_size;
- unsigned long kstart_pfn, start_pfn, free_pfn, end_pfn;
-
- cpu_init();
- unit_setup();
- smp_init_cpus();
-
- /* save unparsed command line copy for /proc/cmdline */
- strlcpy(boot_command_line, redboot_command_line, COMMAND_LINE_SIZE);
-
- /* populate cmd_line too for later use, preserving boot_command_line */
- strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
- *cmdline_p = cmd_line;
-
- parse_early_param();
-
- memory_end = (unsigned long) CONFIG_KERNEL_RAM_BASE_ADDRESS +
- memory_size;
- if (memory_end > phys_memory_end)
- memory_end = phys_memory_end;
-
- init_mm.start_code = (unsigned long)&_text;
- init_mm.end_code = (unsigned long) &_etext;
- init_mm.end_data = (unsigned long) &_edata;
- init_mm.brk = (unsigned long) &_end;
-
- code_resource.start = virt_to_bus(&_text);
- code_resource.end = virt_to_bus(&_etext)-1;
- data_resource.start = virt_to_bus(&_etext);
- data_resource.end = virt_to_bus(&_edata)-1;
-
- start_pfn = (CONFIG_KERNEL_RAM_BASE_ADDRESS >> PAGE_SHIFT);
- kstart_pfn = PFN_UP(__pa(&_text));
- free_pfn = PFN_UP(__pa(&_end));
- end_pfn = PFN_DOWN(__pa(memory_end));
-
- bootmap_size = init_bootmem_node(&contig_page_data,
- free_pfn,
- start_pfn,
- end_pfn);
-
- if (kstart_pfn > start_pfn)
- free_bootmem(PFN_PHYS(start_pfn),
- PFN_PHYS(kstart_pfn - start_pfn));
-
- free_bootmem(PFN_PHYS(free_pfn),
- PFN_PHYS(end_pfn - free_pfn));
-
- /* If interrupt vector table is in main ram, then we need to
- reserve the page it is occupying. */
- if (CONFIG_INTERRUPT_VECTOR_BASE >= CONFIG_KERNEL_RAM_BASE_ADDRESS &&
- CONFIG_INTERRUPT_VECTOR_BASE < memory_end)
- reserve_bootmem(CONFIG_INTERRUPT_VECTOR_BASE, PAGE_SIZE,
- BOOTMEM_DEFAULT);
-
- reserve_bootmem(PAGE_ALIGN(PFN_PHYS(free_pfn)), bootmap_size,
- BOOTMEM_DEFAULT);
-
-#ifdef CONFIG_VT
-#if defined(CONFIG_VGA_CONSOLE)
- conswitchp = &vga_con;
-#elif defined(CONFIG_DUMMY_CONSOLE)
- conswitchp = &dummy_con;
-#endif
-#endif
-
- paging_init();
-}
-
-/*
- * perform CPU initialisation
- */
-void __init cpu_init(void)
-{
- unsigned long cpurev = CPUREV, type;
-
- type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S;
- if (type > mn10300_known_cpus)
- type = mn10300_known_cpus;
-
- printk(KERN_INFO "Panasonic %s, rev %ld\n",
- mn10300_cputypes[type],
- (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S);
-
- get_mem_info(&phys_memory_base, &memory_size);
- phys_memory_end = phys_memory_base + memory_size;
-
- fpu_init_state();
-}
-
-static struct cpu cpu_devices[NR_CPUS];
-
-static int __init topology_init(void)
-{
- int i;
-
- for_each_present_cpu(i)
- register_cpu(&cpu_devices[i], i);
-
- return 0;
-}
-
-subsys_initcall(topology_init);
-
-/*
- * Get CPU information for use by the procfs.
- */
-static int show_cpuinfo(struct seq_file *m, void *v)
-{
-#ifdef CONFIG_SMP
- struct mn10300_cpuinfo *c = v;
- unsigned long cpu_id = c - cpu_data;
- unsigned long cpurev = c->type, type, icachesz, dcachesz;
-#else /* CONFIG_SMP */
- unsigned long cpu_id = 0;
- unsigned long cpurev = CPUREV, type, icachesz, dcachesz;
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_SMP
- if (!cpu_online(cpu_id))
- return 0;
-#endif
-
- type = (cpurev & CPUREV_TYPE) >> CPUREV_TYPE_S;
- if (type > mn10300_known_cpus)
- type = mn10300_known_cpus;
-
- icachesz =
- ((cpurev & CPUREV_ICWAY ) >> CPUREV_ICWAY_S) *
- ((cpurev & CPUREV_ICSIZE) >> CPUREV_ICSIZE_S) *
- 1024;
-
- dcachesz =
- ((cpurev & CPUREV_DCWAY ) >> CPUREV_DCWAY_S) *
- ((cpurev & CPUREV_DCSIZE) >> CPUREV_DCSIZE_S) *
- 1024;
-
- seq_printf(m,
- "processor : %ld\n"
- "vendor_id : " PROCESSOR_VENDOR_NAME "\n"
- "cpu core : %s\n"
- "cpu rev : %lu\n"
- "model name : " PROCESSOR_MODEL_NAME "\n"
- "icache size: %lu\n"
- "dcache size: %lu\n",
- cpu_id,
- mn10300_cputypes[type],
- (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S,
- icachesz,
- dcachesz
- );
-
- seq_printf(m,
- "ioclk speed: %lu.%02luMHz\n"
- "bogomips : %lu.%02lu\n\n",
- MN10300_IOCLK / 1000000,
- (MN10300_IOCLK / 10000) % 100,
-#ifdef CONFIG_SMP
- c->loops_per_jiffy / (500000 / HZ),
- (c->loops_per_jiffy / (5000 / HZ)) % 100
-#else /* CONFIG_SMP */
- loops_per_jiffy / (500000 / HZ),
- (loops_per_jiffy / (5000 / HZ)) % 100
-#endif /* CONFIG_SMP */
- );
-
- return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
- return *pos < NR_CPUS ? cpu_data + *pos : NULL;
-}
-
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
- ++*pos;
- return c_start(m, pos);
-}
-
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-
-const struct seq_operations cpuinfo_op = {
- .start = c_start,
- .next = c_next,
- .stop = c_stop,
- .show = show_cpuinfo,
-};
diff --git a/arch/mn10300/kernel/sigframe.h b/arch/mn10300/kernel/sigframe.h
deleted file mode 100644
index 0decba28ae84..000000000000
--- a/arch/mn10300/kernel/sigframe.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/* MN10300 Signal frame definitions
- *
- * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-struct sigframe
-{
- void (*pretcode)(void);
- int sig;
- struct sigcontext *psc;
- struct sigcontext sc;
- struct fpucontext fpuctx;
- unsigned long extramask[_NSIG_WORDS-1];
- char retcode[8];
-};
-
-struct rt_sigframe
-{
- void (*pretcode)(void);
- int sig;
- struct siginfo *pinfo;
- void *puc;
- struct siginfo info;
- struct ucontext uc;
- struct fpucontext fpuctx;
- char retcode[8];
-};
diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
deleted file mode 100644
index 2f3cb5734235..000000000000
--- a/arch/mn10300/kernel/signal.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/* MN10300 Signal handling
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
-#include <linux/tty.h>
-#include <linux/personality.h>
-#include <linux/suspend.h>
-#include <linux/tracehook.h>
-#include <asm/cacheflush.h>
-#include <asm/ucontext.h>
-#include <linux/uaccess.h>
-#include <asm/fpu.h>
-#include "sigframe.h"
-
-#define DEBUG_SIG 0
-
-/*
- * do a signal return; undo the signal stack.
- */
-static int restore_sigcontext(struct pt_regs *regs,
- struct sigcontext __user *sc, long *_d0)
-{
- unsigned int err = 0;
-
- /* Always make any pending restarted system calls return -EINTR */
- current->restart_block.fn = do_no_restart_syscall;
-
- if (is_using_fpu(current))
- fpu_kill_state(current);
-
-#define COPY(x) err |= __get_user(regs->x, &sc->x)
- COPY(d1); COPY(d2); COPY(d3);
- COPY(a0); COPY(a1); COPY(a2); COPY(a3);
- COPY(e0); COPY(e1); COPY(e2); COPY(e3);
- COPY(e4); COPY(e5); COPY(e6); COPY(e7);
- COPY(lar); COPY(lir);
- COPY(mdr); COPY(mdrq);
- COPY(mcvf); COPY(mcrl); COPY(mcrh);
- COPY(sp); COPY(pc);
-#undef COPY
-
- {
- unsigned int tmpflags;
-#ifndef CONFIG_MN10300_USING_JTAG
-#define USER_EPSW (EPSW_FLAG_Z | EPSW_FLAG_N | EPSW_FLAG_C | EPSW_FLAG_V | \
- EPSW_T | EPSW_nAR)
-#else
-#define USER_EPSW (EPSW_FLAG_Z | EPSW_FLAG_N | EPSW_FLAG_C | EPSW_FLAG_V | \
- EPSW_nAR)
-#endif
- err |= __get_user(tmpflags, &sc->epsw);
- regs->epsw = (regs->epsw & ~USER_EPSW) |
- (tmpflags & USER_EPSW);
- regs->orig_d0 = -1; /* disable syscall checks */
- }
-
- {
- struct fpucontext *buf;
- err |= __get_user(buf, &sc->fpucontext);
- if (buf) {
- if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
- goto badframe;
- err |= fpu_restore_sigcontext(buf);
- }
- }
-
- err |= __get_user(*_d0, &sc->d0);
- return err;
-
-badframe:
- return 1;
-}
-
-/*
- * standard signal return syscall
- */
-asmlinkage long sys_sigreturn(void)
-{
- struct sigframe __user *frame;
- sigset_t set;
- long d0;
-
- frame = (struct sigframe __user *) current_frame()->sp;
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
- if (__get_user(set.sig[0], &frame->sc.oldmask))
- goto badframe;
-
- if (_NSIG_WORDS > 1 &&
- __copy_from_user(&set.sig[1], &frame->extramask,
- sizeof(frame->extramask)))
- goto badframe;
-
- set_current_blocked(&set);
-
- if (restore_sigcontext(current_frame(), &frame->sc, &d0))
- goto badframe;
-
- return d0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-/*
- * realtime signal return syscall
- */
-asmlinkage long sys_rt_sigreturn(void)
-{
- struct rt_sigframe __user *frame;
- sigset_t set;
- long d0;
-
- frame = (struct rt_sigframe __user *) current_frame()->sp;
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
- if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
- goto badframe;
-
- set_current_blocked(&set);
-
- if (restore_sigcontext(current_frame(), &frame->uc.uc_mcontext, &d0))
- goto badframe;
-
- if (restore_altstack(&frame->uc.uc_stack))
- goto badframe;
-
- return d0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-/*
- * store the userspace context into a signal frame
- */
-static int setup_sigcontext(struct sigcontext __user *sc,
- struct fpucontext *fpuctx,
- struct pt_regs *regs,
- unsigned long mask)
-{
- int tmp, err = 0;
-
-#define COPY(x) err |= __put_user(regs->x, &sc->x)
- COPY(d0); COPY(d1); COPY(d2); COPY(d3);
- COPY(a0); COPY(a1); COPY(a2); COPY(a3);
- COPY(e0); COPY(e1); COPY(e2); COPY(e3);
- COPY(e4); COPY(e5); COPY(e6); COPY(e7);
- COPY(lar); COPY(lir);
- COPY(mdr); COPY(mdrq);
- COPY(mcvf); COPY(mcrl); COPY(mcrh);
- COPY(sp); COPY(epsw); COPY(pc);
-#undef COPY
-
- tmp = fpu_setup_sigcontext(fpuctx);
- if (tmp < 0)
- err = 1;
- else
- err |= __put_user(tmp ? fpuctx : NULL, &sc->fpucontext);
-
- /* non-iBCS2 extensions.. */
- err |= __put_user(mask, &sc->oldmask);
-
- return err;
-}
-
-/*
- * determine which stack to use..
- */
-static inline void __user *get_sigframe(struct ksignal *ksig,
- struct pt_regs *regs,
- size_t frame_size)
-{
- unsigned long sp = sigsp(regs->sp, ksig);
-
- return (void __user *) ((sp - frame_size) & ~7UL);
-}
-
-/*
- * set up a normal signal frame
- */
-static int setup_frame(struct ksignal *ksig, sigset_t *set,
- struct pt_regs *regs)
-{
- struct sigframe __user *frame;
- int sig = ksig->sig;
-
- frame = get_sigframe(ksig, regs, sizeof(*frame));
-
- if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- return -EFAULT;
-
- if (__put_user(sig, &frame->sig) < 0 ||
- __put_user(&frame->sc, &frame->psc) < 0)
- return -EFAULT;
-
- if (setup_sigcontext(&frame->sc, &frame->fpuctx, regs, set->sig[0]))
- return -EFAULT;
-
- if (_NSIG_WORDS > 1) {
- if (__copy_to_user(frame->extramask, &set->sig[1],
- sizeof(frame->extramask)))
- return -EFAULT;
- }
-
- /* set up to return from userspace. If provided, use a stub already in
- * userspace */
- if (ksig->ka.sa.sa_flags & SA_RESTORER) {
- if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
- return -EFAULT;
- } else {
- if (__put_user((void (*)(void))frame->retcode,
- &frame->pretcode))
- return -EFAULT;
- /* this is mov $,d0; syscall 0 */
- if (__put_user(0x2c, (char *)(frame->retcode + 0)) ||
- __put_user(__NR_sigreturn, (char *)(frame->retcode + 1)) ||
- __put_user(0x00, (char *)(frame->retcode + 2)) ||
- __put_user(0xf0, (char *)(frame->retcode + 3)) ||
- __put_user(0xe0, (char *)(frame->retcode + 4)))
- return -EFAULT;
- flush_icache_range((unsigned long) frame->retcode,
- (unsigned long) frame->retcode + 5);
- }
-
- /* set up registers for signal handler */
- regs->sp = (unsigned long) frame;
- regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
- regs->d0 = sig;
- regs->d1 = (unsigned long) &frame->sc;
-
-#if DEBUG_SIG
- printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
- sig, current->comm, current->pid, frame, regs->pc,
- frame->pretcode);
-#endif
-
- return 0;
-}
-
-/*
- * set up a realtime signal frame
- */
-static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
- struct pt_regs *regs)
-{
- struct rt_sigframe __user *frame;
- int sig = ksig->sig;
-
- frame = get_sigframe(ksig, regs, sizeof(*frame));
-
- if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
- return -EFAULT;
-
- if (__put_user(sig, &frame->sig) ||
- __put_user(&frame->info, &frame->pinfo) ||
- __put_user(&frame->uc, &frame->puc) ||
- copy_siginfo_to_user(&frame->info, &ksig->info))
- return -EFAULT;
-
- /* create the ucontext. */
- if (__put_user(0, &frame->uc.uc_flags) ||
- __put_user(0, &frame->uc.uc_link) ||
- __save_altstack(&frame->uc.uc_stack, regs->sp) ||
- setup_sigcontext(&frame->uc.uc_mcontext,
- &frame->fpuctx, regs, set->sig[0]) ||
- __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)))
- return -EFAULT;
-
- /* set up to return from userspace. If provided, use a stub already in
- * userspace */
- if (ksig->ka.sa.sa_flags & SA_RESTORER) {
- if (__put_user(ksig->ka.sa.sa_restorer, &frame->pretcode))
- return -EFAULT;
-
- } else {
- if (__put_user((void(*)(void))frame->retcode,
- &frame->pretcode) ||
- /* This is mov $,d0; syscall 0 */
- __put_user(0x2c, (char *)(frame->retcode + 0)) ||
- __put_user(__NR_rt_sigreturn,
- (char *)(frame->retcode + 1)) ||
- __put_user(0x00, (char *)(frame->retcode + 2)) ||
- __put_user(0xf0, (char *)(frame->retcode + 3)) ||
- __put_user(0xe0, (char *)(frame->retcode + 4)))
- return -EFAULT;
-
- flush_icache_range((u_long) frame->retcode,
- (u_long) frame->retcode + 5);
- }
-
- /* Set up registers for signal handler */
- regs->sp = (unsigned long) frame;
- regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
- regs->d0 = sig;
- regs->d1 = (long) &frame->info;
-
-#if DEBUG_SIG
- printk(KERN_DEBUG "SIG deliver %d (%s:%d): sp=%p pc=%lx ra=%p\n",
- sig, current->comm, current->pid, frame, regs->pc,
- frame->pretcode);
-#endif
-
- return 0;
-}
-
-static inline void stepback(struct pt_regs *regs)
-{
- regs->pc -= 2;
- regs->orig_d0 = -1;
-}
-
-/*
- * handle the actual delivery of a signal to userspace
- */
-static int handle_signal(struct ksignal *ksig, struct pt_regs *regs)
-{
- sigset_t *oldset = sigmask_to_save();
- int ret;
-
- /* Are we from a system call? */
- if (regs->orig_d0 >= 0) {
- /* If so, check system call restarting.. */
- switch (regs->d0) {
- case -ERESTART_RESTARTBLOCK:
- case -ERESTARTNOHAND:
- regs->d0 = -EINTR;
- break;
-
- case -ERESTARTSYS:
- if (!(ksig->ka.sa.sa_flags & SA_RESTART)) {
- regs->d0 = -EINTR;
- break;
- }
-
- /* fallthrough */
- case -ERESTARTNOINTR:
- regs->d0 = regs->orig_d0;
- stepback(regs);
- }
- }
-
- /* Set up the stack frame */
- if (ksig->ka.sa.sa_flags & SA_SIGINFO)
- ret = setup_rt_frame(ksig, oldset, regs);
- else
- ret = setup_frame(ksig, oldset, regs);
-
- signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
- return 0;
-}
-
-/*
- * handle a potential signal
- */
-static void do_signal(struct pt_regs *regs)
-{
- struct ksignal ksig;
-
- if (get_signal(&ksig)) {
- handle_signal(&ksig, regs);
- return;
- }
-
- /* did we come from a system call? */
- if (regs->orig_d0 >= 0) {
- /* restart the system call - no handlers present */
- switch (regs->d0) {
- case -ERESTARTNOHAND:
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- regs->d0 = regs->orig_d0;
- stepback(regs);
- break;
-
- case -ERESTART_RESTARTBLOCK:
- regs->d0 = __NR_restart_syscall;
- stepback(regs);
- break;
- }
- }
-
- /* if there's no signal to deliver, we just put the saved sigmask
- * back */
- restore_saved_sigmask();
-}
-
-/*
- * notification of userspace execution resumption
- * - triggered by current->work.notify_resume
- */
-asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
-{
- /* Pending single-step? */
- if (thread_info_flags & _TIF_SINGLESTEP) {
-#ifndef CONFIG_MN10300_USING_JTAG
- regs->epsw |= EPSW_T;
- clear_thread_flag(TIF_SINGLESTEP);
-#else
- BUG(); /* no h/w single-step if using JTAG unit */
-#endif
- }
-
- /* deal with pending signal delivery */
- if (thread_info_flags & _TIF_SIGPENDING)
- do_signal(regs);
-
- if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(current_frame());
- }
-}
diff --git a/arch/mn10300/kernel/smp-low.S b/arch/mn10300/kernel/smp-low.S
deleted file mode 100644
index 71f1b2faaa0b..000000000000
--- a/arch/mn10300/kernel/smp-low.S
+++ /dev/null
@@ -1,97 +0,0 @@
-/* SMP IPI low-level handler
- *
- * Copyright (C) 2006-2007 Matsushita Electric Industrial Co., Ltd.
- * 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
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
- */
-
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/smp.h>
-#include <asm/thread_info.h>
-#include <asm/cpu-regs.h>
-#include <asm/intctl-regs.h>
-#include <proc/smp-regs.h>
-#include <asm/asm-offsets.h>
-#include <asm/frame.inc>
-
- .am33_2
-
-###############################################################################
-#
-# IPI interrupt handler
-#
-###############################################################################
- .globl mn10300_low_ipi_handler
-mn10300_low_ipi_handler:
- add -4,sp
- mov d0,(sp)
- movhu (IAGR),d0
- and IAGR_GN,d0
- lsr 0x2,d0
-#ifdef CONFIG_MN10300_CACHE_ENABLED
- cmp FLUSH_CACHE_IPI,d0
- beq mn10300_flush_cache_ipi
-#endif
- cmp SMP_BOOT_IRQ,d0
- beq mn10300_smp_boot_ipi
- /* OTHERS */
- mov (sp),d0
- add 4,sp
-#ifdef CONFIG_GDBSTUB
- jmp gdbstub_io_rx_handler
-#else
- jmp end
-#endif
-
-###############################################################################
-#
-# Cache flush IPI interrupt handler
-#
-###############################################################################
-#ifdef CONFIG_MN10300_CACHE_ENABLED
-mn10300_flush_cache_ipi:
- mov (sp),d0
- add 4,sp
-
- /* FLUSH_CACHE_IPI */
- add -4,sp
- SAVE_ALL
- mov GxICR_DETECT,d2
- movbu d2,(GxICR(FLUSH_CACHE_IPI)) # ACK the interrupt
- movhu (GxICR(FLUSH_CACHE_IPI)),d2
- call smp_cache_interrupt[],0
- RESTORE_ALL
- jmp end
-#endif
-
-###############################################################################
-#
-# SMP boot CPU IPI interrupt handler
-#
-###############################################################################
-mn10300_smp_boot_ipi:
- /* clear interrupt */
- movhu (GxICR(SMP_BOOT_IRQ)),d0
- and ~GxICR_REQUEST,d0
- movhu d0,(GxICR(SMP_BOOT_IRQ))
- mov (sp),d0
- add 4,sp
-
- # get stack
- mov (CPUID),a0
- add -1,a0
- add a0,a0
- add a0,a0
- mov (start_stack,a0),a0
- mov a0,sp
- jmp initialize_secondary
-
-
-# Jump here after RTI to suppress the icache lookahead
-end:
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
deleted file mode 100644
index 35d2c3fe6f76..000000000000
--- a/arch/mn10300/kernel/smp.c
+++ /dev/null
@@ -1,1186 +0,0 @@
-/* SMP support routines.
- *
- * Copyright (C) 2006-2008 Panasonic Corporation
- * 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.
- *
- * 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.
- */
-
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/cpumask.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/sched/mm.h>
-#include <linux/sched/task.h>
-#include <linux/profile.h>
-#include <linux/smp.h>
-#include <linux/cpu.h>
-#include <asm/tlbflush.h>
-#include <asm/bitops.h>
-#include <asm/processor.h>
-#include <asm/bug.h>
-#include <asm/exceptions.h>
-#include <asm/hardirq.h>
-#include <asm/fpu.h>
-#include <asm/mmu_context.h>
-#include <asm/thread_info.h>
-#include <asm/cpu-regs.h>
-#include <asm/intctl-regs.h>
-#include "internal.h"
-
-#ifdef CONFIG_HOTPLUG_CPU
-#include <asm/cacheflush.h>
-
-static unsigned long sleep_mode[NR_CPUS];
-
-static void run_sleep_cpu(unsigned int cpu);
-static void run_wakeup_cpu(unsigned int cpu);
-#endif /* CONFIG_HOTPLUG_CPU */
-
-/*
- * Debug Message function
- */
-
-#undef DEBUG_SMP
-#ifdef DEBUG_SMP
-#define Dprintk(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#else
-#define Dprintk(fmt, ...) no_printk(KERN_DEBUG fmt, ##__VA_ARGS__)
-#endif
-
-/* timeout value in msec for smp_nmi_call_function. zero is no timeout. */
-#define CALL_FUNCTION_NMI_IPI_TIMEOUT 0
-
-/*
- * Structure and data for smp_nmi_call_function().
- */
-struct nmi_call_data_struct {
- smp_call_func_t func;
- void *info;
- cpumask_t started;
- cpumask_t finished;
- int wait;
- char size_alignment[0]
- __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
-} __attribute__ ((__aligned__(SMP_CACHE_BYTES)));
-
-static DEFINE_SPINLOCK(smp_nmi_call_lock);
-static struct nmi_call_data_struct *nmi_call_data;
-
-/*
- * Data structures and variables
- */
-static cpumask_t cpu_callin_map; /* Bitmask of callin CPUs */
-static cpumask_t cpu_callout_map; /* Bitmask of callout CPUs */
-cpumask_t cpu_boot_map; /* Bitmask of boot APs */
-unsigned long start_stack[NR_CPUS - 1];
-
-/*
- * Per CPU parameters
- */
-struct mn10300_cpuinfo cpu_data[NR_CPUS] __cacheline_aligned;
-
-static int cpucount; /* The count of boot CPUs */
-static cpumask_t smp_commenced_mask;
-cpumask_t cpu_initialized __initdata = CPU_MASK_NONE;
-
-/*
- * Function Prototypes
- */
-static int do_boot_cpu(int);
-static void smp_show_cpu_info(int cpu_id);
-static void smp_callin(void);
-static void smp_online(void);
-static void smp_store_cpu_info(int);
-static void smp_cpu_init(void);
-static void smp_tune_scheduling(void);
-static void send_IPI_mask(const cpumask_t *cpumask, int irq);
-static void init_ipi(void);
-
-/*
- * IPI Initialization interrupt definitions
- */
-static void mn10300_ipi_disable(unsigned int irq);
-static void mn10300_ipi_enable(unsigned int irq);
-static void mn10300_ipi_chip_disable(struct irq_data *d);
-static void mn10300_ipi_chip_enable(struct irq_data *d);
-static void mn10300_ipi_ack(struct irq_data *d);
-static void mn10300_ipi_nop(struct irq_data *d);
-
-static struct irq_chip mn10300_ipi_type = {
- .name = "cpu_ipi",
- .irq_disable = mn10300_ipi_chip_disable,
- .irq_enable = mn10300_ipi_chip_enable,
- .irq_ack = mn10300_ipi_ack,
- .irq_eoi = mn10300_ipi_nop
-};
-
-static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id);
-static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id);
-
-static struct irqaction reschedule_ipi = {
- .handler = smp_reschedule_interrupt,
- .flags = IRQF_NOBALANCING,
- .name = "smp reschedule IPI"
-};
-static struct irqaction call_function_ipi = {
- .handler = smp_call_function_interrupt,
- .flags = IRQF_NOBALANCING,
- .name = "smp call function IPI"
-};
-
-#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
-static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id);
-static struct irqaction local_timer_ipi = {
- .handler = smp_ipi_timer_interrupt,
- .flags = IRQF_NOBALANCING,
- .name = "smp local timer IPI"
-};
-#endif
-
-/**
- * init_ipi - Initialise the IPI mechanism
- */
-static void init_ipi(void)
-{
- unsigned long flags;
- u16 tmp16;
-
- /* set up the reschedule IPI */
- irq_set_chip_and_handler(RESCHEDULE_IPI, &mn10300_ipi_type,
- handle_percpu_irq);
- setup_irq(RESCHEDULE_IPI, &reschedule_ipi);
- set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV);
- mn10300_ipi_enable(RESCHEDULE_IPI);
-
- /* set up the call function IPI */
- irq_set_chip_and_handler(CALL_FUNC_SINGLE_IPI, &mn10300_ipi_type,
- handle_percpu_irq);
- setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi);
- set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV);
- mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
-
- /* set up the local timer IPI */
-#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \
- defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
- irq_set_chip_and_handler(LOCAL_TIMER_IPI, &mn10300_ipi_type,
- handle_percpu_irq);
- setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi);
- set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV);
- mn10300_ipi_enable(LOCAL_TIMER_IPI);
-#endif
-
-#ifdef CONFIG_MN10300_CACHE_ENABLED
- /* set up the cache flush IPI */
- irq_set_chip(FLUSH_CACHE_IPI, &mn10300_ipi_type);
- flags = arch_local_cli_save();
- __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(FLUSH_CACHE_GxICR_LV),
- mn10300_low_ipi_handler);
- GxICR(FLUSH_CACHE_IPI) = FLUSH_CACHE_GxICR_LV | GxICR_DETECT;
- mn10300_ipi_enable(FLUSH_CACHE_IPI);
- arch_local_irq_restore(flags);
-#endif
-
- /* set up the NMI call function IPI */
- irq_set_chip(CALL_FUNCTION_NMI_IPI, &mn10300_ipi_type);
- flags = arch_local_cli_save();
- GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
- tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
- arch_local_irq_restore(flags);
-
- /* set up the SMP boot IPI */
- flags = arch_local_cli_save();
- __set_intr_stub(NUM2EXCEP_IRQ_LEVEL(SMP_BOOT_GxICR_LV),
- mn10300_low_ipi_handler);
- arch_local_irq_restore(flags);
-
-#ifdef CONFIG_KERNEL_DEBUGGER
- irq_set_chip(DEBUGGER_NMI_IPI, &mn10300_ipi_type);
-#endif
-}
-
-/**
- * mn10300_ipi_shutdown - Shut down handling of an IPI
- * @irq: The IPI to be shut down.
- */
-static void mn10300_ipi_shutdown(unsigned int irq)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
-
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_DETECT;
- tmp = GxICR(irq);
-
- arch_local_irq_restore(flags);
-}
-
-/**
- * mn10300_ipi_enable - Enable an IPI
- * @irq: The IPI to be enabled.
- */
-static void mn10300_ipi_enable(unsigned int irq)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
-
- tmp = GxICR(irq);
- GxICR(irq) = (tmp & GxICR_LEVEL) | GxICR_ENABLE;
- tmp = GxICR(irq);
-
- arch_local_irq_restore(flags);
-}
-
-static void mn10300_ipi_chip_enable(struct irq_data *d)
-{
- mn10300_ipi_enable(d->irq);
-}
-
-/**
- * mn10300_ipi_disable - Disable an IPI
- * @irq: The IPI to be disabled.
- */
-static void mn10300_ipi_disable(unsigned int irq)
-{
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
-
- tmp = GxICR(irq);
- GxICR(irq) = tmp & GxICR_LEVEL;
- tmp = GxICR(irq);
-
- arch_local_irq_restore(flags);
-}
-
-static void mn10300_ipi_chip_disable(struct irq_data *d)
-{
- mn10300_ipi_disable(d->irq);
-}
-
-
-/**
- * mn10300_ipi_ack - Acknowledge an IPI interrupt in the PIC
- * @irq: The IPI to be acknowledged.
- *
- * Clear the interrupt detection flag for the IPI on the appropriate interrupt
- * channel in the PIC.
- */
-static void mn10300_ipi_ack(struct irq_data *d)
-{
- unsigned int irq = d->irq;
- unsigned long flags;
- u16 tmp;
-
- flags = arch_local_cli_save();
- GxICR_u8(irq) = GxICR_DETECT;
- tmp = GxICR(irq);
- arch_local_irq_restore(flags);
-}
-
-/**
- * mn10300_ipi_nop - Dummy IPI action
- * @irq: The IPI to be acted upon.
- */
-static void mn10300_ipi_nop(struct irq_data *d)
-{
-}
-
-/**
- * send_IPI_mask - Send IPIs to all CPUs in list
- * @cpumask: The list of CPUs to target.
- * @irq: The IPI request to be sent.
- *
- * Send the specified IPI to all the CPUs in the list, not waiting for them to
- * finish before returning. The caller is responsible for synchronisation if
- * that is needed.
- */
-static void send_IPI_mask(const cpumask_t *cpumask, int irq)
-{
- int i;
- u16 tmp;
-
- for (i = 0; i < NR_CPUS; i++) {
- if (cpumask_test_cpu(i, cpumask)) {
- /* send IPI */
- tmp = CROSS_GxICR(irq, i);
- CROSS_GxICR(irq, i) =
- tmp | GxICR_REQUEST | GxICR_DETECT;
- tmp = CROSS_GxICR(irq, i); /* flush write buffer */
- }
- }
-}
-
-/**
- * send_IPI_self - Send an IPI to this CPU.
- * @irq: The IPI request to be sent.
- *
- * Send the specified IPI to the current CPU.
- */
-void send_IPI_self(int irq)
-{
- send_IPI_mask(cpumask_of(smp_processor_id()), irq);
-}
-
-/**
- * send_IPI_allbutself - Send IPIs to all the other CPUs.
- * @irq: The IPI request to be sent.
- *
- * Send the specified IPI to all CPUs in the system barring the current one,
- * not waiting for them to finish before returning. The caller is responsible
- * for synchronisation if that is needed.
- */
-void send_IPI_allbutself(int irq)
-{
- cpumask_t cpumask;
-
- cpumask_copy(&cpumask, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), &cpumask);
- send_IPI_mask(&cpumask, irq);
-}
-
-void arch_send_call_function_ipi_mask(const struct cpumask *mask)
-{
- BUG();
- /*send_IPI_mask(mask, CALL_FUNCTION_IPI);*/
-}
-
-void arch_send_call_function_single_ipi(int cpu)
-{
- send_IPI_mask(cpumask_of(cpu), CALL_FUNC_SINGLE_IPI);
-}
-
-/**
- * smp_send_reschedule - Send reschedule IPI to a CPU
- * @cpu: The CPU to target.
- */
-void smp_send_reschedule(int cpu)
-{
- send_IPI_mask(cpumask_of(cpu), RESCHEDULE_IPI);
-}
-
-/**
- * smp_nmi_call_function - Send a call function NMI IPI to all CPUs
- * @func: The function to ask to be run.
- * @info: The context data to pass to that function.
- * @wait: If true, wait (atomically) until function is run on all CPUs.
- *
- * Send a non-maskable request to all CPUs in the system, requesting them to
- * run the specified function with the given context data, and, potentially, to
- * wait for completion of that function on all CPUs.
- *
- * Returns 0 if successful, -ETIMEDOUT if we were asked to wait, but hit the
- * timeout.
- */
-int smp_nmi_call_function(smp_call_func_t func, void *info, int wait)
-{
- struct nmi_call_data_struct data;
- unsigned long flags;
- unsigned int cnt;
- int cpus, ret = 0;
-
- cpus = num_online_cpus() - 1;
- if (cpus < 1)
- return 0;
-
- data.func = func;
- data.info = info;
- cpumask_copy(&data.started, cpu_online_mask);
- cpumask_clear_cpu(smp_processor_id(), &data.started);
- data.wait = wait;
- if (wait)
- data.finished = data.started;
-
- spin_lock_irqsave(&smp_nmi_call_lock, flags);
- nmi_call_data = &data;
- smp_mb();
-
- /* Send a message to all other CPUs and wait for them to respond */
- send_IPI_allbutself(CALL_FUNCTION_NMI_IPI);
-
- /* Wait for response */
- if (CALL_FUNCTION_NMI_IPI_TIMEOUT > 0) {
- for (cnt = 0;
- cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
- !cpumask_empty(&data.started);
- cnt++)
- mdelay(1);
-
- if (wait && cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT) {
- for (cnt = 0;
- cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
- !cpumask_empty(&data.finished);
- cnt++)
- mdelay(1);
- }
-
- if (cnt >= CALL_FUNCTION_NMI_IPI_TIMEOUT)
- ret = -ETIMEDOUT;
-
- } else {
- /* If timeout value is zero, wait until cpumask has been
- * cleared */
- while (!cpumask_empty(&data.started))
- barrier();
- if (wait)
- while (!cpumask_empty(&data.finished))
- barrier();
- }
-
- spin_unlock_irqrestore(&smp_nmi_call_lock, flags);
- return ret;
-}
-
-/**
- * smp_jump_to_debugger - Make other CPUs enter the debugger by sending an IPI
- *
- * Send a non-maskable request to all other CPUs in the system, instructing
- * them to jump into the debugger. The caller is responsible for checking that
- * the other CPUs responded to the instruction.
- *
- * The caller should make sure that this CPU's debugger IPI is disabled.
- */
-void smp_jump_to_debugger(void)
-{
- if (num_online_cpus() > 1)
- /* Send a message to all other CPUs */
- send_IPI_allbutself(DEBUGGER_NMI_IPI);
-}
-
-/**
- * stop_this_cpu - Callback to stop a CPU.
- * @unused: Callback context (ignored).
- */
-void stop_this_cpu(void *unused)
-{
- static volatile int stopflag;
- unsigned long flags;
-
-#ifdef CONFIG_GDBSTUB
- /* In case of single stepping smp_send_stop by other CPU,
- * clear procindebug to avoid deadlock.
- */
- atomic_set(&procindebug[smp_processor_id()], 0);
-#endif /* CONFIG_GDBSTUB */
-
- flags = arch_local_cli_save();
- set_cpu_online(smp_processor_id(), false);
-
- while (!stopflag)
- cpu_relax();
-
- set_cpu_online(smp_processor_id(), true);
- arch_local_irq_restore(flags);
-}
-
-/**
- * smp_send_stop - Send a stop request to all CPUs.
- */
-void smp_send_stop(void)
-{
- smp_nmi_call_function(stop_this_cpu, NULL, 0);
-}
-
-/**
- * smp_reschedule_interrupt - Reschedule IPI handler
- * @irq: The interrupt number.
- * @dev_id: The device ID.
- *
- * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
- */
-static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id)
-{
- scheduler_ipi();
- return IRQ_HANDLED;
-}
-
-/**
- * smp_call_function_interrupt - Call function IPI handler
- * @irq: The interrupt number.
- * @dev_id: The device ID.
- *
- * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
- */
-static irqreturn_t smp_call_function_interrupt(int irq, void *dev_id)
-{
- /* generic_smp_call_function_interrupt(); */
- generic_smp_call_function_single_interrupt();
- return IRQ_HANDLED;
-}
-
-/**
- * smp_nmi_call_function_interrupt - Non-maskable call function IPI handler
- */
-void smp_nmi_call_function_interrupt(void)
-{
- smp_call_func_t func = nmi_call_data->func;
- void *info = nmi_call_data->info;
- int wait = nmi_call_data->wait;
-
- /* Notify the initiating CPU that I've grabbed the data and am about to
- * execute the function
- */
- smp_mb();
- cpumask_clear_cpu(smp_processor_id(), &nmi_call_data->started);
- (*func)(info);
-
- if (wait) {
- smp_mb();
- cpumask_clear_cpu(smp_processor_id(),
- &nmi_call_data->finished);
- }
-}
-
-#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \
- defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
-/**
- * smp_ipi_timer_interrupt - Local timer IPI handler
- * @irq: The interrupt number.
- * @dev_id: The device ID.
- *
- * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
- */
-static irqreturn_t smp_ipi_timer_interrupt(int irq, void *dev_id)
-{
- return local_timer_interrupt();
-}
-#endif
-
-void __init smp_init_cpus(void)
-{
- int i;
- for (i = 0; i < NR_CPUS; i++) {
- set_cpu_possible(i, true);
- set_cpu_present(i, true);
- }
-}
-
-/**
- * smp_cpu_init - Initialise AP in start_secondary.
- *
- * For this Application Processor, set up init_mm, initialise FPU and set
- * interrupt level 0-6 setting.
- */
-static void __init smp_cpu_init(void)
-{
- unsigned long flags;
- int cpu_id = smp_processor_id();
- u16 tmp16;
-
- if (test_and_set_bit(cpu_id, &cpu_initialized)) {
- printk(KERN_WARNING "CPU#%d already initialized!\n", cpu_id);
- for (;;)
- local_irq_enable();
- }
- printk(KERN_INFO "Initializing CPU#%d\n", cpu_id);
-
- mmgrab(&init_mm);
- current->active_mm = &init_mm;
- BUG_ON(current->mm);
-
- enter_lazy_tlb(&init_mm, current);
-
- /* Force FPU initialization */
- clear_using_fpu(current);
-
- GxICR(CALL_FUNC_SINGLE_IPI) = CALL_FUNCTION_GxICR_LV | GxICR_DETECT;
- mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
-
- GxICR(LOCAL_TIMER_IPI) = LOCAL_TIMER_GxICR_LV | GxICR_DETECT;
- mn10300_ipi_enable(LOCAL_TIMER_IPI);
-
- GxICR(RESCHEDULE_IPI) = RESCHEDULE_GxICR_LV | GxICR_DETECT;
- mn10300_ipi_enable(RESCHEDULE_IPI);
-
-#ifdef CONFIG_MN10300_CACHE_ENABLED
- GxICR(FLUSH_CACHE_IPI) = FLUSH_CACHE_GxICR_LV | GxICR_DETECT;
- mn10300_ipi_enable(FLUSH_CACHE_IPI);
-#endif
-
- mn10300_ipi_shutdown(SMP_BOOT_IRQ);
-
- /* Set up the non-maskable call function IPI */
- flags = arch_local_cli_save();
- GxICR(CALL_FUNCTION_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
- tmp16 = GxICR(CALL_FUNCTION_NMI_IPI);
- arch_local_irq_restore(flags);
-}
-
-/**
- * smp_prepare_cpu_init - Initialise CPU in startup_secondary
- *
- * Set interrupt level 0-6 setting and init ICR of the kernel debugger.
- */
-void smp_prepare_cpu_init(void)
-{
- int loop;
-
- /* Set the interrupt vector registers */
- IVAR0 = EXCEP_IRQ_LEVEL0;
- IVAR1 = EXCEP_IRQ_LEVEL1;
- IVAR2 = EXCEP_IRQ_LEVEL2;
- IVAR3 = EXCEP_IRQ_LEVEL3;
- IVAR4 = EXCEP_IRQ_LEVEL4;
- IVAR5 = EXCEP_IRQ_LEVEL5;
- IVAR6 = EXCEP_IRQ_LEVEL6;
-
- /* Disable all interrupts and set to priority 6 (lowest) */
- for (loop = 0; loop < GxICR_NUM_IRQS; loop++)
- GxICR(loop) = GxICR_LEVEL_6 | GxICR_DETECT;
-
-#ifdef CONFIG_KERNEL_DEBUGGER
- /* initialise the kernel debugger interrupt */
- do {
- unsigned long flags;
- u16 tmp16;
-
- flags = arch_local_cli_save();
- GxICR(DEBUGGER_NMI_IPI) = GxICR_NMI | GxICR_ENABLE | GxICR_DETECT;
- tmp16 = GxICR(DEBUGGER_NMI_IPI);
- arch_local_irq_restore(flags);
- } while (0);
-#endif
-}
-
-/**
- * start_secondary - Activate a secondary CPU (AP)
- * @unused: Thread parameter (ignored).
- */
-int __init start_secondary(void *unused)
-{
- smp_cpu_init();
- smp_callin();
- while (!cpumask_test_cpu(smp_processor_id(), &smp_commenced_mask))
- cpu_relax();
-
- local_flush_tlb();
- preempt_disable();
- smp_online();
-
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
- init_clockevents();
-#endif
- cpu_startup_entry(CPUHP_AP_ONLINE_IDLE);
- return 0;
-}
-
-/**
- * smp_prepare_cpus - Boot up secondary CPUs (APs)
- * @max_cpus: Maximum number of CPUs to boot.
- *
- * Call do_boot_cpu, and boot up APs.
- */
-void __init smp_prepare_cpus(unsigned int max_cpus)
-{
- int phy_id;
-
- /* Setup boot CPU information */
- smp_store_cpu_info(0);
- smp_tune_scheduling();
-
- init_ipi();
-
- /* If SMP should be disabled, then finish */
- if (max_cpus == 0) {
- printk(KERN_INFO "SMP mode deactivated.\n");
- goto smp_done;
- }
-
- /* Boot secondary CPUs (for which phy_id > 0) */
- for (phy_id = 0; phy_id < NR_CPUS; phy_id++) {
- /* Don't boot primary CPU */
- if (max_cpus <= cpucount + 1)
- continue;
- if (phy_id != 0)
- do_boot_cpu(phy_id);
- set_cpu_possible(phy_id, true);
- smp_show_cpu_info(phy_id);
- }
-
-smp_done:
- Dprintk("Boot done.\n");
-}
-
-/**
- * smp_store_cpu_info - Save a CPU's information
- * @cpu: The CPU to save for.
- *
- * Save boot_cpu_data and jiffy for the specified CPU.
- */
-static void __init smp_store_cpu_info(int cpu)
-{
- struct mn10300_cpuinfo *ci = &cpu_data[cpu];
-
- *ci = boot_cpu_data;
- ci->loops_per_jiffy = loops_per_jiffy;
- ci->type = CPUREV;
-}
-
-/**
- * smp_tune_scheduling - Set time slice value
- *
- * Nothing to do here.
- */
-static void __init smp_tune_scheduling(void)
-{
-}
-
-/**
- * do_boot_cpu: Boot up one CPU
- * @phy_id: Physical ID of CPU to boot.
- *
- * Send an IPI to a secondary CPU to boot it. Returns 0 on success, 1
- * otherwise.
- */
-static int __init do_boot_cpu(int phy_id)
-{
- struct task_struct *idle;
- unsigned long send_status, callin_status;
- int timeout, cpu_id;
-
- send_status = GxICR_REQUEST;
- callin_status = 0;
- timeout = 0;
- cpu_id = phy_id;
-
- cpucount++;
-
- /* Create idle thread for this CPU */
- idle = fork_idle(cpu_id);
- if (IS_ERR(idle))
- panic("Failed fork for CPU#%d.", cpu_id);
-
- idle->thread.pc = (unsigned long)start_secondary;
-
- printk(KERN_NOTICE "Booting CPU#%d\n", cpu_id);
- start_stack[cpu_id - 1] = idle->thread.sp;
-
- task_thread_info(idle)->cpu = cpu_id;
-
- /* Send boot IPI to AP */
- send_IPI_mask(cpumask_of(phy_id), SMP_BOOT_IRQ);
-
- Dprintk("Waiting for send to finish...\n");
-
- /* Wait for AP's IPI receive in 100[ms] */
- do {
- udelay(1000);
- send_status =
- CROSS_GxICR(SMP_BOOT_IRQ, phy_id) & GxICR_REQUEST;
- } while (send_status == GxICR_REQUEST && timeout++ < 100);
-
- Dprintk("Waiting for cpu_callin_map.\n");
-
- if (send_status == 0) {
- /* Allow AP to start initializing */
- cpumask_set_cpu(cpu_id, &cpu_callout_map);
-
- /* Wait for setting cpu_callin_map */
- timeout = 0;
- do {
- udelay(1000);
- callin_status = cpumask_test_cpu(cpu_id,
- &cpu_callin_map);
- } while (callin_status == 0 && timeout++ < 5000);
-
- if (callin_status == 0)
- Dprintk("Not responding.\n");
- } else {
- printk(KERN_WARNING "IPI not delivered.\n");
- }
-
- if (send_status == GxICR_REQUEST || callin_status == 0) {
- cpumask_clear_cpu(cpu_id, &cpu_callout_map);
- cpumask_clear_cpu(cpu_id, &cpu_callin_map);
- cpumask_clear_cpu(cpu_id, &cpu_initialized);
- cpucount--;
- return 1;
- }
- return 0;
-}
-
-/**
- * smp_show_cpu_info - Show SMP CPU information
- * @cpu: The CPU of interest.
- */
-static void __init smp_show_cpu_info(int cpu)
-{
- struct mn10300_cpuinfo *ci = &cpu_data[cpu];
-
- printk(KERN_INFO
- "CPU#%d : ioclk speed: %lu.%02luMHz : bogomips : %lu.%02lu\n",
- cpu,
- MN10300_IOCLK / 1000000,
- (MN10300_IOCLK / 10000) % 100,
- ci->loops_per_jiffy / (500000 / HZ),
- (ci->loops_per_jiffy / (5000 / HZ)) % 100);
-}
-
-/**
- * smp_callin - Set cpu_callin_map of the current CPU ID
- */
-static void __init smp_callin(void)
-{
- unsigned long timeout;
- int cpu;
-
- cpu = smp_processor_id();
- timeout = jiffies + (2 * HZ);
-
- if (cpumask_test_cpu(cpu, &cpu_callin_map)) {
- printk(KERN_ERR "CPU#%d already present.\n", cpu);
- BUG();
- }
- Dprintk("CPU#%d waiting for CALLOUT\n", cpu);
-
- /* Wait for AP startup 2s total */
- while (time_before(jiffies, timeout)) {
- if (cpumask_test_cpu(cpu, &cpu_callout_map))
- break;
- cpu_relax();
- }
-
- if (!time_before(jiffies, timeout)) {
- printk(KERN_ERR
- "BUG: CPU#%d started up but did not get a callout!\n",
- cpu);
- BUG();
- }
-
-#ifdef CONFIG_CALIBRATE_DELAY
- calibrate_delay(); /* Get our bogomips */
-#endif
-
- /* Save our processor parameters */
- smp_store_cpu_info(cpu);
-
- /* Allow the boot processor to continue */
- cpumask_set_cpu(cpu, &cpu_callin_map);
-}
-
-/**
- * smp_online - Set cpu_online_mask
- */
-static void __init smp_online(void)
-{
- int cpu;
-
- cpu = smp_processor_id();
-
- notify_cpu_starting(cpu);
-
- set_cpu_online(cpu, true);
-
- local_irq_enable();
-}
-
-/**
- * smp_cpus_done -
- * @max_cpus: Maximum CPU count.
- *
- * Do nothing.
- */
-void __init smp_cpus_done(unsigned int max_cpus)
-{
-}
-
-/*
- * smp_prepare_boot_cpu - Set up stuff for the boot processor.
- *
- * Set up the cpu_online_mask, cpu_callout_map and cpu_callin_map of the boot
- * processor (CPU 0).
- */
-void smp_prepare_boot_cpu(void)
-{
- cpumask_set_cpu(0, &cpu_callout_map);
- cpumask_set_cpu(0, &cpu_callin_map);
- current_thread_info()->cpu = 0;
-}
-
-/*
- * initialize_secondary - Initialise a secondary CPU (Application Processor).
- *
- * Set SP register and jump to thread's PC address.
- */
-void initialize_secondary(void)
-{
- asm volatile (
- "mov %0,sp \n"
- "jmp (%1) \n"
- :
- : "a"(current->thread.sp), "a"(current->thread.pc));
-}
-
-/**
- * __cpu_up - Set smp_commenced_mask for the nominated CPU
- * @cpu: The target CPU.
- */
-int __cpu_up(unsigned int cpu, struct task_struct *tidle)
-{
- int timeout;
-
-#ifdef CONFIG_HOTPLUG_CPU
- if (sleep_mode[cpu])
- run_wakeup_cpu(cpu);
-#endif /* CONFIG_HOTPLUG_CPU */
-
- cpumask_set_cpu(cpu, &smp_commenced_mask);
-
- /* Wait 5s total for a response */
- for (timeout = 0 ; timeout < 5000 ; timeout++) {
- if (cpu_online(cpu))
- break;
- udelay(1000);
- }
-
- BUG_ON(!cpu_online(cpu));
- return 0;
-}
-
-/**
- * setup_profiling_timer - Set up the profiling timer
- * @multiplier - The frequency multiplier to use
- *
- * The frequency of the profiling timer can be changed by writing a multiplier
- * value into /proc/profile.
- */
-int setup_profiling_timer(unsigned int multiplier)
-{
- return -EINVAL;
-}
-
-/*
- * CPU hotplug routines
- */
-#ifdef CONFIG_HOTPLUG_CPU
-
-static DEFINE_PER_CPU(struct cpu, cpu_devices);
-
-static int __init topology_init(void)
-{
- int cpu, ret;
-
- for_each_cpu(cpu) {
- ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL);
- if (ret)
- printk(KERN_WARNING
- "topology_init: register_cpu %d failed (%d)\n",
- cpu, ret);
- }
- return 0;
-}
-
-subsys_initcall(topology_init);
-
-int __cpu_disable(void)
-{
- int cpu = smp_processor_id();
- if (cpu == 0)
- return -EBUSY;
-
- migrate_irqs();
- cpumask_clear_cpu(cpu, &mm_cpumask(current->active_mm));
- return 0;
-}
-
-void __cpu_die(unsigned int cpu)
-{
- run_sleep_cpu(cpu);
-}
-
-#ifdef CONFIG_MN10300_CACHE_ENABLED
-static inline void hotplug_cpu_disable_cache(void)
-{
- int tmp;
- asm volatile(
- " movhu (%1),%0 \n"
- " and %2,%0 \n"
- " movhu %0,(%1) \n"
- "1: movhu (%1),%0 \n"
- " btst %3,%0 \n"
- " bne 1b \n"
- : "=&r"(tmp)
- : "a"(&CHCTR),
- "i"(~(CHCTR_ICEN | CHCTR_DCEN)),
- "i"(CHCTR_ICBUSY | CHCTR_DCBUSY)
- : "memory", "cc");
-}
-
-static inline void hotplug_cpu_enable_cache(void)
-{
- int tmp;
- asm volatile(
- "movhu (%1),%0 \n"
- "or %2,%0 \n"
- "movhu %0,(%1) \n"
- : "=&r"(tmp)
- : "a"(&CHCTR),
- "i"(CHCTR_ICEN | CHCTR_DCEN)
- : "memory", "cc");
-}
-
-static inline void hotplug_cpu_invalidate_cache(void)
-{
- int tmp;
- asm volatile (
- "movhu (%1),%0 \n"
- "or %2,%0 \n"
- "movhu %0,(%1) \n"
- : "=&r"(tmp)
- : "a"(&CHCTR),
- "i"(CHCTR_ICINV | CHCTR_DCINV)
- : "cc");
-}
-
-#else /* CONFIG_MN10300_CACHE_ENABLED */
-#define hotplug_cpu_disable_cache() do {} while (0)
-#define hotplug_cpu_enable_cache() do {} while (0)
-#define hotplug_cpu_invalidate_cache() do {} while (0)
-#endif /* CONFIG_MN10300_CACHE_ENABLED */
-
-/**
- * hotplug_cpu_nmi_call_function - Call a function on other CPUs for hotplug
- * @cpumask: List of target CPUs.
- * @func: The function to call on those CPUs.
- * @info: The context data for the function to be called.
- * @wait: Whether to wait for the calls to complete.
- *
- * Non-maskably call a function on another CPU for hotplug purposes.
- *
- * This function must be called with maskable interrupts disabled.
- */
-static int hotplug_cpu_nmi_call_function(cpumask_t cpumask,
- smp_call_func_t func, void *info,
- int wait)
-{
- /*
- * The address and the size of nmi_call_func_mask_data
- * need to be aligned on L1_CACHE_BYTES.
- */
- static struct nmi_call_data_struct nmi_call_func_mask_data
- __cacheline_aligned;
- unsigned long start, end;
-
- start = (unsigned long)&nmi_call_func_mask_data;
- end = start + sizeof(struct nmi_call_data_struct);
-
- nmi_call_func_mask_data.func = func;
- nmi_call_func_mask_data.info = info;
- nmi_call_func_mask_data.started = cpumask;
- nmi_call_func_mask_data.wait = wait;
- if (wait)
- nmi_call_func_mask_data.finished = cpumask;
-
- spin_lock(&smp_nmi_call_lock);
- nmi_call_data = &nmi_call_func_mask_data;
- mn10300_local_dcache_flush_range(start, end);
- smp_wmb();
-
- send_IPI_mask(cpumask, CALL_FUNCTION_NMI_IPI);
-
- do {
- mn10300_local_dcache_inv_range(start, end);
- barrier();
- } while (!cpumask_empty(&nmi_call_func_mask_data.started));
-
- if (wait) {
- do {
- mn10300_local_dcache_inv_range(start, end);
- barrier();
- } while (!cpumask_empty(&nmi_call_func_mask_data.finished));
- }
-
- spin_unlock(&smp_nmi_call_lock);
- return 0;
-}
-
-static void restart_wakeup_cpu(void)
-{
- unsigned int cpu = smp_processor_id();
-
- cpumask_set_cpu(cpu, &cpu_callin_map);
- local_flush_tlb();
- set_cpu_online(cpu, true);
- smp_wmb();
-}
-
-static void prepare_sleep_cpu(void *unused)
-{
- sleep_mode[smp_processor_id()] = 1;
- smp_mb();
- mn10300_local_dcache_flush_inv();
- hotplug_cpu_disable_cache();
- hotplug_cpu_invalidate_cache();
-}
-
-/* when this function called, IE=0, NMID=0. */
-static void sleep_cpu(void *unused)
-{
- unsigned int cpu_id = smp_processor_id();
- /*
- * CALL_FUNCTION_NMI_IPI for wakeup_cpu() shall not be requested,
- * before this cpu goes in SLEEP mode.
- */
- do {
- smp_mb();
- __sleep_cpu();
- } while (sleep_mode[cpu_id]);
- restart_wakeup_cpu();
-}
-
-static void run_sleep_cpu(unsigned int cpu)
-{
- unsigned long flags;
- cpumask_t cpumask;
-
- cpumask_copy(&cpumask, &cpumask_of(cpu));
- flags = arch_local_cli_save();
- hotplug_cpu_nmi_call_function(cpumask, prepare_sleep_cpu, NULL, 1);
- hotplug_cpu_nmi_call_function(cpumask, sleep_cpu, NULL, 0);
- udelay(1); /* delay for the cpu to sleep. */
- arch_local_irq_restore(flags);
-}
-
-static void wakeup_cpu(void)
-{
- hotplug_cpu_invalidate_cache();
- hotplug_cpu_enable_cache();
- smp_mb();
- sleep_mode[smp_processor_id()] = 0;
-}
-
-static void run_wakeup_cpu(unsigned int cpu)
-{
- unsigned long flags;
-
- flags = arch_local_cli_save();
-#if NR_CPUS == 2
- mn10300_local_dcache_flush_inv();
-#else
- /*
- * Before waking up the cpu,
- * all online cpus should stop and flush D-Cache for global data.
- */
-#error not support NR_CPUS > 2, when CONFIG_HOTPLUG_CPU=y.
-#endif
- hotplug_cpu_nmi_call_function(cpumask_of(cpu), wakeup_cpu, NULL, 1);
- arch_local_irq_restore(flags);
-}
-
-#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mn10300/kernel/switch_to.S b/arch/mn10300/kernel/switch_to.S
deleted file mode 100644
index de3e74fc9ea0..000000000000
--- a/arch/mn10300/kernel/switch_to.S
+++ /dev/null
@@ -1,179 +0,0 @@
-###############################################################################
-#
-# MN10300 Context switch operation
-#
-# Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
-# Written by David Howells (dhowells@redhat.com)
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public Licence
-# as published by the Free Software Foundation; either version
-# 2 of the Licence, or (at your option) any later version.
-#
-###############################################################################
-#include <linux/sys.h>
-#include <linux/linkage.h>
-#include <asm/thread_info.h>
-#include <asm/cpu-regs.h>
-#ifdef CONFIG_SMP
-#include <proc/smp-regs.h>
-#endif /* CONFIG_SMP */
-
- .text
-
-###############################################################################
-#
-# struct task_struct *__switch_to(struct thread_struct *prev,
-# struct thread_struct *next,
-# struct task_struct *prev_task)
-#
-###############################################################################
-ENTRY(__switch_to)
- movm [d2,d3,a2,a3,exreg1],(sp)
- or EPSW_NMID,epsw
-
- mov (44,sp),d2
-
- mov d0,a0
- mov d1,a1
-
- # save prev context
- mov __switch_back,d0
- mov sp,a2
- mov a2,(THREAD_SP,a0)
- mov a3,(THREAD_A3,a0)
-
-#ifdef CONFIG_KGDB
- btst 0xff,(kgdb_single_step)
- bne __switch_to__lift_sstep_bp
-__switch_to__continue:
-#endif
- mov d0,(THREAD_PC,a0)
-
- mov (THREAD_A3,a1),a3
- mov (THREAD_SP,a1),a2
-
- # switch
- mov a2,sp
-
- # load next context
- GET_THREAD_INFO a2
- mov a2,(__current_ti)
- mov (TI_task,a2),a2
- mov a2,(__current)
-#ifdef CONFIG_MN10300_CURRENT_IN_E2
- mov a2,e2
-#endif
-
- mov (THREAD_PC,a1),a2
- mov d2,d0 # for ret_from_fork
- mov d0,a0 # for __switch_to
-
- jmp (a2)
-
-__switch_back:
- and ~EPSW_NMID,epsw
- ret [d2,d3,a2,a3,exreg1],32
-
-#ifdef CONFIG_KGDB
-###############################################################################
-#
-# Lift the single-step breakpoints when the task being traced is switched out
-# A0 = prev
-# A1 = next
-#
-###############################################################################
-__switch_to__lift_sstep_bp:
- add -12,sp
- mov a0,e4
- mov a1,e5
-
- # Clear the single-step flag to prevent us coming this way until we get
- # switched back in
- bclr 0xff,(kgdb_single_step)
-
- # Remove first breakpoint
- mov (kgdb_sstep_bp_addr),a2
- cmp 0,a2
- beq 1f
- movbu (kgdb_sstep_bp),d0
- movbu d0,(a2)
-#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
- mov a2,d0
- mov a2,d1
- add 1,d1
- calls flush_icache_range
-#endif
-1:
-
- # Remove second breakpoint
- mov (kgdb_sstep_bp_addr+4),a2
- cmp 0,a2
- beq 2f
- movbu (kgdb_sstep_bp+1),d0
- movbu d0,(a2)
-#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
- mov a2,d0
- mov a2,d1
- add 1,d1
- calls flush_icache_range
-#endif
-2:
-
- # Change the resumption address and return
- mov __switch_back__reinstall_sstep_bp,d0
- mov e4,a0
- mov e5,a1
- add 12,sp
- bra __switch_to__continue
-
-###############################################################################
-#
-# Reinstall the single-step breakpoints when the task being traced is switched
-# back in (A1 points to the new thread_struct).
-#
-###############################################################################
-__switch_back__reinstall_sstep_bp:
- add -12,sp
- mov a0,e4 # save the return value
- mov 0xff,d3
-
- # Reinstall first breakpoint
- mov (kgdb_sstep_bp_addr),a2
- cmp 0,a2
- beq 1f
- movbu (a2),d0
- movbu d0,(kgdb_sstep_bp)
- movbu d3,(a2)
-#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
- mov a2,d0
- mov a2,d1
- add 1,d1
- calls flush_icache_range
-#endif
-1:
-
- # Reinstall second breakpoint
- mov (kgdb_sstep_bp_addr+4),a2
- cmp 0,a2
- beq 2f
- movbu (a2),d0
- movbu d0,(kgdb_sstep_bp+1)
- movbu d3,(a2)
-#if defined(CONFIG_MN10300_CACHE_FLUSH_ICACHE) || defined(CONFIG_MN10300_CACHE_INV_ICACHE)
- mov a2,d0
- mov a2,d1
- add 1,d1
- calls flush_icache_range
-#endif
-2:
-
- mov d3,(kgdb_single_step)
-
- # Restore the return value (the previous thread_struct pointer)
- mov e4,a0
- mov a0,d0
- add 12,sp
- bra __switch_back
-
-#endif /* CONFIG_KGDB */
diff --git a/arch/mn10300/kernel/sys_mn10300.c b/arch/mn10300/kernel/sys_mn10300.c
deleted file mode 100644
index f999981e55c0..000000000000
--- a/arch/mn10300/kernel/sys_mn10300.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* MN10300 Weird system calls
- *
- * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/syscalls.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/tty.h>
-
-#include <linux/uaccess.h>
-
-asmlinkage long old_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long offset)
-{
- if (offset & ~PAGE_MASK)
- return -EINVAL;
- return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
-}
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c
deleted file mode 100644
index 06b83b17c5f1..000000000000
--- a/arch/mn10300/kernel/time.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/* MN10300 Low level time management
- *
- * Copyright (C) 2007-2008 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- * - Derived from arch/i386/kernel/time.c
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/sched.h>
-#include <linux/sched/clock.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/time.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/profile.h>
-#include <linux/cnt32_to_63.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <asm/irq.h>
-#include <asm/div64.h>
-#include <asm/processor.h>
-#include <asm/intctl-regs.h>
-#include <asm/rtc.h>
-#include "internal.h"
-
-static unsigned long mn10300_last_tsc; /* time-stamp counter at last time
- * interrupt occurred */
-
-static unsigned long sched_clock_multiplier;
-
-/*
- * scheduler clock - returns current time in nanosec units.
- */
-unsigned long long sched_clock(void)
-{
- union {
- unsigned long long ll;
- unsigned l[2];
- } tsc64, result;
- unsigned long tmp;
- unsigned product[3]; /* 96-bit intermediate value */
-
- /* cnt32_to_63() is not safe with preemption */
- preempt_disable();
-
- /* expand the tsc to 64-bits.
- * - sched_clock() must be called once a minute or better or the
- * following will go horribly wrong - see cnt32_to_63()
- */
- tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL;
-
- preempt_enable();
-
- /* scale the 64-bit TSC value to a nanosecond value via a 96-bit
- * intermediate
- */
- asm("mulu %2,%0,%3,%0 \n" /* LSW * mult -> 0:%3:%0 */
- "mulu %2,%1,%2,%1 \n" /* MSW * mult -> %2:%1:0 */
- "add %3,%1 \n"
- "addc 0,%2 \n" /* result in %2:%1:%0 */
- : "=r"(product[0]), "=r"(product[1]), "=r"(product[2]), "=r"(tmp)
- : "0"(tsc64.l[0]), "1"(tsc64.l[1]), "2"(sched_clock_multiplier)
- : "cc");
-
- result.l[0] = product[1] << 16 | product[0] >> 16;
- result.l[1] = product[2] << 16 | product[1] >> 16;
-
- return result.ll;
-}
-
-/*
- * initialise the scheduler clock
- */
-static void __init mn10300_sched_clock_init(void)
-{
- sched_clock_multiplier =
- __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK);
-}
-
-/**
- * local_timer_interrupt - Local timer interrupt handler
- *
- * Handle local timer interrupts for this CPU. They may have been propagated
- * to this CPU from the CPU that actually gets them by way of an IPI.
- */
-irqreturn_t local_timer_interrupt(void)
-{
- profile_tick(CPU_PROFILING);
- update_process_times(user_mode(get_irq_regs()));
- return IRQ_HANDLED;
-}
-
-/*
- * initialise the various timers used by the main part of the kernel
- */
-void __init time_init(void)
-{
- /* we need the prescalar running to be able to use IOCLK/8
- * - IOCLK runs at 1/4 (ST5 open) or 1/8 (ST5 closed) internal CPU clock
- * - IOCLK runs at Fosc rate (crystal speed)
- */
- TMPSCNT |= TMPSCNT_ENABLE;
-
- init_clocksource();
-
- printk(KERN_INFO
- "timestamp counter I/O clock running at %lu.%02lu"
- " (calibrated against RTC)\n",
- MN10300_TSCCLK / 1000000, (MN10300_TSCCLK / 10000) % 100);
-
- mn10300_last_tsc = read_timestamp_counter();
-
- init_clockevents();
-
-#ifdef CONFIG_MN10300_WD_TIMER
- /* start the watchdog timer */
- watchdog_go();
-#endif
-
- mn10300_sched_clock_init();
-}
diff --git a/arch/mn10300/kernel/traps.c b/arch/mn10300/kernel/traps.c
deleted file mode 100644
index 72d1015b2ae7..000000000000
--- a/arch/mn10300/kernel/traps.c
+++ /dev/null
@@ -1,615 +0,0 @@
-/* MN10300 Exception handling
- *
- * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Modified by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#include <linux/sched.h>
-#include <linux/sched/debug.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/kdebug.h>
-#include <linux/bug.h>
-#include <linux/irq.h>
-#include <linux/export.h>
-#include <asm/processor.h>
-#include <linux/uaccess.h>
-#include <asm/io.h>
-#include <linux/atomic.h>
-#include <asm/smp.h>
-#include <asm/pgalloc.h>
-#include <asm/cacheflush.h>
-#include <asm/cpu-regs.h>
-#include <asm/busctl-regs.h>
-#include <unit/leds.h>
-#include <asm/fpu.h>
-#include <asm/sections.h>
-#include <asm/debugger.h>
-#include "internal.h"
-
-#if (CONFIG_INTERRUPT_VECTOR_BASE & 0xffffff)
-#error "INTERRUPT_VECTOR_BASE not aligned to 16MiB boundary!"
-#endif
-
-int kstack_depth_to_print = 24;
-
-spinlock_t die_lock = __SPIN_LOCK_UNLOCKED(die_lock);
-
-struct exception_to_signal_map {
- u8 signo;
- u32 si_code;
-};
-
-static const struct exception_to_signal_map exception_to_signal_map[256] = {
- /* MMU exceptions */
- [EXCEP_ITLBMISS >> 3] = { 0, 0 },
- [EXCEP_DTLBMISS >> 3] = { 0, 0 },
- [EXCEP_IAERROR >> 3] = { 0, 0 },
- [EXCEP_DAERROR >> 3] = { 0, 0 },
-
- /* system exceptions */
- [EXCEP_TRAP >> 3] = { SIGTRAP, TRAP_BRKPT },
- [EXCEP_ISTEP >> 3] = { SIGTRAP, TRAP_TRACE }, /* Monitor */
- [EXCEP_IBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */
- [EXCEP_OBREAK >> 3] = { SIGTRAP, TRAP_HWBKPT }, /* Monitor */
- [EXCEP_PRIVINS >> 3] = { SIGILL, ILL_PRVOPC },
- [EXCEP_UNIMPINS >> 3] = { SIGILL, ILL_ILLOPC },
- [EXCEP_UNIMPEXINS >> 3] = { SIGILL, ILL_ILLOPC },
- [EXCEP_MEMERR >> 3] = { SIGSEGV, SEGV_ACCERR },
- [EXCEP_MISALIGN >> 3] = { SIGBUS, BUS_ADRALN },
- [EXCEP_BUSERROR >> 3] = { SIGBUS, BUS_ADRERR },
- [EXCEP_ILLINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
- [EXCEP_ILLDATACC >> 3] = { SIGSEGV, SEGV_ACCERR },
- [EXCEP_IOINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
- [EXCEP_PRIVINSACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */
- [EXCEP_PRIVDATACC >> 3] = { SIGSEGV, SEGV_ACCERR }, /* userspace */
- [EXCEP_DATINSACC >> 3] = { SIGSEGV, SEGV_ACCERR },
- [EXCEP_DOUBLE_FAULT >> 3] = { SIGILL, ILL_BADSTK },
-
- /* FPU exceptions */
- [EXCEP_FPU_DISABLED >> 3] = { SIGILL, ILL_COPROC },
- [EXCEP_FPU_UNIMPINS >> 3] = { SIGILL, ILL_COPROC },
- [EXCEP_FPU_OPERATION >> 3] = { SIGFPE, FPE_INTDIV },
-
- /* interrupts */
- [EXCEP_WDT >> 3] = { SIGALRM, 0 },
- [EXCEP_NMI >> 3] = { SIGQUIT, 0 },
- [EXCEP_IRQ_LEVEL0 >> 3] = { SIGINT, 0 },
- [EXCEP_IRQ_LEVEL1 >> 3] = { 0, 0 },
- [EXCEP_IRQ_LEVEL2 >> 3] = { 0, 0 },
- [EXCEP_IRQ_LEVEL3 >> 3] = { 0, 0 },
- [EXCEP_IRQ_LEVEL4 >> 3] = { 0, 0 },
- [EXCEP_IRQ_LEVEL5 >> 3] = { 0, 0 },
- [EXCEP_IRQ_LEVEL6 >> 3] = { 0, 0 },
-
- /* system calls */
- [EXCEP_SYSCALL0 >> 3] = { 0, 0 },
- [EXCEP_SYSCALL1 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL2 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL3 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL4 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL5 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL6 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL7 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL8 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL9 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL10 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL11 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL12 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL13 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL14 >> 3] = { SIGILL, ILL_ILLTRP },
- [EXCEP_SYSCALL15 >> 3] = { SIGABRT, 0 },
-};
-
-/*
- * Handle kernel exceptions.
- *
- * See if there's a fixup handler we can force a jump to when an exception
- * happens due to something kernel code did
- */
-int die_if_no_fixup(const char *str, struct pt_regs *regs,
- enum exception_code code)
-{
- u8 opcode;
- int signo, si_code;
-
- if (user_mode(regs))
- return 0;
-
- peripheral_leds_display_exception(code);
-
- signo = exception_to_signal_map[code >> 3].signo;
- si_code = exception_to_signal_map[code >> 3].si_code;
-
- switch (code) {
- /* see if we can fixup the kernel accessing memory */
- case EXCEP_ITLBMISS:
- case EXCEP_DTLBMISS:
- case EXCEP_IAERROR:
- case EXCEP_DAERROR:
- case EXCEP_MEMERR:
- case EXCEP_MISALIGN:
- case EXCEP_BUSERROR:
- case EXCEP_ILLDATACC:
- case EXCEP_IOINSACC:
- case EXCEP_PRIVINSACC:
- case EXCEP_PRIVDATACC:
- case EXCEP_DATINSACC:
- if (fixup_exception(regs))
- return 1;
- break;
-
- case EXCEP_TRAP:
- case EXCEP_UNIMPINS:
- if (probe_kernel_read(&opcode, (u8 *)regs->pc, 1) < 0)
- break;
- if (opcode == 0xff) {
- if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
- return 1;
- if (at_debugger_breakpoint(regs))
- regs->pc++;
- signo = SIGTRAP;
- si_code = TRAP_BRKPT;
- }
- break;
-
- case EXCEP_SYSCALL1 ... EXCEP_SYSCALL14:
- /* syscall return addr is _after_ the instruction */
- regs->pc -= 2;
- break;
-
- case EXCEP_SYSCALL15:
- if (report_bug(regs->pc, regs) == BUG_TRAP_TYPE_WARN)
- return 1;
-
- /* syscall return addr is _after_ the instruction */
- regs->pc -= 2;
- break;
-
- default:
- break;
- }
-
- if (debugger_intercept(code, signo, si_code, regs) == 0)
- return 1;
-
- if (notify_die(DIE_GPF, str, regs, code, 0, 0))
- return 1;
-
- /* make the process die as the last resort */
- die(str, regs, code);
-}
-
-/*
- * General exception handler
- */
-asmlinkage void handle_exception(struct pt_regs *regs, u32 intcode)
-{
- siginfo_t info;
-
- /* deal with kernel exceptions here */
- if (die_if_no_fixup(NULL, regs, intcode))
- return;
-
- /* otherwise it's a userspace exception */
- info.si_signo = exception_to_signal_map[intcode >> 3].signo;
- info.si_code = exception_to_signal_map[intcode >> 3].si_code;
- info.si_errno = 0;
- info.si_addr = (void *) regs->pc;
- force_sig_info(info.si_signo, &info, current);
-}
-
-/*
- * handle NMI
- */
-asmlinkage void nmi(struct pt_regs *regs, enum exception_code code)
-{
- /* see if gdbstub wants to deal with it */
- if (debugger_intercept(code, SIGQUIT, 0, regs))
- return;
-
- printk(KERN_WARNING "--- Register Dump ---\n");
- show_registers(regs);
- printk(KERN_WARNING "---------------------\n");
-}
-
-/*
- * show a stack trace from the specified stack pointer
- */
-void show_trace(unsigned long *sp)
-{
- unsigned long bottom, stack, addr, fp, raslot;
-
- printk(KERN_EMERG "\nCall Trace:\n");
-
- //stack = (unsigned long)sp;
- asm("mov sp,%0" : "=a"(stack));
- asm("mov a3,%0" : "=r"(fp));
-
- raslot = ULONG_MAX;
- bottom = (stack + THREAD_SIZE) & ~(THREAD_SIZE - 1);
- for (; stack < bottom; stack += sizeof(addr)) {
- addr = *(unsigned long *)stack;
- if (stack == fp) {
- if (addr > stack && addr < bottom) {
- fp = addr;
- raslot = stack + sizeof(addr);
- continue;
- }
- fp = 0;
- raslot = ULONG_MAX;
- }
-
- if (__kernel_text_address(addr)) {
- printk(" [<%08lx>]", addr);
- if (stack >= raslot)
- raslot = ULONG_MAX;
- else
- printk(" ?");
- printk(" %pS\n", (void *)addr);
- }
- }
-
- printk("\n");
-}
-
-/*
- * show the raw stack from the specified stack pointer
- */
-void show_stack(struct task_struct *task, unsigned long *sp)
-{
- unsigned long *stack;
- int i;
-
- if (!sp)
- sp = (unsigned long *) &sp;
-
- stack = sp;
- printk(KERN_EMERG "Stack:");
- for (i = 0; i < kstack_depth_to_print; i++) {
- if (((long) stack & (THREAD_SIZE - 1)) == 0)
- break;
- if ((i % 8) == 0)
- printk(KERN_EMERG " ");
- printk("%08lx ", *stack++);
- }
-
- show_trace(sp);
-}
-
-/*
- * dump the register file in the specified exception frame
- */
-void show_registers_only(struct pt_regs *regs)
-{
- unsigned long ssp;
-
- ssp = (unsigned long) regs + sizeof(*regs);
-
- printk(KERN_EMERG "PC: %08lx EPSW: %08lx SSP: %08lx mode: %s\n",
- regs->pc, regs->epsw, ssp, user_mode(regs) ? "User" : "Super");
- printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
- regs->d0, regs->d1, regs->d2, regs->d3);
- printk(KERN_EMERG "a0: %08lx a1: %08lx a2: %08lx a3: %08lx\n",
- regs->a0, regs->a1, regs->a2, regs->a3);
- printk(KERN_EMERG "e0: %08lx e1: %08lx e2: %08lx e3: %08lx\n",
- regs->e0, regs->e1, regs->e2, regs->e3);
- printk(KERN_EMERG "e4: %08lx e5: %08lx e6: %08lx e7: %08lx\n",
- regs->e4, regs->e5, regs->e6, regs->e7);
- printk(KERN_EMERG "lar: %08lx lir: %08lx mdr: %08lx usp: %08lx\n",
- regs->lar, regs->lir, regs->mdr, regs->sp);
- printk(KERN_EMERG "cvf: %08lx crl: %08lx crh: %08lx drq: %08lx\n",
- regs->mcvf, regs->mcrl, regs->mcrh, regs->mdrq);
- printk(KERN_EMERG "threadinfo=%p task=%p)\n",
- current_thread_info(), current);
-
- if ((unsigned long) current >= PAGE_OFFSET &&
- (unsigned long) current < (unsigned long)high_memory)
- printk(KERN_EMERG "Process %s (pid: %d)\n",
- current->comm, current->pid);
-
-#ifdef CONFIG_SMP
- printk(KERN_EMERG "CPUID: %08x\n", CPUID);
-#endif
- printk(KERN_EMERG "CPUP: %04hx\n", CPUP);
- printk(KERN_EMERG "TBR: %08x\n", TBR);
- printk(KERN_EMERG "DEAR: %08x\n", DEAR);
- printk(KERN_EMERG "sISR: %08x\n", sISR);
- printk(KERN_EMERG "NMICR: %04hx\n", NMICR);
- printk(KERN_EMERG "BCBERR: %08x\n", BCBERR);
- printk(KERN_EMERG "BCBEAR: %08x\n", BCBEAR);
- printk(KERN_EMERG "MMUFCR: %08x\n", MMUFCR);
- printk(KERN_EMERG "IPTEU : %08x IPTEL2: %08x\n", IPTEU, IPTEL2);
- printk(KERN_EMERG "DPTEU: %08x DPTEL2: %08x\n", DPTEU, DPTEL2);
-}
-
-/*
- * dump the registers and the stack
- */
-void show_registers(struct pt_regs *regs)
-{
- unsigned long sp;
- int i;
-
- show_registers_only(regs);
-
- if (!user_mode(regs))
- sp = (unsigned long) regs + sizeof(*regs);
- else
- sp = regs->sp;
-
- /* when in-kernel, we also print out the stack and code at the
- * time of the fault..
- */
- if (!user_mode(regs)) {
- printk(KERN_EMERG "\n");
- show_stack(current, (unsigned long *) sp);
-
-#if 0
- printk(KERN_EMERG "\nCode: ");
- if (regs->pc < PAGE_OFFSET)
- goto bad;
-
- for (i = 0; i < 20; i++) {
- unsigned char c;
- if (__get_user(c, &((unsigned char *) regs->pc)[i]))
- goto bad;
- printk("%02x ", c);
- }
-#else
- i = 0;
-#endif
- }
-
- printk("\n");
- return;
-
-#if 0
-bad:
- printk(KERN_EMERG " Bad PC value.");
- break;
-#endif
-}
-
-/*
- *
- */
-void show_trace_task(struct task_struct *tsk)
-{
- unsigned long sp = tsk->thread.sp;
-
- /* User space on another CPU? */
- if ((sp ^ (unsigned long) tsk) & (PAGE_MASK << 1))
- return;
-
- show_trace((unsigned long *) sp);
-}
-
-/*
- * note the untimely death of part of the kernel
- */
-void die(const char *str, struct pt_regs *regs, enum exception_code code)
-{
- console_verbose();
- spin_lock_irq(&die_lock);
- printk(KERN_EMERG "\n%s: %04x\n",
- str, code & 0xffff);
- show_registers(regs);
-
- if (regs->pc >= 0x02000000 && regs->pc < 0x04000000 &&
- (regs->epsw & (EPSW_IM | EPSW_IE)) != (EPSW_IM | EPSW_IE)) {
- printk(KERN_EMERG "Exception in usermode interrupt handler\n");
- printk(KERN_EMERG "\nPlease connect to kernel debugger !!\n");
- asm volatile ("0: bra 0b");
- }
-
- spin_unlock_irq(&die_lock);
- do_exit(SIGSEGV);
-}
-
-/*
- * display the register file when the stack pointer gets clobbered
- */
-asmlinkage void do_double_fault(struct pt_regs *regs)
-{
- struct task_struct *tsk = current;
-
- strcpy(tsk->comm, "emergency tsk");
- tsk->pid = 0;
- console_verbose();
- printk(KERN_EMERG "--- double fault ---\n");
- show_registers(regs);
-}
-
-/*
- * asynchronous bus error (external, usually I/O DMA)
- */
-asmlinkage void io_bus_error(u32 bcberr, u32 bcbear, struct pt_regs *regs)
-{
- console_verbose();
-
- printk(KERN_EMERG "Asynchronous I/O Bus Error\n");
- printk(KERN_EMERG "==========================\n");
-
- if (bcberr & BCBERR_BEME)
- printk(KERN_EMERG "- Multiple recorded errors\n");
-
- printk(KERN_EMERG "- Faulting Buses:%s%s%s\n",
- bcberr & BCBERR_BEMR_CI ? " CPU-Ins-Fetch" : "",
- bcberr & BCBERR_BEMR_CD ? " CPU-Data" : "",
- bcberr & BCBERR_BEMR_DMA ? " DMA" : "");
-
- printk(KERN_EMERG "- %s %s access made to %s at address %08x\n",
- bcberr & BCBERR_BEBST ? "Burst" : "Single",
- bcberr & BCBERR_BERW ? "Read" : "Write",
- bcberr & BCBERR_BESB_MON ? "Monitor Space" :
- bcberr & BCBERR_BESB_IO ? "Internal CPU I/O Space" :
- bcberr & BCBERR_BESB_EX ? "External I/O Bus" :
- bcberr & BCBERR_BESB_OPEX ? "External Memory Bus" :
- "On Chip Memory",
- bcbear
- );
-
- printk(KERN_EMERG "- Detected by the %s\n",
- bcberr&BCBERR_BESD ? "Bus Control Unit" : "Slave Bus");
-
-#ifdef CONFIG_PCI
-#define BRIDGEREGB(X) (*(volatile __u8 *)(0xBE040000 + (X)))
-#define BRIDGEREGW(X) (*(volatile __u16 *)(0xBE040000 + (X)))
-#define BRIDGEREGL(X) (*(volatile __u32 *)(0xBE040000 + (X)))
-
- printk(KERN_EMERG "- PCI Memory Paging Reg: %08x\n",
- *(volatile __u32 *) (0xBFFFFFF4));
- printk(KERN_EMERG "- PCI Bridge Base Address 0: %08x\n",
- BRIDGEREGL(PCI_BASE_ADDRESS_0));
- printk(KERN_EMERG "- PCI Bridge AMPCI Base Address: %08x\n",
- BRIDGEREGL(0x48));
- printk(KERN_EMERG "- PCI Bridge Command: %04hx\n",
- BRIDGEREGW(PCI_COMMAND));
- printk(KERN_EMERG "- PCI Bridge Status: %04hx\n",
- BRIDGEREGW(PCI_STATUS));
- printk(KERN_EMERG "- PCI Bridge Int Status: %08hx\n",
- BRIDGEREGL(0x4c));
-#endif
-
- printk(KERN_EMERG "\n");
- show_registers(regs);
-
- panic("Halted due to asynchronous I/O Bus Error\n");
-}
-
-/*
- * handle an exception for which a handler has not yet been installed
- */
-asmlinkage void uninitialised_exception(struct pt_regs *regs,
- enum exception_code code)
-{
-
- /* see if gdbstub wants to deal with it */
- if (debugger_intercept(code, SIGSYS, 0, regs) == 0)
- return;
-
- peripheral_leds_display_exception(code);
- printk(KERN_EMERG "Uninitialised Exception 0x%04x\n", code & 0xFFFF);
- show_registers(regs);
-
- for (;;)
- continue;
-}
-
-/*
- * set an interrupt stub to jump to a handler
- * ! NOTE: this does *not* flush the caches
- */
-void __init __set_intr_stub(enum exception_code code, void *handler)
-{
- unsigned long addr;
- u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code);
-
- addr = (unsigned long) handler - (unsigned long) vector;
- vector[0] = 0xdc; /* JMP handler */
- vector[1] = addr;
- vector[2] = addr >> 8;
- vector[3] = addr >> 16;
- vector[4] = addr >> 24;
- vector[5] = 0xcb;
- vector[6] = 0xcb;
- vector[7] = 0xcb;
-}
-
-/*
- * set an interrupt stub to jump to a handler
- */
-void __init set_intr_stub(enum exception_code code, void *handler)
-{
- unsigned long addr;
- u8 *vector = (u8 *)(CONFIG_INTERRUPT_VECTOR_BASE + code);
- unsigned long flags;
-
- addr = (unsigned long) handler - (unsigned long) vector;
-
- flags = arch_local_cli_save();
-
- vector[0] = 0xdc; /* JMP handler */
- vector[1] = addr;
- vector[2] = addr >> 8;
- vector[3] = addr >> 16;
- vector[4] = addr >> 24;
- vector[5] = 0xcb;
- vector[6] = 0xcb;
- vector[7] = 0xcb;
-
- arch_local_irq_restore(flags);
-
-#ifndef CONFIG_MN10300_CACHE_SNOOP
- mn10300_dcache_flush_inv();
- mn10300_icache_inv();
-#endif
-}
-
-/*
- * initialise the exception table
- */
-void __init trap_init(void)
-{
- set_excp_vector(EXCEP_TRAP, handle_exception);
- set_excp_vector(EXCEP_ISTEP, handle_exception);
- set_excp_vector(EXCEP_IBREAK, handle_exception);
- set_excp_vector(EXCEP_OBREAK, handle_exception);
-
- set_excp_vector(EXCEP_PRIVINS, handle_exception);
- set_excp_vector(EXCEP_UNIMPINS, handle_exception);
- set_excp_vector(EXCEP_UNIMPEXINS, handle_exception);
- set_excp_vector(EXCEP_MEMERR, handle_exception);
- set_excp_vector(EXCEP_MISALIGN, misalignment);
- set_excp_vector(EXCEP_BUSERROR, handle_exception);
- set_excp_vector(EXCEP_ILLINSACC, handle_exception);
- set_excp_vector(EXCEP_ILLDATACC, handle_exception);
- set_excp_vector(EXCEP_IOINSACC, handle_exception);
- set_excp_vector(EXCEP_PRIVINSACC, handle_exception);
- set_excp_vector(EXCEP_PRIVDATACC, handle_exception);
- set_excp_vector(EXCEP_DATINSACC, handle_exception);
- set_excp_vector(EXCEP_FPU_UNIMPINS, handle_exception);
- set_excp_vector(EXCEP_FPU_OPERATION, fpu_exception);
-
- set_excp_vector(EXCEP_NMI, nmi);
-
- set_excp_vector(EXCEP_SYSCALL1, handle_exception);
- set_excp_vector(EXCEP_SYSCALL2, handle_exception);
- set_excp_vector(EXCEP_SYSCALL3, handle_exception);
- set_excp_vector(EXCEP_SYSCALL4, handle_exception);
- set_excp_vector(EXCEP_SYSCALL5, handle_exception);
- set_excp_vector(EXCEP_SYSCALL6, handle_exception);
- set_excp_vector(EXCEP_SYSCALL7, handle_exception);
- set_excp_vector(EXCEP_SYSCALL8, handle_exception);
- set_excp_vector(EXCEP_SYSCALL9, handle_exception);
- set_excp_vector(EXCEP_SYSCALL10, handle_exception);
- set_excp_vector(EXCEP_SYSCALL11, handle_exception);
- set_excp_vector(EXCEP_SYSCALL12, handle_exception);
- set_excp_vector(EXCEP_SYSCALL13, handle_exception);
- set_excp_vector(EXCEP_SYSCALL14, handle_exception);
- set_excp_vector(EXCEP_SYSCALL15, handle_exception);
-}
-
-/*
- * determine if a program counter value is a valid bug address
- */
-int is_valid_bugaddr(unsigned long pc)
-{
- return pc >= PAGE_OFFSET;
-}
diff --git a/arch/mn10300/kernel/vmlinux.lds.S b/arch/mn10300/kernel/vmlinux.lds.S
deleted file mode 100644
index 2d5f1c3f1afb..000000000000
--- a/arch/mn10300/kernel/vmlinux.lds.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* MN10300 Main kernel linker script
- *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public Licence
- * as published by the Free Software Foundation; either version
- * 2 of the Licence, or (at your option) any later version.
- */
-#define __VMLINUX_LDS__
-#include <asm-generic/vmlinux.lds.h>
-#include <asm/thread_info.h>
-#include <asm/page.h>
-
-OUTPUT_FORMAT("elf32-am33lin", "elf32-am33lin", "elf32-am33lin")
-OUTPUT_ARCH(mn10300)
-ENTRY(_start)
-jiffies = jiffies_64;
-#ifndef CONFIG_MN10300_CURRENT_IN_E2
-current = __current;
-#endif
-SECTIONS
-{
- . = CONFIG_KERNEL_TEXT_ADDRESS;
- /* read-only */
- _stext = .;
- _text = .; /* Text and read-only data */
- .text : {
- HEAD_TEXT
- TEXT_TEXT
- SCHED_TEXT
- CPUIDLE_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- *(.fixup)
- *(.gnu.warning)
- } = 0xcb
-
- _etext = .; /* End of text section */
-
- EXCEPTION_TABLE(16)
- BUG_TABLE
-
- RO_DATA(PAGE_SIZE)
-
- /* writeable */
- _sdata = .; /* Start of rw data section */
- RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
- _edata = .;
-
- /* might get freed after init */
- . = ALIGN(PAGE_SIZE);
- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
- __smp_locks = .;
- *(.smp_locks)
- __smp_locks_end = .;
- }
-
- /* will be freed after init */
- . = ALIGN(PAGE_SIZE); /* Init code and data */
- __init_begin = .;
- INIT_TEXT_SECTION(PAGE_SIZE)
- INIT_DATA_SECTION(16)
- . = ALIGN(4);
- __alt_instructions = .;
- .altinstructions : { *(.altinstructions) }
- __alt_instructions_end = .;
- .altinstr_replacement : { *(.altinstr_replacement) }
- /* .exit.text is discard at runtime, not link time, to deal with references
- from .altinstructions and .eh_frame */
- .exit.text : { EXIT_TEXT; }
- .exit.data : { EXIT_DATA; }
-
- PERCPU_SECTION(32)
- . = ALIGN(PAGE_SIZE);
- __init_end = .;
- /* freed after init ends here */
-
- BSS_SECTION(0, PAGE_SIZE, 4)
-
- _end = . ;
-
- /* This is where the kernel creates the early boot page tables */
- . = ALIGN(PAGE_SIZE);
- pg0 = .;
-
- STABS_DEBUG
-
- DWARF_DEBUG
-
- /* Sections to be discarded */
- DISCARDS
-}