Help with RaspberryPI USB on Fiasco.OC+Genode

Reinier Millo Sánchez rmillo at ...210...
Sun Mar 22 19:32:11 CET 2015


Hi GenodeOS and L4-Hackers community

I'm trying to use DWC_OTG USB Driver for RaspberryPI, using Fiasco.OC as 
microkernel with Genode. I have tested the USB driver using Genode bare 
metal hardware on RaspberryPI and works fine. I have reviewed the  post 
published by Simon Arlott about the FIQ and Bell IRQ:

    http://permalink.gmane.org/gmane.linux.kernel.rpi/438

Also I have reviewed the correction implemented by Norman Feske in the 
IRQ controller for Genode bare metal hardware:

    repos/base-hw/src/core/include/spec/rpi/pic.h

To use Fiasco.OC as microkernel in Genode I have adapted the patch 
published in:

    http://sourceforge.net/p/genode/mailman/message/33071769/

Based on it, i have tried to use the same idea of Norman Feske, 
modifying the Fiasco.OC's IRQ's controller as shown below:

    ------
    kernel/fiasco/src/kern/arm/bsp/bcm2835/mem_layout-arm-bcm2835.cpp ------
    index aab5906..4385ebe 100644
    @@ -8,5 +8,6 @@ public:
          Pic_phys_base        = 0x2000b200,
          Watchdog_phys_base   = 0x20100000,
          Uart_phys_base       = 0x20201000,
    +    Usb_dwc_otg_base     = 0x20980000,
        };
      };

    ----------
    kernel/fiasco/src/kern/arm/bsp/bcm2835/pic-arm-bcm2835.cpp ----------
    index 20ed280..13fa623 100644
    @@ -7,6 +7,83 @@ IMPLEMENTATION [arm && bcm2835]:
      #include "irq_mgr.h"
      #include "mmio_register_block.h"
      #include "kmem.h"
    +#include "warn.h"
    +
    +class Usb_dwc_otg : Mmio_register_block{
    +private:
    +  enum{
    +    Core_irq_status_reg   = 0x14,
    +    Guid_reg              = 0x3c,
    +    Host_frame_number_reg = 0x408,
    +  };
    +  bool is_sof() const { return read<Mword>(Core_irq_status_reg)&0x8; }
    +};
    +
    +PUBLIC
    +Usb_dwc_otg::Usb_dwc_otg()
    +: Mmio_register_block(Kmem::mmio_remap(Mem_layout::Usb_dwc_otg_base))
    +{
    +
    +  write<Mword>(read<Mword>(Guid_reg)&0x3FFFC000, Guid_reg);
    +}
    +
    +PRIVATE
    +static bool
    +Usb_dwc_otg::need_trigger_sof(Mword host_frame, Mword scheduled_frame)
    +{
    +  Mword const max_frame = 0x3fff;
    +
    +  if (host_frame < scheduled_frame) {
    +    if (scheduled_frame - host_frame < max_frame / 2)
    +      return false;  /* scheduled frame not reached yet */
    +    else
    +      return true;   /* scheduled frame passed, host frame wrapped */
    +  } else {
    +    if (host_frame - scheduled_frame < max_frame / 2)
    +      return true;   /* scheduled frame passed */
    +    else
    +      return false;  /* scheduled frame wrapped, not reached */
    +  }
    +}
    +
    +PUBLIC
    +bool
    +Usb_dwc_otg::handle_sof()
    +{
    +  if (!is_sof())
    +    return false;
    +
    +  static Mword cnt, stat_cnt, filter_cnt, kick_cnt, trigger_cnt;
    +
    +  stat_cnt++;
    +  if (stat_cnt == 8000) {
    +    WARN("kicked: %d filtered: %d  triggered: %d", kick_cnt,
    filter_cnt, trigger_cnt);
    +    stat_cnt = 0;
    +  }
    +
    +  cnt++;
    +  if (cnt == 8*20) {
    +    cnt = 0;
    +    return false;
    +  }
    +
    +  if (read<Mword>(Guid_reg)&0x40000000)
    +    kick_cnt++;
    +
    +  if ((!read<Mword>(Guid_reg)&0x80000000) ||
    (read<Mword>(Guid_reg)&0x40000000))
    +    return false;
    +
    +  if
    (Usb_dwc_otg::need_trigger_sof(read<Mword>(Host_frame_number_reg)&0x3fff,
    read<Mword>(Guid_reg)&0x3fff)) {
    +    trigger_cnt++;
    +    return false;
    +  }
    +
    +  filter_cnt++;
    +
    +  write<Mword>(read<Mword>(Core_irq_status_reg)|0x8,
    Core_irq_status_reg);
    +
    +  return true;
    +}

      class Irq_chip_bcm : public Irq_chip_gen, Mmio_register_block
      {
    @@ -29,6 +106,9 @@ public:
        bool is_edge_triggered(Mword) const { return false; }
        void set_cpu(Mword, Cpu_number) {}
        void ack(Mword) { /* ack is empty */ }
    +
    +private:
    +  Usb_dwc_otg _usb;
      };

      PUBLIC
    @@ -97,6 +177,11 @@ Irq_chip_bcm::irq_handler()
              {
                b = 0;
                p = read<Mword>(Irq_pending_1);
    +          if(p==8){
    +            if(_usb.handle_sof()){
    +              return;
    +            }
    +          }
              }
            else if (p & 0x200)
              {

I have tried to test the *usb_hid *example on Genode using Fiasco.OC as 
microkernel

    make run/usb_hid

The example compiles fine. When I test it in the emulator QEMU get the 
following output

    KERNEL: Warning: kicked: 0 filtered: 0  triggered: 7950
    KERNEL: Warning: kicked: 0 filtered: 0  triggered: 15900
    KERNEL: Warning: kicked: 0 filtered: 0  triggered: 23850
    KERNEL: Warning: kicked: 0 filtered: 0  triggered: 31800

When have tested it on real hardware never get the kernel warning. It 
seems that the *Kick* and *Num_valid* bits are not modified by the USB 
driver.
After that, I have tried to log the USB driver IRQ, setting

    #define DEBUG_IRQ        1

in the file

    repos/dde_linux/src/lib/usb/include/lx_emul.h

Setting this value, the USB driver will log every IRQ handled by the 
function *_handle()* and *_handle_one()***in the USB driver. In the 
Genode bare metal hardware it works fine, but when tried it with 
Fiasco.OC, the IRQ handler *_handle()* and *_handle_one()* are never logged.
There's something wrong in my implementation? Someone has tested the USB 
driver using Fiasco.OC and Genode together? Why Fiasco.OC's IRQ's 
controller is not calling the IRQ's handler defined in the USB driver?
I'm using Genode commit 63293950261bfb17497433c36a3d62e6e1d813b3, 
Fiasco.OC r56 and DWC_OTG commit d08b205cfe01925667f3591117b6d3e1087b4e19.

Best regards

-- 
Lic. Reinier Millo Sánchez
Centro de Estudios de Informática
Universidad Central "Marta Abreu" de Las Villas

"antes de discutir ... respira;
   antes de hablar ... escucha;
  antes de escribir ... piensa;
   antes de herir ... siente;
  antes de rendirte ... intenta;
   antes de morir ... vive"

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.genode.org/pipermail/users/attachments/20150322/575e52f1/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: rmillo.vcf
Type: text/x-vcard
Size: 519 bytes
Desc: not available
URL: <http://lists.genode.org/pipermail/users/attachments/20150322/575e52f1/attachment.vcf>


More information about the users mailing list