ChCore-exercise/lab5/kernel/mm/page_table.h
2021-05-23 22:24:02 +08:00

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;