Minor fixes.

This commit is contained in:
Enrico Fraccaroli
2021-12-13 09:44:35 +01:00
parent 4c8ce44426
commit b48d2ad54a
+75 -67
View File
@@ -82,65 +82,71 @@ typedef enum {
ata_dma_command_write_no_retry = 0xCB, ///< Write DMA without retries (28 bit LBA).
} ata_dma_command_t;
typedef enum {
ata_command_ident = 0xEC, ///< Identify Device.
} ata_command_t;
#if 0
/// @name ATA Commands
/// @{
#define ATA_CMD_READ 0x20 ///< Read Sectors (with retries)
#define ATA_CMD_READN 0x21 ///< Read Sectors (no retries)
#define ATA_CMD_WRITE 0x30 ///< Write Sectores (with retries)
#define ATA_CMD_WRITEN 0x31 ///< Write Sectors (no retries)
#define ATA_CMD_VRFY 0x40 ///< Read Verify (with retries)
#define ATA_CMD_VRFYN 0x41 ///< Read verify (no retries)
#define ATA_CMD_SEEK 0x70 ///< Seek
#define ATA_CMD_DIAG 0x90 ///< Execute Device Diagnostic
#define ATA_CMD_INIT 0x91 ///< Initialize Device Parameters
#define ATA_CMD_RD_MULT 0xC4 ///< Read Multiple
#define ATA_CMD_WR_MULT 0xC5 ///< Write Multiple
#define ATA_CMD_SETMULT 0xC6 ///< Set Multiple Mode
#define ATA_CMD_IDENT 0xEC ///< Identify Device
#define ATA_CMD_CH_FLSH 0xE7 ///< Cache flush.
#define ATA_CMD_SETF 0xEF ///< Set Features
#define ATA_CMD_CHK_PWR 0xE5 ///< Check Power Mode
#define ATA_CMD_READ 0x20 ///< Read Sectors (with retries)
#define ATA_CMD_READN 0x21 ///< Read Sectors (no retries)
#define ATA_CMD_WRITE 0x30 ///< Write Sectores (with retries)
#define ATA_CMD_WRITEN 0x31 ///< Write Sectors (no retries)
#define ATA_CMD_VRFY 0x40 ///< Read Verify (with retries)
#define ATA_CMD_VRFYN 0x41 ///< Read verify (no retries)
#define ATA_CMD_SEEK 0x70 ///< Seek
#define ATA_CMD_DIAG 0x90 ///< Execute Device Diagnostic
#define ATA_CMD_INIT 0x91 ///< Initialize Device Parameters
#define ATA_CMD_RD_MULT 0xC4 ///< Read Multiple
#define ATA_CMD_WR_MULT 0xC5 ///< Write Multiple
#define ATA_CMD_SETMULT 0xC6 ///< Set Multiple Mode
#define ata_command_ident 0xEC ///< Identify Device
#define ATA_CMD_CH_FLSH 0xE7 ///< Cache flush.
#define ATA_CMD_SETF 0xEF ///< Set Features
#define ATA_CMD_CHK_PWR 0xE5 ///< Check Power Mode
/// @}
/// @name ATA Identification Space Bits
/// @brief Definitions used to read information from the identification space.
/// @{
#define ATA_IDENT_DEVICETYPE 0 ///<
#define ATA_IDENT_CYLINDERS 2 ///<
#define ATA_IDENT_HEADS 6 ///<
#define ATA_IDENT_SECTORS 12 ///<
#define ATA_IDENT_SERIAL 20 ///<
#define ATA_IDENT_MODEL 54 ///<
#define ATA_IDENT_CAPABILITIES 98 ///<
#define ATA_IDENT_FIELDVALID 106 ///<
#define ATA_IDENT_MAX_LBA 120 ///<
#define ATA_IDENT_COMMANDSETS 164 ///<
#define ATA_IDENT_MAX_LBA_EXT 200 ///<
#define ATA_IDENT_DEVICETYPE 0 ///<
#define ATA_IDENT_CYLINDERS 2 ///<
#define ATA_IDENT_HEADS 6 ///<
#define ATA_IDENT_SECTORS 12 ///<
#define ATA_IDENT_SERIAL 20 ///<
#define ATA_IDENT_MODEL 54 ///<
#define ATA_IDENT_CAPABILITIES 98 ///<
#define ATA_IDENT_FIELDVALID 106 ///<
#define ATA_IDENT_MAX_LBA 120 ///<
#define ATA_IDENT_COMMANDSETS 164 ///<
#define ATA_IDENT_MAX_LBA_EXT 200 ///<
/// @}
/// @name ATA Interface Type
/// @{
#define IDE_ATA 0x00 ///< ATA (Advanced Technology Attachment) interface.
#define IDE_ATAPI 0x01 ///< Extended ATA with support for SCSI command set.
#define IDE_ATA 0x00 ///< ATA (Advanced Technology Attachment) interface.
#define IDE_ATAPI 0x01 ///< Extended ATA with support for SCSI command set.
/// @}
/// @name ATA Interface Priority
/// @{
#define ATA_DEVICE_0 0x00 ///<
#define ATA_DEVICE_1 0x01 ///<
#define ATA_DEVICE_0 0x00 ///<
#define ATA_DEVICE_1 0x01 ///<
/// @}
/// @name ATA Channels
/// @{
#define ATA_PRIMARY 0x00 ///< Primary channel.
#define ATA_SECONDARY 0x01 ///< Secondary channel.
#define ATA_PRIMARY 0x00 ///< Primary channel.
#define ATA_SECONDARY 0x01 ///< Secondary channel.
/// @}
/// @name ATA Directions
/// @{
#define ATA_READ 0x00 ///< Read direction.
#define ATA_WRITE 0x01 ///< Write direction.
#define ATA_READ 0x00 ///< Read direction.
#define ATA_WRITE 0x01 ///< Write direction.
/// @}
#endif
/// @brief Stores information of a channel.
typedef struct ide_channel_regs_t {
@@ -401,13 +407,27 @@ static void ata_device_write_sector(ata_device_t *, uint64_t, uint8_t *);
static vfs_file_t *ata_open(const char *, int, mode_t);
static int ata_close(vfs_file_t *);
static ssize_t ata_read(vfs_file_t *, char *, off_t, size_t);
static ssize_t atapi_read(vfs_file_t *, char *, off_t, size_t);
static ssize_t ata_write(vfs_file_t *, const void *, off_t, size_t);
static int ata_fstat(vfs_file_t *file, stat_t *stat);
static int ata_stat(const char *path, stat_t *stat);
// == SUPPORT FUNCTIONS =======================================================
static inline const char *ata_get_device_status_str(ata_device_t *dev)
{
static char status_str[9] = { 0 };
uint8_t status = inportb(dev->io_reg.status);
status_str[ata_status_err] = bit_check(status, ata_status_err) ? 'e' : ' ';
status_str[ata_status_idx] = bit_check(status, ata_status_idx) ? 'i' : ' ';
status_str[ata_status_corr] = bit_check(status, ata_status_corr) ? 'c' : ' ';
status_str[ata_status_drq] = bit_check(status, ata_status_drq) ? 'd' : ' ';
status_str[ata_status_srv] = bit_check(status, ata_status_srv) ? 's' : ' ';
status_str[ata_status_df] = bit_check(status, ata_status_df) ? 'd' : ' ';
status_str[ata_status_rdy] = bit_check(status, ata_status_rdy) ? 'r' : ' ';
status_str[ata_status_bsy] = bit_check(status, ata_status_bsy) ? 'b' : ' ';
return status_str;
}
/// @brief Waits for 400 nanoseconds.
/// @param dev the device on which we wait.
static inline void ata_io_wait(ata_device_t *dev)
@@ -479,7 +499,7 @@ static inline void ata_fix_string(char *str, unsigned len)
str[len] = 0;
}
static inline bool_t ata_read_device_identity(ata_device_t *dev, uint8_t command)
static inline bool_t ata_read_device_identity(ata_device_t *dev, ata_command_t command)
{
// Request the device identity.
outportb(dev->io_reg.command, command);
@@ -488,7 +508,7 @@ static inline bool_t ata_read_device_identity(ata_device_t *dev, uint8_t command
// Read the identity.
uint16_t *buffer = (uint16_t *)&dev->identity;
for (unsigned i = 0; i < 256; ++i) {
buffer[i] = inports(dev->io_base);
buffer[i] = inports(dev->io_reg.data);
}
// Fix the serial.
ata_fix_string((char *)&dev->identity.serial, 20 - 1);
@@ -499,21 +519,6 @@ static inline bool_t ata_read_device_identity(ata_device_t *dev, uint8_t command
return true;
}
static inline const char *ata_get_device_status_str(ata_device_t *dev)
{
static char status_str[9] = { 0 };
uint8_t status = inportb(dev->io_reg.status);
status_str[ata_status_err] = bit_check(status, ata_status_err) ? 'e' : ' ';
status_str[ata_status_idx] = bit_check(status, ata_status_idx) ? 'i' : ' ';
status_str[ata_status_corr] = bit_check(status, ata_status_corr) ? 'c' : ' ';
status_str[ata_status_drq] = bit_check(status, ata_status_drq) ? 'd' : ' ';
status_str[ata_status_srv] = bit_check(status, ata_status_srv) ? 's' : ' ';
status_str[ata_status_df] = bit_check(status, ata_status_df) ? 'd' : ' ';
status_str[ata_status_rdy] = bit_check(status, ata_status_rdy) ? 'r' : ' ';
status_str[ata_status_bsy] = bit_check(status, ata_status_bsy) ? 'b' : ' ';
return status_str;
}
/// @brief Performs a soft reset of the device.
/// @details "For non-ATAPI drives, the only method a driver has of resetting a
/// drive after a major error is to do a "software reset" on the bus. Set bit 2
@@ -648,13 +653,13 @@ static inline uintptr_t malloc_dma(size_t size, uintptr_t *physical)
// == ATA DEVICE MANAGEMENT ===================================================
static bool_t ata_device_init(ata_device_t *dev)
{
pr_debug("Detected ATA device on bus 0x%3x\n", dev->io_base);
pr_debug("Detected ATA device on bus 0x%3x\n", dev->io_reg.data);
// Select the ATA device.
ata_device_select(dev);
// Read the ATA device identity.
ata_read_device_identity(dev, ATA_CMD_IDENT);
ata_read_device_identity(dev, ata_command_ident);
// Allocate the memory for the Physical Region Descriptor Table (PRDT).
dev->dma_prdt = (prdt_t *)malloc_dma(sizeof(prdt_t), &dev->dma_prdt_phys);
@@ -703,7 +708,7 @@ static void ata_device_read_sector(ata_device_t *dev, uint32_t lba, uint8_t *buf
pr_debug("ata_device_read_sector(%p, %d, %p)\n", dev, lba, buffer);
spinlock_lock(&ata_lock);
ata_wait(dev, false);
ata_wait(dev, 0);
// Stop.
outportb(dev->bmr.command, 0x00);
@@ -714,12 +719,7 @@ static void ata_device_read_sector(ata_device_t *dev, uint32_t lba, uint8_t *buf
// Set read.
outportb(dev->bmr.command, 0x08);
do {
uint8_t status = inportb(dev->io_reg.status);
if (!bit_check(status, ata_status_bsy)) {
break;
}
} while (true);
while (bit_check(inportb(dev->io_reg.status), ata_status_bsy)) {}
outportb(dev->control_base, 0x00);
outportb(dev->io_reg.hddevsel, 0xe0 | (dev->slave << 4));
@@ -736,11 +736,9 @@ static void ata_device_read_sector(ata_device_t *dev, uint32_t lba, uint8_t *buf
outportb(dev->io_reg.lba_mid, (lba & 0x0000ff00) >> 8);
outportb(dev->io_reg.lba_hi, (lba & 0x00ff0000) >> 16);
while (1) {
uint8_t status = inportb(dev->io_reg.status);
if (!bit_check(status, ata_status_bsy) && bit_check(status, ata_status_rdy))
break;
}
while (bit_check(inportb(dev->io_reg.status), ata_status_bsy)) {}
while (!bit_check(inportb(dev->io_reg.status), ata_status_rdy)) {}
outportb(dev->io_reg.command, ata_dma_command_read);
ata_io_wait(dev);
@@ -1068,6 +1066,8 @@ static int ata_device_detect(ata_device_t *dev)
}
// Increment the drive letter.
++ata_drive_char;
} else if ((type == ata_dev_type_atapi) || (type == ata_dev_type_satapi)) {
pr_warning("ATAPI and SATAPI drives are not currently supported.\n");
} else {
pr_alert("Unsupported drive type.\n");
}
@@ -1135,6 +1135,14 @@ int ata_initialize()
pr_debug("\n");
pr_debug("Done\n");
char buffer[1500];
memset(buffer, 0, 1500);
ata_read(ata_primary_master.fs_root, buffer, 0, 1500);
for (int i = 0; i < 1500; ++i) {
pr_debug("%d ", buffer[i]);
}
pr_debug("\n");
return 0;
}