21#include "pedigree/kernel/LockGuard.h"
22#include "pedigree/kernel/Log.h"
23#include "pedigree/kernel/TargetInfo.h"
24#include "pedigree/kernel/compiler.h"
25#include "pedigree/kernel/panic.h"
26#include "pedigree/kernel/processor/IoBase.h"
27#include "pedigree/kernel/processor/Processor.h"
28#include "pedigree/kernel/processor/types.h"
29#include "pedigree/kernel/utilities/Cache.h"
30#include "pedigree/kernel/utilities/PointerGuard.h"
31#include "pedigree/kernel/utilities/assert.h"
32#include "pedigree/kernel/utilities/utility.h"
34#include "AtaController.h"
35#include "AtaWriteCache.h"
36#include "ata-common.h"
39#pragma GCC diagnostic ignored "-Wunreachable-code"
43#define ATA_DEFAULT_BLOCK_SIZE 0x10000 * 2
46constexpr Time::Timestamp AtapiCommandTimeout = 30 * Time::Multiplier::Second;
47constexpr size_t AtapiMaximumStatusPolls = 30000000;
48constexpr Time::Timestamp AtaDmaCompletionTimeout = 30 * Time::Multiplier::Second;
49constexpr size_t AtaDmaCompletionPollLimit = 30000000;
50constexpr Time::Timestamp AtaPioCompletionTimeout = 30 * Time::Multiplier::Second;
51constexpr size_t AtaPioCompletionPollLimit = 30000000;
52constexpr Time::Timestamp AtaFlushCompletionTimeout = 120 * Time::Multiplier::Second;
53constexpr size_t AtaFlushCompletionPollLimit = 120000000;
55bool waitForAtapiStatus(
IoBase* commandRegs,
IoBase* controlRegs, Time::Timestamp commandStarted,
56 size_t& commandPolls,
AtaStatus& status) {
60 if (commandPolls >= AtapiMaximumStatusPolls ||
61 (Time::getTicks() - commandStarted) >= AtapiCommandTimeout) {
62 WARNING(
"ATAPI: PACKET command exceeded its completion deadline");
66 for (
size_t i = 0; i < 4; ++i) {
67 controlRegs->
read8(2);
70 status.__reg_contents = commandRegs->
read8(7);
71 while (status.reg.bsy || (!status.reg.drq && !status.reg.drdy && !status.reg.err)) {
72 if (!status.__reg_contents) {
75 if (++commandPolls >= AtapiMaximumStatusPolls ||
76 (Time::getTicks() - commandStarted) >= AtapiCommandTimeout) {
78 "ATAPI: PACKET command timed out waiting for device status, "
80 << status.__reg_contents);
85 status.__reg_contents = commandRegs->
read8(7);
91class ScopedBusMasterTransaction {
93 explicit ScopedBusMasterTransaction(
BusMasterIde* busMaster)
94 : m_BusMaster(busMaster), m_OwnsTransaction(false) {}
96 ~ScopedBusMasterTransaction() {
100 bool add(uintptr_t buffer,
size_t bytes) {
104 if (!m_OwnsTransaction && !(m_OwnsTransaction = m_BusMaster->beginTransaction())) {
107 return m_BusMaster->add(buffer, bytes);
110 bool begin(
bool write) {
111 return m_OwnsTransaction && m_BusMaster->begin(write);
115 if (m_OwnsTransaction) {
116 m_BusMaster->commandComplete();
117 m_OwnsTransaction =
false;
122 ScopedBusMasterTransaction(
const ScopedBusMasterTransaction&) =
delete;
123 ScopedBusMasterTransaction& operator=(
const ScopedBusMasterTransaction&) =
delete;
126 bool m_OwnsTransaction;
129class CachePageFillGuard {
131 CachePageFillGuard(
Cache& cache, uint64_t location,
bool* insertedPages,
size_t pageCount)
133 m_Location(location),
134 m_InsertedPages(insertedPages),
135 m_PageCount(pageCount),
136 m_Published(false) {}
138 ~CachePageFillGuard() {
143 bool discarded =
true;
144 for (
size_t i = 0; i < m_PageCount; ++i) {
145 if (m_InsertedPages[i] && !m_Cache.discardEditing(m_Location + (i * 4096))) {
151 "AtaDisk could not discard every page from a failed cache "
158 for (
size_t i = 0; i < m_PageCount; ++i) {
159 if (m_InsertedPages[i]) {
160 m_Cache.markNoLongerEditing(m_Location + (i * 4096));
167 CachePageFillGuard(
const CachePageFillGuard&) =
delete;
168 CachePageFillGuard& operator=(
const CachePageFillGuard&) =
delete;
172 bool* m_InsertedPages;
178AtaDisk::IrqCompletion::IrqCompletion(
AtaDisk& disk)
182 m_StackDiscardScope(&IrqCompletion::discard, this) {
184 if (m_Disk.m_IrqReceived) {
185 FATAL(
"ATA command attempted to replace a live IRQ completion");
187 m_Disk.m_IrqReceived = &m_Completion;
191AtaDisk::IrqCompletion::~IrqCompletion() {
195void AtaDisk::IrqCompletion::discard(
void* context) {
196 reinterpret_cast<IrqCompletion*
>(context)->withdraw();
199void AtaDisk::IrqCompletion::withdraw() {
204 if (m_Disk.m_IrqReceived != &m_Completion) {
205 FATAL(
"ATA IRQ completion publication was corrupted");
207 m_Disk.m_IrqReceived =
nullptr;
224 m_ControlRegs(controlRegs),
225 m_BusMaster(busMaster),
236 releasePagingStorage();
239void AtaDisk::shutdownDeviceCache() {
242 ScsiDisk::shutdownDeviceCache();
248 m_ControlRegs->
write8(0x02, 2);
262 ERROR(
"ATA: this driver requires 4096-byte target pages");
271 IoBase* controlRegs = m_ControlRegs;
277 uint8_t devSelect = (
m_IsMaster) ? 0xA0 : 0xB0;
278 commandRegs->
write8(devSelect, 6);
279 commandRegs->
write8(0xEC, 7);
280 if (commandRegs->
read8(7) == 0) {
281 NOTICE(
"ATA: No device present here");
287 commandRegs->
write8(devSelect, 6);
290 ataWait(commandRegs, controlRegs);
293 commandRegs->
write8(8, 7);
296 ataWait(commandRegs, controlRegs);
305 controlRegs->
write8(0x2, 2);
308 commandRegs->
read8(7);
309 commandRegs->
write8(0xEC, 7);
312 status = ataWait(commandRegs, controlRegs);
315 if (status.__reg_contents == 0)
319 uint8_t m1 = commandRegs->
read8(2);
320 uint8_t m2 = commandRegs->
read8(3);
321 uint8_t m3 = commandRegs->
read8(4);
322 uint8_t m4 = commandRegs->
read8(5);
324 NOTICE(
"ATA signature: " << m1 <<
", " << m2 <<
", " << m3 <<
", " << m4);
327 if (m3 == 0x14 && m4 == 0xeb) {
329 commandRegs->
write8(devSelect, 6);
330 commandRegs->
write8(0xA1, 7);
331 status = ataWait(commandRegs, controlRegs);
338 if (status.reg.err) {
339 WARNING(
"ATA drive errored on IDENTIFY!");
344 for (
int i = 0; i < 256; i++) {
349 if (commandRegs->
read8(7) & 1) {
350 WARNING(
"ATA drive now has an error status after reading IDENTIFY data.");
355 if (
m_pIdent.data.signature == 0xA5) {
358 uint8_t* bytes =
reinterpret_cast<uint8_t*
>(
m_pIdent.__raw);
359 for (
size_t i = 0; i < 512; ++i)
364 WARNING(
"ATA IDENTIFY data failed checksum!");
373 ERROR(
"ATA: Device does not conform to the ATA specification.");
376 ERROR(
"ATA: PACKET device does not conform to the ATA specification.");
389 for (
int i = 39; i > 0; i--) {
401 for (
int i = 19; i > 0; i--) {
413 for (
int i = 7; i > 0; i--) {
421 if (
m_pIdent.data.command_sets_support.address48) {
424 WARNING(
"ATA: Device supports LBA48 but it isn't enabled.");
430 ERROR(
"ATA: Device does not support LBA.");
438 NOTICE(
"ATA: Device supports DMA.");
440 if (
m_pIdent.data.validity.multiword_dma_valid) {
441 size_t highest_mode = ~0U;
442 if (
m_pIdent.data.multiword_dma.mode0)
444 if (
m_pIdent.data.multiword_dma.mode1)
446 if (
m_pIdent.data.multiword_dma.mode2)
449 size_t sel_mode = ~0U;
450 if (
m_pIdent.data.multiword_dma.sel_mode0)
452 if (
m_pIdent.data.multiword_dma.sel_mode1)
454 if (
m_pIdent.data.multiword_dma.sel_mode2)
457 if (highest_mode != ~0U) {
458 NOTICE(
"ATA: Device Multiword DMA: supports up to mode" <<
Dec << highest_mode <<
Hex);
460 NOTICE(
"ATA: Device Multiword DMA: no support");
463 if (sel_mode != ~0U) {
464 NOTICE(
"ATA: Device Multiword DMA: mode" <<
Dec << sel_mode <<
Hex <<
" is selected");
468 if (
m_pIdent.data.validity.ultra_dma_valid) {
469 size_t highest_mode = ~0U;
470 if (
m_pIdent.data.ultra_dma.supp_mode0)
472 if (
m_pIdent.data.ultra_dma.supp_mode1)
474 if (
m_pIdent.data.ultra_dma.supp_mode2)
476 if (
m_pIdent.data.ultra_dma.supp_mode3)
478 if (
m_pIdent.data.ultra_dma.supp_mode4)
480 if (
m_pIdent.data.ultra_dma.supp_mode5)
482 if (
m_pIdent.data.ultra_dma.supp_mode6)
485 size_t sel_mode = ~0U;
486 if (
m_pIdent.data.ultra_dma.sel_mode0)
488 if (
m_pIdent.data.ultra_dma.sel_mode1)
490 if (
m_pIdent.data.ultra_dma.sel_mode2)
492 if (
m_pIdent.data.ultra_dma.sel_mode3)
494 if (
m_pIdent.data.ultra_dma.sel_mode4)
496 if (
m_pIdent.data.ultra_dma.sel_mode5)
498 if (
m_pIdent.data.ultra_dma.sel_mode6)
501 if (highest_mode != ~0U) {
502 NOTICE(
"ATA: Device Ultra DMA: supports up to mode" <<
Dec << highest_mode <<
Hex);
504 NOTICE(
"ATA: Device Ultra DMA: no support");
507 if (sel_mode != ~0U) {
508 NOTICE(
"ATA: Device Ultra DMA: mode" <<
Dec << sel_mode <<
Hex <<
" is enabled");
516 WARNING(
"ATA: Controller does not support DMA");
520 if (
m_pIdent.data.sector_size.logical_larger_than_512b ||
521 m_pIdent.data.sector_size.multiple_logical_per_physical) {
523 size_t logical_size = 512;
524 if (
m_pIdent.data.sector_size.logical_larger_than_512b)
525 logical_size =
m_pIdent.data.words_per_logical *
sizeof(uint16_t);
528 size_t log_per_phys = 1 <<
m_pIdent.data.sector_size.logical_per_physical;
529 size_t physical_size = log_per_phys * logical_size;
531 NOTICE(
"ATA: Physical sector size is " <<
Dec << physical_size <<
Hex <<
" bytes.");
532 NOTICE(
"ATA: Logical sector size is " <<
Dec << logical_size <<
Hex <<
" bytes.");
534 if (physical_size > 512) {
539 "ATA: Default block size doesn't map well to physical "
540 "sectors, performance may be degraded.");
559 commandRegs->
write8(devSelect, 6);
560 commandRegs->
write8(0xDA, 7);
561 status = ataWait(commandRegs, controlRegs);
562 if (status.reg.err) {
564 uint8_t err = commandRegs->
read8(1);
568 WARNING(
"ATAPI: device does not support GET MEDIA STATUS.");
569 }
else if (err & 2) {
570 WARNING(
"ATAPI: No media present in the drive - aborting.");
572 " TODO: handle media changes/insertions/removal "
576 NOTICE(
"ATAPI: Media status: " << err <<
".");
582 ERROR(
"ATAPI: ScsiDisk init failed.");
588 m_Removable = ((pInquiry->Removable & (1 << 7)) != 0);
589 AtaDiskType inquiryType =
static_cast<AtaDiskType
>(pInquiry->Peripheral & 0x1F);
592 "ATAPI: IDENTIY PACKET DEVICE and SCSI INQUIRY disagree on "
602 "Pedigree currently only supports CD/DVD and block ATAPI "
608 preparePagingStorage();
617bool AtaDisk::sendCommand(
size_t nUnit, uintptr_t pCommand, uint8_t nCommandSize,
618 uintptr_t pRespBuffer, uint16_t nRespBytes,
bool bWrite) {
620 ERROR(
"AtaDisk::sendCommand called on a non-PACKET device");
625 ERROR(
"sendCommand called but the packet size is not known!");
632 IoBase* controlRegs = m_ControlRegs;
637 ERROR(
"ATAPI command is " <<
Dec << nCommandSize <<
" bytes, but the device accepts only "
641 MemoryCopy(tmpPacket,
reinterpret_cast<void*
>(pCommand), nCommandSize);
642 ByteSet(
reinterpret_cast<uint8_t*
>(tmpPacket) + nCommandSize, 0,
m_PacketSize - nCommandSize);
645 controlRegs->
write8(2, 2);
651 commandRegs->
write8(devSelect, 6);
652 ataWait(commandRegs, controlRegs);
655 if ((commandRegs->
read8(6) & devSelect) != devSelect) {
656 WARNING(
"ATAPI: Device was not selected");
660 ScopedBusMasterTransaction dmaTransaction(m_BusMaster);
661 bool bDmaSetup =
false;
662 if (
m_bDma && nRespBytes) {
663 bDmaSetup = dmaTransaction.add(pRespBuffer, nRespBytes);
667 bDmaSetup = dmaTransaction.begin(bWrite);
672 if ((
m_pIdent.__raw[62] & (1 << 15)) &&
674 commandRegs->
write8((bWrite ? 1 : 5), 1);
676 commandRegs->
write8(1, 1);
678 commandRegs->
write8(0, 1);
679 commandRegs->
write8(0, 2);
680 commandRegs->
write8(0, 3);
681 commandRegs->
write8(nRespBytes & 0xFF, 4);
682 commandRegs->
write8(((nRespBytes >> 8) & 0xFF), 5);
687 const Time::Timestamp commandStarted = Time::getTicks();
688 size_t commandPolls = 0;
692 commandRegs->
write8(0xA0, 7);
695 if (!waitForAtapiStatus(commandRegs, controlRegs, commandStarted, commandPolls, status)) {
700 if (status.reg.err) {
701 ERROR(
"ATAPI Packet command error [status=" << status.__reg_contents <<
"]!");
707 commandRegs->
write16(tmpPacket[i], 0);
711 for (
size_t i = 0; i < 4; ++i)
712 controlRegs->
read8(2);
716 uint8_t statusreg = commandRegs->
read8(7);
717 if ((statusreg & 1) && !(statusreg & 0x80)) {
719 uint8_t error = commandRegs->
read8(1);
721 WARNING(
"ATAPI command failed (ABORT)");
723 WARNING(
"ATAPI error with status " << statusreg <<
" [error=" << error <<
"]");
732 if (!waitForAtapiStatus(commandRegs, controlRegs, commandStarted, commandPolls, status)) {
735 return !status.reg.err;
740 if (commandPolls >= AtapiMaximumStatusPolls ||
741 (Time::getTicks() - commandStarted) >= AtapiCommandTimeout) {
742 WARNING(
"ATAPI: DMA command timed out");
746 status.__reg_contents = commandRegs->
read8(7);
747 if (!status.reg.bsy && status.reg.err) {
748 WARNING(
"ATAPI: read failed during DMA data transfer");
755 bool bError = m_BusMaster->
hasError();
756 dmaTransaction.complete();
767 if (!waitForAtapiStatus(commandRegs, controlRegs, commandStarted, commandPolls, status)) {
770 if (status.reg.err) {
771 WARNING(
"ATAPI sendCommand failed after sending command packet");
772 logAtaStatus(status);
781 size_t transferred = 0;
782 size_t pioPhases = 0;
783 const size_t maximumPioPhases = nRespBytes /
sizeof(uint16_t);
785 if ((Time::getTicks() - commandStarted) >= AtapiCommandTimeout) {
786 WARNING(
"ATAPI: PIO command timed out");
789 if (!waitForAtapiStatus(commandRegs, controlRegs, commandStarted, commandPolls, status)) {
792 if (status.reg.err) {
793 WARNING(
"ATAPI PIO command failed during a data phase");
794 logAtaStatus(status);
797 if (!status.reg.drq) {
800 if (++pioPhases > maximumPioPhases) {
801 ERROR(
"ATAPI PIO command exceeded its possible data-phase count");
805 size_t realSz = commandRegs->
read8(4) | (commandRegs->
read8(5) << 8);
807 ERROR(
"ATAPI PIO data phase reported a zero byte count");
811 ERROR(
"ATAPI PIO data phase reported an odd byte count");
815 const size_t remaining = nRespBytes - transferred;
816 const size_t transferSz = realSz < remaining ? realSz : remaining;
817 uint16_t* dest =
reinterpret_cast<uint16_t*
>(pRespBuffer + transferred);
818 for (
size_t i = 0; i < (transferSz / 2); ++i) {
820 commandRegs->
write16(dest[i], 0);
822 dest[i] = commandRegs->
read16(0);
829 for (
size_t i = transferSz; i < realSz; i +=
sizeof(uint16_t)) {
831 commandRegs->
write16(0xFFFF, 0);
835 if (realSz > remaining) {
836 ERROR(
"ATAPI PIO data phase exceeds the response buffer: phase="
837 <<
Dec << realSz <<
", remaining=" << remaining <<
Hex);
840 transferred += transferSz;
849 static char alreadyRead[4096]
ALIGN(4096);
859 ERROR(
"ATA: cache fill did not cover a complete 4096-byte cache page");
862 const uint64_t cacheLocation = location;
863 uint64_t ioLocation = location;
867 size_t nBuffers = nBytes / 0x1000;
870 bool* insertedPages =
new bool[nBuffers];
872 ByteSet(insertedPages, 0, nBuffers *
sizeof(
bool));
873 CachePageFillGuard fillGuard(getCache(), cacheLocation, insertedPages, nBuffers);
875 bool bAlreadyAllRead =
true;
876 for (
size_t i = 0; i < nBuffers; ++i) {
877 buffers[i].
offset = i * 0x1000;
879 uintptr_t buffer = getCache().
lookup(location + buffers[i].offset);
881 getCache().
release(location + buffers[i].offset);
882 buffer =
reinterpret_cast<uintptr_t
>(alreadyRead);
884 bool didExist =
false;
885 buffer = getCache().
insert(location + buffers[i].offset, &didExist);
887 FATAL(
"AtaDisk::doRead - couldn't get a buffer!");
892 buffer =
reinterpret_cast<uintptr_t
>(alreadyRead);
894 insertedPages[i] =
true;
895 bAlreadyAllRead =
false;
899 buffers[i].
buffer = buffer;
902 if (bAlreadyAllRead) {
909 IoBase* controlRegs = m_ControlRegs;
913 uint32_t nSectors = nBytes / 512;
917 ataWait(commandRegs, controlRegs);
925 commandRegs->
write8(devSelect, 6);
928 ataWait(commandRegs, controlRegs);
930 size_t buffersConsumed = 0;
931 while (nSectors > 0) {
932 ScopedBusMasterTransaction dmaTransaction(m_BusMaster);
937 status = ataWait(commandRegs, controlRegs);
938 if (status.reg.err || !status.reg.drdy) {
939 ERROR(
"ATA: drive did not become ready for read");
944 uint8_t nSectorsToRead = min(
m_pIdent.data.max_sectors_per_irq, nSectors);
945 nSectors -= nSectorsToRead;
949 size_t buffersThisRead = (nSectorsToRead * 512) / 0x1000;
950 const size_t firstBuffer = buffersConsumed;
952 bool bDmaSetup =
false;
954 for (
size_t i = 0; i < buffersThisRead; ++i) {
955 bDmaSetup = dmaTransaction.add(buffers[firstBuffer + i].buffer, 0x1000);
957 ERROR(
"DMA setup failed!");
966 if (ioLocation >= 0x2000000000ULL) {
968 "Ata: Sector > 128GB requested but LBA48 addressing "
978 controlRegs->
write8(0, 2);
985 if (
m_bDma && bDmaSetup) {
987 bDmaSetup = dmaTransaction.begin(
false);
991 commandRegs->
write8(0xC8, 7);
994 commandRegs->
write8(0x25, 7);
999 commandRegs->
write8(0x24, 7);
1002 commandRegs->
write8(0x20, 7);
1006 const Time::Timestamp completionStarted = Time::getTicks();
1007 size_t completionPolls = 0;
1011 if (++completionPolls >= AtaDmaCompletionPollLimit ||
1012 (Time::getTicks() - completionStarted) >= AtaDmaCompletionTimeout) {
1013 ERROR(
"ATA: DMA read exceeded its completion deadline");
1020 ERROR(
"ATA: timeout during data transfer");
1026 status = ataWait(commandRegs, controlRegs);
1027 if (status.reg.err) {
1029 if (
m_bDma && bDmaSetup) {
1030 WARNING(
"ATA: read failed during DMA data transfer");
1035 if (
m_bDma && bDmaSetup) {
1039 bool bError = m_BusMaster->
hasError();
1040 dmaTransaction.complete();
1054 size_t byteOffset = firstBuffer * 0x1000;
1055 for (
int i = 0; i < nSectorsToRead; i++) {
1057 status = ataWait(commandRegs, controlRegs);
1058 if (status.reg.err) {
1061 WARNING(
"ATA: read failed during data transfer");
1066 size_t nBuffer = byteOffset / 0x1000;
1067 size_t offset = byteOffset % 0x1000;
1070 uint16_t* target =
reinterpret_cast<uint16_t*
>(buffers[nBuffer].
buffer + offset);
1071 for (
int j = 0; j < 256; j++) {
1072 *target++ = commandRegs->
read16(0);
1079 buffersConsumed += buffersThisRead;
1080 ioLocation += nSectorsToRead * 512;
1083 assert(buffersConsumed == nBuffers);
1085 fillGuard.publish();
1091 panic(
"AtaDisk: write request not on a sector boundary!");
1102 getCache().endMutableLoan(location);
1112 const uintptr_t buffer = ataTakeQueuedWritePage(getCache(), location);
1114 ERROR(
"AtaDisk::doWrite - queued buffer was not in cache");
1125 if ((location % 512) || !page)
1139uint64_t AtaDisk::doSync(uint64_t location) {
1145 return ScsiDisk::doSync(location);
1148 const bool wholeDevice = location == SyncWholeDevice;
1153 const size_t validLength =
1155 if (!nativeBlockSize || !validLength ||
1156 (!wholeDevice && ((location % nativeBlockSize) || (validLength % nativeBlockSize))) ||
1161 if ((
m_pIdent.__raw[83] & 0xC000) != 0x4000) {
1165 if (!extended && !
m_pIdent.data.command_sets_support.flush_cache) {
1166 WARNING(
"ATA: device does not advertise a supported cache flush command");
1172 m_ControlRegs->
write8(2, 2);
1174 if (status.reg.bsy || status.reg.drq) {
1179 if (status.reg.bsy || status.reg.drq || status.reg.df || !status.reg.drdy) {
1186 AtaFlushCompletionPollLimit};
1188 status.__reg_contents = 0;
1189 if (!ataPollPioWriteStatus(
m_CommandRegs, m_ControlRegs, budget, status,
false)) {
1190 WARNING(
"ATA: cache flush failed or exceeded its completion deadline, status="
1191 << status.__reg_contents);
1198 const uintptr_t nBytes = 0x1000;
1201 ERROR(
"ATA: writes require 512-byte logical sectors");
1206 NOTICE(
"doWrite(" << location <<
")");
1211 IoBase* controlRegs = m_ControlRegs;
1214 uint32_t nSectors = nBytes / 512;
1220 ataWait(commandRegs, controlRegs);
1228 commandRegs->
write8(devSelect, 6);
1231 ataWait(commandRegs, controlRegs);
1233 uint16_t* tmp =
reinterpret_cast<uint16_t*
>(buffer);
1235 while (nSectors > 0) {
1236 ScopedBusMasterTransaction dmaTransaction(m_BusMaster);
1240 status = ataWait(commandRegs, controlRegs);
1241 if (status.reg.err || !status.reg.drdy) {
1242 ERROR(
"ATA: drive did not become ready for write");
1248 uint8_t nSectorsToWrite =
1249 m_bDma ? min(
m_pIdent.data.max_sectors_per_irq, nSectors) :
static_cast<uint8_t
>(nSectors);
1251 bool bDmaSetup =
false;
1252 if (
m_bDma && nSectorsToWrite) {
1253 bDmaSetup = dmaTransaction.add(buffer, nSectorsToWrite * 512);
1256 nSectorsToWrite =
static_cast<uint8_t
>(nSectors);
1258 nSectors -= nSectorsToWrite;
1263 if (location >= 0x2000000000ULL) {
1265 "Ata: Sector > 128GB requested but LBA48 addressing "
1272 controlRegs->
write8(0, 2);
1280 if (
m_bDma && bDmaSetup) {
1282 if (!dmaTransaction.begin(
true)) {
1283 ERROR(
"ATA: failed to start DMA write");
1289 commandRegs->
write8(0xCA, 7);
1292 commandRegs->
write8(0x35, 7);
1294 const Time::Timestamp completionStarted = Time::getTicks();
1295 size_t completionPolls = 0;
1299 if (++completionPolls >= AtaDmaCompletionPollLimit ||
1300 (Time::getTicks() - completionStarted) >= AtaDmaCompletionTimeout) {
1301 ERROR(
"ATA: DMA write exceeded its completion deadline");
1308 WARNING(
"ATA: failed to get IRQ");
1314 status = ataWait(commandRegs, controlRegs);
1315 if (status.reg.err) {
1317 WARNING(
"ATA: write failed during DMA data transfer");
1324 bool bError = m_BusMaster->
hasError();
1325 dmaTransaction.complete();
1335 AtaPioCompletionPollLimit};
1339 commandRegs->
write8(0x34, 7);
1342 commandRegs->
write8(0x30, 7);
1347 if (!ataPioWrite512ByteSectors(commandRegs, controlRegs, tmp, nSectorsToWrite, budget,
1349 WARNING(
"ATA: PIO write failed, status=" << status.__reg_contents);
1356 NOTICE(
"ATA: successfully wrote " << nBytes <<
" bytes to disk.");
1371 commandRegs->
write8(
static_cast<uint8_t
>(nSectors & 0xFF), 2);
1376 uint8_t sector =
static_cast<uint8_t
>(n & 0xFF);
1377 uint8_t cLow =
static_cast<uint8_t
>((n >> 8) & 0xFF);
1378 uint8_t cHigh =
static_cast<uint8_t
>((n >> 16) & 0xFF);
1379 uint8_t head =
static_cast<uint8_t
>((n >> 24) & 0x0F);
1385 commandRegs->
write8(head, 6);
1386 commandRegs->
write8(sector, 3);
1387 commandRegs->
write8(cLow, 4);
1388 commandRegs->
write8(cHigh, 5);
1397 uint8_t lba1 =
static_cast<uint8_t
>(n & 0xFF);
1398 uint8_t lba2 =
static_cast<uint8_t
>((n >> 8) & 0xFF);
1399 uint8_t lba3 =
static_cast<uint8_t
>((n >> 16) & 0xFF);
1400 uint8_t lba4 =
static_cast<uint8_t
>((n >> 24) & 0xFF);
1401 uint8_t lba5 =
static_cast<uint8_t
>((n >> 32) & 0xFF);
1402 uint8_t lba6 =
static_cast<uint8_t
>((n >> 40) & 0xFF);
1404 commandRegs->
write8((nSectors & 0xFFFF) >> 8, 2);
1405 commandRegs->
write8(lba4, 3);
1406 commandRegs->
write8(lba5, 4);
1407 commandRegs->
write8(lba6, 5);
1408 commandRegs->
write8((nSectors & 0xFF), 2);
1409 commandRegs->
write8(lba1, 3);
1410 commandRegs->
write8(lba2, 4);
1411 commandRegs->
write8(lba3, 5);
1419 uint8_t devSelect = (
m_IsMaster) ? 0xA0 : 0xB0;
1420 commandRegs->
write8(devSelect, 6);
1422 commandRegs->
write8(command, 1);
1423 commandRegs->
write8(countreg, 2);
1424 commandRegs->
write8(lowreg, 3);
1425 commandRegs->
write8(midreg, 4);
1426 commandRegs->
write8(hireg, 5);
1427 commandRegs->
write8(0xEF, 7);
1436 size_t sector_count = 0;
1440 sector_count =
m_pIdent.data.max_user_lba48;
1442 sector_count =
m_pIdent.data.sector_count;
1444 sector_count =
m_pIdent.data.sector_count;
1448 size_t sector_size = 512;
1449 if (
m_pIdent.data.sector_size.logical_larger_than_512b) {
1451 sector_size =
m_pIdent.data.words_per_logical *
sizeof(uint16_t);
1454 return sector_count * sector_size;
1477 size_t sector_size = 512;
1478 if (
m_pIdent.data.sector_size.logical_larger_than_512b) {
1480 sector_size =
m_pIdent.data.words_per_logical *
sizeof(uint16_t);
1486size_t AtaDisk::getBlockCount()
const {
1488 return ScsiDisk::getBlockCount();
1492 size_t sector_count = 0;
1496 sector_count =
m_pIdent.data.max_user_lba48;
1498 sector_count =
m_pIdent.data.sector_count;
1500 sector_count =
m_pIdent.data.sector_count;
1503 return sector_count;
AtaDiskType m_AtaDiskType
virtual MUST_USE_RESULT uint64_t doWriteDirect(uint64_t location, uintptr_t page)
void setupLBA28(uint64_t n, uint32_t nSectors)
virtual uint64_t doWrite(uint64_t location)
virtual size_t getNativeBlockSize() const
Semaphore * m_IrqReceived
virtual size_t getCacheFillSize() const
size_t m_LastPrdTableOffset
void setFeatures(uint8_t command, uint8_t countreg, uint8_t lowreg, uint8_t midreg, uint8_t hireg)
bool initialise(size_t nUnit=~0)
char m_pFirmwareRevision[64]
physical_uintptr_t m_PrdTablePhys
void setupLBA48(uint64_t n, uint32_t nSectors)
virtual uint64_t doRead(uint64_t location)
PhysicalRegionDescriptor * m_PrdTable
virtual void irqReceived()
uint64_t writePageBuffer(uint64_t location, uintptr_t page)
MemoryRegion m_PrdTableMemRegion
virtual size_t getSize() const
Gets the size of the disk.
virtual size_t getBlockSize() const
Gets the preferred I/O extent of the disk.
bool hasError()
Determines if an ERROR has occurred on this channel.
bool hasCompleted()
Determines if the CURRENT TRANSFER has completed.
void commandComplete()
Called by drivers when a command completes.
bool hasInterrupt()
Determines if an INTERRUPT has occurred on this channel.
void release(uintptr_t key)
uintptr_t insert(uintptr_t key, bool *alreadyExisted=nullptr)
uintptr_t lookup(uintptr_t key)
virtual uintptr_t getInterruptNumber()
Abstrace base class for hardware I/O capabilities.
virtual uint8_t read8(size_t offset=0)=0
virtual void write8(uint8_t value, size_t offset=0)=0
virtual void write16(uint16_t value, size_t offset=0)=0
virtual uint16_t read16(size_t offset=0)=0
static bool getInterrupts()
static void setInterrupts(bool bEnable)
virtual uint64_t doRead(uint64_t location)
bool initialise(class ScsiController *pController, size_t nUnit)
virtual size_t getSize() const
Gets the size of the disk.
size_t getCacheFillLength(uint64_t location) const
virtual size_t getCacheFillSize() const
virtual size_t getBlockSize() const
Gets the preferred I/O extent of the disk.
virtual size_t getNativeBlockSize() const
MUST_USE_RESULT bool acquireForCompletion(size_t n=1, size_t timeoutSecs=0, size_t timeoutUsecs=0)
static constexpr size_t getPageSize() noexcept
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
size_t offset
Offset into the read.
uintptr_t buffer
Virtual address of buffer to read into (page sized).