Fixed the ATA read driver. now exposing the Block device interface to the kernel
This commit is contained in:
parent
81e223fc8a
commit
2104685d55
6 changed files with 132 additions and 80 deletions
|
@ -6,7 +6,7 @@ CPP = $(PREFIX)g++
|
|||
CC = $(PREFIX)gcc
|
||||
ASFLAGS = -m32
|
||||
CFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -Ic_include/ -ffreestanding -std=c11 -fno-builtin -Werror -nostdlib -g -fpie
|
||||
CPPFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fno-pie
|
||||
CPPFLAGS = -m32 -Wall -fno-stack-protector -nostdinc -std=c++14 -Iinclude/ -Ic_include/ -fno-rtti -fno-exceptions -ffreestanding -fno-builtin -Werror -nostdlib -fno-use-cxa-atexit -Wextra -Wno-unused -g -fno-pie -Wno-reorder
|
||||
LDFLAGS = -r -melf_i386
|
||||
|
||||
|
||||
|
|
|
@ -18,78 +18,29 @@
|
|||
#define DRV 6
|
||||
#define CMD 7
|
||||
namespace MTGosHAL {
|
||||
uint16_t ataports[4]={0x1F0,0x170,0x1E8,0x168};
|
||||
uint16_t commports[4]={0x3F6,0x376,0x3E6,0x366};
|
||||
BlockDevice::BlockDevice(): numDevices(0), existent(0) {
|
||||
for(int i=0;i<4;i++) {
|
||||
if(inb(ataports[i]+CMD)!=0xFF) {
|
||||
outb(ataports[i]+DRV, 0xE0);
|
||||
outb(ataports[i]+LBAlo,0x55);
|
||||
if(inb(ataports[i]+LBAlo)==0x55) {
|
||||
existent|=1<<(i<<1);
|
||||
numDevices++;
|
||||
}
|
||||
outb(ataports[i]+DRV, 0xF0);
|
||||
outb(ataports[i]+LBAlo,0x55);
|
||||
if(inb(ataports[i]+LBAlo)==0x55) {
|
||||
existent|=1<<((i<<1)+1);
|
||||
numDevices++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(numDevices==0) {
|
||||
BlockDevice::BlockDevice(): numDevices(0), ata0(0x1F0,0), ata1(0x170,1), ata2(0x1E8,2), ata3(0x168,3) {
|
||||
if(getDriveCnt()==0) {
|
||||
err<<"Not a single device was found!\n";
|
||||
}
|
||||
for(int i=0;i<8;i++) {
|
||||
if(!(existent&(1<<i)))
|
||||
continue;
|
||||
outb(commports[i>>1],0x40);
|
||||
inb(ataports[i>>1]+CMD);
|
||||
inb(ataports[i>>1]+CMD);
|
||||
inb(ataports[i>>1]+CMD);
|
||||
inb(ataports[i>>1]+CMD);
|
||||
outb(commports[i>>1],0x00);
|
||||
}
|
||||
}
|
||||
auto BlockDevice::getDriveCnt() -> uint8_t {return numDevices;}
|
||||
auto BlockDevice::getDriveNumByName(const char * name) -> uint8_t {
|
||||
if(strlen(name)!=5)
|
||||
return -1; //Format is ATA[0-3][sm] (regex)
|
||||
if((name[0]!=name[2])||(name[2]!='A'))
|
||||
return -1;
|
||||
if(name[1]!='T')
|
||||
return -1;
|
||||
uint8_t drivenum=name[3]-0x30;
|
||||
if(drivenum>3)
|
||||
return -1;
|
||||
if((name[4]!='s')&&(name[4]!='m'))
|
||||
return -1;
|
||||
drivenum<<=1;
|
||||
drivenum+=(name[4]=='s')?1:0;
|
||||
if(!(existent&(1<<drivenum)))
|
||||
return -1;
|
||||
return drivenum;
|
||||
auto BlockDevice::getDriveCnt() -> int32_t {return ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt()+ata3.getDriveCnt();}
|
||||
auto BlockDevice::getDriveNumByName(const char * name) -> int32_t {
|
||||
int32_t tmp;
|
||||
if((tmp=ata0.getDriveNumByName(name))!=-1)
|
||||
return tmp;
|
||||
else if((tmp=ata1.getDriveNumByName(name))!=-1)
|
||||
return tmp+ata0.getDriveCnt();
|
||||
else if((tmp=ata2.getDriveNumByName(name))!=-1)
|
||||
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt();
|
||||
else if((tmp=ata3.getDriveNumByName(name))!=-1)
|
||||
return tmp+ata0.getDriveCnt()+ata1.getDriveCnt()+ata2.getDriveCnt();
|
||||
else return -1;
|
||||
}
|
||||
BlockDevice::~BlockDevice() {};
|
||||
auto BlockDevice::readSector(uint8_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
if(!(existent&(1<<drv)))
|
||||
return;
|
||||
outb(ataports[drv>>1]+DRV, 0x40 | (drv&1)<<4);
|
||||
outb(ataports[drv>>1]+SECTOR_CNT, 0);
|
||||
outb(ataports[drv>>1]+LBAlo, (uint8_t)(sectorNum>>24));
|
||||
outb(ataports[drv>>1]+LBAmid, (uint8_t)(sectorNum>>32));
|
||||
outb(ataports[drv>>1]+LBAhi, (uint8_t)(sectorNum>>40));
|
||||
outb(ataports[drv>>1]+SECTOR_CNT, 1);
|
||||
outb(ataports[drv>>1]+LBAlo, (uint8_t)(sectorNum));
|
||||
outb(ataports[drv>>1]+LBAmid, (uint8_t)(sectorNum>>8));
|
||||
outb(ataports[drv>>1]+LBAhi, (uint8_t)(sectorNum>>16));
|
||||
outb(ataports[drv>>1]+CMD, 0x24);
|
||||
inb(ataports[drv>>1]+CMD);
|
||||
inb(ataports[drv>>1]+CMD);
|
||||
inb(ataports[drv>>1]+CMD);
|
||||
while(inb(ataports[drv>>1]+CMD)&0x80);
|
||||
uint16_t *bufw=(uint16_t *)buf;
|
||||
for(int i=0;i<256;i++)
|
||||
bufw[i]=inb(ataports[drv>>1]);
|
||||
auto BlockDevice::readSector(int32_t drv, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
ata0.readSector(drv, sectorNum, buf);
|
||||
ata1.readSector(drv, sectorNum, buf);
|
||||
ata2.readSector(drv, sectorNum, buf);
|
||||
ata3.readSector(drv, sectorNum, buf);
|
||||
}
|
||||
}
|
||||
|
|
88
kernel/hal/x86/blk/ide.cpp
Normal file
88
kernel/hal/x86/blk/ide.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include <base.hpp>
|
||||
#include <blockdev.hpp>
|
||||
#include <io.h>
|
||||
#include <textDISP.hpp>
|
||||
#include <string.h>
|
||||
#define ATAPIO_ERR 0x01
|
||||
#define ATAPIO_DRQ 0x08
|
||||
#define ATAPIO_SRV 0x10
|
||||
#define ATAPIO_DF 0x20
|
||||
#define ATAPIO_RDY 0x40
|
||||
#define ATAPIO_BSY 0x80
|
||||
#define DATA 0
|
||||
#define ATAPI_RESV 1
|
||||
#define SECTOR_CNT 2
|
||||
#define LBAlo 3
|
||||
#define LBAmid 4
|
||||
#define LBAhi 5
|
||||
#define DRV 6
|
||||
#define CMD 7
|
||||
#define ALTCMD 0x206
|
||||
namespace MTGosHAL {
|
||||
IDE::IDE(uint16_t baseport, uint8_t num): baseport(baseport), num(num), existent(0), numDevices(0) {
|
||||
if(inb(baseport+CMD)!=0xFF) { //Does the ATA controller return floating bus?
|
||||
// Checking existence of the master
|
||||
outb(baseport+DRV, 0xE0);
|
||||
outb(baseport+LBAlo,0x55);
|
||||
if(inb(baseport+LBAlo)==0x55) {
|
||||
existent|=1;
|
||||
numDevices++;
|
||||
}
|
||||
// Checking existence of the slave
|
||||
outb(baseport+DRV, 0xF0);
|
||||
outb(baseport+LBAlo,0x55);
|
||||
if(inb(baseport+LBAlo)==0x55) {
|
||||
existent|=2;
|
||||
numDevices++;
|
||||
}
|
||||
} else {
|
||||
err << "ATA device could not be found!\n";
|
||||
}
|
||||
outb(baseport+ALTCMD,0x40);
|
||||
inb(baseport+CMD);
|
||||
inb(baseport+CMD);
|
||||
inb(baseport+CMD);
|
||||
outb(baseport+ALTCMD,0x00);
|
||||
}
|
||||
auto IDE::getDriveCnt() -> int32_t {return numDevices;}
|
||||
auto IDE::getDriveNumByName(const char* name) -> int32_t {
|
||||
if(strlen(name)!=5)
|
||||
return -1; //Format is ATA[0-3][sm] (regex)
|
||||
if((name[0]!=name[2])||(name[2]!='A'))
|
||||
return -1;
|
||||
if(name[1]!='T')
|
||||
return -1;
|
||||
int32_t drivenum=name[3]-0x30;
|
||||
if(drivenum!=num)
|
||||
return -1;
|
||||
if((name[4]!='s')&&(name[4]!='m'))
|
||||
return -1;
|
||||
drivenum<<=1;
|
||||
drivenum+=(name[4]=='s')?1:0;
|
||||
if(!(existent&(1<<drivenum)))
|
||||
return -1;
|
||||
return drivenum;
|
||||
}
|
||||
auto IDE::readSector(int32_t drive, uint64_t sectorNum, uint8_t *buf) -> void {
|
||||
if(drive<(num*2)||drive>(num*2+1))
|
||||
return;
|
||||
if(!(existent&(1<<(drive-num*2))))
|
||||
return;
|
||||
outb(baseport+DRV, 0x40 | (drive&1)<<4);
|
||||
outb(baseport+SECTOR_CNT, 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, 1);
|
||||
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));
|
||||
}
|
||||
}
|
|
@ -2,17 +2,34 @@
|
|||
#define __HAL_BLOCKDEV_HPP
|
||||
#include <stdint.h>
|
||||
namespace MTGosHAL {
|
||||
class IDE {
|
||||
private:
|
||||
uint8_t existent; //Bitmap showing which of the up to 2 drives are actually existent.
|
||||
uint8_t num;
|
||||
int32_t numDevices;
|
||||
uint16_t baseport;
|
||||
IDE() {}
|
||||
public:
|
||||
IDE(uint16_t baseport, uint8_t num);
|
||||
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!
|
||||
};
|
||||
class BlockDevice {
|
||||
private:
|
||||
uint8_t numDevices;
|
||||
uint8_t existent; //Bitmap showing which of the up to 8 drives are actually existent.
|
||||
IDE ata0;
|
||||
IDE ata1;
|
||||
IDE ata2;
|
||||
IDE ata3;
|
||||
public:
|
||||
BlockDevice();
|
||||
~BlockDevice();
|
||||
auto getDriveCnt() -> uint8_t;
|
||||
auto getDriveNumByName(const char *) -> uint8_t; //Returns -1 if device is not existent
|
||||
auto readSector(uint8_t drv, uint64_t sectorNum, uint8_t *buf) -> void; //Has to be at least 512 bytes big!
|
||||
auto readSectors(uint8_t drv, uint64_t sectorNum, uint32_t num, uint8_t *buf) -> void; //Has to be at least num*512 bytes big!
|
||||
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!
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace MTGosHAL {
|
|||
uint16_t* vmem=(uint16_t*)0xB8000;
|
||||
auto putChar(char c) -> void;
|
||||
public:
|
||||
Screen() {
|
||||
Screen(): fg(FG_color::WHITE), bg(BG_color::BLACK) {
|
||||
clrscr();
|
||||
}
|
||||
template <typename T>
|
||||
|
|
|
@ -40,11 +40,7 @@ namespace MTGosHAL {
|
|||
idt.setEntry(48, (void *)((uint32_t)&intr_stub_0+768), SEG_KERNEL, IDT_TRAP_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
idt.setEntry(8, (void *)((uint32_t)&intr_stub_0+128), SEG_DBL_FAULT, IDT_TASK_GATE | IDT_SEG_32_BIT | IDT_RING_0 | IDT_USED);
|
||||
idt.apply();
|
||||
char sec[513];
|
||||
sec[512]='\0';
|
||||
disk.readSector(disk.getDriveNumByName("ATA0m"),1,(uint8_t *)sec);
|
||||
out << sec;
|
||||
//sti();
|
||||
sti();
|
||||
::main();
|
||||
for(;;);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue