The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arch/score/kernel/traps.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * arch/score/kernel/traps.c
    3  *
    4  * Score Processor version.
    5  *
    6  * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
    7  *  Chen Liqin <liqin.chen@sunplusct.com>
    8  *  Lennox Wu <lennox.wu@sunplusct.com>
    9  *
   10  * This program is free software; you can redistribute it and/or modify
   11  * it under the terms of the GNU General Public License as published by
   12  * the Free Software Foundation; either version 2 of the License, or
   13  * (at your option) any later version.
   14  *
   15  * This program is distributed in the hope that it will be useful,
   16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18  * GNU General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License
   21  * along with this program; if not, see the file COPYING, or write
   22  * to the Free Software Foundation, Inc.,
   23  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   24  */
   25 
   26 #include <linux/module.h>
   27 #include <linux/sched.h>
   28 
   29 #include <asm/cacheflush.h>
   30 #include <asm/irq.h>
   31 #include <asm/irq_regs.h>
   32 
   33 unsigned long exception_handlers[32];
   34 
   35 /*
   36  * The architecture-independent show_stack generator
   37  */
   38 void show_stack(struct task_struct *task, unsigned long *sp)
   39 {
   40         int i;
   41         long stackdata;
   42 
   43         sp = sp ? sp : (unsigned long *)&sp;
   44 
   45         printk(KERN_NOTICE "Stack: ");
   46         i = 1;
   47         while ((long) sp & (PAGE_SIZE - 1)) {
   48                 if (i && ((i % 8) == 0))
   49                         printk(KERN_NOTICE "\n");
   50                 if (i > 40) {
   51                         printk(KERN_NOTICE " ...");
   52                         break;
   53                 }
   54 
   55                 if (__get_user(stackdata, sp++)) {
   56                         printk(KERN_NOTICE " (Bad stack address)");
   57                         break;
   58                 }
   59 
   60                 printk(KERN_NOTICE " %08lx", stackdata);
   61                 i++;
   62         }
   63         printk(KERN_NOTICE "\n");
   64 }
   65 
   66 static void show_trace(long *sp)
   67 {
   68         int i;
   69         long addr;
   70 
   71         sp = sp ? sp : (long *) &sp;
   72 
   73         printk(KERN_NOTICE "Call Trace:  ");
   74         i = 1;
   75         while ((long) sp & (PAGE_SIZE - 1)) {
   76                 if (__get_user(addr, sp++)) {
   77                         if (i && ((i % 6) == 0))
   78                                 printk(KERN_NOTICE "\n");
   79                         printk(KERN_NOTICE " (Bad stack address)\n");
   80                         break;
   81                 }
   82 
   83                 if (kernel_text_address(addr)) {
   84                         if (i && ((i % 6) == 0))
   85                                 printk(KERN_NOTICE "\n");
   86                         if (i > 40) {
   87                                 printk(KERN_NOTICE " ...");
   88                                 break;
   89                         }
   90 
   91                         printk(KERN_NOTICE " [<%08lx>]", addr);
   92                         i++;
   93                 }
   94         }
   95         printk(KERN_NOTICE "\n");
   96 }
   97 
   98 static void show_code(unsigned int *pc)
   99 {
  100         long i;
  101 
  102         printk(KERN_NOTICE "\nCode:");
  103 
  104         for (i = -3; i < 6; i++) {
  105                 unsigned long insn;
  106                 if (__get_user(insn, pc + i)) {
  107                         printk(KERN_NOTICE " (Bad address in epc)\n");
  108                         break;
  109                 }
  110                 printk(KERN_NOTICE "%c%08lx%c", (i ? ' ' : '<'),
  111                         insn, (i ? ' ' : '>'));
  112         }
  113 }
  114 
  115 /*
  116  * FIXME: really the generic show_regs should take a const pointer argument.
  117  */
  118 void show_regs(struct pt_regs *regs)
  119 {
  120         printk("r0 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  121                 regs->regs[0], regs->regs[1], regs->regs[2], regs->regs[3],
  122                 regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
  123         printk("r8 : %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  124                 regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11],
  125                 regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
  126         printk("r16: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  127                 regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19],
  128                 regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
  129         printk("r24: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  130                 regs->regs[24], regs->regs[25], regs->regs[26], regs->regs[27],
  131                 regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
  132 
  133         printk("CEH : %08lx\n", regs->ceh);
  134         printk("CEL : %08lx\n", regs->cel);
  135 
  136         printk("EMA:%08lx, epc:%08lx %s\nPSR: %08lx\nECR:%08lx\nCondition : %08lx\n",
  137                 regs->cp0_ema, regs->cp0_epc, print_tainted(), regs->cp0_psr,
  138                 regs->cp0_ecr, regs->cp0_condition);
  139 }
  140 
  141 static void show_registers(struct pt_regs *regs)
  142 {
  143         show_regs(regs);
  144         printk(KERN_NOTICE "Process %s (pid: %d, stackpage=%08lx)\n",
  145                 current->comm, current->pid, (unsigned long) current);
  146         show_stack(current_thread_info()->task, (long *) regs->regs[0]);
  147         show_trace((long *) regs->regs[0]);
  148         show_code((unsigned int *) regs->cp0_epc);
  149         printk(KERN_NOTICE "\n");
  150 }
  151 
  152 /*
  153  * The architecture-independent dump_stack generator
  154  */
  155 void dump_stack(void)
  156 {
  157         show_stack(current_thread_info()->task,
  158                    (long *) get_irq_regs()->regs[0]);
  159 }
  160 EXPORT_SYMBOL(dump_stack);
  161 
  162 void __die(const char *str, struct pt_regs *regs, const char *file,
  163         const char *func, unsigned long line)
  164 {
  165         console_verbose();
  166         printk("%s", str);
  167         if (file && func)
  168                 printk(" in %s:%s, line %ld", file, func, line);
  169         printk(":\n");
  170         show_registers(regs);
  171         do_exit(SIGSEGV);
  172 }
  173 
  174 void __die_if_kernel(const char *str, struct pt_regs *regs,
  175                 const char *file, const char *func, unsigned long line)
  176 {
  177         if (!user_mode(regs))
  178                 __die(str, regs, file, func, line);
  179 }
  180 
  181 asmlinkage void do_adelinsn(struct pt_regs *regs)
  182 {
  183         printk("do_ADE-linsn:ema:0x%08lx:epc:0x%08lx\n",
  184                  regs->cp0_ema, regs->cp0_epc);
  185         die_if_kernel("do_ade execution Exception\n", regs);
  186         force_sig(SIGBUS, current);
  187 }
  188 
  189 asmlinkage void do_adedata(struct pt_regs *regs)
  190 {
  191         const struct exception_table_entry *fixup;
  192         fixup = search_exception_tables(regs->cp0_epc);
  193         if (fixup) {
  194                 regs->cp0_epc = fixup->fixup;
  195                 return;
  196         }
  197         printk("do_ADE-data:ema:0x%08lx:epc:0x%08lx\n",
  198                  regs->cp0_ema, regs->cp0_epc);
  199         die_if_kernel("do_ade execution Exception\n", regs);
  200         force_sig(SIGBUS, current);
  201 }
  202 
  203 asmlinkage void do_pel(struct pt_regs *regs)
  204 {
  205         die_if_kernel("do_pel execution Exception", regs);
  206         force_sig(SIGFPE, current);
  207 }
  208 
  209 asmlinkage void do_cee(struct pt_regs *regs)
  210 {
  211         die_if_kernel("do_cee execution Exception", regs);
  212         force_sig(SIGFPE, current);
  213 }
  214 
  215 asmlinkage void do_cpe(struct pt_regs *regs)
  216 {
  217         die_if_kernel("do_cpe execution Exception", regs);
  218         force_sig(SIGFPE, current);
  219 }
  220 
  221 asmlinkage void do_be(struct pt_regs *regs)
  222 {
  223         die_if_kernel("do_be execution Exception", regs);
  224         force_sig(SIGBUS, current);
  225 }
  226 
  227 asmlinkage void do_ov(struct pt_regs *regs)
  228 {
  229         siginfo_t info;
  230 
  231         die_if_kernel("do_ov execution Exception", regs);
  232 
  233         info.si_code = FPE_INTOVF;
  234         info.si_signo = SIGFPE;
  235         info.si_errno = 0;
  236         info.si_addr = (void *)regs->cp0_epc;
  237         force_sig_info(SIGFPE, &info, current);
  238 }
  239 
  240 asmlinkage void do_tr(struct pt_regs *regs)
  241 {
  242         die_if_kernel("do_tr execution Exception", regs);
  243         force_sig(SIGTRAP, current);
  244 }
  245 
  246 asmlinkage void do_ri(struct pt_regs *regs)
  247 {
  248         unsigned long epc_insn;
  249         unsigned long epc = regs->cp0_epc;
  250 
  251         read_tsk_long(current, epc, &epc_insn);
  252         if (current->thread.single_step == 1) {
  253                 if ((epc == current->thread.addr1) ||
  254                     (epc == current->thread.addr2)) {
  255                         user_disable_single_step(current);
  256                         force_sig(SIGTRAP, current);
  257                         return;
  258                 } else
  259                         BUG();
  260         } else if ((epc_insn == BREAKPOINT32_INSN) ||
  261                    ((epc_insn & 0x0000FFFF) == 0x7002) ||
  262                    ((epc_insn & 0xFFFF0000) == 0x70020000)) {
  263                         force_sig(SIGTRAP, current);
  264                         return;
  265         } else {
  266                 die_if_kernel("do_ri execution Exception", regs);
  267                 force_sig(SIGILL, current);
  268         }
  269 }
  270 
  271 asmlinkage void do_ccu(struct pt_regs *regs)
  272 {
  273         die_if_kernel("do_ccu execution Exception", regs);
  274         force_sig(SIGILL, current);
  275 }
  276 
  277 asmlinkage void do_reserved(struct pt_regs *regs)
  278 {
  279         /*
  280          * Game over - no way to handle this if it ever occurs.  Most probably
  281          * caused by a new unknown cpu type or after another deadly
  282          * hard/software error.
  283          */
  284         die_if_kernel("do_reserved execution Exception", regs);
  285         show_regs(regs);
  286         panic("Caught reserved exception - should not happen.");
  287 }
  288 
  289 /*
  290  * NMI exception handler.
  291  */
  292 void nmi_exception_handler(struct pt_regs *regs)
  293 {
  294         die_if_kernel("nmi_exception_handler execution Exception", regs);
  295         die("NMI", regs);
  296 }
  297 
  298 /* Install CPU exception handler */
  299 void *set_except_vector(int n, void *addr)
  300 {
  301         unsigned long handler = (unsigned long) addr;
  302         unsigned long old_handler = exception_handlers[n];
  303 
  304         exception_handlers[n] = handler;
  305         return (void *)old_handler;
  306 }
  307 
  308 void __init trap_init(void)
  309 {
  310         int i;
  311 
  312         pgd_current = (unsigned long)init_mm.pgd;
  313         /* DEBUG EXCEPTION */
  314         memcpy((void *)DEBUG_VECTOR_BASE_ADDR,
  315                         &debug_exception_vector, DEBUG_VECTOR_SIZE);
  316         /* NMI EXCEPTION */
  317         memcpy((void *)GENERAL_VECTOR_BASE_ADDR,
  318                         &general_exception_vector, GENERAL_VECTOR_SIZE);
  319 
  320         /*
  321          * Initialise exception handlers
  322          */
  323         for (i = 0; i <= 31; i++)
  324                 set_except_vector(i, handle_reserved);
  325 
  326         set_except_vector(1, handle_nmi);
  327         set_except_vector(2, handle_adelinsn);
  328         set_except_vector(3, handle_tlb_refill);
  329         set_except_vector(4, handle_tlb_invaild);
  330         set_except_vector(5, handle_ibe);
  331         set_except_vector(6, handle_pel);
  332         set_except_vector(7, handle_sys);
  333         set_except_vector(8, handle_ccu);
  334         set_except_vector(9, handle_ri);
  335         set_except_vector(10, handle_tr);
  336         set_except_vector(11, handle_adedata);
  337         set_except_vector(12, handle_adedata);
  338         set_except_vector(13, handle_tlb_refill);
  339         set_except_vector(14, handle_tlb_invaild);
  340         set_except_vector(15, handle_mod);
  341         set_except_vector(16, handle_cee);
  342         set_except_vector(17, handle_cpe);
  343         set_except_vector(18, handle_dbe);
  344         flush_icache_range(DEBUG_VECTOR_BASE_ADDR, IRQ_VECTOR_BASE_ADDR);
  345 
  346         atomic_inc(&init_mm.mm_count);
  347         current->active_mm = &init_mm;
  348         cpu_cache_init();
  349 }

Cache object: d09b53d8ad0dc66fa9d6bd7814752834


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.