Changeset 457d18a in mainline for arch/ia64/src/mm/page.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.