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