diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/Makefile | 5 | ||||
-rwxr-xr-x | sys/build/virt/kernel.elf | bin | 0 -> 14832 bytes | |||
-rw-r--r-- | sys/dev/cpu.c | 6 | ||||
-rw-r--r-- | sys/dev/fdt/fdt.c | 28 | ||||
-rw-r--r-- | sys/include/asm.h | 55 | ||||
-rw-r--r-- | sys/include/cpu.h | 10 | ||||
-rw-r--r-- | sys/include/fdt.h | 18 | ||||
-rw-r--r-- | sys/include/smp.h | 0 | ||||
-rw-r--r-- | sys/include/spinlock.h | 11 | ||||
-rw-r--r-- | sys/kern/entry.S | 18 | ||||
-rw-r--r-- | sys/kern/init.c | 21 | ||||
-rw-r--r-- | sys/kern/mm/kalloc.c | 2 | ||||
-rw-r--r-- | sys/kern/spinlock.c | 15 |
13 files changed, 179 insertions, 10 deletions
diff --git a/sys/Makefile b/sys/Makefile index db8bf8e..2cfd2bb 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -12,7 +12,10 @@ SRC=\ kern/init.c\ kern/printf.c\ kern/mm/kalloc.c\ - dev/sbi.c + kern/spinlock.c\ + dev/sbi.c\ + dev/fdt/fdt.c + ${BUILDDIR}/kernel.elf: ${SRC} mkdir -p ${BUILDDIR} diff --git a/sys/build/virt/kernel.elf b/sys/build/virt/kernel.elf Binary files differnew file mode 100755 index 0000000..96e2059 --- /dev/null +++ b/sys/build/virt/kernel.elf diff --git a/sys/dev/cpu.c b/sys/dev/cpu.c new file mode 100644 index 0000000..f96b807 --- /dev/null +++ b/sys/dev/cpu.c @@ -0,0 +1,6 @@ +#include <cpu.h> + +extern struct hart harts[NPROC]; + + + diff --git a/sys/dev/fdt/fdt.c b/sys/dev/fdt/fdt.c new file mode 100644 index 0000000..4b132e2 --- /dev/null +++ b/sys/dev/fdt/fdt.c @@ -0,0 +1,28 @@ +#include <fdt.h> +#include <sbi.h> +#include <printf.h> +#include <stdint.h> + +void +fdt_walk(struct fdt_header *header) +{ + if (fdt_uint32(header->magic) != FDT_HEADER_MAGIC) { + printf("corrupted or invalid fdt"); + } + printf("parsing fdt @%p...\n", header); + printf("header->totalsize: %d\n", fdt_uint32(header->totalsize)); + printf("header->off_dt_struct: %d\n", fdt_uint32(header->off_dt_struct)); + printf("header->off_dt_strings: %d\n", fdt_uint32(header->off_dt_strings)); + printf("header->off_mem_rsvmap: %d\n", fdt_uint32(header->off_mem_rsvmap)); + printf("header->version: %d\n", fdt_uint32(header->version)); + printf("header->last_comp_version: %d\n", fdt_uint32(header->last_comp_version)); + printf("header->boot_cpuid_phys: %d\n", fdt_uint32(header->boot_cpuid_phys)); + printf("header->size_dt_strings: %d\n", fdt_uint32(header->size_dt_strings)); + printf("header->size_dt_struct: %d\n", fdt_uint32(header->size_dt_struct)); + + uint8_t *dts = header + fdt_uint32(header->off_dt_struct) + sizeof(uint32_t); + uint8_t *dtstr = header + fdt_uint32(header->off_dt_strings); + printf("parsing dt struct @%p...\n", dts); + printf(dts); +} + diff --git a/sys/include/asm.h b/sys/include/asm.h new file mode 100644 index 0000000..86e6354 --- /dev/null +++ b/sys/include/asm.h @@ -0,0 +1,55 @@ +#ifndef _ASM_H +#define _ASM_H + +#include <stdint.h> + +#define SSTATUS_SIE (1L << 1) + +static inline uint64_t +csrr_sstatus(void) +{ + uint64_t x; + asm volatile("csrr %0, sstatus" : "=r"(x)); + return x; +} + +static inline void +csrw_sstatus(uint64_t x) +{ + asm volatile("csrw sstatus, %0" : : "r"(x)); +} + +/* will enable all supervisor interrupts using the bit in sstatus */ +static inline void +sie_enable(void) +{ + csrw_sstatus(csrr_sstatus() | SSTATUS_SIE); +} + +/* will disable all supervisor interrupts by using the bitin sstatus (though sie can also be used) */ +static inline void +sie_disable(void) +{ + csrw_sstatus(csrr_sstatus() & ~SSTATUS_SIE); +} + +/* returns the status of the sie bit in sstatus + * 1 if enabled, 0 if disabled. + * for more specific info see the sie register + */ +static inline uint64_t +sie_status() +{ + return (csrr_sstatus() & SSTATUS_SIE) != 0; + +} + +/* we use tp to store hartid */ +static inline uint64_t +read_tp(void) +{ + uint64_t x; + asm volatile("addi %0, tp, 0" : "=r"(x)); +} + +#endif /* _ASM_H */ diff --git a/sys/include/cpu.h b/sys/include/cpu.h new file mode 100644 index 0000000..9567496 --- /dev/null +++ b/sys/include/cpu.h @@ -0,0 +1,10 @@ +#ifndef _CPU_H +#define _CPU_H + +struct hart { + int intr_stack; +}; + +struct hart harts[NPROC] = {0}; + +#endif /* _CPU_H */ diff --git a/sys/include/fdt.h b/sys/include/fdt.h index 92e5695..ca1cea0 100644 --- a/sys/include/fdt.h +++ b/sys/include/fdt.h @@ -1,5 +1,6 @@ #include <stdint.h> #include <endian.h> +#include <printf.h> #ifndef _FDT_H #define _FDT_H @@ -34,4 +35,21 @@ struct fdt_reserve_entry { uint64_t size; }; +struct fdt_node_header { + uint32_t tag; + char name[]; +}; + +void walk_fdt(struct fdt_header *header); + +#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ +#define FDT_TAGSIZE sizeof(fdt32_t) + +#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ +#define FDT_END_NODE 0x2 /* End node */ +#define FDT_PROP 0x3 /* Property: name off, + size, content */ +#define FDT_NOP 0x4 /* nop */ +#define FDT_END 0x9 + #endif /* _FDT_H */ diff --git a/sys/include/smp.h b/sys/include/smp.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/sys/include/smp.h diff --git a/sys/include/spinlock.h b/sys/include/spinlock.h new file mode 100644 index 0000000..3400445 --- /dev/null +++ b/sys/include/spinlock.h @@ -0,0 +1,11 @@ +#ifndef _LOCK_H +#define _LOCK_H + +struct spinlock { + int locked; + const char *name; +}; + +void initlock(struct spinlock *, const char *); + +#endif /* _LOCK_H */ diff --git a/sys/kern/entry.S b/sys/kern/entry.S index fccd80f..03ff76c 100644 --- a/sys/kern/entry.S +++ b/sys/kern/entry.S @@ -2,6 +2,7 @@ .globl _start _start: + /* disable interrupts and poging */ csrw satp, zero csrw sie, zero csrw sip, zero @@ -11,33 +12,42 @@ _start: la gp, __global_pointer$ .option pop + /* setup stack */ addi t0, a0, 1 li t1, PAGE_SIZE la sp, __stack_start mul t1, t1, t0 add sp, sp, t1 + /* setup thread pointer */ + mv tp, a0 + + /* the label _boot_hart is shared between threads. only one hart will branch before it is no longer 0 */ li a2, 1 lla a3, _boot_hart amoswap.w a3, a2, (a3) - bnez a3, _spin + bnez a3, 2f + /* clear the bss section */ la a2, __bss_start la a3, __bss_end 1: sd zero, (a2) addi a2, a2, __SIZEOF_POINTER__ blt a2, a3, 1b - +2: call init - + j _spin _spin: wfi j _spin .section ".data" -_boot_hart: .word 0 +_boot_hart: + .word 0 + .section ".rodata" +/* linker imports */ .globl HEAP_START HEAP_START: .dword __heap_start diff --git a/sys/kern/init.c b/sys/kern/init.c index 18feaa3..208df6d 100644 --- a/sys/kern/init.c +++ b/sys/kern/init.c @@ -1,20 +1,35 @@ #include <fdt.h> +#include <mm/kalloc.h> #include <printf.h> #include <stdint.h> -#include <mm/kalloc.h> +#include <spinlock.h> extern uint64_t HEAP_START; void init(unsigned long hartid, struct fdt_header *fdt) { + printf("booting from hart #%d\n", hartid); + asm volatile ("mv tp, %0" : : "r"(hartid)); if (fdt_uint32(fdt->magic) == FDT_HEADER_MAGIC) printf("found flattened device tree at %p!\n", (uint64_t)fdt); + printf("parsing device tree!\n"); + fdt_walk(fdt); + printf("setting up the heap at %p\n", HEAP_START); kalloc_init(); printf("done!\n"); - printf("printing free pages:\n"); - walkfree(); + // printf("printing free pages:\n"); + //walkfree(); +} + +/* non boot harts enter here */ +void +mpinit(unsigned long hartid, struct fdt_header *fdt) +{ + unsigned char *uart = (unsigned char*)0x10000000; + *uart = hartid + '0'; + *(uart + 1) = '\n'; } diff --git a/sys/kern/mm/kalloc.c b/sys/kern/mm/kalloc.c index f354648..bfd4f3f 100644 --- a/sys/kern/mm/kalloc.c +++ b/sys/kern/mm/kalloc.c @@ -46,10 +46,8 @@ kfree(void *p) void kalloc_init(void) { - printf("1\n"); freenode_t *p = (freenode_t*)HEAP_START; for (;(unsigned long)p + PAGE_SIZE <= (HEAP_START + 0x100000); p += PAGE_SIZE) { - printf("freeing page at %p", p); kfree(p); } } diff --git a/sys/kern/spinlock.c b/sys/kern/spinlock.c new file mode 100644 index 0000000..a35b8ce --- /dev/null +++ b/sys/kern/spinlock.c @@ -0,0 +1,15 @@ +#include <spinlock.h> + +void +init_locklock(struct spinlock *l, const char *_name) +{ + l->name = _name; + l->locked = 0; + l->cpu = 0; +} + +void +acquire_lock(struct spinlock *l) +{ + asm volatile("csrr sie, zero"); +} |