aboutsummaryrefslogtreecommitdiff
path: root/qtmips_osemu
diff options
context:
space:
mode:
authorPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-25 14:57:00 +0100
committerPavel Pisa <pisa@cmp.felk.cvut.cz>2019-02-25 14:57:00 +0100
commit1889bd9353b309ea54f3543f5d609015fec5b73c (patch)
treef203dac446435aa395cadbd34ea4d347efdaacd6 /qtmips_osemu
parentca242e325d823bc627ca4e6ff8eca24b888a6113 (diff)
downloadqtmips-1889bd9353b309ea54f3543f5d609015fec5b73c.tar.gz
qtmips-1889bd9353b309ea54f3543f5d609015fec5b73c.tar.bz2
qtmips-1889bd9353b309ea54f3543f5d609015fec5b73c.zip
Simple serial port receive implementation.
Simple polled mode serial port input implemented for serial port peripheral and for read and readv system calls. When end of input character reserve is reached for read/readv, newline is automatically appended. Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
Diffstat (limited to 'qtmips_osemu')
-rw-r--r--qtmips_osemu/ossyscall.cpp81
-rw-r--r--qtmips_osemu/ossyscall.h3
2 files changed, 82 insertions, 2 deletions
diff --git a/qtmips_osemu/ossyscall.cpp b/qtmips_osemu/ossyscall.cpp
index a5748f1..aeee079 100644
--- a/qtmips_osemu/ossyscall.cpp
+++ b/qtmips_osemu/ossyscall.cpp
@@ -62,7 +62,7 @@ static const mips_syscall_desc_t mips_syscall_args[] = {
MIPS_SYS(sys_syscall , 8, syscall_default_handler) /* 4000 */
MIPS_SYS(sys_exit , 1, syscall_default_handler)
MIPS_SYS(sys_fork , 0, syscall_default_handler)
- MIPS_SYS(sys_read , 3, syscall_default_handler)
+ MIPS_SYS(sys_read , 3, do_sys_read)
MIPS_SYS(sys_write , 3, do_sys_write)
MIPS_SYS(sys_open , 3, syscall_default_handler) /* 4005 */
MIPS_SYS(sys_close , 1, syscall_default_handler)
@@ -204,7 +204,7 @@ static const mips_syscall_desc_t mips_syscall_args[] = {
MIPS_SYS(sys_select , 5, syscall_default_handler)
MIPS_SYS(sys_flock , 2, syscall_default_handler)
MIPS_SYS(sys_msync , 3, syscall_default_handler)
- MIPS_SYS(sys_readv , 3, syscall_default_handler) /* 4145 */
+ MIPS_SYS(sys_readv , 3, do_sys_readv) /* 4145 */
MIPS_SYS(sys_writev , 3, do_sys_writev)
MIPS_SYS(sys_cacheflush , 3, syscall_default_handler)
MIPS_SYS(sys_cachectl , 3, syscall_default_handler)
@@ -598,6 +598,83 @@ int OsSyscallExceptionHandler::do_sys_write(std::uint32_t &result, Core *core,
return 0;
}
+// ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
+int OsSyscallExceptionHandler::do_sys_readv(std::uint32_t &result, Core *core,
+ std::uint32_t syscall_num,
+ std::uint32_t a1, std::uint32_t a2, std::uint32_t a3,
+ std::uint32_t a4, std::uint32_t a5, std::uint32_t a6,
+ std::uint32_t a7, std::uint32_t a8) {
+ (void)core; (void)syscall_num;
+ (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; (void)a6; (void)a7; (void)a8;
+
+ result = 0;
+ int fd = a1;
+ std::uint32_t iov = a2;
+ int iovcnt = a3;
+ MemoryAccess *mem = core->get_mem_data();
+ bool available;
+ unsigned int byte;
+
+ printf("sys_readv to fd %d\n", fd);
+
+ while (iovcnt-- > 0) {
+ std::uint32_t iov_base = mem->read_word(iov);
+ std::uint32_t iov_len = mem->read_word(iov + 4);
+ iov += 8;
+ available = true;
+ for (std::uint32_t i = 0; i < iov_len; i++) {
+ emit rx_byte_pool(fd, byte, available);
+ if (!available) {
+ // add final newline if there are no more data
+ mem->write_byte(iov_base++, '\n');
+ result += 1;
+ break;
+ }
+ mem->write_byte(iov_base++, byte);
+ result += 1;
+ }
+ if (!available)
+ break;
+ }
+
+ return 0;
+}
+
+// ssize_t read(int fd, void *buf, size_t count);
+int OsSyscallExceptionHandler::do_sys_read(std::uint32_t &result, Core *core,
+ std::uint32_t syscall_num,
+ std::uint32_t a1, std::uint32_t a2, std::uint32_t a3,
+ std::uint32_t a4, std::uint32_t a5, std::uint32_t a6,
+ std::uint32_t a7, std::uint32_t a8) {
+ (void)core; (void)syscall_num;
+ (void)a1; (void)a2; (void)a3; (void)a4; (void)a5; (void)a6; (void)a7; (void)a8;
+
+ result = 0;
+ int fd = a1;
+ std::uint32_t buf = a2;
+ int size = a3;
+ MemoryAccess *mem = core->get_mem_data();
+ bool available;
+ unsigned int byte;
+
+ printf("sys_read to fd %d\n", fd);
+
+ result = 0;
+ while (size-- > 0) {
+ emit rx_byte_pool(fd, byte, available);
+ if (!available) {
+ // add final newline if there are no more data
+ mem->write_byte(buf++, '\n');
+ result += 1;
+ break;
+ }
+ mem->write_byte(buf++, byte);
+ result += 1;
+ }
+
+ return 0;
+}
+
// int or void * brk(void *addr);
int OsSyscallExceptionHandler::do_sys_brk(std::uint32_t &result, Core *core,
std::uint32_t syscall_num,
diff --git a/qtmips_osemu/ossyscall.h b/qtmips_osemu/ossyscall.h
index 00b6575..0c02699 100644
--- a/qtmips_osemu/ossyscall.h
+++ b/qtmips_osemu/ossyscall.h
@@ -66,10 +66,13 @@ public:
OSSYCALL_HANDLER_DECLARE(do_sys_set_thread_area);
OSSYCALL_HANDLER_DECLARE(do_sys_writev);
OSSYCALL_HANDLER_DECLARE(do_sys_write);
+ OSSYCALL_HANDLER_DECLARE(do_sys_readv);
+ OSSYCALL_HANDLER_DECLARE(do_sys_read);
OSSYCALL_HANDLER_DECLARE(do_sys_brk);
OSSYCALL_HANDLER_DECLARE(do_sys_mmap2);
signals:
void char_written(int fd, unsigned int val);
+ void rx_byte_pool(int fd, unsigned int &data, bool &available);
private:
std::uint32_t brk_limit;
std::uint32_t anonymous_base;