aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qtmips_gui/mainwindow.cpp2
-rw-r--r--qtmips_gui/terminaldock.cpp17
-rw-r--r--qtmips_gui/terminaldock.h4
-rw-r--r--qtmips_machine/serialport.cpp22
-rw-r--r--qtmips_machine/serialport.h5
-rw-r--r--qtmips_osemu/ossyscall.cpp81
-rw-r--r--qtmips_osemu/ossyscall.h3
7 files changed, 130 insertions, 4 deletions
diff --git a/qtmips_gui/mainwindow.cpp b/qtmips_gui/mainwindow.cpp
index 253ab03..01321cf 100644
--- a/qtmips_gui/mainwindow.cpp
+++ b/qtmips_gui/mainwindow.cpp
@@ -154,6 +154,8 @@ void MainWindow::create_core(const machine::MachineConfig &config) {
osemu::OsSyscallExceptionHandler *osemu_handler = new osemu::OsSyscallExceptionHandler;
machine->register_exception_handler(machine::EXCAUSE_SYSCALL, osemu_handler);
connect(osemu_handler, SIGNAL(char_written(int,uint)), terminal, SLOT(tx_byte(int,uint)));
+ connect(osemu_handler, SIGNAL(rx_byte_pool(int,uint&,bool&)),
+ terminal, SLOT(rx_byte_pool(int,uint&,bool&)));
#endif
// Connect machine signals and slots
diff --git a/qtmips_gui/terminaldock.cpp b/qtmips_gui/terminaldock.cpp
index 4b394a6..bb26952 100644
--- a/qtmips_gui/terminaldock.cpp
+++ b/qtmips_gui/terminaldock.cpp
@@ -49,6 +49,11 @@ TerminalDock::TerminalDock(QWidget *parent, QSettings *settings) : QDockWidget(p
terminal_text->setMinimumSize(30, 30);
layout_box->addWidget(terminal_text);
append_cursor = new QTextCursor(terminal_text->document());
+ layout_bottom_box = new QHBoxLayout();
+ layout_bottom_box->addWidget(new QLabel("Input:"));
+ input_edit = new QLineEdit();
+ layout_bottom_box->addWidget(input_edit);
+ layout_box->addLayout(layout_bottom_box);
setObjectName("Terminal");
setWindowTitle("Terminal");
@@ -62,6 +67,8 @@ void TerminalDock::setup(const machine::SerialPort *ser_port) {
if (ser_port == nullptr)
return;
connect(ser_port, SIGNAL(tx_byte(uint)), this, SLOT(tx_byte(uint)));
+ connect(ser_port, SIGNAL(rx_byte_pool(int,uint&,bool&)),
+ this, SLOT(rx_byte_pool(int,uint&,bool&)));
}
void TerminalDock::tx_byte(unsigned int data) {
@@ -76,3 +83,13 @@ void TerminalDock::tx_byte(int fd, unsigned int data)
(void)fd;
tx_byte(data);
}
+
+void TerminalDock::rx_byte_pool(int fd, unsigned int &data, bool &available) {
+ QString str = input_edit->text();
+ available = false;
+ if (str.count() > 0) {
+ data = str[0].toLatin1();
+ input_edit->setText(str.remove(0, 1));
+ available = true;
+ }
+}
diff --git a/qtmips_gui/terminaldock.h b/qtmips_gui/terminaldock.h
index 7154e81..27dc617 100644
--- a/qtmips_gui/terminaldock.h
+++ b/qtmips_gui/terminaldock.h
@@ -39,6 +39,7 @@
#include <QDockWidget>
#include <QLabel>
#include <QFormLayout>
+#include <QLineEdit>
#include <QTextEdit>
#include <QTextCursor>
#include "qtmipsmachine.h"
@@ -54,13 +55,16 @@ public:
public slots:
void tx_byte(unsigned int data);
void tx_byte(int fd, unsigned int data);
+ void rx_byte_pool(int fd, unsigned int &data, bool &available);
private:
QVBoxLayout *layout_box;
+ QHBoxLayout *layout_bottom_box;
QWidget *top_widget, *top_form;
QFormLayout *layout_top_form;
QTextEdit *terminal_text;
QTextCursor *append_cursor;
+ QLineEdit *input_edit;
};
#endif // TERMINALDOCK_H
diff --git a/qtmips_machine/serialport.cpp b/qtmips_machine/serialport.cpp
index 9e4177b..c636d38 100644
--- a/qtmips_machine/serialport.cpp
+++ b/qtmips_machine/serialport.cpp
@@ -51,6 +51,7 @@ using namespace machine;
SerialPort::SerialPort() {
rx_st_reg = 0;
+ rx_data_reg = 0;
tx_st_reg = 0;
}
@@ -58,6 +59,18 @@ SerialPort::~SerialPort() {
}
+void SerialPort::pool_rx_byte() const {
+ unsigned int byte = 0;
+ bool available = false;
+ if (!(rx_st_reg & SERP_RX_ST_REG_READY_m)) {
+ emit rx_byte_pool(0, byte, available);
+ if (available) {
+ rx_data_reg = byte;
+ rx_st_reg |= SERP_RX_ST_REG_READY_m;
+ }
+ }
+}
+
bool SerialPort::wword(std::uint32_t address, std::uint32_t value) {
#if 0
printf("SerialPort::wword address 0x%08lx data 0x%08lx\n",
@@ -90,10 +103,17 @@ std::uint32_t SerialPort::rword(std::uint32_t address, bool debug_access) const
#endif
switch (address) {
case SERP_RX_ST_REG_o:
+ pool_rx_byte();
value = rx_st_reg;
break;
case SERP_RX_DATA_REG_o:
- value = 0;
+ pool_rx_byte();
+ if (rx_st_reg & SERP_RX_ST_REG_READY_m) {
+ value = rx_data_reg;
+ rx_st_reg &= ~SERP_RX_ST_REG_READY_m;
+ } else {
+ value = 0;
+ }
break;
case SERP_TX_ST_REG_o:
value = tx_st_reg | SERP_TX_ST_REG_READY_m;
diff --git a/qtmips_machine/serialport.h b/qtmips_machine/serialport.h
index add1fe6..5262720 100644
--- a/qtmips_machine/serialport.h
+++ b/qtmips_machine/serialport.h
@@ -52,6 +52,7 @@ public:
signals:
void tx_byte(unsigned int data);
+ void rx_byte_pool(int fd, unsigned int &data, bool &available) const;
void write_notification(std::uint32_t address, std::uint32_t value);
void read_notification(std::uint32_t address, std::uint32_t *value) const;
@@ -59,7 +60,9 @@ public:
bool wword(std::uint32_t address, std::uint32_t value);
std::uint32_t rword(std::uint32_t address, bool debug_access = false) const;
private:
- std::uint32_t rx_st_reg;
+ void pool_rx_byte() const;
+ mutable std::uint32_t rx_st_reg;
+ mutable std::uint32_t rx_data_reg;
std::uint32_t tx_st_reg;
};
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;