00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00129 #if !defined(INCLUDED_ALIM1543C_IDE_H_)
00130 #define INCLUDED_ALIM1543C_IDE_H_
00131
00132
00133 #ifdef DEBUG_IDE
00134 #define DEBUG_IDE_BUSMASTER
00135 #define DEBUG_IDE_COMMAND
00136 #define DEBUG_IDE_DMA
00137 #define DEBUG_IDE_INTERRUPT
00138 #define DEBUG_IDE_REG_COMMAND
00139 #define DEBUG_IDE_REG_CONTROL
00140 #define DEBUG_IDE_PACKET
00141 #define DEBUG_IDE_MULTIPLE
00142 #endif
00143
00144 #include "DiskController.h"
00145 #include "Configurator.h"
00146 #include "SCSIDevice.h"
00147 #include "SCSIBus.h"
00148
00149 #define MAX_MULTIPLE_SECTORS 128
00150
00162 class CAliM1543C_ide : public CDiskController, public CSCSIDevice, public Poco::Runnable
00163 {
00164 public:
00165 CAliM1543C_ide(CConfigurator* cfg, class CSystem* c, int pcibus, int pcidev);
00166 virtual ~CAliM1543C_ide();
00167 virtual void register_disk(class CDisk* dsk, int bus, int dev);
00168
00169 virtual void WriteMem_Legacy(int index, u32 address, int dsize, u32 data);
00170 virtual u32 ReadMem_Legacy(int index, u32 address, int dsize);
00171
00172 virtual void WriteMem_Bar(int func, int bar, u32 address, int dsize,
00173 u32 data);
00174 virtual u32 ReadMem_Bar(int func, int bar, u32 address, int dsize);
00175
00176 virtual int SaveState(FILE* f);
00177 virtual int RestoreState(FILE* f);
00178
00179 virtual void check_state();
00180 virtual void ResetPCI();
00181
00182 virtual void run();
00183 virtual void init();
00184 virtual void start_threads();
00185 virtual void stop_threads();
00186 private:
00187
00188
00189 u32 ide_command_read(int channel, u32 address, int dsize);
00190 void ide_command_write(int channel, u32 address, int dsize, u32 data);
00191 u32 ide_control_read(int channel, u32 address);
00192 void ide_control_write(int channel, u32 address, u32 data);
00193 u32 ide_busmaster_read(int channel, u32 address, int dsize);
00194 void ide_busmaster_write(int channel, u32 address, u32 data, int dsize);
00195 int do_dma_transfer(int index, u8* buffer, u32 size, bool direction);
00196
00197 void raise_interrupt(int channel);
00198 void set_signature(int channel, int id);
00199 u8 get_status(int index);
00200 void command_aborted(int index, u8 command);
00201 void identify_drive(int index, bool packet);
00202 void ide_status(int index);
00203
00204 void execute(int index);
00205
00206 Poco::Thread * thrController[2];
00207 Poco::Semaphore * semController[2];
00208 Poco::Semaphore * semBusMaster[2];
00209 CRWMutex* mtRegisters[2];
00210 CRWMutex* mtBusMaster[2];
00211 bool StopThread;
00212
00213 bool usedma;
00214
00215
00216 struct SAliM1543C_ideState
00217 {
00218 struct SDriveState
00219 {
00220 struct
00221 {
00222 bool busy;
00223 bool drive_ready;
00224 bool fault;
00225 bool seek_complete;
00226 bool drq;
00227 bool bit_2;
00228 bool index_pulse;
00229 bool err;
00230 int index_pulse_count;
00231
00232
00233 u8 debug_last_status;
00234 bool debug_status_update;
00235
00236 u8 alt_status;
00237 } status;
00238
00239 struct
00240 {
00241 bool lba_mode;
00242 int features;
00243 int error;
00244 int sector_count;
00245 int sector_no;
00246 int cylinder_no;
00247 int head_no;
00248 int command;
00249 } registers;
00250
00251 struct
00252 {
00253 bool command_in_progress;
00254 int current_command;
00255 int command_cycle;
00256 bool packet_dma;
00257 int packet_phase;
00258 u8 packet_command[12];
00259 int packet_buffersize;
00260 u8 packet_sense;
00261 u8 packet_asc;
00262 u8 packet_ascq;
00263 } command;
00264
00265 u8 multiple_size;
00266 };
00267
00268 struct SControllerState
00269 {
00270
00271
00272 struct SDriveState drive[2];
00273
00274
00275 bool disable_irq;
00276 bool reset;
00277
00278
00279 bool reset_in_progress;
00280 int selected;
00281
00282
00283 u8 busmaster[8];
00284 u8 dma_mode;
00285 u8 bm_status;
00286
00287
00288 #define IDE_BUFFER_SIZE 65536 // 64K words = 128K = 256 sectors @ 512 bytes
00289 u16 data[IDE_BUFFER_SIZE];
00290 int data_ptr;
00291 int data_size;
00292
00293 bool interrupt_pending;
00294 } controller[2];
00295 }
00296 state;
00297
00298 };
00299
00301 #define SEL_STATUS(a) \
00302 state.controller[a].drive[state.controller[a].selected].status
00303
00305 #define SEL_COMMAND(a) \
00306 state.controller[a].drive[state.controller[a].selected].command
00307
00309 #define SEL_REGISTERS(a) \
00310 state.controller[a].drive[state.controller[a].selected].registers
00311
00313 #define SEL_DISK(a) get_disk(a, state.controller[a].selected)
00314
00316 #define SEL_PER_DRIVE(a) state.controller[a].drive[state.controller[a].selected]
00317
00318
00319 #define STATUS(a, b) state.controller[a].drive[b].status
00320
00321
00322 #define COMMAND(a, b) state.controller[a].drive[b].command
00323
00324
00325 #define REGISTERS(a, b) state.controller[a].drive[b].registers
00326
00327
00328 #define PER_DRIVE(a, b) state.controller[a].drive[b]
00329
00330
00331 #define CONTROLLER(a) state.controller[a]
00332
00333
00334 #define UPDATE_ALT_STATUS(a) \
00335 { \
00336 SCOPED_WRITE_LOCK(mtRegisters[a]); \
00337 SEL_STATUS(a).alt_status=get_status(a); \
00338 }
00339
00340
00341 #define PRI_COMMAND 1
00342 #define PRI_CONTROL 2
00343 #define SEC_COMMAND 3
00344 #define SEC_CONTROL 4
00345 #define PRI_BUSMASTER 5
00346 #define SEC_BUSMASTER 6
00347
00348
00349 #define BAR_PRI_COMMAND 0
00350 #define BAR_PRI_CONTROL 1
00351 #define BAR_SEC_COMMAND 2
00352 #define BAR_SEC_CONTROL 3
00353 #define BAR_BUSMASTER 4
00354
00355
00356 #define REG_COMMAND_DATA 0
00357 #define REG_COMMAND_ERROR 1
00358 #define REG_COMMAND_FEATURES 1
00359 #define REG_COMMAND_SECTOR_COUNT 2
00360 #define REG_COMMAND_SECTOR_NO 3
00361 #define REG_COMMAND_CYL_LOW 4
00362 #define REG_COMMAND_CYL_HI 5
00363 #define REG_COMMAND_DRIVE 6
00364 #define REG_COMMAND_STATUS 7
00365 #define REG_COMMAND_COMMAND 7
00366
00367 static const char* register_names[] = {
00368 "DATA",
00369 "ERROR/FEATURES",
00370 "SECTOR_COUNT/PKT REASON",
00371 "SECTOR_NO",
00372 "CYL_LOW/PKT BYTE LOW",
00373 "CYL_HI/PKT BYTE HI",
00374 "DRIVE",
00375 "STATUS/COMMAND",
00376 };
00377
00378
00379
00380
00381 #define DMRD fault
00382 #define SERV seek_complete
00383 #define CHK err
00384 #define BYTE_COUNT cylinder_no
00385 #define REASON sector_count
00386 #define IR_CD 0x01
00387 #define IR_IO 0x02
00388 #define IR_REL 0x04
00389
00390
00391 static const char* packet_states[] = {
00392 "DP0: Prepare A",
00393 "DP1: Receive Packet",
00394 "DP2: Prepare B",
00395 "DP3/4: Ready INITRQ/Transfer Data",
00396 "DIx: Device Interrupt ",
00397 };
00398
00399 #define PACKET_NONE 0
00400 #define PACKET_DP0 0
00401 #define PACKET_DP1 1
00402 #define PACKET_DP2 2
00403 #define PACKET_DP34 3
00404 #define PACKET_DI 4
00405
00406
00407 #define SENSE_NONE 0x00
00408 #define SENSE_RECOVERED_ERROR 0x01
00409 #define SENSE_NOT_READY 0x02
00410 #define SENSE_MEDIUM_ERROR 0x03
00411 #define SENSE_HARDWARE_ERROR 0x04
00412 #define SENSE_ILLEGAL_REQUEST 0x05
00413 #define SENSE_UNIT_ATTENTION 0x06
00414 #define SENSE_DATA_PROTECT 0x07
00415 #define SENSE_BLANK_CHECK 0x08
00416 #define SENSE_ABORT_COMMAND 0x0b
00417 #define SENSE_MISCOMPARE 0x0e
00418
00419
00420 extern CAliM1543C_ide* theIDE;
00421
00422 #endif