- tty: only report unrecognized scancodes once; forget about

remembering the origin and cursor position as that feature didn't
   really work properly anyway
 - tty: map in video and font memory using a vm call, access it from C,
   thereby eliminating pesky weird segment calls and assembly to access it,
   and unbreaks loadfont (Roman Ignatov)
 - bios_wini: fix bios_wini by allocating a <1MB buffers for it
 - memory: preallocate ramdisk, makes it a bit faster (and doesn't
   fail halfway if you allocate a huge one)
 - floppy: use <1MB buffer
 - ramdisk proto: because of the 2x1 page reservations, binaries
   got a little fatter and didn't fit on the ramdisk any more.
   increase it.
This commit is contained in:
Ben Gras 2009-09-21 14:25:54 +00:00
parent 36e935fe0f
commit 89bf7bae27
9 changed files with 114 additions and 160 deletions

View file

@ -493,7 +493,8 @@ PRIVATE void init_params()
dma_buf = mmap(0, ATA_DMA_BUF_SIZE, PROT_READ|PROT_WRITE,
MAP_PREALLOC | MAP_CONTIG | MAP_ANON, -1, 0);
prdt = mmap(0, PRDT_BYTES,
PROT_READ|PROT_WRITE, MAP_CONTIG | MAP_ANON, -1, 0);
PROT_READ|PROT_WRITE,
MAP_PREALLOC | MAP_CONTIG | MAP_ANON, -1, 0);
if(dma_buf == MAP_FAILED || prdt == MAP_FAILED) {
disable_dma = 1;
printf("at_wini%d: no dma\n", w_instance);

View file

@ -22,7 +22,7 @@ OBJ = bios_wini.o
all build: $(DRIVER)
$(DRIVER): $(OBJ)
$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
install -S 8k $(DRIVER)
install $(DRIVER)
# install with other drivers
install: /sbin/$(DRIVER)

View file

@ -59,10 +59,10 @@ PRIVATE struct wini { /* main drive struct, one entry per drive */
PRIVATE int w_drive; /* selected drive */
PRIVATE struct device *w_dv; /* device's base and size */
PRIVATE vir_bytes bios_buf_vir, bios_buf_size;
PRIVATE char *bios_buf_v;
PRIVATE phys_bytes bios_buf_phys;
PRIVATE int remap_first = 0; /* Remap drives for CD HD emulation */
PRIVATE char my_bios_buf[16384];
#define BIOSBUF 16384
PRIVATE cp_grant_id_t my_bios_grant_id;
_PROTOTYPE(int main, (void) );
@ -75,8 +75,6 @@ FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
FORWARD _PROTOTYPE( void w_init, (void) );
FORWARD _PROTOTYPE( void w_geometry, (struct partition *entry));
FORWARD _PROTOTYPE( int w_other, (struct driver *dp, message *m_ptr, int) );
FORWARD _PROTOTYPE( int my_vircopy, (endpoint_t, int, vir_bytes, endpoint_t,
int, vir_bytes, size_t, size_t));
/* Entry points to this driver. */
PRIVATE struct driver w_dtab = {
@ -102,12 +100,6 @@ PRIVATE struct driver w_dtab = {
PUBLIC int main()
{
long v;
struct sigaction sa;
sa.sa_handler = SIG_MESS;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGTERM,&sa,NULL)<0) panic("BIOS","sigaction failed", errno);
v= 0;
env_parse("bios_remap_first", "d", 0, &v, 0, 1);
@ -155,47 +147,6 @@ PRIVATE char *w_name()
return name;
}
/*===========================================================================*
* w_transfer *
*===========================================================================*/
PRIVATE int my_vircopy(from_proc, from_seg, from_vir, to_proc, to_seg,
to_vir, grant_offset, size)
endpoint_t from_proc;
int from_seg;
vir_bytes from_vir;
endpoint_t to_proc;
int to_seg;
vir_bytes to_vir;
size_t grant_offset;
size_t size;
{
phys_bytes addr;
int r;
if(from_seg == GRANT_SEG) {
if((r=sys_umap(from_proc, GRANT_SEG,
(vir_bytes)from_vir, (phys_bytes)size+grant_offset,
&addr)) != OK) {
panic(ME, "sys_umap in my_vircopy failed", r);
}
from_seg = PHYS_SEG;
from_vir = addr + grant_offset;
}
if(to_seg == GRANT_SEG) {
if((r=sys_umap(to_proc, GRANT_SEG,
(vir_bytes)to_vir, (phys_bytes)size+grant_offset,
&addr)) != OK) {
panic(ME, "sys_umap in my_vircopy failed", r);
}
to_seg = PHYS_SEG;
to_vir = addr + grant_offset;
}
return sys_physcopy(from_proc, from_seg, from_vir,
to_proc, to_seg, to_vir, size);
}
/*===========================================================================*
* w_transfer *
*===========================================================================*/
@ -214,29 +165,27 @@ int safe; /* use safecopies? */
unsigned long block;
vir_bytes i13e_rw_off, rem_buf_size;
size_t vir_offset = 0;
unsigned long dv_size = cv64ul(w_dv->dv_size);
unsigned secspcyl = wn->heads * wn->sectors;
off_t position;
struct int13ext_rw {
u8_t len;
u8_t res1;
u16_t count;
u16_t addr[2];
u32_t block[2];
} i13e_rw;
} *i13e_rw;
struct reg86u reg86;
u32_t lopos;
if (ex64hi(pos64))
panic(__FILE__, "should handle 64-bit offsets", NO_NUM);
position= ex64lo(pos64);
lopos= ex64lo(pos64);
/* Check disk address. */
if ((position & SECTOR_MASK) != 0) return(EINVAL);
if ((lopos & SECTOR_MASK) != 0) return(EINVAL);
errors = 0;
i13e_rw_off= bios_buf_size-sizeof(i13e_rw);
i13e_rw_off= BIOSBUF-sizeof(*i13e_rw);
rem_buf_size= (i13e_rw_off & ~SECTOR_MASK);
i13e_rw = (struct int13ext_rw *) (bios_buf_v + i13e_rw_off);
assert(rem_buf_size != 0);
while (nr_req > 0) {
@ -253,9 +202,14 @@ int safe; /* use safecopies? */
if ((nbytes & SECTOR_MASK) != 0) return(EINVAL);
/* Which block on disk and how close to EOF? */
if (position >= dv_size) return(OK); /* At EOF */
if (position + nbytes > dv_size) nbytes = dv_size - position;
block = div64u(add64ul(w_dv->dv_base, position), SECTOR_SIZE);
if (cmp64(pos64, w_dv->dv_size) >= 0) return(OK); /* At EOF */
if (cmp64(add64u(pos64, nbytes), w_dv->dv_size) > 0) {
u64_t n;
n = sub64(w_dv->dv_size, pos64);
assert(ex64hi(n) == 0);
nbytes = ex64lo(n);
}
block = div64u(add64(w_dv->dv_base, pos64), SECTOR_SIZE);
/* Degrade to per-sector mode if there were errors. */
if (errors > 0) nbytes = SECTOR_SIZE;
@ -267,30 +221,34 @@ int safe; /* use safecopies? */
chunk = iov->iov_size;
if (count + chunk > nbytes) chunk = nbytes - count;
assert(chunk <= rem_buf_size);
r= my_vircopy(proc_nr, safe ? GRANT_SEG : D,
(vir_bytes) iop->iov_addr,
SYSTEM, D, bios_buf_vir+count,
vir_offset, chunk);
if (r != OK)
panic(ME, "copy failed", r);
if(safe) {
r=sys_safecopyfrom(proc_nr,
(cp_grant_id_t) iop->iov_addr,
0, (vir_bytes) (bios_buf_v+count),
chunk, D);
if (r != OK)
panic(ME, "copy failed", r);
} else {
if(proc_nr != SELF) {
panic(ME, "unsafe outside self", r);
}
memcpy(bios_buf_v+count,
(char *) iop->iov_addr, chunk);
}
count += chunk;
}
}
/* Do the transfer */
if (wn->int13ext) {
i13e_rw.len = 0x10;
i13e_rw.res1 = 0;
i13e_rw.count = nbytes >> SECTOR_SHIFT;
i13e_rw.addr[0] = bios_buf_phys % HCLICK_SIZE;
i13e_rw.addr[1] = bios_buf_phys / HCLICK_SIZE;
i13e_rw.block[0] = block;
i13e_rw.block[1] = 0;
r= sys_vircopy(SELF, D, (vir_bytes)&i13e_rw,
SYSTEM, D, (bios_buf_vir+i13e_rw_off),
sizeof(i13e_rw));
if (r != OK)
panic(ME, "sys_vircopy failed", r);
i13e_rw->len = 0x10;
i13e_rw->res1 = 0;
i13e_rw->count = nbytes >> SECTOR_SHIFT;
i13e_rw->addr[0] = bios_buf_phys % HCLICK_SIZE;
i13e_rw->addr[1] = bios_buf_phys / HCLICK_SIZE;
i13e_rw->block[0] = block;
i13e_rw->block[1] = 0;
/* Set up an extended read or write BIOS call. */
reg86.u.b.intno = 0x13;
@ -332,17 +290,25 @@ int safe; /* use safecopies? */
chunk = iov->iov_size;
if (count + chunk > nbytes) chunk = nbytes - count;
assert(chunk <= rem_buf_size);
r = my_vircopy(SYSTEM, D, bios_buf_vir+count,
proc_nr, safe ? GRANT_SEG : D,
iop->iov_addr, vir_offset, chunk);
if (r != OK)
panic(ME, "sys_vircopy failed", r);
if(safe) {
r=sys_safecopyto(proc_nr, iop->iov_addr,
0, (vir_bytes) (bios_buf_v+count), chunk, D);
if (r != OK)
panic(ME, "sys_vircopy failed", r);
} else {
if (proc_nr != SELF)
panic(ME, "unsafe without self", NO_NUM);
memcpy((char *) iop->iov_addr,
bios_buf_v+count, chunk);
}
count += chunk;
}
}
/* Book the bytes successfully transferred. */
position += nbytes;
pos64 = add64ul(pos64, nbytes);
for (;;) {
if (nbytes < iov->iov_size) {
/* Not done with this one yet. */
@ -421,31 +387,23 @@ PRIVATE void w_init()
u32_t capacity[2];
u16_t bts_per_sec;
u16_t config[2];
} i13e_par;
} *i13e_par;
struct reg86u reg86;
/* Ask the system task for a suitable buffer */
r= sys_getbiosbuffer(&bios_buf_vir, &bios_buf_size);
if (r != OK)
panic(ME, "sys_getbiosbuffer failed", r);
if(bios_buf_size >= sizeof(my_bios_buf)) {
printf("bios_wini: truncating buffer %d -> %d\n",
bios_buf_size, sizeof(my_bios_buf));
bios_buf_size = sizeof(my_bios_buf);
if(!(bios_buf_v = alloc_contig(BIOSBUF, AC_LOWER1M, &bios_buf_phys))) {
panic(ME, "allocating bios buffer failed", r);
}
r= sys_umap(SYSTEM, D, (vir_bytes)bios_buf_vir, (phys_bytes)bios_buf_size,
&bios_buf_phys);
if (r != OK)
panic(ME, "sys_umap failed", r);
if (bios_buf_phys+bios_buf_size > 0x100000)
if (bios_buf_phys+BIOSBUF > 0x100000)
panic(ME, "bad BIOS buffer, phys", bios_buf_phys);
#if 0
printf("bios_wini: got buffer size %d, virtual 0x%x, phys 0x%x\n",
bios_buf_size, bios_buf_vir, bios_buf_phys);
BIOSBUF, bios_buf_v, bios_buf_phys);
#endif
i13e_par = (struct int13ext_params *) bios_buf_v;
/* Get the geometry of the drives */
for (drive = 0; drive < MAX_DRIVES; drive++) {
if (remap_first)
@ -493,12 +451,7 @@ PRIVATE void w_init()
if (!(reg86.u.w.f & 0x0001) && reg86.u.w.bx == 0xAA55
&& (reg86.u.w.cx & 0x0001)) {
/* INT 13 Extensions available. */
i13e_par.len = 0x001E; /* Input size of parameter packet */
r= sys_vircopy(SELF, D, (vir_bytes)&i13e_par,
SYSTEM, D, bios_buf_vir,
sizeof(i13e_par));
if (r != OK)
panic(ME, "sys_vircopy failed\n", r);
i13e_par->len = 0x001E; /* Input size of parameter packet */
reg86.u.b.intno = 0x13;
reg86.u.b.ah = 0x48; /* Ext. Get drive parameters. */
reg86.u.b.dl = drive_id;
@ -509,16 +462,10 @@ PRIVATE void w_init()
if (r != OK)
panic(ME, "BIOS call failed", r);
r= sys_vircopy(SYSTEM, D, bios_buf_vir,
SELF, D, (vir_bytes)&i13e_par,
sizeof(i13e_par));
if (r != OK)
panic(ME, "sys_vircopy failed\n", r);
if (!(reg86.u.w.f & 0x0001)) {
wn->int13ext = 1; /* Extensions can be used. */
capacity = i13e_par.capacity[0];
if (i13e_par.capacity[1] != 0) capacity = 0xFFFFFFFF;
capacity = i13e_par->capacity[0];
if (i13e_par->capacity[1] != 0) capacity = 0xFFFFFFFF;
}
}

View file

@ -284,6 +284,9 @@ PRIVATE struct driver f_dtab = {
NULL
};
static char *floppy_buf;
static phys_bytes floppy_buf_phys;
/*===========================================================================*
* floppy_task *
*===========================================================================*/
@ -294,7 +297,9 @@ PUBLIC void main()
struct floppy *fp;
int s;
init_buffer();
if(!(floppy_buf = alloc_contig(2*DMA_BUF_SIZE,
AC_LOWER16M | AC_ALIGN4K, &floppy_buf_phys)))
panic("FLOPPY", "couldn't allocate dma buffer", NO_NUM);
f_next_timeout = TMR_NEVER;
tmr_inittimer(&f_tmr_timeout);
@ -604,13 +609,13 @@ int safe;
/* Copy the user bytes to the DMA buffer. */
if(safe) {
s=sys_safecopyfrom(proc_nr, *ug, *up,
(vir_bytes) tmp_buf,
(vir_bytes) floppy_buf,
(phys_bytes) SECTOR_SIZE, D);
if(s != OK)
panic("FLOPPY", "sys_safecopyfrom failed", s);
} else {
assert(proc_nr == SELF);
memcpy(tmp_buf, (void *) (*ug + *up), SECTOR_SIZE);
memcpy(floppy_buf, (void *) (*ug + *up), SECTOR_SIZE);
}
}
@ -630,13 +635,13 @@ int safe;
/* Copy the DMA buffer to user space. */
if(safe) {
s=sys_safecopyto(proc_nr, *ug, *up,
(vir_bytes) tmp_buf,
(vir_bytes) floppy_buf,
(phys_bytes) SECTOR_SIZE, D);
if(s != OK)
panic("FLOPPY", "sys_safecopyto failed", s);
} else {
assert(proc_nr == SELF);
memcpy((void *) (*ug + *up), tmp_buf, SECTOR_SIZE);
memcpy((void *) (*ug + *up), floppy_buf, SECTOR_SIZE);
}
}
@ -702,7 +707,7 @@ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
int s;
/* First check the DMA memory address not to exceed maximum. */
if (tmp_phys != (tmp_phys & DMA_ADDR_MASK)) {
if (floppy_buf_phys != (floppy_buf_phys & DMA_ADDR_MASK)) {
report("FLOPPY", "DMA denied because address out of range", NO_NUM);
return(EIO);
}
@ -713,9 +718,9 @@ int opcode; /* DEV_GATHER_S or DEV_SCATTER_S */
pv_set(byte_out[0], DMA_INIT, DMA_RESET_VAL); /* reset the dma controller */
pv_set(byte_out[1], DMA_FLIPFLOP, 0); /* write anything to reset it */
pv_set(byte_out[2], DMA_MODE, opcode == DEV_SCATTER_S ? DMA_WRITE : DMA_READ);
pv_set(byte_out[3], DMA_ADDR, (unsigned) (tmp_phys >> 0) & 0xff);
pv_set(byte_out[4], DMA_ADDR, (unsigned) (tmp_phys >> 8) & 0xff);
pv_set(byte_out[5], DMA_TOP, (unsigned) (tmp_phys >> 16) & 0xff);
pv_set(byte_out[3], DMA_ADDR, (unsigned) (floppy_buf_phys >> 0) & 0xff);
pv_set(byte_out[4], DMA_ADDR, (unsigned) (floppy_buf_phys >> 8) & 0xff);
pv_set(byte_out[5], DMA_TOP, (unsigned) (floppy_buf_phys >> 16) & 0xff);
pv_set(byte_out[6], DMA_COUNT, (((SECTOR_SIZE - 1) >> 0)) & 0xff);
pv_set(byte_out[7], DMA_COUNT, (SECTOR_SIZE - 1) >> 8);
pv_set(byte_out[8], DMA_INIT, 2); /* some sort of enable */
@ -1316,7 +1321,7 @@ int density;
(void) f_prepare(device);
position = (off_t) f_dp->test << SECTOR_SHIFT;
iovec1.iov_addr = (vir_bytes) tmp_buf;
iovec1.iov_addr = (vir_bytes) floppy_buf;
iovec1.iov_size = SECTOR_SIZE;
result = f_transfer(SELF, DEV_GATHER_S, cvul64(position), &iovec1, 1, 0);

View file

@ -229,11 +229,7 @@ subread(struct logdevice *log, int count, int proc_nr,
if((r=sys_safecopyto(proc_nr, user_vir, offset,
(vir_bytes)buf, count, D)) != OK)
return r;
} else {
if((r=sys_vircopy(SELF,D,(int)buf,
proc_nr, safe ? GRANT_SEG : D, user_vir + offset, count)) != OK)
return r;
}
}
LOGINC(log->log_read, count);
log->log_size -= count;

