am,riscv,mpe: support basic MPE for xs-dualcore

* add two extra APIs for mpe: _mpe_setncpu & _mpe_wakeup
* implement all mpe APIs
* add new linker scripts and start assembly
This commit is contained in:
wangkaifan 2022-04-21 19:31:31 +08:00
parent e3e3f4d37f
commit e35b4eadff
8 changed files with 179 additions and 4 deletions

View File

@ -0,0 +1,37 @@
include $(AM_HOME)/am/arch/isa/riscv64.mk
AM_SRCS := noop/isa/riscv/trm.c \
nemu/common/mainargs.S \
noop/isa/riscv/perf.c \
noop/common/uartlite.c \
nemu/isa/riscv/cte.c \
nemu/isa/riscv/trap.S \
nemu/isa/riscv/cte64.c \
nemu/isa/riscv/mtime.S \
nemu/isa/riscv/vme.c \
nemu/common/ioe.c \
noop/common/input.c \
noop/common/timer.c \
nemu/common/video.c \
dummy/audio.c \
noop/isa/riscv/instr.c \
xs/isa/riscv/mpe.c \
xs/isa/riscv/boot/start_dual.S
CFLAGS += -I$(AM_HOME)/am/src/nemu/include -I$(AM_HOME)/am/src/xs/include -DISA_H=\"riscv.h\"
ASFLAGS += -DMAINARGS=\"$(mainargs)\"
.PHONY: $(AM_HOME)/am/src/nemu/common/mainargs.S
LDFLAGS += -L $(AM_HOME)/am/src/xs/ldscript
LDFLAGS += -T $(AM_HOME)/am/src/nemu/isa/riscv/boot/loader64.ld
image:
@echo + LD "->" $(BINARY_REL).elf
@$(LD) $(LDFLAGS) --gc-sections -o $(BINARY).elf --start-group $(LINK_FILES) --end-group
@$(OBJDUMP) -d $(BINARY).elf > $(BINARY).txt
@echo + OBJCOPY "->" $(BINARY_REL).bin
@$(OBJCOPY) -S --set-section-flags .bss=alloc,contents -O binary $(BINARY).elf $(BINARY).bin
run:
$(MAKE) -C $(NOOP_HOME) emu-run IMAGE="$(BINARY).bin" DATAWIDTH=64

View File

@ -0,0 +1,29 @@
#ifndef __ARCH_H__
#include "riscv64-nemu.h"
#define MAP(c, f) c(f)
#define COUNTERS(f) \
f(cycle) f(time) f(instr)
#define CNT_IDX(cnt) PERFCNT_##cnt
#define CNT_ENUM_ITEM(cnt) CNT_IDX(cnt),
enum {
MAP(COUNTERS, CNT_ENUM_ITEM)
NR_PERFCNT,
};
typedef struct {
union {
struct { uint32_t lo, hi; };
int64_t val;
} cnts[NR_PERFCNT];
} PerfCntSet;
void __am_perfcnt_read(PerfCntSet *t);
void __am_perfcnt_sub(PerfCntSet *res, PerfCntSet *t1, PerfCntSet *t0);
void __am_perfcnt_add(PerfCntSet *res, PerfCntSet *t1, PerfCntSet *t0);
void __am_perfcnt_show(PerfCntSet *t);
void __am_perfcnt_excel(PerfCntSet *t);
#endif

View File

@ -42,6 +42,8 @@ enum { MODE_U = 0, MODE_S, MODE_H, MODE_M };
#define PTW_SV39 ((ptw_config) { .ptw_level = 3, .vpn_width = 9 })
#define PTW_SV48 ((ptw_config) { .ptw_level = 4, .vpn_width = 9 })
#define MAX_CPU 2
#endif
#endif

View File

@ -4,8 +4,11 @@
#include <am.h>
#include <xsextra.h>
#include <klib-macros.h>
#include <klib.h>
#include ISA_H // "x86.h", "mips32.h", ...
extern int __am_ncpu;
#endif

View File

@ -0,0 +1,23 @@
.section entry, "ax"
.globl _start
.type _start, @function
#define MSTATUS_FS 0x00006000
_start:
mv s0, zero
li a0, MSTATUS_FS & (MSTATUS_FS >> 1)
csrs mstatus, a0
csrwi fcsr, 0
#define STKSHIFT 17 // 128KB for each stack && TLS
csrr a0, mhartid
la tp, _stack_top
add sp, a0, 1
sll sp, sp, STKSHIFT
add sp, sp, tp
sll a2, a0, STKSHIFT
add tp, tp, a2
jal _trm_init

View File

@ -1,19 +1,49 @@
#include <xs.h>
int __am_ncpu = 1; // One core by default
void _mpe_setncpu(char arg) {
__am_ncpu = arg ? atoi(&arg) : 1;
assert(0 < __am_ncpu && __am_ncpu <= MAX_CPU);
}
void _mpe_wakeup(int cpu) {
assert(cpu == 1);
uint64_t release_addr = 0x39001008; // Hardware defined
uint64_t release_val = 0;
asm volatile(
"sd %0, (%1);" : : "r"(release_val), "r"(release_addr)
);
return;
}
int _mpe_init(void (*entry)()) {
return 1;
// TODO: init TLS
entry();
return 0;
}
int _ncpu() {
return 1;
return __am_ncpu;
}
int _cpu() {
return 0;
intptr_t result;
asm volatile(
"csrr %0, mhartid;"
: "=r"(result)
);
return result;
}
intptr_t _atomic_xchg(volatile intptr_t *addr, intptr_t newval) {
return 0;
intptr_t result;
asm volatile(
"amoswap.d %0, %1, (%2);"
: "=r"(result)
: "r"(newval), "r"(addr)
);
return result;
}
intptr_t _atomic_add(volatile intptr_t *addr, intptr_t adder) {

View File

@ -0,0 +1,49 @@
ENTRY(_start)
SECTIONS {
. = ORIGIN(ram);
.text : {
*(entry)
*(.text)
}
etext = .;
_etext = .;
.rodata : {
*(.rodata*)
}
.data : {
*(.data)
}
edata = .;
_data = .;
.bss : {
_bss_start = .;
*(.bss*)
*(.sbss*)
*(.scommon)
}
/* stack && TLS, 128KB each */
_stack_top = ALIGN(0x1000);
. = _stack_top + 0x40000;
_stack_pointer = .;
/* thread-local data segment */
.tdata :
{
_tdata_begin = .;
*(.tdata)
_tdata_end = .;
}
.tbss :
{
*(.tbss)
_tbss_end = .;
}
end = .;
_end = .;
_heap_start = ALIGN(0x1000);
_pmem_start = pmem_base;
_pmem_end = _pmem_start + LENGTH(ram);
}

View File

@ -14,6 +14,8 @@ extern "C" {
#endif
// ================= Supplement MPE =================
void _mpe_setncpu(char arg);
void _mpe_wakeup(int cpu);
intptr_t _atomic_add(volatile intptr_t *addr, intptr_t adder);
#ifdef __cplusplus