Skip to content

Commit 862cb51

Browse files
committed
Enable ALSA debug in kernel
Now gets "virtio_snd: probe of virtio2 failed with error -2" in dmesg.
1 parent ba86045 commit 862cb51

File tree

11 files changed

+707
-1
lines changed

11 files changed

+707
-1
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "cnfa"]
2+
path = cnfa
3+
url = https://github.com/cntools/cnfa

Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ OBJS_EXTRA :=
1313
# command line option
1414
OPTS :=
1515

16+
LDFLAGS :=
17+
1618
# virtio-blk
1719
ENABLE_VIRTIOBLK ?= 1
1820
$(call set-feature, VIRTIOBLK)
@@ -41,6 +43,18 @@ ifeq ($(call has, VIRTIONET), 1)
4143
OBJS_EXTRA += virtio-net.o
4244
endif
4345

46+
# virtio-snd
47+
ENABLE_VIRTIOSND ?= 1
48+
ifneq ($(UNAME_S),Linux)
49+
ENABLE_VIRTIOSND := 0
50+
endif
51+
$(call set-feature, VIRTIOSND)
52+
ifeq ($(call has, VIRTIOSND), 1)
53+
OBJS_EXTRA += virtio-snd.o
54+
LDFLAGS += -lasound
55+
CFLAGS += -Icnfa
56+
endif
57+
4458
BIN = semu
4559
all: $(BIN) minimal.dtb
4660

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,21 @@ For macOS, use the following command:
3737
$ brew install e2fsprogs
3838
```
3939

40+
For VirtIO sound support, CNFA should be installed in advance.
41+
To download CNFA, run the following command:
42+
```shell
43+
$ git submodule init
44+
```
45+
4046
## Build and Run
4147

48+
Build the dependency (CNFA):
49+
```shell
50+
$ rm cnfa/CNFA_sf.h
51+
$ make os_generic.h
52+
$ make CNFA_sf.h
53+
```
54+
4255
Build the emulator:
4356
```shell
4457
$ make

cnfa

Submodule cnfa added at 60bcddd

configs/buildroot.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ BR2_RELRO_NONE=y
3636
# BR2_RELRO_PARTIAL is not set
3737
# BR2_RELRO_FULL is not set
3838
BR2_FORTIFY_SOURCE_1=y
39+
BR2_PACKAGE_ALSA_UTILS=y
40+
BR2_PACKAGE_ALSA_UTILS_APLAY=y
41+
BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y
3942
# BR2_PACKAGE_URANDOM_SCRIPTS is not set
4043
BR2_TARGET_ROOTFS_CPIO=y
4144
BR2_TARGET_ROOTFS_CPIO_FULL=y

configs/linux.config

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,15 @@ CONFIG_DUMMY_CONSOLE_ROWS=25
936936
# end of Console display driver support
937937
# end of Graphics support
938938

939-
# CONFIG_SOUND is not set
939+
CONFIG_SOUND=y
940+
CONFIG_SND=y
941+
CONFIG_SND_VERBOSE_PRINTK=y
942+
CONFIG_SND_DEBUG=y
943+
CONFIG_SND_DEBUG_VERBOSE=y
944+
CONFIG_SND_PCM_XRUN_DEBUG=y
945+
CONFIG_SND_DUMMY=y
946+
CONFIG_SND_ALOOP=y
947+
CONFIG_SND_VIRTIO=y
940948

941949
#
942950
# HID support

device.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,52 @@ void clint_write(hart_t *vm,
190190
uint8_t width,
191191
uint32_t value);
192192

193+
#if SEMU_HAS(VIRTIOSND)
194+
195+
#define IRQ_VSND 4
196+
#define IRQ_VSND_BIT (1 << IRQ_VSND)
197+
198+
typedef struct {
199+
uint32_t QueueNum;
200+
uint32_t QueueDesc;
201+
uint32_t QueueAvail;
202+
uint32_t QueueUsed;
203+
uint16_t last_avail;
204+
bool ready;
205+
} virtio_snd_queue_t;
206+
207+
typedef struct {
208+
/* feature negotiation */
209+
uint32_t DeviceFeaturesSel;
210+
uint32_t DriverFeatures;
211+
uint32_t DriverFeaturesSel;
212+
/* queue config */
213+
uint32_t QueueSel;
214+
virtio_snd_queue_t queues[2];
215+
/* status */
216+
uint32_t Status;
217+
uint32_t InterruptStatus;
218+
/* supplied by environment */
219+
uint32_t *ram;
220+
/* implementation-specific */
221+
void *priv;
222+
} virtio_snd_state_t;
223+
224+
void virtio_snd_read(hart_t *core,
225+
virtio_snd_state_t *vsnd,
226+
uint32_t addr,
227+
uint8_t width,
228+
uint32_t *value);
229+
230+
void virtio_snd_write(hart_t *core,
231+
virtio_snd_state_t *vsnd,
232+
uint32_t addr,
233+
uint8_t width,
234+
uint32_t value);
235+
236+
bool virtio_snd_init(virtio_snd_state_t *vsnd);
237+
#endif
238+
193239
/* memory mapping */
194240

