20 #include "PciAtaController.h" 22 #include "BusMasterIde.h" 23 #include "ata-common.h" 24 #include "modules/drivers/common/scsi/ScsiController.h" 25 #include "pedigree/kernel/Log.h" 26 #include "pedigree/kernel/machine/Controller.h" 27 #include "pedigree/kernel/machine/Device.h" 28 #include "pedigree/kernel/machine/IrqManager.h" 29 #include "pedigree/kernel/machine/Machine.h" 30 #include "pedigree/kernel/machine/Pci.h" 31 #include "pedigree/kernel/process/Thread.h" 32 #include "pedigree/kernel/processor/IoBase.h" 33 #include "pedigree/kernel/processor/IoPort.h" 34 #include "pedigree/kernel/processor/Processor.h" 35 #include "pedigree/kernel/processor/ProcessorInformation.h" 36 #include "pedigree/kernel/time/Time.h" 37 #include "pedigree/kernel/utilities/Vector.h" 38 #include "pedigree/kernel/utilities/utility.h" 43 :
AtaController(pDev, nController), m_PciControllerType(UnknownController)
52 m_PciControllerType = PIIX;
56 m_PciControllerType = PIIX3;
60 m_PciControllerType = PIIX4;
64 m_PciControllerType = ICH;
68 m_PciControllerType = ICH0;
73 m_PciControllerType = ICH2;
78 m_PciControllerType = ICH3;
83 m_PciControllerType = ICH4;
87 m_PciControllerType = ICH5;
91 m_PciControllerType = UnknownController;
95 str +=
" PCI IDE controller found";
96 NOTICE(static_cast<const char *>(str));
98 if (m_PciControllerType == UnknownController)
103 for (
size_t i = 0; i <
addresses().count(); i++)
106 static_cast<const char *>(
addresses()[i]->m_Name),
"bar4"))
119 uint32_t busMasterIfaceAddr =
121 busMasterIfaceAddr &= 0xFFFF000F;
122 busMasterIfaceAddr |= bar4->
m_Address & 0xFFF0;
124 " - Bus master interface base register at " << bar4->
m_Address);
131 commandReg = (commandReg & ~(0x7)) | 0x7;
137 uint32_t ideTiming = 0xB3FF;
139 ideTiming |= (ideTiming << 16);
144 if (m_PciControllerType == PIIX)
160 if (m_PciControllerType == PIIX4)
169 uint16_t target_timings = 0x2 * 0x3333;
170 timings = (timings & 0xFFFF) | target_timings;
180 NOTICE(
" - This is a DMA capable controller");
184 #ifndef KERNEL_PROCESSOR_NO_PORT_IO 185 IoPort *masterCommand =
new IoPort(
"pci-ide-master-cmd");
187 IoPort *masterControl =
new IoPort(
"pci-ide-master-ctl");
204 bar4_a =
new IoPort(
"pci-ide-busmaster-primary");
207 ERROR(
"Couldn't allocate primary BusMaster ports");
212 bar4_b =
new IoPort(
"pci-ide-busmaster-secondary");
215 ERROR(
"Couldn't allocate secondary BusMaster ports");
226 ERROR(
"Couldn't initialise primary BusMaster IDE interface");
227 delete primaryBusMaster;
230 primaryBusMaster = 0;
238 ERROR(
"Couldn't initialise secondary BusMaster IDE interface");
239 delete secondaryBusMaster;
242 secondaryBusMaster = 0;
249 if (!masterCommand->
allocate(0x1F0, 8))
250 ERROR(
"Couldn't allocate master command ports");
251 if (!masterControl->
allocate(0x3F4, 4))
252 ERROR(
"Couldn't allocate master control ports");
253 if (!slaveCommand->
allocate(0x170, 8))
254 ERROR(
"Couldn't allocate slave command ports");
255 if (!slaveControl->
allocate(0x374, 4))
256 ERROR(
"Couldn't allocate slave control ports");
259 AtaStatus masterStatus = ataWait(masterCommand, masterControl);
260 AtaStatus slaveStatus = ataWait(slaveCommand, slaveControl);
263 delete masterCommand;
264 delete masterControl;
279 masterControl->
write8(0x6, 2);
282 masterControl->
write8(0x2, 2);
286 slaveControl->
write8(0x6, 2);
288 slaveControl->
write8(0x2, 2);
292 2 * Time::Multiplier::Millisecond);
295 ataWait(masterCommand, masterControl);
297 ataWait(slaveCommand, slaveControl);
307 size_t primaryIrq = 14, secondaryIrq = 15;
310 primaryIrq, static_cast<IrqHandler *>(
this));
313 secondaryIrq, static_cast<IrqHandler *>(
this));
319 true, masterCommand, masterControl, primaryBusMaster, primaryIrq);
321 false, masterCommand, masterControl, primaryBusMaster, primaryIrq);
327 true, slaveCommand, slaveControl, secondaryBusMaster, secondaryIrq);
329 false, slaveCommand, slaveControl, secondaryBusMaster,
333 ERROR(
"PCI ATA: no good, this machine has no port I/O");
337 PciAtaController::~PciAtaController()
341 void PciAtaController::diskHelper(
358 bool PciAtaController::sendCommand(
359 size_t nUnit, uintptr_t pCommand, uint8_t nCommandSize,
360 uintptr_t pRespBuffer, uint16_t nRespBytes,
bool bWrite)
365 ERROR(
"PCI ATA: sendCommand called with a bad unit number.");
371 nUnit, pCommand, nCommandSize, pRespBuffer, nRespBytes, bWrite);
375 uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5,
376 uint64_t p6, uint64_t p7, uint64_t p8)
382 if (p1 == SCSI_REQUEST_READ)
384 else if (p1 == SCSI_REQUEST_WRITE)
399 if (pBusMaster && !pBusMaster->
isActive())
bool initialise(size_t nUnit=~0)
void removeChild(size_t n)
Device * getChild(size_t n)
virtual BusMasterIde * getBusMaster() const
virtual uint64_t executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8)
virtual void setInterruptNumber(uintptr_t n)
virtual Vector< Address * > & addresses()
bool initialise(IoBase *pBase)
Initialises DMA for a specific channel.
virtual uint64_t doWrite(uint64_t location)
virtual bool irq(irq_id_t number, InterruptState &state)
static ProcessorInformation & information()
Abstrace base class for hardware I/O capabilities.
virtual uintptr_t getInterruptNumber()
virtual uint64_t doRead(uint64_t location)
virtual void setSpecificType(String str)
virtual bool sendCommand(size_t nUnit, uintptr_t pCommand, uint8_t nCommandSize, uintptr_t pRespBuffer, uint16_t nRespBytes, bool bWrite)
uint8_t __reg_contents
"Hidden" integer which contains the actual register contents
uint32_t readConfigSpace(Device *pDev, uint8_t offset)
void addChild(Device *pDevice)
virtual void irqReceived()
uint8_t getPciProgInterface()
bool allocate(io_port_t ioPort, size_t size)
uint16_t getPciDeviceId()
void commandComplete()
Called by drivers when a command completes.
PciAtaController(Controller *pDev, int nController=0)
virtual irq_id_t registerIsaIrqHandler(uint8_t irq, IrqHandler *handler, bool bEdge=false)=0
virtual void initialise()
bool isActive() const
Is there currently a DMA transaction taking place?
void clear(bool freeMem=false)
Vector< Device * > m_Children
virtual void write8(uint8_t value, size_t offset=0)
void writeConfigSpace(Device *pDev, uint8_t offset, uint32_t data)