Skip to content

Commit

Permalink
Reorganize kernel to be more independent of userland
Browse files Browse the repository at this point in the history
  • Loading branch information
Henrik Karlsson committed Oct 15, 2023
1 parent 55a0d93 commit 7b6f4e2
Show file tree
Hide file tree
Showing 12 changed files with 219 additions and 45 deletions.
16 changes: 6 additions & 10 deletions kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ ROOT=..
S3K_CONF_H?=s3k_conf.h

# Platform specific config
PLATFORM?=${ROOT}/plat/virt
include ${PLATFORM}/platform.mk

# Common sources
COMMON=${ROOT}/common
PLATFORM?=${ROOT}/plat64
include ${PLATFORM}/config.mk

# Get toolchain
include ${ROOT}/tools.mk
Expand All @@ -29,12 +26,11 @@ vpath %.S src
SRCS =head.S trap.S stack.S
SRCS+=cap_table.c cap_util.c cap_ops.c cap_pmp.c cap_monitor.c cap_ipc.c \
csr.c exception.c kernel.c proc.c sched.c mcslock.c syscall.c
SRCS+=${DRIVERS}
OBJS=${patsubst %, ${BUILD}/${PROGRAM}/%.o, ${SRCS}}
DEPS=${patsubst %, ${BUILD}/${PROGRAM}/%.d, ${SRCS}}

# Compilation flags
CFLAGS =-march=${ARCH} -mabi=${ABI} -mcmodel=${CMODEL}
CFLAGS+=-march=${ARCH} -mabi=${ABI} -mcmodel=${CMODEL}
CFLAGS+=-std=c11
CFLAGS+=-Wall -Wextra -Werror
CFLAGS+=-Wno-unused-parameter
Expand All @@ -47,11 +43,11 @@ CFLAGS+=-Wl,--gc-sections
CFLAGS+=-flto -fwhole-program
CFLAGS+=--specs=nosys.specs
CFLAGS+=-ffunction-sections -fdata-sections
CFLAGS+=-T${PLATFORM}/platform.ld -Tlinker.ld
CFLAGS+=-Tlinker.ld
CFLAGS+=-Wl,--no-warn-rwx-segments
CFLAGS+=-DKERNEL

INC+=-include ${PLAT_CONF_H} -include ${S3K_CONF_H}
INC+=-Iinc -I${COMMON}/inc
INC+=-Iinc -I${PLATFORM}/inc -include ${S3K_CONF_H}

ELF=${BUILD}/${PROGRAM}.elf
BIN=${ELF:.elf=.bin}
Expand Down
4 changes: 2 additions & 2 deletions kernel/inc/kassert.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma once
#include "drivers/uart.h"
#include "uart.h"

/**
* @file kassert.h
Expand All @@ -19,7 +19,7 @@

#define _X_(x) #x
#define KASSERT_FAILURE(FILE, LINE) \
uart_puts("Kernel assertion failed at " FILE ":" _X_(LINE) ".");
uart_write("Kernel assertion failed at " FILE ":" _X_(LINE) ".\n", 128);

#define KASSERT(EXPR) \
do { \
Expand Down
38 changes: 38 additions & 0 deletions kernel/inc/time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <stdint.h>

/** Get the RT clock */
static inline uint64_t time_get(void);

/** Set the RT clock */
static inline void time_set(uint64_t time);

/** Get the RT clock timeout for hart `hartid' */
static inline uint64_t timer_get(uint64_t hartid);

/** Set the RT clock timeout for hart `hartid' */
static inline void timer_set(uint64_t hartid, uint64_t timeout);

static volatile uint64_t *const MTIME = (uint64_t *)MTIME_BASE_ADDR;
static volatile uint64_t *const MTIMECMP = (uint64_t *)MTIMECMP_BASE_ADDR;

uint64_t time_get(void)
{
return MTIME[0];
}

void time_set(uint64_t time)
{
MTIME[0] = time;
}

uint64_t timer_get(uint64_t hartid)
{
return MTIMECMP[hartid];
}

