Skip to content

Commit

Permalink
Preliminary SMP support
Browse files Browse the repository at this point in the history
In this commit, semu is able to simulate SMP architecture on Linux
kernel. The original `vm_t` has been changed to `hart_t`, and now
`vm_t` represents the entire virtual machine. Additionally, HSM,
RFENCE, and IPI SBI extensions have been implemented with rough
implementations.

Before simulation, we need to enable SMP support in the Linux
kernel. Please cross-compile the Linux kernel with the configuration
file located at configs/linux.config

After recompiling the Linux kernel with SMP support enabled, simply
execute `make check SMP=n`, where n means the number of hart you want to
simulate, and SMP=1 is the default setting. If you want to execute semu
by yourself, the --smp argument can be used to specify the hart to
simulate, and you are responsible for modifying the device tree.
  • Loading branch information
ranvd committed Jun 24, 2024
1 parent c370e33 commit bff923d
Show file tree
Hide file tree
Showing 15 changed files with 493 additions and 228 deletions.
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ DTC ?= dtc
# Reference: https://stackoverflow.com/questions/40886386
E :=
S := $E $E
minimal.dtb: minimal.dts

SMP ?= 1
.PHONY: minimal.dtsi
minimal.dtsi:
$(Q)python3 scripts/dtsi-gen.py $@ $(SMP)

minimal.dtb: minimal.dts minimal.dtsi
$(VECHO) " DTC\t$@\n"
$(Q)$(CC) -nostdinc -E -P -x assembler-with-cpp -undef \
$(subst ^,$S,$(filter -D^SEMU_FEATURE_%, $(subst -D$(S)SEMU_FEATURE,-D^SEMU_FEATURE,$(CFLAGS)))) $< \
Expand All @@ -83,7 +89,7 @@ ext4.img:

check: $(BIN) minimal.dtb $(KERNEL_DATA) $(INITRD_DATA) $(DISKIMG_FILE)
@$(call notice, Ready to launch Linux kernel. Please be patient.)
$(Q)./$(BIN) -k $(KERNEL_DATA) -b minimal.dtb -i $(INITRD_DATA) $(OPTS)
$(Q)./$(BIN) -k $(KERNEL_DATA) --smp $(SMP) -b minimal.dtb -i $(INITRD_DATA) $(OPTS)

build-image:
scripts/build-image.sh
Expand Down
12 changes: 6 additions & 6 deletions clint.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "riscv.h"
#include "riscv_private.h"

void clint_update_interrupts(vm_t *hart, clint_state_t *clint)
void clint_update_interrupts(hart_t *hart, clint_state_t *clint)
{
if (clint->mtime > clint->mtimecmp[hart->mhartid])
hart->sip |= RV_INT_STI_BIT;
Expand Down Expand Up @@ -63,25 +63,25 @@ static bool clint_reg_write(clint_state_t *clint, uint32_t addr, uint32_t value)
return false;
}

void clint_read(vm_t *hart,
void clint_read(hart_t *vm,
clint_state_t *clint,
uint32_t addr,
uint8_t width,
uint32_t *value)
{
if (!clint_reg_read(clint, addr, value))
vm_set_exception(hart, RV_EXC_LOAD_FAULT, hart->exc_val);
vm_set_exception(vm, RV_EXC_LOAD_FAULT, vm->exc_val);
*value = (*value) >> (RV_MEM_SW - width);
return;
}

void clint_write(vm_t *hart,
void clint_write(hart_t *vm,
clint_state_t *clint,
uint32_t addr,
uint8_t width,
uint32_t value)
{
if (!clint_reg_write(clint, addr, value >> (RV_MEM_SW - width)))
vm_set_exception(hart, RV_EXC_STORE_FAULT, hart->exc_val);
vm_set_exception(vm, RV_EXC_STORE_FAULT, vm->exc_val);
return;
}
}
2 changes: 1 addition & 1 deletion configs/linux.config
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ CONFIG_ARCH_RV32I=y
# CONFIG_CMODEL_MEDLOW is not set
CONFIG_CMODEL_MEDANY=y
CONFIG_MODULE_SECTIONS=y
# CONFIG_SMP is not set
CONFIG_SMP=y
CONFIG_TUNE_GENERIC=y
# CONFIG_RISCV_ISA_C is not set
CONFIG_TOOLCHAIN_HAS_ZICBOM=y
Expand Down
29 changes: 14 additions & 15 deletions device.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@
#define DTB_SIZE (1 * 1024 * 1024)
#define INITRD_SIZE (8 * 1024 * 1024)

void ram_read(vm_t *core,
void ram_read(hart_t *core,
uint32_t *mem,
const uint32_t addr,
const uint8_t width,
uint32_t *value);

void ram_write(vm_t *core,
void ram_write(hart_t *core,
uint32_t *mem,
const uint32_t addr,
const uint8_t width,
Expand All @@ -31,13 +31,13 @@ typedef struct {
uint32_t active;
} plic_state_t;

void plic_update_interrupts(vm_t *core, plic_state_t *plic);
void plic_read(vm_t *core,
void plic_update_interrupts(vm_t *vm, plic_state_t *plic);
void plic_read(hart_t *core,
plic_state_t *plic,
uint32_t addr,
uint8_t width,
uint32_t *value);
void plic_write(vm_t *core,
void plic_write(hart_t *core,
plic_state_t *plic,
uint32_t addr,
uint8_t width,
Expand All @@ -60,12 +60,12 @@ typedef struct {
} u8250_state_t;

void u8250_update_interrupts(u8250_state_t *uart);
void u8250_read(vm_t *core,
void u8250_read(hart_t *core,
u8250_state_t *uart,
uint32_t addr,
uint8_t width,
uint32_t *value);
void u8250_write(vm_t *core,
void u8250_write(hart_t *core,
u8250_state_t *uart,
uint32_t addr,
uint8_t width,
Expand Down Expand Up @@ -107,12 +107,12 @@ typedef struct {
void *priv;
} virtio_net_state_t;

void virtio_net_read(vm_t *core,
void virtio_net_read(hart_t *core,
virtio_net_state_t *vnet,
uint32_t addr,
uint8_t width,
uint32_t *value);
void virtio_net_write(vm_t *core,
void virtio_net_write(hart_t *core,
virtio_net_state_t *vnet,
uint32_t addr,
uint8_t width,
Expand Down Expand Up @@ -156,13 +156,13 @@ typedef struct {
void *priv;
} virtio_blk_state_t;

void virtio_blk_read(vm_t *vm,
void virtio_blk_read(hart_t *vm,
virtio_blk_state_t *vblk,
uint32_t addr,
uint8_t width,
uint32_t *value);

void virtio_blk_write(vm_t *vm,
void virtio_blk_write(hart_t *vm,
virtio_blk_state_t *vblk,
uint32_t addr,
uint8_t width,
Expand All @@ -178,14 +178,13 @@ typedef struct {
uint64_t mtime;
} clint_state_t;

void clint_update_interrupts(vm_t *vm, clint_state_t *clint);
void clint_read(vm_t *vm,
void clint_update_interrupts(hart_t *vm, clint_state_t *clint);
void clint_read(hart_t *vm,
clint_state_t *clint,
uint32_t addr,
uint8_t width,
uint32_t *value);

void clint_write(vm_t *vm,
void clint_write(hart_t *vm,
clint_state_t *clint,
uint32_t addr,
uint8_t width,
Expand Down
Loading

0 comments on commit bff923d

Please sign in to comment.