Compare commits
16 commits
435b712f25
...
cea6d7505f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cea6d7505f | ||
|
|
65d7cfe584 | ||
|
|
2223a42488 | ||
|
|
8d8ad077ce | ||
|
|
f6e543b64d | ||
|
|
cc24fb66eb | ||
|
|
795cf84a07 | ||
|
|
1ed4b57882 | ||
|
|
f4342ab221 | ||
|
|
802ac9c012 | ||
|
|
0dbb13fea0 | ||
|
|
6c3d50b6a5 | ||
|
|
6a2c1f4ea9 | ||
|
|
2fd62c52b4 | ||
|
|
9d6c9a8bc5 | ||
|
|
111d41d610 |
10 changed files with 173 additions and 8 deletions
5
Makefile
5
Makefile
|
|
@ -28,6 +28,7 @@ LDFLAGS += -m elf64lriscv
|
||||||
|
|
||||||
CFLAGS = -Wall -Werror -O
|
CFLAGS = -Wall -Werror -O
|
||||||
CFLAGS += -Wno-unused-result
|
CFLAGS += -Wno-unused-result
|
||||||
|
CFLAGS += -Wno-unused-variable
|
||||||
CFLAGS += -mcmodel=medany
|
CFLAGS += -mcmodel=medany
|
||||||
CFLAGS += -march=rv64gc -mabi=lp64
|
CFLAGS += -march=rv64gc -mabi=lp64
|
||||||
CFLAGS += -ffreestanding
|
CFLAGS += -ffreestanding
|
||||||
|
|
@ -55,6 +56,7 @@ quickstart:
|
||||||
KERNEL_OBJ := \
|
KERNEL_OBJ := \
|
||||||
kern/entry.o \
|
kern/entry.o \
|
||||||
kern/start.o \
|
kern/start.o \
|
||||||
|
kern/rtc.o \
|
||||||
kern/libkern/freelist.o \
|
kern/libkern/freelist.o \
|
||||||
kern/libkern/string.o \
|
kern/libkern/string.o \
|
||||||
kern/libkern/proc.o \
|
kern/libkern/proc.o \
|
||||||
|
|
@ -65,7 +67,8 @@ KERNEL_OBJ := \
|
||||||
kern/libkern/mini-printf.o \
|
kern/libkern/mini-printf.o \
|
||||||
kern/libkern/stdio.o \
|
kern/libkern/stdio.o \
|
||||||
kern/libkern/buddy.o \
|
kern/libkern/buddy.o \
|
||||||
kern/libkern/badrand.o
|
kern/libkern/badrand.o \
|
||||||
|
kern/libkern/hexdump.o
|
||||||
|
|
||||||
kern/kernel.elf: $(KERNEL_OBJ)
|
kern/kernel.elf: $(KERNEL_OBJ)
|
||||||
@echo LD $@
|
@echo LD $@
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "badrand.h"
|
#include "badrand.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define PRAND_BUILD_SEED \
|
#define PRAND_BUILD_SEED \
|
||||||
((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \
|
((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \
|
||||||
|
|
@ -24,7 +25,23 @@ uint64_t badrand_range(uint64_t min, uint64_t max) {
|
||||||
return min + (x % range);
|
return min + (x % range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sbadprand(uint64_t s) {
|
void badrand_buf(char *buf, size_t len) {
|
||||||
|
unsigned char *p = (unsigned char *)buf;
|
||||||
|
|
||||||
|
while (len >= 8) {
|
||||||
|
uint64_t r = badrand();
|
||||||
|
memcpy(p, &r, 8);
|
||||||
|
p += 8;
|
||||||
|
len -= 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
uint64_t r = badrand();
|
||||||
|
memcpy(p, &r, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sbadrand(uint64_t s) {
|
||||||
if (s) {
|
if (s) {
|
||||||
seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2);
|
seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -40,4 +40,9 @@ uint64_t badrand();
|
||||||
*/
|
*/
|
||||||
uint64_t badrand_range(uint64_t min, uint64_t max);
|
uint64_t badrand_range(uint64_t min, uint64_t max);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Fills buffer with random data
|
||||||
|
*/
|
||||||
|
void badrand_buf(char *buf, size_t len);
|
||||||
|
|
||||||
#endif // BADRAND_H
|
#endif // BADRAND_H
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ int buddy_free(void *ptr) {
|
||||||
block_header_t *hdr = (block_header_t *)ptr - 1;
|
block_header_t *hdr = (block_header_t *)ptr - 1;
|
||||||
int order = hdr->order;
|
int order = hdr->order;
|
||||||
|
|
||||||
assert_msg(order != MAX_ORDER, "The buddy freelist header seems to have been corrupted.");
|
assert_msg(order <= MAX_ORDER, "The buddy freelist header seems to have been corrupted.");
|
||||||
|
|
||||||
uintptr_t addr = (uintptr_t)ptr;
|
uintptr_t addr = (uintptr_t)ptr;
|
||||||
|
|
||||||
|
|
|
||||||
8
kern/libkern/ctype.h
Normal file
8
kern/libkern/ctype.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef CTYPE_H
|
||||||
|
#define CTYPE_H
|
||||||
|
|
||||||
|
static inline int isprint(int c) {
|
||||||
|
return (unsigned)c - 0x20 < 0x5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // CTYPE_H
|
||||||
34
kern/libkern/hexdump.c
Normal file
34
kern/libkern/hexdump.c
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void hexdump(const void *data, size_t size) {
|
||||||
|
const unsigned char *p = (const unsigned char *)data;
|
||||||
|
size_t i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i += 16) {
|
||||||
|
// Print offset
|
||||||
|
kprintf("%08x ", i);
|
||||||
|
|
||||||
|
// Print hex bytes
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
if (i + j < size) {
|
||||||
|
kprintf("%02X ", p[i + j]);
|
||||||
|
} else {
|
||||||
|
kprintf(" "); // padding for incomplete lines
|
||||||
|
}
|
||||||
|
if (j == 7)
|
||||||
|
kprintf(" "); // extra space in middle
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf(" |");
|
||||||
|
|
||||||
|
// Print ASCII characters
|
||||||
|
for (j = 0; j < 16 && i + j < size; j++) {
|
||||||
|
unsigned char c = p[i + j];
|
||||||
|
kprintf("%c", isprint(c) ? c : '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
kprintf("|\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
8
kern/libkern/hexdump.h
Normal file
8
kern/libkern/hexdump.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef HEXDUMP_H
|
||||||
|
#define HEXDUMP_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void hexdump(const void *data, size_t size);
|
||||||
|
|
||||||
|
#endif // HEXDUMP_H
|
||||||
51
kern/rtc.c
Normal file
51
kern/rtc.c
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define VIRT_RTC_BASE 0x0101000UL
|
||||||
|
#define VIRT_RTC_SIZE 0x1000
|
||||||
|
|
||||||
|
#define RTC_TIME_LOW 0x00
|
||||||
|
#define RTC_TIME_HIGH 0x04
|
||||||
|
#define RTC_ALARM_LOW 0x08
|
||||||
|
#define RTC_ALARM_HIGH 0x0c
|
||||||
|
|
||||||
|
#define RTC_IRQ_ENABLED 0x10
|
||||||
|
#define RTC_CLEAR_ALARM 0x14
|
||||||
|
#define RTC_ALARM_STATUS 0x18
|
||||||
|
#define RTC_CLEAR_INTERRUPT 0x1c
|
||||||
|
|
||||||
|
static inline uint32_t mmio_read32(uintptr_t addr) {
|
||||||
|
return *(volatile uint32_t *)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mmio_write32(uintptr_t addr, uint32_t value) {
|
||||||
|
*(volatile uint32_t *)addr = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rtc_read_time(void) {
|
||||||
|
uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_TIME_LOW);
|
||||||
|
uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_TIME_HIGH);
|
||||||
|
return ((uint64_t)high << 32) | low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtc_alarm_set(uint64_t ns) {
|
||||||
|
mmio_write32(VIRT_RTC_BASE + RTC_ALARM_HIGH, ns >> 32);
|
||||||
|
mmio_write32(VIRT_RTC_BASE + RTC_ALARM_LOW, ns & 0xffffffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t rtc_alarm_read(void) {
|
||||||
|
uint32_t low = mmio_read32(VIRT_RTC_BASE + RTC_ALARM_LOW);
|
||||||
|
uint32_t high = mmio_read32(VIRT_RTC_BASE + RTC_ALARM_HIGH);
|
||||||
|
return ((uint64_t)high << 32) | low;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtc_alarm_enable(void) {
|
||||||
|
mmio_write32(VIRT_RTC_BASE + RTC_IRQ_ENABLED, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rtc_alarm_disable(void) {
|
||||||
|
mmio_write32(VIRT_RTC_BASE + RTC_IRQ_ENABLED, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rtc_alarm_status(void) {
|
||||||
|
return mmio_read32(VIRT_RTC_BASE + RTC_IRQ_ENABLED);
|
||||||
|
}
|
||||||
14
kern/rtc.h
Normal file
14
kern/rtc.h
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef RTC_H
|
||||||
|
#define RTC_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
uint64_t rtc_read_time(void);
|
||||||
|
|
||||||
|
void rtc_alarm_set(uint64_t ns);
|
||||||
|
uint64_t rtc_alarm_read(void);
|
||||||
|
void rtc_alarm_enable(void);
|
||||||
|
void rtc_alarm_disable(void);
|
||||||
|
uint32_t rtc_alarm_status(void);
|
||||||
|
|
||||||
|
#endif // RTC_H
|
||||||
35
kern/start.c
35
kern/start.c
|
|
@ -1,3 +1,6 @@
|
||||||
|
#include <endian.h>
|
||||||
|
#include <badrand.h>
|
||||||
|
#include <hexdump.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <banner.h>
|
#include <banner.h>
|
||||||
#include <buddy.h>
|
#include <buddy.h>
|
||||||
|
|
@ -7,6 +10,7 @@
|
||||||
#include <panic.h>
|
#include <panic.h>
|
||||||
#include <proc.h>
|
#include <proc.h>
|
||||||
#include <riscv.h>
|
#include <riscv.h>
|
||||||
|
#include <rtc.h>
|
||||||
#include <spinlock.h>
|
#include <spinlock.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -30,8 +34,7 @@ volatile int max_hart = 0;
|
||||||
/* This is where entry.S drops us of. All cores land here */
|
/* This is where entry.S drops us of. All cores land here */
|
||||||
void start() {
|
void start() {
|
||||||
// Do this first
|
// Do this first
|
||||||
__sync_fetch_and_add(&max_hart, 1);
|
__atomic_fetch_add(&max_hart, 1, __ATOMIC_SEQ_CST);
|
||||||
__sync_synchronize();
|
|
||||||
|
|
||||||
u64 id = read_mhartid();
|
u64 id = read_mhartid();
|
||||||
|
|
||||||
|
|
@ -46,6 +49,7 @@ void start() {
|
||||||
memory_sweep(heap_start, heap_end);
|
memory_sweep(heap_start, heap_end);
|
||||||
buddy_init(heap_start, heap_end);
|
buddy_init(heap_start, heap_end);
|
||||||
spinlock_init(&sl);
|
spinlock_init(&sl);
|
||||||
|
sbadrand(rtc_read_time() ^ swap64(rtc_read_time()));
|
||||||
for (int i = 0; i < banner_len; i++) uart_putc(banner[i]);
|
for (int i = 0; i < banner_len; i++) uart_putc(banner[i]);
|
||||||
__sync_synchronize();
|
__sync_synchronize();
|
||||||
hold = 0;
|
hold = 0;
|
||||||
|
|
@ -68,16 +72,37 @@ void start() {
|
||||||
fl_init(&fl, (uintptr_t)mem, 4096, sizeof(int));
|
fl_init(&fl, (uintptr_t)mem, 4096, sizeof(int));
|
||||||
|
|
||||||
uint32_t *hello = fl_alloc(&fl);
|
uint32_t *hello = fl_alloc(&fl);
|
||||||
|
|
||||||
*hello = UINT32_MAX;
|
*hello = UINT32_MAX;
|
||||||
|
fl_free(&fl, hello);
|
||||||
|
|
||||||
int a = fl_available(&fl);
|
int a = fl_available(&fl);
|
||||||
assert_msg(fl_check(&fl) > 0, "FreeList checking failed, might be corrupt.");
|
assert_msg(fl_check(&fl) > 0, "FreeList checking failed, might be corrupt.");
|
||||||
kprintf("Available: %d\n", a);
|
kprintf("Freelist available: %d\n", a);
|
||||||
kprintf("Size: %d\n", fl.size);
|
kprintf("Freelist item size: %d\n", fl.size);
|
||||||
|
|
||||||
buddy_free(mem);
|
buddy_free(mem);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
uint64_t time = rtc_read_time();
|
||||||
|
time = rtc_read_time();
|
||||||
|
rtc_alarm_set(time + 3000000000);
|
||||||
|
uint64_t alrm = rtc_alarm_read();
|
||||||
|
assert(alrm > time);
|
||||||
|
uint32_t astatus = rtc_alarm_status();
|
||||||
|
assert(astatus == 0);
|
||||||
|
rtc_alarm_enable();
|
||||||
|
astatus = rtc_alarm_status();
|
||||||
|
assert(astatus == 1);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
uint64_t rn = badrand();
|
||||||
|
assert(rn != badrand());
|
||||||
|
}
|
||||||
|
{
|
||||||
|
char buffer[128];
|
||||||
|
badrand_buf(buffer, 128);
|
||||||
|
hexdump(buffer, 128);
|
||||||
|
}
|
||||||
|
|
||||||
kprintf("To exit qemu, press CTRL+a followed by x\n");
|
kprintf("To exit qemu, press CTRL+a followed by x\n");
|
||||||
spin_unlock(&sl);
|
spin_unlock(&sl);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue