From 565724db3b73ee67fa996dab511dc52df586cee1 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Tue, 17 Aug 2021 21:47:38 +0300 Subject: Garbage --- arch/riscv/include/csr.h | 6 +++ arch/riscv/include/pages.h | 47 +++++++++++++++++++ arch/riscv/include/sbi.h | 12 +++++ arch/riscv/include/vmap.h | 19 ++++++++ arch/riscv/init/head.S | 10 ++++ arch/riscv/init/init.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ arch/riscv/main.c | 13 ++++++ arch/riscv/riscv-link.S | 20 ++++++++ arch/riscv/sbi.c | 27 +++++++++++ arch/riscv/source.mk | 5 ++ arch/source.mk | 3 ++ 11 files changed, 273 insertions(+) create mode 100644 arch/riscv/include/csr.h create mode 100644 arch/riscv/include/pages.h create mode 100644 arch/riscv/include/sbi.h create mode 100644 arch/riscv/include/vmap.h create mode 100644 arch/riscv/init/head.S create mode 100644 arch/riscv/init/init.c create mode 100644 arch/riscv/main.c create mode 100644 arch/riscv/riscv-link.S create mode 100644 arch/riscv/sbi.c create mode 100644 arch/riscv/source.mk create mode 100644 arch/source.mk (limited to 'arch') diff --git a/arch/riscv/include/csr.h b/arch/riscv/include/csr.h new file mode 100644 index 0000000..13f96cb --- /dev/null +++ b/arch/riscv/include/csr.h @@ -0,0 +1,6 @@ +#ifndef APOS_CSR_H +#define APOS_CSR_H + +#define csr_write(csr, val) + +#endif /* APOS_CSR_H */ diff --git a/arch/riscv/include/pages.h b/arch/riscv/include/pages.h new file mode 100644 index 0000000..4ae2ab9 --- /dev/null +++ b/arch/riscv/include/pages.h @@ -0,0 +1,47 @@ +#ifndef APOS_RISCV_PAGES_H +#define APOS_RISCV_PAGES_H + +typedef char pagemask_t; +typedef char lockbit_t; + +struct kilopages { + pagemask_t page[64]; +}; + +struct megapages { + lockbit_t lockbit[64]; + pagemask_t empty[64]; + pagemask_t full[64]; + struct kilopages kilo[512]; +}; + +/* Sv39 */ +struct gigapages { + lockbit_t lockbit[64]; + pagemask_t empty[64]; + pagemask_t full[64]; + struct megapages mega[512]; +}; + +struct terapages { + lockbit_t lockbit[64]; + pagemask_t empty[64]; + pagemask_t full[64]; + struct gigapages giga[512]; +}; + +struct mm_pagearr_info { + short tera_num; + struct terapages *tera_top; + + short giga_num; + struct gigapages *giga_top; + + short mega_num; + struct megapages *mega_top; + + short kilo_num; + struct kilopages *kilo_top; +}; + +#endif /* APOS_RISCV_PAGES_H */ diff --git a/arch/riscv/include/sbi.h b/arch/riscv/include/sbi.h new file mode 100644 index 0000000..609849d --- /dev/null +++ b/arch/riscv/include/sbi.h @@ -0,0 +1,12 @@ +#ifndef APOS_RISCV_SBI_H + +struct sbiret { + long error; + long value; +}; + +struct sbiret sbi_ecall(int ext, int fid, + unsigned long arg0, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, unsigned long arg5); + +#endif /* APOS_RISCV_SBI_H */ diff --git a/arch/riscv/include/vmap.h b/arch/riscv/include/vmap.h new file mode 100644 index 0000000..3dac3a1 --- /dev/null +++ b/arch/riscv/include/vmap.h @@ -0,0 +1,19 @@ +#ifndef APOS_RISCV_VMAP_H +#define APOS_RISCV_VMAP_H + +#include + +#define VM_V (1 << 1) +#define VM_R (1 << 2) +#define VM_W (1 << 3) +#define VM_X (1 << 4) +#define VM_U (1 << 5) +#define VM_G (1 << 6) +#define VM_A (1 << 7) +#define VM_D (1 << 8) +#define VM_AL 0xff + +#define VM_TOP (-1) +#define VM_KERN (VM_TOP - SZ_1G) + +#endif /* APOS_RISCV_VMAP_H */ diff --git a/arch/riscv/init/head.S b/arch/riscv/init/head.S new file mode 100644 index 0000000..703d265 --- /dev/null +++ b/arch/riscv/init/head.S @@ -0,0 +1,10 @@ +.section .init.start +.global _start +.type _start, @function +_start: + /* store kernel load address */ + auipc a4, 0 + /* stack grows downward */ + mv sp, a4 + /* go to proper init */ + j init diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c new file mode 100644 index 0000000..cdcfbb7 --- /dev/null +++ b/arch/riscv/init/init.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include + +struct page_ret { + size_t left; + size_t num; + void *top; +}; + +extern void main(struct mm_pagearr_info *pageinfo); + +void __init init_zero(void *ptr, size_t bytes) +{ + char *byte_ptr = ptr; + + /* Not entirely sure if it would be faster to use a larget type than + * char, Linux seems to have memset16/32/64 but I guess I should check + * the generated assembly. + */ + while(bytes--) + *byte_ptr++ = 0; +} + +struct page_ret __init init_pages(size_t ram_size, void *ram_top, + size_t page_size, size_t struct_size) +{ + size_t num_pages = ram_size / page_size; + size_t size_pages = num_pages * struct_size; + + struct page_ret pageret; + pageret.top = ram_top - size_pages; + pageret.num = num_pages; + pageret.left = ram_size - (size_pages * page_size); + + init_zero(pageret.top, size_pages); + + return pageret; +}; + +size_t __init init_align_down(size_t num, size_t a) +{ + size_t rem = num % a; + return num - rem; +} + +size_t __init init_align_up(size_t num, size_t a) +{ + return init_align_down(num, a) + a; +} + +void __init init_enter_vm(unsigned long *root_page) +{ + asm volatile ("csrw 0x180, %0\n" "sfence.vma\n" + : + : "rK" (root_page) + : "memory"); +} + +void call_main() +{ +} + +void __init init(void *ram_base, void *ram_top, void *initrd, void *fdt, void *boot) +{ + size_t ram_size = ram_top - ram_base; + + struct mm_pagearr_info pagearr; + struct page_ret pageret; + + /* create crude page status map at the top of physical RAM */ + pageret = init_pages(ram_size, ram_top, + SZ_512G, sizeof(struct terapages)); + pagearr.tera_num = pageret.num; + pagearr.tera_top = pageret.top; + + pageret = init_pages(pageret.left, pageret.top, + SZ_1G, sizeof(struct gigapages)); + pagearr.giga_num = pageret.num; + pagearr.giga_top = pageret.top; + + pageret = init_pages(pageret.left, pageret.top, + SZ_2M, sizeof(struct megapages)); + pagearr.mega_num = pageret.num; + pagearr.mega_top = pageret.top; + + pageret = init_pages(pageret.left, pageret.top, + SZ_4K, sizeof(struct kilopages)); + pagearr.kilo_num = pageret.num; + pagearr.kilo_top = pageret.top; + + unsigned long *root_page = (unsigned long *) + (init_align_down((size_t)pagearr.kilo_top, SZ_4K) - SZ_4K); + + /* TODO: should init insert page data into the created arrays? */ + + /* map .text.* into top part of RAM */ + root_page[511] = ((unsigned long)&main & VM_AL) | VM_V | VM_R | VM_W | VM_X; + + /* temporarily map .init.* so that our current physical address matches + * the virtual address */ + root_page[0] = 0 | VM_V | VM_R | VM_W | VM_X; + + /* enter virtual memory */ + init_enter_vm(root_page); + + /* enter main */ + call_main(); +} diff --git a/arch/riscv/main.c b/arch/riscv/main.c new file mode 100644 index 0000000..382f311 --- /dev/null +++ b/arch/riscv/main.c @@ -0,0 +1,13 @@ +#include +#include + +void yeet() +{ + int a = 23; +} + +void __main main(struct mm_pagearr_info *pageinfo) +{ + yeet(); + while(1){}; +} diff --git a/arch/riscv/riscv-link.S b/arch/riscv/riscv-link.S new file mode 100644 index 0000000..ffdf590 --- /dev/null +++ b/arch/riscv/riscv-link.S @@ -0,0 +1,20 @@ +#include + +OUTPUT_ARCH(riscv) +ENTRY(_start) + +SECTIONS { + . = 0; /* no offset */ + .init : { + *(.init.start); + *(.init.text); + *(.init.data); + . = ALIGN(4K); + } + + .text ALIGN(VM_KERN) : AT(ADDR(.init) + SIZEOF(.init)) { + *(.init.start); + *(.text.start); + *(.text); + } +} diff --git a/arch/riscv/sbi.c b/arch/riscv/sbi.c new file mode 100644 index 0000000..e255ecf --- /dev/null +++ b/arch/riscv/sbi.c @@ -0,0 +1,27 @@ +#include + +struct sbiret sbi_ecall(int ext, int fid, + unsigned long arg0, unsigned long arg1, unsigned long arg2, + unsigned long arg3, unsigned long arg4, unsigned long arg5) +{ + struct sbiret ret; + + register unsigned long a0 asm("a0") = arg0; + register unsigned long a1 asm("a1") = arg1; + register unsigned long a2 asm("a2") = arg2; + register unsigned long a3 asm("a3") = arg3; + register unsigned long a4 asm("a4") = arg4; + register unsigned long a5 asm("a5") = arg5; + register unsigned long a6 asm("a6") = fid; + register unsigned long a7 asm("a7") = ext; + + asm volatile ("ecall" + : "+r" (a0), "+r" (a1) + : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) + : "memory"); + + ret.error = a0; + ret.value = a1; + + return ret; +} diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk new file mode 100644 index 0000000..f52750c --- /dev/null +++ b/arch/riscv/source.mk @@ -0,0 +1,5 @@ +LOCAL_KERNEL_SOURCES := main.c init/head.S init/init.c +KERNEL_SOURCES += $(addprefix arch/riscv/,$(LOCAL_KERNEL_SOURCES)) + +INCLUDE_DIRS += arch/riscv/include +LINKER_SOURCE := arch/riscv/riscv-link.S diff --git a/arch/source.mk b/arch/source.mk new file mode 100644 index 0000000..1b21b56 --- /dev/null +++ b/arch/source.mk @@ -0,0 +1,3 @@ +ifeq ($(TARGET),riscv) +include arch/riscv/source.mk +endif -- cgit v1.3