void timer_set(uint64_t hartid, uint64_t timeout)
{
MTIMECMP[hartid] = timeout;
}
140 changes: 140 additions & 0 deletions kernel/inc/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#pragma once
#include <stddef.h>

/* Initializes UART */
static inline void uart_init(void);
/* Puts one character in UART */
static inline int uart_putc(char c);
/* Gets one character from UART */
static inline int uart_getc(void);
/* Puts a string to UART */
static inline int uart_write(const char *s, int size);
/* Gets a NUL terminated string */
static inline int uart_read(char *s, int size);

#if defined(UART_NS16550A)
/* Driver for ns16550a UART. */
struct uart {
union {
char rbr; // Receiver buffer register (read only)
char thr; // Transmitter holding register (write only)
};

char ier; // Interrupt enabler register

union {
char iir; // Interrupt identification register (read only)
char fcr; // FIFO control register (write only)
};

char lcr; // Line control register
char __padding;
char lsr; // Line status register
};

static volatile struct uart *UART0 = (volatile struct uart *)UART0_BASE_ADDR;

// Line status register flags
#define LSR_RX_READY 0x1 // Receive data ready
#define LSR_TX_READY 0x60 // Transmit data ready

void uart_init(void)
{
UART0->lcr = 0x3;
UART0->fcr = 0x1;
}

int uart_putc(char c)
{
while (!(UART0->lsr & LSR_TX_READY))
;
UART0->thr = (unsigned char)c;
return (unsigned char)c;
}

int uart_getc(void)
{
while (!(UART0->lsr & LSR_RX_READY))
;
return UART0->rbr;
}

#elif defined(UART_SIFIVE)

/* Driver for SiFive's UART */

struct uart {
int txdata; // Transmit data register
int rxdata; // Receive data register
int txctrl; // Transmit control register
int rxctrl; // Receive control register
int ie; // UART interrupt enable
int ip; // UART interrupt pending
int div; // Baud rate divisor
};

static volatile struct uart *const UART0
= (volatile struct uart *)UART0_BASE_ADDR;

// Bit masks for transmit and receive adata registers
#define TXDATA_FULL 0x80000000ul
#define RXDATA_EMPTY 0x80000000ul

// Control register flags for enabling transmission and reception
#define TXCTRL_TXEN 0x1ul
#define RXCTRL_RXEN 0x1ul

// Control register flags for setting stop bits
#define TXCTRL_NSTOP 0x2ul

void uart_init(void)
{
UART0->txctrl = TXCTRL_TXEN; // Enable transmit data
UART0->rxctrl = RXCTRL_RXEN; // Enable receive data
}

int uart_putc(char c)
{
while (UART0->txdata & TXDATA_FULL) {
}
UART0->txdata = (unsigned char)c;
return (unsigned char)c;
}

int uart_getc(void)
{
int c;
do {
c = UART0->rxdata;
} while (c & RXDATA_EMPTY);
return c;
}
#else
#error "Missing UART"
#endif

int uart_write(const char *s, int size)
{
if (s == NULL)
return 0;

int i = 0;
for (i = 0; i < size && s[i] != '\0'; i++)
uart_putc(s[i]);
return i;
}

int uart_read(char *s, int size)
{
if (s == NULL || size <= 0)
return 0;

int i;
for (i = 0; i < size - 1; ++i) {
s[i] = uart_getc();
if (s[i] == '\n' || s[i] == '\r')
break;
}
s[i] = '\0';
return i;
}
6 changes: 5 additions & 1 deletion kernel/s3k_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#ifndef __S3K_CONF_H__
#define __S3K_CONF_H__

#define PLATFORM_VIRT

#include "plat/config.h"

// Number of user processes
#define S3K_PROC_CNT 8

Expand All @@ -21,6 +25,6 @@
#define S3K_SCHED_TIME (S3K_SLOT_LEN / 10)

// If debugging, comment
// #define NDEBUG
#define NDEBUG

