This source file includes following definitions.
- prom_probe_memory
- probe_memory
- sparc_lvl15_nmi
- do_sparc_fault
- force_user_fault
- window_overflow_fault
- window_underflow_fault
- window_ret_fault
1
2
3
4
5
6
7 #include <linux/string.h>
8 #include <linux/types.h>
9 #include <linux/ptrace.h>
10 #include <linux/mman.h>
11 #include <linux/signal.h>
12 #include <linux/mm.h>
13
14 #include <asm/system.h>
15 #include <asm/segment.h>
16 #include <asm/openprom.h>
17 #include <asm/idprom.h>
18 #include <asm/page.h>
19 #include <asm/pgtable.h>
20 #include <asm/memreg.h>
21 #include <asm/openprom.h>
22 #include <asm/oplib.h>
23 #include <asm/traps.h>
24 #include <asm/kdebug.h>
25
26 #define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
27
28 extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
29 extern int prom_node_root;
30
31 extern void die_if_kernel(char *,struct pt_regs *);
32
33 struct linux_romvec *romvec;
34
35
36
37
38
39 int num_segmaps, num_contexts;
40 int invalid_segment;
41
42
43
44 int vac_size, vac_linesize, vac_do_hw_vac_flushes;
45 int vac_entries_per_context, vac_entries_per_segment;
46 int vac_entries_per_page;
47
48
49 int prom_probe_memory (void)
50 {
51 register struct linux_mlist_v0 *mlist;
52 register unsigned long bytes, base_paddr, tally;
53 register int i;
54
55 i = 0;
56 mlist= *prom_meminfo()->v0_available;
57 bytes = tally = mlist->num_bytes;
58 base_paddr = (unsigned long) mlist->start_adr;
59
60 sp_banks[0].base_addr = base_paddr;
61 sp_banks[0].num_bytes = bytes;
62
63 while (mlist->theres_more != (void *) 0){
64 i++;
65 mlist = mlist->theres_more;
66 bytes = mlist->num_bytes;
67 tally += bytes;
68 if (i >= SPARC_PHYS_BANKS-1) {
69 printk ("The machine has more banks that this kernel can support\n"
70 "Increase the SPARC_PHYS_BANKS setting (currently %d)\n",
71 SPARC_PHYS_BANKS);
72 i = SPARC_PHYS_BANKS-1;
73 break;
74 }
75
76 sp_banks[i].base_addr = (unsigned long) mlist->start_adr;
77 sp_banks[i].num_bytes = mlist->num_bytes;
78 }
79
80 i++;
81 sp_banks[i].base_addr = 0xdeadbeef;
82 sp_banks[i].num_bytes = 0;
83
84 return tally;
85 }
86
87
88
89
90 unsigned long
91 probe_memory(void)
92 {
93 int total;
94
95 total = prom_probe_memory();
96
97
98 return total;
99 }
100
101 extern void sun4c_complete_all_stores(void);
102
103
104 asmlinkage void sparc_lvl15_nmi(struct pt_regs *regs, unsigned long serr,
105 unsigned long svaddr, unsigned long aerr,
106 unsigned long avaddr)
107 {
108 sun4c_complete_all_stores();
109 printk("FAULT: NMI received\n");
110 printk("SREGS: Synchronous Error %08lx\n", serr);
111 printk(" Synchronous Vaddr %08lx\n", svaddr);
112 printk(" Asynchronous Error %08lx\n", aerr);
113 printk(" Asynchronous Vaddr %08lx\n", avaddr);
114 printk("REGISTER DUMP:\n");
115 show_regs(regs);
116 prom_halt();
117 }
118
119 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
120 unsigned long address)
121 {
122 struct vm_area_struct *vma;
123 int from_user = !(regs->psr & PSR_PS);
124
125 if(text_fault)
126 address = regs->pc;
127
128
129
130
131
132
133 if(!from_user && address >= KERNBASE) {
134 quick_kernel_fault(address);
135 return;
136 }
137
138 vma = find_vma(current, address);
139 if(!vma)
140 goto bad_area;
141 if(vma->vm_start <= address)
142 goto good_area;
143 if(!(vma->vm_flags & VM_GROWSDOWN))
144 goto bad_area;
145 if(expand_stack(vma, address))
146 goto bad_area;
147
148
149
150
151 good_area:
152 if(write) {
153 if(!(vma->vm_flags & VM_WRITE))
154 goto bad_area;
155 } else {
156
157 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
158 goto bad_area;
159 }
160 handle_mm_fault(vma, address, write);
161 return;
162
163
164
165
166 bad_area:
167 if(from_user) {
168 current->tss.sig_address = address;
169 current->tss.sig_desc = SUBSIG_NOMAPPING;
170 send_sig(SIGSEGV, current, 1);
171 return;
172 }
173
174 if (wp_works_ok < 0 && address == 0x0) {
175 wp_works_ok = 1;
176 printk("This Sparc honours the WP bit even when in supervisor mode. "
177 "Good.\n");
178
179 regs->pc = regs->npc;
180 regs->npc += 4;
181 return;
182 }
183 if((unsigned long) address < PAGE_SIZE) {
184 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
185 } else
186 printk(KERN_ALERT "Unable to handle kernel paging request");
187 printk(" at virtual address %08lx\n",address);
188 printk(KERN_ALERT "current->mm->context = %08lx\n",
189 (unsigned long) current->mm->context);
190 printk(KERN_ALERT "current->mm->pgd = %08lx\n",
191 (unsigned long) current->mm->pgd);
192 die_if_kernel("Oops", regs);
193 }
194
195
196 inline void force_user_fault(unsigned long address, int write)
197 {
198 struct vm_area_struct *vma;
199
200 vma = find_vma(current, address);
201 if(!vma)
202 goto bad_area;
203 if(vma->vm_start <= address)
204 goto good_area;
205 if(!(vma->vm_flags & VM_GROWSDOWN))
206 goto bad_area;
207 if(expand_stack(vma, address))
208 goto bad_area;
209 good_area:
210 if(write)
211 if(!(vma->vm_flags & VM_WRITE))
212 goto bad_area;
213 else
214 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
215 goto bad_area;
216 handle_mm_fault(vma, address, write);
217 return;
218 bad_area:
219 current->tss.sig_address = address;
220 current->tss.sig_desc = SUBSIG_NOMAPPING;
221 send_sig(SIGSEGV, current, 1);
222 return;
223 }
224
225 void window_overflow_fault(void)
226 {
227 unsigned long sp = current->tss.rwbuf_stkptrs[0];
228
229 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
230 force_user_fault(sp + 0x38, 1);
231 force_user_fault(sp, 1);
232 }
233
234 void window_underflow_fault(unsigned long sp)
235 {
236 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
237 force_user_fault(sp + 0x38, 0);
238 force_user_fault(sp, 0);
239 }
240
241 void window_ret_fault(struct pt_regs *regs)
242 {
243 unsigned long sp = regs->u_regs[UREG_FP];
244
245 if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK))
246 force_user_fault(sp + 0x38, 0);
247 force_user_fault(sp, 0);
248 }