Skip to content

Commit

Permalink
Enable ALSA debug in kernel
Browse files Browse the repository at this point in the history
Now gets "virtio_snd: probe of virtio2 failed with error -2" in
dmesg.
  • Loading branch information
Cuda-Chen committed Sep 5, 2024
1 parent 3713eaf commit f4e14ce
Show file tree
Hide file tree
Showing 11 changed files with 712 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "cnfa"]
path = cnfa
url = https://github.com/cntools/cnfa
shallow = true
26 changes: 26 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ OBJS_EXTRA :=
# command line option
OPTS :=

LDFLAGS :=

# virtio-blk
ENABLE_VIRTIOBLK ?= 1
$(call set-feature, VIRTIOBLK)
Expand Down Expand Up @@ -41,6 +43,30 @@ ifeq ($(call has, VIRTIONET), 1)
OBJS_EXTRA += virtio-net.o
endif

# virtio-snd
ENABLE_VIRTIOSND ?= 1
ifneq ($(UNAME_S),Linux)
ENABLE_VIRTIOSND := 0
endif
$(call set-feature, VIRTIOSND)
ifeq ($(call has, VIRTIOSND), 1)
OBJS_EXTRA += virtio-snd.o
LDFLAGS += -lasound -lpthread
CFLAGS += -Icnfa

cnfa/Makefile:
git submodule update --init cnfa
cnfa/os_generic: cnfa/Makefile
$(MAKE) -C $(dir $<) CC=$(CC) os_generic.h
CNFA_LIB := cnfa/CNFA_sf.h
$(CNFA_LIB): cnfa/Makefile cnfa/os_generic
$(MAKE) -C $(dir $<) CC=$(CC) CNFA_sf.h
endif

# .DEFAULT_GOAL should be set to all since the very first target is not all
# after git submodule.
.DEFAULT_GOAL := all

BIN = semu
all: $(BIN) minimal.dtb

Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ $ brew install e2fsprogs

## Build and Run

Build the dependency (CNFA):
```shell
$ rm cnfa/CNFA_sf.h
$ make os_generic.h
$ make CNFA_sf.h
```

