2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2002-09-25 00:02:00 +04:00
|
|
|
// $Id: harddrv.h,v 1.15 2002-09-24 20:02:00 kevinlawton Exp $
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2002-02-01 19:46:27 +03:00
|
|
|
// Copyright (C) 2002 MandrakeSoft S.A.
|
2001-04-10 05:04:59 +04:00
|
|
|
//
|
|
|
|
// MandrakeSoft S.A.
|
|
|
|
// 43, rue d'Aboukir
|
|
|
|
// 75002 Paris - France
|
|
|
|
// http://www.linux-mandrake.com/
|
|
|
|
// http://www.mandrakesoft.com/
|
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library 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
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
typedef enum _sense {
|
2002-02-03 23:49:44 +03:00
|
|
|
SENSE_NONE = 0, SENSE_NOT_READY = 2, SENSE_ILLEGAL_REQUEST = 5,
|
|
|
|
SENSE_UNIT_ATTENTION = 6
|
2001-04-10 05:04:59 +04:00
|
|
|
} sense_t;
|
|
|
|
|
|
|
|
typedef enum _asc {
|
|
|
|
ASC_INV_FIELD_IN_CMD_PACKET = 0x24,
|
|
|
|
ASC_MEDIUM_NOT_PRESENT = 0x3a,
|
|
|
|
ASC_SAVING_PARAMETERS_NOT_SUPPORTED = 0x39,
|
|
|
|
ASC_LOGICAL_BLOCK_OOR = 0x21
|
|
|
|
} asc_t;
|
|
|
|
|
|
|
|
class LOWLEVEL_CDROM;
|
|
|
|
|
|
|
|
class device_image_t
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Open a image. Returns non-negative if successful.
|
|
|
|
virtual int open (const char* pathname) = 0;
|
|
|
|
|
|
|
|
// Close the image.
|
|
|
|
virtual void close () = 0;
|
|
|
|
|
|
|
|
// Position ourselves. Return the resulting offset from the
|
|
|
|
// beginning of the file.
|
|
|
|
virtual off_t lseek (off_t offset, int whence) = 0;
|
|
|
|
|
|
|
|
// Read count bytes to the buffer buf. Return the number of
|
|
|
|
// bytes read (count).
|
|
|
|
virtual ssize_t read (void* buf, size_t count) = 0;
|
|
|
|
|
|
|
|
// Write count bytes from buf. Return the number of bytes
|
|
|
|
// written (count).
|
|
|
|
virtual ssize_t write (const void* buf, size_t count) = 0;
|
|
|
|
|
|
|
|
unsigned cylinders;
|
|
|
|
unsigned heads;
|
|
|
|
unsigned sectors;
|
|
|
|
};
|
|
|
|
|
|
|
|
class default_image_t : public device_image_t
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Open a image. Returns non-negative if successful.
|
|
|
|
int open (const char* pathname);
|
|
|
|
|
|
|
|
// Close the image.
|
|
|
|
void close ();
|
|
|
|
|
|
|
|
// Position ourselves. Return the resulting offset from the
|
|
|
|
// beginning of the file.
|
|
|
|
off_t lseek (off_t offset, int whence);
|
|
|
|
|
|
|
|
// Read count bytes to the buffer buf. Return the number of
|
|
|
|
// bytes read (count).
|
|
|
|
ssize_t read (void* buf, size_t count);
|
|
|
|
|
|
|
|
// Write count bytes from buf. Return the number of bytes
|
|
|
|
// written (count).
|
|
|
|
ssize_t write (const void* buf, size_t count);
|
|
|
|
|
|
|
|
private:
|
|
|
|
int fd;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2001-05-07 09:47:59 +04:00
|
|
|
#if BX_SPLIT_HD_SUPPORT
|
|
|
|
class concat_image_t : public device_image_t
|
|
|
|
{
|
|
|
|
public:
|
2002-04-09 20:53:15 +04:00
|
|
|
// Default constructor
|
|
|
|
concat_image_t();
|
|
|
|
|
2001-05-07 09:47:59 +04:00
|
|
|
// Open a image. Returns non-negative if successful.
|
|
|
|
int open (const char* pathname);
|
|
|
|
|
|
|
|
// Close the image.
|
|
|
|
void close ();
|
|
|
|
|
|
|
|
// Position ourselves. Return the resulting offset from the
|
|
|
|
// beginning of the file.
|
|
|
|
off_t lseek (off_t offset, int whence);
|
|
|
|
|
|
|
|
// Read count bytes to the buffer buf. Return the number of
|
|
|
|
// bytes read (count).
|
|
|
|
ssize_t read (void* buf, size_t count);
|
|
|
|
|
|
|
|
// Write count bytes from buf. Return the number of bytes
|
|
|
|
// written (count).
|
|
|
|
ssize_t write (const void* buf, size_t count);
|
|
|
|
|
|
|
|
private:
|
|
|
|
#define BX_CONCAT_MAX_IMAGES 8
|
|
|
|
int fd_table[BX_CONCAT_MAX_IMAGES];
|
|
|
|
ssize_t start_offset_table[BX_CONCAT_MAX_IMAGES];
|
|
|
|
ssize_t length_table[BX_CONCAT_MAX_IMAGES];
|
|
|
|
void increment_string (char *str);
|
|
|
|
int maxfd; // number of entries in tables that are valid
|
|
|
|
|
|
|
|
// notice if anyone does sequential read or write without seek in between.
|
|
|
|
// This can be supported pretty easily, but needs additional checks.
|
|
|
|
// 0=something other than seek was last operation
|
|
|
|
// 1=seek was last operation
|
|
|
|
int seek_was_last_op;
|
|
|
|
|
|
|
|
// the following variables tell which partial image file to use for
|
|
|
|
// the next read and write.
|
|
|
|
int index; // index into table
|
|
|
|
int fd; // fd to use for reads and writes
|
|
|
|
int thismin, thismax; // byte offset boundary of this image
|
|
|
|
};
|
|
|
|
#endif /* BX_SPLIT_HD_SUPPORT */
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
#if EXTERNAL_DISK_SIMULATOR
|
|
|
|
#include "external-disk-simulator.h"
|
|
|
|
#endif
|
|
|
|
|
2002-09-12 10:49:04 +04:00
|
|
|
#if DLL_HD_SUPPORT
|
|
|
|
class dll_image_t : public device_image_t
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Open a image. Returns non-negative if successful.
|
|
|
|
int open (const char* pathname);
|
|
|
|
|
|
|
|
// Close the image.
|
|
|
|
void close ();
|
|
|
|
|
|
|
|
// Position ourselves. Return the resulting offset from the
|
|
|
|
// beginning of the file.
|
|
|
|
off_t lseek (off_t offset, int whence);
|
|
|
|
|
|
|
|
// Read count bytes to the buffer buf. Return the number of
|
|
|
|
// bytes read (count).
|
|
|
|
ssize_t read (void* buf, size_t count);
|
|
|
|
|
|
|
|
// Write count bytes from buf. Return the number of bytes
|
|
|
|
// written (count).
|
|
|
|
ssize_t write (const void* buf, size_t count);
|
|
|
|
|
|
|
|
private:
|
|
|
|
int vunit,vblk;
|
|
|
|
|
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
typedef struct {
|
|
|
|
struct {
|
|
|
|
Boolean busy;
|
|
|
|
Boolean drive_ready;
|
|
|
|
Boolean write_fault;
|
|
|
|
Boolean seek_complete;
|
|
|
|
Boolean drq;
|
|
|
|
Boolean corrected_data;
|
|
|
|
Boolean index_pulse;
|
|
|
|
unsigned index_pulse_count;
|
|
|
|
Boolean err;
|
|
|
|
} status;
|
|
|
|
Bit8u error_register;
|
|
|
|
Bit8u head_no;
|
|
|
|
union {
|
|
|
|
Bit8u sector_count;
|
|
|
|
struct {
|
2001-08-13 19:48:13 +04:00
|
|
|
#ifdef BX_LITTLE_ENDIAN
|
2001-04-10 05:04:59 +04:00
|
|
|
unsigned c_d : 1;
|
|
|
|
unsigned i_o : 1;
|
|
|
|
unsigned rel : 1;
|
|
|
|
unsigned tag : 5;
|
2001-08-13 19:48:13 +04:00
|
|
|
#else /* BX_BIG_ENDIAN */
|
|
|
|
unsigned tag : 5;
|
|
|
|
unsigned rel : 1;
|
|
|
|
unsigned i_o : 1;
|
|
|
|
unsigned c_d : 1;
|
|
|
|
#endif
|
2001-04-10 05:04:59 +04:00
|
|
|
} interrupt_reason;
|
|
|
|
};
|
|
|
|
Bit8u sector_no;
|
|
|
|
union {
|
|
|
|
Bit16u cylinder_no;
|
|
|
|
Bit16u byte_count;
|
|
|
|
};
|
|
|
|
Bit8u buffer[2048];
|
2002-08-05 19:51:06 +04:00
|
|
|
Bit32u buffer_index;
|
|
|
|
Bit32u drq_index;
|
2001-04-10 05:04:59 +04:00
|
|
|
Bit8u current_command;
|
|
|
|
Bit8u sectors_per_block;
|
|
|
|
Bit8u lba_mode;
|
|
|
|
struct {
|
|
|
|
Boolean reset; // 0=normal, 1=reset controller
|
|
|
|
Boolean disable_irq; // 0=allow irq, 1=disable irq
|
|
|
|
} control;
|
|
|
|
Bit8u reset_in_progress;
|
|
|
|
Bit8u features;
|
|
|
|
} controller_t;
|
|
|
|
|
|
|
|
struct sense_info_t {
|
|
|
|
sense_t sense_key;
|
|
|
|
struct {
|
|
|
|
Bit8u arr[4];
|
|
|
|
} information;
|
|
|
|
struct {
|
|
|
|
Bit8u arr[4];
|
|
|
|
} specific_inf;
|
|
|
|
struct {
|
|
|
|
Bit8u arr[3];
|
|
|
|
} key_spec;
|
|
|
|
Bit8u fruc;
|
|
|
|
Bit8u asc;
|
|
|
|
Bit8u ascq;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct error_recovery_t {
|
|
|
|
unsigned char data[8];
|
|
|
|
|
|
|
|
error_recovery_t ();
|
|
|
|
};
|
|
|
|
|
|
|
|
uint16 read_16bit(const uint8* buf);
|
|
|
|
uint32 read_32bit(const uint8* buf);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef LOWLEVEL_CDROM
|
|
|
|
# include "cdrom.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
struct cdrom_t
|
|
|
|
{
|
|
|
|
Boolean ready;
|
|
|
|
Boolean locked;
|
|
|
|
#ifdef LOWLEVEL_CDROM
|
|
|
|
LOWLEVEL_CDROM* cd;
|
|
|
|
#endif
|
|
|
|
uint32 capacity;
|
|
|
|
int next_lba;
|
|
|
|
int remaining_blocks;
|
|
|
|
struct currentStruct {
|
|
|
|
error_recovery_t error_recovery;
|
|
|
|
} current;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct atapi_t
|
|
|
|
{
|
|
|
|
uint8 command;
|
|
|
|
int drq_bytes;
|
|
|
|
int total_bytes_remaining;
|
|
|
|
};
|
|
|
|
|
|
|
|
#if BX_USE_HD_SMF
|
|
|
|
# define BX_HD_SMF static
|
|
|
|
# define BX_HD_THIS bx_hard_drive.
|
|
|
|
#else
|
|
|
|
# define BX_HD_SMF
|
|
|
|
# define BX_HD_THIS this->
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef enum {
|
2002-09-23 00:56:12 +04:00
|
|
|
IDE_NONE, IDE_DISK, IDE_CDROM
|
2001-04-10 05:04:59 +04:00
|
|
|
} device_type_t;
|
|
|
|
|
merge in BRANCH-io-cleanup.
To see the commit logs for this use either cvsweb or
cvs update -r BRANCH-io-cleanup and then 'cvs log' the various files.
In general this provides a generic interface for logging.
logfunctions:: is a class that is inherited by some classes, and also
. allocated as a standalone global called 'genlog'. All logging uses
. one of the ::info(), ::error(), ::ldebug(), ::panic() methods of this
. class through 'BX_INFO(), BX_ERROR(), BX_DEBUG(), BX_PANIC()' macros
. respectively.
.
. An example usage:
. BX_INFO(("Hello, World!\n"));
iofunctions:: is a class that is allocated once by default, and assigned
as the iofunction of each logfunctions instance. It is this class that
maintains the file descriptor and other output related code, at this
point using vfprintf(). At some future point, someone may choose to
write a gui 'console' for bochs to which messages would be redirected
simply by assigning a different iofunction class to the various logfunctions
objects.
More cleanup is coming, but this works for now. If you want to see alot
of debugging output, in main.cc, change onoff[LOGLEV_DEBUG]=0 to =1.
Comments, bugs, flames, to me: todd@fries.net
2001-05-15 18:49:57 +04:00
|
|
|
class bx_hard_drive_c : public logfunctions {
|
2001-04-10 05:04:59 +04:00
|
|
|
public:
|
|
|
|
|
|
|
|
bx_hard_drive_c(void);
|
|
|
|
~bx_hard_drive_c(void);
|
|
|
|
BX_HD_SMF void close_harddrive(void);
|
|
|
|
BX_HD_SMF void init(bx_devices_c *d, bx_cmos_c *cmos);
|
2002-08-27 23:54:46 +04:00
|
|
|
BX_HD_SMF void reset(unsigned type);
|
2002-09-23 00:56:12 +04:00
|
|
|
BX_HD_SMF Bit32u get_device_handle(Bit8u channel, Bit8u device);
|
|
|
|
BX_HD_SMF Bit32u get_first_cd_handle(void);
|
|
|
|
BX_HD_SMF unsigned get_cd_media_status(Bit32u handle);
|
|
|
|
BX_HD_SMF unsigned set_cd_media_status(Bit32u handle, unsigned status);
|
2001-04-10 05:04:59 +04:00
|
|
|
|
|
|
|
#if !BX_USE_HD_SMF
|
|
|
|
Bit32u read(Bit32u address, unsigned io_len);
|
|
|
|
void write(Bit32u address, Bit32u value, unsigned io_len);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
|
|
|
|
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2002-09-23 00:56:12 +04:00
|
|
|
BX_HD_SMF Boolean calculate_logical_address(Bit8u channel, Bit32u *sector);
|
|
|
|
BX_HD_SMF void increment_address(Bit8u channel);
|
|
|
|
BX_HD_SMF void identify_drive(Bit8u channel);
|
|
|
|
BX_HD_SMF void identify_ATAPI_drive(Bit8u channel);
|
|
|
|
BX_HD_SMF void command_aborted(Bit8u channel, unsigned command);
|
|
|
|
|
|
|
|
BX_HD_SMF void init_send_atapi_command(Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy = false);
|
|
|
|
BX_HD_SMF void ready_to_send_atapi(Bit8u channel);
|
|
|
|
BX_HD_SMF void raise_interrupt(Bit8u channel);
|
|
|
|
BX_HD_SMF void atapi_cmd_error(Bit8u channel, sense_t sense_key, asc_t asc);
|
|
|
|
BX_HD_SMF void init_mode_sense_single(Bit8u channel, const void* src, int size);
|
|
|
|
BX_HD_SMF void atapi_cmd_nop(Bit8u channel);
|
|
|
|
|
|
|
|
// FIXME:
|
|
|
|
// For each ATA channel we should have one controller struct
|
|
|
|
// and an array of two drive structs
|
|
|
|
struct channel_t {
|
|
|
|
struct drive_t {
|
|
|
|
device_image_t* hard_drive;
|
|
|
|
device_type_t device_type;
|
|
|
|
// 512 byte buffer for ID drive command
|
|
|
|
// These words are stored in native word endian format, as
|
|
|
|
// they are fetched and returned via a return(), so
|
|
|
|
// there's no need to keep them in x86 endian format.
|
|
|
|
Bit16u id_drive[256];
|
|
|
|
|
|
|
|
controller_t controller;
|
|
|
|
cdrom_t cdrom;
|
|
|
|
sense_info_t sense;
|
|
|
|
atapi_t atapi;
|
|
|
|
|
|
|
|
Bit8u model_no[41];
|
|
|
|
} drives[2];
|
|
|
|
unsigned drive_select;
|
|
|
|
|
|
|
|
Bit16u ioaddr1;
|
|
|
|
Bit16u ioaddr2;
|
|
|
|
Bit8u irq;
|
|
|
|
|
|
|
|
} channels[BX_MAX_ATA_CHANNEL];
|
2001-04-10 05:04:59 +04:00
|
|
|
|
2002-09-25 00:02:00 +04:00
|
|
|
#if BX_PDC20230C_VLBIDE_SUPPORT
|
|
|
|
// pdc20630c is only available for 1st ata channel
|
|
|
|
struct pdc20630c_t {
|
|
|
|
Boolean prog_mode;
|
|
|
|
Bit8u prog_count;
|
|
|
|
Bit32u p1f3_value;
|
|
|
|
Bit32u p1f4_value;
|
|
|
|
} pdc20230c;
|
|
|
|
#endif
|
|
|
|
|
2001-04-10 05:04:59 +04:00
|
|
|
bx_devices_c *devices;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern bx_hard_drive_c bx_hard_drive;
|