View file

@ -403,7 +403,8 @@ int safe;
#endif
/* Try to allocate a piece of memory for the RAM disk. */
if((mem = mmap(0, ramdev_size, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0)) == MAP_FAILED) {
if((mem = mmap(0, ramdev_size, PROT_READ|PROT_WRITE,
MAP_PREALLOC|MAP_ANON, -1, 0)) == MAP_FAILED) {
printf("MEM: failed to get memory for ramdisk\n");
return(ENOMEM);
}

View file

@ -1,5 +1,5 @@
boot
160 400
175 400
d--755 0 0
bin d--755 0 0
at_wini ---755 0 0 at_wini

View file

@ -52,7 +52,6 @@ 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 */
/* tells mem_vid_copy() to blank the screen */
#define BLANK_MEM ((vir_bytes) 0)
@ -65,9 +64,7 @@ PRIVATE int disabled_sm; /* Scroll mode to be restored when re-enabling
*/
char *console_memory = NULL;
/* boot_tty_info we use to communicate with the boot code. */
struct boot_tty_info boot_tty_info;
char *font_memory = NULL;
/* Per console data. */
typedef struct console {
@ -90,24 +87,14 @@ typedef struct console {
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((vir_bytes) &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); \
}
@ -1001,13 +988,18 @@ tty_t *tp;
}
if (machine.vdu_ega) vid_size = EGA_SIZE;
wrap = ! machine.vdu_ega;
info_location = vid_size - sizeof(struct boot_tty_info);
console_memory = vm_map_phys(SELF, (void *) vid_base, vid_size);
if(console_memory == MAP_FAILED)
panic("TTY","Console couldn't map video memory", NO_NUM);
font_memory = vm_map_phys(SELF, (void *)GA_VIDEO_ADDRESS, GA_FONT_SIZE);
if(font_memory == MAP_FAILED)
panic("TTY","Console couldn't map font memory", NO_NUM);
vid_size >>= 1; /* word count */
vid_mask = vid_size - 1;
@ -1015,7 +1007,7 @@ tty_t *tp;
scr_size = scr_lines * scr_width;
/* There can be as many consoles as video memory allows. */
nr_cons = (vid_size - sizeof(struct boot_tty_info)/2) / scr_size;
nr_cons = vid_size / scr_size;
if (nr_cons > NR_CONS) nr_cons = NR_CONS;
if (nr_cons > 1) wrap = 0;
@ -1038,12 +1030,6 @@ tty_t *tp;
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);
boot_tty_info.flags = BTIF_CONSCURSOR | BTIF_CONSORIGIN;
boot_tty_info.magic = TTYMAGIC;
UPDATE_ORIGIN(cons, cons->c_org);
}
select_console(0);
cons_ioctl(tp, 0);
@ -1327,6 +1313,7 @@ PUBLIC void select_console(int cons_line)
PUBLIC int con_loadfont(m)
message *m;
{
/* Load a font into the EGA or VGA adapter. */
int result;
static struct sequence seq1[7] = {
@ -1353,8 +1340,11 @@ message *m;
if (!machine.vdu_ega) return(ENOTTY);
result = ga_program(seq1); /* bring font memory into view */
result = sys_physcopy(m->IO_ENDPT, GRANT_SEG, (vir_bytes) m->ADDRESS,
NONE, PHYS_SEG, (phys_bytes) GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE);
if(sys_safecopyfrom(m->IO_ENDPT, (cp_grant_id_t) m->ADDRESS, 0,
(vir_bytes) font_memory, GA_FONT_SIZE, D) != OK) {
printf("tty: copying from %d failed\n", m->IO_ENDPT);
return EFAULT;
}
result = ga_program(seq2); /* restore */

View file

@ -766,8 +766,22 @@ int scode; /* scan code of key just struck or released */
return -1;
if(ch)
return ch;
printf("tty: ignoring unrecognized %s scancode 0x%x\n",
escape ? "escaped" : "straight", scode);
{
static char seen[2][NR_SCAN_CODES];
int notseen = 0, ei;
ei = escape ? 1 : 0;
if(scode >= 0 && scode < NR_SCAN_CODES) {
notseen = !seen[ei][scode];
seen[ei][scode] = 1;
} else {
printf("tty: scode %d makes no sense\n", scode);
}
if(notseen) {
printf("tty: ignoring unrecognized %s "
"scancode 0x%x\n",
escape ? "escaped" : "straight", scode);
}
}
return -1;
}