Set DMA mode, tried fixing ATA_READ
This commit is contained in:
parent
c7aaedbd2a
commit
38a5997c7d
|
|
@ -148,7 +148,7 @@ uint32_t get_paddr(void *vaddr){
|
|||
return 0;
|
||||
}
|
||||
uint32_t *pt = (uint32_t *)(0xffc00000 + (pd_index * 0x1000));
|
||||
return pt[pt_index];
|
||||
return pt[pt_index] & 0xfffff000;
|
||||
}
|
||||
uint32_t get_pflags(void *vaddr){
|
||||
uint32_t pd_index = (uint32_t)vaddr >> 22;
|
||||
|
|
@ -185,7 +185,7 @@ void *kmalloc(uint32_t size_pgs){
|
|||
continue;
|
||||
}
|
||||
for(uint32_t j = 0; j < size_pgs; j++){
|
||||
uint32_t flags = PT_PRESENT | PT_SYS | (PT_LINK_L * (j != 0)) | (PT_LINK_N * (j < (size_pgs - 1)));
|
||||
uint32_t flags = PT_PRESENT | PT_SYS | (PT_LINK_L * (j != 0)) | (PT_LINK_N * (j < (size_pgs - 1)) | PT_PCD);
|
||||
uint32_t physaddr = pm_alloc();
|
||||
// if(j == 0) printf("%x", physaddr);
|
||||
// printf("Mapping %x to %x\n", (i + j) << 12, physaddr);
|
||||
|
|
@ -213,7 +213,7 @@ void *kmalloc_page_paddr(uint32_t paddr, uint32_t size_pgs){
|
|||
continue;
|
||||
}
|
||||
for(uint32_t j = 0; j < size_pgs; j++){
|
||||
uint32_t flags = PT_PRESENT | PT_SYS | (PT_LINK_L * (j != 0)) | (PT_LINK_N * (j < (size_pgs - 1)));
|
||||
uint32_t flags = PT_PRESENT | PT_SYS | (PT_LINK_L * (j != 0)) | (PT_LINK_N * (j < (size_pgs - 1)) | PT_PCD);
|
||||
uint32_t physaddr = paddr + j * 4096;
|
||||
// if(j == 0) printf("%x", physaddr);
|
||||
// printf("Mapping %x to %x\n", (i + j) << 12, physaddr);
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ void sysinit(){
|
|||
i++;
|
||||
}
|
||||
vfile_t *drive_test = fopen("/dev/disk/ide0");
|
||||
uint32_t *buffer = kmalloc(1);
|
||||
int status = fread(drive_test, buffer, 0, 512);
|
||||
printf("Done: %x, %x\n", status, buffer[0]);
|
||||
uint8_t *buffer = kmalloc(1);
|
||||
int status = fread(drive_test, buffer, 0, 4096);
|
||||
printf("Done: %x, %x\n", status, buffer[511]);
|
||||
//fopen shell file & execute it.
|
||||
for(;;);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,7 +134,12 @@ enum DRIVE_TYPE{
|
|||
TYPE_USB,
|
||||
TYPE_FLOPPY, //Here, Navya, just for you
|
||||
};
|
||||
|
||||
|
||||
uint32_t volatile transferring_disk_index = -1;
|
||||
uint32_t expected_ints = 0;
|
||||
uint32_t recieved_ints = 0;
|
||||
|
||||
typedef struct drive_desc{
|
||||
uint32_t BARs[8];
|
||||
enum DRIVE_TYPE type;
|
||||
|
|
@ -183,79 +188,79 @@ uint32_t find_free_drive(){
|
|||
}
|
||||
}
|
||||
|
||||
int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count){
|
||||
if(count == 0){
|
||||
return -1;//prevent from accidentally reading 65536 * 512 bytes
|
||||
}
|
||||
|
||||
int ata_read(vfile_t *file, uint8_t *ptr, uint32_t offset, uint32_t count) {
|
||||
if (count == 0) return -1;
|
||||
|
||||
drive_t drive = drives[file->mount_id];
|
||||
|
||||
uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3);
|
||||
|
||||
uint32_t status = inb(dmabar + 2);
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "status: %x\n", status);
|
||||
uint16_t io_base = drive.BARs[0] >> 2;
|
||||
uint16_t ctrl_base = drive.BARs[1] >> 2;
|
||||
uint16_t bm_base = drive.BARs[4] & ~3;
|
||||
|
||||
uint32_t sector_count = count >> 9;
|
||||
if (sector_count == 0) return 0;
|
||||
|
||||
PRD_T *prdt = drive.PRDT;
|
||||
if(count == 0) return 0;
|
||||
uint32_t count_pgs = ((count + 4096) / 4096);
|
||||
|
||||
for(int i = 0; i < count_pgs; i++){
|
||||
prdt[i].address = api(MODULE_API_PADDR, ptr + (i * (1 << 12)));
|
||||
prdt[i].byte_count = (i == (count_pgs - 1)) ? count % (1 << 12) : 1 << 12;
|
||||
prdt[i].reserved = (1 << 31) * (i == (count_pgs - 1));
|
||||
uint32_t pages = (count + 4095) / 4096;
|
||||
for (uint32_t i = 0; i < pages; i++) {
|
||||
prdt[i].address = api(MODULE_API_PADDR, ptr + (i << 12));
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "ADDR: %x, %x", ptr + (i << 12), api(MODULE_API_PADDR, prdt));
|
||||
prdt[i].byte_count = (i == (pages - 1)) ? (count % 4096) : 4096;
|
||||
prdt[i].reserved = (i == (pages - 1)) ? (1 << 31) : 0;
|
||||
|
||||
}
|
||||
outb(dmabar + 2, 0x6);
|
||||
outl(dmabar + 4, api(MODULE_API_PADDR, prdt));
|
||||
outb(dmabar, 0x8);
|
||||
|
||||
outb(ctrl_base, 0x00);
|
||||
outb(bm_base + 2, 0x06);
|
||||
outl(bm_base + 4, api(MODULE_API_PADDR, prdt));
|
||||
outb(bm_base, 0x08);
|
||||
|
||||
while(!ata_ready(drive.BARs[0] >> 2, drive.BARs[1] >> 2, drive.flags.slave));
|
||||
while(!ata_ready(io_base, ctrl_base, drive.flags.slave << 4));
|
||||
// uint64_t lba = offset >> 9;
|
||||
uint64_t lba = 0;
|
||||
outb(io_base + ATA_DRIVE_HEAD, 0x40 | (drive.flags.slave << 4) | ((lba >> 24) & 0x0F));
|
||||
|
||||
outb(drive.BARs[1], 0x00);
|
||||
|
||||
uint64_t lba = (offset >> 9);
|
||||
uint8_t *lba_arr = &lba;
|
||||
outb(drive.BARs[0] + ATA_DRIVE_HEAD, 0x40 | (drive.flags.slave << 4) | ((lba >> 24) * !drive.flags.huge));
|
||||
|
||||
if(count >> 9 == 0){
|
||||
return 0;
|
||||
if (drive.flags.huge) {
|
||||
// 48-bit LBA (use READ_DMA_EXT)
|
||||
outb(io_base + ATA_SECTOR_COUNT, sector_count >> 8);
|
||||
outb(io_base + ATA_LBA_LOW, (lba >> 24) & 0xFF);
|
||||
outb(io_base + ATA_LBA_MID, (lba >> 32) & 0xFF);
|
||||
outb(io_base + ATA_LBA_HIH, (lba >> 40) & 0xFF);
|
||||
outb(io_base + ATA_SECTOR_COUNT, sector_count & 0xFF);
|
||||
outb(io_base + ATA_LBA_LOW, lba & 0xFF);
|
||||
outb(io_base + ATA_LBA_MID, (lba >> 8) & 0xFF);
|
||||
outb(io_base + ATA_LBA_HIH, (lba >> 16) & 0xFF);
|
||||
outb(io_base + ATA_COMMAND, ATA_CMD_READ_DMA_EXT);
|
||||
} else {
|
||||
// 28-bit LBA (use READ_DMA)
|
||||
outb(io_base + ATA_SECTOR_COUNT, sector_count);
|
||||
outb(io_base + ATA_LBA_LOW, lba & 0xFF);
|
||||
outb(io_base + ATA_LBA_MID, (lba >> 8) & 0xFF);
|
||||
outb(io_base + ATA_LBA_HIH, (lba >> 16) & 0xFF);
|
||||
outb(io_base + ATA_COMMAND, ATA_CMD_READ_DMA);
|
||||
}
|
||||
|
||||
if(drive.flags.huge){
|
||||
outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9) >> 8);
|
||||
}else{
|
||||
outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9));
|
||||
}
|
||||
for(uint32_t i = 0; i < 3; i++){
|
||||
outb(drive.BARs[0] + ATA_LBA_LOW + i, lba_arr[i + 3 * drive.flags.huge]);
|
||||
}
|
||||
if(drive.flags.huge){
|
||||
outb(drive.BARs[0] + ATA_SECTOR_COUNT, (count >> 9) & 0xff);
|
||||
for(uint32_t i = 0; i < 3; i++){
|
||||
outb(drive.BARs[0] + ATA_LBA_LOW + i, lba_arr[i]);
|
||||
}
|
||||
puts(api, MODULE_NAME, "bleh\n");
|
||||
outb(drive.BARs[0] + ATA_COMMAND, ATA_CMD_READ_DMA_EXT);
|
||||
}else{
|
||||
outb(drive.BARs[0] + ATA_COMMAND, ATA_CMD_READ_DMA);
|
||||
}
|
||||
//issue read command to drive
|
||||
expected_ints = pages;
|
||||
recieved_ints = 0;
|
||||
|
||||
transferring_disk_index = file->mount_id;
|
||||
|
||||
outb(dmabar, 0x9);
|
||||
// while(!ata_ready(drive.BARs[0] >> 2, drive.BARs[1] >> 2, drive.flags.slave));
|
||||
while(transferring_disk_index != -1);
|
||||
// while (!(inb(dmabar + 2) & 0x01));
|
||||
outb(dmabar, 0x0);
|
||||
outb(bm_base, 0x09);
|
||||
while (transferring_disk_index != -1);
|
||||
outb(bm_base, 0x00);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpu_registers_t *int_handler(cpu_registers_t * regs){
|
||||
puts(api, MODULE_NAME, "Interrupt called");
|
||||
drive_t drive = drives[transferring_disk_index];
|
||||
uint16_t dmabar = drive.BARs[4] & (uint32_t)(~3);
|
||||
uint32_t status = inb(dmabar + 2);
|
||||
outb(dmabar + 2, 0x4);
|
||||
recieved_ints++;
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "Interrupt called, %x\n", status);
|
||||
// if(status & 1){
|
||||
// return regs;
|
||||
// }
|
||||
transferring_disk_index = -1;
|
||||
if(status & 0x4) return regs;
|
||||
return regs;
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +269,28 @@ int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
|
|||
|
||||
}
|
||||
|
||||
|
||||
//dma set 0x80 for udma
|
||||
//
|
||||
void ata_set_dma(uint32_t index, uint8_t dma_mode){
|
||||
uint16_t bar0 = drives[index].BARs[0] >> 2;
|
||||
uint16_t bar1 = drives[index].BARs[1] >> 2;
|
||||
|
||||
while(!ata_ready(bar0, bar1, drives[index].flags.slave << 4));
|
||||
|
||||
outb(bar0 + ATA_FEATURES, 0x3);
|
||||
uint8_t dma_set = ((dma_mode & 0x80) ? (1 << 6) : (1 << 5)) | dma_mode & 0x7f;
|
||||
outb(bar0 + ATA_SECTOR_COUNT, dma_set);
|
||||
outb(bar0 + ATA_LBA_LOW, 0);
|
||||
outb(bar0 + ATA_LBA_MID, 0);
|
||||
outb(bar0 + ATA_LBA_HIH, 0);
|
||||
outb(bar0 + ATA_COMMAND, 0xEF);
|
||||
|
||||
while (ATA_BSY(inb(bar0 + ATA_STATUS)));
|
||||
uint8_t status = inb(bar0 + ATA_STATUS);
|
||||
if (ATA_ERR(status)) {
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "Failed to enable DMA mode\n");
|
||||
}
|
||||
}
|
||||
|
||||
//return 255 if err/ does not exist
|
||||
//return 0 if is ATA drive
|
||||
|
|
@ -274,7 +300,7 @@ int ata_write(vfile_t *file, void *ptr, uint32_t offset, uint32_t count){
|
|||
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;
|
||||
if(!ata_ready(bar0, bar1, disk)){
|
||||
if(!ata_ready(bar0, bar1, disk & 0x10)){
|
||||
return -1;
|
||||
}
|
||||
// outb(bar0 ATA_DRIVE_HEAD, disk);
|
||||
|
|
@ -312,6 +338,20 @@ uint8_t ata_identify(uint32_t index, uint16_t disk){
|
|||
// 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);
|
||||
if (!(identify[49] & (1 << 8))) {
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "Drive does not support DMA\n");
|
||||
return -1;
|
||||
}
|
||||
uint16_t udma_mode = identify[88] & 0xff;
|
||||
uint16_t mdma_mode = identify[63] & 0xff;
|
||||
api(MODULE_API_PRINT, MODULE_NAME, "DMA Modes\nUDMA: %x\nMDMA: %x\n", udma_mode, mdma_mode);
|
||||
int highest = 0;
|
||||
uint8_t dma = udma_mode != 0 ? udma_mode : mdma_mode;
|
||||
while(dma){
|
||||
highest++;
|
||||
dma >>= 1;
|
||||
}
|
||||
ata_set_dma(index, (udma_mode ? 0x80 : 0) | highest);
|
||||
char fname[32];
|
||||
strcpy("/dev/disk/ide", fname);
|
||||
uint8_t ata_drives = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue