diff options
Diffstat (limited to 'src/kernel/arch/amd64')
-rw-r--r-- | src/kernel/arch/amd64/driver/pata.c | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/rtl8139.c | 18 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.c | 15 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/util.c | 9 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/video.c | 7 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/isr.c | 6 |
6 files changed, 31 insertions, 28 deletions
diff --git a/src/kernel/arch/amd64/driver/pata.c b/src/kernel/arch/amd64/driver/pata.c index 3d5e3c6..6928b4e 100644 --- a/src/kernel/arch/amd64/driver/pata.c +++ b/src/kernel/arch/amd64/driver/pata.c @@ -51,7 +51,7 @@ static void accept(struct vfs_request *req) { fs_normslice(&req->offset, &req->output.len, ata_size(id), false); len = min(req->output.len, sizeof wbuf); ata_read(id, wbuf, len, req->offset); - virt_cpy_to(req->caller->pages, req->output.buf, wbuf, len); + pcpy_to(req->caller, req->output.buf, wbuf, len); vfsreq_finish_short(req, len); break; @@ -63,7 +63,7 @@ static void accept(struct vfs_request *req) { fs_normslice(&req->offset, &req->input.len, ata_size(id), false); len = min(req->input.len, sizeof wbuf); if (len != 0) { - virt_cpy_from(req->caller->pages, wbuf, req->input.buf, len); + len = pcpy_from(req->caller, wbuf, req->input.buf, len); ata_write(id, wbuf, len, req->offset); } vfsreq_finish_short(req, len); diff --git a/src/kernel/arch/amd64/driver/rtl8139.c b/src/kernel/arch/amd64/driver/rtl8139.c index eb07494..1face38 100644 --- a/src/kernel/arch/amd64/driver/rtl8139.c +++ b/src/kernel/arch/amd64/driver/rtl8139.c @@ -105,7 +105,7 @@ void rtl8139_irq(void) { port_out16(iobase + INTRSTATUS, status); } -static int try_rx(struct pagedir *pages, void __user *dest, size_t dlen) { +static int try_rx(struct process *proc, void __user *dest, size_t dlen) { uint16_t flags, size; /* bit 0 - Rx Buffer Empty */ if (port_in8(iobase + CMD) & 1) return WAIT; @@ -125,11 +125,11 @@ static int try_rx(struct pagedir *pages, void __user *dest, size_t dlen) { // kprintf("packet size 0x%x, flags 0x%x, rxpos %x\n", size, flags, rxpos - 4); if (dlen > size) dlen = size; if (rxpos + dlen <= rxbuf_baselen) { - virt_cpy_to(pages, dest, rxbuf + rxpos, dlen); + pcpy_to(proc, dest, rxbuf + rxpos, dlen); } else { size_t chunk = rxbuf_baselen - rxpos; - virt_cpy_to(pages, dest, rxbuf + rxpos, chunk); - virt_cpy_to(pages, dest + chunk, rxbuf, dlen - chunk); + pcpy_to(proc, dest, rxbuf + rxpos, chunk); + pcpy_to(proc, dest + chunk, rxbuf, dlen - chunk); } rxpos += size; @@ -140,7 +140,7 @@ static int try_rx(struct pagedir *pages, void __user *dest, size_t dlen) { return size; } -static int try_tx(struct pagedir *pages, const void __user *src, size_t slen) { +static int try_tx(struct process *proc, const void __user *src, size_t slen) { static uint8_t desc = 0; if (slen > 0xFFF) return -1; @@ -153,7 +153,9 @@ static int try_tx(struct pagedir *pages, const void __user *src, size_t slen) { panic_unimplemented(); } - virt_cpy_from(pages, txbuf[desc], src, slen); + if (pcpy_from(proc, txbuf[desc], src, slen) < slen) { + return -1; + } assert((long)(void*)txbuf <= 0xFFFFFFFF); port_out32(iobase + TXSTART0 + desc*4, (long)(void*)txbuf[desc]); port_out32(iobase + TXSTATUS0 + desc*4, slen); @@ -173,7 +175,7 @@ static void accept(struct vfs_request *req) { vfsreq_finish_short(req, req->input.len == 0 ? 0 : -1); break; case VFSOP_READ: - ret = try_rx(req->caller->pages, req->output.buf, req->output.len); + ret = try_rx(req->caller, req->output.buf, req->output.len); if (ret == WAIT) { postqueue_join(&blocked_on, req); rx_irq_enable(true); @@ -183,7 +185,7 @@ static void accept(struct vfs_request *req) { break; case VFSOP_WRITE: assert(!req->input.kern); - vfsreq_finish_short(req, try_tx(req->caller->pages, req->input.buf, req->input.len)); + vfsreq_finish_short(req, try_tx(req->caller, req->input.buf, req->input.len)); break; default: vfsreq_finish_short(req, -1); diff --git a/src/kernel/arch/amd64/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index 295f9b8..12c4151 100644 --- a/src/kernel/arch/amd64/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -73,13 +73,14 @@ static void accept(struct vfs_request *req) { break; case VFSOP_WRITE: if (req->caller && !req->flags) { - struct virt_iter iter; - virt_iter_new(&iter, req->input.buf, req->input.len, - req->caller->pages, true, false); - while (virt_iter_next(&iter)) - serial_write(iter.frag, iter.frag_len); - ret = iter.prior; - } else ret = -1; + char buf[4096]; + size_t len = min(sizeof buf, req->input.len); + len = pcpy_from(req->caller, buf, req->input.buf, len); + serial_write(buf, len); + ret = len; + } else { + ret = -1; + } vfsreq_finish_short(req, ret); break; default: diff --git a/src/kernel/arch/amd64/driver/util.c b/src/kernel/arch/amd64/driver/util.c index b8895b8..b2c33c6 100644 --- a/src/kernel/arch/amd64/driver/util.c +++ b/src/kernel/arch/amd64/driver/util.c @@ -9,10 +9,8 @@ int req_readcopy(struct vfs_request *req, const void *buf, size_t len) { if (!req->caller) return -1; assert(req->type == VFSOP_READ); fs_normslice(&req->offset, &req->output.len, len, false); - virt_cpy_to( - req->caller->pages, req->output.buf, - buf + req->offset, req->output.len); /* read errors are ignored. TODO write a spec */ + pcpy_to(req->caller, req->output.buf, buf + req->offset, req->output.len); return req->output.len; } @@ -48,8 +46,9 @@ void postqueue_ringreadall(struct vfs_request **queue, ring_t *r) { for (req = *queue; req; req = req->postqueue_next) { size_t ret = min(mlen, req->output.len); assert(req->type == VFSOP_READ); - if (req->caller) - virt_cpy_to(req->caller->pages, req->output.buf, tmp, ret); + if (req->caller) { + pcpy_to(req->caller, req->output.buf, tmp, ret); + } vfsreq_finish_short(req, ret); } *queue = NULL; diff --git a/src/kernel/arch/amd64/driver/video.c b/src/kernel/arch/amd64/driver/video.c index 945d5b4..4cd6b0b 100644 --- a/src/kernel/arch/amd64/driver/video.c +++ b/src/kernel/arch/amd64/driver/video.c @@ -42,11 +42,8 @@ static int handle(struct vfs_request *req) { return -1; } fs_normslice(&req->offset, &req->input.len, fb.size, false); - if (!virt_cpy_from(req->caller->pages, fb.b + req->offset, - req->input.buf, req->input.len)) - { - return -EFAULT; - } + /* parial writes ignored */ + pcpy_from(req->caller, fb.b + req->offset, req->input.buf, req->input.len); return req->input.len; case VFSOP_GETSIZE: diff --git a/src/kernel/arch/amd64/interrupts/isr.c b/src/kernel/arch/amd64/interrupts/isr.c index 519d783..994519d 100644 --- a/src/kernel/arch/amd64/interrupts/isr.c +++ b/src/kernel/arch/amd64/interrupts/isr.c @@ -17,6 +17,10 @@ bool isr_test_interrupt_called = false; static void log_interrupt(int interrupt, uint64_t *stackframe) { kprintf("interrupt %x, rip = k/%08x, cs 0x%x, code 0x%x\n", interrupt, stackframe[0], stackframe[1], stackframe[-1]); + if ((stackframe[1] & 0x3) == 0) { + uint64_t *stack = (void*)stackframe[3]; + kprintf("kernel rip = %p, *rip = %p\n", stack, *stack); + } if (interrupt == 0xe) { uint64_t addr = 0x69; asm("mov %%cr2, %0" : "=r"(addr)); @@ -54,7 +58,7 @@ void isr_stage3(int interrupt, uint64_t *stackframe) { default: if ((stackframe[1] & 0x3) == 0) { - mem_debugprint(); + // mem_debugprint(); log_interrupt(interrupt, stackframe); cpu_halt(); } else { |