| 170 | } |
| 171 | |
| 172 | int Access(ATADiskDevice* drive, uint64_t lba, uint16_t count, bool write){ |
| 173 | if(count > 1){ |
| 174 | Log::Warning("ATA::Read was called with count > 1"); |
| 175 | return 1; |
| 176 | } |
| 177 | |
| 178 | outportb(busMasterPort + ATA_BMR_CMD, 0); |
| 179 | outportd(busMasterPort + ATA_BMR_PRDT_ADDRESS, drive->prdtPhys); |
| 180 | |
| 181 | outportb(busMasterPort + ATA_BMR_STATUS, inportb(busMasterPort + ATA_BMR_STATUS) | 4 | 2); // Clear Error and Interrupt Bits |
| 182 | |
| 183 | WriteRegister(drive->port, ATA_REGISTER_DRIVE_HEAD, 0x40 | (drive->drive << 4)); |
| 184 | |
| 185 | for(int i = 0; i < 4; i++) inportb(controlPort0); |
| 186 | |
| 187 | while(ReadRegister(drive->port, ATA_REGISTER_STATUS) & ATA_DEV_BUSY); |
| 188 | |
| 189 | WriteRegister(drive->port, ATA_REGISTER_SECTOR_COUNT, (count >> 8) & 0xFF); |
| 190 | |
| 191 | WriteRegister(drive->port, ATA_REGISTER_LBA_LOW, (lba >> 24) & 0xFF); |
| 192 | WriteRegister(drive->port, ATA_REGISTER_LBA_MID, (lba >> 32) & 0xFF); |
| 193 | WriteRegister(drive->port, ATA_REGISTER_LBA_HIGH, (lba >> 40) & 0xFF); |
| 194 | |
| 195 | for(int i = 0; i < 4; i++) inportb(controlPort0); |
| 196 | |
| 197 | WriteRegister(drive->port, ATA_REGISTER_SECTOR_COUNT, count & 0xFF); |
| 198 | |
| 199 | WriteRegister(drive->port, ATA_REGISTER_LBA_LOW, lba & 0xFF); |
| 200 | WriteRegister(drive->port, ATA_REGISTER_LBA_MID, (lba >> 8) & 0xFF); |
| 201 | WriteRegister(drive->port, ATA_REGISTER_LBA_HIGH, (lba >> 16) & 0xFF); |
| 202 | |
| 203 | for(int i = 0; i < 4; i++) inportb(controlPort0); |
| 204 | |
| 205 | while(ReadRegister(drive->port, ATA_REGISTER_STATUS) & 0x80 || !(ReadRegister(drive->port, ATA_REGISTER_STATUS) & 0x40)); |
| 206 | |
| 207 | if(write){ |
| 208 | WriteRegister(drive->port, ATA_REGISTER_COMMAND, 0x35); // 48-bit write DMA |
| 209 | } else { |
| 210 | WriteRegister(drive->port, ATA_REGISTER_COMMAND, 0x25); // 48-bit read DMA |
| 211 | } |
| 212 | |
| 213 | if(write){ |
| 214 | outportb(busMasterPort + ATA_BMR_CMD, 0 /*Write*/ | 1 /*Start*/); |
| 215 | } else { |
| 216 | outportb(busMasterPort + ATA_BMR_CMD, 8 /*Read*/ | 1 /*Start*/); |
| 217 | } |
| 218 | |
| 219 | uint8_t status = ReadRegister(drive->port, ATA_REGISTER_STATUS); |
| 220 | while(status & ATA_DEV_BUSY){ |
| 221 | if(status & ATA_DEV_ERR){ |
| 222 | break; |
| 223 | } |
| 224 | |
| 225 | status = ReadRegister(drive->port, ATA_REGISTER_STATUS); |
| 226 | } |
| 227 | |
| 228 | outportb(busMasterPort + ATA_BMR_CMD, 0); |
| 229 |
no test coverage detected