129 lines
4.9 KiB
C
129 lines
4.9 KiB
C
/*
|
|
* Copyright (c) 2020 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
|
|
* OS-Lab-2020 (i.e., ChCore) is licensed under the Mulan PSL v1.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v1.
|
|
* You may obtain a copy of Mulan PSL v1 at:
|
|
* http://license.coscl.org.cn/MulanPSL
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
|
|
* PURPOSE.
|
|
* See the Mulan PSL v1 for more details.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <common/types.h>
|
|
|
|
#define INNER_SHAREABLE (0x3)
|
|
/* Please search mair_el1 for these memory types. */
|
|
#define NORMAL_MEMORY (0x4)
|
|
#define DEVICE_MEMORY (0x0)
|
|
|
|
/* Description bits in page table entries. */
|
|
|
|
/* Read-write permission. */
|
|
#define AARCH64_PTE_AP_HIGH_RW_EL0_RW (1)
|
|
#define AARCH64_PTE_AP_HIGH_RO_EL0_RO (3)
|
|
|
|
/* X: execution permission. U: unprivileged. P: privileged. */
|
|
#define AARCH64_PTE_UX (0)
|
|
#define AARCH64_PTE_UXN (1)
|
|
#define AARCH64_PTE_PXN (1)
|
|
|
|
/* Access flag bit. */
|
|
#define AARCH64_PTE_AF_ACCESSED (1)
|
|
|
|
/* Present (valid) bit. */
|
|
#define AARCH64_PTE_INVALID_MASK (1 << 0)
|
|
/* Table bit: whether the next level is aonther pte or physical memory page. */
|
|
#define AARCH64_PTE_TABLE_MASK (1 << 1)
|
|
#define IS_PTE_INVALID(pte) (!((pte) & AARCH64_PTE_INVALID_MASK))
|
|
#define IS_PTE_TABLE(pte) (!!((pte) & AARCH64_PTE_TABLE_MASK))
|
|
|
|
/* PAGE_SIZE (4k) == (1 << (PAGE_SHIFT)) */
|
|
#define PAGE_SHIFT (12)
|
|
#define PAGE_MASK (PAGE_SIZE - 1)
|
|
#define PAGE_ORDER (9)
|
|
|
|
#define PTP_INDEX_MASK ((1 << (PAGE_ORDER)) - 1)
|
|
#define L0_INDEX_SHIFT ((3 * PAGE_ORDER) + PAGE_SHIFT)
|
|
#define L1_INDEX_SHIFT ((2 * PAGE_ORDER) + PAGE_SHIFT)
|
|
#define L2_INDEX_SHIFT ((1 * PAGE_ORDER) + PAGE_SHIFT)
|
|
#define L3_INDEX_SHIFT ((0 * PAGE_ORDER) + PAGE_SHIFT)
|
|
|
|
#define GET_L0_INDEX(addr) ((addr >> L0_INDEX_SHIFT) & PTP_INDEX_MASK)
|
|
#define GET_L1_INDEX(addr) ((addr >> L1_INDEX_SHIFT) & PTP_INDEX_MASK)
|
|
#define GET_L2_INDEX(addr) ((addr >> L2_INDEX_SHIFT) & PTP_INDEX_MASK)
|
|
#define GET_L3_INDEX(addr) ((addr >> L3_INDEX_SHIFT) & PTP_INDEX_MASK)
|
|
|
|
#define PTP_ENTRIES (1UL << PAGE_ORDER)
|
|
/* Number of 4KB-pages that an Lx-block describes */
|
|
#define L0_PER_ENTRY_PAGES ((PTP_ENTRIES) * (L1_PER_ENTRY_PAGES))
|
|
#define L1_PER_ENTRY_PAGES ((PTP_ENTRIES) * (L2_PER_ENTRY_PAGES))
|
|
#define L2_PER_ENTRY_PAGES ((PTP_ENTRIES) * (L3_PER_ENTRY_PAGES))
|
|
#define L3_PER_ENTRY_PAGES (1)
|
|
|
|
/* Bitmask used by GET_VA_OFFSET_Lx */
|
|
#define L1_BLOCK_MASK ((L1_PER_ENTRY_PAGES << PAGE_SHIFT) - 1)
|
|
#define L2_BLOCK_MASK ((L2_PER_ENTRY_PAGES << PAGE_SHIFT) - 1)
|
|
#define L3_PAGE_MASK ((L3_PER_ENTRY_PAGES << PAGE_SHIFT) - 1)
|
|
|
|
#define GET_VA_OFFSET_L1(va) (va & L1_BLOCK_MASK)
|
|
#define GET_VA_OFFSET_L2(va) (va & L2_BLOCK_MASK)
|
|
#define GET_VA_OFFSET_L3(va) (va & L3_PAGE_MASK)
|
|
|
|
/* table format */
|
|
typedef union {
|
|
struct {
|
|
u64 is_valid:1, is_table:1, ignored1:10, next_table_addr:36, reserved:4, ignored2:7, PXNTable:1, // Privileged Execute-never for next level
|
|
XNTable:1, // Execute-never for next level
|
|
APTable:2, // Access permissions for next level
|
|
NSTable:1;
|
|
} table;
|
|
struct {
|
|
u64 is_valid:1, is_table:1, attr_index:3, // Memory attributes index
|
|
NS:1, // Non-secure
|
|
AP:2, // Data access permissions
|
|
SH:2, // Shareability
|
|
AF:1, // Accesss flag
|
|
nG:1, // Not global bit
|
|
reserved1:4, nT:1, reserved2:13, pfn:18, reserved3:2, GP:1, reserved4:1, DBM:1, // Dirty bit modifier
|
|
Contiguous:1, PXN:1, // Privileged execute-never
|
|
UXN:1, // Execute never
|
|
soft_reserved:4, PBHA:4; // Page based hardware attributes
|
|
} l1_block;
|
|
struct {
|
|
u64 is_valid:1, is_table:1, attr_index:3, // Memory attributes index
|
|
NS:1, // Non-secure
|
|
AP:2, // Data access permissions
|
|
SH:2, // Shareability
|
|
AF:1, // Accesss flag
|
|
nG:1, // Not global bit
|
|
reserved1:4, nT:1, reserved2:4, pfn:27, reserved3:2, GP:1, reserved4:1, DBM:1, // Dirty bit modifier
|
|
Contiguous:1, PXN:1, // Privileged execute-never
|
|
UXN:1, // Execute never
|
|
soft_reserved:4, PBHA:4; // Page based hardware attributes
|
|
} l2_block;
|
|
struct {
|
|
u64 is_valid:1, is_page:1, attr_index:3, // Memory attributes index
|
|
NS:1, // Non-secure
|
|
AP:2, // Data access permissions
|
|
SH:2, // Shareability
|
|
AF:1, // Accesss flag
|
|
nG:1, // Not global bit
|
|
pfn:36, reserved:3, DBM:1, // Dirty bit modifier
|
|
Contiguous:1, PXN:1, // Privileged execute-never
|
|
UXN:1, // Execute never
|
|
soft_reserved:4, PBHA:4, // Page based hardware attributes
|
|
ignored:1;
|
|
} l3_page;
|
|
u64 pte;
|
|
} pte_t;
|
|
|
|
#define PTE_DESCRIPTOR_INVALID (0)
|
|
|
|
/* page_table_page type */
|
|
typedef struct {
|
|
pte_t ent[PTP_ENTRIES];
|
|
} ptp_t;
|