📄 hw_cf.c
字号:
IDE_SECTOR_NUMBER_REG = 3, IDE_CYLINDER_LOW_REG = 4, IDE_CYLINDER_HIGH_REG = 5, IDE_DRIVE_HEAD_REG = 6, IDE_COMMAND_REG = 7, IDE_STATUS_REG = 7, // IDE_CONTROL_REG = 8, IDE_SECTOR_BUF = 0x400};/* reference: * ANSI NCITS 317-1998 * AT Attachment with Packet Interface Extension (ata/atapi-4) */enum ide_command { IDE_COMMAND_READ_BUFFER = 0xE4, IDE_COMMAND_READ_SECTORS = 0x20, /* page 139 */ IDE_COMMAND_WRITE_SECTORS = 0x30, /* page 207 */ IDE_COMMAND_SEEK = 0x70, /* page 157 */ // IDE_COMMAND_ = 0x91; IDE_COMMAND_IDENTIFY = 0xEC, IDE_COMMAND_IDENTIFY_PACKET = 0xA1, /* page 93 */};/* set this bit if passing LBA instead of C/H/S */#define DEVICE_HEAD_IS_LBA (1 << 6)struct drive_identification { /* 0x00 */ unsigned short flags; /* 0x01 */ unsigned short n_cylinders; /* 0x02 */ unsigned short reserved02; /* 0x03 */ unsigned short n_heads; /* 0x04 */ unsigned short n_bytes_per_track; /* 0x05 */ unsigned short n_bytes_per_sector; /* 0x06 */ unsigned short n_sectors_per_track; /* 0x07 */ unsigned short inter_sector_gap; /* 0x08 */ unsigned short reserved08; /* 0x09 */ unsigned short n_vendor_status_words; /* 0x0a */ unsigned char serial_number[20]; /* 0x14 */ unsigned short controller_type; /* 0x15 */ unsigned short n_buffer_512b; /* 0x16 */ unsigned short n_ecc_bytes; /* 0x17 */ unsigned char firmware_revision[8]; /* 0x1b */ unsigned char model_number[40] ; /* 0x2f */ unsigned short read_write_multiples_implemented; /* 0x30 */ unsigned short double_word_io_supported; /* 0x31 */ unsigned short capabilities31; /* 0x32 */ unsigned short capabilities32; /* 0x33 */ unsigned short minimum_pio_mode_number; /* 0x34 */ unsigned short retired34; /* 0x35 */ unsigned short flags53; /* 0x36 */ unsigned short current_n_cylinders; /* 0x37 */ unsigned short current_n_heads; /* 0x38 */ unsigned short current_n_sectors_per_track; /* 0x39 */ unsigned long current_n_sectors; /* 0x3a */ /* 0x3b */ unsigned short reserved3b; /* 0x3c */ unsigned long n_sectors_user_addressable; /* 0x3d */ /* 0x3e */ unsigned short retired3e; /* 0x3f */ unsigned short reserved3f; /* 0x40 - 0x4f */ unsigned short reserved40[16]; /* 0x50 */ unsigned short major_version; /* 0x51 */ unsigned short minor_version; /* 0x52 */ unsigned short cmd_set[6];};struct ide_adapter { volatile char *ioport; char buf[512]; struct drive_identification identification; };/* Byte-swap (in 2-byte chunks) from src to dest and len is in bytes and counts space for a trailing NUL to be added to the end of dest (and is thus odd) */void copy_ident_string(char *dest, const char *src, int len) { int i; len--; for (i = 0; i < len; i += 2) { dest[i] = src[i + 1]; dest[i + 1] = src[i]; } dest[len] = 0;}int ide_attach(void) { struct ide_adapter *ide_adapter = (struct ide_adapter *)0xA3110000; memset(ide_adapter, 0, sizeof(struct ide_adapter)); ide_adapter->ioport = (char *)0x2C000000; ide_identify(); return 0;}#define IDE_STATUS_ERR (1 << 0)#define IDE_STATUS_DRQ (1 << 3)#define IDE_STATUS_DEVFLT (1 << 5)#define IDE_STATUS_DRDY (1 << 6)#define IDE_STATUS_BSY (1 << 7) int ide_identify(void) { int i; int ide_use_packet = 0; int ide_verbose = 0; int ide_debug = 0; struct ide_adapter *ide_adapter = (struct ide_adapter *)0xA3110000; char serial_number[21]; char firmware_revision[9]; char model_number[41]; u8 identify_command = 0; if (ide_use_packet) identify_command = IDE_COMMAND_IDENTIFY_PACKET; else identify_command = IDE_COMMAND_IDENTIFY; ide_adapter->ioport[IDE_COMMAND_REG] = identify_command; if (ide_verbose) putLabeledWord(" identify command=", identify_command); while (ide_adapter->ioport[IDE_STATUS_REG] & IDE_STATUS_BSY) { if (ide_debug) putLabeledWord(" ide status=", ide_adapter->ioport[IDE_STATUS_REG]); } /* copy in identification */ for (i = 0; i < sizeof(struct drive_identification)/2; i++) { unsigned short *buf = (unsigned short *)&ide_adapter->identification; unsigned short *sector_buffer = (unsigned short *)&ide_adapter->ioport[IDE_SECTOR_BUF]; buf[i] = sector_buffer[i]; } //if (ide_verbose) // hex_dump((unsigned char *)&ide_adapter->identification, sizeof(struct drive_identification)); //copy_ident_string(serial_number, ide_adapter->identification.serial_number, sizeof(serial_number)); //copy_ident_string(firmware_revision, ide_adapter->identification.firmware_revision, sizeof(firmware_revision)); //copy_ident_string(model_number, ide_adapter->identification.model_number, sizeof(model_number)); //putstr(" serial_number: "); putstr(serial_number); //putstr(" firmware_revision: "); putstr(firmware_revision); //putstr(" model_number: "); putstr(model_number); if (ide_verbose) { putLabeledWord(" n_sectors_user_addressable=", ide_adapter->identification.n_sectors_user_addressable); putLabeledWord(" bytes_per_sector=", ide_adapter->identification.n_bytes_per_sector); putLabeledWord(" major_version=", ide_adapter->identification.major_version); putLabeledWord(" minor_version=", ide_adapter->identification.minor_version); putLabeledWord(" flags=", ide_adapter->identification.flags); putLabeledWord(" bytes_per_track=", ide_adapter->identification.n_bytes_per_track); putLabeledWord(" n_sectors_per_track=", ide_adapter->identification.n_sectors_per_track); putLabeledWord(" n_cylinders=", ide_adapter->identification.n_cylinders); putLabeledWord(" n_heads=", ide_adapter->identification.n_heads); putLabeledWord(" cmdset[0]=", ide_adapter->identification.cmd_set[0]); putLabeledWord(" cmdset[1]=", ide_adapter->identification.cmd_set[1]); putLabeledWord(" cmdset[2]=", ide_adapter->identification.cmd_set[2]); putLabeledWord(" cmdset[3]=", ide_adapter->identification.cmd_set[3]); putLabeledWord(" cmdset[4]=", ide_adapter->identification.cmd_set[4]); putLabeledWord(" cmdset[5]=", ide_adapter->identification.cmd_set[5]); } ide_adapter->identification.n_bytes_per_sector = 512; //putLabeledWord(" ACTUAL bytes_per_sector=", ide_adapter->identification.n_bytes_per_sector); if (ide_debug) { putLabeledWord(": status reg=", ide_adapter->ioport[IDE_STATUS_REG]); putLabeledWord(": error reg=", ide_adapter->ioport[IDE_ERROR_REG]); } return 0;}int ide_read(char *buf, unsigned long offset, unsigned long len) { struct ide_adapter *ide_adapter = (struct ide_adapter *)0xA3110000; int ide_use_chs = 0; int ide_sector_buffer_stride = 2; int ide_debug = 0; if (!ide_adapter->identification.n_bytes_per_sector) { return -1; } else { struct drive_identification *id = &ide_adapter->identification; unsigned long sector_count = len / id->n_bytes_per_sector; unsigned long sector_number = offset / id->n_bytes_per_sector; unsigned long start_sector = sector_number & 0xff; unsigned long start_cylinder = (sector_number >> 8) &0xffff ; unsigned long start_head = (sector_number >> 24) & 0x7 ; u8 status; int i; unsigned long count; if (ide_use_chs) { u32 track = sector_number / id->n_sectors_per_track; u32 sect_offset = sector_number % id->n_sectors_per_track + 1; } if (ide_debug) { putLabeledWord(" start_cylinder=", start_cylinder); putLabeledWord(" start_head=", start_head); putLabeledWord(" start_sector=", start_sector); putLabeledWord(" sector_count=", sector_count); } ide_adapter->ioport[IDE_SECTOR_NUMBER_REG] = start_sector; ide_adapter->ioport[IDE_CYLINDER_HIGH_REG] = (start_cylinder >> 8) & 0xff; ide_adapter->ioport[IDE_CYLINDER_LOW_REG] = start_cylinder & 0xff; ide_adapter->ioport[IDE_SECTOR_COUNT_REG] = sector_count & 0xff; ide_adapter->ioport[IDE_DRIVE_HEAD_REG] = DEVICE_HEAD_IS_LBA | (start_head & 0xf); ide_adapter->ioport[IDE_COMMAND_REG] = IDE_COMMAND_READ_SECTORS; count = 0; while (ide_adapter->ioport[IDE_STATUS_REG] & IDE_STATUS_BSY) { count++; } status = ide_adapter->ioport[IDE_STATUS_REG]; if (ide_debug) { putLabeledWord("ide read: status reg=", status); putLabeledWord("ide read: error reg=", ide_adapter->ioport[IDE_ERROR_REG]); putLabeledWord("ide read: bsy wait for num times =", count); } if (status & (IDE_STATUS_ERR | IDE_STATUS_DEVFLT)) { putLabeledWord("ide command failed with status=", status); putLabeledWord(" error reg=", ide_adapter->ioport[IDE_ERROR_REG]); putLabeledWord(" cyl high reg=", ide_adapter->ioport[IDE_CYLINDER_HIGH_REG]); putLabeledWord(" cyl low reg=", ide_adapter->ioport[IDE_CYLINDER_LOW_REG]); return -1; } for (i = 0; i < 512; i += ide_sector_buffer_stride) { if (ide_sector_buffer_stride == 1) buf[i] = ide_adapter->ioport[IDE_SECTOR_BUF + i]; else *(short *)&buf[i] = *(short *)&ide_adapter->ioport[IDE_SECTOR_BUF + i]; } return 0; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -