IDE IDENTIFY
This commit is contained in:
parent
c880843b6c
commit
9c1f32a49c
|
|
@ -100,9 +100,9 @@ uint32_t module_api(uint32_t func, ...){
|
|||
return_value = pm_alloc_64kaligned();
|
||||
break;
|
||||
case MODULE_API_KMALLOC_PADDR:
|
||||
paddr = va_arg(vars, uint32_t);
|
||||
paddr = (void *)va_arg(vars, uint32_t);
|
||||
uint32_t size = va_arg(vars, uint32_t);
|
||||
return_value = kmalloc_page_paddr((uint32_t)paddr, size);
|
||||
return_value = (uint32_t)kmalloc_page_paddr((uint32_t)paddr, size);
|
||||
break;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,8 @@ make fini function to destroy global object, and free any remaining resources.
|
|||
#define ATA_TK0NF(a) a & 0x2
|
||||
//data address mark not found
|
||||
#define ATA_AMNF(a) a & 0x1;
|
||||
|
||||
#define ATA_MASTER 0xa0
|
||||
#define ATA_SLAVE 0xb0
|
||||
//commands
|
||||
#define ATA_CMD_READ_PIO 0x20
|
||||
#define ATA_CMD_READ_PIO_EXT 0x24
|
||||
|
|
@ -102,13 +103,14 @@ make fini function to destroy global object, and free any remaining resources.
|
|||
#define PCI_IDE_SUPPORT_DMA(a) (a & 0x80)
|
||||
#define PCI_CLASS_IS_IDE(a) a == 0x0101;
|
||||
|
||||
|
||||
typedef struct PRD{
|
||||
uint32_t address;
|
||||
uint16_t byte_count;
|
||||
uint16_t reserved;//set msb when last;
|
||||
}__attribute__((packed)) PRD_T;
|
||||
|
||||
|
||||
uint8_t native_ide_present = 0;
|
||||
|
||||
void fini();
|
||||
|
||||
|
|
@ -143,15 +145,25 @@ uint16_t get_bus_from_drive(uint32_t drive){
|
|||
|
||||
//return 1 if ready, 0 if not
|
||||
int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){
|
||||
if(drive){
|
||||
outb(BAR ATA_DRIVE_HEAD, drive ? 0xB0 : 0xA0);
|
||||
static uint16_t last_disk = 0;
|
||||
static uint16_t last_bar = 0;
|
||||
if(last_disk != drive && last_bar != BAR){
|
||||
last_disk = drive;
|
||||
last_bar == BAR;
|
||||
outb(BAR ATA_DRIVE_HEAD, drive);
|
||||
}
|
||||
for(uint32_t i = 0; i < 15; i++){
|
||||
uint8_t _ = inb(BAR2 ATA_ALT_STATUS);
|
||||
uint8_t _ = inb(BAR2 ATA_STATUS);
|
||||
}
|
||||
uint8_t status = inb(BAR2 ATA_ALT_STATUS);
|
||||
if(!ATA_BSY(status) || ATA_DRQ(status)) return 1;
|
||||
return 0;
|
||||
return ~(status >> 7);
|
||||
}
|
||||
void ata_reset(uint16_t bar1){
|
||||
outw(bar1 ATA_DEVICE_CONTROL, 0x4);
|
||||
for(uint32_t i = 0; i < 4096; i++){
|
||||
asm volatile("" ::: "memory");
|
||||
}
|
||||
outw(bar1 ATA_DEVICE_CONTROL, 0x0);
|
||||
}
|
||||
//return index of first free drive descriptor
|
||||
uint32_t find_free_drive(){
|
||||
|
|
@ -162,15 +174,96 @@ uint32_t find_free_drive(){
|
|||
}
|
||||
}
|
||||
|
||||
void ide_init(uint32_t BARS[5]){
|
||||
uint32_t index = find_free_drive();
|
||||
drives[index].type = TYPE_IDE;
|
||||
for(int i = 0; i < 5; i++){
|
||||
drives[index].BARs[i] = BARS[i];
|
||||
//return 255 if err/ does not exist
|
||||
//return 0 if is ATA drive
|
||||
//return 1 if is ATAPI
|
||||
//return 2 if is SATA
|
||||
//return 3 if is SATAPI
|
||||
uint8_t ata_identify(uint32_t index, uint16_t disk){
|
||||
uint16_t bar0 = drives[index].BARs[0] >> 2;
|
||||
uint16_t bar1 = drives[index].BARs[1] >> 2;
|
||||
while(!ata_ready(bar0, bar1, disk)){
|
||||
asm volatile ("" ::: "memory");
|
||||
}
|
||||
outb(bar0 ATA_DRIVE_HEAD, disk);
|
||||
outw(bar0 ATA_SECTOR_COUNT, 0);
|
||||
outw(bar0 ATA_LBA_HIH, 0);
|
||||
outw(bar0 ATA_LBA_MID, 0);
|
||||
outw(bar0 ATA_LBA_LOW, 0);
|
||||
outw(bar0 ATA_COMMAND, ATA_CMD_IDENTIFY);
|
||||
|
||||
uint16_t identify[256] = {0};
|
||||
uint8_t status = inb(bar0 ATA_STATUS);
|
||||
if(!status){
|
||||
return -1;
|
||||
}
|
||||
while(ATA_BSY(status)){
|
||||
asm volatile ("":::"memory"); //prevent gcc from optimizing out this loop
|
||||
if(inw(bar0 ATA_LBA_MID)){
|
||||
return -1;//we don't support ATAPI and SATAPI yet
|
||||
}
|
||||
status = inw(bar0 ATA_STATUS);
|
||||
if(ATA_ERR(status)){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for(uint16_t i = 0; i < 256; i++){
|
||||
identify[i] = inw(bar0 ATA_DATA);
|
||||
}
|
||||
// drives[index].size_sectors
|
||||
uint32_t lba48 = (identify[83] & (1 << 10));
|
||||
drives[index].flags.huge = lba48 ? 1 : 0;
|
||||
drives[index].size_sectors = lba48 ? (identify[60] | (identify[61] << 16)) : ((uint64_t)(identify[100]) | (uint64_t)(identify[101] << 16) | ((uint64_t)identify[102] << 32));
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "Sector Count: %x\n", drives[index].size_sectors);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ide_init(uint32_t BARS[5]){
|
||||
uint32_t primary_index = find_free_drive();
|
||||
drives[primary_index].type = TYPE_IDE;
|
||||
uint32_t secondary_index = find_free_drive();
|
||||
drives[secondary_index].type = TYPE_IDE;
|
||||
for(int i = 0; i < 2; i++){
|
||||
drives[primary_index].BARs[i] = BARS[i];
|
||||
drives[secondary_index].BARs[i] = BARS[i+2];
|
||||
}
|
||||
drives[primary_index].BARs[4] = BARS[4];
|
||||
drives[secondary_index].BARs[4] = BARS[4];
|
||||
|
||||
uint32_t prdt_primary_paddr = api(MODULE_API_PMALLOC64K);
|
||||
uint32_t prdt_secondary_paddr = api(MODULE_API_PMALLOC64K);
|
||||
drives[primary_index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_primary_paddr, 16);
|
||||
drives[secondary_index].PRDT = (void *)api(MODULE_API_KMALLOC_PADDR, prdt_secondary_paddr, 16);
|
||||
//now call ATA IDENTIFY
|
||||
uint8_t master_status = ata_identify(primary_index, ATA_MASTER);
|
||||
drive_t master_copy = drives[primary_index];
|
||||
if(ata_identify(primary_index, ATA_SLAVE) == 0){
|
||||
if(master_status == -1){
|
||||
drives[primary_index].flags.slave = 1;
|
||||
}
|
||||
else{
|
||||
uint32_t slave_index = find_free_drive();
|
||||
drives[slave_index] = drives[primary_index];
|
||||
drives[slave_index].flags.slave = 1;
|
||||
drives[primary_index] = master_copy;
|
||||
drives[slave_index].type = TYPE_IDE;
|
||||
}
|
||||
}
|
||||
master_status = ata_identify(secondary_index, ATA_MASTER);
|
||||
master_copy = drives[secondary_index];
|
||||
if(ata_identify(secondary_index, ATA_SLAVE) == 0){
|
||||
if(master_status == -1){
|
||||
drives[secondary_index].flags.slave = 1;
|
||||
}
|
||||
else{
|
||||
uint32_t slave_index = find_free_drive();
|
||||
drives[slave_index] = drives[secondary_index];
|
||||
drives[slave_index].flags.slave = 1;
|
||||
drives[secondary_index] = master_copy;
|
||||
drives[slave_index].type = TYPE_IDE;
|
||||
}
|
||||
}
|
||||
uint32_t paddr = api(MODULE_API_PMALLOC64K);
|
||||
drives[index].PRDT = api(MODULE_API_KMALLOC_PADDR, paddr, 16);
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "Vaddr: %x, Paddr: %x", drives[index].PRDT, paddr);
|
||||
}
|
||||
|
||||
void init(KOS_MAPI_FP module_api, uint32_t api_version){
|
||||
|
|
@ -197,16 +290,17 @@ void init(KOS_MAPI_FP module_api, uint32_t api_version){
|
|||
uint32_t progif = class >> 8 & 0xff;
|
||||
class >>= 16;
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "Class: %x, %x\n", class, progif);
|
||||
if(class == 0x101 && PCI_IDE_SUPPORT_DMA(progif)){ //in this house, we only support DMA.
|
||||
if(class == 0x101 && PCI_IDE_SUPPORT_DMA(progif) && !native_ide_present){ //in this house, we only support DMA.
|
||||
uint32_t BARs[5] = {0};
|
||||
fread(api, current_file, BARs, 0x10, 5);
|
||||
if(PCI_IDE_NATIVE(progif)){
|
||||
BARs[0] = ATA_PRIMARY_BUS;
|
||||
BARs[1] = ATA_PRIMARY_BUS + 0x206;
|
||||
if(PCI_IDE_NATIVE(~progif)){
|
||||
native_ide_present = 1;
|
||||
BARs[0] = (ATA_PRIMARY_BUS) << 2 | 1;
|
||||
BARs[1] = (ATA_PRIMARY_BUS + 0x206) << 2 | 1;
|
||||
}
|
||||
if(PCI_IDE_SECONDARY_NATIVE(progif)){
|
||||
BARs[2] = ATA_SECONDARY_BUS;
|
||||
BARs[3] = ATA_SECONDARY_BUS + 0x206;
|
||||
if(PCI_IDE_SECONDARY_NATIVE(~progif)){
|
||||
BARs[2] = (ATA_SECONDARY_BUS << 2) | 1;
|
||||
BARs[3] = (ATA_SECONDARY_BUS + 0x206) << 2 | 1;
|
||||
}
|
||||
ide_init(BARs);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue