Added a working IDE-write driver
This commit is contained in:
parent
b6333e7174
commit
05941e6cda
6 changed files with 110 additions and 6 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
BIN
kernel/libhal.a
BIN
kernel/libhal.a
Binary file not shown.
Loading…
Reference in a new issue