aboutsummaryrefslogtreecommitdiff
path: root/arch/riscv
diff options
context:
space:
mode:
Diffstat (limited to 'arch/riscv')
-rw-r--r--arch/riscv/include/csr.h2
-rw-r--r--arch/riscv/include/vmap.h17
-rw-r--r--arch/riscv/init-link.S14
-rw-r--r--arch/riscv/init/init.c41
-rw-r--r--arch/riscv/kernel-link.S14
-rw-r--r--arch/riscv/kernel.its34
-rw-r--r--arch/riscv/riscv-link.S12
-rw-r--r--arch/riscv/source.mk12
8 files changed, 111 insertions, 35 deletions
diff --git a/arch/riscv/include/csr.h b/arch/riscv/include/csr.h
index 13f96cb..694000b 100644
--- a/arch/riscv/include/csr.h
+++ b/arch/riscv/include/csr.h
@@ -3,4 +3,6 @@
#define csr_write(csr, val)
+#define SATP_MODE_39 0x8000000000000000
+
#endif /* APOS_CSR_H */
diff --git a/arch/riscv/include/vmap.h b/arch/riscv/include/vmap.h
index 3dac3a1..a1cf52f 100644
--- a/arch/riscv/include/vmap.h
+++ b/arch/riscv/include/vmap.h
@@ -3,15 +3,14 @@
#include <apos/sizes.h>
-#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_V (1 << 0)
+#define VM_R (1 << 1)
+#define VM_W (1 << 2)
+#define VM_X (1 << 3)
+#define VM_U (1 << 4)
+#define VM_G (1 << 5)
+#define VM_A (1 << 6)
+#define VM_D (1 << 7)
#define VM_TOP (-1)
#define VM_KERN (VM_TOP - SZ_1G)
diff --git a/arch/riscv/init-link.S b/arch/riscv/init-link.S
new file mode 100644
index 0000000..db18822
--- /dev/null
+++ b/arch/riscv/init-link.S
@@ -0,0 +1,14 @@
+#include <apos/link.lds.h>
+#include <vmap.h>
+
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+
+SECTIONS {
+ . = ABSOLUTE(PM_KERN);
+ .text ALIGN(4K) : AT(0) {
+ *(.init.start)
+ *(.text);
+ . = ALIGN(4K);
+ }
+}
diff --git a/arch/riscv/init/init.c b/arch/riscv/init/init.c
index cdcfbb7..69dbc0a 100644
--- a/arch/riscv/init/init.c
+++ b/arch/riscv/init/init.c
@@ -2,19 +2,20 @@
#include <apos/init.h>
#include <apos/sizes.h>
#include <pages.h>
+#include <csr.h>
#include <vmap.h>
struct page_ret {
size_t left;
size_t num;
- void *top;
+ size_t top;
};
extern void main(struct mm_pagearr_info *pageinfo);
-void __init init_zero(void *ptr, size_t bytes)
+void __init init_zero(size_t ptr, size_t bytes)
{
- char *byte_ptr = ptr;
+ char *byte_ptr = (char *)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
@@ -24,7 +25,7 @@ void __init init_zero(void *ptr, size_t bytes)
*byte_ptr++ = 0;
}
-struct page_ret __init init_pages(size_t ram_size, void *ram_top,
+struct page_ret __init init_pages(size_t ram_size, size_t ram_top,
size_t page_size, size_t struct_size)
{
size_t num_pages = ram_size / page_size;
@@ -33,7 +34,7 @@ struct page_ret __init init_pages(size_t ram_size, void *ram_top,
struct page_ret pageret;
pageret.top = ram_top - size_pages;
pageret.num = num_pages;
- pageret.left = ram_size - (size_pages * page_size);
+ pageret.left = ram_size - (num_pages * page_size);
init_zero(pageret.top, size_pages);
@@ -55,12 +56,13 @@ void __init init_enter_vm(unsigned long *root_page)
{
asm volatile ("csrw 0x180, %0\n" "sfence.vma\n"
:
- : "rK" (root_page)
+ : "rK" (SATP_MODE_39 | ((unsigned long)root_page >> 12))
: "memory");
}
-void call_main()
+void __init call_main()
{
+ while(1){};
}
void __init init(void *ram_base, void *ram_top, void *initrd, void *fdt, void *boot)
@@ -71,37 +73,42 @@ void __init init(void *ram_base, void *ram_top, void *initrd, void *fdt, void *b
struct page_ret pageret;
/* create crude page status map at the top of physical RAM */
- pageret = init_pages(ram_size, ram_top,
+ pageret = init_pages(ram_size, (size_t)ram_top,
SZ_512G, sizeof(struct terapages));
+ pagearr.tera_top = (struct terapages *)pageret.top;
pagearr.tera_num = pageret.num;
- pagearr.tera_top = pageret.top;
pageret = init_pages(pageret.left, pageret.top,
SZ_1G, sizeof(struct gigapages));
+ pagearr.giga_top = (struct gigapages *)pageret.top;
pagearr.giga_num = pageret.num;
- pagearr.giga_top = pageret.top;
pageret = init_pages(pageret.left, pageret.top,
SZ_2M, sizeof(struct megapages));
+ pagearr.mega_top = (struct megapages *)pageret.top;
pagearr.mega_num = pageret.num;
- pagearr.mega_top = pageret.top;
pageret = init_pages(pageret.left, pageret.top,
SZ_4K, sizeof(struct kilopages));
+ pagearr.kilo_top = (struct kilopages *)pageret.top;
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);
+ unsigned long *mid_page = (unsigned long)root_page - SZ_4K;
+ unsigned long *bot_page = (unsigned long)mid_page - SZ_4K;
+
/* TODO: should init insert page data into the created arrays? */
+ unsigned long root_addr = (((unsigned long)boot >> 12) >> 18) & 0x1ff;
+ unsigned long mid_addr = (((unsigned long)boot >> 12) >> 9) & 0x1ff;
+ unsigned long bot_addr = (((unsigned long)boot >> 12) >> 0) & 0x1ff;
- /* map .text.* into top part of RAM */
- root_page[511] = ((unsigned long)&main & VM_AL) | VM_V | VM_R | VM_W | VM_X;
+ root_page[root_addr] = (((unsigned long)mid_page & ~0x3ff) >> 2) | VM_V;
+ mid_page[mid_addr] = ((unsigned long)bot_page & ~0x3ff) >> 2 | VM_V;
+ bot_page[bot_addr] = (((unsigned long)boot & ~0x3ff) >> 2) | 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;
+ //root_page[0] = (((unsigned long)ram_base & ~0x3ff) >> 2) | VM_V | VM_R | VM_W | VM_X;
/* enter virtual memory */
init_enter_vm(root_page);
diff --git a/arch/riscv/kernel-link.S b/arch/riscv/kernel-link.S
new file mode 100644
index 0000000..873c7de
--- /dev/null
+++ b/arch/riscv/kernel-link.S
@@ -0,0 +1,14 @@
+#include <apos/link.lds.h>
+#include <vmap.h>
+
+OUTPUT_ARCH(riscv)
+ENTRY(main)
+
+SECTIONS {
+ . = ABSOLUTE(VM_KERN);
+ .text ALIGN(4K) : AT(0) {
+ *(.text.start);
+ *(.text);
+ . = ALIGN(4K);
+ }
+}
diff --git a/arch/riscv/kernel.its b/arch/riscv/kernel.its
new file mode 100644
index 0000000..f984d40
--- /dev/null
+++ b/arch/riscv/kernel.its
@@ -0,0 +1,34 @@
+/dts-v1/;
+
+/ {
+ description = "FUCK";
+#address-cells = <1>;
+
+ images {
+ kernel {
+ description = "My default kenel";
+ data = /incbin/("kernel.bin");
+ type = "kernel";
+ arch = "riscv";
+ os = "apos";
+ compression = "none";
+ load = <0x83800000>;
+ entry = <0x83800000>;
+ hash-1 {
+ algo = "md5";
+ };
+ };
+
+ };
+
+ configurations {
+ default = "config";
+
+ config {
+ description = "Default configuration";
+ kernel = "kernel";
+ };
+
+
+ };
+};
diff --git a/arch/riscv/riscv-link.S b/arch/riscv/riscv-link.S
index ffdf590..0950850 100644
--- a/arch/riscv/riscv-link.S
+++ b/arch/riscv/riscv-link.S
@@ -1,20 +1,22 @@
+#include <apos/link.lds.h>
#include <vmap.h>
OUTPUT_ARCH(riscv)
ENTRY(_start)
SECTIONS {
- . = 0; /* no offset */
- .init : {
+ . = ABSOLUTE(PM_KERN);
+ .init ALIGN(4K) : AT(0) {
*(.init.start);
*(.init.text);
*(.init.data);
. = ALIGN(4K);
}
- .text ALIGN(VM_KERN) : AT(ADDR(.init) + SIZEOF(.init)) {
- *(.init.start);
+ . = ABSOLUTE(VM_KERN);
+ .text ALIGN(4K) : AT(SIZEOF(.init)) {
*(.text.start);
- *(.text);
+ *(.text.text);
+ *(.text.data);
}
}
diff --git a/arch/riscv/source.mk b/arch/riscv/source.mk
index f52750c..8bd67ee 100644
--- a/arch/riscv/source.mk
+++ b/arch/riscv/source.mk
@@ -1,5 +1,9 @@
-LOCAL_KERNEL_SOURCES := main.c init/head.S init/init.c
-KERNEL_SOURCES += $(addprefix arch/riscv/,$(LOCAL_KERNEL_SOURCES))
+KERNEL_LOCAL != ./scripts/prepend arch/riscv/ main.c
+KERNEL_SOURCES += $(KERNEL_LOCAL)
-INCLUDE_DIRS += arch/riscv/include
-LINKER_SOURCE := arch/riscv/riscv-link.S
+INIT_LOCAL != ./scripts/prepend arch/riscv/init/ init.c head.S
+INIT_SOURCES += $(INIT_LOCAL)
+
+INCLUDE_DIRS += arch/riscv/include
+KERNEL_LINK := arch/riscv/kernel-link.S
+INIT_LINK := arch/riscv/init-link.S