Feat: Spike abstract machine.
This commit is contained in:
parent
61657035ac
commit
e7f61272cb
13 changed files with 554 additions and 0 deletions
79
src/common/am/include/am.h
Normal file
79
src/common/am/include/am.h
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#ifndef AM_H__
|
||||||
|
#define AM_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// Memory protection flags
|
||||||
|
#define MMAP_NONE 0x00000000 // no access
|
||||||
|
#define MMAP_READ 0x00000001 // can read
|
||||||
|
#define MMAP_WRITE 0x00000002 // can write
|
||||||
|
|
||||||
|
// Memory area for [@start, @end)
|
||||||
|
typedef struct {
|
||||||
|
void *start, *end;
|
||||||
|
} Area;
|
||||||
|
|
||||||
|
// Arch-dependent processor context
|
||||||
|
typedef struct Context Context;
|
||||||
|
|
||||||
|
// An event of type @event, caused by @cause of pointer @ref
|
||||||
|
typedef struct {
|
||||||
|
enum {
|
||||||
|
EVENT_NULL = 0,
|
||||||
|
EVENT_YIELD, EVENT_SYSCALL, EVENT_PAGEFAULT, EVENT_ERROR,
|
||||||
|
EVENT_IRQ_TIMER, EVENT_IRQ_IODEV,
|
||||||
|
} event;
|
||||||
|
uintptr_t cause, ref;
|
||||||
|
const char *msg;
|
||||||
|
} Event;
|
||||||
|
|
||||||
|
// A protected address space with user memory @area
|
||||||
|
// and arch-dependent @ptr
|
||||||
|
typedef struct {
|
||||||
|
int pgsize;
|
||||||
|
Area area;
|
||||||
|
void *ptr;
|
||||||
|
} AddrSpace;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------- TRM: Turing Machine -----------------------
|
||||||
|
extern Area heap;
|
||||||
|
void putch (char ch);
|
||||||
|
void halt (int code) __attribute__((__noreturn__));
|
||||||
|
|
||||||
|
// -------------------- IOE: Input/Output Devices --------------------
|
||||||
|
bool ioe_init (void);
|
||||||
|
void ioe_read (int reg, void *buf);
|
||||||
|
void ioe_write (int reg, void *buf);
|
||||||
|
#include "amdev.h"
|
||||||
|
|
||||||
|
// ---------- CTE: Interrupt Handling and Context Switching ----------
|
||||||
|
bool cte_init (Context *(*handler)(Event ev, Context *ctx));
|
||||||
|
void yield (void);
|
||||||
|
bool ienabled (void);
|
||||||
|
void iset (bool enable);
|
||||||
|
Context *kcontext (Area kstack, void (*entry)(void *), void *arg);
|
||||||
|
|
||||||
|
// ----------------------- VME: Virtual Memory -----------------------
|
||||||
|
bool vme_init (void *(*pgalloc)(int), void (*pgfree)(void *));
|
||||||
|
void protect (AddrSpace *as);
|
||||||
|
void unprotect (AddrSpace *as);
|
||||||
|
void map (AddrSpace *as, void *vaddr, void *paddr, int prot);
|
||||||
|
Context *ucontext (AddrSpace *as, Area kstack, void *entry);
|
||||||
|
|
||||||
|
// ---------------------- MPE: Multi-Processing ----------------------
|
||||||
|
bool mpe_init (void (*entry)());
|
||||||
|
int cpu_count (void);
|
||||||
|
int cpu_current (void);
|
||||||
|
int atomic_xchg (int *addr, int newval);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
74
src/common/am/include/amdev.h
Normal file
74
src/common/am/include/amdev.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#ifndef __AMDEV_H__
|
||||||
|
#define __AMDEV_H__
|
||||||
|
|
||||||
|
// **MAY SUBJECT TO CHANGE IN THE FUTURE**
|
||||||
|
|
||||||
|
#define AM_DEVREG(id, reg, perm, ...) \
|
||||||
|
enum { AM_##reg = (id) }; \
|
||||||
|
typedef struct { __VA_ARGS__; } AM_##reg##_T;
|
||||||
|
|
||||||
|
AM_DEVREG( 1, UART_CONFIG, RD, bool present);
|
||||||
|
AM_DEVREG( 2, UART_TX, WR, char data);
|
||||||
|
AM_DEVREG( 3, UART_RX, RD, char data);
|
||||||
|
AM_DEVREG( 4, TIMER_CONFIG, RD, bool present, has_rtc);
|
||||||
|
AM_DEVREG( 5, TIMER_RTC, RD, int year, month, day, hour, minute, second);
|
||||||
|
AM_DEVREG( 6, TIMER_UPTIME, RD, uint64_t us);
|
||||||
|
AM_DEVREG( 7, INPUT_CONFIG, RD, bool present);
|
||||||
|
AM_DEVREG( 8, INPUT_KEYBRD, RD, bool keydown; int keycode);
|
||||||
|
AM_DEVREG( 9, GPU_CONFIG, RD, bool present, has_accel; int width, height, vmemsz);
|
||||||
|
AM_DEVREG(10, GPU_STATUS, RD, bool ready);
|
||||||
|
AM_DEVREG(11, GPU_FBDRAW, WR, int x, y; void *pixels; int w, h; bool sync);
|
||||||
|
AM_DEVREG(12, GPU_MEMCPY, WR, uint32_t dest; void *src; int size);
|
||||||
|
AM_DEVREG(13, GPU_RENDER, WR, uint32_t root);
|
||||||
|
AM_DEVREG(14, AUDIO_CONFIG, RD, bool present; int bufsize);
|
||||||
|
AM_DEVREG(15, AUDIO_CTRL, WR, int freq, channels, samples);
|
||||||
|
AM_DEVREG(16, AUDIO_STATUS, RD, int count);
|
||||||
|
AM_DEVREG(17, AUDIO_PLAY, WR, Area buf);
|
||||||
|
AM_DEVREG(18, DISK_CONFIG, RD, bool present; int blksz, blkcnt);
|
||||||
|
AM_DEVREG(19, DISK_STATUS, RD, bool ready);
|
||||||
|
AM_DEVREG(20, DISK_BLKIO, WR, bool write; void *buf; int blkno, blkcnt);
|
||||||
|
AM_DEVREG(21, NET_CONFIG, RD, bool present);
|
||||||
|
AM_DEVREG(22, NET_STATUS, RD, int rx_len, tx_len);
|
||||||
|
AM_DEVREG(23, NET_TX, WR, Area buf);
|
||||||
|
AM_DEVREG(24, NET_RX, WR, Area buf);
|
||||||
|
|
||||||
|
// Input
|
||||||
|
|
||||||
|
#define AM_KEYS(_) \
|
||||||
|
_(ESCAPE) _(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) _(F8) _(F9) _(F10) _(F11) _(F12) \
|
||||||
|
_(GRAVE) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(0) _(MINUS) _(EQUALS) _(BACKSPACE) \
|
||||||
|
_(TAB) _(Q) _(W) _(E) _(R) _(T) _(Y) _(U) _(I) _(O) _(P) _(LEFTBRACKET) _(RIGHTBRACKET) _(BACKSLASH) \
|
||||||
|
_(CAPSLOCK) _(A) _(S) _(D) _(F) _(G) _(H) _(J) _(K) _(L) _(SEMICOLON) _(APOSTROPHE) _(RETURN) \
|
||||||
|
_(LSHIFT) _(Z) _(X) _(C) _(V) _(B) _(N) _(M) _(COMMA) _(PERIOD) _(SLASH) _(RSHIFT) \
|
||||||
|
_(LCTRL) _(APPLICATION) _(LALT) _(SPACE) _(RALT) _(RCTRL) \
|
||||||
|
_(UP) _(DOWN) _(LEFT) _(RIGHT) _(INSERT) _(DELETE) _(HOME) _(END) _(PAGEUP) _(PAGEDOWN)
|
||||||
|
|
||||||
|
#define AM_KEY_NAMES(key) AM_KEY_##key,
|
||||||
|
enum {
|
||||||
|
AM_KEY_NONE = 0,
|
||||||
|
AM_KEYS(AM_KEY_NAMES)
|
||||||
|
};
|
||||||
|
|
||||||
|
// GPU
|
||||||
|
|
||||||
|
#define AM_GPU_TEXTURE 1
|
||||||
|
#define AM_GPU_SUBTREE 2
|
||||||
|
#define AM_GPU_NULL 0xffffffff
|
||||||
|
|
||||||
|
typedef uint32_t gpuptr_t;
|
||||||
|
|
||||||
|
struct gpu_texturedesc {
|
||||||
|
uint16_t w, h;
|
||||||
|
gpuptr_t pixels;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct gpu_canvas {
|
||||||
|
uint16_t type, w, h, x1, y1, w1, h1;
|
||||||
|
gpuptr_t sibling;
|
||||||
|
union {
|
||||||
|
gpuptr_t child;
|
||||||
|
struct gpu_texturedesc texture;
|
||||||
|
};
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#endif
|
78
src/common/am/src/atomic.h
Normal file
78
src/common/am/src/atomic.h
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#ifndef _RISCV_ATOMIC_H
|
||||||
|
#define _RISCV_ATOMIC_H
|
||||||
|
|
||||||
|
//#include "config.h"
|
||||||
|
//#include "encoding.h"
|
||||||
|
|
||||||
|
// Currently, interrupts are always disabled in M-mode.
|
||||||
|
#define disable_irqsave() (0)
|
||||||
|
#define enable_irqrestore(flags) ((void) (flags))
|
||||||
|
|
||||||
|
typedef struct { int lock; } spinlock_t;
|
||||||
|
#define SPINLOCK_INIT {0}
|
||||||
|
|
||||||
|
#define mb() asm volatile ("fence" ::: "memory")
|
||||||
|
#define atomic_set(ptr, val) (*(volatile typeof(*(ptr)) *)(ptr) = val)
|
||||||
|
#define atomic_read(ptr) (*(volatile typeof(*(ptr)) *)(ptr))
|
||||||
|
|
||||||
|
#ifdef __riscv_atomic
|
||||||
|
# define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc)
|
||||||
|
# define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc)
|
||||||
|
# define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp)
|
||||||
|
# define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp)
|
||||||
|
#else
|
||||||
|
# define atomic_binop(ptr, inc, op) ({ \
|
||||||
|
long flags = disable_irqsave(); \
|
||||||
|
typeof(*(ptr)) res = atomic_read(ptr); \
|
||||||
|
atomic_set(ptr, op); \
|
||||||
|
enable_irqrestore(flags); \
|
||||||
|
res; })
|
||||||
|
# define atomic_add(ptr, inc) atomic_binop(ptr, inc, res + (inc))
|
||||||
|
# define atomic_or(ptr, inc) atomic_binop(ptr, inc, res | (inc))
|
||||||
|
# define atomic_swap(ptr, inc) atomic_binop(ptr, inc, (inc))
|
||||||
|
# define atomic_cas(ptr, cmp, swp) ({ \
|
||||||
|
long flags = disable_irqsave(); \
|
||||||
|
typeof(*(ptr)) res = *(volatile typeof(*(ptr)) *)(ptr); \
|
||||||
|
if (res == (cmp)) *(volatile typeof(ptr))(ptr) = (swp); \
|
||||||
|
enable_irqrestore(flags); \
|
||||||
|
res; })
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline int spinlock_trylock(spinlock_t* lock)
|
||||||
|
{
|
||||||
|
int res = atomic_swap(&lock->lock, -1);
|
||||||
|
mb();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void spinlock_lock(spinlock_t* lock)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (atomic_read(&lock->lock))
|
||||||
|
;
|
||||||
|
} while (spinlock_trylock(lock));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void spinlock_unlock(spinlock_t* lock)
|
||||||
|
{
|
||||||
|
mb();
|
||||||
|
atomic_set(&lock->lock,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long spinlock_lock_irqsave(spinlock_t* lock)
|
||||||
|
{
|
||||||
|
long flags = disable_irqsave();
|
||||||
|
spinlock_lock(lock);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void spinlock_unlock_irqrestore(spinlock_t* lock, long flags)
|
||||||
|
{
|
||||||
|
spinlock_unlock(lock);
|
||||||
|
enable_irqrestore(flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
19
src/common/am/src/cte.c
Normal file
19
src/common/am/src/cte.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include <am.h>
|
||||||
|
|
||||||
|
bool cte_init(Context*(*handler)(Event, Context*)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *kcontext(Area kstack, void (*entry)(void *), void *arg) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void yield() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ienabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void iset(bool enable) {
|
||||||
|
}
|
111
src/common/am/src/htif.c
Normal file
111
src/common/am/src/htif.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#include "htif.h"
|
||||||
|
#include "atomic.h"
|
||||||
|
#include <klib.h>
|
||||||
|
|
||||||
|
extern uint64_t __htif_base;
|
||||||
|
volatile uint64_t tohost __attribute__((section(".htif")));
|
||||||
|
volatile uint64_t fromhost __attribute__((section(".htif")));
|
||||||
|
volatile int htif_console_buf;
|
||||||
|
static spinlock_t htif_lock = SPINLOCK_INIT;
|
||||||
|
|
||||||
|
#define TOHOST(base_int) (uint64_t *)(base_int + TOHOST_OFFSET)
|
||||||
|
#define FROMHOST(base_int) (uint64_t *)(base_int + FROMHOST_OFFSET)
|
||||||
|
|
||||||
|
#define TOHOST_OFFSET ((uintptr_t)tohost - (uintptr_t)__htif_base)
|
||||||
|
#define FROMHOST_OFFSET ((uintptr_t)fromhost - (uintptr_t)__htif_base)
|
||||||
|
|
||||||
|
static void __check_fromhost()
|
||||||
|
{
|
||||||
|
uint64_t fh = fromhost;
|
||||||
|
if (!fh)
|
||||||
|
return;
|
||||||
|
fromhost = 0;
|
||||||
|
|
||||||
|
// this should be from the console
|
||||||
|
assert(FROMHOST_DEV(fh) == 1);
|
||||||
|
switch (FROMHOST_CMD(fh)) {
|
||||||
|
case 0:
|
||||||
|
htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __set_tohost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
|
||||||
|
{
|
||||||
|
while (tohost)
|
||||||
|
__check_fromhost();
|
||||||
|
tohost = TOHOST_CMD(dev, cmd, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int htif_console_getchar()
|
||||||
|
{
|
||||||
|
#if __riscv_xlen == 32
|
||||||
|
// HTIF devices are not supported on RV32
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
spinlock_lock(&htif_lock);
|
||||||
|
__check_fromhost();
|
||||||
|
int ch = htif_console_buf;
|
||||||
|
if (ch >= 0) {
|
||||||
|
htif_console_buf = -1;
|
||||||
|
__set_tohost(1, 0, 0);
|
||||||
|
}
|
||||||
|
spinlock_unlock(&htif_lock);
|
||||||
|
|
||||||
|
return ch - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data)
|
||||||
|
{
|
||||||
|
spinlock_lock(&htif_lock);
|
||||||
|
__set_tohost(dev, cmd, data);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
uint64_t fh = fromhost;
|
||||||
|
if (fh) {
|
||||||
|
if (FROMHOST_DEV(fh) == dev && FROMHOST_CMD(fh) == cmd) {
|
||||||
|
fromhost = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
__check_fromhost();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spinlock_unlock(&htif_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void htif_syscall(uintptr_t arg)
|
||||||
|
{
|
||||||
|
do_tohost_fromhost(0, 0, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void htif_console_putchar(uint8_t ch)
|
||||||
|
{
|
||||||
|
#if __riscv_xlen == 32
|
||||||
|
// HTIF devices are not supported on RV32, so proxy a write system call
|
||||||
|
volatile uint64_t magic_mem[8];
|
||||||
|
magic_mem[0] = SYS_write;
|
||||||
|
magic_mem[1] = 1;
|
||||||
|
magic_mem[2] = (uintptr_t)&ch;
|
||||||
|
magic_mem[3] = 1;
|
||||||
|
do_tohost_fromhost(0, 0, (uintptr_t)magic_mem);
|
||||||
|
#else
|
||||||
|
spinlock_lock(&htif_lock);
|
||||||
|
__set_tohost(1, 1, ch);
|
||||||
|
spinlock_unlock(&htif_lock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void htif_poweroff()
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
fromhost = 0;
|
||||||
|
tohost = 1;
|
||||||
|
}
|
||||||
|
}
|
24
src/common/am/src/htif.h
Normal file
24
src/common/am/src/htif.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// See LICENSE for license details.
|
||||||
|
|
||||||
|
#ifndef _RISCV_HTIF_H
|
||||||
|
#define _RISCV_HTIF_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if __riscv_xlen == 64
|
||||||
|
# define TOHOST_CMD(dev, cmd, payload) \
|
||||||
|
(((uint64_t)(dev) << 56) | ((uint64_t)(cmd) << 48) | (uint64_t)(payload))
|
||||||
|
#else
|
||||||
|
# define TOHOST_CMD(dev, cmd, payload) ({ \
|
||||||
|
if ((dev) || (cmd)) __builtin_trap(); \
|
||||||
|
(payload); })
|
||||||
|
#endif
|
||||||
|
#define FROMHOST_DEV(fromhost_value) ((uint64_t)(fromhost_value) >> 56)
|
||||||
|
#define FROMHOST_CMD(fromhost_value) ((uint64_t)(fromhost_value) << 8 >> 56)
|
||||||
|
#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16)
|
||||||
|
|
||||||
|
void htif_console_putchar(uint8_t);
|
||||||
|
int htif_console_getchar();
|
||||||
|
void htif_poweroff() __attribute__((noreturn));
|
||||||
|
|
||||||
|
#endif
|
27
src/common/am/src/ioe.c
Normal file
27
src/common/am/src/ioe.c
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <am.h>
|
||||||
|
#include <klib-macros.h>
|
||||||
|
|
||||||
|
void __am_timer_init();
|
||||||
|
void __am_timer_rtc(AM_TIMER_RTC_T *);
|
||||||
|
void __am_timer_uptime(AM_TIMER_UPTIME_T *);
|
||||||
|
|
||||||
|
static void __am_timer_config(AM_TIMER_CONFIG_T *cfg) { cfg->present = true; cfg->has_rtc = true; }
|
||||||
|
|
||||||
|
typedef void (*handler_t)(void *buf);
|
||||||
|
static void *lut[128] = {
|
||||||
|
[AM_TIMER_CONFIG] = __am_timer_config,
|
||||||
|
[AM_TIMER_RTC ] = __am_timer_rtc,
|
||||||
|
[AM_TIMER_UPTIME] = __am_timer_uptime,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void fail(void *buf) { panic("access nonexist register"); }
|
||||||
|
|
||||||
|
bool ioe_init() {
|
||||||
|
for (int i = 0; i < LENGTH(lut); i++)
|
||||||
|
if (!lut[i]) lut[i] = fail;
|
||||||
|
__am_timer_init();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ioe_read (int reg, void *buf) { ((handler_t)lut[reg])(buf); }
|
||||||
|
void ioe_write(int reg, void *buf) { ((handler_t)lut[reg])(buf); }
|
35
src/common/am/src/linker.ld
Normal file
35
src/common/am/src/linker.ld
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
. = 0x80000000;
|
||||||
|
.text : {
|
||||||
|
*(entry)
|
||||||
|
*(.text*)
|
||||||
|
}
|
||||||
|
etext = .;
|
||||||
|
_etext = .;
|
||||||
|
.rodata : {
|
||||||
|
*(.rodata*)
|
||||||
|
}
|
||||||
|
.htif : {
|
||||||
|
PROVIDE(__htif_base = . );
|
||||||
|
*(.htif)
|
||||||
|
}
|
||||||
|
.data : {
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
edata = .;
|
||||||
|
_data = .;
|
||||||
|
.bss : {
|
||||||
|
_bss_start = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(.sbss*)
|
||||||
|
*(.scommon)
|
||||||
|
}
|
||||||
|
_stack_top = ALIGN(0x1000);
|
||||||
|
. = _stack_top + 0x20000;
|
||||||
|
_stack_pointer = .;
|
||||||
|
end = .;
|
||||||
|
_end = .;
|
||||||
|
_heap_start = ALIGN(0x1000);
|
||||||
|
}
|
17
src/common/am/src/mpe.c
Normal file
17
src/common/am/src/mpe.c
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include <am.h>
|
||||||
|
|
||||||
|
bool mpe_init(void (*entry)()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_count() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpu_current() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int atomic_xchg(int *addr, int newval) {
|
||||||
|
return 0;
|
||||||
|
}
|
8
src/common/am/src/start.S
Normal file
8
src/common/am/src/start.S
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
.section entry, "ax"
|
||||||
|
.globl _start
|
||||||
|
.type _start, @function
|
||||||
|
|
||||||
|
_start:
|
||||||
|
mv s0, zero
|
||||||
|
la sp, _stack_pointer
|
||||||
|
jal _trm_init
|
30
src/common/am/src/timer.c
Normal file
30
src/common/am/src/timer.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#include <am.h>
|
||||||
|
|
||||||
|
static uint64_t boot_time = 0;
|
||||||
|
|
||||||
|
#define CLINT_MMIO 0x2000000ul
|
||||||
|
#define TIME_BASE 0xbff8
|
||||||
|
|
||||||
|
static uint64_t read_time() {
|
||||||
|
uint32_t lo = *(volatile uint32_t *)(CLINT_MMIO + TIME_BASE + 0);
|
||||||
|
uint32_t hi = *(volatile uint32_t *)(CLINT_MMIO + TIME_BASE + 4);
|
||||||
|
uint64_t time = ((uint64_t)hi << 32) | lo;
|
||||||
|
return time / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) {
|
||||||
|
uptime->us = read_time() - boot_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __am_timer_init() {
|
||||||
|
boot_time = read_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
void __am_timer_rtc(AM_TIMER_RTC_T *rtc) {
|
||||||
|
rtc->second = 0;
|
||||||
|
rtc->minute = 0;
|
||||||
|
rtc->hour = 0;
|
||||||
|
rtc->day = 0;
|
||||||
|
rtc->month = 0;
|
||||||
|
rtc->year = 1900;
|
||||||
|
}
|
34
src/common/am/src/trm.c
Normal file
34
src/common/am/src/trm.c
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#include <am.h>
|
||||||
|
#include <klib.h>
|
||||||
|
#include <klib-macros.h>
|
||||||
|
#include "htif.h"
|
||||||
|
|
||||||
|
extern char _heap_start;
|
||||||
|
int main(const char *args);
|
||||||
|
|
||||||
|
extern char _pmem_start;
|
||||||
|
#define PMEM_SIZE (128 * 1024 * 1024)
|
||||||
|
#define PMEM_END ((uintptr_t)0x80000000 + PMEM_SIZE)
|
||||||
|
|
||||||
|
Area heap = RANGE(&_heap_start, PMEM_END);
|
||||||
|
#ifndef MAINARGS
|
||||||
|
#define MAINARGS ""
|
||||||
|
#endif
|
||||||
|
static const char mainargs[] = MAINARGS;
|
||||||
|
|
||||||
|
void putch(char ch) {
|
||||||
|
htif_console_putchar(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void halt(int code) {
|
||||||
|
printf("Exit with code = %d\n", code);
|
||||||
|
htif_poweroff();
|
||||||
|
|
||||||
|
// should not reach here
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _trm_init() {
|
||||||
|
int ret = main(mainargs);
|
||||||
|
halt(ret);
|
||||||
|
}
|
18
src/common/am/src/vme.c
Normal file
18
src/common/am/src/vme.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include <am.h>
|
||||||
|
|
||||||
|
bool vme_init(void* (*pgalloc_f)(int), void (*pgfree_f)(void*)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void protect(AddrSpace *as) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void unprotect(AddrSpace *as) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void map(AddrSpace *as, void *va, void *pa, int prot) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Context *ucontext(AddrSpace *as, Area kstack, void *entry) {
|
||||||
|
return NULL;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue