diff --git a/kaleid/kernel/io/ata.asm b/kaleid/kernel/io/ata.asm new file mode 100644 index 0000000..40805c9 --- /dev/null +++ b/kaleid/kernel/io/ata.asm @@ -0,0 +1,152 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Basic Read Only ATA Long mode Driver ; +; (x86_64 architecture only) ; +; ; +; ; +; Copyright © 2018-2019 The OS/K Team ; +; ; +; This file is part of OS/K. ; +; ; +; OS/K is free software: you can redistribute it and/or modify ; +; it under the terms of the GNU General Public License as published by ; +; the Free Software Foundation, either version 3 of the License, or ; +; (at your option) any later version. ; +; ; +; OS/K is distributed in the hope that it will be useful, ; +; but WITHOUT ANY WARRANTY; without even the implied warranty of ; +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; +; GNU General Public License for more details. ; +; ; +; You should have received a copy of the GNU General Public License ; +; along with OS/K. If not, see . ; +;=----------------------------------------------------------------------------=; + +[BITS 64] + +;; BPB +%define OEMName bp+0x03 ; Disk label +%define bytesPerSector bp+0x0b ; Bytes per sector +%define sectorsPerCluster bp+0x0d ; Sectors per cluster +%define reservedSectors bp+0x0e ; Reserved sectors +%define fats bp+0x10 ; Number of fats +%define rootDirEntries bp+0x11 ; Number of entries in root dir +%define sectors bp+0x13 ; Logical sectors +%define mediaType bp+0x15 ; Media descriptor byte +%define fatSectors bp+0x16 ; Sectors per FAT +%define sectorsPerTrack bp+0x18 ; Sectors per track +%define heads bp+0x1a ; Number of sides/heads +%define hiddenSectors bp+0x1c ; Hidden sectors +%define hugeSectors bp+0x20 ; LBA sectors +%define biosBootdrvNum bp+0x24 ; Bootdrv number +%define reserved bp+0x25 ; This is not used +%define bootSignature bp+0x26 ; Bootdrv signature +%define volumeId bp+0x27 ; Volume ID +%define volumeLabel bp+0x2b ; Volume Label +%define fatTypeLabel bp+0x36 ; File system type + +;; GLOBAL DATA + +Bootdrv db 0 +ended db "[End of Sector]", 0x0A, 0x0A, 0x0D, 0x0 +buffer: times 513 db "_", 0 + +;; TEXT + +ata_read: +;-----------------------------------------------------------------------; +; x64/LM ATA Reading function ; +; bl : number of sectors to read XXX ; +; bh : the first sector to read ; +;-----------------------------------------------------------------------; + +; Technical infos about the ports (Intel Doc): +; +; Port Access Mode Misc +; +; 1f0 r/w Data register, the bytes of the disk itself +; 1f1 r Error register that can be handled +; 1f2 r/w Sector count, how many sectors to read +; 1f3 r/w Sector number, the actual sector wanted +; 1f4 r/w Cylinder low, cylinders is 0-1024 +; 1f5 r/w Cylinder high, this makes up the rest of the 1024 +; 1f6 r/w Drive/head +; bit 7 = 1 +; bit 6 = 0 +; bit 5 = 1 +; bit 4 = 0 drive 0 select +; = 1 drive 1 select +; bit 3-0 head select bits +; 1f7 r Status register +; bit 7 = 1 controller is executing a command +; bit 6 = 1 drive is ready +; bit 5 = 1 write fault +; bit 4 = 1 seek complete +; bit 3 = 1 sector buffer requires servicing +; bit 2 = 1 disk data read corrected +; bit 1 = 1 index - set to 1 each revolution +; bit 0 = 1 previous command ended in an error +; 1f7 w Command register +; commands: +; 50h format track +; 20h read sectors with retry +; 21h read sectors without retry +; 22h read long with retry +; 23h read long without retry +; 30h write sectors with retry +; 31h write sectors without retry +; 32h write long with retry +; 33h write long without retry +; + push rax + push rbx + push rcx + push rdx + push rdi + mov dx, 0x1f6 ; Drive and head port + mov al, 0x0a0 ; Drive 0, head 0 + out dx,al + + mov dx, 0x1f2 ; Sector count port + mov al, bl ; Read bl(s) sector + out dx, al + + mov dx, 0x1f3 ; Sector number port + mov al, bh ; Read from sector n°bh + out dx, al + + mov dx, 0x1f4 ; Cylinder low port + mov al, 0 ; Cylinder 0 + out dx, al + + mov dx, 0x1f5 ; Cylinder high port + mov al, 0 ; The rest of the cylinder 0 + out dx, al + + mov dx, 0x1f7 ; Command port + mov al, 0x20 ; Read with retry. + out dx, al +still_going: + in al, dx + test al, 8 ; This means the sector buffer requires + ;servicing. + jz still_going ; Don't continue until the sector buffer + ;is ready. + + mov cx, 512/2 ; One sector /2 because it copies words + mov rdi, QWORD buffer + mov dx, 0x1f0 ; Data port - data comes in and out of here. + rep insw + pop rdi + mov bl, 0x0F + mov rdi, QWORD buffer + call KernLog + mov bl, 0x0A + mov rdi, ended + call KernLog + pop rdx + pop rcx + pop rbx + pop rax + ret