BigOS/include/hd.h
2022-12-13 13:29:17 +08:00

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_ */