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 += -Wno-unused-result
|
||||
CFLAGS += -Wno-unused-variable
|
||||
CFLAGS += -mcmodel=medany
|
||||
CFLAGS += -march=rv64gc -mabi=lp64
|
||||
CFLAGS += -ffreestanding
|
||||
|
|
@ -55,6 +56,7 @@ quickstart:
|
|||
KERNEL_OBJ := \
|
||||
kern/entry.o \
|
||||
kern/start.o \
|
||||
kern/rtc.o \
|
||||
kern/libkern/freelist.o \
|
||||
kern/libkern/string.o \
|
||||
kern/libkern/proc.o \
|
||||
|
|
@ -65,7 +67,8 @@ KERNEL_OBJ := \
|
|||
kern/libkern/mini-printf.o \
|
||||
kern/libkern/stdio.o \
|
||||
kern/libkern/buddy.o \
|
||||
kern/libkern/badrand.o
|
||||
kern/libkern/badrand.o \
|
||||
kern/libkern/hexdump.o
|
||||
|
||||
kern/kernel.elf: $(KERNEL_OBJ)
|
||||
@echo LD $@
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "badrand.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#define PRAND_BUILD_SEED \
|
||||
((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);
|
||||
}
|
||||
|
||||
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) {
|
||||
seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -40,4 +40,9 @@ uint64_t badrand();
|
|||
*/
|
||||
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
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ int buddy_free(void *ptr) {
|
|||
block_header_t *hdr = (block_header_t *)ptr - 1;
|
||||
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;
|
||||
|
||||
|
|
|
|||
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 <banner.h>
|
||||
#include <buddy.h>
|
||||
|
|
@ -7,6 +10,7 @@
|
|||
#include <panic.h>
|
||||
#include <proc.h>
|
||||
#include <riscv.h>
|
||||
#include <rtc.h>
|
||||
#include <spinlock.h>
|
||||
#include <stdint.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 */
|
||||
void start() {
|
||||
// Do this first
|
||||
__sync_fetch_and_add(&max_hart, 1);
|
||||
__sync_synchronize();
|
||||
__atomic_fetch_add(&max_hart, 1, __ATOMIC_SEQ_CST);
|
||||
|
||||
u64 id = read_mhartid();
|
||||
|
||||
|
|
@ -46,6 +49,7 @@ void start() {
|
|||
memory_sweep(heap_start, heap_end);
|
||||
buddy_init(heap_start, heap_end);
|
||||
spinlock_init(&sl);
|
||||
sbadrand(rtc_read_time() ^ swap64(rtc_read_time()));
|
||||
for (int i = 0; i < banner_len; i++) uart_putc(banner[i]);
|
||||
__sync_synchronize();
|
||||
hold = 0;
|
||||
|
|
@ -68,16 +72,37 @@ void start() {
|
|||
fl_init(&fl, (uintptr_t)mem, 4096, sizeof(int));
|
||||
|
||||
uint32_t *hello = fl_alloc(&fl);
|
||||
|
||||
*hello = UINT32_MAX;
|
||||
fl_free(&fl, hello);
|
||||
|
||||
int a = fl_available(&fl);
|
||||
assert_msg(fl_check(&fl) > 0, "FreeList checking failed, might be corrupt.");
|
||||
kprintf("Available: %d\n", a);
|
||||
kprintf("Size: %d\n", fl.size);
|
||||
kprintf("Freelist available: %d\n", a);
|
||||
kprintf("Freelist item size: %d\n", fl.size);
|
||||
|
||||
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");
|
||||
spin_unlock(&sl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue