summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/Makefile36
-rw-r--r--sys/dev/sbi.c39
-rw-r--r--sys/include/fdt.h37
-rw-r--r--sys/include/kernel_earlyprintf.h6
-rw-r--r--sys/include/mm/kalloc.h11
-rw-r--r--sys/include/sbi.h16
-rw-r--r--sys/kern/entry.S39
-rw-r--r--sys/kern/init.c11
-rw-r--r--sys/kern/kernel.lds58
-rw-r--r--sys/kern/kernel_earlyprintf.c11
-rw-r--r--sys/kern/mm/kalloc.c40
11 files changed, 304 insertions, 0 deletions
diff --git a/sys/Makefile b/sys/Makefile
new file mode 100644
index 0000000..865a5a3
--- /dev/null
+++ b/sys/Makefile
@@ -0,0 +1,36 @@
+BUILDDIR=build/${TARGET}
+TARGETDIR=../mainboard/${TARGET}
+
+.if !exists(${TARGETDIR}/conf/mainboard.conf)
+.error 'ERROR: invalid target "${TARGET}"'
+.else
+.include <${TARGETDIR}/conf/mainboard.conf>
+.endif
+
+SRC=\
+ kern/entry.S\
+ kern/init.c\
+ kern/kernel_earlyprintf.c\
+ kern/mm/kalloc.c\
+ dev/sbi.c
+
+${BUILDDIR}/kernel.elf: ${SRC}
+ mkdir -p ${BUILDDIR}
+ ${CROSS_COMPILE}gcc ${SRC} \
+ -Wl,--defsym=LOAD_ADDR=${LOAD_ADDR}\
+ -Wl,--defsym=PAGE_SIZE=${PAGE_SIZE}\
+ -Wl,--defsym=NPROC=${NPROC}\
+ -DPAGE_SIZE=${PAGE_SIZE}\
+ -I ./include\
+ ${CFLAGS} -T kern/kernel.lds ${LDFLAGS}\
+ -L../lib/${BUILDDIR}/\
+ -l:libc.a\
+ -o $@
+
+debug: ${BUILDDIR}/kernel.elf
+ ${DEBUG} ${BUILDDIR}/kernel.elf
+
+clean:
+ rm -rf ${BUILDDIR}
+
+.PHONY: debug clean
diff --git a/sys/dev/sbi.c b/sys/dev/sbi.c
new file mode 100644
index 0000000..0c9e3f2
--- /dev/null
+++ b/sys/dev/sbi.c
@@ -0,0 +1,39 @@
+#include <sbi.h>
+
+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") = (unsigned long)(arg0);
+ register unsigned long a1 asm ("a1") = (unsigned long)(arg1);
+ register unsigned long a2 asm ("a2") = (unsigned long)(arg2);
+ register unsigned long a3 asm ("a3") = (unsigned long)(arg3);
+ register unsigned long a4 asm ("a4") = (unsigned long)(arg4);
+ register unsigned long a5 asm ("a5") = (unsigned long)(arg5);
+ register unsigned long a6 asm ("a6") = (unsigned long)(fid);
+ register unsigned long a7 asm ("a7") = (unsigned long)(ext);
+ asm volatile ("ecall"
+ : "+r" (a0), "+r" (a1)
+ : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
+ : "memory");
+ ret.err = a0;
+ ret.val = a1;
+
+ return ret;
+}
+
+void
+sbi_console_putchar(int c)
+{
+ sbi_ecall(1, 0, c, 0, 0, 0, 0, 0);
+}
+
+void
+sbi_shutdown(void)
+{
+ sbi_ecall(8, 0, 0, 0, 0, 0, 0, 0);
+}
diff --git a/sys/include/fdt.h b/sys/include/fdt.h
new file mode 100644
index 0000000..92e5695
--- /dev/null
+++ b/sys/include/fdt.h
@@ -0,0 +1,37 @@
+#include <stdint.h>
+#include <endian.h>
+
+#ifndef _FDT_H
+#define _FDT_H
+
+#define FDT_HEADER_MAGIC 0xd00dfeed
+
+static inline uint32_t
+fdt_uint32(uint32_t x)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+return __bswap32(x);
+#else
+return x;
+#endif
+}
+
+struct fdt_header {
+ uint32_t magic; /* FDT_HEADER_MAGIC */
+ uint32_t totalsize; /* size of the whole device tree, in bytes */
+ uint32_t off_dt_struct; /* offset to structure block */
+ uint32_t off_dt_strings; /* offset to strings block */
+ uint32_t off_mem_rsvmap; /* offset to memory reservation block */
+ uint32_t version; /* dt spec version */
+ uint32_t last_comp_version; /* last compatible version. spec says this needs to be 16 */
+ uint32_t boot_cpuid_phys; /* physical id of the systems boot cpu */
+ uint32_t size_dt_strings; /* size of strings block */
+ uint32_t size_dt_struct; /* size of structure block */
+};
+
+struct fdt_reserve_entry {
+ uint64_t address;
+ uint64_t size;
+};
+
+#endif /* _FDT_H */
diff --git a/sys/include/kernel_earlyprintf.h b/sys/include/kernel_earlyprintf.h
new file mode 100644
index 0000000..051d7e5
--- /dev/null
+++ b/sys/include/kernel_earlyprintf.h
@@ -0,0 +1,6 @@
+#ifndef _KPRINTF_H
+#define _KPRINTF_H
+
+int kernel_earlyputs(const char *);
+
+#endif /* _KPRINTF_H */
diff --git a/sys/include/mm/kalloc.h b/sys/include/mm/kalloc.h
new file mode 100644
index 0000000..e99d624
--- /dev/null
+++ b/sys/include/mm/kalloc.h
@@ -0,0 +1,11 @@
+#ifndef _KALLOC_H
+#define _KALLOC_H
+
+void *kalloc(void);
+
+void *kzalloc(void);
+
+void kfree(void *);
+
+#endif /* _KALLOC_H */
+
diff --git a/sys/include/sbi.h b/sys/include/sbi.h
new file mode 100644
index 0000000..0dbcd02
--- /dev/null
+++ b/sys/include/sbi.h
@@ -0,0 +1,16 @@
+#ifndef _SBICALL_H
+#define _SBICALL_H
+
+struct sbiret {
+ long err;
+ long val;
+};
+
+struct sbiret sbi_ecall(int _eid, int _fid, unsigned long _a0, unsigned long _a1,
+ unsigned long _a2, unsigned long _a3, unsigned long _a4, unsigned long _a5);
+
+void sbi_console_putchar(int c);
+void sbi_shutdown(void);
+
+#endif /* _SBICALL_H */
+
diff --git a/sys/kern/entry.S b/sys/kern/entry.S
new file mode 100644
index 0000000..5ad0490
--- /dev/null
+++ b/sys/kern/entry.S
@@ -0,0 +1,39 @@
+.section ".text.init"
+
+.globl _start
+_start:
+ csrw satp, zero
+ csrw sie, zero
+ csrw sip, zero
+
+ .option push
+ .option norelax
+ la gp, __global_pointer$
+ .option pop
+
+ la sp, __stack_start
+ li t1, PAGE_SIZE
+ mul t1, t1, a0
+ add sp, sp, t1
+
+ li a2, 1
+ lla a3, _boot_hart
+ amoswap.w a3, a2, (a3)
+ bnez a3, _spin
+
+ la a2, __bss_start
+ la a3, __bss_end
+1:
+ sd zero, (a2)
+ addi a2, a2, __SIZEOF_POINTER__
+ blt a2, a3, 1b
+
+ call init
+
+
+_spin:
+ wfi
+ j _spin
+
+.section ".data"
+_boot_hart: .word 0
diff --git a/sys/kern/init.c b/sys/kern/init.c
new file mode 100644
index 0000000..a49c304
--- /dev/null
+++ b/sys/kern/init.c
@@ -0,0 +1,11 @@
+#include <fdt.h>
+#include <kernel_earlyprintf.h>
+
+void
+init(unsigned long hartid, struct fdt_header *fdt)
+{
+ kernel_earlyputs("booting...\n");
+ if (fdt_uint32(fdt->magic) == FDT_HEADER_MAGIC)
+ kernel_earlyputs("found flattened device tree!\n");
+
+}
diff --git a/sys/kern/kernel.lds b/sys/kern/kernel.lds
new file mode 100644
index 0000000..2e2fe29
--- /dev/null
+++ b/sys/kern/kernel.lds
@@ -0,0 +1,58 @@
+OUTPUT_ARCH(riscv)
+ENTRY(_start)
+
+SECTIONS
+{
+ . = LOAD_ADDR;
+ . = ALIGN(PAGE_SIZE);
+
+ .text :
+ {
+ PROVIDE(__text_start = .);
+ *(.text.init)
+ *(.text .text.*)
+ . = ALIGN(8);
+ PROVIDE(__text_end = .);
+ }
+ . = ALIGN(PAGE_SIZE);
+
+ PROVIDE(__global_pointer$ = .);
+
+ .rodata :
+ {
+ PROVIDE(__rodata_start = .);
+ *(.rodata .rodata.*)
+ . = ALIGN(8);
+ PROVIDE(__rodata_end = .);
+ }
+
+ . = ALIGN(PAGE_SIZE);
+
+ .data :
+ {
+ PROVIDE(__data_start = .);
+ *(.sdata .sdata.*)
+ *(.data .data.*)
+ *(.readmostly.data)
+ *(*.data)
+ . = ALIGN(8);
+ PROVIDE(__data_end = .);
+ }
+
+ . = ALIGN(PAGE_SIZE);
+
+ .bss :
+ {
+ PROVIDE(__bss_start = .);
+ *(.sbss .sbss.*)
+ *(.bss .bss.*)
+ . = ALIGN(8);
+ PROVIDE(__bss_end = .);
+ }
+
+ . = ALIGN(PAGE_SIZE);
+
+ PROVIDE(__stack_start = .);
+ PROVIDE(__stack_end = __stack_start + (PAGE_SIZE * NPROC));
+ PROVIDE(__heap_start = __stack_end);
+}
diff --git a/sys/kern/kernel_earlyprintf.c b/sys/kern/kernel_earlyprintf.c
new file mode 100644
index 0000000..e6c85c4
--- /dev/null
+++ b/sys/kern/kernel_earlyprintf.c
@@ -0,0 +1,11 @@
+#include <kernel_earlyprintf.h>
+#include <sbi.h>
+
+int
+kernel_earlyputs(const char *str)
+{
+ do {
+ sbi_console_putchar(*str);
+ } while (*(str++) != '\0');
+}
+
diff --git a/sys/kern/mm/kalloc.c b/sys/kern/mm/kalloc.c
new file mode 100644
index 0000000..b17d432
--- /dev/null
+++ b/sys/kern/mm/kalloc.c
@@ -0,0 +1,40 @@
+#include <stddef.h>
+#include <string.h>
+#include <mm/kalloc.h>
+
+typedef struct freenode {
+ struct freenode *next;
+} freenode_t;
+
+freenode_t *head = NULL;
+
+void *
+kalloc(void)
+{
+ freenode_t *p = head;
+
+ if (p == NULL)
+ return NULL;
+
+ head = p->next;
+ return p;
+}
+
+void *
+kzalloc(void)
+{
+ freenode_t *p = kalloc();
+ memset(p, 0, PAGE_SIZE);
+ return p;
+}
+
+void
+kfree(void *p)
+{
+ if (p == NULL || (unsigned long)p % PAGE_SIZE)
+ return;
+
+ freenode_t *tmp = head;
+ head = p;
+ head->next = tmp;
+}