Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pc-tty: add PS/2 mouse support and kbd/mouse vdevs #512

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions tty/pc-tty/event_queue.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Phoenix-RTOS
*
* Simple circular buffer for enqueueing PS/2 events
*
* Copyright 2024 Phoenix Systems
* Author: Adam Greloch
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#include <errno.h>
adamgreloch marked this conversation as resolved.
Show resolved Hide resolved
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/threads.h>
#include <sys/minmax.h>

#include "event_queue.h"


int event_queue_init(event_queue_t *eq)
{
int err;

if (eq == NULL) {
return -EINVAL;
}

(void)memset(eq, 0, sizeof(event_queue_t));

err = mutexCreate(&eq->mutex);
if (err < 0) {
return err;
}

err = condCreate(&eq->waitq);
if (err < 0) {
resourceDestroy(eq->mutex);
return err;
}

return EOK;
}


int event_queue_put(event_queue_t *eq, unsigned char event, unsigned int notify_cnt)
{
if (eq == NULL) {
return -EINVAL;
}

int bytes = 0;

mutexLock(eq->mutex);
if (eq->cnt < TTYPC_EQBUF_SIZE) {
eq->buf[eq->w] = event;
eq->w = (eq->w + 1u) % TTYPC_EQBUF_SIZE;
eq->cnt++;
if (eq->cnt >= notify_cnt) {
condSignal(eq->waitq);
}
bytes = 1;
}
mutexUnlock(eq->mutex);

return bytes;
}


int event_queue_get(event_queue_t *eq, void *dest, unsigned int size, unsigned int flags)
{
int err;
unsigned int bytes;

if (eq == NULL || dest == NULL) {
return -EINVAL;
}

if (size == 0u) {
return 0;
}

if (size > TTYPC_EQBUF_SIZE) {
size = TTYPC_EQBUF_SIZE;
}

mutexLock(eq->mutex);
do {
if ((flags & O_NONBLOCK) != 0 && eq->cnt < size) {
err = -EWOULDBLOCK;
break;
}

while (eq->cnt < size) {
condWait(eq->waitq, eq->mutex, 0);
}

if (eq->w > eq->r) {
(void)memcpy(dest, eq->buf + eq->r, bytes = size);
}
else {
(void)memcpy(dest, eq->buf + eq->r, bytes = min(size, TTYPC_EQBUF_SIZE - eq->r));

if (bytes < size) {
size -= bytes;
(void)memcpy((uintptr_t *)dest + bytes, eq->buf, size);
bytes += size;
}
}

eq->r = (eq->r + bytes) % TTYPC_EQBUF_SIZE;
eq->cnt -= bytes;

err = bytes;
} while (0);
mutexUnlock(eq->mutex);

return err;
}


int event_queue_count(event_queue_t *eq)
{
int res;

if (eq == NULL) {
return -EINVAL;
}

mutexLock(eq->mutex);
res = eq->cnt;
mutexUnlock(eq->mutex);

return res;
}


void event_queue_destroy(event_queue_t *eq)
{
if (eq == NULL) {
return;
}

resourceDestroy(eq->waitq);
resourceDestroy(eq->mutex);
}
54 changes: 54 additions & 0 deletions tty/pc-tty/event_queue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Phoenix-RTOS
*
* Simple circular buffer for enqueueing PS/2 events
*
* Copyright 2024 Phoenix Systems
* Author: Adam Greloch
*
* This file is part of Phoenix-RTOS.
*
* %LICENSE%
*/


#ifndef _EVENT_QUEUE_H_
#define _EVENT_QUEUE_H_

#include <sys/threads.h>

#define TTYPC_EQBUF_SIZE 258u /* should be a multiple of 3 for mouse events */

typedef struct _event_queue_t {
unsigned char buf[TTYPC_EQBUF_SIZE];
unsigned int cnt;
unsigned int r;
unsigned int w;
handle_t mutex;
handle_t waitq;
} event_queue_t;


/* Initializes event queue */
extern int event_queue_init(event_queue_t *eq);


/* Puts a byte to event queue. If the queue has notify_cnt bytes or more, wake
the readers. If the queue is full, does nothing and returns 0. If event was
put, returns 1. */
extern int event_queue_put(event_queue_t *eq, unsigned char event, unsigned int notify_cnt);


