📄 forte_ide.c
字号:
#include "printk.h"#include "machine.h"#include <string.h>typedef unsigned long DWORD ;#define TPRINTK(arg...) printk("\t"##arg)void delay_50ms(int delay);static int packet_length = 0;#define MAX_PACKET_LENGTH (256)#include "ide.h"#define IOBASE 0x20000000#define MECR (*(volatile unsigned long*)(0xA0000018))#define IDE_DATA_REG (IOBASE + 0x40)#define IDE_ERROR_REG (IOBASE + 0x41)#define IDE_FEATURE_REG IDE_ERROR_REG#define IDE_NSECTOR_REG (IOBASE + 0x42)#define IDE_SECTOR_REG (IOBASE + 0x43)#define IDE_LCYL_REG (IOBASE + 0x44)#define IDE_HCYL_REG (IOBASE + 0x45)#define IDE_SELECT_REG (IOBASE + 0x46)#define IDE_STATUS_REG (IOBASE + 0x47)#define IDE_COMMAND_REG IDE_STATUS_REG#define IDE_CONTROL_REG (IOBASE + 0xc6)#define IDE_ALTSTATUS_REG IDE_CONTROL_REGvoid ide_fixstring (unsigned char *s, const int bytecount, const int byteswap){ unsigned char *p = s, *end = &s[bytecount & ~1]; if (byteswap) { for (p = end ; p != s;) { unsigned short *pp = (unsigned short *) (p -= 2); *pp = ___swab16(*pp); } } while (s != end && *s == ' ') ++s; while (s != end && *s) { if (*s++ != ' ' || (s != end && *s && *s != ' ')) *p++ = *(s-1); } while (p != end) *p++ = '\0';}char * get_medium_str(unsigned char type){ if (type > 0x04) type -= 0x04; switch(type) { case 0x01 : return "data"; case 0x02 : return "audio"; case 0x03 : return "mixed"; case 0x04 : return "hybrid"; default: return "Unknown"; }}int wait_for_drq(unsigned char good, unsigned char bad){ unsigned char stat; unsigned int try=200; int i,j; while (!OK_STAT(stat=GET_STAT(),good,bad)) {// IDE_DELAY;// printk(__FUNCTION__"(): stat = %x, %x, %x\n", stat, good, bad);// printk(","); for (i=1000;i>0;i--) j=i; if (try) try--; else { return 1; } } return 0;}void init_pc(unsigned char *pc, unsigned char cmd, unsigned short bc){ memset(pc, 0, MAX_PACKET_LENGTH); pc[0] = cmd; WRITE_U8(SELECT_ALL, IDE_SELECT_REG); WRITE_U8(0x00, IDE_FEATURE_REG); WRITE_U8(0x00, IDE_NSECTOR_REG); WRITE_U8(0x00, IDE_SECTOR_REG); WRITE_U8(bc & 0xff, IDE_LCYL_REG); WRITE_U8((bc>>8) & 0xff, IDE_HCYL_REG); WRITE_U8(0x08, IDE_CONTROL_REG); WRITE_U8(0xa0, IDE_COMMAND_REG); // packet command#if 0 while ((READ_U8(IDE_STATUS_REG) & BUSY_STAT)) { IDE_DELAY; printk("!\n"); }#endif}void wait_for_ready(unsigned char extra){ unsigned char stat; int i=100,j; do { stat = READ_U8(IDE_STATUS_REG); for (i=100;i>0;i--) j=i; printk(__FUNCTION__"(): stat = %x\n", stat); IDE_DELAY; } while (stat & (BUSY_STAT | extra));}void write_packet(unsigned char *pc){ int i; unsigned short *pc_w = (unsigned short*)pc; unsigned short cmd; printk("\t"); for (i=0;i<(packet_length / 2); i++) {// cmd = ___swab16(*pc_w); cmd = *pc_w; printk("%04x ", cmd); WRITE_U16(cmd, IDE_DATA_REG); pc_w++; } printk("\n");}void read_packet_data(unsigned short *buf, int size){ int i;// printk("size = %d, bc = %d\n",// size, READ_U8(IDE_LCYL_REG) , (READ_U8(IDE_HCYL_REG)<<8)); for (i=0;i<size;i++) { *buf = (READ_U16(IDE_DATA_REG));// printk(__FUNCTION__"(): buf = %x\n", *buf); buf++; }}void block_read_command(unsigned long block, unsigned char rsector, unsigned char cmd){ WRITE_U8(0x08, IDE_CONTROL_REG); WRITE_U8(rsector, IDE_NSECTOR_REG); WRITE_U8(block & 0xff, IDE_SECTOR_REG); WRITE_U8((block >> 8) & 0xff, IDE_LCYL_REG); WRITE_U8((block >> 16) & 0xff, IDE_HCYL_REG); WRITE_U8(((block >> 24) & 0x0f) | SELECT_0, IDE_SELECT_REG); WRITE_U8(cmd, IDE_COMMAND_REG); // command do {// IDE_DELAY; } while ((READ_U8(IDE_STATUS_REG) & BUSY_STAT));}void delay_50ms(int delay){ printk("\t"); for (; delay; delay--) { IDE_DELAY; printk("."); } printk("\n");}void eject(void){ unsigned char pc[MAX_PACKET_LENGTH]; init_pc(&pc[0], 0x1b, 0); pc[4] = 0x02 + 0; write_packet(&pc[0]);}int main(void){ struct hd_driveid driveid; DWORD hd_status; int media_type = 0; printk("\n\n\n");/* * step0: */ { printk("status = 0x%02x\n", READ_U8(IDE_STATUS_REG)); printk("error = 0x%02x\n", READ_U8(IDE_ERROR_REG)); printk("[+] step #0 : wait for IDE stability\n");// delay_50ms(10); MECR = 0x994A7fff; printk("\tIOBASE = 0x%08x\n", IOBASE); printk("\tMECR = 0x%08x\n", MECR); printk("[-] step #0 : end\n\n");#if 0 // dump REGs printk("DATA : %04x\n" , READ_U16(IOBASE + IDE_DATA)); printk("ERRFEA : %02x\n" , READ_U8(IOBASE + IDE_ERRFEA)); printk("SCTCT : %02x\n" , READ_U8(IOBASE + IDE_SCTCT)); printk("SCT : %02x\n" , READ_U8(IOBASE + IDE_SCT)); printk("CLNLOW : %02x\n" , READ_U8(IOBASE + IDE_CLNLOW)); printk("CLNHIGH: %02x\n" , READ_U8(IOBASE + IDE_CLNHIGH)); printk("HEAD : %02x\n" , READ_U8(IOBASE + IDE_HEAD)); printk("STCMD : %02x\n" , READ_U8(IOBASE + IDE_STCMD));#endif }/* * step1: */ { printk("[+] step #1 : select all ide\n"); WRITE_U8(SELECT_ALL, IDE_SELECT_REG); IDE_DELAY; if (READ_U8(IDE_SELECT_REG) != SELECT_ALL) { printk("\nselect all failed ? : %x != %x\n", READ_U8(IDE_SELECT_REG), SELECT_ALL); } printk("[-] step #1 : end\n\n"); }/* * step2: */ { unsigned char a,s; int stat; printk("[+] step #2 : send identify command\n"); IDE_DELAY; a = READ_U8(IDE_ALTSTATUS_REG); s = READ_U8(IDE_STATUS_REG); if ( (a ^ s) & ~INDEX_STAT ) hd_status = IDE_ALTSTATUS_REG; else hd_status = IDE_STATUS_REG; WRITE_U8(0xec, IDE_COMMAND_REG); // command : identify - ide-disk do { IDE_DELAY; } while (READ_U8(hd_status) & BUSY_STAT); if (!OK_STAT(stat=GET_STAT(),DRQ_STAT,BAD_R_STAT)) { WRITE_U8(0xa1, IDE_COMMAND_REG); // command : pidentify - ide-cd IDE_DELAY; do { IDE_DELAY; } while (READ_U8(hd_status) & BUSY_STAT); if (!OK_STAT(stat=GET_STAT(),DRQ_STAT,BAD_R_STAT)) { printk(" failed. stat=%x (good=%x, bad=%x)\n", stat, DRQ_STAT, BAD_R_STAT); return 0; } } else media_type = IDE_DISK; printk("[-] step #2 : end\n\n"); }/* * step3: */ { unsigned short * dptr = (unsigned short*)&driveid; int i = 0; unsigned short aaa,bbb; printk("[+] step #3 : do identify\n\n"); for (i=0;i<sizeof(driveid)/2 -1;i++) { *dptr = READ_U16(IDE_DATA_REG) & 0xffff; dptr++; } if (!media_type) media_type = (driveid.config >> 8) & 0x1f; TPRINTK("Drive type : "); switch(media_type) { case IDE_FLOPPY: printk("Floppy"); break; case IDE_CDROM: printk("CD/DVD-ROM"); break; case IDE_TAPE: printk("Tape"); break; case IDE_OPTICAL: printk("Optical"); break; case IDE_DISK: printk("ATA-Disk"); break; default: printk("Unknown (type %x)", media_type); break; } printk(" drive\n"); ide_fixstring (&driveid.model[0], sizeof(driveid.model), 1); ide_fixstring (&driveid.fw_rev[0], sizeof(driveid.fw_rev), 1); ide_fixstring (&driveid.serial_no[0], sizeof(driveid.serial_no), 1); driveid.model[sizeof(driveid.model)-1] = '\0'; driveid.fw_rev[sizeof(driveid.fw_rev)-1] = '\0'; driveid.serial_no[sizeof(driveid.serial_no)-1] = '\0'; TPRINTK("Model name : %s\n", driveid.model); TPRINTK("Firmware revision : %s\n", driveid.fw_rev); TPRINTK("Serial number : %s\n", driveid.serial_no); printk("\n"); aaa = driveid.config; TPRINTK("Protocol Type : "); bbb = (aaa >> 14) & 0x03; switch(bbb) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -