summaryrefslogtreecommitdiff
path: root/src/include/pc80/ide.h
blob: 55eec2259d3106df0dd780c4593eb6d2651fa04b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 *   UBL, The Universal Talkware Boot Loader 
 *    Copyright (C) 2000 Universal Talkware Inc.
 *    Copyright (C) 2002 Eric Biederman
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version. 
 * 
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details. 
 * 
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 *
 */

typedef uint64_t sector_t;

struct controller {
	uint16_t cmd_base;
	uint16_t ctrl_base;
};

struct harddisk_info {
	struct controller *ctrl;
	uint16_t heads;
	uint16_t cylinders;
	uint16_t sectors_per_track;
	uint8_t  model_number[41];
	uint8_t  slave;
	sector_t sectors;
	int  address_mode;	/* am i lba (0x40) or chs (0x00) */
#define ADDRESS_MODE_CHS    0
#define ADDRESS_MODE_LBA    1
#define ADDRESS_MODE_LBA48  2
#define ADDRESS_MODE_PACKET 3
	uint32_t hw_sector_size;
	unsigned drive_exists : 1;
	unsigned slave_absent : 1;
	unsigned removable : 1;
};


#define IDE_SECTOR_SIZE 0x200
#define CDROM_SECTOR_SIZE 0x800

#define IDE_BASE0             (0x1F0u) /* primary controller */
#define IDE_BASE1             (0x170u) /* secondary */
#define IDE_BASE2             (0x0F0u) /* third */
#define IDE_BASE3             (0x070u) /* fourth */

#define IDE_REG_EXTENDED_OFFSET   (0x204u)

#define IDE_REG_DATA(ctrl)           ((ctrl)->cmd_base + 0u) /* word register */
#define IDE_REG_ERROR(ctrl)          ((ctrl)->cmd_base + 1u)
#define IDE_REG_PRECOMP(ctrl)        ((ctrl)->cmd_base + 1u)
#define IDE_REG_FEATURE(ctrl)        ((ctrl)->cmd_base + 1u)
#define IDE_REG_SECTOR_COUNT(ctrl)   ((ctrl)->cmd_base + 2u)
#define IDE_REG_SECTOR_NUMBER(ctrl)  ((ctrl)->cmd_base + 3u)
#define IDE_REG_LBA_LOW(ctrl)        ((ctrl)->cmd_base + 3u)
#define IDE_REG_CYLINDER_LSB(ctrl)   ((ctrl)->cmd_base + 4u)
#define IDE_REG_LBA_MID(ctrl)	     ((ctrl)->cmd_base + 4u)
#define IDE_REG_CYLINDER_MSB(ctrl)   ((ctrl)->cmd_base + 5u)
#define IDE_REG_LBA_HIGH(ctrl)	     ((ctrl)->cmd_base + 5u)
#define IDE_REG_DRIVEHEAD(ctrl)      ((ctrl)->cmd_base + 6u)
#define IDE_REG_DEVICE(ctrl)	     ((ctrl)->cmd_base + 6u)
#define IDE_REG_STATUS(ctrl)         ((ctrl)->cmd_base + 7u)
#define IDE_REG_COMMAND(ctrl)        ((ctrl)->cmd_base + 7u)
#define IDE_REG_ALTSTATUS(ctrl)      ((ctrl)->ctrl_base + 2u)
#define IDE_REG_DEVICE_CONTROL(ctrl) ((ctrl)->ctrl_base + 2u)

struct ide_pio_command
{
	uint8_t feature;
	uint8_t sector_count;
	uint8_t lba_low;
	uint8_t lba_mid;
	uint8_t lba_high;
	uint8_t device;
#       define IDE_DH_DEFAULT (0xA0)
#       define IDE_DH_HEAD(x) ((x) & 0x0F)
#       define IDE_DH_MASTER  (0x00)
#       define IDE_DH_SLAVE   (0x10)
#       define IDE_DH_LBA     (0x40)
#       define IDE_DH_CHS     (0x00)
	uint8_t command;
	uint8_t sector_count2;
	uint8_t lba_low2;
	uint8_t lba_mid2;
	uint8_t lba_high2;
};

