309 lines
12 KiB
C
309 lines
12 KiB
C
/*************************************************************************//**
|
|
*****************************************************************************
|
|
* @file include/sys/hd.h
|
|
* @brief
|
|
* @author Forrest Y. Yu
|
|
* @date 2008
|
|
*****************************************************************************
|
|
*****************************************************************************/
|
|
|
|
#ifndef _ORANGES_HD_H_
|
|
#define _ORANGES_HD_H_
|
|
|
|
/**
|
|
* @struct part_ent
|
|
* @brief Partition Entry struct.
|
|
*
|
|
* <b>Master Boot Record (MBR):</b>
|
|
* Located at offset 0x1BE in the 1st sector of a disk. MBR contains
|
|
* four 16-byte partition entries. Should end with 55h & AAh.
|
|
*
|
|
* <b>partitions in MBR:</b>
|
|
* A PC hard disk can contain either as many as four primary partitions,
|
|
* or 1-3 primaries and a single extended partition. Each of these
|
|
* partitions are described by a 16-byte entry in the Partition Table
|
|
* which is located in the Master Boot Record.
|
|
*
|
|
* <b>extented partition:</b>
|
|
* It is essentially a link list with many tricks. See
|
|
* http://en.wikipedia.org/wiki/Extended_boot_record for details.
|
|
*/
|
|
struct part_ent {
|
|
u8 boot_ind; /**
|
|
* boot indicator
|
|
* Bit 7 is the active partition flag,
|
|
* bits 6-0 are zero (when not zero this
|
|
* byte is also the drive number of the
|
|
* drive to boot so the active partition
|
|
* is always found on drive 80H, the first
|
|
* hard disk).
|
|
*/
|
|
|
|
u8 start_head; /**
|
|
* Starting Head
|
|
*/
|
|
|
|
u8 start_sector; /**
|
|
* Starting Sector.
|
|
* Only bits 0-5 are used. Bits 6-7 are
|
|
* the upper two bits for the Starting
|
|
* Cylinder field.
|
|
*/
|
|
|
|
u8 start_cyl; /**
|
|
* Starting Cylinder.
|
|
* This field contains the lower 8 bits
|
|
* of the cylinder value. Starting cylinder
|
|
* is thus a 10-bit number, with a maximum
|
|
* value of 1023.
|
|
*/
|
|
|
|
u8 sys_id; /**
|
|
* System ID
|
|
* e.g.
|
|
* 01: FAT12
|
|
* 81: MINIX
|
|
* 83: Linux
|
|
*/
|
|
|
|
u8 end_head; /**
|
|
* Ending Head
|
|
*/
|
|
|
|
u8 end_sector; /**
|
|
* Ending Sector.
|
|
* Only bits 0-5 are used. Bits 6-7 are
|
|
* the upper two bits for the Ending
|
|
* Cylinder field.
|
|
*/
|
|
|
|
u8 end_cyl; /**
|
|
* Ending Cylinder.
|
|
* This field contains the lower 8 bits
|
|
* of the cylinder value. Ending cylinder
|
|
* is thus a 10-bit number, with a maximum
|
|
* value of 1023.
|
|
*/
|
|
|
|
u32 start_sect; /**
|
|
* starting sector counting from
|
|
* 0 / Relative Sector. / start in LBA
|
|
*/
|
|
|
|
u32 nr_sects; /**
|
|
* nr of sectors in partition
|
|
*/
|
|
|
|
} ;
|
|
|
|
// added by mingxuan 2020-10-27
|
|
struct fs_flags
|
|
{
|
|
u8 orange_flag;
|
|
//u8 reserved1;
|
|
//u8 reserved2;
|
|
u16 reserved;
|
|
u32 fat32_flag1;
|
|
u32 fat32_flag2;
|
|
};
|
|
|
|
|
|
/********************************************/
|
|
/* I/O Ports used by hard disk controllers. */
|
|
/********************************************/
|
|
/* slave disk not supported yet, all master registers below */
|
|
|
|
/* Command Block Registers */
|
|
/* MACRO PORT DESCRIPTION INPUT/OUTPUT */
|
|
/* ----- ---- ----------- ------------ */
|
|
#define REG_DATA 0x1F0 /* Data I/O */
|
|
#define REG_FEATURES 0x1F1 /* Features O */
|
|
#define REG_ERROR REG_FEATURES /* Error I */
|
|
/* The contents of this register are valid only when the error bit
|
|
(ERR) in the Status Register is set, except at drive power-up or at the
|
|
completion of the drive's internal diagnostics, when the register
|
|
contains a status code.
|
|
When the error bit (ERR) is set, Error Register bits are interpreted as such:
|
|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| BRK | UNC | | IDNF| | ABRT|TKONF| AMNF|
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| | | | | | | |
|
|
| | | | | | | `--- 0. Data address mark not found after correct ID field found
|
|
| | | | | | `--------- 1. Track 0 not found during execution of Recalibrate command
|
|
| | | | | `--------------- 2. Command aborted due to drive status error or invalid command
|
|
| | | | `--------------------- 3. Not used
|
|
| | | `--------------------------- 4. Requested sector's ID field not found
|
|
| | `--------------------------------- 5. Not used
|
|
| `--------------------------------------- 6. Uncorrectable data error encountered
|
|
`--------------------------------------------- 7. Bad block mark detected in the requested sector's ID field
|
|
*/
|
|
#define REG_NSECTOR 0x1F2 /* Sector Count I/O */
|
|
#define REG_LBA_LOW 0x1F3 /* Sector Number / LBA Bits 0-7 I/O */
|
|
#define REG_LBA_MID 0x1F4 /* Cylinder Low / LBA Bits 8-15 I/O */
|
|
#define REG_LBA_HIGH 0x1F5 /* Cylinder High / LBA Bits 16-23 I/O */
|
|
#define REG_DEVICE 0x1F6 /* Drive | Head | LBA bits 24-27 I/O */
|
|
/* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| 1 | L | 1 | DRV | HS3 | HS2 | HS1 | HS0 |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| | \_____________________/
|
|
| | |
|
|
| | `------------ If L=0, Head Select.
|
|
| | These four bits select the head number.
|
|
| | HS0 is the least significant.
|
|
| | If L=1, HS0 through HS3 contain bit 24-27 of the LBA.
|
|
| `--------------------------- Drive. When DRV=0, drive 0 (master) is selected.
|
|
| When DRV=1, drive 1 (slave) is selected.
|
|
`--------------------------------------- LBA mode. This bit selects the mode of operation.
|
|
When L=0, addressing is by 'CHS' mode.
|
|
When L=1, addressing is by 'LBA' mode.
|
|
*/
|
|
#define REG_STATUS 0x1F7 /* Status I */
|
|
/* Any pending interrupt is cleared whenever this register is read.
|
|
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| BSY | DRDY|DF/SE| # | DRQ | | | ERR |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| | | | | | | |
|
|
| | | | | | | `--- 0. Error.(an error occurred)
|
|
| | | | | | `--------- 1. Obsolete.
|
|
| | | | | `--------------- 2. Obsolete.
|
|
| | | | `--------------------- 3. Data Request. (ready to transfer data)
|
|
| | | `--------------------------- 4. Command dependent. (formerly DSC bit)
|
|
| | `--------------------------------- 5. Device Fault / Stream Error.
|
|
| `--------------------------------------- 6. Drive Ready.
|
|
`--------------------------------------------- 7. Busy. If BSY=1, no other bits in the register are valid.
|
|
*/
|
|
#define STATUS_BSY 0x80
|
|
#define STATUS_DRDY 0x40
|
|
#define STATUS_DFSE 0x20
|
|
#define STATUS_DSC 0x10
|
|
#define STATUS_DRQ 0x08
|
|
#define STATUS_CORR 0x04
|
|
#define STATUS_IDX 0x02
|
|
#define STATUS_ERR 0x01
|
|
|
|
#define REG_CMD REG_STATUS /* Command O */
|
|
/*
|
|
+--------+---------------------------------+-----------------+
|
|
| Command| Command Description | Parameters Used |
|
|
| Code | | PC SC SN CY DH |
|
|
+--------+---------------------------------+-----------------+
|
|
| ECh @ | Identify Drive | D |
|
|
| 91h | Initialize Drive Parameters | V V |
|
|
| 20h | Read Sectors With Retry | V V V V |
|
|
| E8h @ | Write Buffer | D |
|
|
+--------+---------------------------------+-----------------+
|
|
|
|
KEY FOR SYMBOLS IN THE TABLE:
|
|
===========================================-----=========================================================================
|
|
PC Register 1F1: Write Precompensation @ These commands are optional and may not be supported by some drives.
|
|
SC Register 1F2: Sector Count D Only DRIVE parameter is valid, HEAD parameter is ignored.
|
|
SN Register 1F3: Sector Number D+ Both drives execute this command regardless of the DRIVE parameter.
|
|
CY Register 1F4+1F5: Cylinder low + high V Indicates that the register contains a valid paramterer.
|
|
DH Register 1F6: Drive / Head
|
|
*/
|
|
|
|
/* Control Block Registers */
|
|
/* MACRO PORT DESCRIPTION INPUT/OUTPUT */
|
|
/* ----- ---- ----------- ------------ */
|
|
#define REG_DEV_CTRL 0x3F6 /* Device Control O */
|
|
/* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| HOB | - | - | - | - |SRST |-IEN | 0 |
|
|
+-----+-----+-----+-----+-----+-----+-----+-----+
|
|
| | |
|
|
| | `--------- Interrupt Enable.
|
|
| | - IEN=0, and the drive is selected,
|
|
| | drive interrupts to the host will be enabled.
|
|
| | - IEN=1, or the drive is not selected,
|
|
| | drive interrupts to the host will be disabled.
|
|
| `--------------- Software Reset.
|
|
| - The drive is held reset when RST=1.
|
|
| Setting RST=0 re-enables the drive.
|
|
| - The host must set RST=1 and wait for at least
|
|
| 5 microsecondsbefore setting RST=0, to ensure
|
|
| that the drive recognizes the reset.
|
|
`--------------------------------------------- HOB (High Order Byte)
|
|
- defined by 48-bit Address feature set.
|
|
*/
|
|
#define REG_ALT_STATUS REG_DEV_CTRL /* Alternate Status I */
|
|
/* This register contains the same information as the Status Register.
|
|
The only difference is that reading this register does not imply interrupt acknowledge or clear a pending interrupt.
|
|
*/
|
|
|
|
#define REG_DRV_ADDR 0x3F7 /* Drive Address I */
|
|
|
|
|
|
struct hd_cmd {
|
|
u8 features;
|
|
u8 count;
|
|
u8 lba_low;
|
|
u8 lba_mid;
|
|
u8 lba_high;
|
|
u8 device;
|
|
u8 command;
|
|
};
|
|
|
|
// added by mingxuan 2020-10-27
|
|
# define NO_FS_TYPE 0x0 //added by mingxuan 2020-10-30
|
|
# define ORANGE_TYPE 0x1
|
|
# define FAT32_TYPE 0x2
|
|
# define TTY_FS_TYPE 0x3 //added by mingxuan 2020-10-30
|
|
|
|
struct part_info {
|
|
u32 base; /* # of start sector (NOT byte offset, but SECTOR) */
|
|
u32 size; /* how many sectors in this partition */
|
|
u32 fs_type; //added by mingxuan 2020-10-27
|
|
};
|
|
|
|
/* main drive struct, one entry per drive */
|
|
struct hd_info
|
|
{
|
|
int open_cnt;
|
|
struct part_info primary[NR_PRIM_PER_DRIVE]; // NR_PRIM_PER_DRIVE = 5
|
|
struct part_info logical[NR_SUB_PER_DRIVE]; // NR_SUB_PER_DRIVE = 16 *4 =64
|
|
};
|
|
|
|
|
|
/***************/
|
|
/* DEFINITIONS */
|
|
/***************/
|
|
#define HD_TIMEOUT 10000 /* in millisec */
|
|
#define PARTITION_TABLE_OFFSET 0x1BE
|
|
#define ATA_IDENTIFY 0xEC
|
|
#define ATA_READ 0x20
|
|
#define ATA_WRITE 0x30
|
|
/* for DEVICE register. */
|
|
#define MAKE_DEVICE_REG(lba,drv,lba_highest) (((lba) << 6) | \
|
|
((drv) << 4) | \
|
|
(lba_highest & 0xF) | 0xA0)
|
|
|
|
// added by xw, 18/8/26
|
|
typedef struct rdwt_info
|
|
{
|
|
MESSAGE *msg;
|
|
void *kbuf;
|
|
PROCESS *proc;
|
|
struct rdwt_info *next;
|
|
} RWInfo;
|
|
|
|
typedef struct
|
|
{
|
|
RWInfo *front;
|
|
RWInfo *rear;
|
|
} HDQueue;
|
|
|
|
void init_hd();
|
|
void hd_open(int device);
|
|
void hd_close(int device);
|
|
void hd_service();
|
|
|
|
void hd_rdwt(MESSAGE *p);
|
|
void hd_rdwt_sched(MESSAGE *p);
|
|
void hd_ioctl(MESSAGE *p);
|
|
//~xw
|
|
|
|
#endif /* _ORANGES_HD_H_ */
|