aboutsummaryrefslogtreecommitdiff
path: root/arch/blackfin/include/asm/mmu_context.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/include/asm/mmu_context.h')
-rw-r--r--arch/blackfin/include/asm/mmu_context.h87
1 files changed, 52 insertions, 35 deletions
diff --git a/arch/blackfin/include/asm/mmu_context.h b/arch/blackfin/include/asm/mmu_context.h
index 944e29faae4..15b16d3e8de 100644
--- a/arch/blackfin/include/asm/mmu_context.h
+++ b/arch/blackfin/include/asm/mmu_context.h
@@ -1,41 +1,19 @@
/*
- * File: include/asm-blackfin/mmu_context.h
- * Based on:
- * Author:
+ * Copyright 2004-2009 Analog Devices Inc.
*
- * Created:
- * Description:
- *
- * Modified:
- * Copyright 2004-2006 Analog Devices Inc.
- *
- * Bugs: Enter bugs at http://blackfin.uclinux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * Licensed under the GPL-2 or later.
*/
#ifndef __BLACKFIN_MMU_CONTEXT_H__
#define __BLACKFIN_MMU_CONTEXT_H__
-#include <linux/gfp.h>
+#include <linux/slab.h>
#include <linux/sched.h>
#include <asm/setup.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/cplbinit.h>
+#include <asm/sections.h>
/* Note: L1 stacks are CPU-private things, so we bluntly disable this
feature in SMP mode, and use the per-CPU scratch SRAM bank only to
@@ -52,8 +30,11 @@ extern void *l1sram_alloc_max(void*);
static inline void free_l1stack(void)
{
nr_l1stack_tasks--;
- if (nr_l1stack_tasks == 0)
+ if (nr_l1stack_tasks == 0) {
l1sram_free(l1_stack_base);
+ l1_stack_base = NULL;
+ l1_stack_len = 0;
+ }
}
static inline unsigned long
@@ -89,8 +70,8 @@ activate_l1stack(struct mm_struct *mm, unsigned long sp_base)
#define activate_mm(prev, next) switch_mm(prev, next, NULL)
-static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
- struct task_struct *tsk)
+static inline void __switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
+ struct task_struct *tsk)
{
#ifdef CONFIG_MPU
unsigned int cpu = smp_processor_id();
@@ -118,26 +99,50 @@ static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_m
#endif
}
+#ifdef CONFIG_IPIPE
+#define lock_mm_switch(flags) flags = hard_local_irq_save_cond()
+#define unlock_mm_switch(flags) hard_local_irq_restore_cond(flags)
+#else
+#define lock_mm_switch(flags) do { (void)(flags); } while (0)
+#define unlock_mm_switch(flags) do { (void)(flags); } while (0)
+#endif /* CONFIG_IPIPE */
+
#ifdef CONFIG_MPU
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ unsigned long flags;
+ lock_mm_switch(flags);
+ __switch_mm(prev, next, tsk);
+ unlock_mm_switch(flags);
+}
+
static inline void protect_page(struct mm_struct *mm, unsigned long addr,
unsigned long flags)
{
unsigned long *mask = mm->context.page_rwx_mask;
- unsigned long page = addr >> 12;
- unsigned long idx = page >> 5;
- unsigned long bit = 1 << (page & 31);
+ unsigned long page;
+ unsigned long idx;
+ unsigned long bit;
+
+ if (unlikely(addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
+ page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> 12;
+ else
+ page = addr >> 12;
+ idx = page >> 5;
+ bit = 1 << (page & 31);
- if (flags & VM_MAYREAD)
+ if (flags & VM_READ)
mask[idx] |= bit;
else
mask[idx] &= ~bit;
mask += page_mask_nelts;
- if (flags & VM_MAYWRITE)
+ if (flags & VM_WRITE)
mask[idx] |= bit;
else
mask[idx] &= ~bit;
mask += page_mask_nelts;
- if (flags & VM_MAYEXEC)
+ if (flags & VM_EXEC)
mask[idx] |= bit;
else
mask[idx] &= ~bit;
@@ -151,6 +156,12 @@ static inline void update_protections(struct mm_struct *mm)
set_mask_dcplbs(mm->context.page_rwx_mask, cpu);
}
}
+#else /* !CONFIG_MPU */
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ __switch_mm(prev, next, tsk);
+}
#endif
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
@@ -196,4 +207,10 @@ static inline void destroy_context(struct mm_struct *mm)
#endif
}
+#define ipipe_mm_switch_protect(flags) \
+ flags = hard_local_irq_save_cond()
+
+#define ipipe_mm_switch_unprotect(flags) \
+ hard_local_irq_restore_cond(flags)
+
#endif