Detecting IDE drives, allocating memory for PRDT
This commit is contained in:
parent
a5af6c51da
commit
c880843b6c
2
makefile
2
makefile
|
|
@ -47,7 +47,7 @@ kernel:
|
||||||
nasm src/kernel/arch_i386/idt.s -o bin/kernel/idt.o -felf32
|
nasm src/kernel/arch_i386/idt.s -o bin/kernel/idt.o -felf32
|
||||||
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
|
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
|
||||||
ld -T linker.ld bin/kernel/*.o -melf_i386 -o kernel.elf -static
|
ld -T linker.ld bin/kernel/*.o -melf_i386 -o kernel.elf -static
|
||||||
# ld -T linker.ld -o kernel_interface.elf -r -R kernel.elf -melf_i386
|
ld -T linker.ld -o kernel_interface.elf -r -R kernel.elf -melf_i386
|
||||||
ld -pie bin/modules/disk_driver.o -o idm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
|
ld -pie bin/modules/disk_driver.o -o idm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
|
||||||
# ld bin/modules/fs_driver.o -o ifsm.elf -melf_i386
|
# ld bin/modules/fs_driver.o -o ifsm.elf -melf_i386
|
||||||
ld -pie bin/modules/fs_driver.o -o ifsm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
|
ld -pie bin/modules/fs_driver.o -o ifsm.elf -melf_i386 -e init --no-dynamic-linker -static -nostdlib
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,34 @@ uint32_t pm_alloc(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint32_t pm_alloc_index(uint32_t index){
|
||||||
|
for(uint32_t i = index; i < 2; i++){
|
||||||
|
for(int j = 0; j < 8; j++){
|
||||||
|
// if(!(pm_map[i] & (1 << j))){
|
||||||
|
pm_map[i] |= (1 << j);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (index << 3) << 12;
|
||||||
|
}
|
||||||
|
uint32_t pm_alloc_64kaligned(){
|
||||||
|
uint32_t cont = 0;
|
||||||
|
for(uint32_t i = 0; i < mmap_count; i++){
|
||||||
|
for(int j = 0; j < 8; j++){
|
||||||
|
if(!(pm_map[i] & (1 << j))){
|
||||||
|
continue;
|
||||||
|
}else{
|
||||||
|
j++;
|
||||||
|
cont = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(cont == 1){
|
||||||
|
return pm_alloc_index(i);
|
||||||
|
}
|
||||||
|
cont++;
|
||||||
|
}
|
||||||
|
}
|
||||||
void pm_free(uint32_t address){
|
void pm_free(uint32_t address){
|
||||||
pm_map[address >> 15] &= ~(1 << ((address>>12) & 7));
|
pm_map[address >> 15] &= ~(1 << ((address>>12) & 7));
|
||||||
}
|
}
|
||||||
|
|
@ -169,6 +197,34 @@ void *kmalloc(uint32_t size_pgs){
|
||||||
return (void*)(i << 12);
|
return (void*)(i << 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void *kmalloc_page_paddr(uint32_t paddr, uint32_t size_pgs){
|
||||||
|
uint32_t i = 0xc0000000 >> 12; //4mb/4096 (start search at 1mb line)
|
||||||
|
while(i < (1 << 22)){
|
||||||
|
uint8_t found = 1;
|
||||||
|
for(uint32_t j = 0; j < size_pgs; j++){
|
||||||
|
// printf("found at %x, %x\n", (i + j) << 12, get_paddr((void*)((i + j) << 12)));
|
||||||
|
if(get_pflags((void *)((i + j) << 12))){
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!found){
|
||||||
|
i++;
|
||||||
|
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 physaddr = paddr + j * 4096;
|
||||||
|
// if(j == 0) printf("%x", physaddr);
|
||||||
|
// printf("Mapping %x to %x\n", (i + j) << 12, physaddr);
|
||||||
|
// if(fake) return 0;
|
||||||
|
map((void *)((i + j) << 12), (void*)physaddr, flags);
|
||||||
|
}
|
||||||
|
// fake = !fake;
|
||||||
|
// for(;;);
|
||||||
|
return (void*)(i << 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
void *kfree(void *vaddr){
|
void *kfree(void *vaddr){
|
||||||
uint32_t addr = (uint32_t)vaddr;
|
uint32_t addr = (uint32_t)vaddr;
|
||||||
addr &= ~0xfff;
|
addr &= ~0xfff;
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,20 @@ uint16_t pci_read_config(uint32_t bus, uint32_t slot, uint32_t func, uint8_t off
|
||||||
uint16_t tmp = (uint16_t)((inl(0xcfc) >> ((offset & 2) * 8)) & 0xffff);
|
uint16_t tmp = (uint16_t)((inl(0xcfc) >> ((offset & 2) * 8)) & 0xffff);
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
uint16_t pci_write_config(uint32_t bus, uint32_t slot, uint32_t func, uint8_t offset, uint16_t word){
|
||||||
|
uint32_t address = (uint32_t)((bus << 16) | (slot << 11) | (func << 8) | (offset & 0xfc) | ((uint32_t)0x80000000));
|
||||||
|
outl(0xcf8, address);
|
||||||
|
outl(0xcfc, word);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void pci_read_file(vfile_t *file, uint32_t *buffer, uint32_t offset, uint32_t count){
|
void pci_read_file(vfile_t *file, uint32_t *buffer, uint32_t offset, uint32_t count){
|
||||||
uint8_t bus = file->id >> 16;
|
uint8_t bus = file->id >> 16;
|
||||||
uint8_t func = file->id>> 8 & 0xff;
|
uint8_t func = file->id>> 8 & 0xff;
|
||||||
uint8_t slot = file->id & 0xff;
|
uint8_t slot = file->id & 0xff;
|
||||||
for(uint32_t i = 0; i < count/2; i++){
|
for(uint32_t i = 0; i < (count); i++){
|
||||||
buffer[i] = pci_read_config(bus, slot, func, offset + i*2) | (pci_read_config(bus, slot, func, offset + i * 2 + 2) << 16);
|
buffer[i] = pci_read_config(bus, slot, func, offset + i*4) | (pci_read_config(bus, slot, func, offset + i*4 + 2) << 16);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -45,6 +52,9 @@ void pci_make_file(uint32_t class, uint8_t bus, uint8_t slot, uint8_t func){
|
||||||
switch(class >> 8){
|
switch(class >> 8){
|
||||||
case 0x1://PCI class 0x1 is disks
|
case 0x1://PCI class 0x1 is disks
|
||||||
strcpy("disk/", str + strlen(str));
|
strcpy("disk/", str + strlen(str));
|
||||||
|
uint32_t l = (uint32_t)pci_read_config(bus, slot, func, 0x4) | (uint32_t)pci_read_config(bus, slot, func, 0x6) << 16;
|
||||||
|
pci_write_config(bus, slot, func, 0x4, l | 2);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x2://PCI class 0x2 is network controllers
|
case 0x2://PCI class 0x2 is network controllers
|
||||||
strcpy("net/", str + strlen(str));
|
strcpy("net/", str + strlen(str));
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,9 @@ extern void kmain(kernel_info_t *kernel_info){
|
||||||
vfs_init();
|
vfs_init();
|
||||||
|
|
||||||
fcreate("/dev", VFILE_DIRECTORY, kmalloc(1), 1);
|
fcreate("/dev", VFILE_DIRECTORY, kmalloc(1), 1);
|
||||||
fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1);
|
fcreate("/tmp", VFILE_DIRECTORY, kmalloc(1), 1);
|
||||||
|
vfile_t *file = fopen("/dev");
|
||||||
|
printf("%x", file);
|
||||||
mlog("KERNEL", "Initializing Scheduler & starting PID 1\n", MLOG_PRINT);
|
mlog("KERNEL", "Initializing Scheduler & starting PID 1\n", MLOG_PRINT);
|
||||||
boot_info = kernel_info;
|
boot_info = kernel_info;
|
||||||
scheduler_init();
|
scheduler_init();
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,8 @@ uint32_t get_paddr(void *addr);
|
||||||
uint32_t pm_alloc();
|
uint32_t pm_alloc();
|
||||||
void pm_reserve(uint32_t addr);
|
void pm_reserve(uint32_t addr);
|
||||||
void pm_free(uint32_t addr);
|
void pm_free(uint32_t addr);
|
||||||
|
uint32_t pm_alloc_64kaligned();
|
||||||
|
void *kmalloc_page_paddr(uint32_t paddr, uint32_t size);
|
||||||
|
|
||||||
inline void set_cr3(void *cr3){
|
inline void set_cr3(void *cr3){
|
||||||
asm volatile("mov %0, %%eax; mov %%eax, %%cr3":: "r"(cr3));
|
asm volatile("mov %0, %%eax; mov %%eax, %%cr3":: "r"(cr3));
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,14 @@ uint32_t module_api(uint32_t func, ...){
|
||||||
break;
|
break;
|
||||||
case MODULE_API_OPEN:
|
case MODULE_API_OPEN:
|
||||||
name = va_arg(vars, char *);
|
name = va_arg(vars, char *);
|
||||||
file = va_arg(vars, vfile_t *);
|
return_value = (uint32_t)fopen(name);
|
||||||
return_value = fopen(name, file);
|
|
||||||
break;
|
break;
|
||||||
case MODULE_API_MAP:
|
case MODULE_API_MAP:
|
||||||
return_value = -1;
|
return_value = 0;
|
||||||
|
void *vaddr = va_arg(vars, void *);
|
||||||
|
void *paddr = va_arg(vars, void *);
|
||||||
|
uint32_t flags = va_arg(vars, uint32_t);
|
||||||
|
map(vaddr, paddr, flags);
|
||||||
break;
|
break;
|
||||||
case MODULE_API_UNMAP:
|
case MODULE_API_UNMAP:
|
||||||
return_value = -1;
|
return_value = -1;
|
||||||
|
|
@ -93,6 +96,14 @@ uint32_t module_api(uint32_t func, ...){
|
||||||
kfree(ptr);
|
kfree(ptr);
|
||||||
return_value = 0;
|
return_value = 0;
|
||||||
break;
|
break;
|
||||||
|
case MODULE_API_PMALLOC64K:
|
||||||
|
return_value = pm_alloc_64kaligned();
|
||||||
|
break;
|
||||||
|
case MODULE_API_KMALLOC_PADDR:
|
||||||
|
paddr = va_arg(vars, uint32_t);
|
||||||
|
uint32_t size = va_arg(vars, uint32_t);
|
||||||
|
return_value = kmalloc_page_paddr((uint32_t)paddr, size);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
va_end(vars);
|
va_end(vars);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
#define MODULE_API_PADDR 13 //get physical address of memory
|
#define MODULE_API_PADDR 13 //get physical address of memory
|
||||||
#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks
|
#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks
|
||||||
#define MODULE_API_FREE 15 //free memory allocated by malloc
|
#define MODULE_API_FREE 15 //free memory allocated by malloc
|
||||||
|
#define MODULE_API_PMALLOC64K 16
|
||||||
|
#define MODULE_API_KMALLOC_PADDR 17
|
||||||
|
|
||||||
typedef struct module{
|
typedef struct module{
|
||||||
void *init_entry;
|
void *init_entry;
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ void add_file(vfile_t *vfile, vfile_t *current_dir){
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
dir_data[i] = vfile;
|
dir_data[i] = vfile;
|
||||||
|
dir_data[i + 1] = 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Long comment cause this one's a complicated one.
|
Long comment cause this one's a complicated one.
|
||||||
|
|
@ -77,8 +78,8 @@ vfile_t *fcreate(char *name, VFILE_TYPE type, ...){
|
||||||
void *ptr = va_arg(args, void*);
|
void *ptr = va_arg(args, void*);
|
||||||
vfile->access.data.ptr = ptr;
|
vfile->access.data.ptr = ptr;
|
||||||
vfile->access.data.size_pgs = va_arg(args, uint32_t);
|
vfile->access.data.size_pgs = va_arg(args, uint32_t);
|
||||||
|
*(uint32_t *)ptr = 0;
|
||||||
add_file(vfile, current_dir);
|
add_file(vfile, current_dir);
|
||||||
// printf("Created File: %s\n", vfile->name);
|
|
||||||
break;
|
break;
|
||||||
case VFILE_FILE:
|
case VFILE_FILE:
|
||||||
case VFILE_DEVICE:
|
case VFILE_DEVICE:
|
||||||
|
|
@ -166,8 +167,16 @@ vfile_t *search_dir(char *name, vfile_t dir){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fopen(char *name, vfile_t **file){
|
vfile_t *fopen(char *name){
|
||||||
|
if(name[0] == '/'){
|
||||||
|
name++;
|
||||||
|
}
|
||||||
|
if(name[strlen(name) - 1] == '/'){
|
||||||
|
name[strlen(name) - 1] = 0;
|
||||||
|
}
|
||||||
|
printf("%s\n", name);
|
||||||
char *dir = strtok(name, '/');
|
char *dir = strtok(name, '/');
|
||||||
|
printf("%s", name);
|
||||||
char *tmp = dir;
|
char *tmp = dir;
|
||||||
uint32_t filename_offset = 0;
|
uint32_t filename_offset = 0;
|
||||||
vfile_t *current_dir = &root_dir;
|
vfile_t *current_dir = &root_dir;
|
||||||
|
|
@ -176,21 +185,23 @@ int fopen(char *name, vfile_t **file){
|
||||||
dir = tmp;
|
dir = tmp;
|
||||||
tmpfile = search_dir(tmp, *current_dir);
|
tmpfile = search_dir(tmp, *current_dir);
|
||||||
if(!tmpfile){
|
if(!tmpfile){
|
||||||
return -1;
|
printf("not found\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
switch(tmpfile->type){
|
switch(tmpfile->type){
|
||||||
case VFILE_DIRECTORY:
|
case VFILE_DIRECTORY:
|
||||||
|
printf("found directory in %s: %s\n", current_dir->name, tmpfile->name);
|
||||||
current_dir = tmpfile;
|
current_dir = tmpfile;
|
||||||
break;
|
break;
|
||||||
case VFILE_MOUNT:
|
case VFILE_MOUNT:
|
||||||
return ((mount_t*)(tmpfile->access.data.ptr))->open(name + filename_offset, file);
|
vfile_t *file = kmalloc(1);
|
||||||
|
((mount_t*)(tmpfile->access.data.ptr))->open(name + filename_offset, file);
|
||||||
|
return file;
|
||||||
default:
|
default:
|
||||||
*file = tmpfile;
|
return tmpfile;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
filename_offset += strlen(tmp) + 1;
|
filename_offset += strlen(tmp) + 1;
|
||||||
tmp = strtok(0, '/');
|
tmp = strtok(0, '/');
|
||||||
}
|
}
|
||||||
*file = tmpfile;
|
return tmpfile;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +43,7 @@ typedef enum fs_flags{
|
||||||
typedef struct mount_funcs{
|
typedef struct mount_funcs{
|
||||||
int (*write)(vfile_t *file, void *data, uint32_t offset, uint32_t count);
|
int (*write)(vfile_t *file, void *data, uint32_t offset, uint32_t count);
|
||||||
int (*read)(vfile_t *file, void *data, uint32_t offset, uint32_t count);
|
int (*read)(vfile_t *file, void *data, uint32_t offset, uint32_t count);
|
||||||
int (*open)(char *filename, vfile_t **file);
|
int (*open)(char *filename, vfile_t *file);
|
||||||
void (*delete)(vfile_t *file);
|
void (*delete)(vfile_t *file);
|
||||||
void (*create)(char *filename, FS_FILE_FLAGS flags);
|
void (*create)(char *filename, FS_FILE_FLAGS flags);
|
||||||
}mount_t;
|
}mount_t;
|
||||||
|
|
@ -54,4 +54,4 @@ void fdelete();
|
||||||
int fwrite(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count);
|
int fwrite(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count);
|
||||||
int fread(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count);
|
int fread(vfile_t *file_entry, void *byte_array, uint32_t offset, uint32_t count);
|
||||||
vfile_t *search_dir(char *name, vfile_t dir);
|
vfile_t *search_dir(char *name, vfile_t dir);
|
||||||
int fopen(char *name, vfile_t **file);
|
vfile_t *fopen(char *name);
|
||||||
|
|
@ -1,30 +1,12 @@
|
||||||
#include<stdint.h>
|
#include<stdint.h>
|
||||||
#include "modlib.h"
|
#include "modlib.h"
|
||||||
#include "../kernel/drivers/cpuio.h"
|
#include "../kernel/drivers/cpuio.h"
|
||||||
|
#include "../kernel/shared/string.h"
|
||||||
|
|
||||||
#define MODULE_NAME "KIDM"
|
#define MODULE_NAME "KIDM"
|
||||||
|
|
||||||
KOS_MAPI_FP api;
|
KOS_MAPI_FP api;
|
||||||
|
|
||||||
// inline void outb(uint16_t port, uint8_t data){
|
|
||||||
// asm volatile ("outb %0, %1" :: "a"(data), "Nd"(port));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inline void outw(uint16_t port, uint16_t data){
|
|
||||||
// asm volatile ("outw %0, %1" :: "a"(data), "Nd"(port));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inline uint8_t inb(uint16_t port){
|
|
||||||
// uint8_t byte = 0;
|
|
||||||
// asm volatile ("inb %1, %0" : "=a"(byte) : "Nd"(port));
|
|
||||||
// return byte;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inline uint16_t inw(uint16_t port){
|
|
||||||
// uint16_t word = 0;
|
|
||||||
// asm volatile ("inw %1, %0" : "=a"(word) : "Nd"(port));
|
|
||||||
// return word;
|
|
||||||
// }
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
Register module
|
Register module
|
||||||
|
|
@ -49,11 +31,9 @@ make fini function to destroy global object, and free any remaining resources.
|
||||||
#define ATA_LBA_MID ATA_CYLINDER_LOW
|
#define ATA_LBA_MID ATA_CYLINDER_LOW
|
||||||
#define ATA_LBA_HIH ATA_CYLINDER_HIGH
|
#define ATA_LBA_HIH ATA_CYLINDER_HIGH
|
||||||
|
|
||||||
#define ATA_ALT_STATUS + 0x206
|
#define ATA_ALT_STATUS + 0
|
||||||
#define ATA_DEVICE_CONTROL + 0x206
|
#define ATA_DEVICE_CONTROL + 0
|
||||||
#define ATA_DRIVE_ADDRESS + 0x207
|
#define ATA_DRIVE_ADDRESS + 1
|
||||||
|
|
||||||
#define ATA_IDENTIFY 0xEC
|
|
||||||
|
|
||||||
#define ATA_PRIMARY_BUS 0x1F0
|
#define ATA_PRIMARY_BUS 0x1F0
|
||||||
#define ATA_SECONDARY_BUS 0x170
|
#define ATA_SECONDARY_BUS 0x170
|
||||||
|
|
@ -95,36 +75,103 @@ make fini function to destroy global object, and free any remaining resources.
|
||||||
//data address mark not found
|
//data address mark not found
|
||||||
#define ATA_AMNF(a) a & 0x1;
|
#define ATA_AMNF(a) a & 0x1;
|
||||||
|
|
||||||
struct {
|
//commands
|
||||||
uint8_t pio_mode:1;
|
#define ATA_CMD_READ_PIO 0x20
|
||||||
uint8_t lba48:1;
|
#define ATA_CMD_READ_PIO_EXT 0x24
|
||||||
uint8_t drive:2;
|
#define ATA_CMD_READ_DMA 0xC8
|
||||||
}settings = {1, 0, 0};
|
#define ATA_CMD_READ_DMA_EXT 0x25
|
||||||
|
#define ATA_CMD_WRITE_PIO 0x30
|
||||||
|
#define ATA_CMD_WRITE_PIO_EXT 0x34
|
||||||
|
#define ATA_CMD_WRITE_DMA 0xCA
|
||||||
|
#define ATA_CMD_WRITE_DMA_EXT 0x35
|
||||||
|
#define ATA_CMD_CACHE_FLUSH 0xE7
|
||||||
|
#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
|
||||||
|
#define ATA_CMD_PACKET 0xA0
|
||||||
|
#define ATA_CMD_IDENTIFY_PACKET 0xA1
|
||||||
|
#define ATA_CMD_IDENTIFY 0xEC
|
||||||
|
#define ATAPI_CMD_READ 0xA8
|
||||||
|
#define ATAPI_CMD_EJECT 0x1B
|
||||||
|
|
||||||
|
#define IDE_ATA 0x00
|
||||||
|
#define IDE_ATAPI 0x01
|
||||||
|
|
||||||
|
#define PCI_IDE_NATIVE(a) a & 1
|
||||||
|
#define PCI_IDE_CAN_SET_NATIVE(a) a & 2
|
||||||
|
#define PCI_IDE_SECONDARY_NATIVE(a) a & 4
|
||||||
|
#define PCI_IDE_SECONDARY_CAN_SET_NATIVE(a) a & 8
|
||||||
|
#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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void fini();
|
void fini();
|
||||||
void ata_identify();
|
|
||||||
//return 1 if ready, 0 if not
|
enum DRIVE_TYPE{
|
||||||
|
TYPE_NULL,
|
||||||
|
TYPE_IDE,
|
||||||
|
TYPE_AHCI,
|
||||||
|
TYPE_NVME,
|
||||||
|
TYPE_USB,
|
||||||
|
TYPE_FLOPPY, //Here, Navya, just for you
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct drive_desc{
|
||||||
|
uint32_t BARs[8];
|
||||||
|
enum DRIVE_TYPE type;
|
||||||
|
uint64_t size_sectors;
|
||||||
|
uint32_t sector_size_bytes;
|
||||||
|
struct{
|
||||||
|
uint8_t irq_dispatched:1;
|
||||||
|
uint8_t huge:1;//more than 2^28 sectors
|
||||||
|
uint8_t locked:1;//semaphores!!!!!
|
||||||
|
uint8_t slave:1;//is this drive a slave drive to another drive?
|
||||||
|
}__attribute__((packed))flags;
|
||||||
|
PRD_T *PRDT;
|
||||||
|
}drive_t;
|
||||||
|
|
||||||
|
drive_t drives[32] = {0};
|
||||||
|
|
||||||
uint16_t get_bus_from_drive(uint32_t drive){
|
uint16_t get_bus_from_drive(uint32_t drive){
|
||||||
return drive & 2 ? ATA_SECONDARY_BUS : ATA_PRIMARY_BUS;
|
return drive & 2 ? ATA_SECONDARY_BUS : ATA_PRIMARY_BUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ata_ready(uint32_t drive){
|
//return 1 if ready, 0 if not
|
||||||
uint16_t bus = get_bus_from_drive(drive);
|
int ata_ready(uint32_t BAR, uint32_t BAR2, uint8_t drive){
|
||||||
if(settings.drive != drive){
|
if(drive){
|
||||||
if(drive & 1){
|
outb(BAR ATA_DRIVE_HEAD, drive ? 0xB0 : 0xA0);
|
||||||
outb(bus ATA_DRIVE_HEAD, drive & 1 ? 0xB0 : 0xA0);
|
|
||||||
}
|
|
||||||
for(uint32_t i = 0; i < 15; i++){
|
|
||||||
uint8_t _ = inb(bus ATA_ALT_STATUS);
|
|
||||||
}
|
|
||||||
settings.drive = drive;
|
|
||||||
}
|
}
|
||||||
uint8_t status = inb(bus ATA_ALT_STATUS);
|
for(uint32_t i = 0; i < 15; i++){
|
||||||
|
uint8_t _ = inb(BAR2 ATA_ALT_STATUS);
|
||||||
|
}
|
||||||
|
uint8_t status = inb(BAR2 ATA_ALT_STATUS);
|
||||||
if(!ATA_BSY(status) || ATA_DRQ(status)) return 1;
|
if(!ATA_BSY(status) || ATA_DRQ(status)) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
//return index of first free drive descriptor
|
||||||
|
uint32_t find_free_drive(){
|
||||||
|
for(uint32_t i = 0; i < 32; i++){
|
||||||
|
if(drives[i].type == TYPE_NULL){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
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){
|
void init(KOS_MAPI_FP module_api, uint32_t api_version){
|
||||||
api = module_api;
|
api = module_api;
|
||||||
|
|
@ -140,14 +187,35 @@ void init(KOS_MAPI_FP module_api, uint32_t api_version){
|
||||||
api(MODULE_API_PRINT, MODULE_NAME, "Failed to register module, exiting\n");
|
api(MODULE_API_PRINT, MODULE_NAME, "Failed to register module, exiting\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ata_identify();
|
|
||||||
|
vfile_t *pci_drive_dir = fopen(api, "/dev/pci/disk/");
|
||||||
|
vfile_t **dir_data = (pci_drive_dir->access.data.ptr);
|
||||||
|
for(uint32_t i = 0; dir_data[i]; i++){
|
||||||
|
vfile_t *current_file = dir_data[i];
|
||||||
|
uint32_t class = 0;
|
||||||
|
fread(api, current_file, &class, 0x8, 1);
|
||||||
|
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.
|
||||||
|
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_SECONDARY_NATIVE(progif)){
|
||||||
|
BARs[2] = ATA_SECONDARY_BUS;
|
||||||
|
BARs[3] = ATA_SECONDARY_BUS + 0x206;
|
||||||
|
}
|
||||||
|
ide_init(BARs);
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ata_identify(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void fini(){
|
void fini(){
|
||||||
//destroy all objects, free memory, and
|
//destroy all objects, free memory, and exit
|
||||||
|
return; //nothing to do (yet)
|
||||||
}
|
}
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
#define MODULE_API_PADDR 13 //get physical address of memory
|
#define MODULE_API_PADDR 13 //get physical address of memory
|
||||||
#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks
|
#define MODULE_API_MALLOC 14 //allocate memory in 4kb blocks
|
||||||
#define MODULE_API_FREE 15 //free memory allocated by malloc
|
#define MODULE_API_FREE 15 //free memory allocated by malloc
|
||||||
|
#define MODULE_API_PMALLOC64K 16 //get 64k-aligned pages
|
||||||
|
#define MODULE_API_KMALLOC_PADDR 17
|
||||||
|
|
||||||
typedef uint32_t (*KOS_MAPI_FP)(unsigned int function, ...);
|
typedef uint32_t (*KOS_MAPI_FP)(unsigned int function, ...);
|
||||||
typedef struct module{
|
typedef struct module{
|
||||||
|
|
@ -40,15 +42,42 @@ typedef struct virtual_file{
|
||||||
VFILE_TYPE type;
|
VFILE_TYPE type;
|
||||||
uint32_t id;//to be assigned by driver;
|
uint32_t id;//to be assigned by driver;
|
||||||
uint32_t mount_id;
|
uint32_t mount_id;
|
||||||
|
uint8_t lock;
|
||||||
|
uint32_t size;
|
||||||
|
struct virtual_file *parent;//should point to A: a virtual directory, or B: a mounted filesystem
|
||||||
union{
|
union{
|
||||||
struct{
|
struct{
|
||||||
void (*read)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
|
int (*read)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
|
||||||
void (*write)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
|
int (*write)(struct virtual_file *file, void *data, uint32_t offset, uint32_t count);
|
||||||
}funcs;
|
}funcs;
|
||||||
struct{
|
struct{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
uint16_t size_pgs;
|
uint32_t size_pgs;
|
||||||
uint16_t free_bytes;
|
|
||||||
}__attribute__((packed))data;
|
}__attribute__((packed))data;
|
||||||
}access;
|
}access;
|
||||||
}vfile_t;
|
}vfile_t;
|
||||||
|
|
||||||
|
inline void *malloc(KOS_MAPI_FP api, uint32_t size_pages){
|
||||||
|
return (void *)api(MODULE_API_MALLOC, size_pages);
|
||||||
|
}
|
||||||
|
inline void *free(KOS_MAPI_FP api, void *ptr){
|
||||||
|
api(MODULE_API_FREE, ptr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
inline vfile_t *fopen(KOS_MAPI_FP api, char *filename){
|
||||||
|
// vfile_t *file = malloc(api, 1);
|
||||||
|
return (void *)api(MODULE_API_OPEN, filename);
|
||||||
|
}
|
||||||
|
inline int fread(KOS_MAPI_FP api, vfile_t *file, char *buffer, uint32_t offset, uint32_t count){
|
||||||
|
return api(MODULE_API_READ, file, buffer, offset, count);
|
||||||
|
}
|
||||||
|
inline int fwrite(KOS_MAPI_FP api, vfile_t *file, char *buffer, uint32_t offset, uint32_t count){
|
||||||
|
return api(MODULE_API_WRITE, file, buffer, offset, count);
|
||||||
|
}
|
||||||
|
//read documenation for this one
|
||||||
|
inline vfile_t *fcreate(KOS_MAPI_FP api, char *filename, VFILE_TYPE type, char *pointer_write, char *size_read){
|
||||||
|
return (void *)api(MODULE_API_CREAT, filename, type, pointer_write, size_read);
|
||||||
|
}
|
||||||
|
inline void puts(KOS_MAPI_FP api, char *mname, char *str){
|
||||||
|
api(MODULE_API_PRINT, mname, str);
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue