diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/boot.S b/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/boot.S index 2b3016ef7..d0edd59c6 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/boot.S +++ b/Ubiquitous/XiZi_AIoT/hardkernel/arch/riscv/rv64gc/preboot_for_jh7110/boot.S @@ -42,6 +42,8 @@ clear_bss: blt a3, a4, clear_bss clear_bss_done: + la sp, stacks_top + /* Initialize page tables and relocate to virtual addresses */ call setup_vm_early 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 2ca86cfa0..2f3ee3073 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 @@ -88,7 +88,7 @@ SECTIONS .text : { . = ALIGN(0x1000); - *(.text .text.* .gnu.linkonce.t.*) + *(.text .text.*) } . = ALIGN(0x1000); @@ -138,7 +138,7 @@ SECTIONS __global_pointer$ = . + 0x800; *(.sdata*) } - + . = ALIGN((1 << 21)); _edata = .; _end = .; } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/bootmmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/bootmmu.c index bc48c8b75..0ad40cdf5 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/bootmmu.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/bootmmu.c @@ -33,14 +33,14 @@ Modification: #include "pagetable.h" #include "registers.h" #include "ns16550.h" +#include "printf.h" #include #include #include #include - -// clang-format off +// #define L2_PTE_VALID (1 << 0) #define L3_PTE_VALID (1 << 0) @@ -62,7 +62,7 @@ Modification: #define PAGE_KERNEL_READ (_PAGE_KERNEL & ~_PAGE_WRITE) #define PAGE_KERNEL_EXEC (_PAGE_KERNEL | _PAGE_EXEC) -// clang-format on +// uint64_t boot_l2pgdir[NUM_LEVEL2_PDE] __attribute__((aligned(0x1000))) = { 0 }; uint64_t boot_dev_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { 0 }; @@ -71,7 +71,7 @@ uint64_t boot_kern_l3pgdir[NUM_LEVEL3_PDE] __attribute__((aligned(0x1000))) = { uint64_t boot_dev_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 }; uint64_t boot_kern_l4pgdirs[NUM_LEVEL3_PDE][NUM_LEVEL4_PTE] __attribute__((aligned(0x1000))) = { 0 }; - +// static void build_boot_pgdir() { static bool built = false; @@ -118,16 +118,45 @@ static void load_boot_pgdir() csr_write(CSR_SATP, satp_val); } +// +static int test_access_map_address(void) +{ + unsigned long address = KERN_MEM_BASE + (PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) - 4096; + printf_early("to access 0x%lx\n", address); + *(unsigned long *)address = 0x55; + if(*(unsigned long *)address == 0x55) { + printf_early("access 0x%lx done\n", address); + } + return 0; +} + +static int test_access_unmap_address(void) +{ + unsigned long address = KERN_MEM_BASE + (PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) + 4096; + *(unsigned long *)address = 0x55; + printf_early("access 0x%lx done\n", address); + return 0; +} + +static void test_mmu(void) +{ + test_access_map_address(); + test_access_unmap_address(); +} + +// extern void main(void); void bootmain(void) { - _debug_uart_printascii("bootmain start.\n"); - - build_boot_pgdir(); - load_boot_pgdir(); - _debug_uart_printascii("boot pgdir success\n"); + _debug_uart_printascii("bootmain start\n"); +#if 0 + test_mmu(); +#endif main(); + + _debug_uart_printascii("bootmain end\n"); + while(1); } 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 b7a67bbc5..2e9e32269 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 (0x0000000080000000ULL) +#define PHY_USER_FREEMEM_BASE (0x0000000100000000ULL) #define PHY_USER_FREEMEM_TOP (0x0000000200000000ULL) #define PHY_MEM_STOP (0x0000000200000000ULL) 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 979b78448..698ddee32 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu_init.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/riscv/rv64gc/mmu_init.c @@ -55,6 +55,8 @@ pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __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 *__init get_pmd_virt_early(phys_addr_t pa) @@ -86,7 +88,7 @@ static void __init create_pmd_mapping_early(pmd_t *pmdp, } } -void __init create_pgd_mapping_early(pgd_t *pgdp, +static void __init create_pgd_mapping_early(pgd_t *pgdp, uintptr_t va, phys_addr_t pa, phys_addr_t sz, pgprot_t prot) { @@ -116,7 +118,6 @@ void __init create_pgd_mapping_early(pgd_t *pgdp, static void __init create_kernel_page_table_early(pgd_t *pgdir, bool early) { uintptr_t va, end_va; - int i = 0; end_va = kernel_map.virt_addr + kernel_map.size; for (va = kernel_map.virt_addr; va < end_va; va += PMD_SIZE) { @@ -124,7 +125,76 @@ static void __init create_kernel_page_table_early(pgd_t *pgdir, bool early) kernel_map.phys_addr + (va - kernel_map.virt_addr), PMD_SIZE, PAGE_KERNEL_EXEC); - i++; + } +} + + +static void __init create_kernel_pgd_mapping_free_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); + uintptr_t start_pgd_idx = pgd_index(kernel_map.virt_addr); + + if (pgd_val(pgdp[pgd_idx]) == 0) { + next_phys = early_pmd_free[pgd_idx - start_pgd_idx]; + 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_free_early(pgd_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) { + create_kernel_pgd_mapping_free_early(pgdir, va, + kernel_map.phys_addr + (va - kernel_map.virt_addr), + PMD_SIZE, + PAGE_KERNEL_EXEC); + } +} + +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 = 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); } } @@ -166,5 +236,11 @@ void __init setup_vm_early(void) /* 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); + + /* 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); } diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c b/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c index 07130da60..4aa8f0939 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/uart/uart_common_ope.c @@ -898,13 +898,24 @@ int fctprintf(void (*out)(char character, void* arg), void* arg, const char* for } /////////////////////////////////////////////////////////////////////////////// -__attribute__((weak)) void _debug_uart_putc(int ch); +__attribute__((weak)) void _debug_uart_putc(int ch) {} + +static inline void _out_char_early(char character, void* buffer, size_t idx, size_t maxlen) +{ + (void)buffer; + (void)idx; + (void)maxlen; + if (character) { + _debug_uart_putc(character); + } +} + int printf_early(const char* format, ...) { va_list va; va_start(va, format); char buffer[1]; - const int ret = _vsnprintf(_debug_uart_putc, buffer, (size_t)-1, format, va); + const int ret = _vsnprintf(_out_char_early, buffer, (size_t)-1, format, va); va_end(va); return ret; }