133 lines
3.8 KiB
C
133 lines
3.8 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.
|
|
*/
|
|
|
|
#include <common/mm.h>
|
|
#include <common/kprint.h>
|
|
#include <common/macro.h>
|
|
|
|
#include "buddy.h"
|
|
#include "slab.h"
|
|
#include "page_table.h"
|
|
|
|
extern unsigned long *img_end;
|
|
|
|
#define PHYSICAL_MEM_START (24*1024*1024) //24M
|
|
|
|
#define START_VADDR phys_to_virt(PHYSICAL_MEM_START) //24M
|
|
#define NPAGES (128*1000)
|
|
|
|
#define PHYSICAL_MEM_END (PHYSICAL_MEM_START+NPAGES*BUDDY_PAGE_SIZE)
|
|
|
|
/*
|
|
* Layout:
|
|
*
|
|
* | metadata (npages * sizeof(struct page)) | start_vaddr ... (npages * PAGE_SIZE) |
|
|
*
|
|
*/
|
|
|
|
unsigned long get_ttbr1(void)
|
|
{
|
|
unsigned long pgd;
|
|
|
|
__asm__("mrs %0,ttbr1_el1":"=r"(pgd));
|
|
return pgd;
|
|
}
|
|
|
|
/*
|
|
* map_kernel_space: map the kernel virtual address
|
|
* [va:va+size] to physical addres [pa:pa+size].
|
|
* 1. get the kernel pgd address
|
|
* 2. fill the block entry with corresponding attribution bit
|
|
*
|
|
*/
|
|
void map_kernel_space(vaddr_t va, paddr_t pa, size_t len)
|
|
{
|
|
// <lab2>
|
|
#define IS_VALID (1UL << 0)
|
|
#define UXN (0x1UL << 54)
|
|
#define ACCESSED (0x1UL << 10)
|
|
#define INNER_SHARABLE (0x3UL << 8)
|
|
|
|
#define SIZE_2M (2UL*1024*1024)
|
|
#define PAGE_SHIFT (12)
|
|
#define GET_PADDR_IN_PTE(entry) \
|
|
(((u64)entry.table.next_table_addr) << PAGE_SHIFT)
|
|
|
|
paddr_t addr_l0, addr_l1, addr_l2;
|
|
pte_t pte_l0, pte_l1;
|
|
u64 *table_l2;
|
|
|
|
// 获得页表地址
|
|
// 不妨假设 len 小于 1G 且属于同一块
|
|
addr_l0 = get_ttbr1();
|
|
pte_l0.pte = *((u64 *) phys_to_virt(addr_l0) + GET_L0_INDEX(va));
|
|
addr_l1 = GET_PADDR_IN_PTE(pte_l0);
|
|
pte_l1.pte = *((u64 *) phys_to_virt(addr_l1) + GET_L1_INDEX(va));
|
|
addr_l2 = GET_PADDR_IN_PTE(pte_l1);
|
|
table_l2 = (u64 *) phys_to_virt(addr_l2);
|
|
|
|
// 设置页表
|
|
u32 start_entry_idx = GET_L2_INDEX(va);
|
|
u32 end_entry_idx = GET_L2_INDEX((va + len));
|
|
for (u32 idx = start_entry_idx, cnt = 0; idx < end_entry_idx; ++idx) {
|
|
table_l2[idx] = (pa + cnt++ * SIZE_2M) | UXN | ACCESSED | INNER_SHARABLE | NORMAL_MEMORY | IS_VALID;
|
|
}
|
|
|
|
// </lab2>
|
|
}
|
|
|
|
void kernel_space_check(void)
|
|
{
|
|
unsigned long kernel_val;
|
|
for (unsigned long i = 128; i < 256; i++) {
|
|
kernel_val = *(unsigned long *)(KBASE + (i << 21));
|
|
kinfo("kernel_val: %lx\n", kernel_val);
|
|
}
|
|
kinfo("kernel space check pass\n");
|
|
}
|
|
|
|
struct phys_mem_pool global_mem;
|
|
|
|
void mm_init(void)
|
|
{
|
|
vaddr_t free_mem_start = 0;
|
|
struct page *page_meta_start = NULL;
|
|
u64 npages = 0;
|
|
u64 start_vaddr = 0;
|
|
|
|
free_mem_start =
|
|
phys_to_virt(ROUND_UP((vaddr_t) (&img_end), PAGE_SIZE));
|
|
npages = NPAGES;
|
|
start_vaddr = START_VADDR;
|
|
kdebug("[CHCORE] mm: free_mem_start is 0x%lx, free_mem_end is 0x%lx\n",
|
|
free_mem_start, phys_to_virt(PHYSICAL_MEM_END));
|
|
|
|
if ((free_mem_start + npages * sizeof(struct page)) > start_vaddr) {
|
|
BUG("kernel panic: init_mm metadata is too large!\n");
|
|
}
|
|
|
|
page_meta_start = (struct page *)free_mem_start;
|
|
kdebug("page_meta_start: 0x%lx, real_start_vadd: 0x%lx,"
|
|
"npages: 0x%lx, meta_page_size: 0x%lx\n",
|
|
page_meta_start, start_vaddr, npages, sizeof(struct page));
|
|
|
|
/* buddy alloctor for managing physical memory */
|
|
init_buddy(&global_mem, page_meta_start, start_vaddr, npages);
|
|
|
|
/* slab alloctor for allocating small memory regions */
|
|
init_slab();
|
|
|
|
map_kernel_space(KBASE + (128UL << 21), 128UL << 21, 128UL << 21);
|
|
//check whether kernel space [KABSE + 256 : KBASE + 512] is mapped
|
|
// kernel_space_check();
|
|
}
|