diff options
| author | Russell King <rmk@flint.arm.linux.org.uk> | 2003-08-14 17:51:39 +0100 |
|---|---|---|
| committer | Russell King <rmk@flint.arm.linux.org.uk> | 2003-08-14 17:51:39 +0100 |
| commit | f1a3a362000963535d0be3d6fcac8f25c4569dcb (patch) | |
| tree | 2a3fc4ad028dd3732011a2e6de00fdd3d35ca02d /include/asm-arm | |
| parent | aa5f1ea77b7d635db0345ee068b68f595c265193 (diff) | |
[ARM] Add ARMv6 MMU context handling.
Add MMU context ID handling.
Diffstat (limited to 'include/asm-arm')
| -rw-r--r-- | include/asm-arm/mmu.h | 17 | ||||
| -rw-r--r-- | include/asm-arm/mmu_context.h | 40 |
2 files changed, 53 insertions, 4 deletions
diff --git a/include/asm-arm/mmu.h b/include/asm-arm/mmu.h index 9b8d3d781a1e..c33797d6cc7b 100644 --- a/include/asm-arm/mmu.h +++ b/include/asm-arm/mmu.h @@ -1,9 +1,18 @@ #ifndef __ARM_MMU_H #define __ARM_MMU_H -/* - * The ARM doesn't have a mmu context - */ -typedef struct { } mm_context_t; +#include <linux/config.h> + +typedef struct { +#if __LINUX_ARM_ARCH__ >= 6 + unsigned int id; +#endif +} mm_context_t; + +#if __LINUX_ARM_ARCH__ >= 6 +#define ASID(mm) ((mm)->context.id & 255) +#else +#define ASID(mm) (0) +#endif #endif diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h index e0340f5fbf32..a4cb79241a73 100644 --- a/include/asm-arm/mmu_context.h +++ b/include/asm-arm/mmu_context.h @@ -15,7 +15,45 @@ #include <asm/proc-fns.h> +#if __LINUX_ARM_ARCH__ >= 6 + +/* + * On ARMv6, we have the following structure in the Context ID: + * + * 31 7 0 + * +-------------------------+-----------+ + * | process ID | ASID | + * +-------------------------+-----------+ + * | context ID | + * +-------------------------------------+ + * + * The ASID is used to tag entries in the CPU caches and TLBs. + * The context ID is used by debuggers and trace logic, and + * should be unique within all running processes. + */ +#define ASID_BITS 8 +#define ASID_MASK ((~0) << ASID_BITS) + +extern unsigned int cpu_last_asid; + +void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); +void __new_context(struct mm_struct *mm); + +static inline void check_context(struct mm_struct *mm) +{ + if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) + __new_context(mm); +} + +#define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0) + +#else + +#define check_context(mm) do { } while (0) #define init_new_context(tsk,mm) 0 + +#endif + #define destroy_context(mm) do { } while(0) /* @@ -43,6 +81,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { if (prev != next) { + check_context(next); cpu_switch_mm(next->pgd, next); } } @@ -51,6 +90,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { + check_context(next); cpu_switch_mm(next->pgd, next); } |
