diff options
Diffstat (limited to 'src/kernel/arch')
-rw-r--r-- | src/kernel/arch/amd64/ata.c | 10 | ||||
-rw-r--r-- | src/kernel/arch/amd64/ata.h | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/pata.c | 21 |
3 files changed, 23 insertions, 12 deletions
diff --git a/src/kernel/arch/amd64/ata.c b/src/kernel/arch/amd64/ata.c index 5c5fc57..d88f890 100644 --- a/src/kernel/arch/amd64/ata.c +++ b/src/kernel/arch/amd64/ata.c @@ -23,8 +23,6 @@ enum { CMD = 7, STATUS = 7, - /* note: the OSDev wiki uses a different base port for the control port - * however i can just use this offset and stuff will just work tm */ CTRL = 0x206, }; // offsets @@ -40,11 +38,11 @@ static void ata_400ns(void) { port_in8(base + STATUS); } -static void ata_driveselect(int drive, int block) { +static void ata_driveselect(int drive, int lba) { uint8_t v = 0xE0; if (drive&1) // slave? v |= 0x10; // set drive number bit - // TODO account for block + v |= (lba >> 24) & 0xf; port_out8(ata_iobase(drive) + DRV, v); } @@ -124,6 +122,10 @@ bool ata_available(int drive) { return ata_drives[drive].type != DEV_UNKNOWN; } +size_t ata_size(int drive) { + return ata_drives[drive].sectors * ATA_SECTOR; +} + int ata_read(int drive, uint32_t lba, void *buf) { if (ata_drives[drive].type != DEV_PATA) panic_unimplemented(); diff --git a/src/kernel/arch/amd64/ata.h b/src/kernel/arch/amd64/ata.h index 82f4f81..0c20281 100644 --- a/src/kernel/arch/amd64/ata.h +++ b/src/kernel/arch/amd64/ata.h @@ -1,7 +1,11 @@ #pragma once #include <stdbool.h> +#include <stddef.h> #include <stdint.h> +#define ATA_SECTOR 512 + void ata_init(void); bool ata_available(int drive); +size_t ata_size(int drive); int ata_read(int drive, uint32_t lba, void *buf); diff --git a/src/kernel/arch/amd64/driver/pata.c b/src/kernel/arch/amd64/driver/pata.c index b4ec46c..1193add 100644 --- a/src/kernel/arch/amd64/driver/pata.c +++ b/src/kernel/arch/amd64/driver/pata.c @@ -1,4 +1,5 @@ #include <camellia/errno.h> +#include <camellia/fsutil.h> #include <kernel/arch/amd64/ata.h> #include <kernel/arch/amd64/driver/pata.h> #include <kernel/arch/amd64/driver/util.h> @@ -53,22 +54,26 @@ static void accept(struct vfs_request *req) { vfsreq_finish_short(req, req_readcopy(req, list, len)); break; } - // TODO ata size get - if (req->offset < 0) { - vfsreq_finish_short(req, -ENOSYS); - break; - } + fs_normslice(&req->offset, &req->output.len, ata_size(id), false); + char buf[512]; /* stupid */ - uint32_t sector = req->offset / 512; - size_t len = min(req->output.len, 512 - ((size_t)req->offset & 511)); + uint32_t sector = req->offset / ATA_SECTOR; + size_t skip = (size_t)req->offset & (ATA_SECTOR - 1); + size_t len = min(req->output.len, ATA_SECTOR - skip); ata_read(id, sector, buf); - virt_cpy_to(req->caller->pages, req->output.buf, buf, len); + virt_cpy_to(req->caller->pages, req->output.buf, buf + skip, len); vfsreq_finish_short(req, len); break; case VFSOP_WRITE: panic_unimplemented(); + case VFSOP_GETSIZE: + if (id == root_id) + panic_unimplemented(); + vfsreq_finish_short(req, ata_size(id)); + break; + default: vfsreq_finish_short(req, -ENOSYS); break; |