Skip to content

Commit

Permalink
atahd: implement mandatory SET_MULTIPLE_MODE command.
Browse files Browse the repository at this point in the history
  • Loading branch information
maximumspatium committed Aug 21, 2024
1 parent f5c9196 commit bd16b7c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 5 deletions.
1 change: 1 addition & 0 deletions devices/common/ata/atadefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ enum ATA_Cmd : uint8_t {
ATAPI_SERVICE = 0xA2,
READ_MULTIPLE = 0xC4,
WRITE_MULTIPLE = 0xC5,
SET_MULTIPLE_MODE = 0xC6,
READ_DMA = 0xC8,
WRITE_DMA = 0xCA,
STANDBY_IMMEDIATE_E0 = 0xE0,
Expand Down
21 changes: 18 additions & 3 deletions devices/common/ata/atahd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <machines/machinebase.h>
#include <memaccess.h>

#include <bitset>
#include <cstring>
#include <fstream>
#include <string>
Expand Down Expand Up @@ -116,16 +117,29 @@ int AtaHardDisk::perform_command() {
this->r_status &= ~BSY;
}
break;
case DIAGNOSTICS:
this->r_error = 1;
this->device_set_signature();
break;
case INIT_DEV_PARAM:
// update fictive disk geometry with parameters from host
this->sectors = this->r_sect_count;
this->heads = (this->r_dev_head & 0xF) + 1;
this->r_status &= ~BSY;
this->update_intrq(1);
break;
case DIAGNOSTICS:
this->r_error = 1;
this->device_set_signature();
case SET_MULTIPLE_MODE: // this command is mandatory for ATA devices
if (!this->r_sect_count || this->r_sect_count > 128 ||
std::bitset<8>(this->r_sect_count).count() != 1) { // power of two?
this->multiple_enabled = false;
this->r_error |= ABRT;
this->r_status |= ERR;
} else {
this->sec_per_block = this->r_sect_count;
this->multiple_enabled = true;
}
this->r_status &= ~BSY;
this->update_intrq(1);
break;
case FLUSH_CACHE: // used by the XNU kernel driver
this->r_status &= ~(BSY | DRQ | ERR);
Expand Down Expand Up @@ -184,6 +198,7 @@ void AtaHardDisk::prepare_identify_info() {
std::memset(this->data_buf, 0, sizeof(this->data_buf));

buf_ptr[ 0] = 0x0040; // ATA device, non-removable media, non-removable drive
buf_ptr[47] = this->sec_per_block; // block size of READ_MULTIPLE/WRITE_MULTIPLE
buf_ptr[49] = 0x0200; // report LBA support

buf_ptr[ 1] = this->cylinders;
Expand Down
5 changes: 3 additions & 2 deletions devices/common/ata/atahd.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ class AtaHardDisk : public AtaBaseDevice
uint8_t heads;
uint8_t sectors;

char * buffer = new char[1 <<17];
uint8_t sec_per_block = 8; // sectors per block for READ_MULTIPLE/WRITE_MULTIPLE
bool multiple_enabled = true; // READ_MULTIPLE/WRITE_MULTIPLE enabled

//uint8_t hd_id_data[ATA_HD_SEC_SIZE] = {};
char * buffer = new char[1 <<17];
};

#endif // ATA_HARD_DISK_H

0 comments on commit bd16b7c

Please sign in to comment.