1 ///////////////////////////////////////////////////////////////////////// 2 // $Id: harddrv.h 14155 2021-02-19 13:13:42Z vruppert $ 3 ///////////////////////////////////////////////////////////////////////// 4 // 5 // Copyright (C) 2001-2021 The Bochs Project 6 // 7 // This library is free software; you can redistribute it and/or 8 // modify it under the terms of the GNU Lesser General Public 9 // License as published by the Free Software Foundation; either 10 // version 2 of the License, or (at your option) any later version. 11 // 12 // This library is distributed in the hope that it will be useful, 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 // Lesser General Public License for more details. 16 // 17 // You should have received a copy of the GNU Lesser General Public 18 // License along with this library; if not, write to the Free Software 19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 21 #ifndef BX_IODEV_HDDRIVE_H 22 #define BX_IODEV_HDDRIVE_H 23 24 #define MAX_MULTIPLE_SECTORS 16 25 26 typedef enum _sense { 27 SENSE_NONE = 0, SENSE_NOT_READY = 2, SENSE_ILLEGAL_REQUEST = 5, 28 SENSE_UNIT_ATTENTION = 6 29 } sense_t; 30 31 typedef enum _asc { 32 ASC_ILLEGAL_OPCODE = 0x20, 33 ASC_LOGICAL_BLOCK_OOR = 0x21, 34 ASC_INV_FIELD_IN_CMD_PACKET = 0x24, 35 ASC_MEDIUM_MAY_HAVE_CHANGED = 0x28, 36 ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39, 37 ASC_MEDIUM_NOT_PRESENT = 0x3a 38 } asc_t; 39 40 class device_image_t; 41 class cdrom_base_c; 42 43 typedef struct { 44 struct { 45 bool busy; 46 bool drive_ready; 47 bool write_fault; 48 bool seek_complete; 49 bool drq; 50 bool corrected_data; 51 bool index_pulse; 52 unsigned index_pulse_count; 53 bool err; 54 } status; 55 Bit8u error_register; 56 Bit8u head_no; 57 union { 58 Bit8u sector_count; 59 struct { 60 #ifdef BX_LITTLE_ENDIAN 61 unsigned c_d : 1; 62 unsigned i_o : 1; 63 unsigned rel : 1; 64 unsigned tag : 5; 65 #else /* BX_BIG_ENDIAN */ 66 unsigned tag : 5; 67 unsigned rel : 1; 68 unsigned i_o : 1; 69 unsigned c_d : 1; 70 #endif 71 } interrupt_reason; 72 }; 73 Bit8u sector_no; 74 union { 75 Bit16u cylinder_no; 76 Bit16u byte_count; 77 }; 78 Bit8u *buffer; 79 Bit32u buffer_total_size; 80 Bit32u buffer_size; 81 Bit32u buffer_index; 82 Bit32u drq_index; 83 Bit8u current_command; 84 Bit8u multiple_sectors; 85 bool lba_mode; 86 bool packet_dma; 87 Bit8u mdma_mode; 88 Bit8u udma_mode; 89 struct { 90 bool reset; // 0=normal, 1=reset controller 91 bool disable_irq; // 0=allow irq, 1=disable irq 92 } control; 93 Bit8u reset_in_progress; 94 Bit8u features; 95 struct { 96 Bit8u feature; 97 Bit8u nsector; 98 Bit8u sector; 99 Bit8u lcyl; 100 Bit8u hcyl; 101 } hob; 102 Bit32u num_sectors; 103 bool lba48; 104 } controller_t; 105 106 struct sense_info_t { 107 sense_t sense_key; 108 struct { 109 Bit8u arr[4]; 110 } information; 111 struct { 112 Bit8u arr[4]; 113 } specific_inf; 114 struct { 115 Bit8u arr[3]; 116 } key_spec; 117 Bit8u fruc; 118 Bit8u asc; 119 Bit8u ascq; 120 }; 121 122 struct error_recovery_t { 123 unsigned char data[8]; 124 125 error_recovery_t (); 126 }; 127 128 Bit16u read_16bit(const Bit8u* buf) BX_CPP_AttrRegparmN(1); 129 Bit32u read_32bit(const Bit8u* buf) BX_CPP_AttrRegparmN(1); 130 131 struct cdrom_t 132 { 133 bool ready; 134 bool locked; 135 cdrom_base_c *cd; 136 Bit32u max_lba; 137 Bit32u curr_lba; 138 Bit32u next_lba; 139 int remaining_blocks; 140 struct currentStruct { 141 error_recovery_t error_recovery; 142 } current; 143 }; 144 145 struct atapi_t 146 { 147 Bit8u command; 148 int drq_bytes; 149 int total_bytes_remaining; 150 }; 151 152 #if BX_USE_HD_SMF 153 # define BX_HD_SMF static 154 # define BX_HD_THIS theHardDrive-> 155 # define BX_HD_THIS_PTR theHardDrive 156 #else 157 # define BX_HD_SMF 158 # define BX_HD_THIS this-> 159 # define BX_HD_THIS_PTR this 160 #endif 161 162 typedef enum { 163 IDE_NONE, IDE_DISK, IDE_CDROM 164 } device_type_t; 165 166 class bx_hard_drive_c : public bx_hard_drive_stub_c { 167 public: 168 bx_hard_drive_c(); 169 virtual ~bx_hard_drive_c(); 170 virtual void init(); 171 virtual void reset(unsigned type); 172 #if BX_SUPPORT_PCI 173 virtual bool bmdma_read_sector(Bit8u channel, Bit8u *buffer, Bit32u *sector_size); 174 virtual bool bmdma_write_sector(Bit8u channel, Bit8u *buffer); 175 virtual void bmdma_complete(Bit8u channel); 176 #endif 177 virtual void register_state(void); 178 virt_read_handler(Bit32u address,unsigned io_len)179 virtual Bit32u virt_read_handler(Bit32u address, unsigned io_len) 180 { 181 return read_handler(this, address, io_len); 182 } virt_write_handler(Bit32u address,Bit32u value,unsigned io_len)183 virtual void virt_write_handler(Bit32u address, Bit32u value, unsigned io_len) 184 { 185 write_handler(this, address, value, io_len); 186 } 187 188 #if !BX_USE_HD_SMF 189 Bit32u read(Bit32u address, unsigned io_len); 190 void write(Bit32u address, Bit32u value, unsigned io_len); 191 #endif 192 193 static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len); 194 static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len); 195 196 static void seek_timer_handler(void *); 197 BX_HD_SMF void seek_timer(void); 198 199 static void runtime_config_handler(void *); 200 void runtime_config(void); 201 202 private: 203 204 BX_HD_SMF bool calculate_logical_address(Bit8u channel, Bit64s *sector) BX_CPP_AttrRegparmN(2); 205 BX_HD_SMF void increment_address(Bit8u channel, Bit64s *sector) BX_CPP_AttrRegparmN(2); 206 BX_HD_SMF void identify_drive(Bit8u channel); 207 BX_HD_SMF void identify_ATAPI_drive(Bit8u channel); 208 BX_HD_SMF void command_aborted(Bit8u channel, unsigned command); 209 210 BX_HD_SMF void init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy = 0); 211 BX_HD_SMF void ready_to_send_atapi(Bit8u channel) BX_CPP_AttrRegparmN(1); 212 BX_HD_SMF void raise_interrupt(Bit8u channel) BX_CPP_AttrRegparmN(1); 213 BX_HD_SMF void atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc, bool show); 214 BX_HD_SMF void init_mode_sense_single(Bit8u channel, const void* src, int size); 215 BX_HD_SMF void atapi_cmd_nop(controller_t *controller) BX_CPP_AttrRegparmN(1); 216 BX_HD_SMF bool bmdma_present(void); 217 BX_HD_SMF void set_signature(Bit8u channel, Bit8u id); 218 BX_HD_SMF bool ide_read_sector(Bit8u channel, Bit8u *buffer, Bit32u buffer_size); 219 BX_HD_SMF bool ide_write_sector(Bit8u channel, Bit8u *buffer, Bit32u buffer_size); 220 BX_HD_SMF void lba48_transform(controller_t *controller, bool lba48); 221 BX_HD_SMF void start_seek(Bit8u channel); 222 223 BX_HD_SMF bool set_cd_media_status(Bit32u handle, bool status); 224 225 static Bit64s cdrom_status_handler(bx_param_c *param, bool set, Bit64s val); 226 static const char* cdrom_path_handler(bx_param_string_c *param, bool set, 227 const char *oldval, const char *val, int maxlen); 228 229 // FIXME: 230 // For each ATA channel we should have one controller struct 231 // and an array of two drive structs 232 struct channel_t { 233 struct drive_t { 234 device_type_t device_type; 235 // 512 byte buffer for ID drive command 236 // These words are stored in native word endian format, as 237 // they are fetched and returned via a return(), so 238 // there's no need to keep them in x86 endian format. 239 Bit16u id_drive[256]; 240 bool identify_set; 241 242 controller_t controller; 243 cdrom_t cdrom; 244 sense_info_t sense; 245 atapi_t atapi; 246 247 device_image_t* hdimage; 248 Bit64s curr_lsector; 249 Bit64s next_lsector; 250 unsigned sect_size; 251 252 Bit8u model_no[41]; 253 int statusbar_id; 254 Bit8u device_num; // for ATAPI identify & inquiry 255 bool status_changed; 256 int seek_timer_index; 257 } drives[2]; 258 unsigned drive_select; 259 260 Bit16u ioaddr1; 261 Bit16u ioaddr2; 262 Bit8u irq; 263 264 } channels[BX_MAX_ATA_CHANNEL]; 265 266 int rt_conf_id; 267 Bit8u cdrom_count; 268 bool pci_enabled; 269 }; 270 271 #endif 272