#define IDE_DEFAULT_COMMAND { 0xFFu, 0x01, 0x00, 0x0000, IDE_DH_DEFAULT }

#define IDE_ERR_ICRC	0x80	/* ATA Ultra DMA bad CRC */
#define IDE_ERR_BBK	0x80	/* ATA bad block */
#define IDE_ERR_UNC	0x40	/* ATA uncorrected error */
#define IDE_ERR_MC	0x20	/* ATA media change */
#define IDE_ERR_IDNF	0x10	/* ATA id not found */
#define IDE_ERR_MCR	0x08	/* ATA media change request */
#define IDE_ERR_ABRT	0x04	/* ATA command aborted */
#define IDE_ERR_NTK0	0x02	/* ATA track 0 not found */
#define IDE_ERR_NDAM	0x01	/* ATA address mark not found */

#define IDE_STATUS_BSY	0x80	/* busy */
#define IDE_STATUS_RDY	0x40	/* ready */
#define IDE_STATUS_DF	0x20	/* device fault */
#define IDE_STATUS_WFT	0x20	/* write fault (old name) */
#define IDE_STATUS_SKC	0x10	/* seek complete */
#define IDE_STATUS_DRQ	0x08	/* data request */
#define IDE_STATUS_CORR	0x04	/* corrected */
#define IDE_STATUS_IDX	0x02	/* index */
#define IDE_STATUS_ERR	0x01	/* error (ATA) */
#define IDE_STATUS_CHK	0x01	/* check (ATAPI) */

#define IDE_CTRL_HD15	0x08	/* bit should always be set to one */
#define IDE_CTRL_SRST	0x04	/* soft reset */
#define IDE_CTRL_NIEN	0x02	/* disable interrupts */


/* Most mandtory and optional ATA commands (from ATA-3), */

#define IDE_CMD_CFA_ERASE_SECTORS            0xC0
#define IDE_CMD_CFA_REQUEST_EXT_ERR_CODE     0x03
#define IDE_CMD_CFA_TRANSLATE_SECTOR         0x87
#define IDE_CMD_CFA_WRITE_MULTIPLE_WO_ERASE  0xCD
#define IDE_CMD_CFA_WRITE_SECTORS_WO_ERASE   0x38
#define IDE_CMD_CHECK_POWER_MODE1            0xE5
#define IDE_CMD_CHECK_POWER_MODE2            0x98
#define IDE_CMD_DEVICE_RESET                 0x08
#define IDE_CMD_EXECUTE_DEVICE_DIAGNOSTIC    0x90
#define IDE_CMD_FLUSH_CACHE                  0xE7
#define IDE_CMD_FORMAT_TRACK                 0x50
#define IDE_CMD_IDENTIFY_DEVICE              0xEC
#define IDE_CMD_IDENTIFY_DEVICE_PACKET       0xA1
#define IDE_CMD_IDENTIFY_PACKET_DEVICE       0xA1
#define IDE_CMD_IDLE1                        0xE3
#define IDE_CMD_IDLE2                        0x97
#define IDE_CMD_IDLE_IMMEDIATE1              0xE1
#define IDE_CMD_IDLE_IMMEDIATE2              0x95
#define IDE_CMD_INITIALIZE_DRIVE_PARAMETERS  0x91
#define IDE_CMD_INITIALIZE_DEVICE_PARAMETERS 0x91
#define IDE_CMD_NOP                          0x00
#define IDE_CMD_PACKET                       0xA0
#define IDE_CMD_READ_BUFFER                  0xE4
#define IDE_CMD_READ_DMA                     0xC8
#define IDE_CMD_READ_DMA_QUEUED              0xC7
#define IDE_CMD_READ_MULTIPLE                0xC4
#define IDE_CMD_READ_SECTORS                 0x20
#define IDE_CMD_READ_SECTORS_EXT             0x24
#define IDE_CMD_READ_VERIFY_SECTORS          0x40
#define IDE_CMD_RECALIBRATE                  0x10
#define IDE_CMD_SEEK                         0x70
#define IDE_CMD_SET_FEATURES                 0xEF
#define IDE_CMD_SET_MAX_ADDR_EXT             0x24
#define IDE_CMD_SET_MULTIPLE_MODE            0xC6
#define IDE_CMD_SLEEP1                       0xE6
#define IDE_CMD_SLEEP2                       0x99
#define IDE_CMD_STANDBY1                     0xE2
#define IDE_CMD_STANDBY2                     0x96
#define IDE_CMD_STANDBY_IMMEDIATE1           0xE0
#define IDE_CMD_STANDBY_IMMEDIATE2           0x94
#define IDE_CMD_WRITE_BUFFER                 0xE8
#define IDE_CMD_WRITE_DMA                    0xCA
#define IDE_CMD_WRITE_DMA_QUEUED             0xCC
#define IDE_CMD_WRITE_MULTIPLE               0xC5
#define IDE_CMD_WRITE_SECTORS                0x30
#define IDE_CMD_WRITE_VERIFY                 0x3C

