diff --git a/common/inc/altc/init.h b/common/inc/altc/init.h index 9724cf08..89e1e5e5 100644 --- a/common/inc/altc/init.h +++ b/common/inc/altc/init.h @@ -1,3 +1,3 @@ #pragma once -void alt_init(void); +void alt_init(uint64_t freq, uint64_t baud); diff --git a/common/inc/drivers/uart.h b/common/inc/drivers/uart.h index b449b472..c26ce3ba 100644 --- a/common/inc/drivers/uart.h +++ b/common/inc/drivers/uart.h @@ -1,7 +1,9 @@ #pragma once +#include + /* Initializes UART */ -void uart_init(void *base); +void uart_init(void *base, uint64_t freq, uint64_t baud); /* Puts one character in UART */ int uart_putc(void *base, char c); diff --git a/common/inc/plat/cheshire.h b/common/inc/plat/cheshire.h new file mode 100644 index 00000000..4bba9090 --- /dev/null +++ b/common/inc/plat/cheshire.h @@ -0,0 +1,40 @@ +/** + * Platform configuration for QEMU virt + */ +#pragma once + +#define UART_CHESHIRE +#define UART0_BASE_ADDR (0x03002000ull) + +#define MTIME_BASE_ADDR 0x0204bff8ull +#define MTIMECMP_BASE_ADDR 0x02044000ull + +// Min and max usable hart ID. +#define S3K_MIN_HART 0 +#define S3K_MAX_HART 1 + +// Total number of usable harts. +#define S3K_HART_CNT (S3K_MAX_HART - S3K_MIN_HART + 1ul) + +// Number of PMP slots. +#define S3K_PMP_CNT 8 + +// RTC ticks per second +#define S3K_RTC_HZ 1000000ull + +/// Stack size of 1024 KiB +#define S3K_LOG_STACK_SIZE 10 + +#define INIT_CAPS \ + { \ + [0] = cap_mk_pmp(0x20005fff, MEM_RWX), \ + [1] = cap_mk_memory(0x80020000, 0x80100000, MEM_RWX), \ + [2] = cap_mk_memory(0x03002000, 0x03003000, MEM_RW), \ + [3] = cap_mk_memory(0x0204b000, 0x0204c000, MEM_R), \ + [4] = cap_mk_time(0, 0, S3K_SLOT_CNT), \ + [5] = cap_mk_time(1, 0, S3K_SLOT_CNT), \ + [6] = cap_mk_time(2, 0, S3K_SLOT_CNT), \ + [7] = cap_mk_time(3, 0, S3K_SLOT_CNT), \ + [8] = cap_mk_monitor(0, S3K_PROC_CNT), \ + [9] = cap_mk_channel(0, S3K_CHAN_CNT), \ + } diff --git a/common/inc/plat/config.h b/common/inc/plat/config.h index de488f0b..3b726139 100644 --- a/common/inc/plat/config.h +++ b/common/inc/plat/config.h @@ -8,6 +8,8 @@ #include "plat/sifive_unleashed.h" #elif defined(PLATFORM_sifive_unleashed4) #include "plat/sifive_unleashed4.h" +#elif defined(PLATFORM_cheshire) +#include "plat/cheshire.h" #else #error "Unsupported platform or platform not found" #endif diff --git a/common/plat/cheshire.mk b/common/plat/cheshire.mk new file mode 100644 index 00000000..9c970202 --- /dev/null +++ b/common/plat/cheshire.mk @@ -0,0 +1,9 @@ +export ARCH=rv64imac_zicsr +export ABI=lp64 +export CMODEL=medany +export QEMU_MACHINE=none +export QEMU_SMP=none +export COMMON_INC:=${ROOT}/common/inc +export COMMON_LIB:=${ROOT}/common/build/${PLATFORM} +export STARTFILES:=${ROOT}/common/build/${PLATFORM}/start +PLAT_SRCS=src/drivers/uart/cheshire.c src/drivers/time.c diff --git a/common/src/altc/init.c b/common/src/altc/init.c index 9a95600d..9ac9390c 100644 --- a/common/src/altc/init.c +++ b/common/src/altc/init.c @@ -2,7 +2,7 @@ #include "drivers/uart.h" #include "plat/config.h" -void alt_init(void) +void alt_init(uint64_t freq, uint64_t baud) { - uart_init((void *)UART0_BASE_ADDR); + uart_init((void *)UART0_BASE_ADDR, freq, baud); } diff --git a/common/src/drivers/uart/cheshire.c b/common/src/drivers/uart/cheshire.c new file mode 100644 index 00000000..5b4eec72 --- /dev/null +++ b/common/src/drivers/uart/cheshire.c @@ -0,0 +1,49 @@ +#include + +struct uart { + union { + uint32_t rbr; + uint32_t thr; + uint32_t dlab_lsb; + }; + union { + uint32_t interrupt_enable; + uint32_t dlab_msb; + }; + uint32_t interrupt_ident; + uint32_t fifo_control; + uint32_t line_control; + uint32_t modem_control; + uint32_t line_status; + uint32_t modem_status; +}; + +void uart_init(void *base, uint64_t freq, uint64_t baud) +{ + volatile struct uart *uart = base; + uint64_t divisor = freq / (baud << 4); + uint8_t dlo = (uint8_t)(divisor); + uint8_t dhi = (uint8_t)(divisor >> 8); + *((char*)&uart->interrupt_enable) = 0x00; + *((char*)&uart->line_control) = 0x80; + *((char*)&uart->dlab_lsb) = dlo; + *((char*)&uart->dlab_msb) = dhi; + *((char*)&uart->line_control) = 0x03; + *((char*)&uart->fifo_control) = 0xC7; + *((char*)&uart->modem_control) = 0x20; +} + +int uart_putc(void *base, char c) +{ + volatile struct uart *uart = base; + while (!(uart->line_status & 0x20)) + ; + uart->thr = (unsigned char)c; + return (unsigned char)c; +} + +int uart_getc(void *base) +{ + return 0; +} + diff --git a/common/src/drivers/uart/ns16550a.c b/common/src/drivers/uart/ns16550a.c index 78f8622b..6e89f99c 100644 --- a/common/src/drivers/uart/ns16550a.c +++ b/common/src/drivers/uart/ns16550a.c @@ -22,7 +22,7 @@ struct uart { char lsr; // Line status register }; -void uart_init(void *base) +void uart_init(void *base, uint64_t freq, uint64_t baud) { volatile struct uart *uart = base; uart->lcr = 0x3; diff --git a/common/src/drivers/uart/sifive.c b/common/src/drivers/uart/sifive.c index bea5516b..c2e1fcd6 100644 --- a/common/src/drivers/uart/sifive.c +++ b/common/src/drivers/uart/sifive.c @@ -21,7 +21,7 @@ struct uart { int div; // Baud rate divisor }; -void uart_init(void *base) +void uart_init(void *base, uint64_t freq, uint64_t baud) { volatile struct uart *uart = base; uart->txctrl = TXCTRL_TXEN; // Enable transmit data diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index 8b592656..77bb7062 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -16,11 +16,13 @@ uint64_t kernel_wcrt; void kernel_init(void) { alt_init(); + //alt_init(1000000, 115200); kprintf(0, "# uart initialized\n"); #ifdef SMP cap_lock_init(); kprintf(0, "# capability lock initialized\n"); #endif + mcslock_init(&lock); ctable_init(); kprintf(0, "# ctable initialized\n"); sched_init(); diff --git a/projects/hello/s3k_conf.h b/projects/hello/s3k_conf.h index f9893f28..77a41ca4 100644 --- a/projects/hello/s3k_conf.h +++ b/projects/hello/s3k_conf.h @@ -1,6 +1,5 @@ #pragma once -#define PLATFORM_VIRT #include "plat/config.h" // Number of user processes