[testapp] Re-add testapp to default manifest

This commit re-adds testapp to the default manifest and does some
housecleaning on the module:

- Remove the old serial.* and io.*
- Update it to use current syscall APIs
- Update it to use libj6's higher-level thread API
This commit is contained in:
Justin C. Miller
2023-02-08 22:44:05 -08:00
parent f05a1d3310
commit 1cb8f1258d
8 changed files with 30 additions and 174 deletions

View File

@@ -45,6 +45,12 @@ thread::start()
return m_status;
}
void
thread::join()
{
j6_thread_join(m_thread);
}
}
#endif // __j6kernel

View File

@@ -1,22 +0,0 @@
#include "io.h"
uint8_t
inb(uint16_t port)
{
uint8_t val;
__asm__ __volatile__ ( "inb %1, %0" : "=a"(val) : "Nd"(port) );
return val;
}
void
outb(uint16_t port, uint8_t val)
{
__asm__ __volatile__ ( "outb %0, %1" :: "a"(val), "Nd"(port) );
}
void
io_wait(unsigned times)
{
for (unsigned i = 0; i < times; ++i)
outb(0x80, 0);
}

View File

@@ -1,24 +0,0 @@
#pragma once
#include <stdint.h>
extern "C" {
/// Read a byte from an IO port.
/// \arg port The address of the IO port
/// \returns One byte read from the port
uint8_t inb(uint16_t port);
/// Write a byte to an IO port.
/// \arg port The addres of the IO port
/// \arg val The byte to write
void outb(uint16_t port, uint8_t val);
/// Pause briefly by doing IO to port 0x80
/// \arg times Number of times to delay by writing
void io_wait(unsigned times = 1);
}
constexpr uint16_t COM1 = 0x03f8;
constexpr uint16_t COM2 = 0x02f8;

View File

@@ -1,13 +1,11 @@
#include <stdint.h>
#include <stdlib.h>
#include <j6/types.h>
#include <j6/errors.h>
#include <j6/flags.h>
#include <j6/syscalls.h>
#include "io.h"
#include "serial.h"
#include <j6/thread.hh>
#include <j6/types.h>
char inbuf[1024];
extern j6_handle_t __handle_sys;
@@ -17,10 +15,10 @@ extern "C" {
int main(int, const char **);
}
constexpr j6_handle_t handle_self = 1; // Self program handle is always 1
extern j6_handle_t __handle_self;
constexpr size_t stack_size = 0x10000;
constexpr uintptr_t stack_top = 0xf80000000;
uint32_t flipflop = 0;
void
thread_proc()
@@ -29,10 +27,13 @@ thread_proc()
char buffer[512];
size_t len = sizeof(buffer);
j6_tag_t tag = 0;
j6_status_t result = j6_endpoint_receive(endp, &tag, (void*)buffer, &len);
j6_status_t result = j6_channel_receive(endp, (void*)buffer, &len, j6_channel_block);
__sync_synchronize();
flipflop = 1;
if (result != j6_status_ok)
j6_thread_exit(result);
j6_thread_exit();
j6_log("sub thread received message");
@@ -40,10 +41,9 @@ thread_proc()
if (buffer[i] >= 'A' && buffer[i] <= 'Z')
buffer[i] += 0x20;
tag++;
result = j6_endpoint_send(endp, tag, (void*)buffer, len);
result = j6_channel_send(endp, (void*)buffer, &len);
if (result != j6_status_ok)
j6_thread_exit(result);
j6_thread_exit();
j6_log("sub thread sent message");
@@ -51,7 +51,7 @@ thread_proc()
j6_thread_sleep(i*10);
j6_log("sub thread exiting");
j6_thread_exit(0);
j6_thread_exit();
}
int
@@ -74,72 +74,36 @@ main(int argc, const char **argv)
j6_log("main thread wrote to memory area");
j6_status_t result = j6_endpoint_create(&endp);
j6_status_t result = j6_channel_create(&endp);
if (result != j6_status_ok)
return result;
j6_log("main thread created endpoint");
j6_log("main thread created channel");
j6_handle_t child_stack_vma = j6_handle_invalid;
result = j6_vma_create_map(&child_stack_vma, stack_size, stack_top-stack_size, j6_vm_flag_write);
if (result != j6_status_ok)
return result;
j6_handle_t child = j6_handle_invalid;
result = j6_thread_create(&child, handle_self, stack_top, reinterpret_cast<uintptr_t>(&thread_proc));
j6::thread child_thread {thread_proc, stack_top};
result = child_thread.start();
if (result != j6_status_ok)
return result;
j6_log("main thread created sub thread");
char message[] = "MAIN THREAD SUCCESSFULLY CALLED SENDRECV IF THIS IS LOWERCASE";
char message[] = "MAIN THREAD SUCCESSFULLY CALLED SEND AND RECEIVE IF THIS IS LOWERCASE";
size_t size = sizeof(message);
j6_tag_t tag = 16;
result = j6_endpoint_sendrecv(endp, &tag, (void*)message, &size);
result = j6_channel_send(endp, (void*)message, &size);
if (result != j6_status_ok)
return result;
if (tag != 17)
j6_log("GOT WRONG TAG FROM SENDRECV");
while (!flipflop);
result = j6_system_bind_irq(__handle_sys, endp, 3);
result = j6_channel_receive(endp, (void*)message, &size, j6_channel_block);
if (result != j6_status_ok)
return result;
j6_log(message);
j6_log("main thread waiting on sub thread");
result = j6_kobject_wait(child, -1ull, &out);
if (result != j6_status_ok)
return result;
j6_log("main setting IOPL");
result = j6_system_request_iopl(__handle_sys, 3);
if (result != j6_status_ok)
return result;
j6_log("main testing irqs");
serial_port com2(COM2);
const char *fgseq = "\x1b[2J";
while (*fgseq)
com2.write(*fgseq++);
for (int i = 0; i < 10; ++i)
com2.write('%');
size_t len = 0;
while (true) {
result = j6_endpoint_receive(endp, &tag, nullptr, &len);
if (result != j6_status_ok)
return result;
if (j6_tag_is_irq(tag))
j6_log("main thread got irq!");
}
child_thread.join();
j6_log("main thread done, exiting");
return 0;

