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_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 #endif
  40 
  41 #define ASN_VERSION_SHIFT 16
  42 #define ASN_VERSION_MASK ((~0UL) << ASN_VERSION_SHIFT)
  43 #define ASN_FIRST_VERSION (1UL << ASN_VERSION_SHIFT)
  44 
  45 /*
  46  * NOTE! The way this is set up, the high bits of the "asn_cache" (and
  47  * the "mm->context") are the ASN _version_ code. A version of 0 is
  48  * always considered invalid, so to invalidate another process you only
  49  * need to do "p->mm->context = 0".
  50  *
  51  * If we need more ASN's than the processor has, we invalidate the old
  52  * user TLB's (tbiap()) and start a new ASN version. That will automatically
  53  * force a new asn for any other processes the next time they want to
  54  * run.
  55  */
  56 extern inline void get_mmu_context(struct task_struct *p)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58 #ifdef CONFIG_ALPHA_EV5
  59         static unsigned long asn_cache = ASN_FIRST_VERSION;
  60         struct mm_struct * mm = p->mm;
  61 
  62         if (mm) {
  63                 unsigned long asn = mm->context;
  64                 /* Check if our ASN is of an older version and thus invalid */
  65                 if ((asn_cache ^ asn) & ASN_VERSION_MASK) {
  66                         /* get a new asn of the current version */
  67                         asn = asn_cache++;
  68                         /* check if it's legal.. */
  69                         if ((asn & ~ASN_VERSION_MASK) > MAX_ASN) {
  70                                 /* start a new version, invalidate all old asn's */
  71                                 tbiap(); imb();
  72                                 asn_cache = (asn_cache & ASN_VERSION_MASK) + ASN_FIRST_VERSION;
  73                                 if (!asn_cache)
  74                                         asn_cache = ASN_FIRST_VERSION;
  75                                 asn = asn_cache++;
  76                         }
  77                         mm->context = asn;                      /* full version + asn */
  78                         p->tss.asn = asn & ~ASN_VERSION_MASK;   /* just asn */
  79                 }
  80         }
  81 #endif
  82 }
  83 
  84 #endif

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