/* IDE_CMD_SET_FEATURE sub commands */
#define IDE_FEATURE_CFA_ENABLE_8BIT_PIO                     0x01
#define IDE_FEATURE_ENABLE_WRITE_CACHE                      0x02
#define IDE_FEATURE_SET_TRANSFER_MODE                       0x03
#define IDE_FEATURE_ENABLE_POWER_MANAGEMENT                 0x05
#define IDE_FEATURE_ENABLE_POWERUP_IN_STANDBY               0x06
#define IDE_FEATURE_STANDBY_SPINUP_DRIVE                    0x07
#define IDE_FEATURE_CFA_ENABLE_POWER_MODE1                  0x0A
#define IDE_FEATURE_DISABLE_MEDIA_STATUS_NOTIFICATION       0x31
#define IDE_FEATURE_ENABLE_AUTOMATIC_ACOUSTIC_MANAGEMENT    0x42
#define IDE_FEATURE_SET_MAXIMUM_HOST_INTERFACE_SECTOR_TIMES 0x43
#define IDE_FEATURE_DISABLE_READ_LOOKAHEAD                  0x55
#define IDE_FEATURE_ENABLE_RELEASE_INTERRUPT                0x5D
#define IDE_FEATURE_ENABLE_SERVICE_INTERRUPT                0x5E
#define IDE_FEATURE_DISABLE_REVERTING_TO_POWERON_DEFAULTS   0x66
#define IDE_FEATURE_CFA_DISABLE_8BIT_PIO                    0x81
#define IDE_FEATURE_DISABLE_WRITE_CACHE                     0x82
#define IDE_FEATURE_DISABLE_POWER_MANAGEMENT                0x85
#define IDE_FEATURE_DISABLE_POWERUP_IN_STANDBY              0x86
#define IDE_FEATURE_CFA_DISABLE_POWER_MODE1                 0x8A
#define IDE_FEATURE_ENABLE_MEDIA_STATUS_NOTIFICATION        0x95
#define IDE_FEATURE_ENABLE_READ_LOOKAHEAD                   0xAA
#define IDE_FEATURE_DISABLE_AUTOMATIC_ACOUSTIC_MANAGEMENT   0xC2
#define IDE_FEATURE_ENABLE_REVERTING_TO_POWERON_DEFAULTS    0xCC
#define IDE_FEATURE_DISABLE_SERVICE_INTERRUPT               0xDE

#define IDE_MAX_CONTROLLERS 2
#define IDE_MAX_DRIVES (IDE_MAX_CONTROLLERS*2)
#define SECTOR_SIZE 512
#define SECTOR_SHIFT 9

/* Maximum block_size that may be set. */
#define DISK_BUFFER_SIZE (18 * SECTOR_SIZE)

extern struct harddisk_info harddisk_info[];

extern int ide_probe(int drive);
extern int ide_read(int drive, sector_t sector, void *buffer);