#endif /* __S3K_CONF_H__ */
2 changes: 1 addition & 1 deletion kernel/src/cap_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include "cap_ops.h"
#include "cap_table.h"
#include "csr.h"
#include "drivers/timer.h"
#include "error.h"
#include "kassert.h"
#include "proc.h"
#include "time.h"

#include <stdint.h>

Expand Down
2 changes: 1 addition & 1 deletion kernel/src/cap_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ static uint32_t offset(cte_t c)

void ctable_init(void)
{
cap_t init_caps[] = INIT_CAPS;
const cap_t init_caps[] = INIT_CAPS;
cte_t prev = ctable;
for (unsigned int i = 0; i < ARRAY_SIZE(init_caps); ++i)
cte_insert(&ctable[i], init_caps[i], prev);
Expand Down
46 changes: 21 additions & 25 deletions kernel/src/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@
.globl _start
.type _start, @function
_start:
/* Load gloabl pointer and stack pointer */
/* Load global pointer */
ld_gp
ld_sp t1

/* If hartid != MIN_HARTID, then jump to wait. */
csrr t0,mhartid
li t1,S3K_MIN_HART
li t2,S3K_MAX_HART
bltu t0,t1,__hang
bgtu t0,t2,__hang

/* Set some CSRs to 0 */
csrw mstatus,0
csrw medeleg,0
Expand All @@ -29,7 +36,6 @@ _start:
la t0,trap_entry
csrw mtvec,t0

/* If hartid != MIN_HARTID, then jump to wait. */
csrr t0,mhartid
li t1,S3K_MIN_HART
bne t0,t1,wait
Expand All @@ -44,31 +50,14 @@ zero_bss: /* write zeros to the bss section */

call kernel_init

wake: /* Wake harts MIN_HARTID .. MAX_HARTID. */
/* Wake using software interrupt */
la t0,_clint
addi t1,t0, (S3K_MAX_HART * 4)
addi t0,t0, (S3K_MIN_HART * 4)
li t2,1
1: sw t2,0(t0)
addi t0,t0,4
bne t1,t0,1b
la t0,kernel_ready
li t1,1
sw t1,(t0)

wait: /* Wait for initilization to finish. */
/* Wait on software interrupt */
csrw mie,MIE_MSIE
wfi
csrr t0,mip
andi t0,t0, MIP_MSIP
beqz t0,wait

/* Disable software interrupt. */
csrw mie,0
la t0,_clint
csrr t1,mhartid
slli t1,t1,2
add t0,t0,t1
sw x0,(t0)
la t0,kernel_ready
lw t0,(t0)
beqz t0,wait

head_exit:
/* Enable counter for instrumentation */
Expand All @@ -81,3 +70,10 @@ head_exit:
/* Start user processes. */
li a0,0
tail sched

__hang:
j __hang

.section .data
kernel_ready:
.word 0
4 changes: 2 additions & 2 deletions kernel/src/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

#include "cap_table.h"
#include "csr.h"
#include "drivers/uart.h"
#include "kassert.h"
#include "mcslock.h"
#include "proc.h"
#include "sched.h"
#include "uart.h"

static mcslock_t lock;
static uint64_t wcet;
Expand All @@ -18,7 +18,7 @@ void kernel_init(void)
ctable_init();
sched_init();
proc_init();
uart_puts("kernel initialized");
uart_write("kernel initialized\n", 128);
}

uint64_t kernel_wcet(void)
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include "cap_pmp.h"
#include "csr.h"
#include "drivers/timer.h"
#include "kassert.h"
#include "time.h"

static proc_t _processes[S3K_PROC_CNT];
extern unsigned char _payload[];
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
#include "sched.h"

#include "csr.h"
#include "drivers/timer.h"
#include "kassert.h"
#include "kernel.h"
#include "proc.h"
#include "semaphore.h"
#include "time.h"
#include "trap.h"
#include "wfi.h"

Expand Down
Loading

0 comments on commit 7b6f4e2

Please sign in to comment.