aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/signal.c
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2009-12-10 05:43:57 -0500
committerMichal Simek <monstr@monstr.eu>2009-12-14 02:45:10 -0500
commit2ee2ff875a4d3bdb941e2bb1173cd927c09d5a67 (patch)
treea1ec4db3055527a2814cbdb006652dbf0885b348 /arch/microblaze/kernel/signal.c
parentc8983a5c6ecc5ca68a871c44bc35f714663a4dfa (diff)
microblaze: Support for WB cache
Microblaze version 7.20.d is the first MB version which can be run on MMU linux. Please do not used previous version because they contain HW bug. Based on WB support was necessary to redesign whole cache design. Microblaze versions from 7.20.a don't need to disable IRQ and cache before working with them that's why there are special structures for it. Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'arch/microblaze/kernel/signal.c')
-rw-r--r--arch/microblaze/kernel/signal.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index 0c96ac34c316..6de3db04b1a4 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -176,6 +176,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
176 struct rt_sigframe __user *frame; 176 struct rt_sigframe __user *frame;
177 int err = 0; 177 int err = 0;
178 int signal; 178 int signal;
179 unsigned long address = 0;
180#ifdef CONFIG_MMU
181 pmd_t *pmdp;
182 pte_t *ptep;
183#endif
179 184
180 frame = get_sigframe(ka, regs, sizeof(*frame)); 185 frame = get_sigframe(ka, regs, sizeof(*frame));
181 186
@@ -216,8 +221,29 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
216 Negative 8 offset because return is rtsd r15, 8 */ 221 Negative 8 offset because return is rtsd r15, 8 */
217 regs->r15 = ((unsigned long)frame->tramp)-8; 222 regs->r15 = ((unsigned long)frame->tramp)-8;
218 223
219 __invalidate_cache_sigtramp((unsigned long)frame->tramp); 224 address = ((unsigned long)frame->tramp);
220 225#ifdef CONFIG_MMU
226 pmdp = pmd_offset(pud_offset(
227 pgd_offset(current->mm, address),
228 address), address);
229
230 preempt_disable();
231 ptep = pte_offset_map(pmdp, address);
232 if (pte_present(*ptep)) {
233 address = (unsigned long) page_address(pte_page(*ptep));
234 /* MS: I need add offset in page */
235 address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
236 /* MS address is virtual */
237 address = virt_to_phys(address);
238 invalidate_icache_range(address, address + 8);
239 flush_dcache_range(address, address + 8);
240 }
241 pte_unmap(ptep);
242 preempt_enable();
243#else
244 flush_icache_range(address, address + 8);
245 flush_dcache_range(address, address + 8);
246#endif
221 if (err) 247 if (err)
222 goto give_sigsegv; 248 goto give_sigsegv;
223 249