root/include/asm-alpha/mmu_context.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. get_new_mmu_context
  2. get_mmu_context

   1 #ifndef __ALPHA_MMU_CONTEXT_H
   2 #define __ALPHA_MMU_CONTEXT_H
   3 
   4 /*
   5  * get a new mmu context..
   6  *
   7  * Copyright (C) 1996, Linus Torvalds
   8  */
   9 
  10 #include <linux/config.h>
  11 #include <asm/system.h>
  12 
  13 /*
  14  * The maximum ASN's the processor supports.  On the EV4 this is 63
  15  * but the PAL-code doesn't actually use this information.  On the
  16  * EV5 this is 127.
  17  *
  18  * On the EV4, the ASNs are more-or-less useless anyway, as they are
  19  * only used as a icache tag, not for TB entries.  On the EV5 ASN's
  20  * also validate the TB entries, and thus make a lot more sense.
  21  *
  22  * The EV4 ASN's don't even match the architecture manual, ugh.  And
  23  * I quote: "If a processor implements address space numbers (ASNs),
  24  * and the old PTE has the Address Space Match (ASM) bit clear (ASNs
  25  * in use) and the Valid bit set, then entries can also effectively be
  26  * made coherent by assigning a new, unused ASN to the currently
  27  * running process and not reusing the previous ASN before calling the
  28  * appropriate PALcode routine to invalidate the translation buffer
  29  * (TB)". 
  30  *
  31  * In short, the EV4 has a "kind of" ASN capability, but it doesn't actually
  32  * work correctly and can thus not be used (explaining the lack of PAL-code
  33  * support).
  34  */
  35 #ifdef CONFIG_ALPHA_EV5
  36 #define MAX_ASN 127
  37 #else
  38 #define MAX_ASN 63
  39 #define BROKEN_ASN 1
  40 #endif
  41 
  42 extern unsigned long asn_cache;
  43 
  44 #define ASN_VERSION_SHIFT 16
  45 #define ASN_VERSION_MASK ((~0UL) << ASN_VERSION_SHIFT)
  46 #define ASN_FIRST_VERSION (1UL << ASN_VERSION_SHIFT)
  47 
  48 extern inline void get_new_mmu_context(struct task_struct *p,
     /* [previous][next][first][last][top][bottom][index][help] */
  49         struct mm_struct *mm,
  50         unsigned long asn)
  51 {
  52         /* check if it's legal.. */
  53         if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) {
  54                 /* start a new version, invalidate all old asn's */
  55                 tbiap(); imb();
  56                 asn = (asn & ASN_VERSION_MASK) + ASN_FIRST_VERSION;
  57                 if (!asn)
  58                         asn = ASN_FIRST_VERSION;
  59         }
  60         asn_cache = asn + 1;
  61         mm->context = asn;                      /* full version + asn */
  62         p->tss.asn = asn & ~ASN_VERSION_MASK;   /* just asn */
  63 }
  64 
  65 /*
  66  * NOTE! The way this is set up, the high bits of the "asn_cache" (and
  67  * the "mm->context") are the ASN _version_ code. A version of 0 is
  68  * always considered invalid, so to invalidate another process you only
  69  * need to do "p->mm->context = 0".
  70  *
  71  * If we need more ASN's than the processor has, we invalidate the old
  72  * user TLB's (tbiap()) and start a new ASN version. That will automatically
  73  * force a new asn for any other processes the next time they want to
  74  * run.
  75  */
  76 extern inline void get_mmu_context(struct task_struct *p)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78 #ifndef BROKEN_ASN
  79         struct mm_struct * mm = p->mm;
  80 
  81         if (mm) {
  82                 unsigned long asn = asn_cache;
  83                 /* Check if our ASN is of an older version and thus invalid */
  84                 if ((mm->context ^ asn) & ASN_VERSION_MASK)
  85                         get_new_mmu_context(p, mm, asn);
  86         }
  87 #endif
  88 }
  89 
  90 #endif

/* [previous][next][first][last][top][bottom][index][help] */