Basic VM and other minor improvements.

Not complete, probably not fully debugged or optimized.
This commit is contained in:
Ben Gras
2008-11-19 12:26:10 +00:00
parent c888305e21
commit c078ec0331
273 changed files with 10814 additions and 4305 deletions

View File

@@ -20,61 +20,27 @@
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/vm.h>
#include <sys/video.h>
#include <minix/tty.h>
#include <minix/callnr.h>
#include <minix/com.h>
#include <minix/sys_config.h>
#include "tty.h"
#include "../../kernel/const.h"
#include "../../kernel/config.h"
#include "../../kernel/type.h"
/* Set this to 1 if you want console output duplicated on the first
* serial line.
*/
#define DUP_CONS_TO_SER 0
/* Definitions used by the console driver. */
#define MONO_BASE 0xB0000L /* base of mono video memory */
#define COLOR_BASE 0xB8000L /* base of color video memory */
#define MONO_SIZE 0x1000 /* 4K mono video memory */
#define COLOR_SIZE 0x4000 /* 16K color video memory */
#define EGA_SIZE 0x8000 /* EGA & VGA have at least 32K */
#define BLANK_COLOR 0x0700 /* determines cursor color on blank screen */
#define SCROLL_UP 0 /* scroll forward */
#define SCROLL_DOWN 1 /* scroll backward */
#define BLANK_MEM ((u16_t *) 0) /* tells mem_vid_copy() to blank the screen */
#define CONS_RAM_WORDS 80 /* video ram buffer size */
#define MAX_ESC_PARMS 4 /* number of escape sequence params allowed */
/* Constants relating to the controller chips. */
#define M_6845 0x3B4 /* port for 6845 mono */
#define C_6845 0x3D4 /* port for 6845 color */
#define INDEX 0 /* 6845's index register */
#define DATA 1 /* 6845's data register */
#define STATUS 6 /* 6845's status register */
#define VID_ORG 12 /* 6845's origin register */
#define CURSOR 14 /* 6845's cursor register */
/* The clock task should provide an interface for this */
#define TIMER_FREQ 1193182L /* clock frequency for timer in PC and AT */
/* Beeper. */
#define BEEP_FREQ 0x0533 /* value to put into timer to set beep freq */
#define B_TIME 3 /* length of CTRL-G beep is ticks */
/* definitions used for font management */
#define GA_SEQUENCER_INDEX 0x3C4
#define GA_SEQUENCER_DATA 0x3C5
#define GA_GRAPHICS_INDEX 0x3CE
#define GA_GRAPHICS_DATA 0x3CF
#define GA_VIDEO_ADDRESS 0xA0000L
#define GA_FONT_SIZE 8192
/* Global variables used by the console driver and assembly support. */
PUBLIC int vid_index; /* index of video segment in remote mem map */
PUBLIC u16_t vid_seg;
PUBLIC vir_bytes vid_off; /* video ram is found at vid_seg:vid_off */
PUBLIC unsigned vid_size; /* 0x2000 for color or 0x0800 for mono */
PUBLIC phys_bytes vid_size; /* 0x2000 for color or 0x0800 for mono */
PUBLIC phys_bytes vid_base;
PUBLIC unsigned vid_mask; /* 0x1FFF for color or 0x07FF for mono */
PUBLIC unsigned blank_color = BLANK_COLOR; /* display code for blank */
@@ -87,6 +53,7 @@ PRIVATE unsigned font_lines; /* font lines per character */
PRIVATE unsigned scr_width; /* # characters on a line */
PRIVATE unsigned scr_lines; /* # lines on the screen */
PRIVATE unsigned scr_size; /* # characters on the screen */
PUBLIC unsigned info_location; /* location in video memory of struct */
PRIVATE int disabled_vc = -1; /* Virtual console that was active when
* disable_console was called.
@@ -95,6 +62,9 @@ PRIVATE int disabled_sm; /* Scroll mode to be restored when re-enabling
* console
*/
/* boot_tty_info we use to communicate with the boot code. */
struct boot_tty_info boot_tty_info;
/* Per console data. */
typedef struct console {
tty_t *c_tty; /* associated TTY struct */
@@ -113,11 +83,34 @@ typedef struct console {
int *c_esc_parmp; /* pointer to current escape parameter */
int c_esc_parmv[MAX_ESC_PARMS]; /* list of escape parameters */
u16_t c_ramqueue[CONS_RAM_WORDS]; /* buffer for video RAM */
int c_line; /* line no */
} console_t;
#define UPDATEBOOTINFO(ccons, infofield, value) { \
if(ccons->c_line == 0) { \
boot_tty_info.infofield = value; \
mem_vid_copy((u16_t *) &boot_tty_info, \
info_location/2, sizeof(boot_tty_info)/2); \
} \
}
#define UPDATE_CURSOR(ccons, cursor) { \
ccons->c_cur = cursor; \
UPDATEBOOTINFO(ccons, conscursor, ccons->c_cur); \
if(curcons && ccons == curcons) \
set_6845(CURSOR, ccons->c_cur); \
}
#define UPDATE_ORIGIN(ccons, origin) { \
ccons->c_org = origin; \
UPDATEBOOTINFO(ccons, consorigin, ccons->c_org); \
if (curcons && ccons == curcons) \
set_6845(VID_ORG, ccons->c_org); \
}
PRIVATE int nr_cons= 1; /* actual number of consoles */
PRIVATE console_t cons_table[NR_CONS];
PRIVATE console_t *curcons; /* currently visible */
PRIVATE console_t *curcons = NULL; /* currently visible */
/* Color if using a color controller. */
#define color (vid_port == C_6845)
@@ -142,14 +135,20 @@ FORWARD _PROTOTYPE( void flush, (console_t *cons) );
FORWARD _PROTOTYPE( void parse_escape, (console_t *cons, int c) );
FORWARD _PROTOTYPE( void scroll_screen, (console_t *cons, int dir) );
FORWARD _PROTOTYPE( void set_6845, (int reg, unsigned val) );
FORWARD _PROTOTYPE( void get_6845, (int reg, unsigned *val) );
FORWARD _PROTOTYPE( void stop_beep, (timer_t *tmrp) );
FORWARD _PROTOTYPE( void cons_org0, (void) );
FORWARD _PROTOTYPE( void disable_console, (void) );
FORWARD _PROTOTYPE( void reenable_console, (void) );
FORWARD _PROTOTYPE( int ga_program, (struct sequence *seq) );
FORWARD _PROTOTYPE( int cons_ioctl, (tty_t *tp, int) );
#if DUP_CONS_TO_SER
FORWARD _PROTOTYPE( void ser_putc, (char c) );
#endif
#if 0
FORWARD _PROTOTYPE( void get_6845, (int reg, unsigned *val) );
#endif
/*===========================================================================*
* cons_write *
@@ -174,7 +173,7 @@ int try;
/* Check quickly for nothing to do, so this can be called often without
* unmodular tests elsewhere.
*/
if ((count = tp->tty_outleft) == 0 || tp->tty_inhibited) return;
if ((count = tp->tty_outleft) == 0 || tp->tty_inhibited) return 0;
/* Copy the user bytes to buf[] for decent addressing. Loop over the
* copies, since the user buffer may be much larger than buf[].
@@ -228,6 +227,8 @@ int try;
tp->tty_outcum);
tp->tty_outcum = 0;
}
return 0;
}
/*===========================================================================*
@@ -365,9 +366,9 @@ int dir; /* SCROLL_UP or SCROLL_DOWN */
} else
if (!wrap && cons->c_org + scr_size + scr_width >= cons->c_limit) {
vid_vid_copy(cons->c_org + scr_width, cons->c_start, chars);
cons->c_org = cons->c_start;
UPDATE_ORIGIN(cons, cons->c_start);
} else {
cons->c_org = (cons->c_org + scr_width) & vid_mask;
UPDATE_ORIGIN(cons, (cons->c_org + scr_width) & vid_mask);
}
new_line = (cons->c_org + chars) & vid_mask;
} else {
@@ -378,9 +379,9 @@ int dir; /* SCROLL_UP or SCROLL_DOWN */
if (!wrap && cons->c_org < cons->c_start + scr_width) {
new_org = cons->c_limit - scr_size;
vid_vid_copy(cons->c_org, new_org + scr_width, chars);
cons->c_org = new_org;
UPDATE_ORIGIN(cons, new_org);
} else {
cons->c_org = (cons->c_org - scr_width) & vid_mask;
UPDATE_ORIGIN(cons, (cons->c_org - scr_width) & vid_mask);
}
new_line = cons->c_org;
}
@@ -388,8 +389,6 @@ int dir; /* SCROLL_UP or SCROLL_DOWN */
blank_color = cons->c_blank;
mem_vid_copy(BLANK_MEM, new_line, scr_width);
/* Set the new video origin. */
if (cons == curcons) set_6845(VID_ORG, cons->c_org);
flush(cons);
}
@@ -421,10 +420,8 @@ register console_t *cons; /* pointer to console struct */
if (cons->c_row < 0) cons->c_row = 0;
if (cons->c_row >= scr_lines) cons->c_row = scr_lines - 1;
cur = cons->c_org + cons->c_row * scr_width + cons->c_column;
if (cur != cons->c_cur) {
if (cons == curcons) set_6845(CURSOR, cur);
cons->c_cur = cur;
}
if (cur != cons->c_cur)
UPDATE_CURSOR(cons, cur);
}
/*===========================================================================*
@@ -747,6 +744,7 @@ unsigned val; /* 16-bit value to set it to */
sys_voutb(char_out, 4); /* do actual output */
}
#if 0
/*===========================================================================*
* get_6845 *
*===========================================================================*/
@@ -765,6 +763,7 @@ unsigned *val; /* 16-bit value to set it to */
v2 = v;
*val = (v1 << 8) | v2;
}
#endif
/*===========================================================================*
* beep *
@@ -810,8 +809,7 @@ PRIVATE void beep()
*===========================================================================*/
PUBLIC void do_video(message *m)
{
int i, n, r, ops, watch, safe = 0;
unsigned char c;
int r, safe = 0;
/* Execute the requested device driver function. */
r= EINVAL; /* just in case */
@@ -827,8 +825,10 @@ PUBLIC void do_video(message *m)
break;
case DEV_IOCTL_S:
safe=1;
if (m->TTY_REQUEST == MIOCMAP || m->TTY_REQUEST == MIOCUNMAP)
{
switch(m->TTY_REQUEST) {
case MIOCMAP:
case MIOCUNMAP: {
#if 0
int r, do_map;
struct mapreq mapreq;
@@ -859,8 +859,50 @@ PUBLIC void do_video(message *m)
r= sys_vm_map(safe ? m->POSITION : m->IO_ENDPT,
do_map, (phys_bytes)mapreq.base, mapreq.size,
mapreq.offset);
#else
r = ENOSYS;
printf("tty: %ld used old MIOCMAP interface\n",
safe ? m->POSITION : m->IO_ENDPT);
#endif
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT, r);
return;
}
case TIOCMAPMEM:
case TIOCUNMAPMEM: {
int r, do_map;
struct mapreqvm mapreqvm;
void *result;
do_map= (m->REQUEST == TIOCMAPMEM); /* else unmap */
/* Get request structure */
if(safe) {
r = sys_safecopyfrom(m->IO_ENDPT,
(vir_bytes)m->ADDRESS, 0, (vir_bytes) &mapreqvm,
sizeof(mapreqvm), D);
} else {
r= sys_vircopy(m->IO_ENDPT, D,
(vir_bytes)m->ADDRESS,
SELF, D, (vir_bytes)&mapreqvm,sizeof(mapreqvm));
}
if (r != OK)
{
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT,
r);
return;
}
/* In safe ioctl mode, the POSITION field contains
* the endpt number of the original requestor.
* IO_ENDPT is always FS.
*/
if(do_map) {
} else {
}
tty_reply(TASK_REPLY, m->m_source, m->IO_ENDPT, r);
return;
}
}
r= ENOTTY;
break;
@@ -940,19 +982,19 @@ tty_t *tp;
{
/* Initialize the screen driver. */
console_t *cons;
phys_bytes vid_base;
u16_t bios_columns, bios_crtbase, bios_fontlines;
u8_t bios_rows;
int line;
int s;
static int vdu_initialized = 0;
unsigned page_size;
static unsigned page_size;
/* Associate console and TTY. */
line = tp - &tty_table[0];
if (line >= nr_cons) return;
cons = &cons_table[line];
cons->c_tty = tp;
cons->c_line = line;
tp->tty_priv = cons;
/* Fill in TTY function hooks. */
@@ -987,6 +1029,7 @@ tty_t *tp;
}
if (machine.vdu_ega) vid_size = EGA_SIZE;
wrap = ! machine.vdu_ega;
info_location = vid_size - sizeof(struct boot_tty_info);
s = sys_segctl(&vid_index, &vid_seg, &vid_off, vid_base, vid_size);
@@ -997,7 +1040,8 @@ tty_t *tp;
scr_size = scr_lines * scr_width;
/* There can be as many consoles as video memory allows. */
nr_cons = vid_size / scr_size;
nr_cons = (vid_size - sizeof(struct boot_tty_info)/2) / scr_size;
if (nr_cons > NR_CONS) nr_cons = NR_CONS;
if (nr_cons > 1) wrap = 0;
page_size = vid_size / nr_cons;
@@ -1013,13 +1057,18 @@ tty_t *tp;
blank_color = BLANK_COLOR;
mem_vid_copy(BLANK_MEM, cons->c_start, scr_size);
} else {
int i, n;
/* Set the cursor of the console vty at the bottom. c_cur
* is updated automatically later.
*/
scroll_screen(cons, SCROLL_UP);
cons->c_row = scr_lines - 1;
cons->c_column = 0;
memset(&boot_tty_info, 0, sizeof(boot_tty_info));
UPDATE_CURSOR(cons, cons->c_cur);
UPDATE_ORIGIN(cons, cons->c_org);
boot_tty_info.flags = BTIF_CONSCURSOR | BTIF_CONSORIGIN;
boot_tty_info.magic = TTYMAGIC;
}
select_console(0);
cons_ioctl(tp, 0);
@@ -1045,9 +1094,9 @@ int c;
cons_putk(c);
if (c != 0) {
kmess.km_buf[kmess.km_next] = c; /* put normal char in buffer */
if (kmess.km_size < KMESS_BUF_SIZE)
if (kmess.km_size < _KMESS_BUF_SIZE)
kmess.km_size += 1;
kmess.km_next = (kmess.km_next + 1) % KMESS_BUF_SIZE;
kmess.km_next = (kmess.km_next + 1) % _KMESS_BUF_SIZE;
} else {
notify(LOG_PROC_NR);
}
@@ -1060,9 +1109,8 @@ PUBLIC void do_new_kmess(m)
message *m;
{
/* Notification for a new kernel message. */
struct kmessages kmess; /* kmessages structure */
static struct kmessages kmess; /* kmessages structure */
static int prev_next = 0; /* previous next seen */
int size, next;
int bytes;
int r;
@@ -1081,15 +1129,15 @@ message *m;
/* Print only the new part. Determine how many new bytes there are with
* help of the current and previous 'next' index. Note that the kernel
* buffer is circular. This works fine if less then KMESS_BUF_SIZE bytes
* is new data; else we miss % KMESS_BUF_SIZE here.
* buffer is circular. This works fine if less then _KMESS_BUF_SIZE bytes
* is new data; else we miss % _KMESS_BUF_SIZE here.
* Check for size being positive, the buffer might as well be emptied!
*/
if (kmess.km_size > 0) {
bytes = ((kmess.km_next + KMESS_BUF_SIZE) - prev_next) % KMESS_BUF_SIZE;
bytes = ((kmess.km_next + _KMESS_BUF_SIZE) - prev_next) % _KMESS_BUF_SIZE;
r=prev_next; /* start at previous old */
while (bytes > 0) {
cons_putk( kmess.km_buf[(r%KMESS_BUF_SIZE)] );
cons_putk( kmess.km_buf[(r%_KMESS_BUF_SIZE)] );
bytes --;
r ++;
}
@@ -1121,6 +1169,8 @@ int safe;
int r;
if(safe) {
r = sys_safecopyfrom(proc_nr, src, offset, (vir_bytes) &c, 1, D);
if(r != OK)
printf("<tty: proc %d, grant %ld>", proc_nr, src);
} else {
r = sys_vircopy(proc_nr, D, src+offset, SELF, D, (vir_bytes) &c, 1);
}
@@ -1132,9 +1182,12 @@ int safe;
cons_putk(c);
}
cons_putk(0); /* always terminate, even with EFAULT */
m_ptr->m_type = DIAG_REPL;
m_ptr->REP_STATUS = result;
send(m_ptr->m_source, m_ptr);
if(m_ptr->m_type != ASYN_DIAGNOSTICS) {
m_ptr->m_type = DIAG_REPL;
m_ptr->REP_STATUS = result;
send(m_ptr->m_source, m_ptr);
}
}
/*===========================================================================*
@@ -1237,7 +1290,7 @@ PRIVATE void cons_org0()
if (n > cons->c_org - cons->c_start)
n = cons->c_org - cons->c_start;
vid_vid_copy(cons->c_org, cons->c_org - n, scr_size);
cons->c_org -= n;
UPDATE_ORIGIN(cons, cons->c_org - n);
}
flush(cons);
}
@@ -1283,10 +1336,12 @@ PUBLIC void select_console(int cons_line)
/* Set the current console to console number 'cons_line'. */
if (cons_line < 0 || cons_line >= nr_cons) return;
ccurrent = cons_line;
curcons = &cons_table[cons_line];
set_6845(VID_ORG, curcons->c_org);
set_6845(CURSOR, curcons->c_cur);
UPDATE_CURSOR(curcons, curcons->c_cur);
UPDATE_ORIGIN(curcons, curcons->c_org);
}
/*===========================================================================*
@@ -1358,8 +1413,11 @@ int try;
tp->tty_winsize.ws_col= scr_width;
tp->tty_winsize.ws_xpixel= scr_width * 8;
tp->tty_winsize.ws_ypixel= scr_lines * font_lines;
return 0;
}
#if DUP_CONS_TO_SER
#define COM1_BASE 0x3F8
#define COM1_THR (COM1_BASE + 0)
#define LSR_THRE 0x20
@@ -1381,3 +1439,4 @@ PRIVATE void ser_putc(char c)
}
sys_outb(thr, c);
}
#endif