195241
typedef struct {
@@ -205,4 +251,8 @@ typedef struct {
205251
virtio_blk_state_t vblk;
206252
#endif
207253
clint_state_t clint;
254+
#if SEMU_HAS(VIRTIOSND)
255+
virtio_snd_state_t vsnd;
256+
#endif
257+
uint64_t timer;
208258
} emu_state_t;

feature.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,10 @@
1212
#define SEMU_FEATURE_VIRTIONET 1
1313
#endif
1414

15+
/* virtio-snd */
16+
#ifndef SEMU_FEATUREVIRTIOSND
17+
#define SEMU_FEATUREVIRTIOSND 1
18+
#endif
19+
1520
/* Feature test macro */
1621
#define SEMU_HAS(x) SEMU_FEATURE_##x

main.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ static void emu_update_timer_interrupt(hart_t *hart)
8181
clint_update_interrupts(hart, &data->clint);
8282
}
8383

84+
#if SEMU_HAS(VIRTIOSND)
85+
static void emu_update_vsnd_interrupts(vm_t *vm)
86+
{
87+
emu_state_t *data = PRIV(vm->hart[0]);
88+
if (data->vsnd.InterruptStatus)
89+
data->plic.active |= IRQ_VSND_BIT;
90+
else
91+
data->plic.active &= ~IRQ_VSND_BIT;
92+
plic_update_interrupts(vm, &data->plic);
93+
}
94+
#endif
95+
8496
static void mem_load(hart_t *hart,
8597
uint32_t addr,
8698
uint8_t width,
@@ -121,6 +133,13 @@ static void mem_load(hart_t *hart,
121133
clint_read(hart, &data->clint, addr & 0xFFFFF, width, value);
122134
clint_update_interrupts(hart, &data->clint);
123135
return;
136+
137+
#if SEMU_HAS(VIRTIOSND)
138+
case 0x44: /* virtio-snd */
139+
virtio_snd_read(hart, &data->vsnd, addr & 0xFFFFF, width, value);
140+
emu_update_vsnd_interrupts(hart->vm);
141+
return;
142+
#endif
124143
}
125144
}
126145
vm_set_exception(hart, RV_EXC_LOAD_FAULT, hart->exc_val);
@@ -166,6 +185,12 @@ static void mem_store(hart_t *hart,
166185
clint_write(hart, &data->clint, addr & 0xFFFFF, width, value);
167186
clint_update_interrupts(hart, &data->clint);
168187
return;
188+
#if SEMU_HAS(VIRTIOSND)
189+
case 0x44: /* virtio-snd */
190+
virtio_snd_write(hart, &data->vsnd, addr & 0xFFFFF, width, value);
191+
emu_update_vsnd_interrupts(hart->vm);
192+
return;
193+
#endif
169194
}
170195
}
171196
vm_set_exception(hart, RV_EXC_STORE_FAULT, hart->exc_val);
@@ -581,6 +606,11 @@ static int semu_start(int argc, char **argv)
581606
emu.vblk.ram = emu.ram;
582607
emu.disk = virtio_blk_init(&(emu.vblk), disk_file);
583608
#endif
609+
#if SEMU_HAS(VIRTIOSND)
610+
if (!virtio_snd_init(&(emu.vsnd)))
611+
fprintf(stderr, "No virtio-snd functioned\n");
612+
emu.vsnd.ram = emu.ram;
613+
#endif
584614

585615
/* Emulate */
586616
uint32_t peripheral_update_ctr = 0;
@@ -603,6 +633,11 @@ static int semu_start(int argc, char **argv)
603633
if (emu.vblk.InterruptStatus)
604634
emu_update_vblk_interrupts(&vm);
605635
#endif
636+
637+
#if SEMU_HAS(VIRTIOSND)
638+
if (emu.vsnd.InterruptStatus)
639+
emu_update_vsnd_interrupts(&vm);
640+
#endif
606641
}
607642

608643
emu_update_timer_interrupt(vm.hart[i]);

minimal.dts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,13 @@
6363
interrupts = <3>;
6464
};
6565
#endif
66+
67+
#if SEMU_FEATURE_VIRTIOSND
68+
snd0: virtio@4400000 {
69+
compatible = "virtio,mmio";
70+
reg = <0x4400000 0x200>;
71+
interrupts = <4>;
72+
};
73+
#endif
6674
};
6775
};

0 commit comments

Comments
 (0)