View File

@@ -1,41 +0,0 @@
#include "io.h"
#include "serial.h"
serial_port::serial_port() :
m_port(0)
{
}
serial_port::serial_port(uint16_t port) :
m_port(port)
{
outb(port + 1, 0x00); // Disable all interrupts
outb(port + 3, 0x80); // Enable the Divisor Latch Access Bit
outb(port + 0, 0x01); // Divisor low bit: 1 (115200 baud)
outb(port + 1, 0x00); // Divisor high bit
outb(port + 3, 0x03); // 8-N-1
outb(port + 2, 0xe7); // Clear and enable FIFO, enable 64 byte, 56 byte trigger
outb(port + 4, 0x0b); // Data terminal ready, Request to send, aux output 2 (irq enable)
outb(port + 1, 0x03); // Enable interrupts
}
bool serial_port::read_ready() { return (inb(m_port + 5) & 0x01) != 0; }
bool serial_port::write_ready() {
uint8_t lsr = inb(m_port + 5);
return (lsr & 0x20) != 0;
}
char
serial_port::read() {
while (!read_ready());
return inb(m_port);
}
void
serial_port::write(char c) {
while (!write_ready());
outb(m_port, c);
}

View File

@@ -1,26 +0,0 @@
#pragma once
/// \file serial.h
/// Declarations related to serial ports.
#include <stdint.h>
#define serial_port nulldrv_serial_port
class serial_port
{
public:
/// Constructor.
/// \arg port The IO address of the serial port
serial_port(uint16_t port);
serial_port();
void write(char c);
char read();
private:
uint16_t m_port;
bool read_ready();
bool write_ready();
};

View File

@@ -5,7 +5,5 @@ module("testapp",
deps = [ "libc" ],
description = "Testbed app",
sources = [
"io.cpp",
"main.cpp",
"serial.cpp",
])