Exemple #1
0
void DeviceServer::registerInterrupt(Device *dev, Size vector)
{
    if (!m_interrupts[vector])
    {
        m_interrupts.insert(vector, new List<Device *>);
    }
    m_interrupts[vector]->append(dev);

    // Register to kernel
    ProcessCtl(SELF, WatchIRQ, vector);
    ProcessCtl(SELF, EnableIRQ, vector);

    // Register interrupt handler
    addIRQHandler(vector, (IRQHandlerFunction) &DeviceServer::interruptHandler);
}
Exemple #2
0
Error SynopsisUSB::initialize()
{
    Error r = USBController::initialize();

    if (r != ESUCCESS)
        return r;

    // Map USB host controller registers
    if (m_io.map(IO_BASE + Base, PAGESIZE*2,
                 Memory::User|Memory::Readable|Memory::Writable|Memory::Device) != IO::Success)
    {
        ERROR("failed to map I/O registers");
        return EIO;
    }

    // Check device ID
    if (m_io.read(VendorId) != DefaultVendorId)
    {
        ERROR("incompatible vendorId: " << m_io.read(VendorId) << " != " << DefaultVendorId);
        return EIO;
    }

    DEBUG("UserId: " << m_io.read(UserId) << " VendorId: " << m_io.read(VendorId));
    NOTICE("Synopsis Design Ware USB-on-the-go Host Controller found");

    // Initialize power manager
    if (m_power.initialize() != BroadcomPower::Success)
    {
        ERROR("failed to initialize power manager");
        return EIO;
    }
    // Power on the USB subsystem
    if (m_power.enable(BroadcomPower::USB) != BroadcomPower::Success)
    {
        ERROR("failed to power on the USB subsystem");
        return EIO;
    }
    DEBUG("powered on");

    // Soft-Reset
    softReset();
    DEBUG("software reset done");

    // Setup DMA
    m_io.write(RxFIFOSize, 1024);
    m_io.write(TxFIFOSize, (1024 << 16) | 1024);
    m_io.write(PeriodTxFIFOSize, (1024 << 16) | 2048);
    m_io.set(AHBConfig, DMAEnable | AXIWait);

    // Enable the USB controller interrupt on the ARM's interrupt controller
    addIRQHandler(InterruptNumber, (IRQHandlerFunction) &SynopsisUSB::interruptHandler);
    addIRQHandler(0, (IRQHandlerFunction) &SynopsisUSB::interruptHandler); // TODO: ARM does not have IRQ_REG() yet
    ProcessCtl(SELF, WatchIRQ, InterruptNumber);
    ProcessCtl(SELF, EnableIRQ, InterruptNumber);
    DEBUG("interrupt handler installed");

    // Clear all pending core interrupts
    m_io.write(CoreIntMask, 0);
    m_io.write(CoreInterrupt, 0xffffffff);

    // Enable core host channel and port interrupts
    m_io.write(CoreIntMask, CoreIntChannel | CoreIntPort);

    // Enable interrupts globally on the USB host controller.
    m_io.set(AHBConfig, InterruptEnable);
    DEBUG("interrupts enabled");

    // Power-on host port (virtual root hub)
    u32 val = m_io.read(HostPortControl);
    val &= ~(HostPortEnable | HostPortEnableChanged |
             HostPortConnectChanged | HostPortCurrentChanged);
    val |= HostPortPower;
    m_io.write(HostPortControl, val);
    DEBUG("poweron host port");

    // Begin host port reset (raise the reset signal)
    val = m_io.read(HostPortControl);
    val &= ~(HostPortEnable | HostPortEnableChanged |
             HostPortConnectChanged | HostPortCurrentChanged);
    val |=  HostPortReset;
    m_io.write(HostPortControl, val);

#warning TODO: implement real sleep() now. We need it here.
    sleep(60);

    // Finish host port reset (lower the reset signal)
    val = m_io.read(HostPortControl);
    val &= ~(HostPortEnable | HostPortEnableChanged |
             HostPortConnectChanged | HostPortCurrentChanged);
    m_io.write(HostPortControl, val);
    DEBUG("host port reset done");

    // Clear host port interrupt flags
    val = m_io.read(HostPortControl);
    val |= HostPortEnableChanged | HostPortConnectChanged | HostPortCurrentChanged;
    m_io.write(HostPortControl, val);

    DEBUG("host port (root hub) enabled");
    DEBUG("host port status=" << m_io.read(HostPortControl) << " connected=" <<
        (m_io.read(HostPortControl) & HostPortConnect));

    // Done.
    return ESUCCESS;
}