/*************************************************************************//** ***************************************************************************** * @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. * * Master Boot Record (MBR): * Located at offset 0x1BE in the 1st sector of a disk. MBR contains * four 16-byte partition entries. Should end with 55h & AAh. * * partitions in MBR: * 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. * * extented partition: * 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_ */