-
Notifications
You must be signed in to change notification settings - Fork 9
Open
Description
[ 8.398521 0:2 starry_api::vfs::dev::usb::usb_host:120] [USB] Initializing USB Host Controller
[ 8.399462 0:2 starry_api::vfs::dev::usb::usb_host:48] [USB] iomap: paddr=0x10010000, size=0x4000
[ 8.400452 0:2 starry_api::vfs::dev::usb::usb_host:54] [USB] phys_to_virt => vaddr = 0xffff000010010000
[ 8.403943 0:2 starry_api::vfs::dev::usb::usb_host:75] [USB] mapping protect OK, final vaddr = 0xffff000010010000
[ 8.404896 0:2 starry_api::vfs::dev::usb::usb_host:122] [USB] XHCI base mapped at vaddr = 0xffff000010010000
[ 8.406619 0:2 starry_api::vfs::dev::usb::usb_host:125] [USB] USBHost created
[ 8.407381 0:2 starry_api::vfs::dev::usb::usb_host:130] [USB] Register IRQ 36
[ 8.408204 0:2 starry_api::vfs::dev::usb::usb_host:133] Register IRQ ok
[ 8.408850 0:2 starry_api::vfs::dev::usb::usb_host:141] [USB] calling host.init()
[ 8.415294 0:2 starry_api::vfs::dev::usb::usb_host:41] [USB] page_size
[ 8.416195 0:2 starry_api::vfs::dev::usb::usb_host:41] [USB] page_size
[ 8.416755 0:2 starry_api::vfs::dev::usb::usb_host:41] [USB] page_size
[ 8.422651 0:2 starry_api::vfs::dev::usb::usb_host:34] [USB] sleep 50 ms
[ 8.473889 0:2 starry_api::vfs::dev::usb::usb_host:34] [USB] sleep 100 ms
qemu-system-aarch64: info: [UVC] usb_video_handle_reset, 0x56207cdc0690
[ 8.576635 0:2 starry_api::vfs::dev::usb::usb_host:34] [USB] sleep 100 ms
[ 8.677687 0:2 starry_api::vfs::dev::usb::usb_host:144] [USB] host.init OK
[ 8.679136 0:2 crab_usb::backend::xhci:248] Port 0: Enabled: false, Connected: false, Speed 0, Power true
[ 8.680027 0:2 crab_usb::backend::xhci:248] Port 1: Enabled: false, Connected: false, Speed 0, Power true
[ 8.680753 0:2 crab_usb::backend::xhci:248] Port 2: Enabled: false, Connected: false, Speed 0, Power true
[ 8.681638 0:2 crab_usb::backend::xhci:248] Port 3: Enabled: false, Connected: false, Speed 0, Power true
[ 8.682341 0:2 crab_usb::backend::xhci:248] Port 4: Enabled: true, Connected: true, Speed 3, Power true
[ 8.683194 0:2 crab_usb::backend::xhci:248] Port 5: Enabled: false, Connected: false, Speed 0, Power true
[ 8.683900 0:2 crab_usb::backend::xhci:248] Port 6: Enabled: false, Connected: false, Speed 0, Power true
[ 8.684598 0:2 crab_usb::backend::xhci:248] Port 7: Enabled: false, Connected: false, Speed 0, Power true
[ 8.685453 0:2 crab_usb::backend::xhci::root:525] New device on port 4
[ 8.686512 0:2 crab_usb::backend::xhci::ring:80] [CMD] >> EnableSlot(EnableSlot { slot_type: 0, cycle_bit: true }) @BusAddr(45EC2000)
[ 8.689034 0:2 usb_if::transfer::wait:73] WaitMap: try_wait_for_result called with id 45EC2000, elem@0xffff00004e20b400 false
qemu 启动命令 (qemu 支持 uvc 的代码仓库在 https://cnb.cool/rzhangsan/ChenLongOS_ai_stack/qemu-10.0.0)
# 编译
make ARCH=aarch64 build SMP=1
# qeum 运行
# 挂载虚拟 usb 设备
# usb-video 摄像头
/opt/qemu-10.0.0/bin/qemu-system-aarch64 -m 1G -smp 1 -cpu cortex-a72 -machine virt \
-kernel workspace_aarch64-qemu-virt.bin \
-device virtio-blk-pci,drive=disk0 \
-drive id=disk0,if=none,format=raw,file=disk.img \
-device virtio-net-pci,netdev=net0 \
-netdev user,id=net0,hostfwd=tcp::10122-:22 \
-device qemu-xhci,id=xhci,msi=off,msix=off \
-device usb-video,bus=xhci.0,id=myuvc0,file=qemu/sample-30s.mp4 \
-nographic在 satrryos 中初始化 usbhub 及获取 list 代码
extern crate alloc;
use alloc::{boxed::Box, vec::Vec};
use core::{ptr::NonNull, time::Duration};
use axerrno::AxError;
use axhal::{
irq::register,
mem::{PhysAddr, phys_to_virt, virt_to_phys},
paging::MappingFlags,
};
use axmm::kernel_aspace;
use crab_usb::err::USBError;
pub use crab_usb::*;
use mbarrier::mb;
use spin::{Mutex, Once};
// ===> qemu xhci addr
const USB_3_HOST_MMIO_BASE: usize = 0x10010000;
const USB_3_HOST_MMIO_SIZE: usize = 0x4000;
const USB_3_HOST_IRQ: usize = 36;
// <=== qemu xhci addr end
// ===> todo broad xhci addr
// <=== todo broad xhci addr
static USB_HOST: Once<Mutex<USBHost>> = Once::new();
static USB_IRQ_HANDLE: Once<EventHandler> = Once::new();
struct KernelImpl;
impl_trait! {
impl Kernel for KernelImpl {
fn sleep<'a>(duration: Duration) -> BoxFuture<'a, ()> {
warn!("[USB] sleep {} ms", duration.as_millis());
Box::pin(async move {
axhal::time::busy_wait(duration);
})
}
fn page_size() -> usize {
warn!("[USB] page_size");
0x1000
}
}
}
fn iomap(paddr: PhysAddr, size: usize) -> Result<NonNull<u8>, AxError> {
warn!(
"[USB] iomap: paddr=0x{:x}, size=0x{:x}",
paddr.as_usize(),
size
);
let vaddr = phys_to_virt(paddr);
warn!("[USB] phys_to_virt => vaddr = 0x{:x}", vaddr.as_usize());
let mut g = kernel_aspace().lock();
if let Err(e) = g.map_linear(
vaddr,
paddr,
size,
MappingFlags::READ | MappingFlags::WRITE | MappingFlags::DEVICE,
) {
if !matches!(e, AxError::AlreadyExists) {
return Err(e);
}
}
g.protect(
vaddr,
size,
MappingFlags::READ | MappingFlags::WRITE | MappingFlags::DEVICE,
)?;
warn!(
"[USB] mapping protect OK, final vaddr = 0x{:x}",
vaddr.as_usize()
);
mb();
Ok(unsafe { NonNull::new_unchecked(vaddr.as_mut_ptr()) })
}
struct Cache;
impl dma_api::Impl for Cache {
fn map(addr: NonNull<u8>, _size: usize, _direction: dma_api::Direction) -> u64 {
virt_to_phys((addr.as_ptr() as usize).into()).as_usize() as _
}
fn unmap(_addr: NonNull<u8>, _size: usize) {}
fn flush(addr: NonNull<u8>, size: usize) {
aarch64_cpu_ext::cache::dcache_range(
aarch64_cpu_ext::cache::CacheOp::Clean,
addr.as_ptr() as usize,
size,
);
}
fn invalidate(addr: NonNull<u8>, size: usize) {
aarch64_cpu_ext::cache::dcache_range(
aarch64_cpu_ext::cache::CacheOp::Invalidate,
addr.as_ptr() as usize,
size,
);
}
}
dma_api::set_impl!(Cache);
fn irq_handler() {
// warn!("[USB] IRQ irq_handler");
USB_IRQ_HANDLE.wait().handle_event();
}
fn get_usb_host() -> &'static Mutex<USBHost> {
USB_HOST.call_once(|| {
warn!("[USB] Initializing USB Host Controller");
let mmio_base = iomap(USB_3_HOST_MMIO_BASE.into(), USB_3_HOST_MMIO_SIZE).unwrap();
warn!("[USB] XHCI base mapped at vaddr = {:?}", mmio_base);
let mut host = USBHost::new_xhci(mmio_base);
warn!("[USB] USBHost created");
let event_handler = host.event_handler();
USB_IRQ_HANDLE.call_once(|| event_handler);
warn!("[USB] Register IRQ {}", USB_3_HOST_IRQ);
match register(USB_3_HOST_IRQ, irq_handler) {
true => {
warn!("Register IRQ ok");
}
false => {
warn!("Register IRQ fail");
}
}
spin_on::spin_on(async move {
warn!("[USB] calling host.init()");
host.init().await.unwrap();
warn!("[USB] host.init OK");
Mutex::new(host)
})
})
}
pub fn get_device_list() -> Result<Vec<DeviceInfo>, USBError> {
// warn!("[USB] get usb host");
let mut host = get_usb_host().lock();
// warn!("[USB] get usb list");
spin_on::spin_on(async {
let ls = host.device_list().await?;
// warn!("[USB] collect");
Ok(ls.collect())
})
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels