From ffd226230096f77e0ce13b5c0d3994abff2050d0 Mon Sep 17 00:00:00 2001 From: songyanguang <345810377@qq.com> Date: Thu, 19 Dec 2024 20:05:14 +0800 Subject: [PATCH] kernel runs in virtual memory --- .../rv64gc/preboot_for_jh7110/jh7110.lds | 13 +- .../mmu/riscv/rv64gc/jh7110/memlayout.h | 11 +- .../hardkernel/mmu/riscv/rv64gc/mmu_init.c | 151 ++++++------------ 3 files changed, 68 insertions(+), 107 deletions(-) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/jh7110.lds b/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/jh7110.lds index 2f3ee3073..f3630b83c 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/jh7110.lds +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/jh7110.lds @@ -42,17 +42,16 @@ OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") /* ENTRY(_start) */ ENTRY( _boot_start ) - MEMORY { + vir_ddr3 (rwx) : ORIGIN = (0 - 0x80000000), LENGTH = 1024M phy_ddr3 (rwx) : ORIGIN = 0x40200000, LENGTH = 1024M - vir_ddr3 (rwx) : ORIGIN = 0x0000000040800000, LENGTH = 1024M } BOOT_STACK_SIZE = 0x4000; SECTIONS { - . = ORIGIN(phy_ddr3); + . = ORIGIN(vir_ddr3); _start = .; _boot_start = .; @@ -60,22 +59,22 @@ SECTIONS _start_image_addr = .; boot.o(.text) - bootmmu.o(.text .text.*) ns16550.o(.text .text.*) + mmu_init.o(.text .text.*) boot.o(.rodata .rodata.*) - bootmmu.o(.rodata .rodata.*) ns16550.o(.rodata .rodata.*) + mmu_init.o(.rodata .rodata.*) boot.o(.data .data.*) - bootmmu.o(.data .data.*) ns16550.o(.data .data.*) + mmu_init.o(.data .data.*) PROVIDE(boot_start_addr = .); boot.o(.bss .bss.* COMMON) - bootmmu.o(.bss .bss.* COMMON) ns16550.o(.bss .bss.* COMMON) + mmu_init.o(.bss .bss.* COMMON) . = ALIGN(0x1000); PROVIDE(stacks_start = .); diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/jh7110/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/jh7110/memlayout.h index d66516710..ebc4832ac 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/jh7110/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/jh7110/memlayout.h @@ -35,7 +35,7 @@ Modification: /* physical memory layout */ #define PHY_MEM_BASE (0x0000000040200000ULL) -#define PHY_USER_FREEMEM_BASE (0x0000000100000000ULL) +#define PHY_USER_FREEMEM_BASE (0x0000000080000000ULL) #define PHY_USER_FREEMEM_TOP (0x0000000200000000ULL) #define PHY_MEM_STOP (0x0000000200000000ULL) @@ -78,9 +78,14 @@ Modification: #define KERN_MEM_BASE ((0 - 0x0000002000000000ULL) + PHY_MEM_BASE) // First kernel virtual address #define KERN_OFFSET (KERN_MEM_BASE - PHY_MEM_BASE) +/* Leave 2GB for kernel and BPF at the end of the address space */ +#define KERNEL_LINK_ADDR (0 - 0x80000000ULL) +#define KERNEL_LINK_OFFSET (KERNEL_LINK_ADDR - PHY_MEM_BASE) + /* PLIC (platform-level interrupt controller) memory layout */ #define PLIC_PHYMEM_BASE (0x0C000000ULL) #define PLIC_MEM_SIZE (0x00400000ULL) +#define PLIC_VIRTMEM_BASE ((0 - 0x0000003000000000ULL) + PLIC_PHYMEM_BASE) #define V2P(a) (((uint64_t)(a)) - KERN_OFFSET) @@ -88,4 +93,6 @@ Modification: #define V2P_WO(x) ((x) - KERN_OFFSET) // same as V2P, but without casts #define P2V_WO(x) ((x) + KERN_OFFSET) // same as P2V, but without casts -// clang-format on \ No newline at end of file + +#define V2P_LINK(a) (((uint64_t)(a)) - KERNEL_LINK_OFFSET) +#define P2V_LINK(a) ((a) + KERNEL_LINK_OFFSET) diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu_init.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu_init.c index 88f7f7800..1224eb13a 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu_init.c @@ -33,87 +33,81 @@ Modification: #include "pgtable.h" #include "memlayout.h" #include "ns16550.h" +#include "asm/pgtable-bits.h" +#define PFN_PD(x, prot) (((x) << _PAGE_PFN_SHIFT) | (prot)) +#define _PD_PFN(x) ((x) >> _PAGE_PFN_SHIFT) -#define __ro_after_init __attribute__((section(".data..ro_after_init"))) -#define __page_aligned_data __attribute__((section(".data..page_aligned"))) __attribute__((aligned(PAGE_SIZE))) -#define __page_aligned_bss __attribute__((section(".bss..page_aligned"))) __attribute__((aligned(PAGE_SIZE))) -#define __initdata __attribute__((section(".init.data"))) -#define __init __attribute__((section(".init.text"))) -#define __maybe_unused __attribute__((__unused__)) - - -struct kernel_mapping kernel_map __ro_after_init; extern char _start[]; -unsigned long riscv_pfn_base __ro_after_init; +struct kernel_mapping kernel_map; -pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss; -pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __attribute__((aligned(PAGE_SIZE))); +uintptr_t trampoline_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); +uintptr_t early_pg_dir[PTRS_PER_PGD] __attribute__((aligned(PAGE_SIZE))); -static pmd_t trampoline_pmd[PTRS_PER_PMD] __page_aligned_bss; -static pmd_t early_pmd[PTRS_PER_PMD] __initdata __attribute__((aligned(PAGE_SIZE))); -static pmd_t early_uart_pmd[PTRS_PER_PMD] __initdata __attribute__((aligned(PAGE_SIZE))); -static pmd_t early_pmd_free[((PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) >> PGDIR_SHIFT) + 1][PTRS_PER_PMD] __initdata __attribute__((aligned(PAGE_SIZE))); -static pmd_t early_pmd_inear_map[PTRS_PER_PMD] __initdata __attribute__((aligned(PAGE_SIZE))); -static pmd_t early_plic_pmd[PTRS_PER_PMD] __initdata __attribute__((aligned(PAGE_SIZE))); +static uintptr_t trampoline_pmd[PTRS_PER_PMD] __attribute__((aligned(PAGE_SIZE))); +static uintptr_t early_pmd[PTRS_PER_PMD] __attribute__((aligned(PAGE_SIZE))); +static uintptr_t early_uart_pmd[PTRS_PER_PMD] __attribute__((aligned(PAGE_SIZE))); +static uintptr_t early_pmd_free[((PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) >> PGDIR_SHIFT) + 1][PTRS_PER_PMD] __attribute__((aligned(PAGE_SIZE))); +static uintptr_t early_pmd_inear_map[PTRS_PER_PMD] __attribute__((aligned(PAGE_SIZE))); +static uintptr_t early_plic_pmd[PTRS_PER_PMD] __attribute__((aligned(PAGE_SIZE))); -static pmd_t *__init get_pmd_virt_early(phys_addr_t pa) + +static uintptr_t *get_pmd_virt_early(phys_addr_t pa) { /* Before MMU is enabled */ - return (pmd_t *)((uintptr_t)pa); + return (uintptr_t *)((uintptr_t)pa); } -static phys_addr_t __init alloc_pmd_early(uintptr_t va) +static phys_addr_t alloc_pmd_early(uintptr_t va) { return (uintptr_t)early_pmd; } -static void __init create_pmd_mapping_early(pmd_t *pmdp, +static void create_pmd_mapping_early(uintptr_t *pmdp, uintptr_t va, phys_addr_t pa, - phys_addr_t sz, pgprot_t prot) + phys_addr_t sz, uintptr_t prot) { uintptr_t pmd_idx = pmd_index(va); if (sz == PMD_SIZE) { - if (pmd_none(pmdp[pmd_idx])) - pmdp[pmd_idx] = pfn_pmd(PFN_DOWN(pa), prot); - + if ((pmdp[pmd_idx]) == 0) + pmdp[pmd_idx] = (PFN_PD(PFN_DOWN(pa), prot)); return; } } -static void __init create_pgd_mapping_early(pgd_t *pgdp, +static void create_pgd_mapping_early(uintptr_t *pgdp, uintptr_t va, phys_addr_t pa, - phys_addr_t sz, pgprot_t prot) + phys_addr_t sz, uintptr_t prot) { - pmd_t *nextp; + uintptr_t *nextp; phys_addr_t next_phys; uintptr_t pgd_idx = pgd_index(va); if (sz == PGDIR_SIZE) { - if (pgd_val(pgdp[pgd_idx]) == 0) - pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(pa), prot); + if ((pgdp[pgd_idx]) == 0) + pgdp[pgd_idx] = (PFN_PD(PFN_DOWN(pa), prot)); return; } - if (pgd_val(pgdp[pgd_idx]) == 0) { + if ((pgdp[pgd_idx]) == 0) { next_phys = alloc_pmd_early(va); - pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(next_phys), PAGE_TABLE); + pgdp[pgd_idx] = (PFN_PD(PFN_DOWN(next_phys), _PAGE_TABLE)); nextp = get_pmd_virt_early(next_phys); memset(nextp, 0, PAGE_SIZE); } else { - next_phys = PFN_PHYS(_pgd_pfn(pgdp[pgd_idx])); + next_phys = PFN_PHYS(_PD_PFN((pgdp[pgd_idx]))); nextp = get_pmd_virt_early(next_phys); } create_pmd_mapping_early(nextp, va, pa, sz, prot); } -static void __init create_kernel_page_table_early(pgd_t *pgdir, bool early) +static void create_kernel_page_table_early(uintptr_t *pgdir, bool early) { uintptr_t va, end_va; @@ -122,87 +116,54 @@ static void __init create_kernel_page_table_early(pgd_t *pgdir, bool early) create_pgd_mapping_early(pgdir, va, kernel_map.phys_addr + (va - kernel_map.virt_addr), PMD_SIZE, - PAGE_KERNEL_EXEC); + (_PAGE_KERNEL | _PAGE_EXEC)); } } -static void __init create_kernel_pgd_mapping_free_early(pgd_t *pgdp, +static void create_kernel_pgd_mapping_free_early(uintptr_t *pgdp, uintptr_t va, phys_addr_t pa, - phys_addr_t sz, pgprot_t prot) + phys_addr_t sz, uintptr_t prot) { - pmd_t *nextp; + uintptr_t *nextp; phys_addr_t next_phys; uintptr_t pgd_idx = pgd_index(va); uintptr_t start_pgd_idx = pgd_index(kernel_map.virt_addr); - if (pgd_val(pgdp[pgd_idx]) == 0) { + if ((pgdp[pgd_idx]) == 0) { next_phys = (uintptr_t)early_pmd_free[pgd_idx - start_pgd_idx]; - pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(next_phys), PAGE_TABLE); + pgdp[pgd_idx] = (PFN_PD(PFN_DOWN(next_phys), _PAGE_TABLE)); nextp = get_pmd_virt_early(next_phys); memset(nextp, 0, PAGE_SIZE); } else { - next_phys = PFN_PHYS(_pgd_pfn(pgdp[pgd_idx])); + next_phys = PFN_PHYS(_PD_PFN((pgdp[pgd_idx]))); nextp = get_pmd_virt_early(next_phys); } create_pmd_mapping_early(nextp, va, pa, sz, prot); } -static void __init create_kernel_page_table_free_early(pgd_t *pgdir, bool early) +static void create_kernel_page_table_free_early(uintptr_t *pgdir, bool early) { uintptr_t va, end_va; - end_va = kernel_map.virt_addr + (PHY_USER_FREEMEM_BASE - kernel_map.phys_addr); - for (va = kernel_map.virt_addr + kernel_map.size; va < end_va; va += PMD_SIZE) { + end_va = KERN_MEM_BASE + (PHY_USER_FREEMEM_BASE - PHY_MEM_BASE); + for (va = KERN_MEM_BASE + kernel_map.size; va < end_va; va += PMD_SIZE) { create_kernel_pgd_mapping_free_early(pgdir, va, - kernel_map.phys_addr + (va - kernel_map.virt_addr), + kernel_map.phys_addr + (va - KERN_MEM_BASE), PMD_SIZE, - PAGE_KERNEL_EXEC); + _PAGE_KERNEL); } } -static void __init create_kernel_pgd_mapping_linear_map_early(pgd_t *pgdp, - uintptr_t va, phys_addr_t pa, - phys_addr_t sz, pgprot_t prot) -{ - pmd_t *nextp; - phys_addr_t next_phys; - uintptr_t pgd_idx = pgd_index(va); - - if (pgd_val(pgdp[pgd_idx]) == 0) { - next_phys = (uintptr_t)early_pmd_inear_map; - pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(next_phys), PAGE_TABLE); - nextp = get_pmd_virt_early(next_phys); - memset(nextp, 0, PAGE_SIZE); - } else { - next_phys = PFN_PHYS(_pgd_pfn(pgdp[pgd_idx])); - nextp = get_pmd_virt_early(next_phys); - } - - create_pmd_mapping_early(nextp, va, pa, sz, prot); -} - -static void __init create_kernel_page_table_linear_map_early(pgd_t *pgdir, bool early) -{ - uintptr_t va, end_va; - - end_va = kernel_map.phys_addr + kernel_map.size; - for (va = kernel_map.phys_addr; va < end_va; va += PMD_SIZE) { - create_kernel_pgd_mapping_linear_map_early(pgdir, va, - kernel_map.phys_addr + (va - kernel_map.phys_addr), - PMD_SIZE, - PAGE_KERNEL_EXEC); - } -} - - -static void __init create_plic_page_table_early(pgd_t *pgdir, bool early) +static void create_plic_page_table_early(uintptr_t *pgdir, bool early) { uintptr_t va; + uintptr_t pa; - for (va = PLIC_PHYMEM_BASE; va < PLIC_PHYMEM_BASE + PLIC_MEM_SIZE; va += PMD_SIZE) { - create_pgd_mapping_early(pgdir, va, (uintptr_t)early_plic_pmd, PGDIR_SIZE, PAGE_TABLE); - create_pmd_mapping_early(early_plic_pmd, va, va, PMD_SIZE, PAGE_KERNEL); + for (va = PLIC_VIRTMEM_BASE; va < PLIC_VIRTMEM_BASE + PLIC_MEM_SIZE; va += PMD_SIZE) { + pa = va - PLIC_VIRTMEM_BASE + PLIC_PHYMEM_BASE; + create_pgd_mapping_early(pgdir, va, (uintptr_t)early_plic_pmd, PGDIR_SIZE, _PAGE_TABLE); + create_pmd_mapping_early(early_plic_pmd, va, pa, PMD_SIZE, _PAGE_KERNEL); } } @@ -217,9 +178,9 @@ static void __init create_plic_page_table_early(pgd_t *pgdir, bool early) * so disable compiler instrumentation when FTRACE is enabled. */ -void __init setup_vm_early(void) +void setup_vm_early(void) { - kernel_map.virt_addr = KERN_MEM_BASE; + kernel_map.virt_addr = KERNEL_LINK_ADDR; kernel_map.phys_addr = (uintptr_t)(&_start); kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr; @@ -227,11 +188,9 @@ void __init setup_vm_early(void) kernel_map.va_pa_offset = PAGE_OFFSET - kernel_map.phys_addr; kernel_map.va_kernel_pa_offset = kernel_map.virt_addr - kernel_map.phys_addr; - riscv_pfn_base = PFN_DOWN(kernel_map.phys_addr); - /* Setup trampoline PGD and PMD */ - create_pgd_mapping_early(trampoline_pg_dir, kernel_map.virt_addr, (uintptr_t)trampoline_pmd, PGDIR_SIZE, PAGE_TABLE); - create_pmd_mapping_early(trampoline_pmd, kernel_map.virt_addr, kernel_map.phys_addr, PMD_SIZE, PAGE_KERNEL_EXEC); + create_pgd_mapping_early(trampoline_pg_dir, kernel_map.virt_addr, (uintptr_t)trampoline_pmd, PGDIR_SIZE, _PAGE_TABLE); + create_pmd_mapping_early(trampoline_pmd, kernel_map.virt_addr, kernel_map.phys_addr, PMD_SIZE, (_PAGE_KERNEL | _PAGE_EXEC)); /* * Setup early PGD covering entire kernel which will allow @@ -241,16 +200,12 @@ void __init setup_vm_early(void) create_kernel_page_table_early(early_pg_dir, true); /* Setup uart PGD and PMD */ - create_pgd_mapping_early(early_pg_dir, DEV_VRTMEM_BASE, (uintptr_t)early_uart_pmd, PGDIR_SIZE, PAGE_TABLE); - create_pmd_mapping_early(early_uart_pmd, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, PMD_SIZE, PAGE_KERNEL); + create_pgd_mapping_early(early_pg_dir, DEV_VRTMEM_BASE, (uintptr_t)early_uart_pmd, PGDIR_SIZE, _PAGE_TABLE); + create_pmd_mapping_early(early_uart_pmd, DEV_VRTMEM_BASE, DEV_PHYMEM_BASE, PMD_SIZE, _PAGE_KERNEL); /* Setup kernel free PGD and PMD */ create_kernel_page_table_free_early(early_pg_dir, true); - /* Setup kernel linear map PGD and PMD */ - create_kernel_page_table_linear_map_early(early_pg_dir, true); - /* Setup PLIC PGD and PMD */ create_plic_page_table_early(early_pg_dir, true); } -