Changeset 457d18a in mainline


Ignore:
Timestamp:
2006-01-28T16:47:39Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d0780b4c
Parents:
849386a
Message:

ia64 virtual address translation subsystem update.

Location:
arch/ia64
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • arch/ia64/include/mm/asid.h

    r849386a r457d18a  
    4343#define RID_OVERFLOW            16777216        /* 2^24 */
    4444
     45#define ASID2RID(asid, vrn)     (((asid)*RIDS_PER_ASID)+(vrn))
     46#define RID2ASID(rid)           ((rid)/RIDS_PER_ASID)
     47
     48typedef __u32 rid_t;
     49
    4550/**
    4651 * This macro is needed only to compile the kernel.
  • arch/ia64/include/mm/page.h

    r849386a r457d18a  
    3333#include <arch/mm/frame.h>
    3434#include <genarch/mm/page_ht.h>
     35#include <arch/mm/asid.h>
    3536#include <arch/types.h>
    3637#include <typedefs.h>
     
    4748
    4849/** Implementation of page hash table interface. */
    49 #define HT_ENTRIES_ARCH                 (VHPT_SIZE/sizeof(pte_t))
    50 #define HT_HASH_ARCH(page, asid)        vhpt_hash((page), (asid))
    51 #define HT_COMPARE_ARCH(page, asid, t)  0
    52 #define HT_SLOT_EMPTY_ARCH(t)           1
    53 #define HT_INVALIDATE_SLOT_ARCH(t)
    54 #define HT_GET_NEXT_ARCH(t)             0
    55 #define HT_SET_NEXT_ARCH(t, s)
    56 #define HT_SET_RECORD_ARCH(t, page, asid, frame, flags)
     50#define HT_ENTRIES_ARCH                                 (VHPT_SIZE/sizeof(pte_t))
     51#define HT_HASH_ARCH(page, asid)                        vhpt_hash((page), (asid))
     52#define HT_COMPARE_ARCH(page, asid, t)                  vhpt_compare((page), (asid), (t))
     53#define HT_SLOT_EMPTY_ARCH(t)                           ((t)->present.tag.tag_info.ti)
     54#define HT_INVALIDATE_SLOT_ARCH(t)                      (t)->present.tag.tag_info.ti = true
     55#define HT_GET_NEXT_ARCH(t)                             (t)->present.next
     56#define HT_SET_NEXT_ARCH(t, s)                          (t)->present.next = (s)
     57#define HT_SET_RECORD_ARCH(t, page, asid, frame, flags) vhpt_set_record(t, page, asid, frame, flags)
     58
     59#define PPN_SHIFT                       12
    5760
    5861#define VRN_SHIFT                       61
     
    6063
    6164#define VRN_KERNEL                      0
    62 #define VRN_WORK                        1LL
    6365#define REGION_REGISTERS                8
    6466
     
    6769
    6870#define VHPT_BASE                       page_ht         /* Must be aligned to VHPT_SIZE */
     71
     72/** Memory Attributes. */
     73#define MA_WRITEBACK    0x0
     74#define MA_UNCACHEABLE  0x4
     75
     76/** Privilege Levels. Only the most and the least privileged ones are ever used. */
     77#define PL_KERNEL       0x0
     78#define PL_USER         0x3
     79
     80/* Access Rigths. Only certain combinations are used by the kernel. */
     81#define AR_READ         0x0
     82#define AR_EXECUTE      0x1
     83#define AR_WRITE        0x2
    6984
    7085struct vhpt_tag_info {
     
    102117       
    103118        /* Word 3 */                                                                                                   
    104         unsigned long long next : 64;   /**< Collision chain next pointer. */
     119        pte_t *next;                    /**< Collision chain next pointer. */
    105120} __attribute__ ((packed));
    106121
     
    120135       
    121136        /* Word 3 */                                                                                                   
    122         unsigned long long next : 64;   /**< Collision chain next pointer. */
     137        pte_t *next;                    /**< Collision chain next pointer. */
    123138       
    124139} __attribute__ ((packed));
     
    127142        struct vhpt_entry_present present;
    128143        struct vhpt_entry_not_present not_present;
     144        __u64 word[4];
    129145} vhpt_entry;
    130146
     
    244260extern void page_arch_init(void);
    245261extern pte_t *vhpt_hash(__address page, asid_t asid);
     262extern bool vhpt_compare(__address page, asid_t asid, pte_t *t);
     263extern void vhpt_set_record(pte_t *t, __address page, asid_t asid, __address frame, int flags);
    246264
    247265#endif
  • arch/ia64/src/mm/asid.c

    r849386a r457d18a  
    5050#include <mm/asid.h>
    5151#include <mm/as.h>
     52#include <genarch/mm/page_ht.h>
    5253#include <mm/tlb.h>
    5354#include <list.h>
     
    105106                        spinlock_unlock(&as->lock);
    106107                }
     108               
     109                /*
     110                 * The page hash table uses VHPT long format PTE's.
     111                 * Unfortunatelly, this format has no space to
     112                 * store as_t pointer, so it is necessary to
     113                 * invalidate the whole structure after all ASIDs
     114                 * have been reassigned. The information swept out
     115                 * from the page hash table can be later reconstructed
     116                 * from as_t structures on demand.
     117                 */
     118                ht_invalidate_all();
    107119
    108120                /*
  • arch/ia64/src/mm/page.c

    r849386a r457d18a  
    3131#include <genarch/mm/page_ht.h>
    3232#include <mm/asid.h>
     33#include <arch/mm/asid.h>
    3334#include <arch/types.h>
     35#include <typedefs.h>
    3436#include <print.h>
    3537#include <mm/page.h>
     
    4143#include <memstr.h>
    4244
     45static void set_vhpt_environment(void);
     46
     47/** Initialize ia64 virtual address translation subsystem. */
     48void page_arch_init(void)
     49{
     50        page_operations = &page_ht_operations;
     51        pk_disable();
     52        set_vhpt_environment();
     53}
     54
    4355/** Initialize VHPT and region registers. */
    44 static void set_vhpt_environment(void)
     56void set_vhpt_environment(void)
    4557{
    4658        region_register rr;
     
    95107}
    96108
    97 /** Initialize ia64 virtual address translation subsystem. */
    98 void page_arch_init(void)
    99 {
    100         page_operations = &page_ht_operations;
    101         pk_disable();
    102         set_vhpt_environment();
    103 }
    104 
    105109/** Calculate address of collision chain from VPN and ASID.
    106110 *
    107  * This is rather non-trivial function.
    108  * First, it has to translate ASID to RID.
    109  * This is achieved by taking VRN bits of
    110  * page into account.
    111  * Second, it must preserve the region register
    112  * it writes the RID to.
     111 * Interrupts must be disabled.
    113112 *
    114113 * @param page Address of virtual page including VRN bits.
     
    120119{
    121120        region_register rr_save, rr;
     121        index_t vrn;
     122        rid_t rid;
    122123        pte_t *t;
    123124
    124         rr_save.word = rr_read(VRN_WORK);
     125        vrn = page >> VRN_SHIFT;
     126        rid = ASID2RID(asid, vrn);
     127       
     128        rr_save.word = rr_read(vrn);
     129        if (rr_save.map.rid == rid) {
     130                /*
     131                 * The RID is already in place, compute thash and return.
     132                 */
     133                t = (pte_t *) thash(page);
     134                return t;
     135        }
     136       
     137        /*
     138         * The RID must be written to some region register.
     139         * To speed things up, register indexed by vrn is used.
     140         */
    125141        rr.word = rr_save.word;
    126         if ((page >> VRN_SHIFT) != VRN_KERNEL)
    127                 rr.map.rid = (asid * RIDS_PER_ASID) + (page >> VRN_SHIFT);
    128         else
    129                 rr.map.rid = ASID_KERNEL;
    130         rr_write(VRN_WORK, rr.word);
    131         srlz_i();
    132         t = (pte_t *) thash((VRN_WORK << VRN_SHIFT) | (~(VRN_MASK) & page));
    133         rr_write(VRN_WORK, rr_save.word);
     142        rr.map.rid = rid;
     143        rr_write(vrn, rr.word);
     144        srlz_i();
     145        t = (pte_t *) thash(page);
     146        rr_write(vrn, rr_save.word);
    134147        srlz_i();
    135148        srlz_d();
     
    137150        return t;
    138151}
     152
     153/** Compare ASID and VPN against PTE.
     154 *
     155 * Interrupts must be disabled.
     156 *
     157 * @param page Address of virtual page including VRN bits.
     158 * @param asid Address space identifier.
     159 *
     160 * @return True if page and asid match the page and asid of t, false otherwise.
     161 */
     162bool vhpt_compare(__address page, asid_t asid, pte_t *t)
     163{
     164        region_register rr_save, rr;   
     165        index_t vrn;
     166        rid_t rid;
     167        bool match;
     168
     169        ASSERT(t);
     170
     171        vrn = page >> VRN_SHIFT;
     172        rid = ASID2RID(asid, vrn);
     173       
     174        rr_save.word = rr_read(vrn);
     175        if (rr_save.map.rid == rid) {
     176                /*
     177                 * The RID is already in place, compare ttag with t and return.
     178                 */
     179                return ttag(page) == t->present.tag.tag_word;
     180        }
     181       
     182        /*
     183         * The RID must be written to some region register.
     184         * To speed things up, register indexed by vrn is used.
     185         */
     186        rr.word = rr_save.word;
     187        rr.map.rid = rid;
     188        rr_write(vrn, rr.word);
     189        srlz_i();
     190        match = (ttag(page) == t->present.tag.tag_word);
     191        rr_write(vrn, rr_save.word);
     192        srlz_i();
     193        srlz_d();
     194
     195        return match;           
     196}
     197
     198/** Set up one VHPT entry.
     199 *
     200 * @param t VHPT entry to be set up.
     201 * @param page Virtual address of the page mapped by the entry.
     202 * @param asid Address space identifier of the address space to which page belongs.
     203 * @param frame Physical address of the frame to wich page is mapped.
     204 * @param flags Different flags for the mapping.
     205 */
     206void vhpt_set_record(pte_t *t, __address page, asid_t asid, __address frame, int flags)
     207{
     208        region_register rr_save, rr;   
     209        index_t vrn;
     210        rid_t rid;
     211        __u64 tag;
     212
     213        ASSERT(t);
     214
     215        vrn = page >> VRN_SHIFT;
     216        rid = ASID2RID(asid, vrn);
     217       
     218        /*
     219         * Compute ttag.
     220         */
     221        rr_save.word = rr_read(vrn);
     222        rr.word = rr_save.word;
     223        rr.map.rid = rid;
     224        rr_write(vrn, rr.word);
     225        srlz_i();
     226        tag = ttag(page);
     227        rr_write(vrn, rr_save.word);
     228        srlz_i();
     229        srlz_d();
     230       
     231        /*
     232         * Clear the entry.
     233         */
     234        t->word[0] = 0;
     235        t->word[1] = 0;
     236        t->word[2] = 0;
     237        t->word[3] = 0;
     238       
     239        t->present.p = true;
     240        t->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
     241        t->present.a = false;   /* not accessed */
     242        t->present.d = false;   /* not dirty */
     243        t->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
     244        t->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ;
     245        t->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0;
     246        t->present.ppn = frame >> PPN_SHIFT;
     247        t->present.ed = false;  /* exception not deffered */
     248        t->present.ps = PAGE_WIDTH;
     249        t->present.key = 0;
     250        t->present.tag.tag_word = tag;
     251        t->present.next = NULL;
     252}
Note: See TracChangeset for help on using the changeset viewer.