Build the emulator:
```shell
$ make
Expand Down
1 change: 1 addition & 0 deletions cnfa
Submodule cnfa added at 60bcdd
3 changes: 3 additions & 0 deletions configs/buildroot.config
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ BR2_RELRO_NONE=y
# BR2_RELRO_PARTIAL is not set
# BR2_RELRO_FULL is not set
BR2_FORTIFY_SOURCE_1=y
BR2_PACKAGE_ALSA_UTILS=y
BR2_PACKAGE_ALSA_UTILS_APLAY=y
BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y
# BR2_PACKAGE_URANDOM_SCRIPTS is not set
BR2_TARGET_ROOTFS_CPIO=y
BR2_TARGET_ROOTFS_CPIO_FULL=y
Expand Down
10 changes: 9 additions & 1 deletion configs/linux.config
Original file line number Diff line number Diff line change
Expand Up @@ -936,7 +936,15 @@ CONFIG_DUMMY_CONSOLE_ROWS=25
# end of Console display driver support
# end of Graphics support

# CONFIG_SOUND is not set
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_VERBOSE=y
CONFIG_SND_PCM_XRUN_DEBUG=y
CONFIG_SND_DUMMY=y
CONFIG_SND_ALOOP=y
CONFIG_SND_VIRTIO=y

#
# HID support
Expand Down
51 changes: 51 additions & 0 deletions device.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,53 @@ void clint_write(hart_t *vm,
uint8_t width,
uint32_t value);

/* VirtIO-Sound */

#if SEMU_HAS(VIRTIOSND)
#define IRQ_VSND 4
#define IRQ_VSND_BIT (1 << IRQ_VSND)

typedef struct {
uint32_t QueueNum;
uint32_t QueueDesc;
uint32_t QueueAvail;
uint32_t QueueUsed;
uint16_t last_avail;
bool ready;
} virtio_snd_queue_t;

typedef struct {
/* feature negotiation */
uint32_t DeviceFeaturesSel;
uint32_t DriverFeatures;
uint32_t DriverFeaturesSel;
/* queue config */
uint32_t QueueSel;
virtio_snd_queue_t queues[2];
/* status */
uint32_t Status;
uint32_t InterruptStatus;
/* supplied by environment */
uint32_t *ram;
/* implementation-specific */
void *priv;
} virtio_snd_state_t;

void virtio_snd_read(hart_t *core,
virtio_snd_state_t *vsnd,
uint32_t addr,
uint8_t width,
uint32_t *value);

void virtio_snd_write(hart_t *core,
virtio_snd_state_t *vsnd,
uint32_t addr,
uint8_t width,
uint32_t value);

bool virtio_snd_init(virtio_snd_state_t *vsnd);
#endif /* SEMU_HAS(VIRTIOSND) */

/* memory mapping */

typedef struct {
Expand All @@ -205,4 +252,8 @@ typedef struct {
virtio_blk_state_t vblk;
#endif
clint_state_t clint;
#if SEMU_HAS(VIRTIOSND)
virtio_snd_state_t vsnd;
#endif
uint64_t timer;
} emu_state_t;
5 changes: 5 additions & 0 deletions feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,10 @@
#define SEMU_FEATURE_VIRTIONET 1
#endif

/* virtio-snd */
#ifndef SEMU_FEATURE_VIRTIOSND
#define SEMU_FEATURE_VIRTIOSND 1
#endif

/* Feature test macro */
#define SEMU_HAS(x) SEMU_FEATURE_##x
35 changes: 35 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ static void emu_update_timer_interrupt(hart_t *hart)
clint_update_interrupts(hart, &data->clint);
}

#if SEMU_HAS(VIRTIOSND)
static void emu_update_vsnd_interrupts(vm_t *vm)
{
emu_state_t *data = PRIV(vm->hart[0]);
if (data->vsnd.InterruptStatus)
data->plic.active |= IRQ_VSND_BIT;
else
data->plic.active &= ~IRQ_VSND_BIT;
plic_update_interrupts(vm, &data->plic);
}
#endif

static void mem_load(hart_t *hart,
uint32_t addr,
uint8_t width,
Expand Down Expand Up @@ -121,6 +133,13 @@ static void mem_load(hart_t *hart,
clint_read(hart, &data->clint, addr & 0xFFFFF, width, value);
clint_update_interrupts(hart, &data->clint);
return;

#if SEMU_HAS(VIRTIOSND)
case 0x44: /* virtio-snd */
virtio_snd_read(hart, &data->vsnd, addr & 0xFFFFF, width, value);
emu_update_vsnd_interrupts(hart->vm);
return;
#endif
}
}
vm_set_exception(hart, RV_EXC_LOAD_FAULT, hart->exc_val);
Expand Down Expand Up @@ -166,6 +185,12 @@ static void mem_store(hart_t *hart,
clint_write(hart, &data->clint, addr & 0xFFFFF, width, value);
clint_update_interrupts(hart, &data->clint);
return;
#if SEMU_HAS(VIRTIOSND)
case 0x44: /* virtio-snd */
virtio_snd_write(hart, &data->vsnd, addr & 0xFFFFF, width, value);
emu_update_vsnd_interrupts(hart->vm);
return;
#endif
}
}
vm_set_exception(hart, RV_EXC_STORE_FAULT, hart->exc_val);
Expand Down Expand Up @@ -581,6 +606,11 @@ static int semu_start(int argc, char **argv)
emu.vblk.ram = emu.ram;
emu.disk = virtio_blk_init(&(emu.vblk), disk_file);
#endif
#if SEMU_HAS(VIRTIOSND)
if (!virtio_snd_init(&(emu.vsnd)))
fprintf(stderr, "No virtio-snd functioned\n");
emu.vsnd.ram = emu.ram;
#endif

/* Emulate */
uint32_t peripheral_update_ctr = 0;
Expand All @@ -603,6 +633,11 @@ static int semu_start(int argc, char **argv)
if (emu.vblk.InterruptStatus)
emu_update_vblk_interrupts(&vm);
#endif

#if SEMU_HAS(VIRTIOSND)
if (emu.vsnd.InterruptStatus)
emu_update_vsnd_interrupts(&vm);
#endif
}

emu_update_timer_interrupt(vm.hart[i]);
Expand Down
8 changes: 8 additions & 0 deletions minimal.dts
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,13 @@
interrupts = <3>;
};
#endif

#if SEMU_FEATURE_VIRTIOSND
snd0: virtio@4400000 {
compatible = "virtio,mmio";
reg = <0x4400000 0x200>;
interrupts = <4>;
};
#endif
};
};
Loading

0 comments on commit f4e14ce

Please sign in to comment.