feat: setup structure for block devices

added ide block device
added mbr block device driver
started fat block device driver

reordered boot
start timer before pci/ide/etc.
enable interrupts earlier

fixed exception from ide controller

cleanup code
more printfs
This commit is contained in:
2021-02-09 22:47:35 +01:00
parent 9440fae968
commit 2ac0da6574
16 changed files with 467 additions and 106 deletions

View File

@@ -12,6 +12,8 @@
#include <libk.h>
#include <cpu/timer.h>
#include <libc/kprintf.h>
#include <fs/blockdev.h>
#include <mem/mem.h>
#define ATA_SR_BSY 0x80 // Busy
#define ATA_SR_DRDY 0x40 // Drive ready
@@ -128,6 +130,11 @@ struct ide_device {
unsigned char model[41]; // Model in string.
} ide_devices[4];
typedef struct {
u8 device_number: 2;
u8 print_error: 1;
} ide_block_device_info;
u8 ide_read(u8 channel, u8 reg);
void ide_write(u8 channel, u8 reg, u8 data);
@@ -256,48 +263,54 @@ unsigned char ide_print_error(unsigned int drive, unsigned char err) {
kprint("IDE:");
if (err == 1) {
kprint("- Device Fault\n ");
kprint("- Device Fault ");
err = 19;
} else if (err == 2) {
unsigned char st = ide_read(ide_devices[drive].channel, ATA_REG_ERROR);
if (st & ATA_ER_AMNF) {
kprint("- No Address Mark Found\n ");
kprint("- No Address Mark Found - ");
err = 7;
}
if (st & ATA_ER_TK0NF) {
kprint("- No Media or Media Error\n ");
kprint("- No Media or Media Error - ");
err = 3;
}
if (st & ATA_ER_ABRT) {
kprint("- Command Aborted\n ");
kprint("- Command Aborted - ");
err = 20;
}
if (st & ATA_ER_MCR) {
kprint("- No Media or Media Error\n ");
kprint("- No Media or Media Error - ");
err = 3;
}
if (st & ATA_ER_IDNF) {
kprint("- ID mark not Found\n ");
kprint("- ID mark not Found - ");
err = 21;
}
if (st & ATA_ER_MC) {
kprint("- No Media or Media Error\n ");
kprint("- No Media or Media Error - ");
err = 3;
}
if (st & ATA_ER_UNC) {
kprint("- Uncorrectable Data Error\n ");
kprint("- Uncorrectable Data Error - ");
err = 22;
}
if (st & ATA_ER_BBK) {
kprint("- Bad Sectors\n ");
kprint("- Bad Sectors - ");
err = 13;
}
} else if (err == 3) {
kprint("- Reads Nothing\n ");
kprint("- Reads Nothing - ");
err = 23;
} else if (err == 4) {
kprint("- Write Protected\n ");
kprint("- Write Protected - ");
err = 8;
} else if (err & 0xF0) {
if (err == 0xF1) {
kprint("- Unsupported operation by driver - ");
} else {
kprint(" - Unknown driver error - ");
}
}
printf(" - [%s %s] %s\n",
((const char *[]) {"Primary", "Secondary"}[ide_devices[drive].channel]),
@@ -313,7 +326,7 @@ u8 ide_pci_initialize(pci_device *device);
const pci_driver ide_pci_driver = {
.name = "pci-ide",
.description = "Default PCI IDE Driver",
.order = 0xFF, // let other drivers precede if they can
.order = 0xFF, // let other block_dev_drivers precede if they can
.pci_use_subclass = true,
.pci_class = PCI_CLASS_MASS_STORAGE,
.pci_subclass = PCI_SUB_CLASS_IDE,
@@ -381,6 +394,43 @@ bool ide_pci_init_channels(pci_device *device) {
return true;
}
u8 ide_block_dev_access(const block_device *device, u8 direction, u32 lba, u8 sectors, void *target) {
ide_block_device_info *info = device->device_info;
u8 result = ide_access(direction, info->device_number, lba, sectors, target);
if (result != 0) {
if (info->print_error) {
ide_print_error(info->device_number, result);
}
return BLOCK_DEV_ACCESS_ERR;
}
return BLOCK_DEV_ACCESS_OK;
}
void ide_register_block_devices() {
for (int i = 0; i < 3; ++i) {
if (!ide_devices[i].reserved) {
continue;
}
ide_block_device_info *info = malloc(sizeof(ide_block_device_info)); // todo free for this one
info->device_number = i;
info->print_error = 1;
block_device device = {
.flags.present = 1,
.flags.root_device = 1,
.device_info = info,
.num_lba = ide_devices[i].size,
.block_size = 0x200,
.access = ide_block_dev_access,
};
sprintf(device.identifier, "ide%d", i);
block_dev_register(&device);
break;
}
}
u8 ide_pci_initialize(pci_device *device) {
if (!ide_pci_init_channels(device)) {
@@ -393,7 +443,7 @@ u8 ide_pci_initialize(pci_device *device) {
int count = 0;
// 3- Detect ATA-ATAPI Devices:
for (int i = 0; i < 2; i++)
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
unsigned char err = 0, type = IDE_ATA, status;
@@ -467,6 +517,8 @@ u8 ide_pci_initialize(pci_device *device) {
count++;
}
}
ide_register_block_devices();
return PCI_INIT_OK;
}
@@ -543,9 +595,6 @@ u8 ide_read_ata_access(u8 direction, u8 drive, u32 lba, u8 numsects, void *targe
// wait for the drive to have time for us
while (ide_read(channel, ATA_REG_STATUS) & ATA_SR_BSY) {}
// clear error
ide_write(channel, ATA_REG_ERROR, 0);
if (lba_mode == 0) {
ide_write(channel,
ATA_REG_HDDEVSEL,
@@ -618,11 +667,11 @@ u8 ide_read_ata_access(u8 direction, u8 drive, u32 lba, u8 numsects, void *targe
return 0;
}
u8 ide_read_access(u8 direction, u8 drive, u32 lba, u8 numsects, void *target) {
u8 ide_access(u8 direction, u8 drive, u32 lba, u8 numsects, void *target) {
if (drive > 3
|| ide_devices[drive].reserved == 1
|| ide_devices[drive].reserved == 0
|| ide_devices[drive].type == IDE_ATAPI) {
k_panics("Not supported device read operation");
return 0xF1;
}
return ide_read_ata_access(direction, drive, lba, numsects, target);
}