diff options
author | Benji Dial <Benji3.141@gmail.com> | 2020-08-13 17:58:50 -0400 |
---|---|---|
committer | Benji Dial <Benji3.141@gmail.com> | 2020-08-13 17:58:50 -0400 |
commit | 2ddbeb9f7214f6d3feef651eba83e6a9d120a743 (patch) | |
tree | 10a2aef195e0f40b0e44ffac82dcf60e426c4385 | |
parent | 63167f223e1f54910f6b80e698390ee60aec79ee (diff) | |
download | portland-os-2ddbeb9f7214f6d3feef651eba83e6a9d120a743.tar.gz |
lots of progress, including readonly PATA driver and part of FAT16 driver
-rw-r--r-- | makefile | 2 | ||||
-rw-r--r-- | src/kernel/ata.h | 36 | ||||
-rw-r--r-- | src/kernel/drive.c | 12 | ||||
-rw-r--r-- | src/kernel/drive.h | 12 | ||||
-rw-r--r-- | src/kernel/fat.c | 70 | ||||
-rw-r--r-- | src/kernel/fat.h | 2 | ||||
-rw-r--r-- | src/kernel/ide.c | 226 | ||||
-rw-r--r-- | src/kernel/ide.h | 6 | ||||
-rw-r--r-- | src/kernel/main.c | 49 | ||||
-rw-r--r-- | src/kernel/mem.c | 4 | ||||
-rw-r--r-- | src/kernel/mem.h | 4 | ||||
-rw-r--r-- | src/kernel/panic.c | 7 | ||||
-rw-r--r-- | src/kernel/panic.h | 4 | ||||
-rw-r--r-- | src/kernel/pci.c | 9 | ||||
-rw-r--r-- | src/kernel/pci.h | 8 | ||||
-rw-r--r-- | src/kernel/plef.c | 7 | ||||
-rw-r--r-- | src/kernel/plef.h | 3 | ||||
-rw-r--r-- | src/kernel/serial.c | 7 | ||||
-rw-r--r-- | src/kernel/serial.h | 8 | ||||
-rw-r--r-- | src/kernel/task.c | 2 | ||||
-rw-r--r-- | src/kernel/task.h | 2 | ||||
-rw-r--r-- | src/kernel/util.c | 10 | ||||
-rw-r--r-- | src/kernel/util.h | 16 | ||||
-rw-r--r-- | src/kernel/vesa.c | 18 | ||||
-rw-r--r-- | src/kernel/vesa.h | 25 | ||||
-rw-r--r-- | src/kernel/vga.c | 6 | ||||
-rw-r--r-- | src/kernel/vga.h | 4 |
27 files changed, 285 insertions, 274 deletions
@@ -21,7 +21,7 @@ skel: mkdir -p out/fs cp -r fs-skel/* out/fs/ -kgccargs = -Wall -m32 -Og -ffreestanding -fno-asynchronous-unwind-tables +kgccargs = -Wall -Wsuggest-attribute=pure -Wsuggest-attribute=const -Wsuggest-attribute=malloc -m32 -Og -ffreestanding -fno-asynchronous-unwind-tables ugccargs = ${kgccargs} -Isrc/libc/inc nasmargs = -f elf32 diff --git a/src/kernel/ata.h b/src/kernel/ata.h index 7c42cdb..28ef0de 100644 --- a/src/kernel/ata.h +++ b/src/kernel/ata.h @@ -38,23 +38,16 @@ enum { }; enum { - ATA_REG_DATA = 0x0, - ATA_REG_ERROR = 0x1, - ATA_REG_FEAT = 0x1, - ATA_REG_COUNT_LOW = 0x2, - ATA_REG_LBA0 = 0x3, - ATA_REG_LBA1 = 0x4, - ATA_REG_LBA2 = 0x5, - ATA_REG_SELECT = 0x6, - ATA_REG_CMD = 0x7, - ATA_REG_STATUS = 0x7, - ATA_REG_COUNT_HIGH = 0x8, - ATA_REG_LBA3 = 0x9, - ATA_REG_LBA4 = 0xa, - ATA_REG_LBA5 = 0xb, - ATA_REG_CONTROL = 0xc, - ATA_REG_ALT_STATUS = 0xc, - ATA_REG_ADDR = 0xd + ATA_REG_DATA = 0x0, + ATA_REG_ERROR = 0x1, + ATA_REG_FEAT = 0x1, + ATA_REG_COUNT = 0x2, + ATA_REG_LBA0 = 0x3, + ATA_REG_LBA1 = 0x4, + ATA_REG_LBA2 = 0x5, + ATA_REG_SELECT = 0x6, + ATA_REG_CMD = 0x7, + ATA_REG_STATUS = 0x7, }; enum { @@ -71,5 +64,12 @@ enum { }; enum { - ATA_CONTROL_NO_IRQS = 0x02 + ATA_CONTROL_NO_IRQS = 0x02, +}; + +enum { + PATA_TYPE_ID = 0x0000, + SATA_TYPE_ID = 0xc33c, + PATAPI_TYPE_ID = 0xeb14, + SATAPI_TYPE_ID = 0x9669 };
\ No newline at end of file diff --git a/src/kernel/drive.c b/src/kernel/drive.c index bf27ec6..b001aca 100644 --- a/src/kernel/drive.c +++ b/src/kernel/drive.c @@ -1,24 +1,24 @@ #include "drive.h" -#include "fat.h" #include "panic.h" +#include "fat.h" uint8_t n_drives = 0; struct drive drives[256]; -drive_file_id_t unknown_get_file(struct drive *d, char *path) { +__attribute__ ((const)) drive_file_id_t unknown_get_file(const struct drive *d, const char *path) { return 0; } -void unknown_free_file(struct drive *d, drive_file_id_t fid) { +void unknown_free_file(const struct drive *d, drive_file_id_t fid) { panic("Free file called on unknown file system"); } -void unknown_load_sector(struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) { +void unknown_load_sector(const struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) { panic("Load sector called on unknown file system"); } -uint32_t unknown_get_free_sectors(struct drive *d) { - return d->n_sectors; +__attribute__ ((const)) uint32_t unknown_get_free_sectors(const struct drive *d) { + return -1; } void determine_fs(struct drive *d) { diff --git a/src/kernel/drive.h b/src/kernel/drive.h index 8d3f3b2..ca6d1ee 100644 --- a/src/kernel/drive.h +++ b/src/kernel/drive.h @@ -14,15 +14,15 @@ struct drive { char *drive_type; char *fs_type; - uint8_t (*read_sectors)(struct drive *d, uint32_t start, uint32_t count, void *buffer); - uint8_t (*write_sectors)(struct drive *d, uint32_t start, uint32_t count, void *buffer); + uint8_t (*read_sectors)(const struct drive *d, uint32_t start, uint32_t count, void *buffer); + uint8_t (*write_sectors)(const struct drive *d, uint32_t start, uint32_t count, const void *buffer); uint32_t n_sectors; drive_id_t drive_id; - drive_file_id_t (*get_file)(struct drive *d, char *path); - void (*free_file)(struct drive *d, drive_file_id_t fid); - void (*load_sector)(struct drive *d, drive_file_id_t fid, uint32_t sector, void *at); - uint32_t (*get_free_sectors)(struct drive *d); + drive_file_id_t (*get_file)(const struct drive *d, const char *path); + void (*free_file)(const struct drive *d, drive_file_id_t fid); + void (*load_sector)(const struct drive *d, drive_file_id_t fid, uint32_t sector, void *at); + uint32_t (*get_free_sectors)(const struct drive *d); fs_id_t fs_id; }; diff --git a/src/kernel/fat.c b/src/kernel/fat.c index 087d79e..807af00 100644 --- a/src/kernel/fat.c +++ b/src/kernel/fat.c @@ -1,9 +1,9 @@ -#include "fat.h" -#include "ata.h" -#include "panic.h" #include "drive.h" -#include "mem.h" +#include "panic.h" #include "util.h" +#include "ata.h" +#include "fat.h" +#include "mem.h" #define MAX_FAT_DRIVES 16 #define MAX_OPEN_FILES_PER_DRIVE 32 @@ -57,20 +57,19 @@ struct fat_info { uint8_t fs_type[8]; } __attribute__ ((packed)); -#define CTOS(c, fi) ((fi)->reserved_sectors + (fi)->sectors_per_fat * (fi)->fats + ((fi)->root_entries >> 4) + (c) - 2) +#define CTOS(c, fdi) ((fdi)->data_start + (c) - 2) struct fat_drive_info { - struct fat_info *fi; + const struct fat_info *fi; uint16_t *fat; + uint16_t root_start; + uint16_t data_start; struct directory_entry open_files[MAX_OPEN_FILES_PER_DRIVE]; }; struct fat_drive_info infos[MAX_FAT_DRIVES]; uint8_t next_id = 0; -#define FI(n) ((struct fat_info *)(infos[n].fi + 3)) -#define FN(n, f) (infos[n].open_files[f - 1]) - uint8_t fat_driver_buffer[512]; struct fat_info *next_fi; @@ -80,8 +79,9 @@ void alloc_next_fi() { panic("Out of memory in FAT driver."); } -struct drive *cur_drive; +const struct drive *cur_drive; fs_id_t cur_id; +const struct fat_drive_info *cur_fdi; struct directory_entry *cur_dir; //loads cluster `c` @@ -91,7 +91,7 @@ void load_cluster(uint16_t c, void *to) { return; } - uint32_t s = CTOS(c, FI(cur_id)); + uint32_t s = CTOS(c, cur_fdi); cur_drive->read_sectors(cur_drive, s, 1, to); } @@ -99,7 +99,7 @@ uint16_t next_cluster(uint16_t c) { panic("TODO: compute next sector (or 0 for none)"); } -static inline bool check_fat_names(uint8_t *a, uint8_t *b) { +static inline bool check_fat_names(const uint8_t *a, const uint8_t *b) { return (((uint32_t *)a)[0] == ((uint32_t *)b)[0]) && (((uint32_t *)a)[1] == ((uint32_t *)b)[1]) && (((uint16_t *)a)[8] == ((uint16_t *)b)[8]) && @@ -107,8 +107,8 @@ static inline bool check_fat_names(uint8_t *a, uint8_t *b) { } //after: cur_dir -> specified entry in root -bool try_locate_root_entry(uint8_t *fat_name) { - uint32_t cur_dir_sect = FI(cur_id)->reserved_sectors + FI(cur_id)->sectors_per_fat * FI(cur_id)->fats - 1; +bool try_locate_root_entry(const uint8_t *fat_name) { + uint32_t cur_dir_sect = cur_fdi->root_start - 1; cur_dir = (struct directory_entry *)(fat_driver_buffer + 512); while (true) { if (cur_dir == (struct directory_entry *)(fat_driver_buffer + 512)) { @@ -127,7 +127,7 @@ bool try_locate_root_entry(uint8_t *fat_name) { //before: cur_dir -> entry of dir to search //after: cur_dir -> specified entry in dir -bool try_locate_entry(uint8_t *fat_name) { +bool try_locate_entry(const uint8_t *fat_name) { uint16_t cur_dir_cluster = cur_dir->first_cluster; load_cluster(cur_dir_cluster, fat_driver_buffer); cur_dir = (struct directory_entry *)fat_driver_buffer; @@ -146,32 +146,41 @@ bool try_locate_entry(uint8_t *fat_name) { } } -drive_file_id_t fat_get_file(struct drive *d, char *path) { +drive_file_id_t fat_get_file(const struct drive *d, const char *path) { cur_drive = d; cur_id = d->drive_id; + cur_fdi = &infos[cur_id]; + const struct directory_entry *open_files = cur_fdi->open_files - 1; for (drive_file_id_t n = 1; n != MAX_OPEN_FILES_PER_DRIVE + 1; ++n) - if (!*(uint8_t *)(&FN(d->drive_id, n))) { - panic("TODO: open path at FN(id, n)"); + if (!*(uint8_t *)(&open_files[n])) { + panic("TODO: open path into open_files[n]"); return n; } panic("Maximum number of files open reached for FAT drive."); } -void fat_free_file(struct drive *d, drive_file_id_t fid) { - *(uint8_t *)(&FN(d->drive_id, fid)) = 0; +void fat_free_file(const struct drive *d, drive_file_id_t fid) { + *(uint8_t *)(&infos[d->drive_id].open_files[fid - 1]) = 0; } -void fat_load_sector(struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) { +void fat_load_sector(const struct drive *d, drive_file_id_t fid, uint32_t sector, void *at) { cur_drive = d; cur_id = d->drive_id; - uint16_t c = FN(d->drive_id, fid).first_cluster; + cur_fdi = &infos[cur_id]; + uint16_t c = cur_fdi->open_files[fid - 1].first_cluster; for (uint32_t i = 0; i < sector; ++i) c = next_cluster(c); load_cluster(c, at); } -uint32_t fat_get_free_sectors(struct drive *d) { - panic("TODO: get free sectors of drive"); +__attribute__ ((pure)) uint32_t fat_get_free_sectors(const struct drive *d) { + uint16_t *start = infos[d->fs_id].fat + 2; + uint16_t *end = start + d->n_sectors - infos[d->fs_id].data_start; + uint32_t count = 0; + for (uint16_t *i = start; i < end; ++i) + if (!*i) + ++count; + return count; } void init_fat() { @@ -186,8 +195,8 @@ bool try_fat_init_drive(struct drive *d) { return false; memcpy(next_fi, fat_driver_buffer + 3, sizeof(struct fat_info)); uint32_t *fs_type_32 = (uint32_t *)next_fi->fs_type; - if ((fs_type_32[0] != ('F' + 'A' * 256 + 'T' + 65536 + '1' * 16777216)) || - (fs_type_32[1] != ('6' + ' ' * 256 + ' ' + 65536 + ' ' * 16777216))) + if ((fs_type_32[0] != ('F' + 'A' * 256 + 'T' * 65536 + '1' * 16777216)) || + (fs_type_32[1] != ('6' + ' ' * 256 + ' ' * 65536 + ' ' * 16777216))) return false; d->fs_type = "FAT16"; @@ -199,10 +208,15 @@ bool try_fat_init_drive(struct drive *d) { d->fs_id = next_id; infos[next_id].fi = next_fi; infos[next_id].fat = allocate_pages(((next_fi->sectors_per_fat - 1) >> 3) + 1); - for (drive_file_id_t i = 0; i < MAX_OPEN_FILES_PER_DRIVE; ++i) - *(uint8_t *)&FN(next_id, i) = 0; + infos[next_id].root_start = next_fi->reserved_sectors + + next_fi->sectors_per_fat * next_fi->fats; + infos[next_id].data_start = infos[next_id].root_start + + ((next_fi->root_entries - 1) >> 4) + 1; d->read_sectors(d, next_fi->reserved_sectors, next_fi->sectors_per_fat, infos[next_id].fat); + struct directory_entry *open_files = infos[next_id].open_files - 1; + for (drive_file_id_t i = 0; i < MAX_OPEN_FILES_PER_DRIVE; ++i) + *(uint8_t *)&open_files[i] = 0; alloc_next_fi(); ++next_id; diff --git a/src/kernel/fat.h b/src/kernel/fat.h index d9db906..cadb073 100644 --- a/src/kernel/fat.h +++ b/src/kernel/fat.h @@ -1,8 +1,8 @@ #ifndef FAT_H #define FAT_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #include "drive.h" void init_fat(); diff --git a/src/kernel/ide.c b/src/kernel/ide.c index a2d3895..a32f149 100644 --- a/src/kernel/ide.c +++ b/src/kernel/ide.c @@ -1,171 +1,192 @@ -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> +#include "drive.h" #include "panic.h" #include "util.h" -#include "drive.h" -#include "pci.h" #include "ata.h" +#include "pci.h" #define MAX_IDE_DRIVES 8 struct ide_drive_info { uint16_t base_port; - uint16_t control_port; + uint16_t alt_port; bool slave; }; struct ide_drive_info ide_drives[MAX_IDE_DRIVES]; drive_id_t n_ide_drives = 0; -void spin_delay() { - for (uint32_t i = -1; i; --i) - ; -} - -//return true on error condition -bool poll(struct ide_drive_info *info) { - spin_delay(); - - uint8_t status; +typedef uint16_t spinner_t; - while ((status = inb(info->base_port | ATA_REG_STATUS)) & ATA_STATUS_BUSY) - ; +//returns the status after waiting +uint8_t wait_after_cmd(uint16_t base_port) { + for (spinner_t n = -1; n; --n) { + uint8_t s = inb(base_port | ATA_REG_STATUS); + if (s & ATA_STATUS_ERROR) + panic("Error status in IDE driver."); + if (!(s & ATA_STATUS_BUSY)) + return s; + } + panic("Spun out in IDE driver."); +} - return (status & (ATA_STATUS_ERROR | ATA_STATUS_DRIVE_FAULT)) || !(status & ATA_STATUS_DRIVE_READY); +//returns the status after waiting +uint8_t wait_for_ready(uint16_t base_port) { + for (spinner_t n = -1; n; --n) { + uint8_t s = inb(base_port | ATA_REG_STATUS); + if (s & ATA_STATUS_ERROR) + panic("Error status in IDE driver."); + if (s & ATA_STATUS_DRIVE_READY) + return s; + } + panic("Spun out in IDE driver."); } -uint8_t ide_ata_rs(struct drive *d, uint32_t start, uint32_t count, void *buffer) { - if (start & 0xf0000000) - panic("IDE ATA driver only supports LBA28 addressing currently."); +//returns the status after waiting +uint8_t wait_for_error_or_ready(uint16_t base_port) { + for (spinner_t n = -1; n; --n) { + uint8_t s = inb(base_port | ATA_REG_STATUS); + if (s & (ATA_STATUS_DRIVE_READY | ATA_STATUS_ERROR)) + return s; + } + panic("Spun out in IDE driver."); +} - struct ide_drive_info *info = ide_drives + d->drive_id; +//returns the status after waiting +uint8_t wait_for_data_ready_not_busy(uint16_t base_port) { + for (spinner_t n = -1; n; --n) { + uint8_t s = inb(base_port | ATA_REG_STATUS); + if (!(s & ATA_STATUS_BUSY) && (s & ATA_STATUS_DATA_READY)) + return s; + if (s & ATA_STATUS_ERROR) + panic("Error status in IDE driver."); + } + panic("Spun out in IDE driver."); +} +uint8_t ide_ata_rs(const struct drive *d, uint32_t start, uint32_t count, void *buffer) { + if (start >= d->n_sectors) + return 0; if (start + count > d->n_sectors) count = d->n_sectors - start; + if (!count) + return 0; + if (start & 0xf0000000) + panic("IDE ATA driver does not support reads starting past 256MiB currently."); if (count & 0xffffff00) - panic("IDE ATA driver only supports reading up to 128k at a time currently."); + panic("IDE ATA driver does not support reads over 128kiB in length currently."); uint32_t lba = start & 0x00ffffff; - uint32_t spin = -1; - while (inb(info->base_port | ATA_REG_STATUS) & ATA_STATUS_BUSY) - if (!spin--) - panic("Spun out in IDE ATA reading"); + struct ide_drive_info *info = ide_drives + d->drive_id; outb(info->base_port | ATA_REG_SELECT, (info->slave ? 0xf0 : 0xe0) | (start >> 24)); - outb(info->base_port | ATA_REG_COUNT_LOW, count); + //spin? + + outb(info->base_port | ATA_REG_COUNT, count); outb(info->base_port | ATA_REG_LBA0, lba); outb(info->base_port | ATA_REG_LBA1, lba >> 8); outb(info->base_port | ATA_REG_LBA2, lba >> 16); - uint16_t *buffer_16 = buffer; + outb(info->base_port | ATA_REG_CMD, ATA_CMD_READ); + + uint16_t *buf16 = (uint16_t *)buffer; for (uint16_t i = 0; i < count; ++i) { - if (poll(info)) - return i; + wait_for_data_ready_not_busy(info->base_port); for (uint16_t j = 0; j < 256; ++j) - *buffer_16++ = inw(info->base_port + ATA_REG_DATA); + *buf16++ = inw(info->base_port | ATA_REG_DATA); } return count; } -uint8_t ide_ata_ws(struct drive *d, uint32_t start, uint32_t count, void *buffer) { +uint8_t ide_ata_ws(const struct drive *d, uint32_t start, uint32_t count, const void *buffer) { panic("IDE ATA writing not implemented yet"); return 0; } -uint8_t ide_atapi_rs(struct drive *d, uint32_t start, uint32_t count, void *buffer) { +uint8_t ide_atapi_rs(const struct drive *d, uint32_t start, uint32_t count, void *buffer) { //panic("IDE ATAPI reading not implemented yet"); return 0; } -uint8_t ide_atapi_ws(struct drive *d, uint32_t start, uint32_t count, void *buffer) { +uint8_t ide_atapi_ws(const struct drive *d, uint32_t start, uint32_t count, const void *buffer) { panic("IDE ATAPI writing not implemented yet"); return 0; } struct id_space { - uint16_t device_type;//0 - uint8_t skip1[98 - 2]; - uint16_t capabilities;//98 - uint8_t skip2[120 - (98 + 2)]; + uint8_t skip1[120]; uint32_t max_lba;//120 - uint8_t skip3[164 - (120 + 4)]; - uint32_t command_sets;//164 - uint8_t skip4[200 - (164 + 4)]; - uint32_t max_lba_ext;//200 - uint8_t skip5[512 - (200 + 4)]; -} __attribute__ ((__packed__)); - -void read_id_space(uint16_t base_port, struct id_space *to) { - uint32_t *to_32 = (uint32_t *)to; - for (uint8_t i = 0; i < 128; ++i) - *(to_32++) = ind(base_port | ATA_REG_DATA); -} + uint8_t skip2[512 - (120 + 4)]; +} __attribute__ ((__packed__ )); -void test_drive(uint16_t base_port, uint16_t control_port, bool slave) { - outb(base_port | ATA_REG_SELECT, slave ? ATA_SLAVE_SELECT : ATA_MASTER_SELECT); - spin_delay(); +void vga_printsz(char *s); - outb(base_port | ATA_REG_CMD, ATA_CMD_ID); - spin_delay(); +void test_drive(uint16_t base_port, uint16_t alt_port, bool slave) { + if (n_ide_drives == MAX_IDE_DRIVES) + panic("Maximum number of IDE drives reached."); - if (!inb(base_port | ATA_REG_STATUS)) - return; + struct ide_drive_info *next = ide_drives + n_ide_drives; + struct drive next_d; + next_d.drive_id = n_ide_drives; - if (n_ide_drives == MAX_IDE_DRIVES) - panic("Maximum IDE drives reached"); + next->base_port = base_port; + next->alt_port = alt_port; + next->slave = slave; - outb(base_port | ATA_REG_CONTROL, ATA_CONTROL_NO_IRQS); + outb(base_port | ATA_REG_SELECT, slave ? 0xb0 : 0xa0); + outb(base_port | ATA_REG_COUNT, 0); + outb(base_port | ATA_REG_LBA0, 0); + outb(base_port | ATA_REG_LBA1, 0); + outb(base_port | ATA_REG_LBA2, 0); - struct ide_drive_info *this_drive = ide_drives + n_ide_drives; - this_drive->base_port = base_port; - this_drive->control_port = control_port; - this_drive->slave = slave; + outb(base_port | ATA_REG_CMD, ATA_CMD_ID); - struct drive data; - data.drive_id = n_ide_drives; + if (!inb(base_port | ATA_REG_STATUS)) + return; - uint32_t spin_out = -1; - while (1) {//wait for identify to complete - uint8_t status = inb(base_port | ATA_REG_STATUS); - if (status & ATA_STATUS_ERROR) { - uint16_t type = inb(base_port | ATA_REG_LBA1) + - (inb(base_port | ATA_REG_LBA2) << 8); + struct id_space ids; - //These two are listed on OSDev Wiki - // as being ATAPI device types. - if ((type != 0xeb14) && (type != 0x9669)) - return; + if (!(wait_for_error_or_ready(base_port) & ATA_STATUS_ERROR)) { + wait_for_ready(base_port); + for (uint16_t *ids_16 = (uint16_t *)&ids; ids_16 < (uint16_t *)&ids + 256; ++ids_16) + *ids_16 = inw(base_port | ATA_REG_DATA); - outb(base_port | ATA_REG_CMD, ATAPI_CMD_ID); + next_d.drive_type = "IDE PATA"; + next_d.read_sectors = &ide_ata_rs; + next_d.write_sectors = &ide_ata_ws; + } + else { + uint16_t code = inb(base_port | 0x4) + (inb(base_port | 0x5) << 8); + if (!code) { + panic("PATA identification aborted."); + } + if (code == 0xeb14) { + next_d.drive_type = "IDE PATAPI"; + next_d.read_sectors = &ide_atapi_rs; + next_d.write_sectors = &ide_atapi_ws; - data.read_sectors = &ide_atapi_rs; - data.write_sectors = &ide_atapi_ws; - data.drive_type = "IDE ATAPI"; - break; + //TODO: issue proper identify command + ids.max_lba = -1; } - if (!(status & ATA_STATUS_BUSY) && (status & ATA_STATUS_DATA_READY)) { - data.read_sectors = &ide_ata_rs; - data.write_sectors = &ide_ata_ws; - data.drive_type = "IDE ATA"; - break; + else if (code == 0xc33c) { + next_d.drive_type = "IDE SATA"; + + //TODO: set up drive hooks, issue proper identify command + return; } - if (!spin_out--) - panic("IDE ATA identify won't complete"); } - struct id_space id; - read_id_space(base_port, &id); - - if (!(id.capabilities & ATA_CAP_LBA)) - //TODO: CHS compability driver? - return; - data.n_sectors = (id.command_sets & ATA_SET_EXT) ? id.max_lba_ext : id.max_lba; + //in the future, maybe add support for 48-bit LBA, and/or CHS addressing + if (!ids.max_lba) + panic("Encountered ATA drive that doesn't support 28-bit LBA"); + next_d.n_sectors = ids.max_lba; - commit_drive(data); + commit_drive(next_d); ++n_ide_drives; } @@ -176,14 +197,9 @@ void init_ide() { while ((device = find_pci_device_from_class_and_subclass(PCI_MASS_STORAGE, PCI_IDE, check_from, &check_from))) { ++check_from; - uint16_t primary_base_port = device->bar0 <= 1 ? 0x01f0 : device->bar0; - uint16_t primary_control_port = device->bar1 <= 1 ? 0x03f6 : device->bar1; - uint16_t secondary_base_port = device->bar2 <= 1 ? 0x0170 : device->bar2; - uint16_t secondary_control_port = device->bar3 <= 1 ? 0x0376 : device->bar3; - - test_drive(primary_base_port, primary_control_port, false); - test_drive(primary_base_port, primary_control_port, true); - test_drive(secondary_base_port, secondary_control_port, false); - test_drive(secondary_base_port, secondary_control_port, true); + test_drive(0x01f0, 0x03f6, false); + test_drive(0x01f0, 0x03f6, true); + test_drive(0x0170, 0x0376, false); + test_drive(0x0170, 0x0376, true); } }
\ No newline at end of file diff --git a/src/kernel/ide.h b/src/kernel/ide.h index 44b02ec..47bcc49 100644 --- a/src/kernel/ide.h +++ b/src/kernel/ide.h @@ -1,12 +1,6 @@ #ifndef IDE_H #define IDE_H -#include <stdint.h> -#include "drive.h" - void init_ide(); -uint8_t ide_read_sectors(drive_id_t id, uint32_t start, uint32_t count, void *buffer); -uint8_t ide_write_sectors(drive_id_t id, uint32_t start, uint32_t count, void *buffer); - #endif
\ No newline at end of file diff --git a/src/kernel/main.c b/src/kernel/main.c index e5c0013..cbdebfa 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,30 +1,20 @@ #include <stdint.h> -#include "vga.h" -#include "fat.h" -#include "ide.h" -#include "panic.h" #include "serial.h" +#include "panic.h" +#include "boot.h" #include "util.h" +#include "vesa.h" +#include "fat.h" +#include "ide.h" #include "mem.h" #include "pci.h" -#include "boot.h" -#include "vesa.h" - -char nbuf[11]; - -#define SOTL(field) field = (void *)((*((uint16_t *)(&field) + 1) << 16) + *(uint16_t *)(&field)); +#include "vga.h" __attribute__ ((noreturn)) void main() { - SOTL(VESA_INFO->oem) - SOTL(VESA_INFO->modes) - SOTL(VESA_INFO->vendor) - SOTL(VESA_INFO->pname) - SOTL(VESA_INFO->prev) + char nbuf[11]; init_mmap(); - init_vesa(); - init_serial(); vga_blank(); @@ -64,8 +54,10 @@ __attribute__ ((noreturn)) void main() { vga_printch('\n'); init_fat(); + //other fs drivers init_ide(); + //other drive drivers u8_dec(n_drives, nbuf); vga_printsz(nbuf); @@ -79,24 +71,27 @@ __attribute__ ((noreturn)) void main() { vga_printsz(nbuf); vga_printsz(" ("); vga_printsz(d->drive_type); - vga_printsz("): "); - - vga_printsz(d->fs_type); vga_printsz(", "); u32_dec(d->n_sectors / 2, nbuf); vga_printsz(nbuf); if (d->n_sectors % 2) vga_printsz(".5"); - vga_printsz("k, "); + vga_printsz("k): "); - uint32_t free_sectors = d->get_free_sectors(d); + vga_printsz(d->fs_type); - u32_dec(free_sectors / 2, nbuf); - vga_printsz(nbuf); - if (d->n_sectors % 2) - vga_printsz(".5"); - vga_printsz("k free.\n"); + uint32_t free_sectors = d->get_free_sectors(d); + if (free_sectors != -1) { + u32_dec(free_sectors / 2, nbuf); + vga_printsz(", "); + vga_printsz(nbuf); + if (free_sectors % 2) + vga_printsz(".5"); + vga_printsz("k free"); + } + + vga_printsz(".\n"); } vga_printch('\n'); diff --git a/src/kernel/mem.c b/src/kernel/mem.c index 2e8173d..d3baad3 100644 --- a/src/kernel/mem.c +++ b/src/kernel/mem.c @@ -1,6 +1,6 @@ #include <stdint.h> -#include <stdbool.h> #include "panic.h" +#include "mem.h" #define DYNAMIC_START (0x10000000) #define DYNAMIC_END (DYNAMIC_START + 65536 * 4096) @@ -55,7 +55,7 @@ void *allocate_pages(uint16_t n) { } //in the future, change this to go by bytes or dwords instead of bits. -void free_pages(void *ptr, uint16_t n) { +void free_pages(const void *ptr, uint16_t n) { uint16_t page = ADDR_TO_PAGE(ptr); for (uint32_t i = page; i < page + n; ++i) CLEAR_PAGE(i); diff --git a/src/kernel/mem.h b/src/kernel/mem.h index 913f70b..9a9ae79 100644 --- a/src/kernel/mem.h +++ b/src/kernel/mem.h @@ -7,7 +7,7 @@ extern uint16_t pages_left; void init_mmap(); -void *allocate_pages(uint16_t n); -void free_pages(void *ptr, uint16_t n); +void *allocate_pages(uint16_t n) __attribute__ ((malloc)); +void free_pages(const void *ptr, uint16_t n); #endif
\ No newline at end of file diff --git a/src/kernel/panic.c b/src/kernel/panic.c index 93944ff..e04ae38 100644 --- a/src/kernel/panic.c +++ b/src/kernel/panic.c @@ -1,10 +1,7 @@ -#include <stdint.h> -#include "vga.h" -#include "serial.h" -#include "util.h" #include "panic.h" +#include "vga.h" -void panic(char *message) { +void panic(const char *message) { vga_set_color(0x4f); vga_blank(); vga_printsz("Kernel panic: "); diff --git a/src/kernel/panic.h b/src/kernel/panic.h index 7d2e9df..08328f2 100644 --- a/src/kernel/panic.h +++ b/src/kernel/panic.h @@ -1,8 +1,6 @@ #ifndef PANIC_H #define PANIC_H -#include <stdint.h> - -void panic(char *message) __attribute__ ((noreturn)); +void panic(const char *message) __attribute__ ((noreturn)); #endif
\ No newline at end of file diff --git a/src/kernel/pci.c b/src/kernel/pci.c index fe96c4c..5d8170d 100644 --- a/src/kernel/pci.c +++ b/src/kernel/pci.c @@ -1,8 +1,8 @@ +#include "panic.h" #include "boot.h" -#include "mem.h" #include "util.h" +#include "mem.h" #include "pci.h" -#include "panic.h" enum { PCP_SELECT = 0x0cf8, @@ -59,11 +59,6 @@ void pci_device_check(uint16_t number) { next_device->class = class >> 24; next_device->subclass = class >> 16; next_device->iface = class >> 8; - - next_device->bar0 = pci_read_config(number, 4); - next_device->bar1 = pci_read_config(number, 5); - next_device->bar2 = pci_read_config(number, 6); - next_device->bar3 = pci_read_config(number, 7); } void pci_init() { diff --git a/src/kernel/pci.h b/src/kernel/pci.h index 1ab5936..8ff9f45 100644 --- a/src/kernel/pci.h +++ b/src/kernel/pci.h @@ -20,16 +20,10 @@ struct pci_device { uint8_t class; uint8_t subclass; uint8_t iface; - - uint32_t bar0; - uint32_t bar1; - uint32_t bar2; - uint32_t bar3; - //etc }; extern uint16_t n_pci_devices; -struct pci_device *nth_pci_device(uint16_t n); +struct pci_device *nth_pci_device(uint16_t n) __attribute__ ((pure)); struct pci_device *find_pci_device_from_class_and_subclass(uint8_t class, uint8_t subclass, uint16_t start, uint16_t *index); diff --git a/src/kernel/plef.c b/src/kernel/plef.c index 2cba843..710943f 100644 --- a/src/kernel/plef.c +++ b/src/kernel/plef.c @@ -1,13 +1,12 @@ #include <stdint.h> -#include <stdbool.h> -#include "plef.h" #include "drive.h" -#include "util.h" +#include "plef.h" #include "task.h" +#include "util.h" #define PLEF_MAGIC 0xb9ba4c50 -task_handle plef_run(struct drive *d, char *path) { +task_handle plef_run(const struct drive *d, const char *path) { drive_file_id_t h = d->get_file(d, path); if (!h) return 0; diff --git a/src/kernel/plef.h b/src/kernel/plef.h index 29100ee..a14ea9b 100644 --- a/src/kernel/plef.h +++ b/src/kernel/plef.h @@ -2,7 +2,6 @@ #define PLEF_H #include <stdint.h> -#include <stdbool.h> #include "drive.h" typedef uint8_t task_handle; @@ -17,6 +16,6 @@ struct plef_header { uint32_t entry_point; } __attribute__ ((packed)); -task_handle plef_run(struct drive *d, char *path); +task_handle plef_run(const struct drive *d, const char *path); #endif
\ No newline at end of file diff --git a/src/kernel/serial.c b/src/kernel/serial.c index 0f7abe6..c92f173 100644 --- a/src/kernel/serial.c +++ b/src/kernel/serial.c @@ -1,5 +1,6 @@ -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> +#include "serial.h" #include "util.h" enum { @@ -76,12 +77,12 @@ void sout(char b) { outb(CP_1 | CP_DATA, (uint8_t)b); } -void soutsz(char *s) { +void soutsz(const char *s) { while (*s) sout(*(s++)); } -void soutsn(char *s, uint8_t n) { +void soutsn(const char *s, uint8_t n) { while (n--) sout(*(s++)); } diff --git a/src/kernel/serial.h b/src/kernel/serial.h index bb12edb..2fb21a6 100644 --- a/src/kernel/serial.h +++ b/src/kernel/serial.h @@ -1,14 +1,14 @@ #ifndef SERIAL_H #define SERIAL_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> -bool serr(); +bool serr() __attribute__ ((pure)); void init_serial(); void sout(char b); -void soutsz(char *s); -void soutsn(char *s, uint8_t n); +void soutsz(const char *s); +void soutsn(const char *s, uint8_t n); char sin(); void sinsn(char *s, uint8_t n); diff --git a/src/kernel/task.c b/src/kernel/task.c index c08a195..3e64639 100644 --- a/src/kernel/task.c +++ b/src/kernel/task.c @@ -1,5 +1,5 @@ -#include "task.h" #include "panic.h" +#include "task.h" segment_id new_segment(bool is_code, uint32_t length, uint32_t *location_out) { panic("TODO: make new segment"); diff --git a/src/kernel/task.h b/src/kernel/task.h index add668b..c3f2acd 100644 --- a/src/kernel/task.h +++ b/src/kernel/task.h @@ -1,8 +1,8 @@ #ifndef TASK_H #define TASK_H -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> typedef uint8_t segment_id; typedef uint8_t task_handle; diff --git a/src/kernel/util.c b/src/kernel/util.c index 1531f83..29d7e3f 100644 --- a/src/kernel/util.c +++ b/src/kernel/util.c @@ -1,10 +1,10 @@ -#include <stdint.h> -#include "panic.h" #include <stdbool.h> +#include <stdint.h> #include "drive.h" -void memcpy(void *to, void *from, uint32_t n) { - uint32_t *tp = to, *fp = from; +void memcpy(void *to, const void *from, uint32_t n) { + uint32_t *tp = to; + const uint32_t *fp = from; while (n >= 4) { *(tp++) = *(fp++); n -= 4; @@ -14,7 +14,7 @@ void memcpy(void *to, void *from, uint32_t n) { *(tpp++) = *(fpp++); } -void fmcpy(void *to, struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n) { +void fmcpy(void *to, const struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n) { uint8_t buf[512]; d->load_sector(d, f, from >> 9, buf); uint16_t from_low = from & 511; diff --git a/src/kernel/util.h b/src/kernel/util.h index 243541c..324f379 100644 --- a/src/kernel/util.h +++ b/src/kernel/util.h @@ -10,8 +10,8 @@ static inline void outb(uint16_t port, uint8_t value) { : : "a"(value), "Nd"(port)); } static inline uint8_t inb(uint16_t port) { - uint8_t value; - asm volatile ( + volatile uint8_t value; + asm ( "inb %1, %0" : "=a"(value) : "Nd"(port)); return value; @@ -22,8 +22,8 @@ static inline void outw(uint16_t port, uint16_t value) { : : "a"(value), "Nd"(port)); } static inline uint16_t inw(uint16_t port) { - uint16_t value; - asm volatile ( + volatile uint16_t value; + asm ( "inw %1, %0" : "=a"(value) : "Nd"(port)); return value; @@ -34,15 +34,15 @@ static inline void outd(uint16_t port, uint32_t value) { : : "a"(value), "Nd"(port)); } static inline uint32_t ind(uint16_t port) { - uint32_t value; - asm volatile ( + volatile uint32_t value; + asm ( "inl %1, %0" : "=a"(value) : "Nd"(port)); return value; } -void memcpy(void *to, void *from, uint32_t n); -void fmcpy(void *to, struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n); +void memcpy(void *to, const void *from, uint32_t n); +void fmcpy(void *to, const struct drive *d, drive_file_id_t f, uint32_t from, uint32_t n); void u32_dec(uint32_t n, char *b); void u16_dec(uint16_t n, char *b); diff --git a/src/kernel/vesa.c b/src/kernel/vesa.c index e781249..4cdabb2 100644 --- a/src/kernel/vesa.c +++ b/src/kernel/vesa.c @@ -1,5 +1,21 @@ #include "vesa.h" +uint16_t screen_width; +uint16_t screen_height; +uint8_t bpp; + +void *frame_buffer; + +void put_pixel(uint16_t x, uint16_t y, color c) { + +} + +void screen_fill(color c) { + +} + void init_vesa() { - +// for (void *v = 0; v < 0x65536; ++v) { +// if (*(uint32_t *)v == 'P' + 'M' * 256 + 'I' * 65536 + 'D' * 16777216) +// } }
\ No newline at end of file diff --git a/src/kernel/vesa.h b/src/kernel/vesa.h index 495b593..b2f17c8 100644 --- a/src/kernel/vesa.h +++ b/src/kernel/vesa.h @@ -1,23 +1,16 @@ #ifndef VESA_H #define VESA_H -struct video_mode { - //TODO -}; +#include <stdint.h> -#define VESA_INFO \ - ((struct { \ - uint32_t sig; \ - uint16_t vbe_ver; \ - char *oem; \ - uint32_t capabilities; \ - struct video_mode *modes; \ - uint16_t vram_size_high; \ - uint16_t soft_ver; \ - char *vendor; \ - char *pname; \ - char *prev; \ - } *)0x4200) +extern uint16_t screen_width; +extern uint16_t screen_height; +extern uint8_t bpp; + +typedef uint32_t color; + +void put_pixel(uint16_t x, uint16_t y, color c); +void screen_fill(color c); void init_vesa(); diff --git a/src/kernel/vga.c b/src/kernel/vga.c index 788ce6c..e103732 100644 --- a/src/kernel/vga.c +++ b/src/kernel/vga.c @@ -1,5 +1,5 @@ -#include <stdint.h> #include <stdbool.h> +#include <stdint.h> #define VGA_COM_MIRROR @@ -50,12 +50,12 @@ void vga_printch(char ch) { vga_scroll(); } -void vga_printsz(char *sz) { +void vga_printsz(const char *sz) { while (*sz) vga_printch(*(sz++)); } -void vga_printsn(char *sn, uint8_t n) { +void vga_printsn(const char *sn, uint8_t n) { while (n--) vga_printch(*(sn++)); }
\ No newline at end of file diff --git a/src/kernel/vga.h b/src/kernel/vga.h index 1be2131..e88ddfe 100644 --- a/src/kernel/vga.h +++ b/src/kernel/vga.h @@ -7,7 +7,7 @@ void vga_set_color(uint8_t color); void vga_blank(); void vga_scroll(); void vga_printch(char ch); -void vga_printsz(char *sz); -void vga_printsn(char *sn, uint8_t n); +void vga_printsz(const char *sz); +void vga_printsn(const char *sn, uint8_t n); #endif
\ No newline at end of file |