diff --git a/.gitignore b/.gitignore index 46d0d9b..7a0242b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ bochs-com1.txt mop3dist.tar mop3dist.tar.lz4 site/ +*.img diff --git a/kernel/amd64/intr_defs.h b/kernel/amd64/intr_defs.h index af19eb6..8da1fa4 100644 --- a/kernel/amd64/intr_defs.h +++ b/kernel/amd64/intr_defs.h @@ -2,6 +2,8 @@ #define _KERNEL_AMD64_INTR_DEFS_H #define PS2KB 32 +#define IDE_DRIVE_PRIM 33 +#define IDE_DRIVE_SCND 34 #define SCHED_PREEMPT_TIMER 80 #define CPU_REQUEST_SCHED 82 diff --git a/kernel/amd64/intr_stub.S b/kernel/amd64/intr_stub.S index 0d3347f..cd5c565 100644 --- a/kernel/amd64/intr_stub.S +++ b/kernel/amd64/intr_stub.S @@ -26,7 +26,8 @@ ; \ movq %rsp, %rdi; \ ; \ - movq %cr3, %rax; pushq %rax; \ + movq %cr3, %rax; \ + pushq %rax; \ ; \ movq %rsp, %rbp; \ ; \ @@ -36,7 +37,8 @@ ; \ movq %rbp, %rsp; \ ; \ - popq %rax; movq %rax, %cr3; \ + popq %rax; \ + movq %rax, %cr3; \ ; \ pop_regs; \ addq $16, %rsp; \ diff --git a/kernel/amd64/syscallentry.S b/kernel/amd64/syscallentry.S index 2c63ebd..f707167 100644 --- a/kernel/amd64/syscallentry.S +++ b/kernel/amd64/syscallentry.S @@ -28,7 +28,8 @@ syscall_entry: movq %rsp, %rdi - movq %cr3, %rax; pushq %rax + movq %cr3, %rax + pushq %rax movq %rsp, %rbp @@ -38,7 +39,8 @@ syscall_entry: movq %rbp, %rsp - popq %rbx; movq %rbx, %cr3 + popq %rbx + movq %rbx, %cr3 pop_regs_skip_rax diff --git a/kernel/device/debugconsole.c b/kernel/device/debugconsole.c index 213766f..2bc4238 100644 --- a/kernel/device/debugconsole.c +++ b/kernel/device/debugconsole.c @@ -6,12 +6,14 @@ #include #include -bool debugconsole_init (struct device* device, void* arg) { - (void)device, (void)arg; +bool debugconsole_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + (void)device, (void)arg, (void)proc, (void)rctx; return true; } -void debugconsole_fini (struct device* device) { (void)device; } +void debugconsole_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { + (void)device, (void)proc, (void)rctx; +} int debugconsole_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { diff --git a/kernel/device/debugconsole.h b/kernel/device/debugconsole.h index 25f883f..56a3bae 100644 --- a/kernel/device/debugconsole.h +++ b/kernel/device/debugconsole.h @@ -7,9 +7,9 @@ struct device; -bool debugconsole_init (struct device* device, void* arg); +bool debugconsole_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -void debugconsole_fini (struct device* device); +void debugconsole_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); int debugconsole_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); diff --git a/kernel/device/device.c b/kernel/device/device.c index 6008e92..667a2f0 100644 --- a/kernel/device/device.c +++ b/kernel/device/device.c @@ -49,7 +49,8 @@ struct device* device_find (const char* key) { } struct device* device_create (const char* key, device_op_func_t* ops, size_t ops_len, - device_init_func_t init, device_fini_func_t fini, void* arg) { + device_init_func_t init, device_fini_func_t fini, void* arg, + struct proc* proc, struct reschedule_ctx* rctx) { if (ops_len >= fieldlengthof (struct device, ops)) return NULL; @@ -67,7 +68,7 @@ struct device* device_create (const char* key, device_op_func_t* ops, size_t ops if (ops != NULL) memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t)); - if (!device->init (device, arg)) { + if (!device->init (device, arg, proc, rctx)) { free (device); return NULL; } @@ -87,21 +88,30 @@ struct device* device_create (const char* key, device_op_func_t* ops, size_t ops } static void debugconsole_device_init (void) { + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + device_op_func_t ops[] = { [DEBUGCONSOLE_PUTSTR] = &debugconsole_putstr, }; - device_create ("DEBUGCONSOLE", ops, lengthof (ops), &debugconsole_init, &debugconsole_fini, NULL); + device_create ("DEBUGCONSOLE", ops, lengthof (ops), &debugconsole_init, &debugconsole_fini, NULL, thiscpu->kproc, &rctx); } static void terminal_device_init (void) { + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + device_op_func_t ops[] = { [TERMINAL_PUTSTR] = &terminal_putstr, [TERMINAL_DIMENSIONS] = &terminal_dimensions, }; - device_create ("TERMINAL", ops, lengthof (ops), &terminal_init, &terminal_fini, NULL); + device_create ("TERMINAL", ops, lengthof (ops), &terminal_init, &terminal_fini, NULL, thiscpu->kproc, &rctx); } static void ramdisk_device_init (void) { + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + device_op_func_t ops[] = { [XDRV_GET_SIZE] = &ramdrv_get_size, [XDRV_GET_SECTOR_SIZE] = &ramdrv_get_sector_size, @@ -139,12 +149,15 @@ static void ramdisk_device_init (void) { .sector_size = 512, .buffer = unpack_buffer, }; - device_create ("RD0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init); + device_create ("RD0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init, thiscpu->kproc, &rctx); LZ4F_freeDecompressionContext (dctx); } static void temp_device_init (void) { + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + device_op_func_t ops[] = { [XDRV_GET_SIZE] = &ramdrv_get_size, [XDRV_GET_SECTOR_SIZE] = &ramdrv_get_sector_size, @@ -157,15 +170,18 @@ static void temp_device_init (void) { .total_size = 1024 * 1024 * 20, .sector_size = 512, }; - device_create ("TEMP0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init); + device_create ("TEMP0", ops, lengthof (ops), &ramdrv_init, &ramdrv_fini, &init, thiscpu->kproc, &rctx); } #if defined(__x86_64__) static void ps2kb_device_init (void) { + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + device_op_func_t ops[] = { [KB_READ_KEY] = &ps2kb_read_key, }; - device_create ("KB", ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL); + device_create ("KB", ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL, thiscpu->kproc, &rctx); } #endif diff --git a/kernel/device/device.h b/kernel/device/device.h index 533bd88..8263afb 100644 --- a/kernel/device/device.h +++ b/kernel/device/device.h @@ -22,8 +22,8 @@ struct device; typedef int (*device_op_func_t) (struct device* device, struct proc*, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); -typedef bool (*device_init_func_t) (struct device* device, void* arg); -typedef void (*device_fini_func_t) (struct device* device); +typedef bool (*device_init_func_t) (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); +typedef void (*device_fini_func_t) (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); struct device { char key[0x100]; @@ -36,7 +36,8 @@ struct device { }; struct device* device_create (const char* key, device_op_func_t* ops, size_t ops_len, - device_init_func_t init, device_fini_func_t fini, void* arg); + device_init_func_t init, device_fini_func_t fini, void* arg, + struct proc* proc, struct reschedule_ctx* rctx); struct device* device_find (const char* key); diff --git a/kernel/device/idedrv.c b/kernel/device/idedrv.c index 00703dd..10a876e 100644 --- a/kernel/device/idedrv.c +++ b/kernel/device/idedrv.c @@ -1,13 +1,18 @@ #include +#include +#include #include #include #include #include #include +#include +#include #include #include #include #include +#include #define IDE_REG_DATA 0x00 #define IDE_REG_ERROR 0x01 @@ -78,6 +83,75 @@ static void ide_delay (uint16_t ctrl) { } #pragma clang optimize on +static void ide_flush (struct idedrv* idedrv) { + if (idedrv->lba48) + outb (idedrv->io + IDE_REG_CMD, IDE_CMD_FLUSH48); + else + outb (idedrv->io + IDE_REG_CMD, IDE_CMD_FLUSH28); +} + +static void ide_irq (void* arg, void* regs, struct reschedule_ctx* rctx) { + struct idedrv* idedrv = arg; + + spin_lock (&idedrv->device->lock); + + struct list_node_link* node = idedrv->requests; + + if (node == NULL) { + (void)inb (idedrv->io + IDE_REG_STATUS); + spin_unlock (&idedrv->device->lock); + return; + } + + struct idedrv_request* req = list_entry (node, struct idedrv_request, requests_link); + struct list_node_link* sqlist_node = req->sq.proc_list; + struct proc_sq_entry* sq_entry = list_entry (sqlist_node, struct proc_sq_entry, sq_link); + struct proc* resumed_proc = sq_entry->proc; + + uint8_t status = inb (idedrv->io + IDE_REG_STATUS); + + if ((status & (IDE_ERR | IDE_DRQ))) { + list_remove (idedrv->requests, &req->requests_link); + spin_unlock (&idedrv->device->lock); + proc_sq_resume (resumed_proc, sq_entry, rctx); + free (req); + return; + } + + spin_lock (&resumed_proc->lock); + + if (req->rw == 1) { + if ((status & IDE_DRQ)) { + uint16_t* p = req->outbuffer + (req->sector_done_count * (idedrv->sector_size / 2)); + insw (idedrv->io + IDE_REG_DATA, p, idedrv->sector_size / 2); + req->sector_done_count++; + } + } else if (req->rw == 2) { + req->sector_done_count++; + if (req->sector_done_count < req->sector_count) { + uint16_t* p = req->outbuffer + (req->sector_done_count * (idedrv->sector_size / 2)); + outsw (idedrv->io + IDE_REG_DATA, p, idedrv->sector_size / 2); + } + } + + if (req->sector_done_count >= req->sector_count) { + if (req->rw == 2) + ide_flush (idedrv); + + list_remove (idedrv->requests, &req->requests_link); + + spin_unlock (&resumed_proc->lock); + spin_unlock (&idedrv->device->lock); + + free (req); + proc_sq_resume (resumed_proc, sq_entry, rctx); + return; + } + + spin_unlock (&resumed_proc->lock); + spin_unlock (&idedrv->device->lock); +} + void ide_probe (uint16_t io, uint16_t ctrl, uint8_t devno, struct ide_probe* probe) { probe->flags = 0; probe->sector_count = 0; @@ -141,7 +215,10 @@ void ide_probe (uint16_t io, uint16_t ctrl, uint8_t devno, struct ide_probe* pro probe->sector_size = 512; } -static void ide_prepare (struct idedrv* idedrv, size_t sector, uint16_t sector_count) { +static void ide_prepare (struct idedrv* idedrv, size_t sector, uint16_t sector_count, bool clear) { + if (clear) + outb (idedrv->ctrl, 0x00); + if (idedrv->lba48) { outb (idedrv->io + IDE_REG_DRIVE, 0x40 | (idedrv->devno << 4)); ide_delay (idedrv->ctrl); @@ -167,7 +244,9 @@ static void ide_prepare (struct idedrv* idedrv, size_t sector, uint16_t sector_c } } -bool idedrv_init (struct device* device, void* arg) { +bool idedrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + (void)proc, (void)rctx; + struct idedrv_init* init = arg; struct idedrv* idedrv = malloc (sizeof (*idedrv)); @@ -175,23 +254,41 @@ bool idedrv_init (struct device* device, void* arg) { if (idedrv == NULL) return false; + idedrv->device = device; idedrv->lba48 = init->lba48; idedrv->sector_count = init->sector_count; idedrv->sector_size = init->sector_size; idedrv->io = init->io; idedrv->ctrl = init->ctrl; idedrv->devno = init->devno; + idedrv->primscnd = init->primscnd; device->udata = idedrv; - device_probe_partitions (device); + if (idedrv->primscnd == 1) { + ioapic_route_irq (IDE_DRIVE_PRIM, 14, 0, thiscpu->lapic_id); + irq_attach (&ide_irq, idedrv, IDE_DRIVE_PRIM); + } else if (idedrv->primscnd == 2) { + ioapic_route_irq (IDE_DRIVE_SCND, 15, 0, thiscpu->lapic_id); + irq_attach (&ide_irq, idedrv, IDE_DRIVE_SCND); + } return true; } -void idedrv_fini (struct device* device) { +void idedrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { struct idedrv* idedrv = device->udata; + struct list_node_link* req_link, *tmp_req_link; + list_foreach (idedrv->requests, req_link, tmp_req_link) { + struct idedrv_request* req = list_entry (req_link, struct idedrv_request, requests_link); + list_remove (idedrv->requests, &req->requests_link); + struct proc_sq_entry* sq_entry = list_entry (req->sq.proc_list, struct proc_sq_entry, sq_link); + proc_sq_resume (proc, sq_entry, rctx); + free (req); + } + + irq_detach (idedrv->primscnd == 1 ? IDE_DRIVE_PRIM : IDE_DRIVE_SCND); free (idedrv); } @@ -211,20 +308,47 @@ int idedrv_read (struct device* device, struct proc* proc, struct reschedule_ctx if (sector + sector_count > idedrv->sector_count) return -ST_OOB_ERROR; - ide_prepare (idedrv, sector, sector_count); + spin_lock (&proc->lock); + bool is_kproc = (proc->flags & PROC_KPROC) != 0; + spin_unlock (&proc->lock); - uint8_t cmd = idedrv->lba48 ? IDE_CMD_READ48 : IDE_CMD_READ28; - outb (idedrv->io + IDE_REG_CMD, cmd); + /* /1* polling *1/ */ + /* if (is_kproc) { */ + ide_prepare (idedrv, sector, sector_count, false); - for (uint16_t s = 0; s < sector_count; s++) { - if (!ide_wait (idedrv->io, 100000, true, true)) - return -ST_XDRV_READ_ERROR; + uint8_t cmd = idedrv->lba48 ? IDE_CMD_READ48 : IDE_CMD_READ28; + outb (idedrv->io + IDE_REG_CMD, cmd); - insw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), - idedrv->sector_size / 2); - } + for (uint16_t s = 0; s < sector_count; s++) { + if (!ide_wait (idedrv->io, 100000, true, true)) + return -ST_XDRV_READ_ERROR; - return ST_OK; + insw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), (idedrv->sector_size / 2)); + } + + return ST_OK; + /* } else { /1* IRQ *1/ */ + /* struct idedrv_request* req = malloc (sizeof (*req)); */ + + /* if (req == NULL) */ + /* return -ST_OOM_ERROR; */ + + /* memset (req, 0, sizeof (*req)); */ + /* req->outbuffer = buffer; */ + /* req->sector_count = sector_count; */ + /* req->sector_done_count = 0; */ + /* req->rw = 1; */ + + /* list_append (idedrv->requests, &req->requests_link); */ + /* proc_sq_suspend (proc, &req->sq, NULL, rctx); */ + + /* ide_prepare (idedrv, sector, sector_count, true); */ + + /* uint8_t cmd = idedrv->lba48 ? IDE_CMD_READ48 : IDE_CMD_READ28; */ + /* outb (idedrv->io + IDE_REG_CMD, cmd); */ + + /* return ST_OK; */ + /* } */ } int idedrv_write (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, @@ -242,25 +366,58 @@ int idedrv_write (struct device* device, struct proc* proc, struct reschedule_ct if (sector + sector_count > idedrv->sector_count) return -ST_OOB_ERROR; + + spin_lock (&proc->lock); + bool is_kproc = (proc->flags & PROC_KPROC) != 0; + spin_unlock (&proc->lock); - ide_prepare (idedrv, sector, sector_count); + /* /1* polling *1/ */ + /* if (is_kproc) { */ + ide_prepare (idedrv, sector, sector_count, false); - uint8_t cmd = idedrv->lba48 ? IDE_CMD_WRITE48 : IDE_CMD_WRITE28; - outb (idedrv->io + IDE_REG_CMD, cmd); + uint8_t cmd = idedrv->lba48 ? IDE_CMD_WRITE48 : IDE_CMD_WRITE28; + outb (idedrv->io + IDE_REG_CMD, cmd); - for (uint16_t s = 0; s < sector_count; s++) { - if (!ide_wait (idedrv->io, 100000, true, true)) - return -ST_XDRV_WRITE_ERROR; + for (uint16_t s = 0; s < sector_count; s++) { + if (!ide_wait (idedrv->io, 100000, true, true)) + return -ST_XDRV_WRITE_ERROR; - outsw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), - idedrv->sector_size / 2); - } + outsw (idedrv->io + IDE_REG_DATA, buffer + (s * (idedrv->sector_size / 2)), (idedrv->sector_size / 2)); + } - cmd = idedrv->lba48 ? IDE_CMD_FLUSH48 : IDE_CMD_FLUSH28; - outb (idedrv->io + IDE_REG_CMD, cmd); - ide_wait (idedrv->io, 100000, false, true); + return ST_OK; + /* } else { /1* IRQ *1/ */ + /* struct idedrv_request* req = malloc (sizeof (*req)); */ - return ST_OK; + /* if (req == NULL) */ + /* return -ST_OOM_ERROR; */ + + /* memset (req, 0, sizeof (*req)); */ + /* req->outbuffer = buffer; */ + /* req->sector_count = sector_count; */ + /* req->sector_done_count = 0; */ + /* req->rw = 2; */ + + /* list_append (idedrv->requests, &req->requests_link); */ + /* proc_sq_suspend (proc, &req->sq, NULL, rctx); */ + + /* ide_prepare (idedrv, sector, sector_count, true); */ + + /* uint8_t cmd = idedrv->lba48 ? IDE_CMD_WRITE48 : IDE_CMD_WRITE28; */ + /* outb (idedrv->io + IDE_REG_CMD, cmd); */ + + /* if (!ide_wait (idedrv->io, 100000, true, true)) { */ + /* list_remove (idedrv->requests, &req->requests_link); */ + /* struct proc_sq_entry* sq_entry = list_entry (req->sq.proc_list, struct proc_sq_entry, sq_link); */ + /* proc_sq_resume (proc, sq_entry, rctx); */ + /* free (req); */ + /* return -ST_XDRV_WRITE_ERROR; */ + /* } */ + + /* outsw (idedrv->io + IDE_REG_DATA, buffer, idedrv->sector_size / 2); */ + + /* return ST_OK; */ + /* } */ } int idedrv_get_device_type (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, diff --git a/kernel/device/idedrv.h b/kernel/device/idedrv.h index d6311f2..48298dc 100644 --- a/kernel/device/idedrv.h +++ b/kernel/device/idedrv.h @@ -2,8 +2,11 @@ #define _KERNEL_DEVICE_IDEDRV_H #include +#include #include #include +#include +#include #define IDE_PROBE_AVAIL (1 << 0) #define IDE_PROBE_LBA48 (1 << 1) @@ -16,14 +19,28 @@ struct idedrv_init { size_t sector_size; uint16_t io, ctrl; uint8_t devno; + uint8_t primscnd; +}; + +struct idedrv_request { + uint16_t* outbuffer; + size_t sector_done_count; + size_t sector_count; + struct list_node_link requests_link; + struct proc_suspension_q sq; + int rw; }; struct idedrv { + struct device* device; bool lba48; size_t sector_count; size_t sector_size; uint16_t io, ctrl; uint8_t devno; + uint8_t primscnd; + + struct list_node_link* requests; }; struct ide_probe { @@ -32,11 +49,12 @@ struct ide_probe { size_t sector_size; uint16_t io, ctrl; uint8_t devno; + uint8_t primscnd; }; -bool idedrv_init (struct device* device, void* arg); +bool idedrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -void idedrv_fini (struct device* device); +void idedrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); int idedrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); diff --git a/kernel/device/partdrv.c b/kernel/device/partdrv.c index bbd63f7..8a36f4e 100644 --- a/kernel/device/partdrv.c +++ b/kernel/device/partdrv.c @@ -7,7 +7,9 @@ #include #include -bool partdrv_init (struct device* device, void* arg) { +bool partdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + (void)proc, (void)rctx; + struct partdrv_init* init = arg; struct partdrv* partdrv = malloc (sizeof (*partdrv)); @@ -24,7 +26,8 @@ bool partdrv_init (struct device* device, void* arg) { return true; } -void partdrv_fini (struct device* device) { +void partdrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { + (void)proc, (void)rctx; struct partdrv* partdrv = device->udata; free (partdrv); @@ -45,7 +48,7 @@ int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ct uint8_t* buffer = a3; spin_lock (&super->lock); - int ret = device_op (super, XDRV_READ, NULL, NULL, §or, §or_count, buffer); + int ret = device_op (super, XDRV_READ, proc, rctx, §or, §or_count, buffer); spin_unlock (&super->lock); return ret; @@ -66,7 +69,7 @@ int partdrv_write (struct device* device, struct proc* proc, struct reschedule_c uint8_t* buffer = a3; spin_lock (&super->lock); - int ret = device_op (super, XDRV_WRITE, NULL, NULL, §or, §or_count, buffer); + int ret = device_op (super, XDRV_WRITE, proc, rctx, §or, §or_count, buffer); spin_unlock (&super->lock); return ret; @@ -98,7 +101,7 @@ int partdrv_get_sector_size (struct device* device, struct proc* proc, struct re struct partdrv* partdrv = device->udata; spin_lock (&partdrv->super->lock); - device_op (partdrv->super, XDRV_GET_SECTOR_SIZE, NULL, NULL, secsize); + device_op (partdrv->super, XDRV_GET_SECTOR_SIZE, proc, rctx, secsize); spin_unlock (&partdrv->super->lock); return ST_OK; diff --git a/kernel/device/partdrv.h b/kernel/device/partdrv.h index 7165f34..e0229c3 100644 --- a/kernel/device/partdrv.h +++ b/kernel/device/partdrv.h @@ -19,9 +19,9 @@ struct partdrv { size_t total_size; }; -bool partdrv_init (struct device* device, void* arg); +bool partdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -void partdrv_fini (struct device* device); +void partdrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); int partdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); diff --git a/kernel/device/partitions.c b/kernel/device/partitions.c index 4565f4f..ea10500 100644 --- a/kernel/device/partitions.c +++ b/kernel/device/partitions.c @@ -9,8 +9,10 @@ #include #include #include +#include +#include -static int device_probe_partitions_dos (struct device* device) { +static int device_probe_partitions_dos (struct proc* proc, struct reschedule_ctx* rctx, struct device* device) { struct dos_mbr mbr; memset (&mbr, 0, sizeof (mbr)); size_t sector = 0; @@ -27,9 +29,9 @@ static int device_probe_partitions_dos (struct device* device) { spin_lock (&device->lock); - device_op (device, XDRV_GET_SECTOR_SIZE, NULL, NULL, §or_size); + device_op (device, XDRV_GET_SECTOR_SIZE, proc, rctx, §or_size); - int ret = device_op (device, XDRV_READ, NULL, NULL, §or, §or_count, &mbr); + int ret = device_op (device, XDRV_READ, proc, rctx, §or, §or_count, &mbr); if (ret < 0) { spin_unlock (&device->lock); @@ -54,7 +56,7 @@ static int device_probe_partitions_dos (struct device* device) { memset (key, 0, sizeof (key)); snprintf (key, sizeof (key), "%sp%zu", device->key, i); - device_create (key, ops, lengthof (ops), &partdrv_init, &partdrv_fini, &init); + device_create (key, ops, lengthof (ops), &partdrv_init, &partdrv_fini, &init, proc, rctx); } spin_unlock (&device->lock); @@ -62,4 +64,4 @@ static int device_probe_partitions_dos (struct device* device) { return ST_OK; } -int device_probe_partitions (struct device* device) { return device_probe_partitions_dos (device); } +int device_probe_partitions (struct proc* proc, struct reschedule_ctx* rctx, struct device* device) { return device_probe_partitions_dos (proc, rctx, device); } diff --git a/kernel/device/partitions.h b/kernel/device/partitions.h index 7883613..d738e92 100644 --- a/kernel/device/partitions.h +++ b/kernel/device/partitions.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include struct dos_pte { uint8_t drive_attrs; @@ -22,6 +24,6 @@ struct dos_mbr { uint8_t valid_sign[2]; } PACKED; -int device_probe_partitions (struct device* device); +int device_probe_partitions (struct proc* proc, struct reschedule_ctx* rctx, struct device* device); #endif // _KERNEL_DEVICE_PARTITIONS_H diff --git a/kernel/device/pci.c b/kernel/device/pci.c index 9ffc503..a30c153 100644 --- a/kernel/device/pci.c +++ b/kernel/device/pci.c @@ -4,8 +4,10 @@ #include #include #include +#include #include #include +#include static const struct pci_driver_info pci_driver_infos[] = { {.class = 0x01, .subclass = 0x01, .init = &pci_ide_init}, @@ -91,9 +93,9 @@ void pci_write8 (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset, uint8_ spin_unlock (&pci_lock); } -static void pci_check_bus (uint8_t bus, pci_cb_func_t cb); +static void pci_check_bus (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, pci_cb_func_t cb); -static void pci_check_func (uint8_t bus, uint8_t slot, uint8_t func, pci_cb_func_t cb) { +static void pci_check_func (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, uint8_t slot, uint8_t func, pci_cb_func_t cb) { uint32_t reg0 = pci_read32 (bus, slot, func, PCI_VENDOR_ID); uint16_t vendor = (uint16_t)(reg0 & 0xFFFF); @@ -112,47 +114,47 @@ static void pci_check_func (uint8_t bus, uint8_t slot, uint8_t func, pci_cb_func .subclass = ((uint8_t)(reg8 >> 16)), }; - cb (pci_info); + cb (proc, rctx, pci_info); /* PCI 2 PCI bridge */ if (pci_info.class == 0x06 && pci_info.subclass == 0x04) { uint32_t reg18 = pci_read32 (bus, slot, func, 0x18); uint8_t secondary = (uint8_t)(reg18 >> 8); - pci_check_bus (secondary, cb); + pci_check_bus (proc, rctx, secondary, cb); } } -static void pci_check_device (uint8_t bus, uint8_t slot, pci_cb_func_t cb) { +static void pci_check_device (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, uint8_t slot, pci_cb_func_t cb) { uint32_t reg0 = pci_read32 (bus, slot, 0, PCI_VENDOR_ID); if ((uint16_t)(reg0 & 0xFFFF) == 0xFFFF) return; - pci_check_func (bus, slot, 0, cb); + pci_check_func (proc, rctx, bus, slot, 0, cb); /* multifunc device */ uint32_t reg0xc = pci_read32 (bus, slot, 0, PCI_CACHELINE); if ((reg0xc >> 16) & 0x80) { for (uint8_t func = 1; func < 8; func++) - pci_check_func (bus, slot, func, cb); + pci_check_func (proc, rctx, bus, slot, func, cb); } } -static void pci_check_bus (uint8_t bus, pci_cb_func_t cb) { +static void pci_check_bus (struct proc* proc, struct reschedule_ctx* rctx, uint8_t bus, pci_cb_func_t cb) { for (uint8_t slot = 0; slot < 32; slot++) - pci_check_device (bus, slot, cb); + pci_check_device (proc, rctx, bus, slot, cb); } -static void pci_enumerate (pci_cb_func_t cb) { +static void pci_enumerate (struct proc* proc, struct reschedule_ctx* rctx, pci_cb_func_t cb) { uint32_t reg0xc = pci_read32 (0, 0, 0, PCI_CACHELINE); bool is_multictrl = (reg0xc >> 16) & 0x80; if (!is_multictrl) - pci_check_bus (0, cb); + pci_check_bus (proc, rctx, 0, cb); else { for (uint8_t func = 0; func < 8; func++) { if ((pci_read32 (0, 0, func, PCI_VENDOR_ID) & 0xFFFF) != 0xFFFF) - pci_check_bus (func, cb); + pci_check_bus (proc, rctx, func, cb); } } } @@ -186,7 +188,7 @@ static void pci_string_identifiers (uint16_t vendor_id, uint16_t device_id, uint } } -static void pci_discovery_cb (struct pci_info pci_info) { +static void pci_discovery_cb (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info) { const char *vname, *dname, *cname; pci_string_identifiers (pci_info.vendor, pci_info.device, pci_info.class, pci_info.subclass, &vname, &dname, &cname); @@ -198,9 +200,14 @@ static void pci_discovery_cb (struct pci_info pci_info) { for (size_t driver = 0; driver < lengthof (pci_driver_infos); driver++) { if (pci_driver_infos[driver].class == pci_info.class && pci_driver_infos[driver].subclass == pci_info.subclass) { - pci_driver_infos[driver].init (pci_info); + pci_driver_infos[driver].init (proc, rctx, pci_info); } } } -void pci_init (void) { pci_enumerate (&pci_discovery_cb); } +void pci_init (void) { + struct reschedule_ctx rctx; + memset (&rctx, 0, sizeof (rctx)); + + pci_enumerate (thiscpu->kproc, &rctx, &pci_discovery_cb); +} diff --git a/kernel/device/pci.h b/kernel/device/pci.h index a8bc7b2..b88e21c 100644 --- a/kernel/device/pci.h +++ b/kernel/device/pci.h @@ -3,6 +3,8 @@ #include #include +#include +#include #define PCI_CONFIG_ADDR 0xCF8 #define PCI_CONFIG_DATA 0xCFC @@ -53,10 +55,10 @@ struct pci_class { struct pci_driver_info { uint8_t class; uint8_t subclass; - bool (*init) (struct pci_info pci_info); + bool (*init) (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info); }; -typedef void (*pci_cb_func_t) (struct pci_info pci_info); +typedef void (*pci_cb_func_t) (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info); void pci_init (void); diff --git a/kernel/device/pci_ide.c b/kernel/device/pci_ide.c index b4bfbb9..510587f 100644 --- a/kernel/device/pci_ide.c +++ b/kernel/device/pci_ide.c @@ -3,12 +3,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include static atomic_int ide_counter = 0; @@ -27,7 +30,7 @@ static const char* progif_msg[] = { "PCI native mode controller, supports both channels switched to ISA compatibility mode, supports bus mastering", }; -static void ide_make_device (struct ide_probe probe) { +static void ide_make_device (struct proc* proc, struct reschedule_ctx* rctx, struct ide_probe probe) { DEBUG ("Found IDE drive: io=%x ctrl=%x no=%u sector=%zu count=%zu\n", probe.io, probe.ctrl, probe.devno, probe.sector_size, probe.sector_count); @@ -49,14 +52,16 @@ static void ide_make_device (struct ide_probe probe) { .io = probe.io, .ctrl = probe.ctrl, .devno = probe.devno, + .primscnd = probe.primscnd, }; - device_create (device_key, ops, lengthof (ops), &idedrv_init, &idedrv_fini, &init); + struct device* ide = device_create (device_key, ops, lengthof (ops), &idedrv_init, &idedrv_fini, &init, proc, rctx); + device_probe_partitions (proc, rctx, ide); } -bool pci_ide_init (struct pci_info pci_info) { +bool pci_ide_init (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info) { uint16_t pci_cmd = pci_read16 (pci_info.bus, pci_info.slot, pci_info.func, PCI_COMMAND); - uint16_t new_cmd = pci_cmd | (1 << 0); + uint16_t new_cmd = (pci_cmd | (1 << 0)) & ~(1 << 10); if (pci_cmd != new_cmd) { pci_write16 (pci_info.bus, pci_info.slot, pci_info.func, PCI_COMMAND, new_cmd); @@ -116,11 +121,13 @@ bool pci_ide_init (struct pci_info pci_info) { if (cmd == 0) continue; + probe.primscnd = i + 1; + for (size_t dev = 0; dev < 2; dev++) { ide_probe (cmd, ctrl, dev, &probe); if ((probe.flags & IDE_PROBE_AVAIL)) - ide_make_device (probe); + ide_make_device (proc, rctx, probe); } } diff --git a/kernel/device/pci_ide.h b/kernel/device/pci_ide.h index 573700a..855ecd0 100644 --- a/kernel/device/pci_ide.h +++ b/kernel/device/pci_ide.h @@ -3,7 +3,9 @@ #include #include +#include +#include -bool pci_ide_init (struct pci_info pci_info); +bool pci_ide_init (struct proc* proc, struct reschedule_ctx* rctx, struct pci_info pci_info); #endif // _KERNEL_DEVICE_PCI_IDE_H diff --git a/kernel/device/ps2_kb.c b/kernel/device/ps2_kb.c index 6ba1f66..3bfd244 100644 --- a/kernel/device/ps2_kb.c +++ b/kernel/device/ps2_kb.c @@ -229,8 +229,8 @@ static void ps2kb_set_typematic (uint8_t delay, uint8_t rate) { outb (KB_DATA, (delay << 5) | (rate & 0x1F)); } -bool ps2kb_init (struct device* device, void* arg) { - (void)device, (void)arg; +bool ps2kb_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + (void)device, (void)arg, (void)proc, (void)rctx; ioapic_route_irq (PS2KB, 1, 0, thiscpu->lapic_id); irq_attach (&ps2kb_irq, NULL, PS2KB); @@ -255,8 +255,8 @@ bool ps2kb_init (struct device* device, void* arg) { return true; } -void ps2kb_fini (struct device* device) { - (void)device; +void ps2kb_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { + (void)device, (void)proc, (void)rctx; irq_detach (PS2KB); ringbuffer_fini (&ps2kb_ringbuffer); diff --git a/kernel/device/ps2_kb.h b/kernel/device/ps2_kb.h index ae59661..5d85a9b 100644 --- a/kernel/device/ps2_kb.h +++ b/kernel/device/ps2_kb.h @@ -11,8 +11,8 @@ struct device; int ps2kb_read_key (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); -bool ps2kb_init (struct device* device, void* arg); +bool ps2kb_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -void ps2kb_fini (struct device* device); +void ps2kb_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); #endif // _KERNEL_DEVICE_PS2_KB_H diff --git a/kernel/device/ramdrv.c b/kernel/device/ramdrv.c index 00d1473..18b9bb3 100644 --- a/kernel/device/ramdrv.c +++ b/kernel/device/ramdrv.c @@ -9,7 +9,8 @@ #include #include -bool ramdrv_init (struct device* device, void* arg) { +bool ramdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + (void)proc, (void)rctx; struct ramdrv_init* init = arg; struct ramdrv* ramdrv = malloc (sizeof (*ramdrv)); @@ -37,7 +38,9 @@ bool ramdrv_init (struct device* device, void* arg) { return true; } -void ramdrv_fini (struct device* device) { +void ramdrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { + (void)proc, (void)rctx; + struct ramdrv* ramdrv = device->udata; free (ramdrv->buffer); diff --git a/kernel/device/ramdrv.h b/kernel/device/ramdrv.h index fd71670..3df8b5b 100644 --- a/kernel/device/ramdrv.h +++ b/kernel/device/ramdrv.h @@ -20,9 +20,9 @@ struct ramdrv { uint8_t* buffer; }; -bool ramdrv_init (struct device* device, void* arg); +bool ramdrv_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -void ramdrv_fini (struct device* device); +void ramdrv_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); int ramdrv_read (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); diff --git a/kernel/device/terminal.c b/kernel/device/terminal.c index 6d19ced..d470587 100644 --- a/kernel/device/terminal.c +++ b/kernel/device/terminal.c @@ -19,8 +19,8 @@ void ft_free (void* ptr, size_t size) { free (ptr); } -bool terminal_init (struct device* device, void* arg) { - (void)arg, (void)device; +bool terminal_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx) { + (void)arg, (void)device, (void)proc, (void)rctx; struct limine_framebuffer_response* fb_r = limine_framebuffer_request.response; struct limine_framebuffer* fb = fb_r->framebuffers[0]; @@ -33,7 +33,9 @@ bool terminal_init (struct device* device, void* arg) { return true; } -void terminal_fini (struct device* device) { (void)device; } +void terminal_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx) { + (void)device, (void)proc, (void)rctx; +} int terminal_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4) { diff --git a/kernel/device/terminal.h b/kernel/device/terminal.h index 1218a86..761bfef 100644 --- a/kernel/device/terminal.h +++ b/kernel/device/terminal.h @@ -8,9 +8,9 @@ struct device; -bool terminal_init (struct device* device, void* arg); +bool terminal_init (struct device* device, void* arg, struct proc* proc, struct reschedule_ctx* rctx); -void terminal_fini (struct device* device); +void terminal_fini (struct device* device, struct proc* proc, struct reschedule_ctx* rctx); int terminal_putstr (struct device* device, struct proc* proc, struct reschedule_ctx* rctx, void* a1, void* a2, void* a3, void* a4); diff --git a/kernel/fs/fat1.c b/kernel/fs/fat1.c index 4b7ed06..55b0b99 100644 --- a/kernel/fs/fat1.c +++ b/kernel/fs/fat1.c @@ -1,7 +1,19 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" +#pragma clang diagnostic ignored "-Wmacro-redefined" #include #include +#include +#include + +static int media_write (struct fatfs* _fs, struct fatfs_ctx* ctx, size_t sector, uint8_t* buffer, size_t sector_count) { + return _fs->disk_io.write_media (ctx, sector, buffer, sector_count); +} + +static int media_read (struct fatfs* _fs, struct fatfs_ctx* ctx, size_t sector, uint8_t* buffer, size_t sector_count) { + return _fs->disk_io.read_media (ctx, sector, buffer, sector_count); +} + #define _KERNEL_LIBK_STRING_H #define _KERNEL_LIBK_STD_H @@ -225,14 +237,6 @@ typedef __WCHAR_TYPE__ wchar_t; #define NULL ((void*)0) #undef offsetof #define offsetof(s, m) __builtin_offsetof (s, m) -typedef enum memory_order { - memory_order_relaxed = __ATOMIC_RELAXED, - memory_order_consume = __ATOMIC_CONSUME, - memory_order_acquire = __ATOMIC_ACQUIRE, - memory_order_release = __ATOMIC_RELEASE, - memory_order_acq_rel = __ATOMIC_ACQ_REL, - memory_order_seq_cst = __ATOMIC_SEQ_CST -} memory_order; typedef _Atomic (_Bool) atomic_bool; typedef _Atomic (char) atomic_char; typedef _Atomic (signed char) atomic_schar; @@ -270,9 +274,6 @@ typedef _Atomic (size_t) atomic_size_t; typedef _Atomic (ptrdiff_t) atomic_ptrdiff_t; typedef _Atomic (intmax_t) atomic_intmax_t; typedef _Atomic (uintmax_t) atomic_uintmax_t; -typedef struct atomic_flag { - atomic_bool _Value; -} atomic_flag; #define ATOMIC_FLAG_INIT ((atomic_flag){0}) #define atomic_store(object, desired) __c11_atomic_store (object, desired, __ATOMIC_SEQ_CST) #define atomic_store_explicit __c11_atomic_store @@ -813,7 +814,7 @@ static int fatfs_fat_writeback (struct fatfs_ctx* ctx, struct fatfs* fs, struct sectors = FAT_BUFFER_SECTORS; else sectors = fs->fat_sectors - offset; - if (!fs->disk_io.write_media (ctx, pcur->address, pcur->sector, sectors)) + if (!media_write (fs, ctx, pcur->address, pcur->sector, sectors)) return 0; } pcur->dirty = 0; @@ -849,7 +850,7 @@ static struct fat_buffer* fatfs_fat_read_sector (struct fatfs_ctx* ctx, struct f if (!fatfs_fat_writeback (ctx, fs, pcur)) return 0; pcur->address = sector; - if (!fs->disk_io.read_media (ctx, pcur->address, pcur->sector, FAT_BUFFER_SECTORS)) { + if (!media_read (fs, ctx, pcur->address, pcur->sector, FAT_BUFFER_SECTORS)) { pcur->address = FAT32_INVALID_CLUSTER; return NULL; } @@ -904,7 +905,7 @@ void fatfs_set_fs_info_next_free_cluster (struct fatfs_ctx* ctx, struct fatfs* f FAT32_SET_32BIT_WORD (pbuf, 492, newValue); fs->next_free_cluster = newValue; if (fs->disk_io.write_media) - fs->disk_io.write_media (ctx, pbuf->address, pbuf->sector, 1); + media_write (fs, ctx, pbuf->address, pbuf->sector, 1); pbuf->address = FAT32_INVALID_CLUSTER; pbuf->dirty = 0; } @@ -1180,8 +1181,7 @@ int fatfs_add_file_entry (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 dirClu if (entryCount == 0) { fatfs_sfn_create_entry (shortfilename, size, startCluster, &shortEntry, dir); memcpy (&fs->currentsector.sector[recordoffset], &shortEntry, sizeof (shortEntry)); - return fs->disk_io.write_media (ctx, fs->currentsector.address, - fs->currentsector.sector, 1); + return media_write (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } else { entryCount--; fatfs_filename_to_lfn (filename, &fs->currentsector.sector[recordoffset], entryCount, @@ -1191,7 +1191,7 @@ int fatfs_add_file_entry (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 dirClu } } if (dirtySector) { - if (!fs->disk_io.write_media (ctx, fs->currentsector.address, fs->currentsector.sector, 1)) + if (!media_write (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1)) return 0; dirtySector = 0; } @@ -1215,7 +1215,7 @@ int fatfs_init (struct fatfs_ctx* ctx, struct fatfs* fs) { fatfs_fat_init (fs); if (!fs->disk_io.read_media) return FAT_INIT_MEDIA_ACCESS_ERROR; - if (!fs->disk_io.read_media (ctx, 0, fs->currentsector.sector, 1)) + if (!media_read (fs, ctx, 0, fs->currentsector.sector, 1)) return FAT_INIT_MEDIA_ACCESS_ERROR; if (fs->currentsector.sector[SIGNATURE_POSITION] != 0x55 || fs->currentsector.sector[SIGNATURE_POSITION + 1] != 0xAA) @@ -1245,7 +1245,7 @@ int fatfs_init (struct fatfs_ctx* ctx, struct fatfs* fs) { fs->lba_begin = GET_32BIT_WORD (fs->currentsector.sector, PARTITION1_LBA_BEGIN_LOCATION); else fs->lba_begin = 0; - if (!fs->disk_io.read_media (ctx, fs->lba_begin, fs->currentsector.sector, 1)) + if (!media_read (fs, ctx, fs->lba_begin, fs->currentsector.sector, 1)) return FAT_INIT_MEDIA_ACCESS_ERROR; if (GET_16BIT_WORD (fs->currentsector.sector, 0x0B) != FAT_SECTOR_SIZE) return FAT_INIT_INVALID_SECTOR_SIZE; @@ -1303,11 +1303,11 @@ uint32 fatfs_lba_of_cluster (struct fatfs* fs, uint32 Cluster_Number) { } int fatfs_sector_read (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 lba, uint8* target, uint32 count) { - return fs->disk_io.read_media (ctx, lba, target, count); + return media_read (fs, ctx, lba, target, count); } int fatfs_sector_write (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 lba, uint8* target, uint32 count) { - return fs->disk_io.write_media (ctx, lba, target, count); + return media_write (fs, ctx, lba, target, count); } int fatfs_sector_reader (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster, uint32 offset, uint8* target) { @@ -1332,10 +1332,10 @@ int fatfs_sector_reader (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_c lba = fatfs_lba_of_cluster (fs, cluster_chain) + sector_to_read; } if (target) - return fs->disk_io.read_media (ctx, lba, target, 1); + return media_read (fs, ctx, lba, target, 1); else if (lba != fs->currentsector.address) { fs->currentsector.address = lba; - return fs->disk_io.read_media (ctx, fs->currentsector.address, fs->currentsector.sector, 1); + return media_read (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } else return 1; } @@ -1348,18 +1348,18 @@ int fatfs_read_sector (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, else return 0; if (target) { - return fs->disk_io.read_media (ctx, lba, target, 1); + return media_read (fs, ctx, lba, target, 1); } else { fs->currentsector.address = lba; - return fs->disk_io.read_media (ctx, fs->currentsector.address, fs->currentsector.sector, 1); + return media_read (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } } else { if (target) { uint32 lba = fatfs_lba_of_cluster (fs, cluster) + sector; - return fs->disk_io.read_media (ctx, lba, target, 1); + return media_read (fs, ctx, lba, target, 1); } else { fs->currentsector.address = fatfs_lba_of_cluster (fs, cluster) + sector; - return fs->disk_io.read_media (ctx, fs->currentsector.address, fs->currentsector.sector, 1); + return media_read (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } } } @@ -1374,18 +1374,18 @@ int fatfs_write_sector (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, else return 0; if (target) { - return fs->disk_io.write_media (ctx, lba, target, 1); + return media_write (fs, ctx, lba, target, 1); } else { fs->currentsector.address = lba; - return fs->disk_io.write_media (ctx, fs->currentsector.address, fs->currentsector.sector, 1); + return media_write (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } } else { if (target) { uint32 lba = fatfs_lba_of_cluster (fs, cluster) + sector; - return fs->disk_io.write_media (ctx, lba, target, 1); + return media_write (fs, ctx, lba, target, 1); } else { fs->currentsector.address = fatfs_lba_of_cluster (fs, cluster) + sector; - return fs->disk_io.write_media (ctx, fs->currentsector.address, fs->currentsector.sector, 1); + return media_write (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } } } @@ -1501,8 +1501,7 @@ int fatfs_update_file_length (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cl directoryEntry->FileSize = FAT_HTONL (fileLength); memcpy ((uint8*)(fs->currentsector.sector + recordoffset), (uint8*)directoryEntry, sizeof (struct fat_dir_entry)); - return fs->disk_io.write_media (ctx, fs->currentsector.address, - fs->currentsector.sector, 1); + return media_write (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } } } @@ -1533,8 +1532,7 @@ int fatfs_mark_file_deleted (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Clu directoryEntry->Name[0] = FILE_HEADER_DELETED; memcpy ((uint8*)(fs->currentsector.sector + recordoffset), (uint8*)directoryEntry, sizeof (struct fat_dir_entry)); - return fs->disk_io.write_media (ctx, fs->currentsector.address, - fs->currentsector.sector, 1); + return media_write (fs, ctx, fs->currentsector.address, fs->currentsector.sector, 1); } } } @@ -1653,7 +1651,7 @@ static int fatfs_erase_sectors (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 int i; memset (fs->currentsector.sector, 0, FAT_SECTOR_SIZE); for (i = 0; i < count; i++) - if (!fs->disk_io.write_media (ctx, lba + i, fs->currentsector.sector, 1)) + if (!media_write (fs, ctx, lba + i, fs->currentsector.sector, 1)) return 0; return 1; } @@ -1796,7 +1794,7 @@ static int fatfs_create_boot_sector (struct fatfs_ctx* ctx, struct fatfs* fs, fs->currentsector.sector[510] = 0x55; fs->currentsector.sector[511] = 0xAA; } - if (fs->disk_io.write_media (ctx, boot_sector_lba, fs->currentsector.sector, 1)) + if (media_write (fs, ctx, boot_sector_lba, fs->currentsector.sector, 1)) return 1; else return 0; @@ -1821,7 +1819,7 @@ static int fatfs_create_fsinfo_sector (struct fatfs_ctx* ctx, struct fatfs* fs, fs->currentsector.sector[495] = 0xFF; fs->currentsector.sector[510] = 0x55; fs->currentsector.sector[511] = 0xAA; - if (fs->disk_io.write_media (ctx, sector_lba, fs->currentsector.sector, 1)) + if (media_write (fs, ctx, sector_lba, fs->currentsector.sector, 1)) return 1; else return 0; @@ -1837,11 +1835,11 @@ static int fatfs_erase_fat (struct fatfs_ctx* ctx, struct fatfs* fs, int is_fat3 SET_32BIT_WORD (fs->currentsector.sector, 4, 0xFFFFFFFF); SET_32BIT_WORD (fs->currentsector.sector, 8, 0x0FFFFFFF); } - if (!fs->disk_io.write_media (ctx, fs->fat_begin_lba + 0, fs->currentsector.sector, 1)) + if (!media_write (fs, ctx, fs->fat_begin_lba + 0, fs->currentsector.sector, 1)) return 0; memset (fs->currentsector.sector, 0, FAT_SECTOR_SIZE); for (i = 1; i < fs->fat_sectors * fs->num_of_fats; i++) - if (!fs->disk_io.write_media (ctx, fs->fat_begin_lba + i, fs->currentsector.sector, 1)) + if (!media_write (fs, ctx, fs->fat_begin_lba + i, fs->currentsector.sector, 1)) return 0; return 1; } diff --git a/kernel/proc/proc.c b/kernel/proc/proc.c index a44117e..a00c094 100644 --- a/kernel/proc/proc.c +++ b/kernel/proc/proc.c @@ -137,36 +137,8 @@ struct proc* proc_from_file (struct proc* proc1, const char* volume, const char* struct desc desc; int ret; - spin_lock (&proc1->lock); - bool is_kproc = (proc1->flags & PROC_KPROC) != 0; - spin_unlock (&proc1->lock); - - if (is_kproc) { - for (;;) { - ret = vfs_volume_open (proc1, volume, rctx); - - if (ret < 0) - return NULL; - - spin_lock (&proc1->lock); - - if (ret == ST_OK && proc1->state != PROC_SUSPENDED) { - spin_unlock (&proc1->lock); - break; - } - - for (;;) { - spin_lock (&proc1->lock); - - if (proc1->state != PROC_SUSPENDED) { - spin_unlock (&proc1->lock); - break; - } - - spin_unlock (&proc1->lock); - } - } - } + if ((ret = vfs_volume_open (proc1, volume, rctx)) < 0) + return NULL; if ((ret = vfs_describe (proc1, rctx, volume, path, &desc)) < 0) { vfs_volume_close (proc1, volume, rctx); diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index c7ec0e2..295ad0d 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -356,16 +356,19 @@ DEFINE_SYSCALL (sys_volume_open) { /* int volume_close (void) */ DEFINE_SYSCALL (sys_volume_close) { + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); + spin_unlock (&proc->lock); - int ret = vfs_volume_close (proc, proc->cwv, rctx); + int ret = vfs_volume_close (proc, cwv, rctx); if (ret == ST_OK) { + spin_lock (&proc->lock); memset (proc->cwv, 0, sizeof (proc->cwv)); + spin_unlock (&proc->lock); } - spin_unlock (&proc->lock); - return SYSRESULT (ret); } @@ -394,10 +397,13 @@ DEFINE_SYSCALL (sys_read_file) { if (buffer == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_read_file (proc, rctx, proc->cwv, path, buffer, off, size); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_read_file (proc, rctx, cwv, path, buffer, off, size); + return SYSRESULT (ret); } @@ -423,11 +429,14 @@ DEFINE_SYSCALL (sys_describe) { if (desc == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - + + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_describe (proc, rctx, proc->cwv, path, desc); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_describe (proc, rctx, cwv, path, desc); + return SYSRESULT (ret); } @@ -477,11 +486,14 @@ DEFINE_SYSCALL (sys_read_dir_entry) { if (entry == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - + + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_read_dir_entry (proc, rctx, proc->cwv, path, entry, entry_num); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_read_dir_entry (proc, rctx, cwv, path, entry, entry_num); + return SYSRESULT (ret); } @@ -501,11 +513,14 @@ DEFINE_SYSCALL (sys_create_file) { return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - + + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_create_file (proc, rctx, proc->cwv, path); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_create_file (proc, rctx, cwv, path); + return SYSRESULT (ret); } @@ -534,11 +549,14 @@ DEFINE_SYSCALL (sys_write_file) { if (buffer == NULL) return SYSRESULT (-ST_BAD_ADDRESS_SPACE); - + + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_write_file (proc, rctx, proc->cwv, path, buffer, off, size, flags); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_write_file (proc, rctx, cwv, path, buffer, off, size, flags); + return SYSRESULT (ret); } @@ -614,11 +632,14 @@ DEFINE_SYSCALL (sys_create_dir) { return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - + + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_create_dir (proc, rctx, proc->cwv, path); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_create_dir (proc, rctx, cwv, path); + return SYSRESULT (ret); } @@ -638,11 +659,14 @@ DEFINE_SYSCALL (sys_remove) { return SYSRESULT (-ST_BAD_ADDRESS_SPACE); const char* path = (const char*)((uintptr_t)hhdm->offset + out_paddr); - + + char cwv[VOLUME_MAX]; spin_lock (&proc->lock); - int ret = vfs_remove (proc, rctx, proc->cwv, path); + memcpy (cwv, proc->cwv, sizeof (proc->cwv)); spin_unlock (&proc->lock); + int ret = vfs_remove (proc, rctx, cwv, path); + return SYSRESULT (ret); } diff --git a/testing/make_empty_drive.sh b/testing/make_empty_drive.sh new file mode 100755 index 0000000..2f7071d --- /dev/null +++ b/testing/make_empty_drive.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +set -xe + +rm -f empty_drive.img + +dd if=/dev/zero of=empty_drive.img bs=1M count=128 diff --git a/testing/make_test_drive.sh b/testing/make_test_drive.sh index 801821f..257e9ea 100755 --- a/testing/make_test_drive.sh +++ b/testing/make_test_drive.sh @@ -5,5 +5,6 @@ set -xe rm -f test_drive.img dd if=/dev/zero of=test_drive.img bs=1M count=128 - -mkfs.vfat -F 32 test_drive.img +parted test_drive.img --script mklabel msdos +parted test_drive.img --script mkpart primary fat32 1MiB 127MiB +mkfs.vfat -F 32 --offset 2048 test_drive.img