diff --git a/kernel/hal/x86/blk/BlockDevice.cpp b/kernel/hal/x86/blk/BlockDevice.cpp index ab57e86..f7ea8f9 100644 --- a/kernel/hal/x86/blk/BlockDevice.cpp +++ b/kernel/hal/x86/blk/BlockDevice.cpp @@ -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); + } } diff --git a/kernel/hal/x86/blk/ide.cpp b/kernel/hal/x86/blk/ide.cpp index bdb2b4e..091773e 100644 --- a/kernel/hal/x86/blk/ide.cpp +++ b/kernel/hal/x86/blk/ide.cpp @@ -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. + } + } } diff --git a/kernel/hal/x86/include/blockdev.hpp b/kernel/hal/x86/include/blockdev.hpp index bd7a085..f7fb399 100644 --- a/kernel/hal/x86/include/blockdev.hpp +++ b/kernel/hal/x86/include/blockdev.hpp @@ -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; }; } diff --git a/kernel/hal/x86/init/init.cpp b/kernel/hal/x86/init/init.cpp index 853258d..3e0ad2d 100644 --- a/kernel/hal/x86/init/init.cpp +++ b/kernel/hal/x86/init/init.cpp @@ -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(); diff --git a/kernel/kernel/include/blockdev.hpp b/kernel/kernel/include/blockdev.hpp index dbb6518..a38223a 100644 --- a/kernel/kernel/include/blockdev.hpp +++ b/kernel/kernel/include/blockdev.hpp @@ -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; }; } diff --git a/kernel/libhal.a b/kernel/libhal.a index 1ba527c..75fcef5 100644 Binary files a/kernel/libhal.a and b/kernel/libhal.a differ