diff options
| author | cpplover0 <osdev555@yandex.com> | 2025-09-24 21:13:52 +0300 |
|---|---|---|
| committer | cpplover0 <osdev555@yandex.com> | 2025-09-24 21:13:52 +0300 |
| commit | af06ca180e33f80fd9e95f2101e6a17728fc7178 (patch) | |
| tree | 3b21714de97477969a9e45dedb253d08e69288d9 | |
| parent | d87d454c4d9069a04d610feee34a7961242c1c89 (diff) | |
sys_poll()
| -rw-r--r-- | kernel/include/arch/x86_64/syscalls/sockets.hpp | 3 | ||||
| -rw-r--r-- | kernel/include/arch/x86_64/syscalls/syscalls.hpp | 10 | ||||
| -rw-r--r-- | kernel/include/etc/list.hpp | 5 | ||||
| -rw-r--r-- | kernel/include/generic/vfs/fd.hpp | 2 | ||||
| -rw-r--r-- | kernel/include/generic/vfs/vfs.hpp | 44 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/interrupts/panic.cpp | 16 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/syscalls/file.cpp | 128 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/syscalls/process.cpp | 2 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/syscalls/sockets.cpp | 11 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/syscalls/syscalls.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/drivers/tsc.cpp | 8 | ||||
| -rw-r--r-- | kernel/src/generic/vfs/devfs.cpp | 33 | ||||
| -rw-r--r-- | kernel/src/generic/vfs/vfs.cpp | 189 | ||||
| -rw-r--r-- | tools/pkg/2/init/src/include/etc.hpp | 24 | ||||
| -rw-r--r-- | tools/pkg/2/xhci_driver/src/main.cpp | 45 | ||||
| -rw-r--r-- | tools/pkg/3/poll_test/info.txt | 1 | ||||
| -rw-r--r-- | tools/pkg/3/poll_test/pkg.sh | 2 | ||||
| -rw-r--r-- | tools/pkg/3/poll_test/src/main.c | 44 |
18 files changed, 530 insertions, 41 deletions
diff --git a/kernel/include/arch/x86_64/syscalls/sockets.hpp b/kernel/include/arch/x86_64/syscalls/sockets.hpp index 428220e..4aca66e 100644 --- a/kernel/include/arch/x86_64/syscalls/sockets.hpp +++ b/kernel/include/arch/x86_64/syscalls/sockets.hpp @@ -138,4 +138,7 @@ public: static int connect(userspace_fd_t* fd, struct sockaddr_un* path); static int accept(userspace_fd_t* fd, struct sockaddr_un* path); static void init(); + + static socket_node_t* find(char* path); + };
\ No newline at end of file diff --git a/kernel/include/arch/x86_64/syscalls/syscalls.hpp b/kernel/include/arch/x86_64/syscalls/syscalls.hpp index 02b1f2e..10976cf 100644 --- a/kernel/include/arch/x86_64/syscalls/syscalls.hpp +++ b/kernel/include/arch/x86_64/syscalls/syscalls.hpp @@ -133,6 +133,8 @@ syscall_ret_t sys_fcntl(int fd, int request, std::uint64_t arg); syscall_ret_t sys_fchdir(int fd); +syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout); + /* Process */ syscall_ret_t sys_mmap(std::uint64_t hint, std::uint64_t size, int fd0, int_frame_t* ctx); syscall_ret_t sys_free(void *pointer, size_t size); @@ -165,6 +167,8 @@ syscall_ret_t sys_map_phys(std::uint64_t phys, std::uint64_t flags, std::uint64_ syscall_ret_t sys_timestamp(); +syscall_ret_t sys_mkfifoat(int dirfd, const char *path, int mode); + /* Futex */ syscall_ret_t sys_futex_wait(int* pointer, int excepted); syscall_ret_t sys_futex_wake(int* pointer); @@ -178,6 +182,12 @@ syscall_ret_t sys_connect(int fd, struct sockaddr_un* path, int len); syscall_ret_t sys_listen(int fd, int backlog); +struct pollfd { + int fd; + short events; + short revents; +}; + namespace arch { namespace x86_64 { typedef struct { diff --git a/kernel/include/etc/list.hpp b/kernel/include/etc/list.hpp index 25e6d98..d19c0b9 100644 --- a/kernel/include/etc/list.hpp +++ b/kernel/include/etc/list.hpp @@ -139,11 +139,16 @@ namespace Lists { locks::spinlock ring_lock; + std::uint64_t read_counter = 0; + std::uint64_t write_counter = 0; + void send(std::uint64_t value1) { ring_lock.lock(); ring.objs[ring.tail].cycle = ring.cycle; ring.objs[ring.tail].value1 = value1; + read_counter++; + if (++ring.tail == ring.size) { ring.tail = 0; ring.cycle = !ring.cycle; diff --git a/kernel/include/generic/vfs/fd.hpp b/kernel/include/generic/vfs/fd.hpp index 46d5e26..3d28eca 100644 --- a/kernel/include/generic/vfs/fd.hpp +++ b/kernel/include/generic/vfs/fd.hpp @@ -27,6 +27,8 @@ namespace vfs { } current->state = USERSPACE_FD_STATE_FILE; + current->read_counter = -1; + current->write_counter = -1; return current->index; diff --git a/kernel/include/generic/vfs/vfs.hpp b/kernel/include/generic/vfs/vfs.hpp index cf6c74b..6c91e7b 100644 --- a/kernel/include/generic/vfs/vfs.hpp +++ b/kernel/include/generic/vfs/vfs.hpp @@ -108,8 +108,6 @@ namespace vfs { class pipe { private: char* buffer; - std::uint32_t connected_to_pipe = 0; - std::uint32_t connected_to_pipe_write = 0; std::int64_t size = 0; std::uint64_t total_size = 0; std::uint64_t read_ptr = 0; @@ -117,8 +115,16 @@ namespace vfs { std::atomic_flag is_received = ATOMIC_FLAG_INIT; std::atomic_flag is_n_closed = ATOMIC_FLAG_INIT; std::atomic_flag is_closed = ATOMIC_FLAG_INIT; + + int is_was_writed_ever = 0; + public: + std::uint64_t write_counter = 0; + std::uint64_t read_counter = 0; + + std::uint32_t connected_to_pipe = 0; + std::uint32_t connected_to_pipe_write = 0; std::uint64_t flags = 0; pipe(std::uint64_t flags) { @@ -130,15 +136,23 @@ namespace vfs { this->flags = flags; } + void fifoclose() { + this->lock.lock(); + this->is_received.clear(); + this->is_closed.test_and_set(); + this->lock.unlock(); + } + void close(std::uint8_t side) { this->lock.lock(); this->connected_to_pipe--; if(side == PIPE_SIDE_WRITE) { this->connected_to_pipe_write--; - if(this->connected_to_pipe_write == 0) { + if(is_was_writed_ever || this->connected_to_pipe_write == 0) { this->is_received.clear(); this->is_closed.test_and_set(); + is_was_writed_ever = 0; } } @@ -170,10 +184,12 @@ namespace vfs { if (space_left == 0) { continue; } + is_was_writed_ever = 1; std::uint64_t to_write = (count - written < space_left) ? (count - written) : space_left; force_write(src_buffer + written, to_write); written += to_write; this->is_received.clear(); + read_counter++; } return written; } @@ -198,6 +214,7 @@ namespace vfs { this->read_ptr = 0; this->size = 0; this->is_received.test_and_set(); + write_counter++; } break; } @@ -212,6 +229,18 @@ namespace vfs { }; +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM 0x0100 +#define POLLWRBAND 0x0200 +#define POLLRDHUP 0x2000 + #define USERSPACE_FD_OTHERSTATE_MASTER 1 #define USERSPACE_FD_OTHERSTATE_SLAVE 2 @@ -242,6 +271,9 @@ typedef struct userspace_fd { std::uint32_t mode; + std::int64_t write_counter; + std::int64_t read_counter; + vfs::pipe* pipe; char path[2048]; @@ -463,6 +495,8 @@ namespace vfs { std::int32_t (*create) (char* path, std::uint8_t type ); std::int32_t (*touch) (char* path ); + std::int64_t (*poll) (userspace_fd_t* fd, char* path, int request); + void (*close)(userspace_fd_t* fd, char* path); char path[2048]; @@ -489,6 +523,8 @@ namespace vfs { static std::int64_t ioctl (userspace_fd_t* fd, unsigned long req, void *arg, int *res ); static std::int32_t mmap (userspace_fd_t* fd, std::uint64_t* outp, std::uint64_t* outsz, std::uint64_t* outflags); + static std::int64_t poll(userspace_fd_t* fd, int operation_type); + static void close(userspace_fd_t* fd); static std::int32_t create (char* path, std::uint8_t type ); @@ -496,6 +532,8 @@ namespace vfs { static std::int32_t nlstat (userspace_fd_t* fd, stat_t* out ); + static std::uint32_t create_fifo(char* path); + static void unlock(); static void lock(); diff --git a/kernel/src/arch/x86_64/interrupts/panic.cpp b/kernel/src/arch/x86_64/interrupts/panic.cpp index c43dc66..13adec2 100644 --- a/kernel/src/arch/x86_64/interrupts/panic.cpp +++ b/kernel/src/arch/x86_64/interrupts/panic.cpp @@ -23,14 +23,14 @@ void panic(int_frame_t* ctx, const char* msg) { memory::paging::enablekernel(); - arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; - if(proc) { - uint64_t cr2; - asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory"); - Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"process %d fired cpu exception with vec %d, rip 0x%p, cr2 0x%p, error code 0x%p\n",proc->id,ctx->vec,ctx->rip,cr2,ctx->err_code); - arch::x86_64::scheduling::kill(proc); - schedulingSchedule(0); - } + // arch::x86_64::process_t* proc = arch::x86_64::cpu::data()->temp.proc; + // if(proc) { + // uint64_t cr2; + // asm volatile("mov %%cr2, %0" : "=r"(cr2) : : "memory"); + // Log::SerialDisplay(LEVEL_MESSAGE_FAIL,"process %d fired cpu exception with vec %d, rip 0x%p, cr2 0x%p, error code 0x%p\n",proc->id,ctx->vec,ctx->rip,cr2,ctx->err_code); + // arch::x86_64::scheduling::kill(proc); + // schedulingSchedule(0); + // } extern locks::spinlock log_lock; log_lock.unlock(); diff --git a/kernel/src/arch/x86_64/syscalls/file.cpp b/kernel/src/arch/x86_64/syscalls/file.cpp index 9b794e1..f06a507 100644 --- a/kernel/src/arch/x86_64/syscalls/file.cpp +++ b/kernel/src/arch/x86_64/syscalls/file.cpp @@ -11,6 +11,8 @@ #include <generic/vfs/devfs.hpp> +#include <drivers/tsc.hpp> + #include <etc/etc.hpp> #include <etc/errno.hpp> @@ -295,6 +297,9 @@ syscall_ret_t sys_dup(int fd, int flags) { nfd_s->pipe_side = fd_s->pipe_side; nfd_s->queue = fd_s->queue; nfd_s->is_a_tty = fd_s->is_a_tty; + nfd_s->read_counter = fd_s->read_counter; + nfd_s->write_counter = fd_s->write_counter; + memcpy(nfd_s->path,fd_s->path,sizeof(fd_s->path)); return {1,0,new_fd}; @@ -328,6 +333,8 @@ syscall_ret_t sys_dup2(int fd, int flags, int newfd) { nfd_s->pipe_side = fd_s->pipe_side; nfd_s->queue = fd_s->queue; nfd_s->is_a_tty = fd_s->is_a_tty; + nfd_s->write_counter = fd_s->write_counter; + nfd_s->read_counter = fd_s->read_counter; if(nfd_s->state == USERSPACE_FD_STATE_PIPE) nfd_s->pipe->create(nfd_s->pipe_side); @@ -599,13 +606,126 @@ syscall_ret_t sys_mkfifoat(int dirfd, const char *path, int mode) { memset(result,0,2048); vfs::resolve_path(kpath,first_path,result,1,0); - userspace_fd_t* new_fd_s; - memset(new_fd_s->path,0,2048); - memcpy(new_fd_s->path,result,strlen(result)); + userspace_fd_t new_fd_s; + memset(new_fd_s.path,0,2048); + memcpy(new_fd_s.path,result,strlen(result)); vfs::stat_t stat; - if(vfs::vfs::stat(new_fd_s,&stat) == 0) + if(vfs::vfs::stat(&new_fd_s,&stat) == 0) return {0,EEXIST,0}; + int status = vfs::vfs::create_fifo(result); + + Log::SerialDisplay(LEVEL_MESSAGE_INFO,"new fifo %s status %d\n",result,status); + + return {0,status,0}; +} + +syscall_ret_t sys_poll(struct pollfd *fds, int count, int timeout) { + SYSCALL_IS_SAFEA((void*)fds,0); + + if(!fds) + return {1,EINVAL,0}; + + arch::x86_64::process_t* proc = CURRENT_PROC; + struct pollfd fd[count]; + + copy_in_userspace(proc,fd,fds,count * sizeof(struct pollfd)); + + std::uint64_t current_timestamp = drivers::tsc::currentus(); + + int total_events = 0; + + for(int i = 0;i < count; i++) { + userspace_fd_t* fd0 = vfs::fdmanager::search(proc,fd[i].fd); + + fd[i].revents = 0; + + if(!fd0) + return {1,EINVAL,0}; + + if(fd[i].events & POLLIN) + total_events++; + + if(fd[i].events & POLLOUT) + total_events++; + + if(fd0->write_counter == -1) { + std::int64_t ret = vfs::vfs::poll(fd0,POLLOUT); + fd0->write_counter = ret < 0 ? 0 : ret; + } + + if(fd0->read_counter == -1) { + std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); + fd0->read_counter = ret < 0 ? 0 : ret; + } + + } + + int num_events = 0; + + SYSCALL_ENABLE_PREEMPT(); + + int success = true; + + if(timeout == -1) { + while(success) { + for(int i = 0;i < count; i++) { + userspace_fd_t* fd0 = vfs::fdmanager::search(proc,fd[i].fd); + if(fd[i].events & POLLIN) { + std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); + if(ret > fd0->read_counter) { + fd0->read_counter = ret; + num_events++; + fd[i].revents |= POLLIN; + } + } + + if(fd[i].events & POLLOUT) { + std::int64_t ret = vfs::vfs::poll(fd0,POLLOUT); + if(ret > fd0->write_counter) { + fd0->write_counter = ret; + num_events++; + fd[i].revents |= POLLOUT; + } + } + + if(num_events) + success = false; + } + } + } else { + while(drivers::tsc::currentus() < (current_timestamp + (timeout * 1000)) && success) { + for(int i = 0;i < count; i++) { + userspace_fd_t* fd0 = vfs::fdmanager::search(proc,fd[i].fd); + if(fd[i].events & POLLIN) { + std::int64_t ret = vfs::vfs::poll(fd0,POLLIN); + if(ret > fd0->read_counter) { + fd0->read_counter = ret; + num_events++; + fd[i].revents |= POLLIN; + } + } + + if(fd[i].events & POLLOUT) { + std::int64_t ret = vfs::vfs::poll(fd0,POLLOUT); + if(ret > fd0->write_counter) { + fd0->write_counter = ret; + num_events++; + fd[i].revents |= POLLOUT; + } + } + + if(num_events) + success = false; + } + } + } + + copy_in_userspace(proc,fds,fd,count * sizeof(struct pollfd)); + + return {1,0,num_events}; + + }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/process.cpp b/kernel/src/arch/x86_64/syscalls/process.cpp index 4d6de96..bcfa25c 100644 --- a/kernel/src/arch/x86_64/syscalls/process.cpp +++ b/kernel/src/arch/x86_64/syscalls/process.cpp @@ -399,5 +399,5 @@ syscall_ret_t sys_map_phys(std::uint64_t phys, std::uint64_t flags, std::uint64_ } syscall_ret_t sys_timestamp() { - return {1,0,(std::int64_t)drivers::hpet::nanocurrent()}; + return {1,0,(std::int64_t)drivers::tsc::currentnano()}; }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/syscalls/sockets.cpp b/kernel/src/arch/x86_64/syscalls/sockets.cpp index d172ac8..ed450b5 100644 --- a/kernel/src/arch/x86_64/syscalls/sockets.cpp +++ b/kernel/src/arch/x86_64/syscalls/sockets.cpp @@ -28,6 +28,17 @@ socket_node_t* find_node(struct sockaddr_un* path) { return 0; } +socket_node_t* sockets::find(char* path) { + socket_node_t* current = head; + while(current) { + if(!strcmp(current->path,path)) { + return current; + } + current = current->next; + } + return 0; +} + socket_node_t* find_node_str(char* path) { socket_node_t* current = head; while(current) { diff --git a/kernel/src/arch/x86_64/syscalls/syscalls.cpp b/kernel/src/arch/x86_64/syscalls/syscalls.cpp index df0bff7..fb0d349 100644 --- a/kernel/src/arch/x86_64/syscalls/syscalls.cpp +++ b/kernel/src/arch/x86_64/syscalls/syscalls.cpp @@ -55,7 +55,9 @@ arch::x86_64::syscall_item_t sys_table[] = { {43,(void*)sys_bind}, {44,(void*)sys_socket}, {45,(void*)sys_listen}, - {46,(void*)sys_timestamp} + {46,(void*)sys_timestamp}, + {47,(void*)sys_mkfifoat}, + {48,(void*)sys_poll} }; arch::x86_64::syscall_item_t* __syscall_find(int rax) { diff --git a/kernel/src/drivers/tsc.cpp b/kernel/src/drivers/tsc.cpp index 32d1038..0490ccd 100644 --- a/kernel/src/drivers/tsc.cpp +++ b/kernel/src/drivers/tsc.cpp @@ -17,16 +17,16 @@ std::uint64_t freq; void tsc::init() { std::uint64_t start = __rdtsc(); - time::sleep(100 * 1000); + time::sleep(100); std::uint64_t end = __rdtsc(); std::uint64_t d = end - start; - arch::x86_64::cpu::data()->tsc.freq = (d * 1000000000ULL) / (100 * 1000000ULL); + arch::x86_64::cpu::data()->tsc.freq = (d * 1000000ULL) / (100 * 1000ULL); } void tsc::sleep(std::uint64_t us) { - if(freq == 0) { + if(arch::x86_64::cpu::data()->tsc.freq == 0) { drivers::hpet::sleep(us); return; } @@ -38,7 +38,7 @@ void tsc::sleep(std::uint64_t us) { } std::uint64_t tsc::currentnano() { - return (__rdtsc() * 1000000000ULL) / arch::x86_64::cpu::data()->tsc.freq; + return (__rdtsc() * 1000000ULL) / arch::x86_64::cpu::data()->tsc.freq; } std::uint64_t tsc::currentus() { diff --git a/kernel/src/generic/vfs/devfs.cpp b/kernel/src/generic/vfs/devfs.cpp index 21de176..ad33c7a 100644 --- a/kernel/src/generic/vfs/devfs.cpp +++ b/kernel/src/generic/vfs/devfs.cpp @@ -67,7 +67,7 @@ std::int32_t __devfs__open(userspace_fd_t* fd, char* path) { if(node->open_flags.is_pipe) { fd->pipe = (vfs::pipe*)(node->pipe0 | (((uint64_t)node->pipe0 & (1 << 62)) << 63)); fd->state = USERSPACE_FD_STATE_PIPE; - fd->pipe_side = (node->pipe0 & (1 << 63)) == 1 ? PIPE_SIDE_WRITE : PIPE_SIDE_READ; + fd->pipe_side = (node->pipe0 & (1 << 63)) ? PIPE_SIDE_WRITE : PIPE_SIDE_READ; } else { fd->queue = is_slave == 1 ? node->readring->ring.tail : node->writering->ring.tail; fd->cycle = is_slave == 1 ? node->readring->ring.cycle : node->writering->ring.cycle; @@ -187,6 +187,36 @@ std::int32_t __devfs__stat(userspace_fd_t* fd, char* path, vfs::stat_t* out) { return 0; } +std::int64_t __devfs__poll(userspace_fd_t* fd, char* path, int operation_type) { + + vfs::devfs_node_t* node = devfs_find_dev(path); + + std::int64_t ret = 0; + if(node->open_flags.is_pipe_rw) { + switch (operation_type) + { + + case POLLIN: + ret = !is_slave ? node->writepipe->read_counter : node->readpipe->read_counter; + break; + + case POLLOUT: + ret = !is_slave ? node->readpipe->write_counter : node->writepipe->write_counter; + break; + + default: + break; + } + } else { + if(operation_type == POLLIN) { + ret = !is_slave ? node->writering->read_counter : node->readring->read_counter; + } else if(operation_type == POLLOUT) { + ret = !is_slave ? ++node->readring->write_counter : ++node->writering->write_counter; + } + } + return ret; +} + extern locks::spinlock* vfs_lock; std::int64_t vfs::devfs::send_packet(char* path,devfs_packet_t* packet) { @@ -522,6 +552,7 @@ void vfs::devfs::mount(vfs_node_t* node) { node->mmap = __devfs__mmap; node->var = __devfs__var; node->stat = __devfs__stat; + node->poll = __devfs__poll; const char* name = "/ptmx"; diff --git a/kernel/src/generic/vfs/vfs.cpp b/kernel/src/generic/vfs/vfs.cpp index 12616ce..2615019 100644 --- a/kernel/src/generic/vfs/vfs.cpp +++ b/kernel/src/generic/vfs/vfs.cpp @@ -28,8 +28,79 @@ vfs::vfs_node_t* find_node(char* path) { return match; } +vfs::fifo_node_t* fifo_head = 0; + +int is_fifo_exists(char* path) { + vfs::fifo_node_t* current = fifo_head; + while(current) { + if(!strcmp(current->path,path)) + return 1; + current = current->next; + } + return 0; +} + +vfs::fifo_node_t* fifo_get(char* path) { + + vfs::fifo_node_t* current = fifo_head; + while(current) { + if(!strcmp(current->path,path)) + return current; + current = current->next; + } + return 0; + +} + +std::uint32_t vfs::vfs::create_fifo(char* path) { + + vfs_lock->lock(); + + if(!path) { + vfs_lock->unlock(); + return EINVAL; + } + + if(is_fifo_exists(path)) { + vfs_lock->unlock(); + return EEXIST; + } + + fifo_node_t* current = fifo_head; + while(current) { + if(!current->is_used) + break; + current = current->next; + } + + if(!current) { + current = new fifo_node_t; + current->next = fifo_head; + fifo_head = current; + } + + current->main_pipe = new pipe(0); + current->main_pipe->connected_to_pipe_write = 2; + + memset(current->path,0,2048); + memcpy(current->path,path,strlen(path)); + + current->is_used = 1; + + vfs_lock->unlock(); + return 0; +} + std::int64_t vfs::vfs::write(userspace_fd_t* fd, void* buffer, std::uint64_t size) { vfs_lock->lock(); + + if(is_fifo_exists(fd->path)) { + fifo_node_t* fifo = fifo_get(fd->path); + vfs_lock->unlock(); + asm volatile("sti"); + return fifo->main_pipe->write((const char*)buffer,size); + } + vfs_node_t* node = find_node(fd->path); if(!node) { vfs::vfs::unlock(); return -ENOENT; } @@ -44,6 +115,14 @@ std::int64_t vfs::vfs::write(userspace_fd_t* fd, void* buffer, std::uint64_t siz std::int64_t vfs::vfs::read(userspace_fd_t* fd, void* buffer, std::uint64_t count) { vfs_lock->lock(); + + if(is_fifo_exists(fd->path)) { + fifo_node_t* fifo = fifo_get(fd->path); + vfs_lock->unlock(); + asm volatile("sti"); + return fifo->main_pipe->read((char*)buffer,count); + } + vfs_node_t* node = find_node(fd->path); if(!node) { vfs::vfs::unlock(); return -ENOENT; } @@ -59,7 +138,7 @@ std::int64_t vfs::vfs::read(userspace_fd_t* fd, void* buffer, std::uint64_t coun std::int32_t vfs::vfs::create(char* path, std::uint8_t type) { vfs_lock->lock(); - if(sockets::is_exists(path)) { + if(sockets::is_exists(path) || is_fifo_exists(path)) { vfs_lock->unlock(); return EEXIST; } @@ -94,6 +173,13 @@ std::int32_t vfs::vfs::mmap(userspace_fd_t* fd, std::uint64_t* outp, std::uint64 std::int32_t vfs::vfs::open(userspace_fd_t* fd) { vfs_lock->lock(); + + if(is_fifo_exists(fd->path)) { + fifo_node_t* fifo = fifo_get(fd->path); + vfs_lock->unlock(); + return 0; + } + vfs_node_t* node = find_node(fd->path); if(!node) { vfs::vfs::unlock(); @@ -110,6 +196,16 @@ std::int32_t vfs::vfs::open(userspace_fd_t* fd) { std::int32_t vfs::vfs::remove(userspace_fd_t* fd) { vfs_lock->lock(); + + if(is_fifo_exists(fd->path)) { + fifo_node_t* fifo = fifo_get(fd->path); + memset(fifo->path,0,2048); + fifo->is_used = 0; + delete fifo->main_pipe; + vfs_lock->unlock(); + return 0; + } + vfs_node_t* node = find_node(fd->path); if(!node) { vfs::vfs::unlock(); return ENOENT; } @@ -156,7 +252,7 @@ std::int32_t vfs::vfs::var(userspace_fd_t* fd, std::uint64_t value, std::uint8_t std::int32_t vfs::vfs::touch(char* path) { vfs_lock->lock(); - if(sockets::is_exists(path)) { + if(sockets::is_exists(path) || is_fifo_exists(path)) { vfs_lock->unlock(); return EEXIST; } @@ -177,6 +273,13 @@ std::int32_t vfs::vfs::touch(char* path) { std::int32_t vfs::vfs::stat(userspace_fd_t* fd, stat_t* out) { vfs_lock->lock(); + if(is_fifo_exists(fd->path)) { + memset(out,0,sizeof(stat_t)); + out->st_mode |= S_IFIFO; + vfs_lock->unlock(); + return 0; + } + if(sockets::is_exists(fd->path)) { memset(out,0,sizeof(stat_t)); out->st_mode |= S_IFSOCK; @@ -227,6 +330,14 @@ std::int64_t vfs::vfs::ioctl(userspace_fd_t* fd, unsigned long req, void *arg, i void vfs::vfs::close(userspace_fd_t* fd) { vfs_lock->lock(); + + if(is_fifo_exists(fd->path)) { + fifo_node_t* fifo = fifo_get(fd->path); + fifo->main_pipe->fifoclose(); + vfs_lock->unlock(); + return; + } + vfs_node_t* node = find_node(fd->path); if(!node) { vfs::vfs::unlock(); return; } @@ -240,6 +351,80 @@ void vfs::vfs::close(userspace_fd_t* fd) { return; } +std::int64_t vfs::vfs::poll(userspace_fd_t* fd, int operation_type) { + vfs_lock->lock(); + + if(is_fifo_exists(fd->path)) { + fifo_node_t* fifo = fifo_get(fd->path); + std::int64_t ret = 0; + switch (operation_type) + { + + case POLLIN: + ret = fifo->main_pipe->read_counter; + break; + + case POLLOUT: + ret = fifo->main_pipe->write_counter; + break; + + default: + break; + } + vfs_lock->unlock(); + return ret; + } else if(fd->state == USERSPACE_FD_STATE_SOCKET) { + std::int64_t ret = 0; + switch (operation_type) + { + + case POLLIN: + ret = fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd->write_socket_pipe->read_counter : fd->read_socket_pipe->read_counter; + break; + + case POLLOUT: + ret = fd->other_state == USERSPACE_FD_OTHERSTATE_MASTER ? fd->read_socket_pipe->write_counter : fd->write_socket_pipe->write_counter; + break; + + default: + break; + } + vfs_lock->unlock(); + return ret; + } else if(fd->state == USERSPACE_FD_STATE_PIPE) { + std::int64_t ret = 0; + switch (operation_type) + { + + case POLLIN: + ret = fd->pipe->read_counter; + break; + + case POLLOUT: + ret = fd->pipe->write_counter; + break; + + default: + break; + } + vfs_lock->unlock(); + return ret; + } + + vfs_node_t* node = find_node(fd->path); + if(!node) { vfs::vfs::unlock(); + return -ENOENT; } + + char* fs_love_name = fd->path + strlen(node->path) - 1; + if(!node->poll) { vfs::vfs::unlock(); + return -ENOSYS ; } + + std::int64_t ret = node->poll(fd,fs_love_name,operation_type); + vfs_lock->unlock(); + return ret; +} + + void vfs::vfs::unlock() { vfs_lock->unlock(); } diff --git a/tools/pkg/2/init/src/include/etc.hpp b/tools/pkg/2/init/src/include/etc.hpp index fff68a0..a1e5bc3 100644 --- a/tools/pkg/2/init/src/include/etc.hpp +++ b/tools/pkg/2/init/src/include/etc.hpp @@ -11,6 +11,8 @@ #include <stdint.h> #include <termios.h> #include <signal.h> + +#include <poll.h> #include <fcntl.h> #include <dirent.h> @@ -217,15 +219,25 @@ public: pid = fork(); if(pid == 0) { + struct pollfd pfd; + pfd.fd = slave_input; + pfd.events = POLLIN; + while(1) { - char buffer[32]; - memset(buffer,0,32); - int count = read(slave_input,buffer,32); - if(count) { - for(int i = 0;i < count;i++) { - doKeyWork(buffer[i],master_fd); + int ret = poll(&pfd, 1, -1); + if(ret > 0) { + if(pfd.revents & POLLIN) { + char buffer[32]; + memset(buffer, 0, 32); + int count = read(slave_input, buffer, 32); + if(count > 0) { + for(int i = 0; i < count; i++) { + doKeyWork(buffer[i], master_fd); + } + } } } + } } } diff --git a/tools/pkg/2/xhci_driver/src/main.cpp b/tools/pkg/2/xhci_driver/src/main.cpp index 08290a0..7264121 100644 --- a/tools/pkg/2/xhci_driver/src/main.cpp +++ b/tools/pkg/2/xhci_driver/src/main.cpp @@ -255,7 +255,7 @@ xhci_trb_t __xhci_event_wait(xhci_device_t* dev,int type) { return t; } - usleep(5000); + usleep(500); } } @@ -570,6 +570,7 @@ void __xhci_unicode_to_ascii(uint16_t* src,char* dest) { uint16_t* ptr = (uint16_t*)src; while(ptr[src_ptr]) { + if(ptr[src_ptr] < 128) dest[dest_ptr++] = ptr[src_ptr++]; else @@ -592,6 +593,10 @@ int __xhci_read_usb_string(xhci_device_t* dev,xhci_usb_device_t* usbdev,xhci_str usbcommand.len = out->head.len; + if(usbcommand.len < 8) { + return 1; + } + ret = __xhci_send_usb_request_packet(dev,usbdev,usbcommand,out,usbcommand.len); if(ret.ret_code != 1) return 0; @@ -637,6 +642,9 @@ int __xhci_print_device_info(xhci_device_t* dev,xhci_usb_device_t* usb_dev,char* xhci_string_descriptor_t product; xhci_string_descriptor_t manufacter; + memset(&product,0,sizeof(product)); + memset(&manufacter,0,sizeof(manufacter)); + status = __xhci_read_usb_string(dev,usb_dev,&product,usb_dev->desc->product1,lang0); if(!status) @@ -770,12 +778,15 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { uint64_t addr = liborange_alloc_dma(4096); __xhci_create_dcbaa(dev,usb_dev->slotid,addr); - if(!dev->cap->hccparams1.contextsize) + uint32_t* hccparams = (uint32_t*)(&dev->cap->hccparams1); + char context_size = ((hccparams1_t*)hccparams)->contextsize; + + if(!context_size) dev->dcbaa[id] += 64; else dev->dcbaa[id] += 128; - if(!dev->cap->hccparams1.contextsize) + if(!context_size) usb_dev->_is64byte = 0; else usb_dev->_is64byte = 1; @@ -795,7 +806,7 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { "(10 Gb/s - USB 3.1)" }; - if(!dev->cap->hccparams1.contextsize) { + if(!context_size) { xhci_input_ctx_t* input_ctx = (xhci_input_ctx_t*)liborange_map_phys(addr,0,4096); memset(input_ctx,0,4096); @@ -851,8 +862,11 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { return; //now i cant ignore anymore... } - char product[256]; - char manufacter[256]; + char product[1024]; + char manufacter[1024]; + + memset(product,0,1024); + memset(manufacter,0,1024); int status4 = __xhci_print_device_info(dev,usb_dev,product,manufacter); if(!status4) @@ -862,9 +876,10 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { usb_dev->config = cfg; __xhci_get_config_descriptor(dev,usb_dev,cfg); + __xhci_setup_config(dev,usb_dev,cfg->configval); - if(!dev->cap->hccparams1.contextsize) { + if(!context_size) { usb_dev->input_ctx->input_ctx.A = (1 << 0); } else { xhci_input_ctx64_t* input = (xhci_input_ctx64_t*)liborange_map_phys(addr,0,4096); @@ -950,7 +965,7 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { usb_dev->buffers[idx] = (uint8_t*)liborange_map_phys(usb_dev->phys_buffers[idx],0,4096); usb_dev->doorbell_values[idx] = idx + 2; - if(!dev->cap->hccparams1.contextsize) { + if(!context_size) { xhci_input_ctx_t* input = (xhci_input_ctx_t*)liborange_map_phys(addr,0,4096); xhci_endpoint_ctx_t* ep1 = &input->ep[idx]; memset(ep1,0,sizeof(xhci_endpoint_ctx_t)); @@ -1020,7 +1035,7 @@ void __xhci_init_dev(xhci_device_t* dev,int portnum) { __xhci_command_ring_queue(dev,dev->com_ring,(xhci_trb_t*)&ep_trb); __xhci_doorbell(dev,0); usleep(10000); - + xhci_trb_t ret = __xhci_event_wait(dev,TRB_COMMANDCOMPLETIONEVENT_TYPE); if(ret.ret_code != 1) { @@ -1043,7 +1058,9 @@ void __xhci_init_ports(xhci_device_t* dev) { } void __xhci_iterate_usb_ports(xhci_device_t* dev) { + volatile uint32_t* cap = (volatile uint32_t*)(dev->xhci_virt_base + dev->cap->hccparams1.xECP * 4); + xhci_ext_cap_t load_cap; load_cap.full = *cap; //INFO("0x%p\n",cap); @@ -1064,12 +1081,12 @@ void __xhci_iterate_usb_ports(xhci_device_t* dev) { if(usb_cap.major == 3) { for(uint8_t i = usb_cap.portoffset - 1;i <= (usb_cap.portoffset - 1) + usb_cap.portcount - 1;i++) { dev->usb3ports[i] = 1; - //INFO("Found USB 3.0 Port %d !\n",i); + //log(LEVEL_MESSAGE_INFO,"Found USB 3.0 Port %d !\n",i); } } else { for(uint8_t i = usb_cap.portoffset - 1;i <= (usb_cap.portoffset - 1) + usb_cap.portcount - 1;i++) { dev->usb3ports[i] = 0; - //INFO("Found USB 2.0 Port %d !\n",i); + //log(LEVEL_MESSAGE_INFO,"Found USB 2.0 Port %d !\n",i); } } @@ -1164,6 +1181,12 @@ void __xhci_device(pci_t pci_dev,uint8_t a, uint8_t b,uint8_t c) { xhci_device_t* dev = (xhci_device_t*)malloc(4096); memset(dev,0,4096); + uint32_t usb3_ports = pci_in(a,b,c,0xDC,4); + pci_out(a,b,c,0xD8,usb3_ports,4); + + auto usb2_ports = pci_in(a,b,c,0xD4,4); + pci_out(a,b,c,0xD0,usb2_ports,4); + uint64_t addr = pci_dev.bar0 & ~4; // clear upper 2 bits addr |= ((uint64_t)pci_dev.bar1 << 32); diff --git a/tools/pkg/3/poll_test/info.txt b/tools/pkg/3/poll_test/info.txt new file mode 100644 index 0000000..e251bd2 --- /dev/null +++ b/tools/pkg/3/poll_test/info.txt @@ -0,0 +1 @@ +poll_test
\ No newline at end of file diff --git a/tools/pkg/3/poll_test/pkg.sh b/tools/pkg/3/poll_test/pkg.sh new file mode 100644 index 0000000..458be2d --- /dev/null +++ b/tools/pkg/3/poll_test/pkg.sh @@ -0,0 +1,2 @@ + +x86_64-orange-g++ -o "$1/usr/bin/poll_test" src/main.c
\ No newline at end of file diff --git a/tools/pkg/3/poll_test/src/main.c b/tools/pkg/3/poll_test/src/main.c new file mode 100644 index 0000000..4d6fdd2 --- /dev/null +++ b/tools/pkg/3/poll_test/src/main.c @@ -0,0 +1,44 @@ +#include <stdio.h> +#include <poll.h> +#include <unistd.h> + +#include <termios.h> + +#include <string.h> + +int main() { + struct pollfd fds[1]; + fds[0].fd = 0; + fds[0].events = POLLIN; + + struct termios newt; + tcgetattr(STDIN_FILENO, &newt); + newt.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + + printf("Waiting for input (5 second timeout)...\n"); + int ret = poll(fds, 1, 5000); + + if (ret == -1) { + perror("poll"); + return 1; + } else if (ret == 0) { + printf("Timeout !\n"); + } else { + if (fds[0].revents & POLLIN) { + printf("Input ! waiting for string\n"); + char buf[100]; + read(STDIN_FILENO,buf,100); + memset(buf,0,100); + newt.c_lflag |= ICANON | ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + read(STDIN_FILENO,buf,100); + printf("You enter: %s", buf); + } + } + + newt.c_lflag |= ICANON | ECHO; + tcsetattr(STDIN_FILENO, TCSANOW, &newt); + + return 0; +}
\ No newline at end of file |
