Added a working IDE-write driver

This commit is contained in:
Morten Delenk 2016-07-24 12:48:17 +02:00
parent b6333e7174
commit 05941e6cda
6 changed files with 110 additions and 6 deletions

View file

@ -43,4 +43,22 @@ namespace MTGosHAL {
ata2.readSector(drv, sectorNum, buf);
ata3.readSector(drv, sectorNum, buf);
}
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
ata0.readSector(drv, sectorNum, num, buf);
ata1.readSector(drv, sectorNum, num, buf);
ata2.readSector(drv, sectorNum, num, buf);
ata3.readSector(drv, sectorNum, num, buf);
}
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
ata0.writeSector(drv, sectorNum, buf);
ata1.writeSector(drv, sectorNum, buf);
ata2.writeSector(drv, sectorNum, buf);
ata3.writeSector(drv, sectorNum, buf);
}
auto BlockDevice::writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
ata0.writeSector(drv, sectorNum, num, buf);
ata1.writeSector(drv, sectorNum, num, buf);
ata2.writeSector(drv, sectorNum, num, buf);
ata3.writeSector(drv, sectorNum, num, buf);
}
}

View file

@ -68,6 +68,7 @@ namespace MTGosHAL {
return;
if(!(existent&(1<<(drive-num*2))))
return;
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
outb(baseport+DRV, 0x40 | (drive&1)<<4);
outb(baseport+SECTOR_CNT, 0);
outb(baseport+LBAlo, (uint8_t)(sectorNum>>24));
@ -85,4 +86,85 @@ namespace MTGosHAL {
uint16_t *bufw=(uint16_t *)buf;
asm volatile ("rep insw" : : "D"((int)bufw),"d"(baseport),"c"(256));
}
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
if(drive<(this->num*2)||drive>(this->num*2+1))
return;
if(!(existent&(1<<(drive-this->num*2))))
return;
if(num==0)
return;
if(num>65536)
return;
if(num==65536)
num=0;
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
outb(baseport+DRV, 0x40 | (drive&1)<<4);
outb(baseport+SECTOR_CNT, (uint8_t)(num >> 8));
outb(baseport+LBAlo, (uint8_t)(sectorNum>>24));
outb(baseport+LBAmid, (uint8_t)(sectorNum>>32));
outb(baseport+LBAhi, (uint8_t)(sectorNum>>40));
outb(baseport+SECTOR_CNT, (uint8_t)num);
outb(baseport+LBAlo, (uint8_t)(sectorNum));
outb(baseport+LBAmid, (uint8_t)(sectorNum>>8));
outb(baseport+LBAhi, (uint8_t)(sectorNum>>16));
outb(baseport+CMD, 0x24);
inb(baseport+CMD);
inb(baseport+CMD);
inb(baseport+CMD);
while(inb(baseport+CMD)&0x80);
uint16_t *bufw=(uint16_t *)buf;
asm volatile ("rep insw" : : "D"((int)bufw),"d"(baseport),"c"(256*num));
}
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
if(drive<(this->num*2)||drive>(this->num*2+1))
return;
if(!(existent&(1<<(drive-this->num*2))))
return;
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
outb(baseport+SECTOR_CNT, (uint8_t)(0));
outb(baseport+LBAlo, (uint8_t)(sectorNum>>24));
outb(baseport+LBAmid, (uint8_t)(sectorNum>>32));
outb(baseport+LBAhi, (uint8_t)(sectorNum>>40));
outb(baseport+SECTOR_CNT, (uint8_t)1);
outb(baseport+LBAlo, (uint8_t)(sectorNum));
outb(baseport+LBAmid, (uint8_t)(sectorNum>>8));
outb(baseport+LBAhi, (uint8_t)(sectorNum>>16));
outb(baseport+CMD, 0x34);
inb(baseport+CMD);
inb(baseport+CMD);
inb(baseport+CMD);
while(inb(baseport+CMD)&ATAPIO_BSY);
for(int i=0;i<256;i++) {
asm volatile("outsw; aad" : : "S"((int)buf),"d"(baseport),"a"(8787)); //The AAD is for creating a short delay between writes, as the compiler might unroll this loop.
}
}
auto IDE::writeSector(int32_t drive, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void {
if(drive<(this->num*2)||drive>(this->num*2+1))
return;
if(!(existent&(1<<(drive-this->num*2))))
return;
if(num==0)
return;
if(num>65536)
return;
if(num==65536)
num=0;
while(inb(baseport+ALTCMD)&ATAPIO_BSY);
outb(baseport+SECTOR_CNT, (uint8_t)(num >> 8));
outb(baseport+LBAlo, (uint8_t)(sectorNum>>24));
outb(baseport+LBAmid, (uint8_t)(sectorNum>>32));
outb(baseport+LBAhi, (uint8_t)(sectorNum>>40));
outb(baseport+SECTOR_CNT, (uint8_t)num);
outb(baseport+LBAlo, (uint8_t)(sectorNum));
outb(baseport+LBAmid, (uint8_t)(sectorNum>>8));
outb(baseport+LBAhi, (uint8_t)(sectorNum>>16));
outb(baseport+CMD, 0x34);
inb(baseport+CMD);
inb(baseport+CMD);
inb(baseport+CMD);
while(inb(baseport+CMD)&ATAPIO_BSY);
for(uint32_t i=0;i<(num<<8);i++) {
asm volatile("outsw; aad" : : "S"((int)buf),"d"(baseport),"a"(8787)); //The AAD is for creating a short delay between writes, as the compiler might partially unroll this loop.
}
}
}

View file

@ -14,7 +14,9 @@ namespace MTGosHAL {
auto getDriveCnt() -> int32_t;
auto getDriveNumByName(const char *) -> int32_t;
auto readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void; //Has to be at least 512 bytes big!
auto readSectors(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
auto readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
auto writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void;
auto writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void;
};
class BlockDevice {
private:
@ -29,8 +31,9 @@ namespace MTGosHAL {
auto getDriveCnt() -> int32_t;
auto getDriveNumByName(const char *) -> int32_t; //Returns -1 if device is not existent
auto readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void; //Has to be at least 512 bytes big!
auto readSectors(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
auto readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
auto writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void;
auto writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void;
};
}

View file

@ -80,7 +80,7 @@ namespace MTGosHAL {
}
::main(progs, debug, mm, out, err, in, tasks, disk);
uint8_t buf[512];
disk.readSector(disk.getDriveNumByName("ATA0m1"),0,buf);
disk.readSector(disk.getDriveNumByName("ATA0m"),0,buf);
out << (char*)buf;
out << "こんにちは、ユニコード。\nЗдравствуй, Юникод.\nΓεια σου, Γιούνικοντ.\n안녕하세요, 유니코드.\n"_s;
//sti();

View file

@ -11,8 +11,9 @@ namespace MTGosHAL {
auto getDriveCnt() -> int32_t;
auto getDriveNumByName(const char *) -> int32_t; //Returns -1 if device is not existent
auto readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void; //Has to be at least 512 bytes big!
auto readSectors(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
auto readSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
auto writeSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void;
auto writeSector(int32_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void;
};
}

Binary file not shown.