ata #2

Merged
mathieu merged 6 commits from ata into master 2021-10-06 13:50:11 +02:00
4 changed files with 145 additions and 0 deletions
Showing only changes of commit f2e32cc0fd - Show all commits

View File

@ -11,6 +11,25 @@
#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
#define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a)-1)) == 0) #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a)-1)) == 0)
#ifdef __CHECKER__
#define BUILD_BUG_ON_ZERO(e) (0)
#else /* __CHECKER__ */
/*
* Force a compilation error if condition is true, but also produce a
* result (of value 0 and type int), so the expression can be used
* e.g. in a structure initializer (or where-ever else comma expressions
* aren't permitted).
*/
#define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); })))
#endif /* __CHECKER__ */
/* Are two types/vars the same type (ignoring qualifiers)? */
#ifndef __same_type
# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
#endif
/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
/* /*

View File

@ -1,5 +1,6 @@
#include "alloc.h" #include "alloc.h"
#include "allocArea.h" #include "allocArea.h"
#include "ata.h"
#include "exception.h" #include "exception.h"
#include "gdt.h" #include "gdt.h"
#include "idt.h" #include "idt.h"
@ -152,6 +153,8 @@ void kmain(unsigned long magic, unsigned long addr)
kthreadCreate("idle ", idleThread, NULL); kthreadCreate("idle ", idleThread, NULL);
irqSetRoutine(IRQ_TIMER, pit_handler); irqSetRoutine(IRQ_TIMER, pit_handler);
ATAInit();
#ifdef RUN_TEST #ifdef RUN_TEST
run_test(); run_test();
#endif #endif

71
drivers/ata.c Normal file
View File

@ -0,0 +1,71 @@
#include "ata.h"
#include "io.h"
#include "kernel.h"
#include "klibc.h"
static struct ata_drive drives[4];
int ATADectectType(struct ata_drive *drive)
{
outb(drive->base + ATA_PIO_DRIVE, 0xA0 | drive->isSlave << 4);
outb(drive->base + ATA_PIO_SEC_COUNT, 0x0);
outb(drive->base + ATA_PIO_LBALO, 0x0);
outb(drive->base + ATA_PIO_LBAMID, 0x0);
outb(drive->base + ATA_PIO_LBAHI, 0x0);
outb(drive->base + ATA_PIO_CMD, ATA_PIO_CMD_IDENTIFY);
unsigned st = inb(drive->base + ATA_PIO_STATUS);
if(st & ATA_PIO_STATUS_DRIVE_BUSY)
goto no_disk;
inb(drive->dev_ctl); /* Drop the next 4 read to wait */
inb(drive->dev_ctl);
inb(drive->dev_ctl);
inb(drive->dev_ctl);
unsigned cl = inb(drive->base + ATA_PIO_LBAMID); /* get the "signature bytes" */
unsigned ch = inb(drive->base + ATA_PIO_LBAHI);
/* differentiate ATA, ATAPI, SATA and SATAPI */
if (cl == 0x14 && ch == 0xEB) {
drive->status = ATA_DEV_PATAPI;
return 0;
}
if (cl == 0x69 && ch == 0x96) {
drive->status = ATA_DEV_SATAPI;
return 0;
}
if (cl == 0 && ch == 0) {
drive->status = ATA_DEV_PATA;
return 0;
}
if (cl == 0x3c && ch == 0xc3) {
drive->status = ATA_DEV_SATA;
return 0;
}
no_disk:
drive->status = ATA_DEV_UNKNOWN;
return -1;
}
int ATAInit()
{
memset(drives, 0, sizeof(drives));
drives[0].base = 0x1F0;
drives[0].dev_ctl = 0x3F6;
drives[0].isSlave = 0;
drives[1].base = 0x1F0;
drives[1].dev_ctl = 0x3F6;
drives[1].isSlave = 1;
drives[1].base = 0x170;
drives[1].dev_ctl = 0x376;
drives[1].isSlave = 0;
drives[2].base = 0x170;
drives[2].dev_ctl = 0x376;
drives[2].isSlave = 1;
for(uint i = 0; i < ARRAY_SIZE(drives); i++){
if(!ATADectectType(&drives[i])){
printf("Driver %d detected %d\n", i, drives[i].status);
}
}
return 0;
}

52
drivers/ata.h Normal file
View File

@ -0,0 +1,52 @@
#pragma once
#include "stdarg.h"
#define ATA_PIO_REG_DATA 0
#define ATA_PIO_REG_ERR 1
#define ATA_PIO_REG_FEAT 1
#define ATA_PIO_SEC_COUNT 2
#define ATA_PIO_LBALO 3
#define ATA_PIO_LBAMID 4
#define ATA_PIO_CYL_LOW 4
#define ATA_PIO_LBAHI 5
#define ATA_PIO_CYL_HI 5
#define ATA_PIO_DRIVE 6
#define ATA_PIO_STATUS 7
#define ATA_PIO_CMD 7
#define ATA_PIO_CMD_IDENTIFY 0xEC
#define ATA_PIO_ERROR_ADDR_MARK_NOT_FOUND 0
#define ATA_PIO_ERROR_TRACK_ZERO_NOT_FOUND 1
#define ATA_PIO_ERROR_ABORTED 2
#define ATA_PIO_ERROR_MEDIA_CHANGE_REQUEST 3
#define ATA_PIO_ERROR_ID_NOT_FOUND 4
#define ATA_PIO_ERROR_MEDIA_CHANGED 5
#define ATA_PIO_ERROR_UNCORRECTABLE_DATA 6
#define ATA_PIO_ERROR_BAD_BLOCK 7
#define ATA_PIO_STATUS_REG_ERR (1<<0)
#define ATA_PIO_STATUS_IDX (1<<1)
#define ATA_PIO_STATUS_CORP (1<<2)
#define ATA_PIO_STATUS_DRQ (1<<3)
#define ATA_PIO_STATUS_SRV (1<<4)
#define ATA_PIO_STATUS_DRIVE_FAULT (1<<5)
#define ATA_PIO_STATUS_DRIVE_RDY (1<<6)
#define ATA_PIO_STATUS_DRIVE_BUSY (1<<7)
#define ATA_DEV_PATA 1
#define ATA_DEV_SATA 2
#define ATA_DEV_PATAPI 3
#define ATA_DEV_SATAPI 4
#define ATA_DEV_UNKNOWN 0
struct ata_drive {
int16_t base;
int16_t dev_ctl;
int status;
int isSlave;
};
int ATADectectType(struct ata_drive* drive);
int ATAInit();