/* Reads data from event queue */
extern int event_queue_get(event_queue_t *eq, void *dest, unsigned int size, unsigned int flags);


/* Retrieves number of bytes stored in event queue */
extern int event_queue_count(event_queue_t *eq);


/* Destroys event queue */
extern void event_queue_destroy(event_queue_t *eq);


#endif
77 changes: 50 additions & 27 deletions tty/pc-tty/ttypc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,61 +18,84 @@
#include <sys/types.h>

#include "ttypc_vt.h"
#include "board_config.h"
#include "event_queue.h"


/* Number of virtual terminals */
#define NVTS 4


/* Keyboard types */
enum { KBD_BIOS, KBD_PS2 };
enum { KBD_BIOS,
KBD_PS2 };


/* Keyboard key types */
enum {
KB_NONE = 0x0000,
KB_CTL = 0x0001,
KB_SHIFT = 0x0002,
KB_ALT = 0x0004,
KB_ALTGR = 0x0008,
KB_SCROLL = 0x0010,
KB_NUM = 0x0020,
KB_CAPS = 0x0040,
KB_FUNC = 0x0080,
KB_ASCII = 0x0100,
KB_KP = 0x0200,
KB_EXT = 0x0400
KB_NONE = 0x0000,
KB_CTL = 0x0001,
KB_SHIFT = 0x0002,
KB_ALT = 0x0004,
KB_ALTGR = 0x0008,
KB_SCROLL = 0x0010,
KB_NUM = 0x0020,
KB_CAPS = 0x0040,
KB_FUNC = 0x0080,
KB_ASCII = 0x0100,
KB_KP = 0x0200,
KB_EXT = 0x0400
};


struct _ttypc_t {
unsigned int port; /* Driver port */
unsigned int port; /* Driver port */

/* VGA */
volatile void *vga; /* VGA screen memory */
void *crtc; /* Video Display Controller (CRTC) */
unsigned color; /* Color support */
volatile void *vga; /* VGA screen memory */
void *crtc; /* Video Display Controller (CRTC) */
unsigned color; /* Color support */

/* KBD */
volatile void *kbd; /* Keyboard controller */
unsigned char ktype; /* Keyboard type */
unsigned char lockst; /* Lock keys state */
unsigned char shiftst; /* Shift keys state */
unsigned int kirq; /* Interrupt number */
handle_t klock; /* Interrupt mutex */
handle_t kcond; /* Interrupt condition variable */
handle_t kinth; /* Interrupt handle */
handle_t kmcond; /* Kbd/mouse interrupt condition variable */

unsigned int kirq; /* Kbd interrupt number */
handle_t klock; /* Kbd interrupt mutex */
handle_t kinth; /* Kbd interrupt handle */

#if PC_TTY_MOUSE_ENABLE
unsigned int mirq; /* Mouse interrupt number */
handle_t minth; /* Mouse interrupt handle */
#endif

#if PC_TTY_CREATE_PS2_VDEVS
event_queue_t keq; /* Kbd event buffer */
unsigned int kport; /* Kbd device port */

/* Kbd pool thread stack */
char kpstack[1024] __attribute__((aligned(8)));
#if PC_TTY_MOUSE_ENABLE
event_queue_t meq; /* Mouse event buffer */
unsigned int mport; /* Mouse device port */

/* Mouse pool thread stack */
char mpstack[1024] __attribute__((aligned(8)));
#endif
#endif

/* Virtual terminals */
ttypc_vt_t *vt; /* Active virtual terminal */
ttypc_vt_t vts[NVTS]; /* Virtual Terminals */
ttypc_vt_t *vt; /* Active virtual terminal */
ttypc_vt_t vts[NVTS]; /* Virtual Terminals */

/* Synchronization */
handle_t lock; /* Access mutex */
handle_t lock; /* Access mutex */

/* Thread stacks */
char kstack[2048] __attribute__ ((aligned(8)));
char pstack[2048] __attribute__ ((aligned(8)));
char kstack[2048] __attribute__((aligned(8)));
char pstack[2048] __attribute__((aligned(8)));
};


Expand Down
Loading
Loading