summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpplover0 <osdev555@yandex.com>2025-09-24 21:13:52 +0300
committercpplover0 <osdev555@yandex.com>2025-09-24 21:13:52 +0300
commitaf06ca180e33f80fd9e95f2101e6a17728fc7178 (patch)
tree3b21714de97477969a9e45dedb253d08e69288d9
parentd87d454c4d9069a04d610feee34a7961242c1c89 (diff)
sys_poll()
-rw-r--r--kernel/include/arch/x86_64/syscalls/sockets.hpp3
-rw-r--r--kernel/include/arch/x86_64/syscalls/syscalls.hpp10
-rw-r--r--kernel/include/etc/list.hpp5
-rw-r--r--kernel/include/generic/vfs/fd.hpp2
-rw-r--r--kernel/include/generic/vfs/vfs.hpp44
-rw-r--r--kernel/src/arch/x86_64/interrupts/panic.cpp16
-rw-r--r--kernel/src/arch/x86_64/syscalls/file.cpp128
-rw-r--r--kernel/src/arch/x86_64/syscalls/process.cpp2
-rw-r--r--kernel/src/arch/x86_64/syscalls/sockets.cpp11
-rw-r--r--kernel/src/arch/x86_64/syscalls/syscalls.cpp4
-rw-r--r--kernel/src/drivers/tsc.cpp8
-rw-r--r--kernel/src/generic/vfs/devfs.cpp33
-rw-r--r--kernel/src/generic/vfs/vfs.cpp189
-rw-r--r--tools/pkg/2/init/src/include/etc.hpp24
-rw-r--r--tools/pkg/2/xhci_driver/src/main.cpp45
-rw-r--r--tools/pkg/3/poll_test/info.txt1
-rw-r--r--tools/pkg/3/poll_test/pkg.sh2
-rw-r--r--tools/pkg/3/poll_test/src/main.c44
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