Skip to content

Commit f33effa

Browse files
committed
ci(gem-net): test GEM NIC on RISC-V with QEMU
1 parent cf7629d commit f33effa

File tree

2 files changed

+62
-28
lines changed

2 files changed

+62
-28
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,14 +216,20 @@ jobs:
216216
if: matrix.arch == 'riscv64'
217217
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --netdev rtl8139
218218
if: matrix.arch == 'x86_64'
219+
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package httpd --features ci,hermit/dhcpv4,hermit/gem-net qemu ${{ matrix.flags }} --netdev gem-net
220+
if: matrix.arch == 'riscv64'
219221
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci
220222
if: matrix.arch != 'riscv64'
221223
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --netdev rtl8139
222224
if: matrix.arch == 'x86_64'
225+
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package testudp --features hermit/udp,hermit/dhcpv4,hermit/gem-net qemu ${{ matrix.flags }} --netdev gem-net
226+
if: matrix.arch == 'riscv64'
223227
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci
224228
if: matrix.arch != 'riscv64'
225229
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --netdev rtl8139
226230
if: matrix.arch == 'x86_64'
231+
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package miotcp --features hermit/dhcpv4,hermit/gem-net qemu ${{ matrix.flags }} --netdev gem-net
232+
if: matrix.arch == 'riscv64'
227233
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4 qemu ${{ matrix.flags }} --netdev virtio-net-pci
228234
if: matrix.arch != 'riscv64'
229235
- run: cargo xtask ci rs --arch ${{ matrix.arch }} --profile ${{ matrix.profile }} --package poll --features hermit/dhcpv4,hermit/rtl8139 qemu ${{ matrix.flags }} --netdev rtl8139

xtask/src/ci/qemu.rs

Lines changed: 56 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub enum NetworkDevice {
5151
VirtioNetPci,
5252
VirtioNetMmio,
5353
Rtl8139,
54+
GEMNet,
5455
}
5556

5657
impl Qemu {
@@ -70,13 +71,19 @@ impl Qemu {
7071
let arg = self.sudo.then_some(qemu.as_str());
7172
let memory = self.memory(image_name, arch, small);
7273

74+
// GEM requires sifive_u, which in turn requires an SMP of at least 2.
75+
let effective_smp = match self.netdev {
76+
Some(NetworkDevice::GEMNet) => usize::max(smp, 2),
77+
_ => smp,
78+
};
79+
7380
let qemu = cmd!(sh, "{program} {arg...}")
7481
.args(&["-display", "none"])
7582
.args(&["-serial", "stdio"])
7683
.args(self.image_args(image, arch)?)
7784
.args(self.machine_args(arch))
7885
.args(self.cpu_args(arch))
79-
.args(&["-smp", &smp.to_string()])
86+
.args(&["-smp", &effective_smp.to_string()])
8087
.args(&["-m".to_string(), format!("{memory}M")])
8188
.args(&["-global", "virtio-mmio.force-legacy=off"])
8289
.args(self.netdev_args())
@@ -196,9 +203,14 @@ impl Qemu {
196203
} else if arch == Arch::Aarch64 {
197204
vec!["-machine".to_string(), "virt,gic-version=3".to_string()]
198205
} else if arch == Arch::Riscv64 {
206+
// GEM requires sifive_u
207+
let machine = match self.netdev {
208+
Some(NetworkDevice::GEMNet) => "sifive_u",
209+
_ => "virt",
210+
};
199211
vec![
200212
"-machine".to_string(),
201-
"virt".to_string(),
213+
machine.to_string(),
202214
"-bios".to_string(),
203215
"opensbi-1.6-rv-bin/share/opensbi/lp64/generic/firmware/fw_jump.bin".to_string(),
204216
]
@@ -240,7 +252,12 @@ impl Qemu {
240252
if self.accel {
241253
todo!()
242254
} else {
243-
vec!["-cpu".to_string(), "rv64".to_string()]
255+
match self.netdev {
256+
// GEM does not seem to work with rv64 as the CPU,
257+
// possibly because it requires sifive_u as the machine.
258+
Some(NetworkDevice::GEMNet) => vec![],
259+
_ => vec!["-cpu".to_string(), "rv64".to_string()],
260+
}
244261
}
245262
}
246263
}
@@ -265,34 +282,45 @@ impl Qemu {
265282
}
266283

267284
fn netdev_args(&self) -> Vec<String> {
268-
let Some(netdev) = self.netdev else {
269-
return vec![];
270-
};
285+
const NETDEV_OPTIONS: &str = "user,id=u1,hostfwd=tcp::9975-:9975,hostfwd=udp::9975-:9975,net=192.168.76.0/24,dhcpstart=192.168.76.9";
286+
match self.netdev {
287+
Some(NetworkDevice::GEMNet) => {
288+
vec![
289+
"-nic".to_string(),
290+
format!("{NETDEV_OPTIONS},model=cadence_gem"),
291+
]
292+
}
293+
Some(netdev) => {
294+
let mut netdev_args = vec![
295+
"-netdev".to_string(),
296+
NETDEV_OPTIONS.to_string(),
297+
"-device".to_string(),
298+
];
299+
300+
let mut device_arg = match netdev {
301+
NetworkDevice::VirtioNetPci => "virtio-net-pci,netdev=u1,disable-legacy=on",
302+
NetworkDevice::VirtioNetMmio => "virtio-net-device,netdev=u1",
303+
NetworkDevice::Rtl8139 => "rtl8139,netdev=u1",
304+
NetworkDevice::GEMNet => {
305+
unreachable!("We should have already checked for GEM earlier.")
306+
}
307+
}
308+
.to_string();
309+
310+
if !self.no_default_virtio_features
311+
&& matches!(
312+
netdev,
313+
NetworkDevice::VirtioNetPci | NetworkDevice::VirtioNetMmio
314+
) {
315+
device_arg.push_str(",packed=on,mq=on");
316+
}
271317

272-
let mut netdev_args = vec![
273-
"-netdev".to_string(),
274-
"user,id=u1,hostfwd=tcp::9975-:9975,hostfwd=udp::9975-:9975,net=192.168.76.0/24,dhcpstart=192.168.76.9".to_string(),
275-
"-device".to_string(),
276-
];
318+
netdev_args.push(device_arg);
277319

278-
let mut device_arg = match netdev {
279-
NetworkDevice::VirtioNetPci => "virtio-net-pci,netdev=u1,disable-legacy=on",
280-
NetworkDevice::VirtioNetMmio => "virtio-net-device,netdev=u1",
281-
NetworkDevice::Rtl8139 => "rtl8139,netdev=u1",
282-
}
283-
.to_string();
284-
285-
if !self.no_default_virtio_features
286-
&& matches!(
287-
netdev,
288-
NetworkDevice::VirtioNetPci | NetworkDevice::VirtioNetMmio
289-
) {
290-
device_arg.push_str(",packed=on,mq=on");
320+
netdev_args
321+
}
322+
None => vec![],
291323
}
292-
293-
netdev_args.push(device_arg);
294-
295-
netdev_args
296324
}
297325

298326
fn virtiofsd_args(&self, memory: usize) -> Vec<String> {

0 commit comments

Comments
 (0)