HelenOS sources

root/kernel/arch/ia64/include/arch/mm/page.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. thash
  2. ttag
  3. rr_read
  4. rr_write
  5. pta_read
  6. pta_write

/*
 * Copyright (c) 2005 - 2006 Jakub Jermar
 * Copyright (c) 2006 Jakub Vana
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** @addtogroup kernel_ia64_mm
 * @{
 */
/** @file
 */

#ifndef KERN_ia64_PAGE_H_
#define KERN_ia64_PAGE_H_

#include <arch/mm/frame.h>
#include <arch/register.h>

#ifndef __ASSEMBLER__
#include <assert.h>
#endif

#define PAGE_SIZE   FRAME_SIZE
#define PAGE_WIDTH  FRAME_WIDTH

/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH       28      /* 256M */

#define PPN_SHIFT  12

#define VRN_SHIFT   61
#define VRN_MASK    (7ULL << VRN_SHIFT)
#define VA2VRN(va)  ((va) >> VRN_SHIFT)

#ifdef __ASSEMBLER__
#define VRN_KERNEL  7
#else
#define VRN_KERNEL  7ULL
#endif

#define REGION_REGISTERS  8

#define KA2PA(x)  (((uintptr_t) (x)) - (VRN_KERNEL << VRN_SHIFT))
#define PA2KA(x)  (((uintptr_t) (x)) + (VRN_KERNEL << VRN_SHIFT))

#define VHPT_WIDTH  20  /* 1M */
#define VHPT_SIZE   (1 << VHPT_WIDTH)

#define PTA_BASE_SHIFT  15

/** Memory Attributes. */
#define MA_WRITEBACK    0x00
#define MA_UNCACHEABLE  0x04

/** Privilege Levels. Only the most and the least privileged ones are ever used. */
#define PL_KERNEL  PSR_CPL_KERNEL
#define PL_USER    PSR_CPL_USER

/* Access Rigths. Only certain combinations are used by the kernel. */
#define AR_READ     0x00
#define AR_EXECUTE  0x01
#define AR_WRITE    0x02

#ifndef __ASSEMBLER__

#include <arch/mm/as.h>
#include <arch/mm/frame.h>
#include <arch/interrupt.h>
#include <barrier.h>
#include <arch/mm/asid.h>
#include <typedefs.h>
#include <debug.h>

struct vhpt_tag_info {
        unsigned long long tag : 63;
        unsigned int ti : 1;
} __attribute__((packed));

union vhpt_tag {
        struct vhpt_tag_info tag_info;
        unsigned tag_word;
};

struct vhpt_entry_present {
        /* Word 0 */
        unsigned int p : 1;
        unsigned int : 1;
        unsigned int ma : 3;
        unsigned int a : 1;
        unsigned int d : 1;
        unsigned int pl : 2;
        unsigned int ar : 3;
        unsigned long long ppn : 38;
        unsigned int : 2;
        unsigned int ed : 1;
        unsigned int ig1 : 11;

        /* Word 1 */
        unsigned int : 2;
        unsigned int ps : 6;
        unsigned int key : 24;
        unsigned int : 32;

        /* Word 2 */
        union vhpt_tag tag;

        /* Word 3 */
        uint64_t ig3 : 64;
} __attribute__((packed));

struct vhpt_entry_not_present {
        /* Word 0 */
        unsigned int p : 1;
        unsigned long long ig0 : 52;
        unsigned int ig1 : 11;

        /* Word 1 */
        unsigned int : 2;
        unsigned int ps : 6;
        unsigned long long ig2 : 56;

        /* Word 2 */
        union vhpt_tag tag;

        /* Word 3 */
        uint64_t ig3 : 64;
} __attribute__((packed));

typedef union {
        struct vhpt_entry_present present;
        struct vhpt_entry_not_present not_present;
        uint64_t word[4];
} vhpt_entry_t;

struct region_register_map {
        unsigned int ve : 1;
        unsigned int : 1;
        unsigned int ps : 6;
        unsigned int rid : 24;
        unsigned int : 32;
} __attribute__((packed));

typedef union {
        struct region_register_map map;
        unsigned long long word;
} region_register_t;

struct pta_register_map {
        unsigned int ve : 1;
        unsigned int : 1;
        unsigned int size : 6;
        unsigned int vf : 1;
        unsigned int : 6;
        unsigned long long base : 49;
} __attribute__((packed));

typedef union pta_register {
        struct pta_register_map map;
        uint64_t word;
} pta_register_t;

/** Return Translation Hashed Entry Address.
 *
 * VRN bits are used to read RID (ASID) from one
 * of the eight region registers registers.
 *
 * @param va Virtual address including VRN bits.
 *
 * @return Address of the head of VHPT collision chain.
 */
_NO_TRACE static inline uint64_t thash(uint64_t va)
{
        uint64_t ret;

        asm volatile (
            "thash %[ret] = %[va]\n"
            : [ret] "=r" (ret)
            : [va] "r" (va)
        );

        return ret;
}

/** Return Translation Hashed Entry Tag.
 *
 * VRN bits are used to read RID (ASID) from one
 * of the eight region registers.
 *
 * @param va Virtual address including VRN bits.
 *
 * @return The unique tag for VPN and RID in the collision chain returned by thash().
 */
_NO_TRACE static inline uint64_t ttag(uint64_t va)
{
        uint64_t ret;

        asm volatile (
            "ttag %[ret] = %[va]\n"
            : [ret] "=r" (ret)
            : [va] "r" (va)
        );

        return ret;
}

/** Read Region Register.
 *
 * @param i Region register index.
 *
 * @return Current contents of rr[i].
 */
_NO_TRACE static inline uint64_t rr_read(size_t i)
{
        uint64_t ret;

        assert(i < REGION_REGISTERS);

        asm volatile (
            "mov %[ret] = rr[%[index]]\n"
            : [ret] "=r" (ret)
            : [index] "r" (i << VRN_SHIFT)
        );

        return ret;
}

/** Write Region Register.
 *
 * @param i Region register index.
 * @param v Value to be written to rr[i].
 */
_NO_TRACE static inline void rr_write(size_t i, uint64_t v)
{
        assert(i < REGION_REGISTERS);

        asm volatile (
            "mov rr[%[index]] = %[value]\n"
            :: [index] "r" (i << VRN_SHIFT),
              [value] "r" (v)
        );
}

/** Read Page Table Register.
 *
 * @return Current value stored in PTA.
 */
_NO_TRACE static inline uint64_t pta_read(void)
{
        uint64_t ret;

        asm volatile (
            "mov %[ret] = cr.pta\n"
            : [ret] "=r" (ret)
        );

        return ret;
}

/** Write Page Table Register.
 *
 * @param v New value to be stored in PTA.
 */
_NO_TRACE static inline void pta_write(uint64_t v)
{
        asm volatile (
            "mov cr.pta = %[value]\n"
            :: [value] "r" (v)
        );
}

extern void page_arch_init(void);

extern vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid);
extern bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v);
extern void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags);

#endif /* __ASSEMBLER__ */

#endif

/** @}
 */

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub