OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [armnommu/] [mm/] [fault-armv.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1622 jcastillo
/*
2
 *  linux/arch/arm/mm/fault.c
3
 *
4
 *  Copyright (C) 1995  Linus Torvalds
5
 *  Modifications for ARM processor (c) 1995, 1996 Russell King
6
 */
7
 
8
#include <linux/signal.h>
9
#include <linux/sched.h>
10
#include <linux/head.h>
11
#include <linux/kernel.h>
12
#include <linux/errno.h>
13
#include <linux/string.h>
14
#include <linux/types.h>
15
#include <linux/ptrace.h>
16
#include <linux/mman.h>
17
#include <linux/mm.h>
18
 
19
#include <asm/system.h>
20
#include <asm/segment.h>
21
#include <asm/pgtable.h>
22
 
23
#define FAULT_CODE_READ         0x02
24
#define FAULT_CODE_USER         0x01
25
 
26
extern void die_if_kernel(char *msg, struct pt_regs *regs, unsigned int err, unsigned int ret);
27
 
28
static void kernel_page_fault (unsigned long addr, int mode, struct pt_regs *regs,
29
                               struct task_struct *tsk, struct mm_struct *mm)
30
{
31
        /*
32
         * Oops. The kernel tried to access some bad page. We'll have to
33
         * terminate things with extreme prejudice.
34
         */
35
        if (addr < PAGE_SIZE)
36
            printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");
37
        else
38
            printk (KERN_ALERT "Unable to handle kernel paging request");
39
        printk (" at virtual address %08lx\n", addr);
40
        die_if_kernel ("Oops", regs, mode, SIGKILL);
41
        do_exit (SIGKILL);
42
}
43
 
44
static void page_fault (unsigned long addr, int mode, struct pt_regs *regs)
45
{
46
        struct task_struct *tsk = current;
47
        struct mm_struct *mm = tsk->mm;
48
        struct vm_area_struct *vma;
49
 
50
        if (mode & FAULT_CODE_USER) {
51
                tsk->tss.error_code = mode;
52
                tsk->tss.trap_no = 14;
53
                printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
54
                        tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
55
#ifdef DEBUG
56
                show_regs (regs);
57
                c_backtrace (regs->ARM_fp, regs->ARM_cpsr);
58
#endif
59
                force_sig(SIGSEGV, tsk);
60
                return;
61
        }
62
 
63
        kernel_page_fault (addr, mode, regs, tsk, mm);
64
}
65
 
66
/*
67
 * Handle a data abort.  Note that we have to handle a range of addresses
68
 * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
69
 * a copy-on-write
70
 */
71
asmlinkage void
72
do_DataAbort (unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
73
{
74
        if (user_mode(regs))
75
                error_code |= FAULT_CODE_USER;
76
 
77
#define DIE(signr,nam)\
78
                force_sig(signr, current);\
79
                die_if_kernel(nam, regs, fsr, signr);\
80
                break;
81
 
82
        switch (fsr & 15) {
83
        case 2:
84
                DIE(SIGKILL, "Terminal exception")
85
        case 0:
86
                DIE(SIGSEGV, "Vector exception")
87
        case 1:
88
        case 3:
89
                DIE(SIGBUS, "Alignment exception")
90
        case 12:
91
        case 14:
92
                DIE(SIGBUS, "External abort on translation")
93
        case 9:
94
        case 11:
95
                DIE(SIGSEGV, "Domain fault")
96
        case 13:/* permission fault on section */
97
#ifndef DEBUG
98
                show_regs(regs);
99
                {
100
                        unsigned int i, j, a;
101
                        a = regs->ARM_sp;
102
                        for (j = 0; j < 10; j++) {
103
                                printk ("%08x: ", a);
104
                                for (i = 0; i < 8; i += 1, a += 4)
105
                                        printk ("%08lx ", *(unsigned long *)a);
106
                                printk ("\n");
107
                        }
108
                }
109
#endif
110
                DIE(SIGSEGV, "Permission fault")
111
 
112
        case 15:/* permission fault on page */
113
        case 5: /* page-table entry descriptor fault */
114
        case 7: /* first-level descriptor fault */
115
                page_fault (addr, error_code, regs);
116
                break;
117
        case 4:
118
        case 6:
119
                DIE(SIGBUS, "External abort on linefetch")
120
        case 8:
121
        case 10:
122
                DIE(SIGBUS, "External abort on non-linefetch")
123
        }
124
}
125
 
126
asmlinkage int
127
do_PrefetchAbort (unsigned long addr, struct pt_regs *regs)
128
{
129
#if 0
130
        /* does this still apply ? */
131
        if (the memc mapping for this page exists - can check now...) {
132
                printk ("Page in, but got abort (undefined instruction?)\n");
133
                return 0;
134
        }
135
#endif
136
        page_fault (addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
137
        return 1;
138
}
139
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.