Files
mango/include/socks/tty.h
Max Wash b0c021d4e9 kernel: add kernel.early-console and kernel.console boot args
kernel.early-console is used to specify which output device the
kernel boot log should be written to. the first thing the kernel
does on boot after initialising the bootstrap processor is initialise
the early console, making it useful for debugging problems that
occur early in the boot process. this arg accepts a list of hard-coded
values for output devices, such as tty0 for the display or ttyS0
for the serial port. the exact values supported will depend on the
platform.

once all drivers are loaded, the kernel switches to the device specified
by kernel.console for output. unlike kernel.early-console, this arg
specifies the name of a tty device in /dev/tty. this means that, not
only are more devices supported (any device provided by a tty driver),
but the kernel can also get input from the user using this console too
(not used by the kernel itself, but will be used by the user to interact
with userspace programs, like the shell).
2023-12-30 09:09:18 +00:00

146 lines
4.7 KiB
C

#ifndef SOCKS_TTY_H_
#define SOCKS_TTY_H_
#include <socks/status.h>
#include <socks/device.h>
#include <socks/queue.h>
#include <socks/object.h>
#include <socks/termios.h>
#include <stdint.h>
#define TTY_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_CHAR ? (dev)->chr.c_tty : NULL)
#define TTY_DRIVER(drv) ((struct tty_driver *)((char *)drv - offsetof(struct tty_driver, tty_base)))
#define TTY_INPUT_QUEUE_SIZE 256
#define TTY_LINE_MAX 4096
struct kext;
/* The TTY system.
TTYs are an enhanced version of the console object. Rather than a simple output
device for log messages, TTYs are intended to support fully-featured interactive
user sessions, including advanced display manipulation (if applicable) and
buffered user input.
A TTY object is split into 2 parts:
- struct tty: This represents the terminal session, and tracks things like the cursor
position, input buffer, flags, etc.
- struct tty_driver: This is a set of function callbacks that the TTY can use to
manipulate the output device. This could represent a char-based framebuffer
device, a serial port, etc.
*/
#ifdef __cplusplus
extern "C" {
#endif
enum tty_driver_type {
/* For TTYs operating on simple IO devices like serial ports.
Allows writing characters, receiving characters, and not much else. */
TTY_DRIVER_SIMPLE,
/* For TTYs operating on more capable display interfaces.
Allows putting characters at arbitrary locations, scrolling, etc */
TTY_DRIVER_FULL,
};
/* TTY cursor status. The extra cursor styles are just for completeness,
the important one to support (if possible), is TTY_CURSOR_NONE.
The others can be interpreted as "just turn on a cursor of any style". */
enum tty_cursor {
TTY_CURSOR_ULINE,
TTY_CURSOR_BLOCK,
TTY_CURSOR_NONE,
};
/* direction to use for scrolling. The important one to support is
TTY_SCROLL_DOWN for when output overflows the display */
enum tty_scroll_dir {
TTY_SCROLL_DOWN,
TTY_SCROLL_UP,
};
enum tty_modifier_key {
TTY_KEY_OTHER = 0x00u,
TTY_KEY_CTRL = 0x01u,
TTY_KEY_ALT = 0x02u,
TTY_KEY_SHIFT = 0x04u,
};
/* character attribute. this could be as simple as VGA's 16-colour palette
plus an extra bit for bright, or a full 24-bit RGB value with bold and underline
support, depending on what the driver supports. */
typedef uint64_t tty_attrib_t;
struct tty_driver_ops {
void (*tty_init)(struct device *dev);
void (*tty_deinit)(struct device *dev);
void (*tty_clear)(struct device *dev, int x, int y, int width, int height);
void (*tty_putc)(struct device *dev, int c, int xpos, int ypos, tty_attrib_t attrib);
void (*tty_set_cursor)(struct device *dev, enum tty_cursor cur);
void (*tty_move_cursor)(struct device *dev, int x, int y);
void (*tty_scroll)(struct device *dev, enum tty_scroll_dir dir, int lines);
};
struct tty_driver {
struct driver tty_base;
char tty_name[16];
enum tty_driver_type tty_type;
struct queue_entry tty_head;
struct tty_driver_ops *tty_ops;
};
struct tty_ldisc {
char name[OBJECT_NAME_MAX];
kern_status_t(*read)(struct device *, void *, size_t, size_t *, socks_flags_t);
void(*write)(struct device *, const struct input_event *);
};
struct tty_device {
unsigned int tty_xcells, tty_ycells;
unsigned int tty_xcur, tty_ycur;
struct termios tty_config;
tty_attrib_t tty_curattrib;
enum tty_modifier_key tty_modstate;
struct tty_ldisc *tty_ldisc;
/* input characters processed from tty_events, returned by tty_read() */
struct ringbuffer tty_input;
char *tty_linebuf;
};
extern void register_tty_console(void);
extern void redirect_printk_to_tty(struct device *dest);
extern kern_status_t tty_bootstrap(void);
extern struct tty_ldisc *tty_default_line_discipline(void);
extern struct device *tty_device_create(void);
extern kern_status_t tty_device_register(struct device *dev, struct tty_driver *owner, struct device *parent);
extern void tty_set_foreground(struct device *tty);
extern kern_status_t tty_connect_foreground_input_device(struct device *input);
extern struct tty_driver *tty_driver_create(struct kext *self, const char *name);
extern kern_status_t tty_driver_destroy(struct tty_driver *drv);
extern kern_status_t tty_driver_register(struct tty_driver *drv);
extern kern_status_t tty_driver_unregister(struct tty_driver *drv);
static inline struct driver *tty_driver_base(struct tty_driver *drv)
{
return &drv->tty_base;
}
extern kern_status_t tty_read(struct device *tty, void *buf, size_t offset, size_t max, size_t *nr_read, socks_flags_t flags);
extern kern_status_t tty_write(struct device *tty, const void *buf, size_t offset, size_t len, size_t *nr_written, socks_flags_t flags);
extern kern_status_t tty_report_event(struct device *tty, const struct input_event *ev);
#ifdef __cplusplus
}
#endif
#endif