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