[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 5/7] ide: remove magic constants from the device register
From: |
John Snow |
Subject: |
[PATCH 5/7] ide: remove magic constants from the device register |
Date: |
Fri, 24 Jul 2020 01:22:58 -0400 |
(In QEMU, we call this the "select" register.)
My memory isn't good enough to memorize what these magic runes
do. Label them to prevent mixups from happening in the future.
Side note: I assume it's safe to always set 0xA0 even though ATA2 claims
these bits are reserved, because ATA3 immediately reinstated that these
bits should be always on. ATA4 and subsequent specs only claim that the
fields are obsolete, so I assume it's safe to leave these set and that
it should work with the widest array of guests.
Signed-off-by: John Snow <jsnow@redhat.com>
---
include/hw/ide/internal.h | 11 +++++++++++
hw/ide/core.c | 26 ++++++++++++++------------
2 files changed, 25 insertions(+), 12 deletions(-)
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
index 16d806e0cf..d5a6ba1056 100644
--- a/include/hw/ide/internal.h
+++ b/include/hw/ide/internal.h
@@ -29,6 +29,17 @@ typedef struct IDEDMAOps IDEDMAOps;
#define MAX_IDE_DEVS 2
+/* Device/Head ("select") Register */
+#define ATA_DEV_SELECT 0x10
+/* ATA1,3: Defined as '1'.
+ * ATA2: Reserved.
+ * ATA3-7: obsolete. */
+#define ATA_DEV_ALWAYS_ON 0xA0
+#define ATA_DEV_LBA 0x40
+#define ATA_DEV_LBA_MSB 0x0F /* LBA 24:27 */
+#define ATA_DEV_HS 0x0F /* HS 3:0 */
+
+
/* Bits of HD_STATUS */
#define ERR_STAT 0x01
#define INDEX_STAT 0x02
diff --git a/hw/ide/core.c b/hw/ide/core.c
index f35864070b..5f4f004312 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -367,7 +367,7 @@ fill_buffer:
static void ide_set_signature(IDEState *s)
{
- s->select &= 0xf0; /* clear head */
+ s->select &= ~(ATA_DEV_HS); /* clear head */
/* put signature */
s->nsector = 1;
s->sector = 1;
@@ -586,7 +586,7 @@ void ide_transfer_stop(IDEState *s)
int64_t ide_get_sector(IDEState *s)
{
int64_t sector_num;
- if (s->select & 0x40) {
+ if (s->select & (ATA_DEV_LBA)) {
if (s->lba48) {
sector_num = ((int64_t)s->hob_hcyl << 40) |
((int64_t) s->hob_lcyl << 32) |
@@ -595,13 +595,13 @@ int64_t ide_get_sector(IDEState *s)
((int64_t) s->lcyl << 8) | s->sector;
} else {
/* LBA28 */
- sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
- (s->lcyl << 8) | s->sector;
+ sector_num = ((s->select & (ATA_DEV_LBA_MSB)) << 24) |
+ (s->hcyl << 16) | (s->lcyl << 8) | s->sector;
}
} else {
/* CHS */
sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
- (s->select & 0x0f) * s->sectors + (s->sector - 1);
+ (s->select & (ATA_DEV_HS)) * s->sectors + (s->sector - 1);
}
return sector_num;
@@ -610,7 +610,7 @@ int64_t ide_get_sector(IDEState *s)
void ide_set_sector(IDEState *s, int64_t sector_num)
{
unsigned int cyl, r;
- if (s->select & 0x40) {
+ if (s->select & (ATA_DEV_LBA)) {
if (s->lba48) {
s->sector = sector_num;
s->lcyl = sector_num >> 8;
@@ -620,7 +620,8 @@ void ide_set_sector(IDEState *s, int64_t sector_num)
s->hob_hcyl = sector_num >> 40;
} else {
/* LBA28 */
- s->select = (s->select & 0xf0) | (sector_num >> 24);
+ s->select = (s->select & ~(ATA_DEV_LBA_MSB)) |
+ ((sector_num >> 24) & (ATA_DEV_LBA_MSB));
s->hcyl = (sector_num >> 16);
s->lcyl = (sector_num >> 8);
s->sector = (sector_num);
@@ -631,7 +632,8 @@ void ide_set_sector(IDEState *s, int64_t sector_num)
r = sector_num % (s->heads * s->sectors);
s->hcyl = cyl >> 8;
s->lcyl = cyl;
- s->select = (s->select & 0xf0) | ((r / s->sectors) & 0x0f);
+ s->select = (s->select & ~(ATA_DEV_HS)) |
+ ((r / s->sectors) & (ATA_DEV_HS));
s->sector = (r % s->sectors) + 1;
}
}
@@ -1302,10 +1304,10 @@ void ide_ioport_write(void *opaque, uint32_t addr,
uint32_t val)
break;
case ATA_IOPORT_WR_DEVICE_HEAD:
ide_clear_hob(bus);
- bus->ifs[0].select = val | 0xa0;
- bus->ifs[1].select = val | 0xa0;
+ bus->ifs[0].select = val | (ATA_DEV_ALWAYS_ON);
+ bus->ifs[1].select = val | (ATA_DEV_ALWAYS_ON);
/* select drive */
- bus->unit = (val >> 4) & 1;
+ bus->unit = (val & (ATA_DEV_SELECT)) ? 1 : 0;
break;
default:
case ATA_IOPORT_WR_COMMAND:
@@ -1343,7 +1345,7 @@ static void ide_reset(IDEState *s)
s->hob_lcyl = 0;
s->hob_hcyl = 0;
- s->select = 0xa0;
+ s->select = (ATA_DEV_ALWAYS_ON);
s->status = READY_STAT | SEEK_STAT;
s->lba48 = 0;
--
2.26.2
- [PATCH 0/7] IDE: SRST and other fixes, John Snow, 2020/07/24
- [PATCH 2/7] ide: don't tamper with the device register, John Snow, 2020/07/24
- [PATCH 3/7] ide: model HOB correctly, John Snow, 2020/07/24
- [PATCH 1/7] ide: rename cmd_write to ctrl_write, John Snow, 2020/07/24
- [PATCH 6/7] ide: clear interrupt on command write, John Snow, 2020/07/24
- [PATCH 4/7] ide: reorder set/get sector functions, John Snow, 2020/07/24
- [PATCH 5/7] ide: remove magic constants from the device register,
John Snow <=
- [PATCH 7/7] ide: cancel pending callbacks on SRST, John Snow, 2020/07/24