:: commit 9b5c159d1f8416a88298d99f367f3e5b224e399e

mintsuki <mintsuki@protonmail.com> — 2020-01-23 00:48

parents: 42325aed4a

Improve disk driver

diff --git a/src/drivers/disk.c b/src/drivers/disk.c
index df13b5a2..f94e1488 100644
--- a/src/drivers/disk.c
+++ b/src/drivers/disk.c
@@ -7,9 +7,15 @@
 #include <lib/mbr.h>
 
 #define SECTOR_SIZE 512
+#define BLOCK_SIZE_IN_SECTORS 16
+#define BLOCK_SIZE  (SECTOR_SIZE * BLOCK_SIZE_IN_SECTORS)
+#define BUFFER_SEG  0x7000
+#define BUFFER_OFF  0
+#define BUFFER_ADDR ((uint8_t *)((BUFFER_SEG << 4) + BUFFER_OFF))
 
-static uint64_t cached_sector = -1;
-static uint8_t sector_buf[512];
+#define CACHE_INVALID (~((uint64_t)0))
+
+static uint64_t cached_block = CACHE_INVALID;
 
 static struct {
     uint16_t size;
@@ -17,14 +23,13 @@ static struct {
     uint16_t offset;
     uint16_t segment;
     uint64_t lba;
-} dap = { 16, 1, 0, 0, 0 };
+} dap = { 16, BLOCK_SIZE_IN_SECTORS, BUFFER_OFF, BUFFER_SEG, 0 };
 
