aboutsummaryrefslogtreecommitdiff
path: root/arch/microblaze/kernel/signal.c
diff options
context:
space:
mode:
authorMichal Simek <monstr@monstr.eu>2009-12-10 11:43:57 +0100
committerMichal Simek <monstr@monstr.eu>2009-12-14 08:45:10 +0100
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 0c96ac34c31..6de3db04b1a 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,
struct rt_sigframe __user *frame;
int err = 0;
int signal;
+ unsigned long address = 0;
+#ifdef CONFIG_MMU
+ pmd_t *pmdp;
+ pte_t *ptep;
+#endif
frame = get_sigframe(ka, regs, sizeof(*frame));
@@ -216,8 +221,29 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
Negative 8 offset because return is rtsd r15, 8 */
regs->r15 = ((unsigned long)frame->tramp)-8;
- __invalidate_cache_sigtramp((unsigned long)frame->tramp);
-
+ address = ((unsigned long)frame->tramp);
+#ifdef CONFIG_MMU
+ pmdp = pmd_offset(pud_offset(
+ pgd_offset(current->mm, address),
+ address), address);
+
+ preempt_disable();
+ ptep = pte_offset_map(pmdp, address);
+ if (pte_present(*ptep)) {
+ address = (unsigned long) page_address(pte_page(*ptep));
+ /* MS: I need add offset in page */
+ address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
+ /* MS address is virtual */
+ address = virt_to_phys(address);
+ invalidate_icache_range(address, address + 8);
+ flush_dcache_range(address, address + 8);
+ }
+ pte_unmap(ptep);
+ preempt_enable();
+#else
+ flush_icache_range(address, address + 8);
+ flush_dcache_range(address, address + 8);
+#endif
if (err)
goto give_sigsegv;