Skip to content

Commit bff923d

Browse files
committed
Preliminary SMP support
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.
1 parent c370e33 commit bff923d

15 files changed

+493
-228
lines changed

Makefile

+8-2
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ DTC ?= dtc
6868
# Reference: https://stackoverflow.com/questions/40886386
6969
E :=
7070
S := $E $E
71-
minimal.dtb: minimal.dts
71+
72+
SMP ?= 1
73+
.PHONY: minimal.dtsi
74+
minimal.dtsi:
75+
$(Q)python3 scripts/dtsi-gen.py $@ $(SMP)
76+
77+
minimal.dtb: minimal.dts minimal.dtsi
7278
$(VECHO) " DTC\t$@\n"
7379
$(Q)$(CC) -nostdinc -E -P -x assembler-with-cpp -undef \
7480
$(subst ^,$S,$(filter -D^SEMU_FEATURE_%, $(subst -D$(S)SEMU_FEATURE,-D^SEMU_FEATURE,$(CFLAGS)))) $< \
@@ -83,7 +89,7 @@ ext4.img:
8389

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

8894
build-image:
8995
scripts/build-image.sh

clint.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include "riscv.h"
44
#include "riscv_private.h"
55

6-
void clint_update_interrupts(vm_t *hart, clint_state_t *clint)
6+
void clint_update_interrupts(hart_t *hart, clint_state_t *clint)
77
{
88
if (clint->mtime > clint->mtimecmp[hart->mhartid])
99
hart->sip |= RV_INT_STI_BIT;
@@ -63,25 +63,25 @@ static bool clint_reg_write(clint_state_t *clint, uint32_t addr, uint32_t value)
6363
return false;
6464
}
6565

66-
void clint_read(vm_t *hart,
66+
void clint_read(hart_t *vm,
6767
clint_state_t *clint,
6868
uint32_t addr,
6969
uint8_t width,
7070
uint32_t *value)
7171
{
7272
if (!clint_reg_read(clint, addr, value))
73-
vm_set_exception(hart, RV_EXC_LOAD_FAULT, hart->exc_val);
73+
vm_set_exception(vm, RV_EXC_LOAD_FAULT, vm->exc_val);
7474
*value = (*value) >> (RV_MEM_SW - width);
7575
return;
7676
}
7777

78-
void clint_write(vm_t *hart,
78+
void clint_write(hart_t *vm,
7979
clint_state_t *clint,
8080
uint32_t addr,
8181
uint8_t width,
8282
uint32_t value)
8383
{
8484
if (!clint_reg_write(clint, addr, value >> (RV_MEM_SW - width)))
85-
vm_set_exception(hart, RV_EXC_STORE_FAULT, hart->exc_val);
85+
vm_set_exception(vm, RV_EXC_STORE_FAULT, vm->exc_val);
8686
return;
87-
}
87+
}

configs/linux.config

+1-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ CONFIG_ARCH_RV32I=y
223223
# CONFIG_CMODEL_MEDLOW is not set
224224
CONFIG_CMODEL_MEDANY=y
225225
CONFIG_MODULE_SECTIONS=y
226-
# CONFIG_SMP is not set
226+
CONFIG_SMP=y
227227
CONFIG_TUNE_GENERIC=y
228228
# CONFIG_RISCV_ISA_C is not set
229229
CONFIG_TOOLCHAIN_HAS_ZICBOM=y

device.h

+14-15
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
#define DTB_SIZE (1 * 1024 * 1024)
1010
#define INITRD_SIZE (8 * 1024 * 1024)
1111

12-
void ram_read(vm_t *core,
12+
void ram_read(hart_t *core,
1313
uint32_t *mem,
1414
const uint32_t addr,
1515
const uint8_t width,
1616
uint32_t *value);
1717

18-
void ram_write(vm_t *core,
18+
void ram_write(hart_t *core,
1919
uint32_t *mem,
2020
const uint32_t addr,
2121
const uint8_t width,
@@ -31,13 +31,13 @@ typedef struct {
3131
uint32_t active;
3232
} plic_state_t;
3333

34-
void plic_update_interrupts(vm_t *core, plic_state_t *plic);
35-
void plic_read(vm_t *core,
34+
void plic_update_interrupts(vm_t *vm, plic_state_t *plic);
35+
void plic_read(hart_t *core,
3636
plic_state_t *plic,
3737
uint32_t addr,
3838
uint8_t width,
3939
uint32_t *value);
40-
void plic_write(vm_t *core,
40+
void plic_write(hart_t *core,
4141
plic_state_t *plic,
4242
uint32_t addr,
4343
uint8_t width,
@@ -60,12 +60,12 @@ typedef struct {
6060
} u8250_state_t;
6161

6262
void u8250_update_interrupts(u8250_state_t *uart);
63-
void u8250_read(vm_t *core,
63+
void u8250_read(hart_t *core,
6464
u8250_state_t *uart,
6565
uint32_t addr,
6666
uint8_t width,
6767
uint32_t *value);
68-
void u8250_write(vm_t *core,
68+
void u8250_write(hart_t *core,
6969
u8250_state_t *uart,
7070
uint32_t addr,
7171
uint8_t width,
@@ -107,12 +107,12 @@ typedef struct {
107107
void *priv;
108108
} virtio_net_state_t;
109109

110-
void virtio_net_read(vm_t *core,
110+
void virtio_net_read(hart_t *core,
111111
virtio_net_state_t *vnet,
112112
uint32_t addr,
113113
uint8_t width,
114114
uint32_t *value);
115-
void virtio_net_write(vm_t *core,
115+
void virtio_net_write(hart_t *core,
116116
virtio_net_state_t *vnet,
117117
uint32_t addr,
118118
uint8_t width,
@@ -156,13 +156,13 @@ typedef struct {
156156
void *priv;
157157
} virtio_blk_state_t;
158158

159-
void virtio_blk_read(vm_t *vm,
159+
void virtio_blk_read(hart_t *vm,
160160
virtio_blk_state_t *vblk,
161161
uint32_t addr,
162162
uint8_t width,
163163
uint32_t *value);
164164

165-
void virtio_blk_write(vm_t *vm,
165+
void virtio_blk_write(hart_t *vm,
166166
virtio_blk_state_t *vblk,
167167
uint32_t addr,
168168
uint8_t width,
@@ -178,14 +178,13 @@ typedef struct {
178178
uint64_t mtime;
179179
} clint_state_t;
180180

181-
void clint_update_interrupts(vm_t *vm, clint_state_t *clint);
182-
void clint_read(vm_t *vm,
181+
void clint_update_interrupts(hart_t *vm, clint_state_t *clint);
182+
void clint_read(hart_t *vm,
183183
clint_state_t *clint,
184184
uint32_t addr,
185185
uint8_t width,
186186
uint32_t *value);
187-
188-
void clint_write(vm_t *vm,
187+
void clint_write(hart_t *vm,
189188
clint_state_t *clint,
190189
uint32_t addr,
191190
uint8_t width,

0 commit comments

Comments
 (0)