arch/m68k/include/asm/mmu_context.h

Source file repositories/reference/linux-study-clean/arch/m68k/include/asm/mmu_context.h

File Facts

System
Linux kernel
Corpus path
arch/m68k/include/asm/mmu_context.h
Extension
.h
Size
7273 bytes
Lines
323
Domain
Architecture Layer
Bucket
arch/m68k
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef __M68K_MMU_CONTEXT_H
#define __M68K_MMU_CONTEXT_H

#include <asm-generic/mm_hooks.h>
#include <linux/mm_types.h>

#ifdef CONFIG_MMU

#if defined(CONFIG_COLDFIRE)

#include <asm/atomic.h>
#include <asm/bitops.h>
#include <asm/mcfmmu.h>
#include <asm/mmu.h>

#define NO_CONTEXT		256
#define LAST_CONTEXT		255
#define FIRST_CONTEXT		1

extern unsigned long context_map[];
extern mm_context_t next_mmu_context;

extern atomic_t nr_free_contexts;
extern struct mm_struct *context_mm[LAST_CONTEXT+1];
extern void steal_context(void);

static inline void get_mmu_context(struct mm_struct *mm)
{
	mm_context_t ctx;

	if (mm->context != NO_CONTEXT)
		return;
	while (arch_atomic_dec_and_test_lt(&nr_free_contexts)) {
		atomic_inc(&nr_free_contexts);
		steal_context();
	}
	ctx = next_mmu_context;
	while (test_and_set_bit(ctx, context_map)) {
		ctx = find_next_zero_bit(context_map, LAST_CONTEXT+1, ctx);
		if (ctx > LAST_CONTEXT)
			ctx = 0;
	}
	next_mmu_context = (ctx + 1) & LAST_CONTEXT;
	mm->context = ctx;
	context_mm[ctx] = mm;
}

/*
 * Set up the context for a new address space.
 */
#define init_new_context(tsk, mm)	(((mm)->context = NO_CONTEXT), 0)

/*
 * We're finished using the context for an address space.
 */
#define destroy_context destroy_context
static inline void destroy_context(struct mm_struct *mm)
{
	if (mm->context != NO_CONTEXT) {
		clear_bit(mm->context, context_map);
		mm->context = NO_CONTEXT;
		atomic_inc(&nr_free_contexts);
	}
}

static inline void set_context(mm_context_t context, pgd_t *pgd)
{
	__asm__ __volatile__ ("movec %0,%%asid" : : "d" (context));
}

static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
	struct task_struct *tsk)
{
	get_mmu_context(tsk->mm);
	set_context(tsk->mm->context, next->pgd);
}

/*
 * After we have set current->mm to a new value, this activates
 * the context for the new mm so we see the new mappings.
 */
#define activate_mm activate_mm
static inline void activate_mm(struct mm_struct *active_mm,
	struct mm_struct *mm)
{
	get_mmu_context(mm);
	set_context(mm->context, mm->pgd);
}

#define prepare_arch_switch(next) load_ksp_mmu(next)

Annotation

Implementation Notes