-static int cache_sector(int drive, uint64_t lba) {
-    if (lba == cached_sector)
+static int cache_block(int drive, uint64_t block) {
+    if (block == cached_block)
         return 0;
 
-    dap.offset = (uint16_t)(size_t)sector_buf;
-    dap.lba = lba;
+    dap.lba = block * BLOCK_SIZE_IN_SECTORS;
 
     struct rm_regs r = {0};
     r.eax = 0x4200;
@@ -35,25 +40,12 @@ static int cache_sector(int drive, uint64_t lba) {
 
     if (r.eflags & EFLAGS_CF) {
         int ah = (r.eax >> 8) & 0xff;
-        print("Disk error %x. Drive %x, LBA %x.\n", ah, drive, lba);
+        print("Disk error %x. Drive %x, LBA %x.\n", ah, drive, dap.lba);
+        cached_block = CACHE_INVALID;
         return ah;
     }
 
-    cached_sector = lba;
-
-    return 0;
-}
-
-int read_sector(int drive, void *buffer, uint64_t lba, uint64_t count) {
-    while (count--) {
-        int ret;
-        if ((ret = cache_sector(drive, lba++)))
-            return ret;
-
-        memcpy(buffer, sector_buf, SECTOR_SIZE);
-
-        buffer += SECTOR_SIZE;
-    }
+    cached_block = block;
 
     return 0;
 }
@@ -61,30 +53,24 @@ int read_sector(int drive, void *buffer, uint64_t lba, uint64_t count) {
 int read(int drive, void *buffer, uint64_t loc, uint64_t count) {
     uint64_t progress = 0;
     while (progress < count) {
-        uint64_t sect = (loc + progress) / SECTOR_SIZE;
+        uint64_t block = (loc + progress) / BLOCK_SIZE;
 
         int ret;
-        if ((ret = cache_sector(drive, sect)))
+        if ((ret = cache_block(drive, block)))
             return ret;
 
         uint64_t chunk = count - progress;
-        uint64_t offset = (loc + progress) % SECTOR_SIZE;
-        if (chunk > SECTOR_SIZE - offset)
-            chunk = SECTOR_SIZE - offset;
+        uint64_t offset = (loc + progress) % BLOCK_SIZE;
+        if (chunk > BLOCK_SIZE - offset)
+            chunk = BLOCK_SIZE - offset;
 
-        memcpy(buffer + progress, &sector_buf[offset], chunk);
+        memcpy(buffer + progress, &BUFFER_ADDR[offset], chunk);
         progress += chunk;
     }
 
     return 0;
 }
 
-int read_partition(int drive, int partition, void *buffer, uint64_t loc, uint64_t count) {
-    struct mbr_part part;
-    int ret = mbr_get_part(&part, drive, partition);
-    if (ret) {
-        return ret;
-    }
-
-    return read(drive, buffer, loc + (part.first_sect * 512), count);
+int read_partition(int drive, struct mbr_part *part, void *buffer, uint64_t loc, uint64_t count) {
+    return read(drive, buffer, loc + (part->first_sect * 512), count);
 }
diff --git a/src/drivers/disk.h b/src/drivers/disk.h
index 4bce1fb1..e6ed913a 100644
--- a/src/drivers/disk.h
+++ b/src/drivers/disk.h
@@ -1,11 +1,11 @@
-#ifndef __DISK_H__
-#define __DISK_H__
+#ifndef __DRIVERS__DISK_H__
+#define __DRIVERS__DISK_H__
 
 #include <stddef.h>
 #include <stdint.h>
+#include <lib/mbr.h>
 
-int read_sector(int drive, void *buffer, uint64_t lba, uint64_t count);
 int read(int drive, void *buffer, uint64_t loc, uint64_t count);
-int read_partition(int drive, int partition, void *buffer, uint64_t loc, uint64_t count);
+int read_partition(int drive, struct mbr_part *part, void *buffer, uint64_t loc, uint64_t count);
 
 #endif
diff --git a/src/fs/echfs.c b/src/fs/echfs.c
index 1bbf85f7..20c1491f 100644
--- a/src/fs/echfs.c
+++ b/src/fs/echfs.c
@@ -31,8 +31,11 @@ struct echfs_dir_entry {
 #define FILE_TYPE    0
 
 int load_echfs_file(int disk, int partition, void *buffer, const char *filename) {
+    struct mbr_part mbr_part;
+    mbr_get_part(&mbr_part, disk, partition);
+
     struct echfs_identity_table id_table;
-    read_partition(disk, partition, &id_table, 0, sizeof(struct echfs_identity_table));
+    read_partition(disk, &mbr_part, &id_table, 0, sizeof(struct echfs_identity_table));
 
     if (strncmp(id_table.signature, "_ECH_FS_", 8)) {
         print("echfs: signature invalid\n", filename);
@@ -49,7 +52,7 @@ int load_echfs_file(int disk, int partition, void *buffer, const char *filename)
     // Find the file in the root dir.
     struct echfs_dir_entry entry;
     for (uint64_t i = 0; i < dir_length; i += sizeof(struct echfs_dir_entry)) {
-        read_partition(disk, partition, &entry, i + dir_offset, sizeof(struct echfs_dir_entry));
+        read_partition(disk, &mbr_part, &entry, i + dir_offset, sizeof(struct echfs_dir_entry));
 
         if (!entry.parent_id) {
             break;
@@ -67,11 +70,11 @@ found:;
     // Load the file.
     for (uint64_t i = entry.payload; i != END_OF_CHAIN;) {
         // Read block.
-        read_partition(disk, partition, buffer, i * block_size, block_size);
+        read_partition(disk, &mbr_part, buffer, i * block_size, block_size);
         buffer += block_size;
 
         // Read the next block.
-        read_partition(disk, partition, &i, alloc_table_offset + i * sizeof(uint64_t), sizeof(uint64_t));
+        read_partition(disk, &mbr_part, &i, alloc_table_offset + i * sizeof(uint64_t), sizeof(uint64_t));
     }
 
     return 0;
diff --git a/src/fs/echfs.h b/src/fs/echfs.h
index 1132ecd5..7323e470 100644
--- a/src/fs/echfs.h
+++ b/src/fs/echfs.h
@@ -1,5 +1,5 @@
-#ifndef __ECHFS_H__
-#define __ECHFS_H__
+#ifndef __FS__ECHFS_H__
+#define __FS__ECHFS_H__
 
 int load_echfs_file(int disk, int partition, void *buffer, const char *filename);
 
tab: 248 wrap: offon