Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
d84b4711 | 2 | * linux/arch/arm/mm/context.c |
1da177e4 LT |
3 | * |
4 | * Copyright (C) 2002-2003 Deep Blue Solutions Ltd, all rights reserved. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 as | |
8 | * published by the Free Software Foundation. | |
9 | */ | |
10 | #include <linux/init.h> | |
11 | #include <linux/sched.h> | |
12 | #include <linux/mm.h> | |
13 | ||
14 | #include <asm/mmu_context.h> | |
15 | #include <asm/tlbflush.h> | |
16 | ||
17 | unsigned int cpu_last_asid = { 1 << ASID_BITS }; | |
18 | ||
19 | /* | |
20 | * We fork()ed a process, and we need a new context for the child | |
21 | * to run in. We reserve version 0 for initial tasks so we will | |
9d99df4b CM |
22 | * always allocate an ASID. The ASID 0 is reserved for the TTBR |
23 | * register changing sequence. | |
1da177e4 LT |
24 | */ |
25 | void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) | |
26 | { | |
27 | mm->context.id = 0; | |
28 | } | |
29 | ||
30 | void __new_context(struct mm_struct *mm) | |
31 | { | |
32 | unsigned int asid; | |
33 | ||
34 | asid = ++cpu_last_asid; | |
35 | if (asid == 0) | |
36 | asid = cpu_last_asid = 1 << ASID_BITS; | |
37 | ||
38 | /* | |
39 | * If we've used up all our ASIDs, we need | |
40 | * to start a new version and flush the TLB. | |
41 | */ | |
9d99df4b CM |
42 | if ((asid & ~ASID_MASK) == 0) { |
43 | asid = ++cpu_last_asid; | |
44 | /* set the reserved ASID before flushing the TLB */ | |
45 | asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n" | |
46 | : | |
47 | : "r" (0)); | |
48 | isb(); | |
1da177e4 | 49 | flush_tlb_all(); |
9d99df4b | 50 | } |
1da177e4 LT |
51 | |
52 | mm->context.id = asid; | |
53 | } |