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; }
pid_t getppid() { return ProcessCtl(SELF, GetParent); }
Error Keyboard::initialize() { return ProcessCtl(SELF, AllowIO, PS2_PORT); }
Error ATAController::initialize() { ATADrive *drive; /* * Request ATA Control I/O port. */ ProcessCtl(SELF, AllowIO, ATA_BASE_CTL0); /* * Request ATA Command I/O ports. */ for (Size i = 0; i <= ATA_REG_CMD; i++) { ProcessCtl(SELF, AllowIO, ATA_BASE_CMD0 + i); } /* Detect ATA Controller. */ if (inb(ATA_BASE_CMD0 + ATA_REG_STATUS) == 0xff) { exit(EXIT_FAILURE); } pollReady(true); /* Attempt to detect first drive. */ outb(ATA_BASE_CMD0 + ATA_REG_SELECT, ATA_SEL_MASTER); pollReady(true); outb(ATA_BASE_CMD0 + ATA_REG_CMD, ATA_CMD_IDENTIFY); switch (inb(ATA_BASE_CMD0 + ATA_REG_STATUS)) { case 0: syslog(LOG_INFO, "No ATA drive(s) detected"); break; default: /* Wait until the command completed. */ pollReady(); /* Allocate a new drive. */ drive = new ATADrive; drives.insertTail(drive); /* Read IDENTIFY data. */ for (int i = 0; i < 256; i++) { ((u16 *) &drive->identity)[i] = inw(ATA_BASE_CMD0 + ATA_REG_DATA); } /* Fixup ASCII bytes. */ IDENTIFY_TEXT_SWAP(drive->identity.firmware, 8); IDENTIFY_TEXT_SWAP(drive->identity.serial, 20); IDENTIFY_TEXT_SWAP(drive->identity.model, 40); /* Print out information. */ syslog(LOG_INFO, "ATA drive detected: SERIAL=%20s FIRMWARE=%8s " "MODEL=%40s MAJOR=%x MINOR=%x SECTORS=%x", drive->identity.serial, drive->identity.firmware, drive->identity.model, drive->identity.majorRevision, drive->identity.minorRevision, drive->identity.sectors28); break; } return ESUCCESS; }
Error i8250::interrupt(Size vector) { ProcessCtl(SELF, EnableIRQ, irq); }