From 89ac678b9b40f9f7dbbab727674e4dd8e6cef861 Mon Sep 17 00:00:00 2001 From: Jorrit Herder Date: Fri, 29 Apr 2005 15:36:43 +0000 Subject: [PATCH] *** empty log message *** --- drivers/at_wini/at_wini.c | 27 +- drivers/libdriver/driver.c | 1 - drivers/libdriver/drvlib.c | 4 +- drivers/memory/memory.c | 193 ++-- drivers/printer/printer.c | 6 +- drivers/tty/console.c | 31 +- drivers/tty/keyboard.c | 2 +- drivers/tty/tty.c | 4 +- drivers/tty/tty.h | 3 +- include/ibm/bios.h | 160 +++- include/ibm/memory.h | 174 ++++ include/minix/com.h | 33 +- include/minix/config.h | 12 +- include/minix/const.h | 2 + include/minix/syslib.h | 41 +- include/minix/type.h | 44 +- kernel/Makefile | 10 +- kernel/clock.c | 2 +- kernel/const.h | 5 +- kernel/exception.c | 2 +- kernel/glo.h | 29 +- kernel/i8259.c | 6 +- kernel/klib386.s | 20 + kernel/klib88.s | 1057 ---------------------- kernel/main.c | 79 +- kernel/memory.c | 120 --- kernel/mpx88.s | 762 ---------------- kernel/proc.c | 4 +- kernel/proc.h | 6 +- kernel/protect.c | 60 +- kernel/protect.h | 2 +- kernel/proto.h | 6 +- kernel/sendmask.h | 8 +- kernel/start.c | 123 ++- kernel/system.c | 175 ++-- kernel/system.h | 22 +- kernel/system/Makefile | 8 +- kernel/system/copying.c | 79 +- kernel/system/do_copy.c | 69 -- kernel/system/do_vcopy.c | 55 -- kernel/system/irqctl.c | 8 +- kernel/system/misc.c | 56 +- kernel/system/proctl.c | 20 +- kernel/system/sigctl.c | 126 ++- kernel/system/{srvrctl.c => sysctl.c} | 44 +- kernel/system/tracing.c | 2 +- kernel/table.c | 2 +- kernel/type.h | 7 - lib/syslib/Makefile | 28 +- lib/syslib/sys_copy.c | 31 - lib/syslib/sys_endsig.c | 16 +- lib/syslib/sys_getmap.c | 14 - lib/syslib/sys_getsig.c | 18 + lib/syslib/sys_oldsig.c | 16 - lib/syslib/sys_physcp.c | 26 +- lib/syslib/{sys_ph2sg.c => sys_segctl.c} | 8 +- lib/syslib/sys_sendsig.c | 12 - lib/syslib/sys_sigctl.c | 29 - lib/syslib/sys_sigret.c | 24 +- lib/syslib/sys_sigsend.c | 18 + lib/syslib/sys_vidcp.c | 22 - lib/syslib/sys_vircp.c | 4 +- lib/utils/get_proc_nr.c | 3 +- servers/fs/cmostime.c | 4 +- servers/fs/device.c | 2 +- servers/fs/main.c | 6 +- servers/fs/misc.c | 20 +- servers/fs/pipe.c | 2 +- servers/fs/read.c | 2 +- servers/fs/stadir.c | 2 +- servers/inet/sr.c | 41 +- servers/is/dmp.c | 59 +- servers/mm/exec.c | 10 +- servers/mm/forkexit.c | 2 +- servers/mm/main.c | 2 +- servers/mm/misc.c | 9 +- servers/mm/signal.c | 6 +- servers/mm/utility.c | 4 +- 78 files changed, 1293 insertions(+), 2858 deletions(-) create mode 100644 include/ibm/memory.h delete mode 100755 kernel/memory.c delete mode 100644 kernel/system/do_copy.c delete mode 100644 kernel/system/do_vcopy.c rename kernel/system/{srvrctl.c => sysctl.c} (87%) delete mode 100755 lib/syslib/sys_copy.c delete mode 100755 lib/syslib/sys_getmap.c create mode 100644 lib/syslib/sys_getsig.c delete mode 100755 lib/syslib/sys_oldsig.c rename lib/syslib/{sys_ph2sg.c => sys_segctl.c} (69%) delete mode 100755 lib/syslib/sys_sendsig.c delete mode 100644 lib/syslib/sys_sigctl.c create mode 100644 lib/syslib/sys_sigsend.c delete mode 100644 lib/syslib/sys_vidcp.c diff --git a/drivers/at_wini/at_wini.c b/drivers/at_wini/at_wini.c index 8b65f7275..3b4c36f30 100644 --- a/drivers/at_wini/at_wini.c +++ b/drivers/at_wini/at_wini.c @@ -247,9 +247,12 @@ PUBLIC void main() /* Register function key for debugging dumps. */ fkey_enable(SF8); -/* Set special disk parameters then call the generic main loop. */ +#if DEAD_CODE if ((s=get_own_proc_nr(&win_tasknr)) != OK) server_panic(w_name(),"Couldn't get own process number",s); +#endif + printf("AT wini task started.\n"); +/* Set special disk parameters then call the generic main loop. */ init_params(); driver_task(&w_dtab); } @@ -270,17 +273,17 @@ PRIVATE void init_params() int s; /* Get the number of drives from the BIOS data area */ - if ((s=sys_vircopy(SELF, BIOS_SEG, ADR_WINI_PARAMS, - SELF, D, (vir_bytes) params, LEN_WINI_PARAMS)) != OK) + if ((s=sys_vircopy(SELF, BIOS_SEG, NR_HD_DRIVES_ADDR, + SELF, D, (vir_bytes) params, NR_HD_DRIVES_SIZE)) != OK) server_panic(w_name(), "Couldn't read BIOS", s); if ((nr_drives = params[0]) > 2) nr_drives = 2; for (drive = 0, wn = wini; drive < MAX_DRIVES; drive++, wn++) { if (drive < nr_drives) { - /* Copy the BIOS parameter vector */ - vector = drive == 0 ? ADR_WINI_0_PARM_VEC:ADR_WINI_1_PARM_VEC; - size = drive == 0 ? LEN_WINI_0_PARM_VEC:LEN_WINI_1_PARM_VEC; - if ((s=sys_vircopy(SELF, BIOS_SEG, vector, + /* Copy the BIOS parameter vector */ + vector = (drive == 0) ? BIOS_HD0_PARAMS_ADDR:BIOS_HD1_PARAMS_ADDR; + size = (drive == 0) ? BIOS_HD0_PARAMS_SIZE:BIOS_HD1_PARAMS_SIZE; + if ((s=sys_vircopy(SELF, BIOS_SEG, vector, SELF, D, (vir_bytes) parv, size)) != OK) server_panic(w_name(), "Couldn't read BIOS", s); @@ -460,7 +463,7 @@ PRIVATE int w_identify() if (w_specify() != OK && w_specify() != OK) return(ERR); - printf("%s: user-level AT Winchester driver detected ", w_name()); + printf("%s: user-space AT Winchester driver detected ", w_name()); if (wn->state & (SMART|ATAPI)) { printf("%.40s\n", id_string); } else { @@ -469,8 +472,12 @@ PRIVATE int w_identify() /* Everything looks OK; register IRQ so we can stop polling. */ wn->irq = w_drive < 2 ? AT_WINI_0_IRQ : AT_WINI_1_IRQ; +#if DEAD_CODE sys_irqsetpolicy(w_wn->irq, (IRQ_READ_PORT | IRQ_BYTE | IRQ_REENABLE), SELF, (w_wn->base + REG_STATUS), &w_byteval, 0); +#else + sys_irqsetpolicy(w_wn->irq, IRQ_REENABLE, SELF, 0, 0, 0); +#endif sys_irqenable(wn->irq); return(OK); } @@ -834,7 +841,11 @@ PRIVATE void w_intr_wait() if (m.m_type == SYN_ALARM) { /* but check for timeout */ w_timeout(); /* a.o. set w_status */ } else if (m.m_type == HARD_INT) { +#if DEAD_CODE w_status = w_byteval; /* read by generic handler */ +#else + sys_inb((w_wn->base + REG_STATUS), &w_status); +#endif } } } else { diff --git a/drivers/libdriver/driver.c b/drivers/libdriver/driver.c index b4010dec1..84007fd6e 100644 --- a/drivers/libdriver/driver.c +++ b/drivers/libdriver/driver.c @@ -118,7 +118,6 @@ struct driver *dp; /* Device dependent entry points. */ r = do_vrdwt(dp, &mess); break; case HARD_INT: /* leftover interrupt or expired timer. */ - /* printf("Driver.c: Left-over interrupt!\n"); */ continue; case HARD_STOP: (*dp->dr_stop)(dp); continue; /* don't reply */ diff --git a/drivers/libdriver/drvlib.c b/drivers/libdriver/drvlib.c index 0caa5104b..6115bc516 100644 --- a/drivers/libdriver/drvlib.c +++ b/drivers/libdriver/drvlib.c @@ -161,9 +161,9 @@ struct part_entry *table; /* four entries */ /* Read the partition table at 'offset'. */ if (proc_nr == NONE) { - if ((s=get_proc_nr(&proc_nr,NULL)) != OK) { + if ((s=sys_getprocnr(&proc_nr,0,0)) != OK) { printf("%s: can't get own proc nr: %d\n", (*dp->dr_name)(), s); - return 0; + return(0); } } position = offset << SECTOR_SHIFT; diff --git a/drivers/memory/memory.c b/drivers/memory/memory.c index e5b859224..603668847 100644 --- a/drivers/memory/memory.c +++ b/drivers/memory/memory.c @@ -4,10 +4,14 @@ * /dev/mem - absolute memory * /dev/kmem - kernel virtual memory * /dev/null - null device (data sink) - * /dev/boot - boot FS loaded from boot image + * /dev/boot - boot device loaded from boot image + * /dev/random - random number generator + * /dev/zero - null byte stream generator * * Changes: - * Apr 09, 2005 added support for boot FS (Jorrit N. Herder) + * Apr 29, 2005 added null byte generator (Jorrit N. Herder) + * Apr 27, 2005 added random device handling (Jorrit N. Herder) + * Apr 09, 2005 added support for boot device (Jorrit N. Herder) * Sep 03, 2004 secured code with ENABLE_USERPRIV (Jorrit N. Herder) * Jul 26, 2004 moved RAM driver to user-space (Jorrit N. Herder) * Apr 20, 1992 device dependent/independent split (Kees J. Bot) @@ -16,20 +20,16 @@ #include "../drivers.h" #include "../libdriver/driver.h" #include -#if (CHIP == INTEL) && ENABLE_USERBIOS -#include -#endif -#define NR_DEVS 6 /* number of RAM-type devices */ +#define NR_DEVS 7 /* number of minor devices */ -PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each RAM disk */ +PRIVATE struct device m_geom[NR_DEVS]; /* base and size of each device */ +PRIVATE int m_seg[NR_DEVS]; /* segment index of each device */ PRIVATE int m_device; /* current device */ -PRIVATE struct kenviron kenv; /* need protected_mode */ +PRIVATE struct kinfo kinfo; /* need kernel info */ +PRIVATE struct machine machine; /* need machine info */ PRIVATE struct psinfo psinfo = { NR_TASKS, NR_PROCS, 0, 0, 0 }; -#define RANDOM_BUFFER_SIZE (1024*32) -PRIVATE char random_state[RANDOM_BUFFER_SIZE]; - FORWARD _PROTOTYPE( struct device *m_prepare, (int device) ); FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, off_t position, iovec_t *iov, unsigned nr_req) ); @@ -54,6 +54,14 @@ PRIVATE struct driver m_dtab = { nop_alarm, /* ignore leftover alarms */ }; +/* Buffer for the /dev/zero null byte feed. */ +#define ZERO_BUF_SIZE 1024 +PRIVATE char zero[ZERO_BUF_SIZE]; + +/* Buffer for the /dev/random number generator. */ +#define RANDOM_BUF_SIZE 1024 +PRIVATE char random[RANDOM_BUF_SIZE]; + /*===========================================================================* * main * @@ -101,53 +109,105 @@ off_t position; /* offset on device to read or write */ iovec_t *iov; /* pointer to read or write request vector */ unsigned nr_req; /* length of request vector */ { -/* Read or write /dev/null, /dev/mem, /dev/kmem, /dev/ram, /dev/boot, - * /dev/random, or /dev/urandom - */ - +/* Read or write /dev/null, /dev/mem, /dev/kmem, /dev/ram, or /dev/boot. */ int device; phys_bytes mem_phys, user_phys; - unsigned count; + int seg; + unsigned count, left, chunk; vir_bytes user_vir; struct device *dv; unsigned long dv_size; + int s; /* Get minor device number and check for /dev/null. */ device = m_device; dv = &m_geom[device]; dv_size = cv64ul(dv->dv_size); - while (nr_req > 0) { + + /* How much to transfer and where to / from. */ count = iov->iov_size; user_vir = iov->iov_addr; switch (device) { + + /* No copying; ignore request. */ case NULL_DEV: if (opcode == DEV_GATHER) return(OK); /* always at EOF */ break; - case RANDOM_DEV: - return OK; - break; - default: - /* /dev/mem, /dev/kmem, /dev/ram, /dev/boot: check for EOF */ - if (position >= dv_size) return(OK); + /* Virtual copying. For boot device. */ + case RAM_DEV: + case KMEM_DEV: + case BOOT_DEV: + if (position >= dv_size) return(OK); /* check for EOF */ + if (position + count > dv_size) count = dv_size - position; + seg = m_seg[device]; + + if (opcode == DEV_GATHER) { /* copy actual data */ + sys_vircopy(SELF,seg,position, proc_nr,D,user_vir, count); + } else { + sys_vircopy(proc_nr,D,user_vir, SELF,seg,position, count); + } + break; + + /* Physical copying. Only used to access entire memory. */ + case MEM_DEV: + if (position >= dv_size) return(OK); /* check for EOF */ if (position + count > dv_size) count = dv_size - position; mem_phys = cv64ul(dv->dv_base) + position; - /* Copy the data. */ - if (opcode == DEV_GATHER) { - sys_copy(ABS, D, mem_phys, proc_nr, D, user_vir, count); + if (opcode == DEV_GATHER) { /* copy data */ + sys_physcopy(NONE, PHYS_SEG, mem_phys, + proc_nr, D, user_vir, count); } else { - sys_copy(proc_nr, D, user_vir, ABS, D, mem_phys, count); + sys_physcopy(proc_nr, D, user_vir, + NONE, PHYS_SEG, mem_phys, count); } + break; + + /* Random number generator. Character instead of block device. */ + case RANDOM_DEV: + printf("MEMORY: please note /dev/random is NOT yet random!\n"); + left = count; + while (left > 0) { + chunk = (left > RANDOM_BUF_SIZE) ? RANDOM_BUF_SIZE : left; + if (opcode == DEV_GATHER) { + sys_vircopy(SELF, D, (vir_bytes) random, + proc_nr, D, user_vir, chunk); + } else if (opcode == DEV_SCATTER) { + sys_vircopy(proc_nr, D, user_vir, + SELF, D, (vir_bytes) random, chunk); + } + left -= chunk; + } + break; + + /* Null byte stream generator. */ + case ZERO_DEV: + if (opcode == DEV_GATHER) { + left = count; + while (left > 0) { + chunk = (left > ZERO_BUF_SIZE) ? ZERO_BUF_SIZE : left; + if (OK != (s=sys_vircopy(SELF, D, (vir_bytes) zero, + proc_nr, D, user_vir, chunk))) + printf("MEMORY: sys_vircopy failed: %d\n", s); + left -= chunk; + } + } + break; + + /* Unknown (illegal) minor device. */ + default: + return(EINVAL); } /* Book the number of bytes transferred. */ position += count; iov->iov_addr += count; if ((iov->iov_size -= count) == 0) { iov++; nr_req--; } + } return(OK); } @@ -161,7 +221,7 @@ struct driver *dp; message *m_ptr; { /* Check device number on open. Give I/O privileges to a process opening - * /dev/mem or /dev/kmem. This is needed for systems with memory mapped I/O. + * /dev/mem or /dev/kmem. This may be needed in case of memory mapped I/O. */ if (m_prepare(m_ptr->DEVICE) == NIL_DEV) return(ENXIO); @@ -181,30 +241,51 @@ message *m_ptr; *===========================================================================*/ PRIVATE void m_init() { - /* Initialize this task. */ - extern int end; - int s; + /* Initialize this task. All minor devices are initialized one by one. */ + int i,s; /* Print welcome message. */ - printf("MEMORY: user-level memory (RAM) driver is alive"); + printf("MEMORY: user-level memory (RAM, etc.) driver is alive\n"); - /* Get kernel environment (protected_mode and addresses). */ - if (OK != (s=sys_getkenviron(&kenv))) { - server_panic("MEM","Couldn't get kernel environment.",s); + /* Get kernel info for memory addresses of kernel and boot device. */ + if (OK != (s=sys_getkinfo(&kinfo))) { + server_panic("MEM","Couldn't get kernel information.",s); } - m_geom[KMEM_DEV].dv_base = cvul64(kenv.kmem_base); - m_geom[KMEM_DEV].dv_size = cvul64(kenv.kmem_size); - m_geom[BOOT_DEV].dv_base = cvul64(kenv.bootfs_base); - m_geom[BOOT_DEV].dv_size = cvul64(kenv.bootfs_size); - /* dv_base isn't used for the random device */ - m_geom[RANDOM_DEV].dv_base = cvul64(NULL); - m_geom[RANDOM_DEV].dv_size = cvul64(RANDOM_BUFFER_SIZE); + /* Install remote segment for /dev/kmem memory. */ + m_geom[KMEM_DEV].dv_base = cvul64(kinfo.kmem_base); + m_geom[KMEM_DEV].dv_size = cvul64(kinfo.kmem_size); + if (OK != (s=sys_segctl(&m_seg[KMEM_DEV], (u16_t *) &s, (vir_bytes *) &s, + kinfo.kmem_base, kinfo.kmem_size))) { + server_panic("MEM","Couldn't install remote segment.",s); + } - psinfo.proc = kenv.proc_addr; + /* Install remote segment for /dev/boot memory, if enabled. */ + m_geom[BOOT_DEV].dv_base = cvul64(kinfo.bootdev_base); + m_geom[BOOT_DEV].dv_size = cvul64(kinfo.bootdev_size); + if (kinfo.bootdev_base > 0) { + if (OK != (s=sys_segctl(&m_seg[BOOT_DEV], (u16_t *) &s, (vir_bytes *) &s, + kinfo.bootdev_base, kinfo.bootdev_size))) { + server_panic("MEM","Couldn't install remote segment.",s); + } + } + psinfo.proc = kinfo.proc_addr; + + /* Initialize /dev/random and /dev/zero. */ + for (i=0; iREQUEST) { case MIOCRAMSIZE: { /* FS wants to create a new RAM disk with the given size. */ - unsigned long bytesize; - phys_bytes base; + unsigned long ramdev_size; + phys_bytes ramdev_base; int s; if (m_ptr->PROC_NR != FS_PROC_NR) return(EPERM); - /* Try to allocate a piece of kernel memory for the RAM disk. */ - bytesize = m_ptr->POSITION; - if (OK != (s = sys_kmalloc(bytesize, &base))) + /* Try to allocate a piece of memory for the RAM disk. */ + ramdev_size = m_ptr->POSITION; + if (OK != (s=sys_kmalloc(ramdev_size, &ramdev_base))) server_panic("MEM","Couldn't allocate kernel memory", s); - dv->dv_base = cvul64(base); - dv->dv_size = cvul64(bytesize); + dv->dv_base = cvul64(ramdev_base); + dv->dv_size = cvul64(ramdev_size); + if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, (vir_bytes *) &s, + ramdev_base, ramdev_size))) { + server_panic("MEM","Couldn't install remote segment.",s); + } + break; } /* Perhaps it is cleaner to move all code relating to psinfo to the info @@ -261,10 +347,9 @@ message *m_ptr; /* pointer to read or write message */ /* MM or FS set the address of their process table. */ phys_bytes psinfo_phys; - if (m_ptr->PROC_NR == MM_PROC_NR) { + if (m_ptr->PROC_NR == PM_PROC_NR) { psinfo.mproc = (vir_bytes) m_ptr->ADDRESS; - } else - if (m_ptr->PROC_NR == FS_PROC_NR) { + } else if (m_ptr->PROC_NR == FS_PROC_NR) { psinfo.fproc = (vir_bytes) m_ptr->ADDRESS; } else { return(EPERM); diff --git a/drivers/printer/printer.c b/drivers/printer/printer.c index 7d5ae494a..367f8aa2d 100644 --- a/drivers/printer/printer.c +++ b/drivers/printer/printer.c @@ -3,7 +3,7 @@ * are written to the printer without any changes at all. * * Changes: - * May 07, 2004 wait until printer is ready (Jorrit N. Herder) + * May 07, 2004 fix: wait until printer is ready (Jorrit N. Herder) * May 06, 2004 printer driver moved to user-space (Jorrit N. Herder) * * The valid messages and their parameters are: @@ -278,11 +278,15 @@ PRIVATE void do_initialize() if (initialized) return; initialized = TRUE; +#if DEAD_CODE /* Get the base port for first printer. This used to be done from the * BIOS with phys_copy(0x408L, vir2phys(&port_base), 2L); but currently * a magic number is put in place. */ port_base = 0x378; +#endif + sys_vircopy(SELF, BIOS_SEG, LPT1_IO_PORT_ADDR, + SELF, D, (vir_bytes) &port_base, LPT1_IO_PORT_SIZE); sys_outb(port_base + 2, INIT_PRINTER); tick_delay(1); /* easily satisfies Centronics minimum */ /* was 2 millisecs; now is ~17 millisecs */ diff --git a/drivers/tty/console.c b/drivers/tty/console.c index 44713690c..bc6119699 100644 --- a/drivers/tty/console.c +++ b/drivers/tty/console.c @@ -56,6 +56,7 @@ #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 */ @@ -793,19 +794,19 @@ tty_t *tp; if (! vdu_initialized++) { /* How about error checking? What to do on failure??? */ - s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x44AL, - SELF, D, (vir_bytes) &bios_columns, 2L); - s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x463L, - SELF, D, (vir_bytes) &bios_crtbase, 2L); - s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x484L, - SELF, D, (vir_bytes) &bios_rows, 1L); - s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) 0x485L, - SELF, D, (vir_bytes) &bios_fontlines, 2L); + s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_SCREEN_COLS_ADDR, + SELF, D, (vir_bytes) &bios_columns, VDU_SCREEN_COLS_SIZE); + s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_CRT_BASE_ADDR, + SELF, D, (vir_bytes) &bios_crtbase, VDU_CRT_BASE_SIZE); + s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_SCREEN_ROWS_ADDR, + SELF, D, (vir_bytes) &bios_rows, VDU_SCREEN_ROWS_SIZE); + s=sys_vircopy(SELF, BIOS_SEG, (vir_bytes) VDU_FONTLINES_ADDR, + SELF, D, (vir_bytes) &bios_fontlines, VDU_FONTLINES_SIZE); vid_port = bios_crtbase; scr_width = bios_columns; font_lines = bios_fontlines; - scr_lines = kenv.ega ? bios_rows+1 : 25; + scr_lines = machine.vdu_ega ? bios_rows+1 : 25; if (color) { vid_base = COLOR_BASE; @@ -814,10 +815,10 @@ tty_t *tp; vid_base = MONO_BASE; vid_size = MONO_SIZE; } - if (kenv.ega) vid_size = EGA_SIZE; - wrap = !kenv.ega; + if (machine.vdu_ega) vid_size = EGA_SIZE; + wrap = ! machine.vdu_ega; - s = sys_phys2seg(&vid_seg, &vid_off, vid_base, vid_size); + s = sys_segctl(&vid_index, &vid_seg, &vid_off, vid_base, vid_size); vid_size >>= 1; /* word count */ vid_mask = vid_size - 1; @@ -1039,11 +1040,11 @@ message *m; seq2[6].value= color ? 0x0E : 0x0A; - if (!kenv.ega) return(ENOTTY); + if (!machine.vdu_ega) return(ENOTTY); result = ga_program(seq1); /* bring font memory into view */ - result = sys_copy(m->PROC_NR, D, (vir_bytes) m->ADDRESS, - ABS, 0, (phys_bytes) GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE); + result = sys_physcopy(m->PROC_NR, D, (vir_bytes) m->ADDRESS, + NONE, PHYS_SEG, (phys_bytes) GA_VIDEO_ADDRESS, (phys_bytes)GA_FONT_SIZE); result = ga_program(seq2); /* restore */ diff --git a/drivers/tty/keyboard.c b/drivers/tty/keyboard.c index 06bfde611..ff6d3b30f 100644 --- a/drivers/tty/keyboard.c +++ b/drivers/tty/keyboard.c @@ -296,7 +296,7 @@ PRIVATE void set_leds() { /* Set the LEDs on the caps, num, and scroll lock keys */ int s; - if (!kenv.pc_at) return; /* PC/XT doesn't have LEDs */ + if (! machine.pc_at) return; /* PC/XT doesn't have LEDs */ kb_wait(); /* wait for buffer empty */ if ((s=sys_outb(KEYBD, LED_CODE)) != OK) diff --git a/drivers/tty/tty.c b/drivers/tty/tty.c index e10b638be..4dfac5334 100644 --- a/drivers/tty/tty.c +++ b/drivers/tty/tty.c @@ -141,7 +141,7 @@ PUBLIC tty_t tty_table[NR_CONS+NR_RS_LINES+NR_PTYS]; PUBLIC int ccurrent; /* currently active console */ PUBLIC timer_t *tty_timers; /* queue of TTY timers */ PUBLIC clock_t tty_next_timeout; /* time that the next alarm is due */ -PUBLIC struct kenviron kenv; /* kernel environment variables */ +PUBLIC struct machine machine; /* kernel environment variables */ /*===========================================================================* @@ -165,7 +165,7 @@ PUBLIC void main(void) } /* Get kernel environment (protected_mode, pc_at and ega are needed). */ - if (OK != (s=sys_getkenviron(&kenv))) { + if (OK != (s=sys_getmachine(&machine))) { server_panic("TTY","Couldn't obtain kernel environment.", s); } diff --git a/drivers/tty/tty.h b/drivers/tty/tty.h index d0431adf7..5f4223ee5 100644 --- a/drivers/tty/tty.h +++ b/drivers/tty/tty.h @@ -104,8 +104,7 @@ extern clock_t tty_next_timeout; /* next TTY timeout */ #define bufend(buf) ((buf) + buflen(buf)) /* Memory allocated in tty.c, so extern here. */ -extern struct kenviron kenv; /* kernel environment (a.o.: pc_at, ega) */ - +extern struct machine machine; /* machine information (a.o.: pc_at, ega) */ /* Function prototypes for TTY driver. */ /* tty.c */ diff --git a/include/ibm/bios.h b/include/ibm/bios.h index 6bf014a6d..b5d22db4e 100644 --- a/include/ibm/bios.h +++ b/include/ibm/bios.h @@ -1,55 +1,129 @@ -/* BIOS definitions. Each BIOS entry has an index that is to be used with the - * sys_bioscopy() system call. The raw addresses, sizes, and magic numbers - * are defined here as well. The values that are defined here were collected - * from various kernel files in MINIX 2.0.4. - * - * Author: Jorrit N. Herder +/* Definitions of several known BIOS addresses. The addresses listed here + * are found in three memory areas that have been defined in . + * - the BIOS interrupt vectors + * - the BIOS data area + * - the motherboard BIOS memory + * + * Created: March 2005, Jorrit N. Herder */ #ifndef _BIOS_H #define _BIOS_H -/* Memory check (is stopped on reboot). */ -#define BIOS_MEM_CHECK 0 /* address to stop memory check */ -#define ADR_MEM_CHECK 0x472L -#define LEN_MEM_CHECK 1L -#define STOP_MEM_CHECK 0x1234 /* magic number to stop memory check */ -/* Centronics printers. */ -#define BIOS_PRN_PORTBASE 1 /* base of printer ports */ -#define ADR_PRN_PORTBASE 0x408L -#define LEN_PRN_PORTBASE 2L +/* PART I -- + * The BIOS interrupt vector table (IVT) area (1024 B as of address 0x0000). + * Although this area holds 256 interrupt vectors (with jump addresses), some + * vectors actually contain important BIOS data. Some addresses are below. + */ +#define BIOS_EQUIP_CHECK_ADDR 0x0044 +#define BIOS_EQUIP_CHECK_SIZE 4L -/* Hard disk parameter vectors. */ -#define BIOS_WINI_PARAMS 2 /* number of hard disk drives */ -#define ADR_WINI_PARAMS 0x475L -#define LEN_WINI_PARAMS 1L -#define BIOS_WINI_0_PARM_VEC 3 /* disk 0 parameters */ -#define ADR_WINI_0_PARM_VEC 0x41*4L -#define LEN_WINI_0_PARM_VEC 4L -#define BIOS_WINI_1_PARM_VEC 4 /* disk 1 parameters */ -#define ADR_WINI_1_PARM_VEC 0x46*4L -#define LEN_WINI_1_PARM_VEC 4L +#define BIOS_VIDEO_PARAMS_ADDR 0x0074 +#define BIOS_VIDEO_PARAMS_SIZE 4L + +#define BIOS_FLOP_PARAMS_ADDR 0x0078 +#define BIOS_FLOP_PARAMS_SIZE 4L + +#define BIOS_HD0_PARAMS_ADDR 0x0104 /* disk 0 parameters */ +#define BIOS_HD0_PARAMS_SIZE 4L + +#define BIOS_HD1_PARAMS_ADDR 0x0118 /* disk 1 parameters */ +#define BIOS_HD1_PARAMS_SIZE 4L + + +/* PART I -- + * Addresses in the BIOS data area (256 B as of address 0x0400). The addresses + * listed below are the most important ones, and the ones that are currently + * used. Other addresses may be defined below when new features are added. + */ + +/* Parallel ports (LPT1-LPT4). */ +#define COM1_IO_PORT_ADDR 0x400 /* COM1 port address */ +#define COM1_IO_PORT_SIZE 2L +#define COM2_IO_PORT_ADDR 0x402 /* COM2 port address */ +#define COM2_IO_PORT_SIZE 2L +#define COM3_IO_PORT_ADDR 0x404 /* COM3 port address */ +#define COM3_IO_PORT_SIZE 2L +#define COM4_IO_PORT_ADDR 0x406 /* COM4 port address */ +#define COM4_IO_PORT_SIZE 2L + +/* Serial ports (COM1-COM4). */ +#define LPT1_IO_PORT_ADDR 0x408 /* LPT1 port address */ +#define LPT1_IO_PORT_SIZE 2L +#define LPT2_IO_PORT_ADDR 0x40A /* LPT2 port address */ +#define LPT2_IO_PORT_SIZE 2L +#define LPT3_IO_PORT_ADDR 0x40C /* LPT3 port address */ +#define LPT3_IO_PORT_SIZE 2L +#define LPT4_IO_PORT_ADDR 0x40E /* LPT4 port (except on PS/2) */ +#define LPT4_IO_PORT_SIZE 2L + +/* Video controller (VDU). */ +#define VDU_SCREEN_COLS_ADDR 0x44A /* VDU nr of screen columns */ +#define VDU_SCREEN_COLS_SIZE 2L + +/* Base I/O port address for active 6845 CRT controller. */ +#define VDU_CRT_BASE_ADDR 0x463 /* 3B4h = mono, 3D4h = color */ +#define VDU_CRT_BASE_SIZE 2L + +/* Soft reset flags to control shutdown. */ +#define SOFT_RESET_FLAG_ADDR 0x472 /* soft reset flag on Ctl-Alt-Del */ +#define SOFT_RESET_FLAG_SIZE 2L +#define STOP_MEM_CHECK 0x1234 /* bypass memory tests & CRT init */ +#define PRESERVE_MEMORY 0x4321 /* preserve memory */ +#define SYSTEM_SUSPEND 0x5678 /* system suspend */ +#define MANUFACTURER_TEST 0x9ABC /* manufacturer test */ +#define CONVERTIBLE_POST 0xABCD /* convertible POST loop */ + /* ... many other values are used during POST */ + +/* Hard disk parameters. (Also see BIOS interrupt vector table above.) */ +#define NR_HD_DRIVES_ADDR 0x475 /* number of hard disk drives */ +#define NR_HD_DRIVES_SIZE 1L + +/* Parallel ports (LPT1-LPT4) timeout values. */ +#define LPT1_TIMEOUT_ADDR 0x478 /* time-out value for LPT1 */ +#define LPT1_TIMEOUT_SIZE 1L +#define LPT2_TIMEOUT_ADDR 0x479 /* time-out value for LPT2 */ +#define LPT2_TIMEOUT_SIZE 1L +#define LPT3_TIMEOUT_ADDR 0x47A /* time-out value for LPT3 */ +#define LPT3_TIMEOUT_SIZE 1L +#define LPT4_TIMEOUT_ADDR 0x47B /* time-out for LPT4 (except PS/2) */ +#define LPT4_TIMEOUT_SIZE 1L + +/* Serial ports (COM1-COM4) timeout values. */ +#define COM1_TIMEOUT_ADDR 0x47C /* time-out value for COM1 */ +#define COM1_TIMEOUT_SIZE 1L +#define COM2_TIMEOUT_ADDR 0x47D /* time-out value for COM2 */ +#define COM2_TIMEOUT_SIZE 1L +#define COM3_TIMEOUT_ADDR 0x47E /* time-out value for COM3 */ +#define COM3_TIMEOUT_SIZE 1L +#define COM4_TIMEOUT_ADDR 0x47F /* time-out value for COM4 */ +#define COM4_TIMEOUT_SIZE 1L /* Video controller (VDU). */ -#define BIOS_VDU_COLUMNS 5 -#define ADR_VDU_COLUMNS 0x44AL -#define LEN_VDU_COLUMNS 2L -#define BIOS_VDU_CRTBASE 6 -#define ADR_VDU_CRTBASE 0x463L -#define LEN_VDU_CRTBASE 2L -#define BIOS_VDU_ROWS 7 -#define ADR_VDU_ROWS 0x484L -#define LEN_VDU_ROWS 1L -#define BIOS_VDU_FONTLINES 8 -#define ADR_VDU_FONTLINES 0x485L -#define LEN_VDU_FONTLINES 2L +#define VDU_SCREEN_ROWS_ADDR 0x484 /* screen rows (less 1, EGA+)*/ +#define VDU_SCREEN_ROWS_SIZE 1L +#define VDU_FONTLINES_ADDR 0x485 /* point height of char matrix */ +#define VDU_FONTLINES_SIZE 2L + +/* Video controller (VDU). */ +#define VDU_VIDEO_MODE_ADDR 0x49A /* current video mode */ +#define VDU_VIDEO_MODE_SIZE 1L + + +/* PART III -- + * The motherboard BIOS memory contains some known values that are currently + * in use. Other sections in the upper memory area (UMA) addresses vary in + * size and locus and are not further defined here. A rough map is given in + * . + */ + +/* Machine ID (we're interested in PS/2 and AT models). */ +#define MACHINE_ID_ADDR 0xFFFFE /* BIOS machine ID byte */ +#define MACHINE_ID_SIZE 1L +#define PS_386_MACHINE 0xF8 /* ID byte for PS/2 modela 70/80 */ +#define PC_AT_MACHINE 0xFC /* PC/AT, PC/XT286, PS/2 models 50/60 */ -/* Machine ID. */ -#define BIOS_MACHINE_ID 9 -#define ADR_MACHINE_ID 0xFFFFEL -#define LEN_MACHINE_ID 1L -#define PS_386_MACHINE 0xF8 /* Machine ID byte for PS/2 model 80 */ -#define PC_AT_MACHINE 0xFC /* PC/AT, PC/XT286, PS/2 models 50/60 */ #endif /* _BIOS_H */ + diff --git a/include/ibm/memory.h b/include/ibm/memory.h new file mode 100644 index 000000000..850d6e671 --- /dev/null +++ b/include/ibm/memory.h @@ -0,0 +1,174 @@ +/* Physical memory layout on IMB compatible PCs. Only the major, fixed memory + * areas are detailed here. Known addresses of the BIOS data area are defined + * in . The map upper memory area (UMA) is only roughly defined + * since the UMA sections may vary in size and locus. + * + * Created: March 2005, Jorrit N. Herder + */ + + +/* I/O-mapped peripherals. I/O addresses are different from memory addresses + * due to the I/O signal on the ISA bus. Individual I/O ports are defined by + * the drivers that use them or looked up with help of the BIOS. + */ +#define IO_MEMORY_BEGIN 0x0000 +#define IO_MEMORY_END 0xFFFF + + +/* Physical memory layout. Design decisions made for the earliest PCs, caused + * memory to be broken broken into the following four basic pieces: + * - Conventional or base memory: first 640 KB (incl. BIOS data, see below); + * - Upper Memory Area (UMA): upper 384 KB of the first megabyte of memory; + * - High Memory Area (HMA): ~ first 64 KB of the second megabyte of memory; + * - Extended Memory: all the memory above first megabyte of memory. + * The high memory area overlaps with the first 64 KB of extended memory, but + * is different from the rest of extended memory because it can be accessed + * when the processor is in real mode. + */ +#define BASE_MEM_BEGIN 0x000000 +#define BASE_MEM_END 0x09FFFF + +#define UPPER_MEM_BEGIN 0x0A0000 +#define UPPER_MEM_END 0x0FFFFF + +#define HIGH_MEM_BEGIN 0x100000 +#define HIGH_MEM_END 0x10FFEF + +#define EXTENDED_MEM_BEGIN 0x100000 +#define EXTENDED_MEM_END ((unsigned) -1) + + +/* The logical memory map of the first 1.5 MB is as follows (hexadecimals): + * + * offset [size] (id) = memory usage + * ------------------------------------------------------------------------ + * 000000 [00400] (I) = Real-Mode Interrupt Vector Table (1024 B) + * 000400 [00100] (B) = BIOS Data Area (256 B) + * 000800 [00066] (W) = 80286 Loadall workspace + * 010000 [10000] (c) = Real-Mode Compatibility Segment (64 KB) + * 020000 [70000] (.) = Program-accessible memory (free) + * 090000 [10000] (E) = BIOS Extension + * 0A0000 [10000] (G) = Graphics Mode Video RAM + * 0B0000 [08000] (M) = Monochrome Text Mode Video RAM + * 0B8000 [08000] (C) = Color Text Mode Video RAM + * 0C0000 [08000] (V) = Video ROM BIOS (would be "a" in PS/2) + * 0C8000 [18000] (a) = Adapter ROM + special-purpose RAM (free UMA space) + * 0E0000 [10000] (r) = PS/2 Motherboard ROM BIOS (free UMA in non-PS/2) + * 0F0000 [06000] (R) = Motherboard ROM BIOS + * 0F6000 [08000] (b) = IBM Cassette BASIC ROM ("R" in IBM compatibles) + * 0FD000 [02000] (R) = Motherboard ROM BIOS + * 100000 [.....] (.) = Extended memory, program-accessible (free) + * 100000 [0FFEF] (h) = High Memory Area (HMA) + * + * + * Conventional (Base) Memory: + * + * : [~~~~~16 KB~~~~][~~~~~16 KB~~~~][~~~~~16 KB~~~~][~~~~~16 KB~~~~] + * : 0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F--- + * 000000: IBW............................................................. + * 010000: cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc + * 020000: ................................................................ + * 030000: ................................................................ + * 040000: ................................................................ + * 050000: ................................................................ + * 060000: ................................................................ + * 070000: ................................................................ + * 080000: ................................................................ + * 090000: EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + * + * Upper Memory Area (UMA): + * + * : 0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F--- + * 0A0000: GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG + * 0B0000: MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC + * 0C0000: VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + * 0D0000: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + * 0E0000: rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr + * 0F0000: RRRRRRRRRRRRRRRRRRRRRRRRbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbRRRRRRRR + * + * Extended Memory: + * + * : 0---1---2---3---4---5---6---7---8---9---A---B---C---D---E---F--- + * 100000: hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh. + * 110000: ................................................................ + * 120000: ................................................................ + * 130000: ................................................................ + * 140000: ................................................................ + * 150000: ................................................................ + * 160000: ................................................................ + * 170000: ................................................................ + * + * Source: The logical memory map was partly taken from the book "Upgrading + * & Repairing PCs Eight Edition", Macmillan Computer Publishing. + */ + + +/* The bottom part of conventional or base memory is occupied by BIOS data. + * The BIOS memory can be distinguished in two parts: + * o The first the first 1024 bytes of addressable memory contains the BIOS + * real-mode interrupt vector table (IVT). The table is used to access BIOS + * hardware services in real-mode by loading a interrupt vector and issuing + * an INT instruction. Some vectors contain BIOS data that can be retrieved + * directly and are useful in protected-mode as well. + * o The BIOS data area is located directly above the interrupt vectors. It + * comprises 256 bytes of memory. These data are used by the device drivers + * to retrieve hardware details, such as I/O ports to be used. + */ +#define BIOS_MEM_BEGIN 0x00000 /* all BIOS memory */ +#define BIOS_MEM_END 0x004FF +#define BIOS_IVT_BEGIN 0x00000 /* BIOS interrupt vectors */ +#define BIOS_IVT_END 0x003FF +#define BIOS_DATA_BEGIN 0x00400 /* BIOS data area */ +#define BIOS_DATA_END 0x004FF + + +/* The base memory is followed by 384 KB reserved memory located at the top of + * the first MB of physical memory. This memory is known as the upper memory + * area (UMA). It is used for memory-mapped peripherals, such as video RAM, + * adapter BIOS (adapter ROM and special purpose RAM), and the motherboard + * BIOS (I/O system, Power-On Self Test, bootstrap loader). The upper memory + * can roughly be distinguished in three parts: + * + * o The first 128K of the upper memory area (A0000-BFFFF) is reserved for use + * by memory-mapped video adapters. Hence, it is also called Video RAM. The + * display driver can directly write to this memory and request the hardware + * to show the data on the screen. + */ +#define UMA_VIDEO_RAM_BEGIN 0xA0000 /* video RAM */ +#define UMA_VIDEO_RAM_END 0xBFFFF +#define UMA_GRAPHICS_RAM_BEGIN 0xA0000 /* graphics RAM */ +#define UMA_GRAPHICS_RAM_END 0xAFFFF +#define UMA_MONO_TEXT_BEGIN 0xB0000 /* monochrome text */ +#define UMA_MONO_TEXT_END 0xB7FFF +#define UMA_COLOR_TEXT_BEGIN 0xB8000 /* color text */ +#define UMA_COLOR_TEXT_END 0xBFFFF + + +/* o The next 128K (the memory range C0000-DFFFF) is reserved for the adapter + * BIOS that resides in the ROM on some adapter boards. Most VGA-compatible + * video adapters use the first 32 KB of this area for their on-board BIOS. + * The rest can be used by any other adapters. The IDE controller often + * occupies the second 32 KB. + */ +#define UMA_ADAPTER_BIOS_BEGIN 0xC0000 /* adapter BIOS */ +#define UMA_ADAPTER_BIOS_END 0xDFFFF +#define UMA_VIDEO_BIOS_BEGIN 0xC0000 /* video adapter */ +#define UMA_VIDEO_BIOS_END 0xC7FFF +#define UMA_IDE_HD_BIOS_BEGIN 0xC8000 /* IDE hard disk */ +#define UMA_IDE_HD_BIOS_END 0xCBFFF + + +/* o The last 128K of the upper memory area (E0000-FFFFF) is reserved for + * motherboard BIOS (Basic I/O System). The POST (Power-On Self Test) and + * bootstrap loader also reside in this space. The memory falls apart in + * two areas: Plug & Play BIOS data and the system BIOS data. + */ +#define UMA_MB_BIOS_BEGIN 0xE0000 /* motherboard BIOS */ +#define UMA_MB_BIOS_END 0xFFFFF +#define UMA_PNP_ESCD_BIOS_BEGIN 0xE0000 /* PnP extended data */ +#define UMA_PNP_ESCD_BIOS_END 0xEFFFF +#define UMA_SYSTEM_BIOS_BEGIN 0xF0000 /* system BIOS */ +#define UMA_SYSTEM_BIOS_END 0xFFFFF + + + diff --git a/include/minix/com.h b/include/minix/com.h index 579e537c1..ea3095252 100755 --- a/include/minix/com.h +++ b/include/minix/com.h @@ -45,7 +45,7 @@ #define CTRLR(n) (NONE + (n)) /* User-level processes, that is, device drivers, servers, and INIT. */ -#define MM_PROC_NR 0 /* memory manager */ +#define PM_PROC_NR 0 /* process manager */ #define FS_PROC_NR 1 /* file system */ #define IS_PROC_NR 5 /* information server */ #define TTY 6 /* terminal (TTY) driver */ @@ -130,12 +130,11 @@ # define NULL_DEV 3 /* minor device for /dev/null */ # define BOOT_DEV 4 /* minor device for /dev/boot */ # define RANDOM_DEV 5 /* minor device for /dev/random */ -# define URANDOM_DEV 6 /* minor device for /dev/urandom */ +# define ZERO_DEV 6 /* minor device for /dev/zero */ +/* Full device numbers that are special to the boot monitor and FS. */ # define DEV_RAM 0x0100 /* device number of /dev/ram */ # define DEV_BOOT 0x0104 /* device number of /dev/boot */ -# define DEV_RANDOM 0x0105 /* device number of /dev/random */ -# define DEV_URANDOM 0x0106 /* device number of /dev/urandom */ /*===========================================================================* @@ -204,40 +203,40 @@ * modifying the system call numbers. The numbers here determine which call * is made from the call vector. */ -#define NR_SYS_CALLS 32 /* number of system calls */ +#define NR_SYS_CALLS 33 /* number of system calls */ # define SYS_TIMES 0 /* sys_times(proc_nr, bufptr) */ # define SYS_XIT 1 /* sys_xit(parent, proc) */ +# define SYS_GETSIG 2 /* sys_getsig(proc_nr, sig_map) */ -# define SYS_SIGCTL 3 /* sys_sigctl(req,pnr,sig,ctxt,flag,pnr,map) */ # define SYS_FORK 4 /* sys_fork(parent, child, pid) */ # define SYS_NEWMAP 5 /* sys_newmap(proc_nr, map_ptr) */ -# define SYS_COPY 6 /* sys_copy(ptr) */ +# define SYS_ENDSIG 6 /* sys_endsig(proc_nr) */ # define SYS_EXEC 7 /* sys_exec(proc_nr, new_sp) */ - +# define SYS_SIGSEND 8 /* sys_sigsend(proc_nr, ctxt_ptr) */ # define SYS_ABORT 9 /* sys_abort() */ # define SYS_KILL 10 /* sys_kill(proc_nr, sig) */ # define SYS_UMAP 11 /* sys_umap(proc_nr, etc) */ - +# define SYS_RANDOM 12 /* sys_random(...) */ # define SYS_TRACE 13 /* sys_trace(req,pid,addr,data) */ -# define SYS_VCOPY 14 /* sys_vcopy(src_p, dst_p, vcpy_s, vcpy_ptr) */ + # define SYS_SIGNALRM 15 /* sys_signalrm(proc_nr, ticks) */ # define SYS_SYNCALRM 16 /* sys_syncalrm(proc_nr,exp_time,abs_time) */ # define SYS_FLAGALRM 17 /* sys_flagalrm(ticks, flag_ptr) */ # define SYS_SVRCTL 19 /* sys_svrctl(proc_nr, req, argp) */ # define SYS_SDEVIO 20 /* sys_sdevio(port, proc_nr, buf, count) */ - +# define SYS_SIGRETURN 21 /* sys_sigreturn(proc_nr, ctxt_ptr, flags) */ # define SYS_GETINFO 22 /* sys_getinfo(what, whereto) */ # define SYS_DEVIO 23 /* sys_devio(port, value) */ # define SYS_VDEVIO 24 /* sys_vdevio(buf_ptr, nr_ports) */ # define SYS_IRQCTL 25 /* sys_irqctl() */ # define SYS_KMALLOC 26 /* sys_kmalloc(size, phys_base) */ # define SYS_IOPENABLE 27 /* sys_enable_iop() */ -# define SYS_PHYS2SEG 28 /* sys_phys2seg(*seg, *off, phys) */ +# define SYS_SEGCTL 28 /* sys_segctl(*idx, *seg, *off, phys, size) */ # define SYS_EXIT 29 /* sys_exit(status) */ # define SYS_VIRCOPY 30 /* sys_vircopy(src,seg,addr,dst,seg,addr,cnt) */ # define SYS_PHYSCOPY 31 /* sys_physcopy(src_addr,dst_addr,count) */ -# define SYS_MSTATS 32 +# define SYS_VIRVCOPY 32 /* sys_virvcopy(vec_ptr, vec_size) */ /* Field names for SYS_MEM, SYS_KMALLOC. */ #define MEM_CHUNK_BASE m4_l1 /* physical base address */ @@ -289,11 +288,12 @@ /* Names of message field and paramaters for SYS_EXIT request. */ #define EXIT_STATUS m2_i1 /* zero for normal exit, non-zero else */ -/* Field names for SYS_PHYS2SEG. */ +/* Field names for SYS_SEGCTL. */ #define SEG_SELECT m4_l1 /* segment selector returned */ #define SEG_OFFSET m4_l2 /* offset in segment returned */ #define SEG_PHYS m4_l3 /* physical address of segment */ #define SEG_SIZE m4_l4 /* segment size */ +#define SEG_INDEX m4_l5 /* segment index in remote map */ /* Field names for SYS_VIDCOPY. */ #define VID_REQUEST m4_l1 /* what to do? */ @@ -310,7 +310,7 @@ #define ABRT_MON_LEN m1_i3 /* length of monitor params */ #define ABRT_MON_ADDR m1_p1 /* virtual address of monitor params */ -/* Field names for SYS_COPY, _UMAP, _VIRCOPY, _PHYSCOPY. */ +/* Field names for _UMAP, _VIRCOPY, _PHYSCOPY. */ #define CP_SRC_SPACE m5_c1 /* T or D space (stack is also D) */ #define CP_SRC_PROC_NR m5_i1 /* process to copy from */ #define CP_SRC_ADDR m5_l1 /* address where data come from */ @@ -327,7 +327,7 @@ /* Field names for SYS_GETINFO. */ #define I_REQUEST m7_i3 /* what info to get */ -# define GET_KENVIRON 0 /* get kernel environment variables */ +# define GET_KINFO 0 /* get kernel information structure */ # define GET_IMAGE 1 /* get system image table */ # define GET_PROCTAB 2 /* get (kernel) process table */ # define GET_PROCNR 3 /* find nr of process with name */ @@ -339,6 +339,7 @@ # define GET_KADDRESSES 9 /* get various kernel addresses */ # define GET_SCHEDINFO 10 /* get scheduling queues */ # define GET_PROC 11 /* get process slot if given process */ +# define GET_MACHINE 12 /* get machine information */ #define I_PROC_NR m7_i4 /* calling process */ #define I_VAL_PTR m7_p1 /* virtual address at caller */ #define I_VAL_LEN m7_i1 /* max length of value */ diff --git a/include/minix/config.h b/include/minix/config.h index 8a4151e55..a8f420620 100755 --- a/include/minix/config.h +++ b/include/minix/config.h @@ -38,7 +38,7 @@ #endif #if (MACHINE == IBM_PC && _WORD_SIZE == 4) -#define NR_BUFS 128 /* # blocks in the buffer cache */ +#define NR_BUFS 1024 /* # blocks in the buffer cache */ #define NR_BUF_HASH 1024 /* size of buf hash table; MUST BE POWER OF 2*/ #endif @@ -52,7 +52,7 @@ #define LINEWRAP 1 /* console.c - wrap lines at column 80 */ #define ALLOW_GAP_MESSAGES 1 /* proc.c - allow messages in the gap between * the end of bss and lowest stack address */ -#define KMESS_BUF_SIZE 512 /* size in B for kernel messages */ +#define KMESS_BUF_SIZE 512 /* size in bytes for kernel messages */ /* Number of controller tasks (/dev/cN device classes). */ #define NR_CTRLRS 2 @@ -65,7 +65,10 @@ /* Enable or disable kernel calls (allows for minimal kernel). */ #define ENABLE_K_TRACING 1 /* process tracing can be disabled */ -#define ENABLE_K_DEBUGGING 1 /* kernel debugging calls */ +#define ENABLE_K_DEBUGGING 0 /* kernel debugging calls */ + +/* Include or exclude an image of /dev/boot in the boot image. */ +#define ENABLE_BOOTDEV 1 /* Include or exclude device drivers. Set to 1 to include, 0 to exclude. */ #define ENABLE_BIOS_WINI 0 /* enable BIOS winchester driver */ @@ -110,8 +113,7 @@ * ENABLE_USERPRIV must be set to 1 to allow the features anyway. */ #define ENABLE_USERBIOS 0 /* enable user mode BIOS calls */ -#define ENABLE_LOOSELDT 0 /* allow imprecise, page based LDT entries */ -#define ENABLE_USERIOPL 1 /* enable CPU's IOPL bits for /dev/(k)mem */ +#define ENABLE_USERIOPL 0 /* enable CPU's IOPL bits for /dev/(k)mem */ /* NR_CONS, NR_RS_LINES, and NR_PTYS determine the number of terminals the * system can handle. diff --git a/include/minix/const.h b/include/minix/const.h index d9c796f9a..b2d820fac 100755 --- a/include/minix/const.h +++ b/include/minix/const.h @@ -42,6 +42,8 @@ #define BIOS_SEG 0x0200 /* flags indicating BIOS memory segment */ #define NR_BIOS_SEGS 3 /* # BIOS memory regions (variable) */ +#define PHYS_SEG 0x0300 /* flag indicating entire physical memory */ + /* Labels used to disable code sections for different reasons. */ #define DEAD_CODE 0 /* unused code in normal configuration */ #define FUTURE_CODE 0 /* new code to be activated + tested later */ diff --git a/include/minix/syslib.h b/include/minix/syslib.h index 98264fffc..9697dd9f6 100755 --- a/include/minix/syslib.h +++ b/include/minix/syslib.h @@ -11,7 +11,7 @@ * Sep 02, 2004 added sys_exit (Jorrit N. Herder) * Aug 15, 2004 added sys_getinfo (Jorrit N. Herder) * Jul 23, 2004 added sys_umap (Jorrit N. Herder) - * Jul 13, 2004 added sys_enable_iop, sys_phys2seg (Jorrit N. Herder) + * Jul 13, 2004 added sys_enable_iop, sys_segctl (Jorrit N. Herder) * Mar 20, 2004 added sys_devio, sys_vdevio (Jorrit N. Herder) */ @@ -41,8 +41,6 @@ _PROTOTYPE( int _taskcall, (int who, int syscallnr, message *msgptr) ); _PROTOTYPE( int sys_abort, (int how, ...) ); _PROTOTYPE( int sys_adjmap, (int proc, struct mem_map *ptr, vir_clicks data_clicks, vir_clicks sp) ); -_PROTOTYPE( int sys_copy, (int src_proc, int src_seg, phys_bytes src_vir, - int dst_proc, int dst_seg, phys_bytes dst_vir, phys_bytes bytes)); _PROTOTYPE( int sys_exec, (int proc, char *ptr, int traced, char *aout, vir_bytes initpc) ); _PROTOTYPE( int sys_execmap, (int proc, struct mem_map *ptr) ); @@ -54,14 +52,9 @@ _PROTOTYPE( int sys_times, (int proc_nr, clock_t *ptr) ); _PROTOTYPE( int sys_getuptime, (clock_t *ticks) ); _PROTOTYPE( int sys_trace, (int req, int proc, long addr, long *data_p) ); _PROTOTYPE( int sys_xit, (int parent, int proc) ); -_PROTOTYPE( int sys_kill, (int proc, int sig) ); _PROTOTYPE( int sys_svrctl, (int proc, int req, int priv,vir_bytes argp)); -/*==========================================================================* - * New prototypes since MINIX release 2 (Jorrit N. Herder) * - *==========================================================================*/ - /* Shorthands for sys_sdevio() system call. */ #define sys_insb(port, proc_nr, buffer, count) \ sys_sdevio(DIO_INPUT, port, DIO_BYTE, proc_nr, buffer, count) @@ -89,7 +82,7 @@ _PROTOTYPE(int sys_syncalrm, (int proc_nr, clock_t exp_time, int abs_time) ); _PROTOTYPE ( int sys_irqctl, (int request, int irq_vec, int policy, int proc_nr, long port, void *val_ptr, long mask_val) ); -/* Shorthands for sys_vircopy() system call. */ +/* Shorthands for sys_vircopy() and sys_physcopy() system calls. */ #define sys_biosin(bios_vir, dst_vir, bytes) \ sys_vircopy(SELF, BIOS_SEG, bios_vir, SELF, D, dst_vir, bytes) #define sys_biosout(src_vir, bios_vir, bytes) \ @@ -103,17 +96,22 @@ _PROTOTYPE ( int sys_irqctl, (int request, int irq_vec, int policy, _PROTOTYPE(int sys_vircopy, (int src_proc, int src_seg, vir_bytes src_vir, int dst_proc, int dst_seg, vir_bytes dst_vir, phys_bytes bytes) ); -_PROTOTYPE(int sys_physcopy, (phys_bytes src_phys, phys_bytes dst_phys, - phys_bytes bytes) ); +#define sys_abscopy(src_phys, dst_phys, bytes) \ + sys_physcopy(NONE, PHYS_SEG, src_phys, NONE, PHYS_SEG, dst_phys, bytes) +_PROTOTYPE(int sys_physcopy, (int src_proc, int src_seg, vir_bytes src_vir, + int dst_proc, int dst_seg, vir_bytes dst_vir, phys_bytes bytes) ); + _PROTOTYPE(int sys_umap, (int proc_nr, int seg, vir_bytes vir_addr, vir_bytes bytes, phys_bytes *phys_addr) ); -_PROTOTYPE(int sys_phys2seg, (u16_t *seg,vir_bytes *off,phys_bytes phys, vir_bytes size)); +_PROTOTYPE(int sys_segctl, (int *index, u16_t *seg, vir_bytes *off, + phys_bytes phys, vir_bytes size)); _PROTOTYPE(int sys_enable_iop, (int proc_nr) ); _PROTOTYPE(int sys_kmalloc, (size_t size, phys_bytes *phys_base) ); /* Shorthands for sys_getinfo() system call. */ #define sys_getkmessages(dst) sys_getinfo(GET_KMESSAGES, dst, 0,0,0) -#define sys_getkenviron(dst) sys_getinfo(GET_KENVIRON, dst, 0,0,0) +#define sys_getkinfo(dst) sys_getinfo(GET_KINFO, dst, 0,0,0) +#define sys_getmachine(dst) sys_getinfo(GET_MACHINE, dst, 0,0,0) #define sys_getproctab(dst) sys_getinfo(GET_PROCTAB, dst, 0,0,0) #define sys_getproc(dst,nr) sys_getinfo(GET_PROC, dst, 0,0, nr) #define sys_getprocnr(dst,k,kl) sys_getinfo(GET_PROCNR, dst, 0,k,kl) @@ -129,17 +127,12 @@ _PROTOTYPE(int sys_getinfo, (int request, void *val_ptr, int val_len, _PROTOTYPE(int sys_exit, (int status) ); -/* Shorthands for sys_sigctl() system call. */ -#define sys_getsig(proc_nr, sig_map) \ - sys_sigctl(S_GETSIG, 0,0,0, proc_nr, sig_map) -#define sys_endsig(proc_nr) \ - sys_sigctl(S_ENDSIG, proc_nr, 0,0,0,0) -#define sys_sendsig(proc_nr, sig_ctxt) \ - sys_sigctl(S_SENDSIG, proc_nr, sig_ctxt, 0,0,0) -#define sys_sigreturn(proc_nr, sig_ctxt, flags) \ - sys_sigctl(S_SIGRETURN, proc_nr, sig_ctxt, flags, 0,0) -_PROTOTYPE(int sys_sigctl, (int request, int proc_nr, struct sigmsg *sig_ctxt, - int flags, int *k_proc_nr, sigset_t *k_sig_map) ); +/* Signal control. */ +_PROTOTYPE(int sys_kill, (int proc, int sig) ); +_PROTOTYPE(int sys_sigsend, (int proc_nr, struct sigmsg *sig_ctxt) ); +_PROTOTYPE(int sys_sigreturn, (int proc_nr, struct sigmsg *sig_ctxt, int flags) ); +_PROTOTYPE(int sys_getsig, (int *k_proc_nr, sigset_t *k_sig_map) ); +_PROTOTYPE(int sys_endsig, (int proc_nr) ); /* NOTE: two different approaches were used to distinguish the device I/O * types 'byte', 'word', 'long': the latter uses #define and results in a diff --git a/include/minix/type.h b/include/minix/type.h index 2dd6236c4..10fe1d064 100755 --- a/include/minix/type.h +++ b/include/minix/type.h @@ -22,17 +22,33 @@ typedef unsigned long vir_bytes;/* virtual addresses and lengths in bytes */ typedef unsigned long vir_bytes;/* virtual addresses and lengths in bytes */ #endif +/* Memory map for local text, stack, data segments. */ struct mem_map { vir_clicks mem_vir; /* virtual address */ phys_clicks mem_phys; /* physical address */ vir_clicks mem_len; /* length */ }; +/* Memory map for remote memory areas, e.g., for the RAM disk. */ struct far_mem { + int in_use; /* entry in use, unless zero */ phys_clicks mem_phys; /* physical address */ vir_clicks mem_len; /* length */ }; +/* Structure for virtual copying by means of a vector with requests. */ +struct vir_addr { + int proc_nr; + int segment; + vir_bytes offset; +}; + +struct vir_cp_req { + struct vir_addr src; + struct vir_addr dst; + phys_bytes count; +}; + typedef struct { vir_bytes iov_addr; /* address of an I/O buffer */ vir_bytes iov_size; /* sizeof an I/O buffer */ @@ -74,20 +90,28 @@ struct psinfo { /* information for the ps(1) program */ }; /* This is used to obtain system information through SYS_GETINFO. */ -struct kenviron { +struct kinfo { + phys_bytes code_base; /* base of kernel code */ + phys_bytes code_size; + phys_bytes data_base; /* base of kernel data */ + phys_bytes data_size; + vir_bytes proc_addr; /* virtual address of process table */ + phys_bytes kmem_base; /* kernel memory layout (/dev/kmem) */ + phys_bytes kmem_size; + phys_bytes bootdev_base; /* boot device from boot image (/dev/boot) */ + phys_bytes bootdev_size; + phys_bytes params_base; /* parameters passed by boot monitor */ + phys_bytes params_size; + char version[8]; /* kernel version number */ +}; + +struct machine { int pc_at; int ps_mca; int processor; int protected; - int ega; - int vga; - vir_bytes proc_addr; /* virtual address of process table */ - phys_bytes kmem_base; /* kernel memory layout (/dev/kmem) */ - phys_bytes kmem_size; - phys_bytes bootfs_base; /* FS image from boot image (/dev/boot) */ - phys_bytes bootfs_size; - phys_bytes params_base; /* parameters passed by boot monitor */ - phys_bytes params_size; + int vdu_ega; + int vdu_vga; }; /* The kernel outputs messages in a local buffer, which can be requested and diff --git a/kernel/Makefile b/kernel/Makefile index 28323a77e..10f9f1d45 100755 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -21,7 +21,7 @@ LIBS = -lsys -lutils -ltimers HEAD = mpx.o OBJS = start.o protect.o klibc.o klib.o table.o main.o proc.o \ - i8259.o exception.o system.o clock.o memory.o misc.o \ + i8259.o exception.o system.o clock.o misc.o \ dummy.o \ rtl8139.o pci.o pci_table.o @@ -91,10 +91,6 @@ main.o: $h/com.h main.o: proc.h main.o: sendmask.h -memory.o: $a -memory.o: proc.h -memory.o: protect.h - misc.o: $a misc.o: $i/stdlib.h misc.o: $h/com.h @@ -175,9 +171,7 @@ system/system.a: system/irqctl.c system/system.a: system/misc.c system/system.a: system/proctl.c system/system.a: system/sigctl.c -system/system.a: system/srvrctl.c +system/system.a: system/sysctl.c system/system.a: system/tracing.c system/system.a: system/debugging.c -system/system.a: system/do_copy.c -system/system.a: system/do_vcopy.c diff --git a/kernel/clock.c b/kernel/clock.c index fce234433..0b7b58267 100755 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -222,7 +222,7 @@ irq_hook_t *hook; clock_t now; /* Acknowledge the PS/2 clock interrupt. */ - if (ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT); + if (machine.ps_mca) outb(PORT_B, inb(PORT_B) | CLOCK_ACK_BIT); /* Update user and system accounting times. Charge the current process for * user time. If the current process is not billable, that is, if a non-user diff --git a/kernel/const.h b/kernel/const.h index f7921363a..a8f78a836 100755 --- a/kernel/const.h +++ b/kernel/const.h @@ -9,7 +9,7 @@ /* To translate an address in kernel space to a physical address. This is * the same as umap_local(proc_ptr, D, vir, sizeof(*vir)), but less costly. */ -#define vir2phys(vir) (data_base + (vir_bytes) (vir)) +#define vir2phys(vir) (kinfo.data_base + (vir_bytes) (vir)) /* Constants used in virtual_copy(). Values must be 0 and 1, respectively! */ #define _SRC_ 0 @@ -27,6 +27,9 @@ /* How many bytes for (port,value)-pairs vector to copy in. */ #define VDEVIO_BUF_SIZE 128 +/* How many elements in vector of virtual copy requests. */ +#define VCOPY_VEC_SIZE 16 + /* Program stack words and masks. */ #define INIT_PSW 0x0200 /* initial psw */ #define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */ diff --git a/kernel/exception.c b/kernel/exception.c index 093360848..ee3b78173 100755 --- a/kernel/exception.c +++ b/kernel/exception.c @@ -62,7 +62,7 @@ unsigned vec_nr; } /* Exception in system code. This is not supposed to happen. */ - if (ep->msg == NIL_PTR || processor < ep->minprocessor) + if (ep->msg == NIL_PTR || machine.processor < ep->minprocessor) kprintf("\nIntel-reserved exception %d\n", vec_nr); else kprintf("\n%s\n", karg(ep->msg)); diff --git a/kernel/glo.h b/kernel/glo.h index 36c118f6f..ebb844ba2 100755 --- a/kernel/glo.h +++ b/kernel/glo.h @@ -16,10 +16,12 @@ EXTERN int shutting_down; /* TRUE if the system is shutting down */ EXTERN struct proc *shutdown_process; /* process awaiting shutdown of */ EXTERN timer_t shutdown_timer; /* watchdog function called after timeout */ -/* Kernel memory. */ -EXTERN phys_bytes code_base; /* base of kernel code */ -EXTERN phys_bytes data_base; /* base of kernel data */ +/* Kernel information structures. This groups vital kernel information. */ EXTERN phys_bytes aout; /* address of a.out headers */ +EXTERN struct kinfo kinfo; /* kernel information for users */ +EXTERN struct machine machine; /* machine information for users */ +EXTERN struct kmessages kmess; /* diagnostic messages in kernel */ +EXTERN struct memory mem[NR_MEMS]; /* base and size of chunks of memory */ /* Low level notifications may be put on the 'held' queue to prevent races. */ EXTERN struct proc *held_head; /* head of queue of held-up interrupts */ @@ -29,29 +31,11 @@ EXTERN unsigned char k_reenter; /* kernel reentry count (entry count less 1)*/ /* Process table. Here to stop too many things having to include proc.h. */ EXTERN struct proc *proc_ptr; /* pointer to currently running process */ -/* Memory sizes. */ -EXTERN struct memory mem[NR_MEMS]; /* base and size of chunks of memory */ -EXTERN phys_clicks tot_mem_size; /* total system memory size */ - /* Miscellaneous. */ EXTERN unsigned lost_ticks; /* clock ticks counted outside the clock task */ #if (CHIP == INTEL) -/* Machine type. */ -EXTERN int pc_at; /* PC-AT compatible hardware interface */ -EXTERN int ps_mca; /* PS/2 with Micro Channel */ -EXTERN unsigned int processor; /* 86, 186, 286, 386, ... */ -#if _WORD_SIZE == 2 -EXTERN int protected_mode; /* nonzero if running in Intel protected mode*/ -#else -#define protected_mode 1 /* 386 mode implies protected mode */ -#endif - -/* Video card types. */ -EXTERN int ega; /* nonzero if console is EGA */ -EXTERN int vga; /* nonzero if console is VGA */ - /* Interrupt related variables. */ EXTERN struct irqtab irqtab[NR_IRQ_VECTORS]; /* table with IRQ policies */ EXTERN irq_hook_t *irq_hooks[NR_IRQ_VECTORS]; /* list of IRQ handlers */ @@ -59,11 +43,8 @@ EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */ EXTERN int irq_use; /* bit map of all in-use irq's */ /* Miscellaneous. */ -EXTERN struct kmessages kmess; /* diagnostic messages in kernel */ EXTERN reg_t mon_ss, mon_sp; /* monitor stack */ EXTERN int mon_return; /* true if return to the monitor possible */ -EXTERN phys_bytes mon_params; /* boot parameter block passed in/out */ -EXTERN size_t mon_parmsize; /* boot parameter block size */ /* Variables that are initialized elsewhere are just extern here. */ extern struct system_image image[]; /* system image processes (table.c) */ diff --git a/kernel/i8259.c b/kernel/i8259.c index f856a840e..b46ee57fc 100755 --- a/kernel/i8259.c +++ b/kernel/i8259.c @@ -45,18 +45,18 @@ int mine; int i; lock(); - if (protected_mode) { + if (machine.protected) { /* The AT and newer PS/2 have two interrupt controllers, one master, * one slaved at IRQ 2. (We don't have to deal with the PC that * has just one controller, because it must run in real mode.) */ - outb(INT_CTL, ps_mca ? ICW1_PS : ICW1_AT); + outb(INT_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT); outb(INT_CTLMASK, mine ? IRQ0_VECTOR : BIOS_IRQ0_VEC); /* ICW2 for master */ outb(INT_CTLMASK, (1 << CASCADE_IRQ)); /* ICW3 tells slaves */ outb(INT_CTLMASK, ICW4_AT); outb(INT_CTLMASK, ~(1 << CASCADE_IRQ)); /* IRQ 0-7 mask */ - outb(INT2_CTL, ps_mca ? ICW1_PS : ICW1_AT); + outb(INT2_CTL, machine.ps_mca ? ICW1_PS : ICW1_AT); outb(INT2_CTLMASK, mine ? IRQ8_VECTOR : BIOS_IRQ8_VEC); /* ICW2 for slave */ outb(INT2_CTLMASK, CASCADE_IRQ); /* ICW3 is slave nr */ diff --git a/kernel/klib386.s b/kernel/klib386.s index 95d2093f1..4bade860b 100755 --- a/kernel/klib386.s +++ b/kernel/klib386.s @@ -30,6 +30,7 @@ .define _reset ! reset the system .define _idle_task ! task executed when there is no work .define _level0 ! call a function at level 0 +.define _read_tsc ! read the cycle counter (Pentium and up) ! The routines only guarantee to preserve the registers the C compiler ! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and @@ -495,3 +496,22 @@ _level0: mov (_level0_func), eax int LEVEL0_VECTOR ret + + +!*===========================================================================* +!* read_tsc * +!*===========================================================================* +! PUBLIC void read_tsc(unsigned long *low, unsigned long *high); +! Read the cycle counter of the CPU. Pentium and up. +.align 16 +_read_tsc: +.data1 0x0f ! this is the RDTSC instruction +.data1 0x31 ! it places the TSC in EDX:EAX + push ebp + mov ebp, 8(esp) + mov (ebp), edx + mov ebp, 12(esp) + mov (ebp), eax + pop ebp + ret + diff --git a/kernel/klib88.s b/kernel/klib88.s index 68f28219d..e69de29bb 100755 --- a/kernel/klib88.s +++ b/kernel/klib88.s @@ -1,1057 +0,0 @@ -# -#include -#include -#include "const.h" -#include "sconst.h" -#include "protect.h" - -! This file contains a number of assembly code utility routines needed by the -! kernel. They are: - -.define _monitor ! exit Minix and return to the monitor -.define _int86 ! make an 8086 interrupt call -.define real2prot ! switch from real to protected mode -.define prot2real ! switch from protected to real mode -.define _cp_mess ! copies messages from source to destination -.define _exit ! dummy for library routines -.define __exit ! dummy for library routines -.define ___exit ! dummy for library routines -.define .fat, .trp ! dummies for library routines -.define _phys_insw ! transfer data from (disk controller) port to memory -.define _phys_insb ! likewise byte by byte -.define _phys_outsw ! transfer data from memory to (disk controller) port -.define _phys_outsb ! likewise byte by byte -.define _enable_irq ! enable an irq at the 8259 controller -.define _disable_irq ! disable an irq -.define _phys_copy ! copy data from anywhere to anywhere in memory -.define _mem_rdw ! copy one word from [segment:offset] -.define _reset ! reset the system -.define _mem_vid_copy ! copy data to video ram -.define _vid_vid_copy ! move data in video ram -.define _idle_task ! executed when there is no work -.define _level0 ! call a function at level 0 -.define klib_init_prot ! initialize klib functions for protected mode - -! The routines only guarantee to preserve the registers the C compiler -! expects to be preserved (si, di, bp, sp, segment registers, and direction -! bit in the flags), though some of the older ones preserve bx, cx and dx. - -#define DS_286_OFFSET DS_286_INDEX*DESC_SIZE -#define ES_286_OFFSET ES_286_INDEX*DESC_SIZE -# define EM_XFER_FUNC 0x87 -#define JMP_OPCODE 0xE9 /* opcode used for patching */ -#define OFF_MASK 0x000F /* offset mask for phys_b -> hclick:offset */ -#define HCHIGH_MASK 0x0F /* h/w click mask for low byte of hi word */ -#define HCLOW_MASK 0xF0 /* h/w click mask for low byte of low word */ - -! Exported variables -.extern kernel_cs - - .text -!*===========================================================================* -!* monitor * -!*===========================================================================* -! PUBLIC void monitor(); -! Return to the monitor. - -_monitor: - call prot2real ! switch to real mode - mov sp, _mon_sp ! restore monitor stack pointer - mov bx, _mon_ss ! monitor data segment - mov ds, bx - mov es, bx - mov ss, bx - pop di - pop si - pop bp - retf ! return to the monitor - - -!*===========================================================================* -!* int86 * -!*===========================================================================* -! PUBLIC void int86(); -_int86: ! make an 8086 interrupt call. - push bp - push si - push di ! save C variable registers - pushf ! save flags - - call int86 ! make the actual call - - popf ! restore flags - pop di ! restore C registers - pop si - pop bp - ret - -! Do an 8086 interrupt from protected mode -p_int86: - push bp - push si - push di ! save C variable registers - pushf ! save flags - - cli ! no interruptions - inb INT2_CTLMASK - movb ah, al - inb INT_CTLMASK - push ax ! save interrupt masks - mov ax, _irq_use ! map of in-use IRQs - and ax, #~[1< CLICK_SHIFT -#error /* Small click sizes are not supported (right shift will lose bits). */ -#endif -#if HCLICK_SHIFT < CLICK_SHIFT - movb cl,#CLICK_SHIFT-HCLICK_SHIFT - shl ax,cl ! destination segment -#endif - mov es,ax - mov di,14(bx) ! offset of destination message - -! Be careful not to destroy ds before we are finished with the bx pointer. -! We are using bx and not the more natural bp to save pushing bp. - - mov ax,6(bx) ! process number of sender - mov si,10(bx) ! offset of source message - mov bx,8(bx) ! source click (finished with bx as a pointer) -#if HCLICK_SHIFT < CLICK_SHIFT - shl bx,cl ! source segment -#endif - mov ds,bx - - stos ! copy process number of sender to dest message - add si,*2 ! do not copy first word - mov cx,*Msize-1 ! remember, first word does not count - rep ! iterate cx times to copy 11 words - movs ! copy the message - pop di ! restore di - pop si ! restore si - pop ds ! restore ds - pop es ! restore es - ret ! that is all folks! - - -!*===========================================================================* -!* exit * -!*===========================================================================* -! PUBLIC void exit(); -! Some library routines use exit, so provide a dummy version. -! Actual calls to exit cannot occur in the kernel. -! Same for .fat & .trp. - -_exit: -__exit: -___exit: -.fat: -.trp: - sti - jmp __exit - - -!*===========================================================================* -!* phys_insw * -!*===========================================================================* -! PUBLIC void phys_insw(Port_t port, phys_bytes buf, size_t count); -! Input an array from an I/O port. Absolute address version of insw(). - -_phys_insw: - call portio_intro - mov es, bx ! destination segment - mov di, ax ! destination offset - shr cx, #1 ! word count - rep ins ! input many words - jmp portio_return - -portio_intro: - pop ax ! hold return address - push bp ! create stack frame - mov bp, sp - push si - push di - push ax ! retore return address - mov dx, 4(bp) ! port to do I/O - mov ax, 6(bp) ! source/destination address in bx:ax - mov bx, 8(bp) - mov cx, 10(bp) ! count in bytes - cld ! direction is UP -portio_setup: - push cx ! segment/offset setup - movb ch, bl - mov bx, ax - and ax, #0x000F ! ax = offset = address % HCLICK_SIZE - movb cl, #4 - shr bx, cl - shlb ch, cl - orb bh, ch ! bx = segment = address / HCLICK_SIZE - pop cx - ret - -portio_return: - mov ax, ss ! restore segment registers - mov ds, ax - mov es, ax - pop di ! unwind stack frame - pop si - pop bp - ret - - -!*===========================================================================* -!* phys_insb * -!*===========================================================================* -! PUBLIC void phys_insb(Port_t port, phys_bytes buf, size_t count); -! Input an array from an I/O port. Absolute address version of insb(). -! Note: The 8086 doesn't have string I/O instructions, so a loop is used. - -_phys_insb: - call portio_intro - mov es, bx ! destination segment - mov di, ax ! destination offset - jcxz 1f -0: inb dx ! input 1 byte - stosb ! write 1 byte - loop 0b ! many times -1: - jmp portio_return - - -!*===========================================================================* -!* phys_outsw * -!*===========================================================================* -! PUBLIC void phys_outsw(Port_t port, phys_bytes buf, size_t count); -! Output an array to an I/O port. Absolute address version of outsw(). - -_phys_outsw: - call portio_intro - mov ds, bx ! source segment - mov si, ax ! source offset - shr cx, #1 ! word count - rep outs ! output many words - jmp portio_return - - -!*===========================================================================* -!* phys_outsb * -!*===========================================================================* -! PUBLIC void phys_outsb(Port_t port, phys_bytes buf, size_t count); -! Output an array to an I/O port. Absolute address version of outsb(). - -_phys_outsb: - call portio_intro - mov ds, bx ! source segment - mov si, ax ! source offset - jcxz 1f -0: lodsb ! read 1 byte - outb dx ! output 1 byte - loop 0b ! many times -1: - jmp portio_return - - -!*==========================================================================* -!* enable_irq * -!*==========================================================================*/ -! PUBLIC void enable_irq(irq_hook_t *hook) -! Enable an interrupt request line by clearing an 8259 bit. -! Equivalent code for irq < 8: -! if ((irq_actids[hook->irq] &= ~hook->id) == 0) -! outb(INT_CTLMASK, inb(INT_CTLMASK) & ~(1 << irq)); - -_enable_irq: - push bp - mov bp, sp - pushf - cli - mov bx, 4(bp) ! hook - mov cx, 4(bx) ! irq - mov ax, 6(bx) ! id bit - not ax - mov bx, cx - add bx, bx - and _irq_actids(bx), ax ! clear this id bit - jnz en_done ! still masked by other handlers? - movb ah, #~1 - rolb ah, cl ! ah = ~(1 << (irq % 8)) - mov dx, #INT_CTLMASK ! enable irq < 8 at the master 8259 - cmpb cl, #8 - jb 0f - mov dx, #INT2_CTLMASK ! enable irq >= 8 at the slave 8259 -0: inb dx - andb al, ah - outb dx ! clear bit at the 8259 -en_done:popf - leave - ret - - -!*==========================================================================* -!* disable_irq * -!*==========================================================================*/ -! PUBLIC int disable_irq(irq_hook_t *hook) -! Disable an interrupt request line by setting an 8259 bit. -! Equivalent code for irq < 8: -! irq_actids[hook->irq] |= hook->id; -! outb(INT_CTLMASK, inb(INT_CTLMASK) | (1 << irq)); -! Returns true iff the interrupt was not already disabled. - -_disable_irq: - push bp - mov bp, sp - pushf - cli - mov bx, 4(bp) ! hook - mov cx, 4(bx) ! irq - mov ax, 6(bx) ! id bit - pushf - cli - mov bx, cx - add bx, bx - or _irq_actids(bx), ax ! set this id bit - movb ah, #1 - rolb ah, cl ! ah = (1 << (irq % 8)) - mov dx, #INT_CTLMASK ! disable irq < 8 at the master 8259 - cmpb cl, #8 - jb 0f - mov dx, #INT2_CTLMASK ! disable irq >= 8 at the slave 8259 -0: inb dx - testb al, ah - jnz dis_already ! already disabled? - orb al, ah - outb dx ! set bit at the 8259 - mov ax, #1 ! disabled by this function - popf - leave - ret -dis_already: - xor ax, ax ! already disabled - popf - leave - ret - - -!*===========================================================================* -!* phys_copy * -!*===========================================================================* -! PUBLIC void phys_copy(phys_bytes source, phys_bytes destination, -! phys_bytes bytecount); -! Copy a block of physical memory. - -SRCLO = 4 -SRCHI = 6 -DESTLO = 8 -DESTHI = 10 -COUNTLO = 12 -COUNTHI = 14 - -_phys_copy: - push bp ! save only registers required by C - mov bp,sp ! set bp to point to source arg less 4 - - push si ! save si - push di ! save di - push ds ! save ds - push es ! save es - - mov ax,SRCLO(bp) ! dx:ax = source address (dx is NOT segment) - mov dx,SRCHI(bp) - mov si,ax ! si = source offset = address % 16 - and si,#OFF_MASK - andb dl,#HCHIGH_MASK ! ds = source segment = address / 16 % 0x10000 - andb al,#HCLOW_MASK - orb al,dl ! now bottom 4 bits of dx are in ax - movb cl,#HCLICK_SHIFT ! rotate them to the top 4 - ror ax,cl - mov ds,ax - - mov ax,DESTLO(bp) ! dx:ax = destination addr (dx is NOT segment) - mov dx,DESTHI(bp) - mov di,ax ! di = dest offset = address % 16 - and di,#OFF_MASK - andb dl,#HCHIGH_MASK ! es = dest segment = address / 16 % 0x10000 - andb al,#HCLOW_MASK - orb al,dl - ror ax,cl - mov es,ax - - mov ax,COUNTLO(bp) ! dx:ax = remaining count - mov dx,COUNTHI(bp) - -! copy upwards (cannot handle overlapped copy) - -pc_loop: - mov cx,ax ! provisional count for this iteration - test ax,ax ! if count >= 0x8000, only do 0x8000 per iter - js pc_bigcount ! low byte already >= 0x8000 - test dx,dx - jz pc_upcount ! less than 0x8000 -pc_bigcount: - mov cx,#0x8000 ! use maximum count per iteration -pc_upcount: - sub ax,cx ! update count - sbb dx,#0 ! cannot underflow, so carry clear now for rcr - rcr cx,#1 ! count in words, carry remembers if byte - jnb pc_even ! no odd byte - movb ! copy odd byte -pc_even: - rep ! copy 1 word at a time - movs ! word copy - - mov cx,ax ! test if remaining count is 0 - or cx,dx - jnz pc_more ! more to do - - pop es ! restore es - pop ds ! restore ds - pop di ! restore di - pop si ! restore si - pop bp ! restore bp - ret ! return to caller - -pc_more: - sub si,#0x8000 ! adjust pointers so the offset does not - mov cx,ds ! overflow in the next 0x8000 bytes - add cx,#0x800 ! pointers end up same physical location - mov ds,cx ! the current offsets are known >= 0x8000 - sub di,#0x8000 ! since we just copied that many - mov cx,es - add cx,#0x800 - mov es,cx - jmp pc_loop ! start next iteration - - -!*===========================================================================* -!* mem_rdw * -!*===========================================================================* -! PUBLIC u16_t mem_rdw(u16_t segment, u16_t *offset); -! Load and return the word at the far pointer segment:offset. - -_mem_rdw: - mov cx,ds ! save ds - pop dx ! return adr - pop ds ! segment - pop bx ! offset - sub sp,#2+2 ! adjust for parameters popped - mov ax,(bx) ! load the word to return - mov ds,cx ! restore ds - jmp (dx) ! return - - -!*===========================================================================* -!* reset * -!*===========================================================================* -! PUBLIC void reset(); -! Reset the system. -! In real mode we simply jump to the reset address at F000:FFF0. - -_reset: - jmpf 0xFFF0,0xF000 - - -!*===========================================================================* -!* mem_vid_copy * -!*===========================================================================* -! PUBLIC void mem_vid_copy(u16 *src, unsigned dst, unsigned count); -! -! Copy count characters from kernel memory to video memory. Src is an ordinary -! pointer to a word, but dst and count are character (word) based video offset -! and count. If src is null then screen memory is blanked by filling it with -! blank_color. - -_mem_vid_copy: - push bp - mov bp, sp - push si - push di - push es - mov si, 4(bp) ! source - mov di, 6(bp) ! destination - mov dx, 8(bp) ! count - mov es, _vid_seg ! segment containing video memory - cld ! make sure direction is up -mvc_loop: - and di, _vid_mask ! wrap address - mov cx, dx ! one chunk to copy - mov ax, _vid_size - sub ax, di - cmp cx, ax - jbe 0f - mov cx, ax ! cx = min(cx, vid_size - di) -0: sub dx, cx ! count -= cx - shl di, #1 ! byte address - add di, _vid_off ! in video memory - test si, si ! source == 0 means blank the screen - jz mvc_blank -mvc_copy: - rep ! copy words to video memory - movs - jmp mvc_test -mvc_blank: - mov ax, _blank_color ! ax = blanking character - rep - stos ! copy blanks to video memory - !jmp mvc_test -mvc_test: - sub di, _vid_off - shr di, #1 ! back to a word address - test dx, dx - jnz mvc_loop -mvc_done: - pop es - pop di - pop si - pop bp - ret - - -!*===========================================================================* -!* vid_vid_copy * -!*===========================================================================* -! PUBLIC void vid_vid_copy(unsigned src, unsigned dst, unsigned count); -! -! Copy count characters from video memory to video memory. Handle overlap. -! Used for scrolling, line or character insertion and deletion. Src, dst -! and count are character (word) based video offsets and counts. - -_vid_vid_copy: - push bp - mov bp, sp - push si - push di - push es - mov si, 4(bp) ! source - mov di, 6(bp) ! destination - mov dx, 8(bp) ! count - mov es, _vid_seg ! segment containing video memory - cmp si, di ! copy up or down? - jb vvc_down -vvc_up: - cld ! direction is up -vvc_uploop: - and si, _vid_mask ! wrap addresses - and di, _vid_mask - mov cx, dx ! one chunk to copy - mov ax, _vid_size - sub ax, si - cmp cx, ax - jbe 0f - mov cx, ax ! cx = min(cx, vid_size - si) -0: mov ax, _vid_size - sub ax, di - cmp cx, ax - jbe 0f - mov cx, ax ! cx = min(cx, vid_size - di) -0: sub dx, cx ! count -= cx - call vvc_copy - test dx, dx - jnz vvc_uploop ! again? - jmp vvc_done -vvc_down: - std ! direction is down - add si, dx ! start copying at the top - dec si - add di, dx - dec di -vvc_downloop: - and si, _vid_mask ! wrap addresses - and di, _vid_mask - mov cx, dx ! one chunk to copy - lea ax, 1(si) - cmp cx, ax - jbe 0f - mov cx, ax ! cx = min(cx, si + 1) -0: lea ax, 1(di) - cmp cx, ax - jbe 0f - mov cx, ax ! cx = min(cx, di + 1) -0: sub dx, cx ! count -= cx - call vvc_copy - test dx, dx - jnz vvc_downloop ! again? - cld ! C compiler expect up - !jmp vvc_done -vvc_done: - pop es - pop di - pop si - pop bp - ret - -! Copy video words. (Inner code of both the up and downcopying loop.) -vvc_copy: - shl si, #1 - shl di, #1 ! byte addresses - add si, _vid_off - add di, _vid_off ! in video memory - push ds ! must set ds here, 8086 can't do - mov ds, _vid_seg ! 'rep eseg movs' with interrupts on - rep - movs ! copy video words - pop ds - sub si, _vid_off - sub di, _vid_off - shr si, #1 - shr di, #1 ! back to word addresses - ret - - -!*===========================================================================* -!* level0 * -!*===========================================================================* -! PUBLIC void level0(void (*func)(void)) -! Not very interesting in real mode, see p_level0. -! -_level0: - mov bx, sp - jmp @2(bx) - - -!*===========================================================================* -!* klib_init_prot * -!*===========================================================================* -! PUBLIC void klib_init_prot(); -! Initialize klib for protected mode by patching some real mode functions -! at their starts to jump to their protected mode equivalents, according to -! the patch table. Saves a lot of tests on the "protected_mode" variable. -! Note that this function must be run in real mode, for it writes the code -! segment. (One otherwise has to set up a descriptor, etc, etc.) - -klib_init_prot: - mov si,#patch_table -kip_next: - lods ! original function - mov bx,ax - cseg movb (bx),#JMP_OPCODE ! overwrite start of function by a long jump - lods ! new function - target of jump - sub ax,bx ! relative jump - sub ax,#3 ! adjust by length of jump instruction - cseg mov 1(bx),ax ! set address - cmp si,#end_patch_table ! end of table? - jb kip_next -kip_done: - ret - - -!*===========================================================================* -!* variants for protected mode * -!*===========================================================================* -! Some routines are different in protected mode. -! The only essential difference is the handling of segment registers. -! One complication is that the method of building segment descriptors is not -! reentrant, so the protected mode versions must not be called by interrupt -! handlers. - - -!*===========================================================================* -!* p_cp_mess * -!*===========================================================================* -! The real mode version attempts to be efficient by passing raw segments but -! that just gets in the way here. - -p_cp_mess: - mov bx, sp ! bx -> arguments - push si - push di - push ds - push es - - mov ax, 4(bx) ! Compute source descriptor base - mov dx, ax - shl ax, #CLICK_SHIFT - shr dx, #16-CLICK_SHIFT ! dx:ax = src_clicks * CLICK_SIZE - add ax, 6(bx) - adc dx, #0 ! dx:ax += src_offset - mov _gdt+DS_286_OFFSET+DESC_BASE, ax - movb _gdt+DS_286_OFFSET+DESC_BASE_MIDDLE, dl - movb _gdt+DS_286_OFFSET+DESC_BASE_HIGH, dh - - mov ax, 8(bx) ! Compute destination descriptor base - mov dx, ax - shl ax, #CLICK_SHIFT - shr dx, #16-CLICK_SHIFT ! dx:ax = dst_clicks * CLICK_SIZE - add ax, 10(bx) - adc dx, #0 ! dx:ax += dst_offset - mov _gdt+ES_286_OFFSET+DESC_BASE, ax - movb _gdt+ES_286_OFFSET+DESC_BASE_MIDDLE, dl - movb _gdt+ES_286_OFFSET+DESC_BASE_HIGH, dh - - mov bx, 2(bx) ! proc no - mov ax, #DS_286_SELECTOR - mov ds, ax - mov ax, #ES_286_SELECTOR - mov es, ax - - eseg mov 0, bx ! proc no. of sender from arg, not msg - mov si, #2 ! src offset is now 2 relative to start of seg - mov di, si ! and destination offset - mov cx, #Msize-1 ! word count - cld ! direction is up - rep - movs ! copy message (except first word) - - pop es - pop ds - pop di - pop si - ret - - -!*===========================================================================* -!* p_portio_setup * -!*===========================================================================* -! The phys_insw, phys_outsw, etc. functions need an address setup routine that -! uses a segment descriptor. -p_portio_setup: - mov _gdt+DS_286_OFFSET+DESC_BASE, ax - movb _gdt+DS_286_OFFSET+DESC_BASE_MIDDLE, bl - movb _gdt+DS_286_OFFSET+DESC_BASE_HIGH, bh - xor ax, ax ! ax = 0 = start of segment - mov bx, #DS_286_SELECTOR ! bx = segment selector - ret - - -!*===========================================================================* -!* p_phys_copy * -!*===========================================================================* -p_phys_copy: - cld - pop dx - pop _gdt+DS_286_OFFSET+DESC_BASE - pop ax ! pop source into base of source descriptor - movb _gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,al - movb _gdt+DS_286_OFFSET+DESC_BASE_HIGH,ah - pop _gdt+ES_286_OFFSET+DESC_BASE - pop ax ! pop destination into base of dst descriptor - movb _gdt+ES_286_OFFSET+DESC_BASE_MIDDLE,al - movb _gdt+ES_286_OFFSET+DESC_BASE_HIGH,ah - pop cx ! byte count in bx:cx - pop bx - sub sp,#4+4+4 - - push di - push si - push es - push ds - sub si,si ! src offset is now 0 relative to start of seg - mov di,si ! and destination offset - jmp ppc_next - -! It is too much trouble to align the segment bases, so word alignment is hard. -! Avoiding the book-keeping for alignment may be good anyway. - -ppc_large: - push cx - mov cx,#0x8000 ! copy a large chunk of this many words - rep - movs - pop cx - dec bx - pop ds ! update the descriptors - addb _gdt+DS_286_OFFSET+DESC_BASE_MIDDLE,#1 - adcb _gdt+DS_286_OFFSET+DESC_BASE_HIGH,#0 - addb _gdt+ES_286_OFFSET+DESC_BASE_MIDDLE,#1 - adcb _gdt+ES_286_OFFSET+DESC_BASE_HIGH,#0 - push ds -ppc_next: - mov ax,#DS_286_SELECTOR ! (re)load the selectors - mov ds,ax - mov ax,#ES_286_SELECTOR - mov es,ax - test bx,bx - jnz ppc_large - - shr cx,#1 ! word count - rep - movs ! move any leftover words - rcl cx,#1 ! restore old bit 0 - rep - movb ! move any leftover byte - pop ds - pop es - pop si - pop di - jmp (dx) - -!*===========================================================================* -!* p_reset * -!*===========================================================================* -! Reset the system by loading IDT with offset 0 and interrupting. - -p_reset: - lidt idt_zero - int 3 ! anything goes, the 286 will not like it - -!*===========================================================================* -!* idle_task * -!*===========================================================================* -_idle_task: -! This task is called when the system has nothing else to do. The HLT -! instruction puts the processor in a state where it draws minimum power. - mov ax, #halt - push ax - call _level0 ! level0(halt) - pop ax - jmp _idle_task -halt: - sti - hlt - cli - ret - - -!*===========================================================================* -!* p_level0 * -!*===========================================================================* -! PUBLIC void level0(void (*func)(void)) -! Call a function at permission level 0. This allows kernel tasks to do -! things that are only possible at the most privileged CPU level. -! -p_level0: - mov bx, sp - mov ax, 2(bx) - mov _level0_func, ax - int LEVEL0_VECTOR - ret - - -!*===========================================================================* -!* data * -!*===========================================================================* - .data -patch_table: ! pairs (old function, new function) - .data2 _int86, p_int86 - .data2 _cp_mess, p_cp_mess - .data2 _phys_copy, p_phys_copy - .data2 portio_setup, p_portio_setup - .data2 _reset, p_reset - .data2 _level0, p_level0 - .data2 _restart, p_restart ! in mpx file - .data2 save, p_save ! in mpx file -end_patch_table: ! end of table - -idt_vectors: ! limit and base of real mode interrupt vectors - .data2 0x3FF -idt_zero: ! zero limit IDT to cause a processor shutdown - .data2 0, 0, 0 - - .bss -save_sp: ! place to put sp when switching to real mode - .space 2 -msw: ! saved real mode machine status word - .space 2 diff --git a/kernel/main.c b/kernel/main.c index 66c182a26..ed8de0e2a 100755 --- a/kernel/main.c +++ b/kernel/main.c @@ -14,7 +14,6 @@ * Changes: * Nov 24, 2004 simplified main() with system image (Jorrit N. Herder) * Oct 21, 2004 moved copyright to announce() (Jorrit N. Herder) - * Sep 30, 2004 moved mem_init() to this file (Jorrit N. Herder) * Sep 04, 2004 created stop_sequence() to cleanup (Jorrit N. Herder) * Aug 20, 2004 split wreboot() and shutdown() (Jorrit N. Herder) * Jun 15, 2004 moved wreboot() to this file (Jorrit N. Herder) @@ -42,8 +41,8 @@ PUBLIC void main() register struct proc *rp; register int i; int hdrindex; /* index to array of a.out headers */ - phys_clicks text_base; - vir_clicks text_clicks; + phys_clicks text_base, bootdev_base; + vir_clicks text_clicks, bootdev_clicks; vir_clicks data_clicks; reg_t ktsb; /* kernel task stack base */ struct memory *memp; @@ -53,9 +52,6 @@ PUBLIC void main() /* Initialize the interrupt controller. */ intr_init(1); - /* Make free memory list from memory sizes passed by boot monitor. */ - mem_init(); - /* Clear the process table. Anounce each slot as empty and * set up mappings for proc_addr() and proc_number() macros. */ @@ -90,7 +86,7 @@ PUBLIC void main() } ktsb += ttp->stksize; /* point to high end of stack */ rp->p_reg.sp = ktsb; /* this task's initial stack ptr */ - text_base = code_base >> CLICK_SHIFT; + text_base = kinfo.code_base >> CLICK_SHIFT; /* processes that are in the kernel */ hdrindex = 0; /* all use the first a.out header */ } else { @@ -150,44 +146,37 @@ PUBLIC void main() /* Code and data segments must be allocated in protected mode. */ alloc_segments(rp); } - bill_ptr = proc_addr(IDLE); /* it has to point somewhere */ - /* This actually is not needed, because ready() already set 'proc_ptr' to - * first task that was announced ready. - */ - lock_pick_proc(); - - /* Expect an image of the root FS to be loaded into memory as well. The - * root FS image is located directly after the programs. +#if ENABLE_BOOTDEV + /* Expect an image of the boot device to be loaded into memory as well. + * The boot device is the last module that is loaded into memory, and, + * for example, can contain the root FS (useful for embedded systems). */ hdrindex ++; - phys_copy(aout+hdrindex * A_MINHDR, vir2phys(&e_hdr), (phys_bytes) A_MINHDR); - kprintf("Root FS image found: %s\n", (e_hdr.a_flags&A_IMG)? "yes" : "no"); + phys_copy(aout + hdrindex * A_MINHDR,vir2phys(&e_hdr),(phys_bytes) A_MINHDR); if (e_hdr.a_flags & A_IMG) { - kprintf("Size of root FS: %u, ", e_hdr.a_data); - kprintf("base : %u, ", e_hdr.a_syms); - kprintf("header size : %u, ", e_hdr.a_hdrlen); - rp = proc_addr(MEMORY); - rp->p_farmem[0].mem_phys = e_hdr.a_syms; - rp->p_farmem[0].mem_len = e_hdr.a_data; + + kinfo.bootdev_base = e_hdr.a_syms; + kinfo.bootdev_size = e_hdr.a_data; /* Remove from free list, to prevent being overwritten. */ - text_base = e_hdr.a_syms >> CLICK_SHIFT; - text_clicks = (e_hdr.a_text + CLICK_SIZE-1) >> CLICK_SHIFT; - if (!(e_hdr.a_flags & A_SEP)) text_clicks = 0; /* Common I&D */ - data_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT; + bootdev_base = e_hdr.a_syms >> CLICK_SHIFT; + bootdev_clicks = (e_hdr.a_total + CLICK_SIZE-1) >> CLICK_SHIFT; for (memp = mem; memp < &mem[NR_MEMS]; memp++) { - if (memp->base == text_base) { - kprintf("Memory removed from free list.\n", NO_ARG); - memp->base += text_clicks + data_clicks; - memp->size -= text_clicks + data_clicks; + if (memp->base == bootdev_base) { + memp->base += bootdev_clicks; + memp->size -= bootdev_clicks; } } } - +#endif - /* MINIX and all system services have been loaded. Announce to the user. - * Then go to the assembly code to start running the current process. + /* This actually is not needed, because ready() already set 'proc_ptr.' */ + lock_pick_proc(); + bill_ptr = proc_addr(IDLE); /* it has to point somewhere */ + + /* MINIX is now ready. Display the startup banner to the user and return + * to the assembly code to start running the current process. */ announce(); restart(); @@ -201,14 +190,18 @@ PUBLIC void main() PRIVATE void announce(void) { /* Display the MINIX startup banner. */ - kprintf("MINIX %s Copyright 2001 Prentice-Hall, Inc.\n", - karg(OS_RELEASE "." OS_VERSION)); + kprintf("MINIX %s. Copyright 2001 Prentice-Hall, Inc.\n", + karg(kinfo.version)); #if (CHIP == INTEL) /* Real mode, or 16/32-bit protected mode? */ kprintf("Executing in %s mode\n\n", - protected_mode ? karg("32-bit protected") : karg("real")); + machine.protected ? karg("32-bit protected") : karg("real")); #endif + + /* Check if boot device was loaded with the kernel. */ + if (kinfo.bootdev_base > 0) + kprintf("Image of /dev/boot loaded. Size: %u KB.\n", kinfo.bootdev_size); } @@ -274,7 +267,7 @@ timer_t *tp; /* See if the last process' shutdown was successfull. Else, force exit. */ if (p != NIL_PROC) { - kprintf("[%s]\n", isalivep(p) ? "FAILED" : "OK"); + kprintf("[%s]\n", isalivep(p) ? karg("FAILED") : karg("OK")); if (isalivep(p)) clear_proc(p->p_nr); /* now force process to exit */ } @@ -289,8 +282,8 @@ timer_t *tp; if (p == NIL_PROC) p = BEG_PROC_ADDR; while (TRUE) { if (isalivep(p) && p->p_type == level) { /* found a process */ - kprintf("- Stopping %s ", p->p_name); - kprintf("%s ... ", types[p->p_type]); + kprintf("- Stopping %s ", karg(p->p_name)); + kprintf("%s ... ", karg(types[p->p_type])); shutdown_process = p; /* directly continue if exited */ notify(proc_number(p), HARD_STOP); set_timer(tp, get_uptime()+STOP_TICKS, stop_sequence); @@ -336,15 +329,15 @@ timer_t *tp; * For RBT_MONITOR, the MM has provided the program. */ if (how == RBT_HALT) { - phys_copy(vir2phys(" "), mon_params, 2); + phys_copy(vir2phys("delay;"), kinfo.params_base, 7); } else if (how == RBT_REBOOT) { - phys_copy(vir2phys("delay;boot"), mon_params, 11); + phys_copy(vir2phys("delay;boot"), kinfo.params_base, 11); } level0(monitor); } /* Stop BIOS memory test. */ - phys_copy(vir2phys(&magic), (phys_bytes) ADR_MEM_CHECK, LEN_MEM_CHECK); + phys_copy(vir2phys(&magic), SOFT_RESET_FLAG_ADDR, SOFT_RESET_FLAG_SIZE); /* Reset the system by jumping to the reset address (real mode), or by * forcing a processor shutdown (protected mode). diff --git a/kernel/memory.c b/kernel/memory.c deleted file mode 100755 index e07fb7165..000000000 --- a/kernel/memory.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Entry points into this file: - * mem_init: create a list a free memory - * alloc_segments: allocate segments for 8088 or higher processor - */ - -#include "kernel.h" -#include "protect.h" -#include "proc.h" - - -#if (CHIP == INTEL) - -/* In real mode only 1M can be addressed, and in 16-bit protected we can go - * no further than we can count in clicks. (The 286 is further limited by - * its 24 bit address bus, but we can assume in that case that no more than - * 16M memory is reported by the BIOS.) - */ -#define MAX_REAL 0x00100000L -#define MAX_16BIT (0xFFF0L << CLICK_SHIFT) - -/*=========================================================================* - * mem_init * - *=========================================================================*/ -PUBLIC void mem_init() -{ -/* Initialize the free memory list from the 'memory' boot variable. Translate - * the byte offsets and sizes in this list to clicks, properly truncated. Also - * make sure that we don't exceed the maximum address space of the 286 or the - * 8086, i.e. when running in 16-bit protected mode or real mode. - */ - long base, size, limit; - char *s, *end; /* use to parse boot variable */ - int i; - struct memory *memp; -#if _WORD_SIZE == 2 - unsigned long max_address; -#endif - - /* The available memory is determined by MINIX' boot loader as a list of - * (base:size)-pairs in boothead.s. The 'memory' boot variable is set in - * in boot.s. The format is "b0:s0,b1:s1,b2:s2", where b0:s0 is low mem, - * b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1 - * and b2:s2 are combined if the memory is adjacent. - */ - s = getkenv("memory"); /* get memory boot variable */ - tot_mem_size = 0; - for (i = 0; i < NR_MEMS; i++) { - memp = &mem[i]; /* result is stored here */ - base = size = 0; - if (*s != 0) { /* end of boot variable */ - /* Expect base to be read (end != s) and ':' as next char. */ - base = kstrtoul(s, &end, 0x10); /* get number */ - if (end != s && *end == ':') s = ++end; /* skip ':' */ - else *s=0; /* fake end for next; should not happen */ - /* Expect size to be read and skip ',', unless at end. */ - size = kstrtoul(s, &end, 0x10); /* get number */ - if (end != s && *end == ',') s = ++end; /* skip ',' */ - else if (end != s && *end == 0) s = end; /* end found */ - else *s=0; /* fake end for next; should not happen */ - } - limit = base + size; -#if _WORD_SIZE == 2 - max_address = protected_mode ? MAX_16BIT : MAX_REAL; - if (limit > max_address) limit = max_address; -#endif - base = (base + CLICK_SIZE-1) & ~(long)(CLICK_SIZE-1); - limit &= ~(long)(CLICK_SIZE-1); - if (limit <= base) continue; - memp->base = base >> CLICK_SHIFT; - memp->size = (limit - base) >> CLICK_SHIFT; - tot_mem_size += memp->size; - } -} - -/*==========================================================================* - * alloc_segments * - *==========================================================================*/ -PUBLIC void alloc_segments(rp) -register struct proc *rp; -{ -/* This is called at system initialization from main() and by do_newmap(). - * The code has a separate function because of all hardware-dependencies. - * Note that IDLE is part of the kernel and gets TASK_PRIVILEGE here. - */ - phys_bytes code_bytes; - phys_bytes data_bytes; - int privilege; - - if (protected_mode) { - data_bytes = (phys_bytes) (rp->p_memmap[S].mem_vir + - rp->p_memmap[S].mem_len) << CLICK_SHIFT; - if (rp->p_memmap[T].mem_len == 0) - code_bytes = data_bytes; /* common I&D, poor protect */ - else - code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT; - privilege = (isidlep(rp) || istaskp(rp)) ? - TASK_PRIVILEGE : USER_PRIVILEGE; - init_codeseg(&rp->p_ldt[CS_LDT_INDEX], - (phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT, - code_bytes, privilege); - init_dataseg(&rp->p_ldt[DS_LDT_INDEX], - (phys_bytes) rp->p_memmap[D].mem_phys << CLICK_SHIFT, - data_bytes, privilege); - rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege; -#if _WORD_SIZE == 4 - rp->p_reg.gs = - rp->p_reg.fs = -#endif - rp->p_reg.ss = - rp->p_reg.es = - rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege; - } else { - rp->p_reg.cs = click_to_hclick(rp->p_memmap[T].mem_phys); - rp->p_reg.ss = - rp->p_reg.es = - rp->p_reg.ds = click_to_hclick(rp->p_memmap[D].mem_phys); - } -} -#endif /* (CHIP == INTEL) */ - diff --git a/kernel/mpx88.s b/kernel/mpx88.s index 8b8d6e75e..e69de29bb 100755 --- a/kernel/mpx88.s +++ b/kernel/mpx88.s @@ -1,762 +0,0 @@ -# -! This file, mpx88.s, is included by mpx.s when Minix is compiled for -! 16-bit Intel CPUs. The alternative mpx386.s is compiled for 32-bit CPUs. -! -! This file contains the assembler startup code for Minix and the 16-bit -! interrupt handlers. It cooperates with cstart.c to set up a good -! environment for main(). - -! This file is part of the lowest layer of the MINIX kernel. The other part -! is "proc.c". The lowest layer does process switching and message handling. - -! Every transition to the kernel goes through this file. Transitions are -! caused by sending/receiving messages and by most interrupts. (RS232 -! interrupts may be handled in the file "rs2.s" and then they rarely enter -! the kernel.) - -! Transitions to the kernel may be nested. The initial entry may be with a -! system call, exception or hardware interrupt; reentries may only be made -! by hardware interrupts. The count of reentries is kept in "k_reenter". -! It is important for deciding whether to switch to the kernel stack and -! for protecting the message passing code in "proc.c". - -! For the message passing trap, most of the machine state is saved in the -! proc table. (Some of the registers need not be saved.) Then the stack is -! switched to "k_stack", and interrupts are reenabled. Finally, the system -! call handler (in C) is called. When it returns, interrupts are disabled -! again and the code falls into the restart routine, to finish off held-up -! interrupts and run the process or task whose pointer is in "proc_ptr". - -! Hardware interrupt handlers do the same, except (1) The entire state must -! be saved. (2) There are too many handlers to do this inline, so the save -! routine is called. A few cycles are saved by pushing the address of the -! appropiate restart routine for a return later. (3) A stack switch is -! avoided when the stack is already switched. (4) The (master) 8259 interrupt -! controller is reenabled centrally in save(). (5) Each interrupt handler -! masks its interrupt line using the 8259 before enabling (other unmasked) -! interrupts, and unmasks it after servicing the interrupt. This limits the -! nest level to the number of lines and protects the handler from itself. - -! For communication with the boot monitor at startup time some constant -! data are compiled into the beginning of the text segment. This facilitates -! reading the data at the start of the boot process, since only the first -! sector of the file needs to be read. - -! Some data storage is also allocated at the end of this file. This data -! will be at the start of the data segment of the kernel and will be read -! and modified by the boot monitor before the kernel starts. - -#include -#include -#include -#include "const.h" -#include "sconst.h" -#include "protect.h" - -! The external entry points into this file are: -! Note: in assembly language the .define statement applied to a function name -! is loosely equivalent to a prototype in C code -- it makes it possible to -! link to an entity declared in the assembly code but does not create -! the entity. - -.define _int00 ! handlers for traps and exceptions -.define _int01 -.define _int02 -.define _int03 -.define _int04 -.define _int05 -.define _int06 -.define _int07 -.define _hwint00 ! handlers for hardware interrupts -.define _hwint01 -.define _hwint02 -.define _hwint03 -.define _hwint04 -.define _hwint05 -.define _hwint06 -.define _hwint07 -.define _hwint08 -.define _hwint09 -.define _hwint10 -.define _hwint11 -.define _hwint12 -.define _hwint13 -.define _hwint14 -.define _hwint15 -.define _restart ! start running a task or process -.define save ! save the machine state in the proc table -.define _s_call ! process or task wants to send or receive a message - -! Exported variables. -.define kernel_ds -.define begbss -.define begdata - - .text -!*===========================================================================* -!* MINIX * -!*===========================================================================* -MINIX: ! this is the entry point for the MINIX kernel - jmp over_kernel_ds ! skip over the next few bytes - .data2 CLICK_SHIFT ! for the monitor: memory granularity -kernel_ds: - .data2 0x01B4 ! boot monitor flags: (later kernel DS) - ! call in 8086 mode, make bss, make stack, - ! load low, don`t patch, will return, - ! (has own INT calls), memory vector, - ! new boot code return -over_kernel_ds: - -! Set up a C stack frame on the monitor stack. (The monitor sets cs and ds -! right. The ss register still references the monitor data segment.) - push bp - mov bp, sp - push si - push di - cmp 4(bp), #0 ! monitor code segment is - jz noret ! nonzero if return possible - inc _mon_return -noret: mov _mon_ss, ss ! save stack location for later return - mov _mon_sp, sp - -! Locate boot parameters, set up kernel segment registers and stack. - mov bx, 6(bp) ! boot parameters offset - mov dx, 8(bp) ! boot parameters length - mov ax, 10(bp) ! address of a.out headers - mov _aout+0, ax - mov ax, 12(bp) - mov _aout+2, ax - mov ax, ds ! kernel data - mov es, ax - mov ss, ax - mov sp, #k_stktop ! set sp to point to the top of kernel stack - -! Real mode needs to get kernel DS from the code segment. Protected mode -! needs CS in the jump back to real mode. - - cseg mov kernel_cs, cs - cseg mov kernel_ds, ds - -! Call C startup code to set up a proper environment to run main(). - push dx - push bx - push _mon_ss - push ds - push cs - call _cstart ! cstart(cs, ds, mds, parmoff, parmlen) - add sp, #5*2 - - cmp _protected_mode, #0 - jz nosw ! ok to switch to protected mode? - - call klib_init_prot ! initialize klib functions for protected mode - call real2prot ! switch to protected mode - - push #0 ! set flags to known good state - popf ! especially, clear nested task and int enable -nosw: - jmp _main ! main() - - -!*===========================================================================* -!* interrupt handlers * -!*===========================================================================* - - -!*===========================================================================* -!* hwint00 - 07 * -!*===========================================================================* -! Note that the first few lines are a macro -#define hwint_master(irq) \ - call save /* save interrupted process state */;\ - mov si, *[2*irq] /* load array index offset */;\ - mov di, *[1< +#include "protect.h" #include "const.h" struct proc { @@ -21,8 +22,7 @@ struct proc { #if (CHIP == INTEL) reg_t p_ldt_sel; /* selector in gdt giving ldt base and limit*/ - struct segdesc_s p_ldt[4]; /* local descriptors for code and data */ - /* 4 is LDT_SIZE - avoid include protect.h */ + struct segdesc_s p_ldt[2+NR_REMOTE_SEGS]; /* CS, DS and remote segments */ #endif /* (CHIP == INTEL) */ #if (CHIP == M68000) @@ -123,7 +123,7 @@ struct proc { #define isalivep(p) ((p)->p_type > P_NONE) #define isrxhardware(n) ((n) == ANY || (n) == HARDWARE) #define iskernel(n) ((n) == CLOCK || (n) == SYSTASK) -#define issysentn(n) ((n) == FS_PROC_NR || (n) == MM_PROC_NR) +#define issysentn(n) ((n) == FS_PROC_NR || (n) == PM_PROC_NR) #define issysentp(p) (issysentn((p)->p_nr)) #define isreservedp(p) ((p)->p_type == P_RESERVED) #define isemptyp(p) ((p)->p_type == P_NONE) diff --git a/kernel/protect.c b/kernel/protect.c index 7057ac91e..c6e327980 100755 --- a/kernel/protect.c +++ b/kernel/protect.c @@ -82,10 +82,6 @@ PUBLIC void prot_init() /* Set up tables for protected mode. * All GDT slots are allocated at compile time. */ - - extern int etext, end; -#define code_bytes ((vir_bytes) &etext) /* Size of code segment. */ -#define data_bytes ((vir_bytes) &end) /* Size of data segment. */ struct gate_table_s *gtp; struct desctableptr_s *dtp; unsigned ldt_index; @@ -149,8 +145,8 @@ PUBLIC void prot_init() * (u32_t *) dtp->base = vir2phys(idt); /* Build segment descriptors for tasks and interrupt handlers. */ - init_codeseg(&gdt[CS_INDEX], code_base, code_bytes, INTR_PRIVILEGE); - init_dataseg(&gdt[DS_INDEX], data_base, data_bytes, INTR_PRIVILEGE); + init_codeseg(&gdt[CS_INDEX], kinfo.code_base, kinfo.code_size, INTR_PRIVILEGE); + init_dataseg(&gdt[DS_INDEX], kinfo.data_base, kinfo.data_size, INTR_PRIVILEGE); init_dataseg(&gdt[ES_INDEX], 0L, 0, TASK_PRIVILEGE); /* Build scratch descriptors for functions in klib88. */ @@ -268,7 +264,7 @@ U16_t seg; phys_bytes base; struct segdesc_s *segdp; - if (!protected_mode) { + if (! machine.protected) { base = hclick_to_physb(seg); } else { segdp = &gdt[seg >> 3]; @@ -292,7 +288,7 @@ phys_bytes phys; * address, for use by a driver doing memory I/O in the A0000 - DFFFF range. */ #if _WORD_SIZE == 2 - if (!protected_mode) { + if (! machine.protected) { *seg = phys / HCLICK_SIZE; *off = phys % HCLICK_SIZE; } else { @@ -342,3 +338,51 @@ struct proc *pp; */ pp->p_reg.psw |= 0x3000; } + + +/*==========================================================================* + * alloc_segments * + *==========================================================================*/ +PUBLIC void alloc_segments(rp) +register struct proc *rp; +{ +/* This is called at system initialization from main() and by do_newmap(). + * The code has a separate function because of all hardware-dependencies. + * Note that IDLE is part of the kernel and gets TASK_PRIVILEGE here. + */ + phys_bytes code_bytes; + phys_bytes data_bytes; + int privilege; + + if (machine.protected) { + data_bytes = (phys_bytes) (rp->p_memmap[S].mem_vir + + rp->p_memmap[S].mem_len) << CLICK_SHIFT; + if (rp->p_memmap[T].mem_len == 0) + code_bytes = data_bytes; /* common I&D, poor protect */ + else + code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT; + privilege = (isidlep(rp) || istaskp(rp)) ? + TASK_PRIVILEGE : USER_PRIVILEGE; + init_codeseg(&rp->p_ldt[CS_LDT_INDEX], + (phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT, + code_bytes, privilege); + init_dataseg(&rp->p_ldt[DS_LDT_INDEX], + (phys_bytes) rp->p_memmap[D].mem_phys << CLICK_SHIFT, + data_bytes, privilege); + rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege; +#if _WORD_SIZE == 4 + rp->p_reg.gs = + rp->p_reg.fs = +#endif + rp->p_reg.ss = + rp->p_reg.es = + rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege; + } else { + rp->p_reg.cs = click_to_hclick(rp->p_memmap[T].mem_phys); + rp->p_reg.ss = + rp->p_reg.es = + rp->p_reg.ds = click_to_hclick(rp->p_memmap[D].mem_phys); + } +} + + diff --git a/kernel/protect.h b/kernel/protect.h index 14b3fef7c..6ccfb05f2 100755 --- a/kernel/protect.h +++ b/kernel/protect.h @@ -4,7 +4,7 @@ #define GDT_SIZE (FIRST_LDT_INDEX + NR_TASKS + NR_PROCS) /* spec. and LDT's */ #define IDT_SIZE (IRQ8_VECTOR + 8) /* only up to the highest vector */ -#define LDT_SIZE 4 /* contains CS, DS and two extras */ +#define LDT_SIZE (2 + NR_REMOTE_SEGS) /* CS, DS and remote segments */ /* Fixed global descriptors. 1 to 7 are prescribed by the BIOS. */ #define GDT_INDEX 1 /* GDT descriptor */ diff --git a/kernel/proto.h b/kernel/proto.h index 99c095b95..99bab5465 100755 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -46,10 +46,6 @@ _PROTOTYPE( void prepare_shutdown, (int how) ); _PROTOTYPE( void stop_sequence, (struct timer *tp) ); _PROTOTYPE( void shutdown, (struct timer *tp) ); -/* memory.c */ -_PROTOTYPE( void mem_init, (void) ); -_PROTOTYPE( void alloc_segments, (struct proc *rp) ); - /* misc.c */ _PROTOTYPE( void panic, (_CONST char *s, int n) ); @@ -145,6 +141,7 @@ _PROTOTYPE( void phys_outsw, (Port_t port, phys_bytes buf, size_t count)); _PROTOTYPE( void reset, (void) ); _PROTOTYPE( void level0, (void (*func)(void)) ); _PROTOTYPE( void monitor, (void) ); +_PROTOTYPE( void read_tsc, (unsigned long *low, unsigned long *high) ); /* mpx*.s */ _PROTOTYPE( void idle_task, (void) ); @@ -202,6 +199,7 @@ _PROTOTYPE( void init_dataseg, (struct segdesc_s *segdp, phys_bytes base, _PROTOTYPE( phys_bytes seg2phys, (U16_t seg) ); _PROTOTYPE( void phys2seg, (u16_t *seg, vir_bytes *off, phys_bytes phys)); _PROTOTYPE( void enable_iop, (struct proc *pp) ); +_PROTOTYPE( void alloc_segments, (struct proc *rp) ); #endif /* (CHIP == INTEL) */ diff --git a/kernel/sendmask.h b/kernel/sendmask.h index 6d6f2ed29..252ec73de 100644 --- a/kernel/sendmask.h +++ b/kernel/sendmask.h @@ -88,7 +88,7 @@ allow_all_mask \ deny(1, USER_PROC_NR) -#define MM_SENDMASK \ +#define PM_SENDMASK \ deny_all_mask \ allow(1, IS_PROC_NR) /* output diagnostics */ \ allow(1, SYSTASK) \ @@ -120,7 +120,7 @@ allow((NR_CTRLRS >= 3), CTRLR(2)) \ allow((NR_CTRLRS >= 4), CTRLR(3)) \ allow(1, INIT_PROC_NR) \ - allow(1, MM_PROC_NR) /* cooperates with memory manager */ \ + allow(1, PM_PROC_NR) /* cooperates with process manager */ \ allow(1, USER_PROC_NR) /* reply to system calls */ #endif @@ -154,12 +154,12 @@ #define INIT_SENDMASK \ deny_all_mask \ allow(1, FS_PROC_NR) /* init makes system calls to FS and MM */ \ - allow(1, MM_PROC_NR) + allow(1, PM_PROC_NR) #define USER_PROC_SENDMASK \ deny_all_mask \ allow(1, FS_PROC_NR) /* users can only make system calls */ \ - allow(1, MM_PROC_NR) \ + allow(1, PM_PROC_NR) \ allow(1, IS_PROC_NR) \ allow(ENABLE_TASKSERVER, TS_PROC_NR) diff --git a/kernel/start.c b/kernel/start.c index 249d957ba..bfc2ff83e 100755 --- a/kernel/start.c +++ b/kernel/start.c @@ -11,10 +11,12 @@ #include "kernel.h" #include "protect.h" +#include "proc.h" /* Environment strings passed by loader. */ PRIVATE char k_environ[128*sizeof(char *)]; +FORWARD _PROTOTYPE( void mem_init, (void) ); /*==========================================================================* * cstart * @@ -29,46 +31,127 @@ U16_t parmoff, parmsize; /* boot parameters offset and length */ */ register char *envp; unsigned mon_start; + extern int etext, end; + + /* Decide if mode is protected; 386 or higher implies protected mode. + * This must be done first, because it is needed for, e.g., seg2phys(). + * For 286 machines we cannot decide on protected mode, yet. This is + * done below. + */ +#if _WORD_SIZE != 2 + machine.protected = 1; +#endif /* Record where the kernel and the monitor are. */ - code_base = seg2phys(cs); - data_base = seg2phys(ds); + kinfo.code_base = seg2phys(cs); + kinfo.code_size = (phys_bytes) &etext; /* size of code segment */ + kinfo.data_base = seg2phys(ds); + kinfo.data_size = (phys_bytes) &end; /* size of data segment */ /* Initialize protected mode descriptors. */ prot_init(); /* Copy the boot parameters to kernel memory. */ - mon_params = seg2phys(mds) + parmoff; - mon_parmsize = MAX(parmsize,sizeof(k_environ)); - if (parmsize > sizeof k_environ - 2) parmsize = sizeof k_environ - 2; - phys_copy(mon_params, vir2phys(k_environ), (phys_bytes) parmsize); + kinfo.params_base = seg2phys(mds) + parmoff; + kinfo.params_size = MAX(parmsize,sizeof(k_environ)-2); + phys_copy(kinfo.params_base, vir2phys(k_environ), kinfo.params_size); - /* Type of VDU: */ - envp = getkenv("video"); - if (kstrcmp(envp, "ega") == 0) ega = TRUE; - if (kstrcmp(envp, "vga") == 0) vga = ega = TRUE; + /* Record miscellaneous information for user-space servers. */ + kstrncpy(kinfo.version, OS_RELEASE "." OS_VERSION, 6); + kinfo.proc_addr = (vir_bytes) proc; + kinfo.kmem_base = vir2phys(0); + kinfo.kmem_size = (phys_bytes) &end; /* Processor? */ - processor = katoi(getkenv("processor")); /* 86, 186, 286, 386, ... */ + machine.processor=katoi(getkenv("processor")); /* 86, 186, 286, 386, ... */ + + /* Decide if mode is protected for older machines. */ +#if _WORD_SIZE == 2 + machine.protected = machine.processor >= 286; +#endif + if (! machine.protected) mon_return = 0; /* XT, AT or MCA bus? */ envp = getkenv("bus"); if (envp == NIL_PTR || kstrcmp(envp, "at") == 0) { - pc_at = TRUE; - } else - if (kstrcmp(envp, "mca") == 0) { - pc_at = ps_mca = TRUE; + machine.pc_at = TRUE; /* PC-AT compatible hardware */ + } else if (kstrcmp(envp, "mca") == 0) { + machine.pc_at = machine.ps_mca = TRUE; /* PS/2 with micro channel */ } - /* Decide if mode is protected. */ + /* Type of VDU: */ + envp = getkenv("video"); /* EGA or VGA video unit */ + if (kstrcmp(envp, "ega") == 0) machine.vdu_ega = TRUE; + if (kstrcmp(envp, "vga") == 0) machine.vdu_vga = machine.vdu_ega = TRUE; + + /* Initialize free memory list from size passed by boot monitor. */ + mem_init(); + + /* Return to assembler code to switch to protected mode (if 286), + * reload selectors and call main(). + */ +} + + + +/* In real mode only 1M can be addressed, and in 16-bit protected we can go + * no further than we can count in clicks. (The 286 is further limited by + * its 24 bit address bus, but we can assume in that case that no more than + * 16M memory is reported by the BIOS.) + */ +#define MAX_REAL 0x00100000L +#define MAX_16BIT (0xFFF0L << CLICK_SHIFT) + +/*=========================================================================* + * mem_init * + *=========================================================================*/ +PRIVATE void mem_init() +{ +/* Initialize the free memory list from the 'memory' boot variable. Translate + * the byte offsets and sizes in this list to clicks, properly truncated. Also + * make sure that we don't exceed the maximum address space of the 286 or the + * 8086, i.e. when running in 16-bit protected mode or real mode. + */ + long base, size, limit; + char *s, *end; /* use to parse boot variable */ + int i; + struct memory *memp; #if _WORD_SIZE == 2 - protected_mode = processor >= 286; - if (!protected_mode) mon_return = 0; + unsigned long max_address; #endif - /* Return to assembler code to switch to protected mode (if 286), reload - * selectors and call main(). + /* The available memory is determined by MINIX' boot loader as a list of + * (base:size)-pairs in boothead.s. The 'memory' boot variable is set in + * in boot.s. The format is "b0:s0,b1:s1,b2:s2", where b0:s0 is low mem, + * b1:s1 is mem between 1M and 16M, b2:s2 is mem above 16M. Pairs b1:s1 + * and b2:s2 are combined if the memory is adjacent. */ + s = getkenv("memory"); /* get memory boot variable */ + for (i = 0; i < NR_MEMS; i++) { + memp = &mem[i]; /* result is stored here */ + base = size = 0; + if (*s != 0) { /* end of boot variable */ + /* Expect base to be read (end != s) and ':' as next char. */ + base = kstrtoul(s, &end, 0x10); /* get number */ + if (end != s && *end == ':') s = ++end; /* skip ':' */ + else *s=0; /* fake end for next; should not happen */ + /* Expect size to be read and skip ',', unless at end. */ + size = kstrtoul(s, &end, 0x10); /* get number */ + if (end != s && *end == ',') s = ++end; /* skip ',' */ + else if (end != s && *end == 0) s = end; /* end found */ + else *s=0; /* fake end for next; should not happen */ + } + limit = base + size; +#if _WORD_SIZE == 2 + max_address = kinfo.protected ? MAX_16BIT : MAX_REAL; + if (limit > max_address) limit = max_address; +#endif + base = (base + CLICK_SIZE-1) & ~(long)(CLICK_SIZE-1); + limit &= ~(long)(CLICK_SIZE-1); + if (limit <= base) continue; + memp->base = base >> CLICK_SHIFT; + memp->size = (limit - base) >> CLICK_SHIFT; + } } diff --git a/kernel/system.c b/kernel/system.c index c6e1dc856..30757d5f2 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -18,16 +18,16 @@ * umap_bios: map virtual address in BIOS_SEG to physical * numap_local: umap_local D segment from proc nr instead of pointer * virtual_copy: copy bytes from one virtual address to another - * vir_copy: copy bytes from one process to another * generic_handler: interrupt handler for user-level device drivers * * Changes: + * Apr 25, 2005 made mapping of call vector explicit (Jorrit N. Herder) * Oct 29, 2004 new clear_proc() function (Jorrit N. Herder) * Oct 17, 2004 generic handler and IRQ policies (Jorrit N. Herder) * Oct 10, 2004 dispatch system calls from call vector (Jorrit N. Herder) * Sep 30, 2004 source code documentation updated (Jorrit N. Herder) * Sep 10, 2004 system call functions in library (Jorrit N. Herder) - * 2003/2004 various new syscalls (see syslib.h) (Jorrit N. Herder) + * 2004 to 2005 various new syscalls (see syslib.h) (Jorrit N. Herder) */ #include "kernel.h" @@ -40,59 +40,24 @@ #include #include "sendmask.h" #if (CHIP == INTEL) +#include #include "protect.h" #endif +/* Declaration of the call vector that defines the mapping of system calls + * to handler functions. The vector is initialized in sys_init() with map(), + * which makes sure the system call numbers are ok. No space is allocated, + * because the dummy is declared extern. If an illegal call is given, the + * array size will be negative and this won't compile. + */ +PUBLIC int (*call_vec[NR_SYS_CALLS])(message *m_ptr); + +#define map(call_nr, handler) \ + {extern int dummy[NR_SYS_CALLS > (unsigned) (call_nr) ? 1 : -1];} \ + call_vec[(call_nr)] = (handler) + FORWARD _PROTOTYPE( void initialize, (void)); -/* Declaration of the call vector that defines the mapping of system calls to - * handler functions. The order of the do_call handler functions must match - * the SYS_CALL numbering defined in . - */ -PUBLIC _PROTOTYPE (int (*call_vec[]), (message *m_ptr) ) = { - do_times, /* 0: get uptime and process CPU time consumption */ - do_xit, /* 1: informs kernel that a process has exited */ - do_unused, /* 2: unused */ - do_sigctl, /* 3: MM signal control (incl. POSIX style handling) */ - do_fork, /* 4: informs kernel that a process has forked */ - do_newmap, /* 5: allows MM to set up a process memory map */ - do_copy, /* 6: copy a block of data between processes */ - do_exec, /* 7: sets program counter and stack pointer after EXEC */ - do_unused, /* 8: unused */ - do_abort, /* 9: MM or FS cannot go on; abort MINIX */ - do_kill, /* 10: cause a signal to be sent via MM */ - do_umap, /* 11: compute the physical address for a virtual address */ - do_unused, /* 12: returns the next free chunk of physical memory */ - do_trace, /* 13: request a trace operation */ - do_vcopy, /* 14: request a series of data blocks to be copied */ - do_signalrm, /* 15: schedule an alarm that causes an alarm signal */ - do_syncalrm, /* 16: schedule an alarm that sends a notification message */ - do_flagalrm, /* 17: schedule an alarm that sets a timeout flag to 1 */ - do_unused, /* 18: unused */ - do_svrctl, /* 19: handles miscelleneous kernel control functions */ - do_sdevio, /* 20: device I/O: phys_insb, _insw, _outsb, _outsw */ - do_unused, /* 21: unused */ - do_getinfo, /* 22: request some kind of system information */ - do_devio, /* 23: device I/O: inb, inw, inl, outb, outw, outl */ - do_vdevio, /* 24: device I/O: vector with in[b|w|l], out[b|w|l] */ - do_irqctl, /* 25: request an interrupt control operation */ - do_kmalloc, /* 26: request allocation of (DMA) buffer in mem chunk */ - do_iopenable, /* 27: allow a user process to use I/O instructions */ - do_phys2seg, /* 28: do a phys addr to segment selector/ offset conversion */ - do_exit, /* 29: an server or driver requests to be aborted */ - do_vircopy, /* 30: copy from process to process (virtual addressing) */ - do_physcopy, /* 31: copy from anywhere to anywhere (physical addressing) */ -}; - -/* Check if system call table is correct. This should not fail. No space is - * allocated here, because the dummy is declared extern. If the call vector - * is unbalanced, the array size will be negative and this won't compile. - */ -extern int dummy[sizeof(call_vec)==NR_SYS_CALLS*sizeof(call_vec[0]) ? 1 : -1]; - -/* Some system task variables. */ -PRIVATE message m; /* used to receive requests */ - /*===========================================================================* * sys_task * @@ -100,7 +65,7 @@ PRIVATE message m; /* used to receive requests */ PUBLIC void sys_task() { /* Main entry point of sys_task. Get the message and dispatch on type. */ - + static message m; register int result; /* Initialize the system task. */ @@ -145,6 +110,59 @@ PRIVATE void initialize(void) tmr_inittimer(&(rp->p_syncalrm)); tmr_inittimer(&(rp->p_flagalrm)); } + + /* Initialize the call vector to a safe default handler. Some system calls + * may be disabled or nonexistant. Then explicitely map known calls to their + * handler functions. This is done with a macro that gives a compile error + * if an illegal call number is used. The ordering is not important here. + */ + for (i=0; iirq].policy; + int proc_nr = irqtab[hook->irq].proc_nr; + +#if DEAD_CODE /* This function handles hardware interrupt in a generic way, according to * the policy set with SYS_IRQCTL. This is rather complicated since different * devices require different actions. Options are (1) do nothing, (2a) read a @@ -223,8 +249,6 @@ irq_hook_t *hook; * read, or (3) write a value to a port. Finally, the policy may or may not * reenable IRQs. A notification is sent in all cases. */ - irq_policy_t policy = irqtab[hook->irq].policy; - int proc_nr = irqtab[hook->irq].proc_nr; long port = irqtab[hook->irq].port; phys_bytes addr = irqtab[hook->irq].addr; long mask_val = irqtab[hook->irq].mask_val; @@ -270,6 +294,7 @@ irq_hook_t *hook; default: /* do nothing */ ; /* wrong type flags */ } } +#endif /* DEAD_CODE */ /* Almost done, send a HARD_INT notification to allow further processing * and possibly reenable interrupts - this depends on the policy given. @@ -290,12 +315,12 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */ * TTY wanting to cause SIGINT upon getting a DEL * CLOCK wanting to cause SIGALRM when timer expires * FS also uses this to send a signal, via the SYS_KILL message. Signals are - * handled by sending a message to MM. This central function handles the - * signals and makes sure the MM gets them by sending a notification. The - * process being signaled is blocked while MM has not finished all signals + * handled by sending a message to PM. This central function handles the + * signals and makes sure the PM gets them by sending a notification. The + * process being signaled is blocked while PM has not finished all signals * for it. These signals are counted in p_pendcount, and the SIG_PENDING * flag is kept nonzero while there are some. It is not sufficient to ready - * the process when MM is informed, because MM can block waiting for FS to + * the process when PM is informed, because PM can block waiting for FS to * do a core dump. */ register struct proc *rp, *mmp; @@ -309,7 +334,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */ return; /* another signal already pending */ if (rp->p_flags == 0) lock_unready(rp); rp->p_flags |= PENDING | SIG_PENDING; - notify(MM_PROC_NR, KSIG_PENDING); + notify(PM_PROC_NR, KSIG_PENDING); } @@ -321,12 +346,22 @@ register struct proc *rp; /* pointer to proc table entry for process */ vir_bytes vir_addr; /* virtual address in BIOS segment */ vir_bytes bytes; /* # of bytes to be copied */ { -/* Calculate the physical memory address at the BIOS. */ +/* Calculate the physical memory address at the BIOS. Note: currently, BIOS + * address zero (the first BIOS interrupt vector) is not considered, as an + * error here, but since the physical address will be zero as well, the + * calling function will think an error occurred. This is not a problem, + * since no one uses the first BIOS interrupt vector. + */ phys_bytes phys_addr; - phys_addr = (phys_bytes) vir_addr; /* no check currently! */ + /* Check all acceptable ranges. */ + if (vir_addr >= BIOS_MEM_BEGIN && vir_addr + bytes <= BIOS_MEM_END) + return (phys_bytes) vir_addr; + else if (vir_addr >= UPPER_MEM_BEGIN && vir_addr + bytes <= UPPER_MEM_END) + return (phys_bytes) vir_addr; - return phys_addr; + kprintf("Warning, error in umap_bios, virtual address 0x%x\n", vir_addr); + return 0; } /*===========================================================================* @@ -438,11 +473,16 @@ vir_bytes vir_addr; /* virtual address in bytes within the seg */ vir_bytes bytes; /* # of bytes to be copied */ { /* Calculate the physical memory address for a given virtual address. */ - phys_bytes phys_addr; + struct far_mem *fm; - phys_addr = (phys_bytes) 0; /* no yet supported currently! */ + if (bytes <= 0) return( (phys_bytes) 0); + if (seg < 0 || seg >= NR_REMOTE_SEGS) return( (phys_bytes) 0); - return phys_addr; + fm = &rp->p_farmem[seg]; + if (! fm->in_use) return( (phys_bytes) 0); + if (vir_addr + bytes > fm->mem_len) return( (phys_bytes) 0); + + return(fm->mem_phys + (phys_bytes) vir_addr); } /*==========================================================================* @@ -454,7 +494,7 @@ struct vir_addr *dst_addr; /* destination virtual address */ vir_bytes bytes; /* # of bytes to copy */ { /* Copy bytes from virtual address src_addr to virtual address dst_addr. - * Virtual addresses can be in LOCAL_SEG, REMOTE_SEG, or BIOS_SEG. + * Virtual addresses can be in ABS, LOCAL_SEG, REMOTE_SEG, or BIOS_SEG. */ struct vir_addr *vir_addr[2]; /* virtual source and destination address */ phys_bytes phys_addr[2]; /* absolute source and destination */ @@ -488,6 +528,9 @@ vir_bytes bytes; /* # of bytes to copy */ phys_addr[i] = umap_bios( proc_addr(vir_addr[i]->proc_nr), vir_addr[i]->offset, bytes ); break; + case PHYS_SEG: + phys_addr[i] = vir_addr[i]->offset; + break; default: kprintf("v_cp: Unknown segment type: %d\n", vir_addr[i]->segment & SEGMENT_TYPE); @@ -495,7 +538,7 @@ vir_bytes bytes; /* # of bytes to copy */ } /* Check if mapping succeeded. */ - if (phys_addr[i] <= 0) { + if (phys_addr[i] <= 0 && vir_addr[i]->segment != PHYS_SEG) { kprintf("v_cp: Mapping failed ... phys <= 0\n", NO_ARG); return(EFAULT); } diff --git a/kernel/system.h b/kernel/system.h index 4d1ac9ec5..9e73988de 100644 --- a/kernel/system.h +++ b/kernel/system.h @@ -19,22 +19,23 @@ _PROTOTYPE( int do_fork, (message *m_ptr) ); _PROTOTYPE( int do_newmap, (message *m_ptr) ); _PROTOTYPE( int do_xit, (message *m_ptr) ); -_PROTOTYPE( int do_vircopy, (message *m_ptr) ); /* copying */ -_PROTOTYPE( int do_physcopy, (message *m_ptr) ); +_PROTOTYPE( int do_copy, (message *m_ptr) ); /* copying */ +#define do_vircopy do_copy +#define do_physcopy do_copy +_PROTOTYPE( int do_vcopy, (message *m_ptr) ); +#define do_virvcopy do_vcopy _PROTOTYPE( int do_umap, (message *m_ptr) ); -_PROTOTYPE( int do_vcopy, (message *m_ptr) ); -_PROTOTYPE( int do_copy, (message *m_ptr) ); _PROTOTYPE( int do_unused, (message *m_ptr) ); /* miscellaneous */ _PROTOTYPE( int do_abort, (message *m_ptr) ); -_PROTOTYPE( int do_times, (message *m_ptr) ); _PROTOTYPE( int do_getinfo, (message *m_ptr) ); +_PROTOTYPE( int do_random, (message *m_ptr) ); _PROTOTYPE( int do_exit, (message *m_ptr) ); /* server control */ _PROTOTYPE( int do_svrctl, (message *m_ptr) ); _PROTOTYPE( int do_kmalloc, (message *m_ptr) ); _PROTOTYPE( int do_iopenable, (message *m_ptr) ); -_PROTOTYPE( int do_phys2seg, (message *m_ptr) ); +_PROTOTYPE( int do_segctl, (message *m_ptr) ); _PROTOTYPE( int do_devio, (message *m_ptr) ); /* device I/O */ _PROTOTYPE( int do_vdevio, (message *m_ptr) ); @@ -43,9 +44,13 @@ _PROTOTYPE( int do_sdevio, (message *m_ptr) ); _PROTOTYPE( int do_irqctl, (message *m_ptr) ); /* interrupt control */ _PROTOTYPE( int do_kill, (message *m_ptr) ); /* signal handling */ -_PROTOTYPE( int do_sigctl, (message *m_ptr) ); +_PROTOTYPE( int do_getsig, (message *m_ptr) ); +_PROTOTYPE( int do_endsig, (message *m_ptr) ); +_PROTOTYPE( int do_sigsend, (message *m_ptr) ); +_PROTOTYPE( int do_sigreturn, (message *m_ptr) ); -_PROTOTYPE( int do_setalarm, (message *m_ptr) ); /* alarm functions */ +_PROTOTYPE( int do_times, (message *m_ptr) ); /* clock functions */ +_PROTOTYPE( int do_setalarm, (message *m_ptr) ); #define do_flagalrm do_setalarm #define do_signalrm do_setalarm #define do_syncalrm do_setalarm @@ -57,6 +62,7 @@ _PROTOTYPE( int do_trace, (message *m_ptr) ); /* process tracing */ #endif #if ENABLE_K_DEBUGGING /* debugging */ +#error Kernel debugging routines are not implemented. #else #endif diff --git a/kernel/system/Makefile b/kernel/system/Makefile index dc0126d49..fe1072e3a 100644 --- a/kernel/system/Makefile +++ b/kernel/system/Makefile @@ -20,8 +20,7 @@ CFLAGS = -I$i LDFLAGS = -i SYS = alarms.o copying.o debugging.o devio.o irqctl.o proctl.o \ - srvrctl.o misc.o sigctl.o tracing.o \ - do_copy.o do_vcopy.o + sysctl.o misc.o sigctl.o tracing.o \ # What to make. all build: $(SYS) @@ -48,11 +47,8 @@ irqctl.o: $a $b misc.o: $a $b $i/unistd.h proctl.o: $a $b $k/sendmask.h $k/protect.h $i/signal.h sigctl.o: $a $b $i/signal.h $s/sigcontext.h -srvrctl.o: $a $b $s/svrctl.h $k/sendmask.h +sysctl.o: $a $b $s/svrctl.h $k/sendmask.h tracing.o: $a $b $s/ptrace.h -do_copy.o: $a $b -do_vcopy.o: $a $b - diff --git a/kernel/system/copying.c b/kernel/system/copying.c index 0ee19f6f4..a221c8a0c 100644 --- a/kernel/system/copying.c +++ b/kernel/system/copying.c @@ -1,5 +1,5 @@ /* The system call implemented in this file: - * m_type: SYS_VIRCOPY + * m_type: SYS_VIRCOPY, SYS_PHYSCOPY * * The parameters for this system call are: * m5_c1: CP_SRC_SPACE @@ -13,14 +13,17 @@ #include "../kernel.h" #include "../system.h" +#include /*===========================================================================* - * do_vircopy * + * do_copy * *===========================================================================*/ -PUBLIC int do_vircopy(m_ptr) +PUBLIC int do_copy(m_ptr) register message *m_ptr; /* pointer to request message */ { -/* Handle sys_vircopy(). Copy data by using virtual addressing. */ +/* Handle sys_vircopy() and sys_physcopy(). Copy data using virtual or + * physical addressing. + */ struct vir_addr vir_addr[2]; /* virtual source and destination address */ vir_bytes bytes; /* number of bytes to copy */ int i; @@ -41,21 +44,18 @@ register message *m_ptr; /* pointer to request message */ /* Check if process number was given implictly with SELF and is valid. */ if (vir_addr[i].proc_nr == SELF) vir_addr[i].proc_nr = m_ptr->m_source; - if (! isokprocn(vir_addr[i].proc_nr)) { - kprintf("do_vircopy: illegal proc nr\n",NO_ARG); + if (! isokprocn(vir_addr[i].proc_nr) && vir_addr[i].segment != PHYS_SEG) { + kprintf("do_vircopy: illegal proc nr, while not phys addr\n",NO_ARG); return(EINVAL); } - /* Copying from or to special segments can only done by the owner. */ - if ((vir_addr[i].segment & SEGMENT_TYPE) != LOCAL_SEG && - vir_addr[i].proc_nr != m_ptr->m_source) { - kprintf("do_vircopy: special seg permission denied\n", NO_ARG); - return(EPERM); - } + /* Check if physical addressing is used without SYS_PHYSCOPY. */ + if ((vir_addr[i].segment & SEGMENT_TYPE) == PHYS_SEG && + m_ptr->m_type != SYS_PHYSCOPY) return(EPERM); } /* Check for overflow. This would happen for 64K segments and 16-bit - * vir_bytes. Especially copying by the MM on do_fork() is affected. + * vir_bytes. Especially copying by the PM on do_fork() is affected. */ if (bytes != (vir_bytes) bytes) { kprintf("do_vircopy: overflow\n", NO_ARG); @@ -67,37 +67,44 @@ register message *m_ptr; /* pointer to request message */ } -/* The system call implemented in this file: - * m_type: SYS_PHYSCOPY - * - * The parameters for this system call are: - * m5_l1: CP_SRC_ADDR (physical source address) - * m5_l2: CP_DST_ADDR (physical destination address) - * m5_l3: CP_NR_BYTES (number of bytes to copy) - * - * Author: - * Jorrit N. Herder - */ +/* Buffer to hold copy request vector from user. */ +PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE]; /*===========================================================================* - * do_physcopy * + * do_vcopy * *===========================================================================*/ -PUBLIC int do_physcopy(m_ptr) +PUBLIC int do_vcopy(m_ptr) register message *m_ptr; /* pointer to request message */ { -/* Handle sys_physcopy(). Copy data by using physical addressing. */ +/* Handle sys_virvcopy(). Handle virtual copy requests from vector. */ + int nr_req; + int caller_pid; + vir_bytes caller_vir; + phys_bytes caller_phys; + phys_bytes kernel_phys; + phys_bytes bytes; + int i,s; - phys_bytes src_phys, dst_phys, bytes; + /* Check if request vector size is ok. */ + nr_req = (unsigned) m_ptr->VCP_VEC_SIZE; + if (nr_req > VCOPY_VEC_SIZE) return(EINVAL); + bytes = nr_req * sizeof(struct vir_cp_req); - /* Dismember the command message. */ - src_phys = (phys_bytes) m_ptr->CP_SRC_ADDR; - dst_phys = (phys_bytes) m_ptr->CP_DST_ADDR; - bytes = (phys_bytes) m_ptr->CP_NR_BYTES; + /* Calculate physical addresses and copy (port,value)-pairs from user. */ + caller_pid = (int) m_ptr->m_source; + caller_vir = (vir_bytes) m_ptr->VCP_VEC_ADDR; + caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes); + if (0 == caller_phys) return(EFAULT); + kernel_phys = vir2phys(vir_cp_req); + phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes); - /* Do some checks and copy the data. */ - if (src_phys == 0 || dst_phys == 0) return(EFAULT); - phys_copy(src_phys, dst_phys, bytes); - return(OK); + /* Assume vector with requests is correct. Try to copy everything. */ + for (i=0; iCP_SRC_PROC_NR; - dst_proc = m_ptr->CP_DST_PROC_NR; - src_space = m_ptr->CP_SRC_SPACE; - dst_space = m_ptr->CP_DST_SPACE; - src_vir = (vir_bytes) m_ptr->CP_SRC_ADDR; - dst_vir = (vir_bytes) m_ptr->CP_DST_ADDR; - bytes = (phys_bytes) m_ptr->CP_NR_BYTES; - - /* Check if process number was given implicitly with SELF. */ - if (src_proc == SELF) src_proc = m_ptr->m_source; - if (dst_proc == SELF) dst_proc = m_ptr->m_source; - - /* Compute the source and destination addresses and do the copy. */ - if (src_proc == ABS) { - src_phys = (phys_bytes) m_ptr->CP_SRC_ADDR; - } else { - if (bytes != (vir_bytes) bytes) { - /* This would happen for 64K segments and 16-bit vir_bytes. - * It would happen a lot for do_fork except MM uses ABS - * copies for that case. - */ - panic("overflow in count in do_copy", NO_NUM); - } - src_phys = umap_local(proc_addr(src_proc), src_space, src_vir, - (vir_bytes) bytes); - } - - if (dst_proc == ABS) { - dst_phys = (phys_bytes) m_ptr->CP_DST_ADDR; - } else { - dst_phys = umap_local(proc_addr(dst_proc), dst_space, dst_vir, - (vir_bytes) bytes); - } - - if (src_phys == 0 || dst_phys == 0) return(EFAULT); - phys_copy(src_phys, dst_phys, bytes); - return(OK); -} - - diff --git a/kernel/system/do_vcopy.c b/kernel/system/do_vcopy.c deleted file mode 100644 index cb862fc57..000000000 --- a/kernel/system/do_vcopy.c +++ /dev/null @@ -1,55 +0,0 @@ -/* The system call implemented in this file: - * m_type: SYS_VCOPY - * - * The parameters for this system call are: - * m1_i1: VCP_SRC_PROC (source process number) - * m1_i2: VCP_DST_PROC (destination process number) - * m1_i3: VCP_VEC_SIZE (vector size) - * m1_p1: VCP_VEC_ADDR (pointer to vector) - * - * Author: - * Jorrit N. Herder - */ - -#include "../kernel.h" -#include "../system.h" - -/*===========================================================================* - * do_vcopy * - *===========================================================================*/ -PUBLIC int do_vcopy(m_ptr) -register message *m_ptr; /* pointer to request message */ -{ -/* Handle sys_vcopy(). Copy multiple blocks of memory */ - - int src_proc, dst_proc, vect_s, i; - vir_bytes src_vir, dst_vir, vect_addr; - phys_bytes src_phys, dst_phys, bytes; - cpvec_t cpvec_table[CPVEC_NR]; - - /* Dismember the command message. */ - src_proc = m_ptr->VCP_SRC_PROC; - dst_proc = m_ptr->VCP_DST_PROC; - vect_s = m_ptr->VCP_VEC_SIZE; - vect_addr = (vir_bytes)m_ptr->VCP_VEC_ADDR; - - if (vect_s > CPVEC_NR) return EDOM; - - src_phys= numap_local(m_ptr->m_source, vect_addr, vect_s * sizeof(cpvec_t)); - if (!src_phys) return EFAULT; - phys_copy(src_phys, vir2phys(cpvec_table), - (phys_bytes) (vect_s * sizeof(cpvec_t))); - - for (i = 0; i < vect_s; i++) { - src_vir= cpvec_table[i].cpv_src; - dst_vir= cpvec_table[i].cpv_dst; - bytes= cpvec_table[i].cpv_size; - src_phys = numap_local(src_proc,src_vir,(vir_bytes)bytes); - dst_phys = numap_local(dst_proc,dst_vir,(vir_bytes)bytes); - if (src_phys == 0 || dst_phys == 0) return(EFAULT); - phys_copy(src_phys, dst_phys, bytes); - } - return(OK); -} - - diff --git a/kernel/system/irqctl.c b/kernel/system/irqctl.c index 3107e71fb..c69e5417e 100644 --- a/kernel/system/irqctl.c +++ b/kernel/system/irqctl.c @@ -27,11 +27,13 @@ register message *m_ptr; /* pointer to request message */ /* Dismember the request message. */ int irq = m_ptr->IRQ_VECTOR; /* which IRQ vector */ int policy = m_ptr->IRQ_POLICY; /* policy field with flags */ + int proc_nr = m_ptr->IRQ_PROC_NR; /* process number to forward to */ +#if DEAD_CODE long port = m_ptr->IRQ_PORT; /* port to read or write */ vir_bytes vir_addr = m_ptr->IRQ_VIR_ADDR; /* address at caller */ phys_bytes phys_addr = 0; /* calculate physical address */ long mask_val = m_ptr->IRQ_MASK_VAL; /* mask or value to be written */ - int proc_nr = m_ptr->IRQ_PROC_NR; /* process number to forward to */ +#endif /* Check if IRQ line is acceptable. */ if ((unsigned) irq >= NR_IRQ_VECTORS) { @@ -76,6 +78,7 @@ register message *m_ptr; /* pointer to request message */ kprintf("ST: notify: invalid proc_nr: %d\n", proc_nr); return(EINVAL); } +#if DEAD_CODE if (policy & IRQ_READ_PORT) { /* get phys_addr at caller */ switch(policy & (IRQ_BYTE|IRQ_WORD|IRQ_LONG)) { case IRQ_BYTE: phys_addr=numap_local(proc_nr,vir_addr,sizeof( u8_t)); @@ -88,12 +91,15 @@ register message *m_ptr; /* pointer to request message */ } if (phys_addr==0) return(EFAULT); /* invalid address */ } +#endif /* Arguments seem to be OK, register them in the IRQ table. */ irqtab[irq].policy = policy; /* policy for interrupts */ irqtab[irq].proc_nr = proc_nr; /* process number to notify */ +#if DEAD_CODE irqtab[irq].port = port; /* port to read or write */ irqtab[irq].addr = phys_addr; /* address to store status */ irqtab[irq].mask_val = mask_val; /* strobe mask or value */ +#endif put_irq_handler(&irqtab[irq].hook, irq, generic_handler); } break; diff --git a/kernel/system/misc.c b/kernel/system/misc.c index 9fc33e089..2c1c204f0 100644 --- a/kernel/system/misc.c +++ b/kernel/system/misc.c @@ -54,6 +54,16 @@ message *m; /* pointer to request message */ } +/*===========================================================================* + * do_random * + *===========================================================================*/ +PUBLIC int do_random(m) +message *m; /* pointer to request message */ +{ + return(ENOSYS); /* no yet implemented */ +} + + /* The system call implemented in this file: * m_type: SYS_ABORT * @@ -71,7 +81,7 @@ PUBLIC int do_abort(m_ptr) message *m_ptr; /* pointer to request message */ { /* Handle sys_abort. MINIX is unable to continue. This can originate in the - * MM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC + * PM (normal abort or panic) or FS (panic), or TTY (a CTRL-ALT-DEL or ESC * after debugging dumps). */ register struct proc *rp; @@ -84,11 +94,11 @@ message *m_ptr; /* pointer to request message */ if (how == RBT_MONITOR) { /* The monitor is to run user specified instructions. */ len = m_ptr->ABRT_MON_LEN + 1; - assert(len <= mon_parmsize); + assert(len <= kinfo.params_size); src_phys = numap_local(m_ptr->ABRT_MON_PROC, (vir_bytes) m_ptr->ABRT_MON_ADDR, len); assert(src_phys != 0); - phys_copy(src_phys, mon_params, (phys_bytes) len); + phys_copy(src_phys, kinfo.params_base, (phys_bytes) len); } prepare_shutdown(how); return(OK); /* pro-forma (really EDISASTER) */ @@ -125,23 +135,14 @@ register message *m_ptr; /* pointer to request message */ /* Set source address and length based on request type. */ switch (m_ptr->I_REQUEST) { - case GET_KENVIRON: { - struct kenviron kenv; - extern int end; - - kenv.pc_at = pc_at; kenv.ps_mca = ps_mca; - kenv.processor = processor; kenv.protected = protected_mode; - kenv.ega = ega; kenv.vga = vga; - - kenv.proc_addr = (vir_bytes) proc; - kenv.params_base = mon_params; - kenv.params_size = mon_parmsize; - kenv.kmem_base = vir2phys(0); - kenv.kmem_size = vir2phys(&end) - vir2phys(0) + 1; - kenv.bootfs_base = proc_addr(MEMORY)->p_farmem[0].mem_phys; - kenv.bootfs_size = proc_addr(MEMORY)->p_farmem[0].mem_len; - length = sizeof(struct kenviron); - src_phys = vir2phys(&kenv); + case GET_MACHINE: { + length = sizeof(struct machine); + src_phys = vir2phys(&machine); + break; + } + case GET_KINFO: { + length = sizeof(struct kinfo); + src_phys = vir2phys(&kinfo); break; } case GET_IMAGE: { @@ -184,20 +185,26 @@ register message *m_ptr; /* pointer to request message */ break; } case GET_MONPARAMS: { - src_phys = mon_params; /* already is a physical address! */ - length = mon_parmsize; + src_phys = kinfo.params_base; /* already is a physical address! */ + length = kinfo.params_size; break; } case GET_PROCNR: { - length = sizeof(int); if (m_ptr->I_KEY_LEN == 0) { /* get own process nr */ +#if DEAD_CODE + /* GET_PROCNR functionality will be moved to the Process Manager! */ kprintf("GET_PROCNR (own) from %d\n", m_ptr->m_source); +#endif src_phys = vir2phys(&proc_nr); + length = sizeof(int); } else { /* lookup nr by name */ int proc_found = FALSE; struct proc *pp; char key[8]; /* storage for process name to lookup */ - kprintf("GET_PROCNR (others) from %d\n", m_ptr->m_source); +#if DEAD_CODE + /* GET_PROCNR functionality will be moved to the Process Manager! */ + kprintf("GET_PROCNR (by name) from %d\n", m_ptr->m_source); +#endif proc_nr = m_ptr->m_source; /* only caller can request copy */ if (m_ptr->I_KEY_LEN > sizeof(key)) return(EINVAL); if (vir_copy(proc_nr, (vir_bytes) m_ptr->I_KEY_PTR, SYSTASK, @@ -205,6 +212,7 @@ register message *m_ptr; /* pointer to request message */ for (pp=BEG_PROC_ADDR; ppp_name, key, m_ptr->I_KEY_LEN) == 0) { src_phys = vir2phys(&(pp->p_nr)); + length = sizeof(int); proc_found = TRUE; break; } diff --git a/kernel/system/proctl.c b/kernel/system/proctl.c index d03c62052..31493b838 100644 --- a/kernel/system/proctl.c +++ b/kernel/system/proctl.c @@ -4,7 +4,7 @@ * The parameters for this system call are: * m1_i1: PR_PROC_NR (child's process table slot) * m1_i2: PR_PPROC_NR (parent, process that forked) - * m1_i3: PR_PID (child pid received from MM) + * m1_i3: PR_PID (child pid received from PM) */ #include "../kernel.h" @@ -81,23 +81,23 @@ register message *m_ptr; /* pointer to request message */ PUBLIC int do_newmap(m_ptr) message *m_ptr; /* pointer to request message */ { -/* Handle sys_newmap(). Fetch the memory map from MM. */ +/* Handle sys_newmap(). Fetch the memory map from PM. */ register struct proc *rp; phys_bytes src_phys; - int caller; /* whose space has the new map (usually MM) */ + int caller; /* whose space has the new map (usually PM) */ int k; /* process whose map is to be loaded */ int old_flags; /* value of flags before modification */ - struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */ + struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */ - /* Extract message parameters and copy new memory map from MM. */ + /* Extract message parameters and copy new memory map from PM. */ caller = m_ptr->m_source; k = m_ptr->PR_PROC_NR; map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR; if (!isokprocn(k)) return(EINVAL); rp = proc_addr(k); /* ptr to entry of user getting new map */ - /* Copy the map from MM. */ + /* Copy the map from PM. */ src_phys = umap_local(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_memmap)); assert(src_phys != 0); @@ -158,7 +158,7 @@ register message *m_ptr; /* pointer to request message */ (LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0])); #endif rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR; /* set pc */ - rp->p_flags &= ~RECEIVING; /* MM does not reply to EXEC call */ + rp->p_flags &= ~RECEIVING; /* PM does not reply to EXEC call */ if (rp->p_flags == 0) lock_ready(rp); /* Save command name for debugging, ps(1) output, etc. */ @@ -189,7 +189,7 @@ register message *m_ptr; /* pointer to request message */ PUBLIC int do_xit(m_ptr) message *m_ptr; /* pointer to request message */ { -/* Handle sys_exit. A user process has exited (the MM sent the request). +/* Handle sys_exit. A user process has exited (the PM sent the request). */ register struct proc *rp, *rc; struct proc *np, *xp; @@ -201,7 +201,7 @@ message *m_ptr; /* pointer to request message */ if (! isokprocn(exit_proc_nr)) return(EINVAL); rc = proc_addr(exit_proc_nr); - /* If this is a user process and the MM passed in a valid parent process, + /* If this is a user process and the PM passed in a valid parent process, * accumulate the child times at the parent. */ if (isuserp(rc) && isokprocn(m_ptr->PR_PPROC_NR)) { @@ -217,7 +217,7 @@ message *m_ptr; /* pointer to request message */ * and resets important process table fields. */ clear_proc(exit_proc_nr); - return(OK); /* tell MM that cleanup succeeded */ + return(OK); /* tell PM that cleanup succeeded */ } diff --git a/kernel/system/sigctl.c b/kernel/system/sigctl.c index 6aad28339..e154a8250 100644 --- a/kernel/system/sigctl.c +++ b/kernel/system/sigctl.c @@ -23,67 +23,54 @@ #include INIT_ASSERT -/*===========================================================================* - * do_sigctl * - *===========================================================================*/ -PUBLIC int do_sigctl(m_ptr) +/* PM is ready to accept signals and repeatedly does a system call to get + * one. Find a process with pending signals. If no signals are available, + * return NONE in the process number field. + */ +PUBLIC int do_getsig(m_ptr) message *m_ptr; /* pointer to request message */ { - /* Only the MM and FS are allowed to use signal control operations. */ - if (m_ptr->m_source != MM_PROC_NR && m_ptr->m_source != FS_PROC_NR) - return(EPERM); + register struct proc *rp; - /* Now see what request we got. The supported requests are S_GETSIG, - * S_ENDSIG, S_SENDSIG, S_SIGRETURN, and S_KILL. Unsupported requests - * result in an EINVAL error. - */ - switch(m_ptr->SIG_REQUEST) { - - /* MM is ready to accept signals and repeatedly does a system call to get - * one. Find a process with pending signals. If no signals are available, - * return NONE in the process number field. - */ - case S_GETSIG: { - - register struct proc *rp; - - /* Find the next process with pending signals. */ - for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) { - if (rp->p_flags & PENDING) { - m_ptr->SIG_PROC = proc_number(rp); - m_ptr->SIG_MAP = rp->p_pending; - sigemptyset(&rp->p_pending); /* ball is in MM's court */ - rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */ - return(OK); - } - } - - /* No process with pending signals was found. */ - m_ptr->SIG_PROC = NONE; - return(OK); + /* Find the next process with pending signals. */ + for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) { + if (rp->p_flags & PENDING) { + m_ptr->SIG_PROC = proc_number(rp); + m_ptr->SIG_MAP = rp->p_pending; + sigemptyset(&rp->p_pending); /* ball is in PM's court */ + rp->p_flags &= ~PENDING; /* blocked by SIG_PENDING */ + return(OK); + } } - /* Finish up after a KSIG-type signal, caused by a SYS_KILL message or a - * call to cause_sig by a task - */ - case S_ENDSIG: { + /* No process with pending signals was found. */ + m_ptr->SIG_PROC = NONE; + return(OK); +} - register struct proc *rp; +PUBLIC int do_endsig(m_ptr) +message *m_ptr; /* pointer to request message */ +{ +/* Finish up after a kernel type signal, caused by a SYS_KILL message or a + * call to cause_sig by a task. This is called by the PM after processing a + * signal it got with SYS_GETSIG. + */ + register struct proc *rp; - rp = proc_addr(m_ptr->SIG_PROC); - if (isemptyp(rp)) return(EINVAL); /* process already dead? */ - assert(isuserp(rp)); + rp = proc_addr(m_ptr->SIG_PROC); + if (isemptyp(rp)) return(EINVAL); /* process already dead? */ - /* MM has finished one KSIG. Perhaps process is ready now? */ - if (rp->p_pendcount != 0 && --rp->p_pendcount == 0 - && (rp->p_flags &= ~SIG_PENDING) == 0) - lock_ready(rp); - return(OK); - } + /* PM has finished one kernel signal. Perhaps process is ready now? */ + if (rp->p_pendcount != 0 && --rp->p_pendcount == 0 + && (rp->p_flags &= ~SIG_PENDING) == 0) + lock_ready(rp); + return(OK); +} - /* Handle sys_sendsig, POSIX-style signal handling. - */ - case S_SENDSIG: { +PUBLIC int do_sigsend(m_ptr) +message *m_ptr; /* pointer to request message */ +{ +/* Handle sys_sigsend, POSIX-style signal handling. */ struct sigmsg smsg; register struct proc *rp; @@ -95,7 +82,7 @@ message *m_ptr; /* pointer to request message */ assert(isuserp(rp)); /* Get the sigmsg structure into our address space. */ - src_phys = umap_local(proc_addr(MM_PROC_NR), D, (vir_bytes) + src_phys = umap_local(proc_addr(PM_PROC_NR), D, (vir_bytes) m_ptr->SIG_CTXT_PTR, (vir_bytes) sizeof(struct sigmsg)); assert(src_phys != 0); phys_copy(src_phys,vir2phys(&smsg),(phys_bytes) sizeof(struct sigmsg)); @@ -140,13 +127,14 @@ message *m_ptr; /* pointer to request message */ rp->p_reg.pc = (reg_t) smsg.sm_sighandler; return(OK); - } - - /* POSIX style signals require sys_sigreturn to put things in order before - * the signalled process can resume execution - */ - case S_SIGRETURN: { +} +PUBLIC int do_sigreturn(m_ptr) +message *m_ptr; /* pointer to request message */ +{ +/* POSIX style signals require sys_sigreturn to put things in order before + * the signalled process can resume execution + */ struct sigcontext sc; register struct proc *rp; phys_bytes src_phys; @@ -193,30 +181,18 @@ message *m_ptr; /* pointer to request message */ /* Restore the registers. */ kmemcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs)); - return(OK); - } - - /* Handle sys_kill(). Cause a signal to be sent to a process via MM. - * Note that this has nothing to do with the kill(2) system call, this - * is how the FS (and possibly other servers) get access to cause_sig. - */ - case S_KILL: { - cause_sig(m_ptr->SIG_PROC, m_ptr->SIG_NUMBER); - return(OK); - } - default: - return(EINVAL); - } } - +/*===========================================================================* + * do_sigctl * + *===========================================================================*/ PUBLIC int do_kill(m_ptr) message *m_ptr; /* pointer to request message */ { -/* Handle sys_kill(). Cause a signal to be sent to a process via MM. +/* Handle sys_kill(). Cause a signal to be sent to a process via PM. * Note that this has nothing to do with the kill (2) system call, this * is how the FS (and possibly other servers) get access to cause_sig. */ diff --git a/kernel/system/srvrctl.c b/kernel/system/sysctl.c similarity index 87% rename from kernel/system/srvrctl.c rename to kernel/system/sysctl.c index 7ec27283e..a67c4f71b 100644 --- a/kernel/system/srvrctl.c +++ b/kernel/system/sysctl.c @@ -82,7 +82,7 @@ message *m_ptr; /* pointer to request message */ argp = (vir_bytes) m_ptr->CTL_ARG_PTR; rp = proc_addr(proc_nr); - /* Check if the MM privileges are super user. */ + /* Check if the PM privileges are super user. */ if (!priv || !isuserp(rp)) return(EPERM); @@ -99,7 +99,7 @@ message *m_ptr; /* pointer to request message */ rp->p_type = P_SERVER; rp->p_sendmask = ALLOW_ALL_MASK; send_mask_allow(proc_addr(RTL8139)->p_sendmask, proc_nr); - send_mask_allow(proc_addr(MM_PROC_NR)->p_sendmask, proc_nr); + send_mask_allow(proc_addr(PM_PROC_NR)->p_sendmask, proc_nr); send_mask_allow(proc_addr(FS_PROC_NR)->p_sendmask, proc_nr); send_mask_allow(proc_addr(IS_PROC_NR)->p_sendmask, proc_nr); send_mask_allow(proc_addr(CLOCK)->p_sendmask, proc_nr); @@ -112,7 +112,7 @@ message *m_ptr; /* pointer to request message */ } /* The system call implemented in this file: - * m_type: SYS_MEMCTL + * m_type: SYS_SEGCTL * * The parameters for this system call are: * m4_l3: SEG_PHYS (physical base address) @@ -127,9 +127,9 @@ message *m_ptr; /* pointer to request message */ /*===========================================================================* - * do_phys2seg * + * do_segctl * *===========================================================================*/ -PUBLIC int do_phys2seg(m_ptr) +PUBLIC int do_segctl(m_ptr) register message *m_ptr; /* pointer to request message */ { /* Return a segment selector and offset that can be used to reach a physical @@ -137,14 +137,28 @@ register message *m_ptr; /* pointer to request message */ */ u16_t selector; vir_bytes offset; + int i, index; register struct proc *rp; phys_bytes phys = (phys_bytes) m_ptr->SEG_PHYS; vir_bytes size = (vir_bytes) m_ptr->SEG_SIZE; int result; - kprintf("Using Experimental LDT selector for video memory\n", NO_ARG); + /* First check if there is a slot available for this segment. */ + rp = proc_addr(m_ptr->m_source); + index = -1; + for (i=0; i < NR_REMOTE_SEGS; i++) { + if (! rp->p_farmem[i].in_use) { + index = i; + rp->p_farmem[i].in_use = TRUE; + rp->p_farmem[i].mem_phys = phys; + rp->p_farmem[i].mem_len = size; + break; + } + } + if (index < 0) return(ENOSPC); - if (!protected_mode) { + + if (! machine.protected) { selector = phys / HCLICK_SIZE; offset = phys % HCLICK_SIZE; result = OK; @@ -155,26 +169,22 @@ register message *m_ptr; /* pointer to request message */ * instead of bytes are used. */ if (size < BYTE_GRAN_MAX) { - rp = proc_addr(m_ptr->m_source); - init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX], phys, size, + init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys, size, USER_PRIVILEGE); - selector = (EXTRA_LDT_INDEX * 0x08) | (1 * 0x04) | USER_PRIVILEGE; + selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE; offset = 0; result = OK; } else { -#if ENABLE_USERPRIV && ENABLE_LOOSELDT - rp = proc_addr(m_ptr->m_source); - init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX], phys & ~0xFFFF, 0, + init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0, USER_PRIVILEGE); - selector = (EXTRA_LDT_INDEX * 0x08) | (1 * 0x04) | USER_PRIVILEGE; + selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE; offset = phys & 0xFFFF; result = OK; -#else - result = E2BIG; /* allow settings only */ -#endif } } + /* Request successfully done. Now return the result. */ + m_ptr->SEG_INDEX = index | REMOTE_SEG; m_ptr->SEG_SELECT = selector; m_ptr->SEG_OFFSET = offset; return(result); diff --git a/kernel/system/tracing.c b/kernel/system/tracing.c index d33f227ba..1d7bedda1 100644 --- a/kernel/system/tracing.c +++ b/kernel/system/tracing.c @@ -36,7 +36,7 @@ register message *m_ptr; * T_EXIT exit * T_STEP set trace bit * - * The T_OK and T_EXIT commands are handled completely by the memory manager, + * The T_OK and T_EXIT commands are handled completely by the process manager, * all others come here. */ diff --git a/kernel/table.c b/kernel/table.c index 662d5251e..b7e886e65 100755 --- a/kernel/table.c +++ b/kernel/table.c @@ -70,7 +70,7 @@ PUBLIC struct system_image image[] = { { CLOCK, clock_task, P_TASK, PPRI_TASK, CLOCK_STACK, CLOCK_SENDMASK, "CLOCK" }, { SYSTASK, sys_task, P_TASK, PPRI_TASK, SYS_STACK, SYSTEM_SENDMASK, "SYS" }, { HARDWARE, 0, P_TASK, PPRI_TASK, HARDWARE_STACK,HARDWARE_SENDMASK,"HARDWAR" }, - { MM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, MM_SENDMASK, "MM" }, + { PM_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, PM_SENDMASK, "PM" }, { FS_PROC_NR, 0, P_SERVER, PPRI_NORMAL, 0, FS_SENDMASK, "FS" }, { IS_PROC_NR, 0, P_SYSTEM, PPRI_HIGHER, 0, IS_SENDMASK, "IS" }, { TTY, 0, P_SYSTEM, PPRI_HIGHER, 0, TTY_SENDMASK, "TTY" }, diff --git a/kernel/type.h b/kernel/type.h index ba009ad71..e3ac0e291 100755 --- a/kernel/type.h +++ b/kernel/type.h @@ -5,13 +5,6 @@ typedef _PROTOTYPE( void task_t, (void) ); typedef _PROTOTYPE( int (*rdwt_t), (message *m_ptr) ); typedef _PROTOTYPE( void (*watchdog_t), (void) ); -/* This is used within the kernel to handle virtual copying. */ -struct vir_addr { - int proc_nr; - int segment; - vir_bytes offset; -}; - /* Type accepted by kprintf(). This is a hack to accept both integers and * char pointers in the same argument. */ diff --git a/lib/syslib/Makefile b/lib/syslib/Makefile index 555274e88..ff51fe076 100755 --- a/lib/syslib/Makefile +++ b/lib/syslib/Makefile @@ -13,12 +13,14 @@ OBJECTS = \ $(LIBSYS)(sys_times.o) \ $(LIBSYS)(sys_getuptm.o) \ $(LIBSYS)(sys_abort.o) \ - $(LIBSYS)(sys_copy.o) \ $(LIBSYS)(sys_exec.o) \ $(LIBSYS)(sys_fork.o) \ $(LIBSYS)(sys_kill.o) \ $(LIBSYS)(sys_newmap.o) \ - $(LIBSYS)(sys_sigctl.o) \ + $(LIBSYS)(sys_sigsend.o) \ + $(LIBSYS)(sys_sigret.o) \ + $(LIBSYS)(sys_endsig.o) \ + $(LIBSYS)(sys_getsig.o) \ $(LIBSYS)(sys_svrctl.o) \ $(LIBSYS)(sys_trace.o) \ $(LIBSYS)(sys_xit.o) \ @@ -27,7 +29,7 @@ OBJECTS = \ $(LIBSYS)(sys_kmalloc.o) \ $(LIBSYS)(sys_irqctl.o) \ $(LIBSYS)(sys_eniop.o) \ - $(LIBSYS)(sys_ph2sg.o) \ + $(LIBSYS)(sys_segctl.o) \ $(LIBSYS)(sys_umap.o) \ $(LIBSYS)(sys_exit.o) \ $(LIBSYS)(sys_physcp.o) \ @@ -67,9 +69,6 @@ $(LIBSYS)(sys_getuptm.o): sys_getuptm.c $(LIBSYS)(sys_abort.o): sys_abort.c $(CC1) sys_abort.c -$(LIBSYS)(sys_copy.o): sys_copy.c - $(CC1) sys_copy.c - $(LIBSYS)(sys_exec.o): sys_exec.c $(CC1) sys_exec.c @@ -106,8 +105,8 @@ $(LIBSYS)(sys_irqctl.o): sys_irqctl.c $(LIBSYS)(sys_eniop.o): sys_eniop.c $(CC1) sys_eniop.c -$(LIBSYS)(sys_ph2sg.o): sys_ph2sg.c - $(CC1) sys_ph2sg.c +$(LIBSYS)(sys_segctl.o): sys_segctl.c + $(CC1) sys_segctl.c $(LIBSYS)(sys_umap.o): sys_umap.c $(CC1) sys_umap.c @@ -115,8 +114,17 @@ $(LIBSYS)(sys_umap.o): sys_umap.c $(LIBSYS)(sys_exit.o): sys_exit.c $(CC1) sys_exit.c -$(LIBSYS)(sys_sigctl.o): sys_sigctl.c - $(CC1) sys_sigctl.c +$(LIBSYS)(sys_getsig.o): sys_getsig.c + $(CC1) sys_getsig.c + +$(LIBSYS)(sys_endsig.o): sys_endsig.c + $(CC1) sys_endsig.c + +$(LIBSYS)(sys_sigsend.o): sys_sigsend.c + $(CC1) sys_sigsend.c + +$(LIBSYS)(sys_sigret.o): sys_sigret.c + $(CC1) sys_sigret.c $(LIBSYS)(sys_physcp.o): sys_physcp.c $(CC1) sys_physcp.c diff --git a/lib/syslib/sys_copy.c b/lib/syslib/sys_copy.c deleted file mode 100755 index e360bf767..000000000 --- a/lib/syslib/sys_copy.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "syslib.h" - -PUBLIC int sys_copy(src_proc, src_seg, src_vir, - dst_proc, dst_seg, dst_vir, bytes) -int src_proc; /* source process */ -int src_seg; /* source segment: T, D, or S */ -phys_bytes src_vir; /* source virtual address (phys addr for ABS)*/ -int dst_proc; /* dest process */ -int dst_seg; /* dest segment: T, D, or S */ -phys_bytes dst_vir; /* dest virtual address (phys addr for ABS) */ -phys_bytes bytes; /* how many bytes */ -{ -/* Transfer a block of data. The source and destination can each either be a - * process number, SELF (to set own process number), or ABS (to indicate the - * use of an absolute memory address). - */ - - message copy_mess; - - if (bytes == 0L) return(OK); - copy_mess.CP_SRC_SPACE = src_seg; - copy_mess.CP_SRC_PROC_NR = src_proc; - copy_mess.CP_SRC_ADDR = (long) src_vir; - - copy_mess.CP_DST_SPACE = dst_seg; - copy_mess.CP_DST_PROC_NR = dst_proc; - copy_mess.CP_DST_ADDR = (long) dst_vir; - - copy_mess.CP_NR_BYTES = (long) bytes; - return(_taskcall(SYSTASK, SYS_COPY, ©_mess)); -} diff --git a/lib/syslib/sys_endsig.c b/lib/syslib/sys_endsig.c index acf07c7c1..ce63c5027 100755 --- a/lib/syslib/sys_endsig.c +++ b/lib/syslib/sys_endsig.c @@ -1,10 +1,16 @@ #include "syslib.h" -PUBLIC int sys_endsig(proc) -int proc; +/*===========================================================================* + * sys_endsig * + *===========================================================================*/ +PUBLIC int sys_endsig(proc_nr) +int proc_nr; /* process number */ { - message m; + message m; + int result; - m.m1_i1 = proc; - return(_taskcall(SYSTASK, SYS_ENDSIG, &m)); + m.SIG_PROC = proc_nr; + result = _taskcall(SYSTASK, SYS_ENDSIG, &m); + return(result); } + diff --git a/lib/syslib/sys_getmap.c b/lib/syslib/sys_getmap.c deleted file mode 100755 index 5cf3d175a..000000000 --- a/lib/syslib/sys_getmap.c +++ /dev/null @@ -1,14 +0,0 @@ -#include "syslib.h" - -PUBLIC int sys_getmap(proc, ptr) -int proc; /* process whose map is to be fetched */ -struct mem_map *ptr; /* pointer to new map */ -{ -/* Want to know map of a process, ask the kernel. */ - - message m; - - m.m1_i1 = proc; - m.m1_p1 = (char *) ptr; - return(_taskcall(SYSTASK, SYS_GETMAP, &m)); -} diff --git a/lib/syslib/sys_getsig.c b/lib/syslib/sys_getsig.c new file mode 100644 index 000000000..2e2fe1800 --- /dev/null +++ b/lib/syslib/sys_getsig.c @@ -0,0 +1,18 @@ +#include "syslib.h" + +/*===========================================================================* + * sys_getsig * + *===========================================================================*/ +PUBLIC int sys_getsig(k_proc_nr, k_sig_map) +int *k_proc_nr; /* return process number here */ +sigset_t *k_sig_map; /* return signal map here */ +{ + message m; + int result; + + result = _taskcall(SYSTASK, SYS_GETSIG, &m); + *k_proc_nr = m.SIG_PROC; + *k_sig_map = (sigset_t) m.SIG_MAP; + return(result); +} + diff --git a/lib/syslib/sys_oldsig.c b/lib/syslib/sys_oldsig.c deleted file mode 100755 index 844416670..000000000 --- a/lib/syslib/sys_oldsig.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "syslib.h" - -PUBLIC int sys_oldsig(proc, sig, sighandler) -int proc; /* process to be signaled */ -int sig; /* signal number: 1 to _NSIG */ -sighandler_t sighandler; /* pointer to signal handler in user space */ -{ -/* A proc has to be signaled. Tell the kernel. This function is obsolete. */ - - message m; - - m.m6_i1 = proc; - m.m6_i2 = sig; - m.m6_f1 = sighandler; - return(_taskcall(SYSTASK, SYS_OLDSIG, &m)); -} diff --git a/lib/syslib/sys_physcp.c b/lib/syslib/sys_physcp.c index cfa8112bf..79f03beb0 100644 --- a/lib/syslib/sys_physcp.c +++ b/lib/syslib/sys_physcp.c @@ -1,18 +1,30 @@ #include "syslib.h" -PUBLIC int sys_physcopy(src_phys, dst_phys, bytes) -phys_bytes src_phys; /* source physical address */ -phys_bytes dst_phys; /* destination physical address */ +PUBLIC int sys_physcopy(src_proc, src_seg, src_vir, + dst_proc, dst_seg, dst_vir, bytes) +int src_proc; /* source process */ +int src_seg; /* source memory segment */ +vir_bytes src_vir; /* source virtual address */ +int dst_proc; /* destination process */ +int dst_seg; /* destination memory segment */ +vir_bytes dst_vir; /* destination virtual address */ phys_bytes bytes; /* how many bytes */ { -/* Transfer a block of data. This uses absolute memory addresses only. Use - * sys_umap to convert a virtual address into a physical address if needed. +/* Transfer a block of data. The source and destination can each either be a + * process number or SELF (to indicate own process number). Virtual addresses + * are offsets within LOCAL_SEG (text, stack, data), REMOTE_SEG, or BIOS_SEG. + * Physicall addressing is also possible with PHYS_SEG. */ + message copy_mess; if (bytes == 0L) return(OK); - copy_mess.CP_SRC_ADDR = (long) src_phys; - copy_mess.CP_DST_ADDR = (long) dst_phys; + copy_mess.CP_SRC_PROC_NR = src_proc; + copy_mess.CP_SRC_SPACE = src_seg; + copy_mess.CP_SRC_ADDR = (long) src_vir; + copy_mess.CP_DST_PROC_NR = dst_proc; + copy_mess.CP_DST_SPACE = dst_seg; + copy_mess.CP_DST_ADDR = (long) dst_vir; copy_mess.CP_NR_BYTES = (long) bytes; return(_taskcall(SYSTASK, SYS_PHYSCOPY, ©_mess)); } diff --git a/lib/syslib/sys_ph2sg.c b/lib/syslib/sys_segctl.c similarity index 69% rename from lib/syslib/sys_ph2sg.c rename to lib/syslib/sys_segctl.c index de0c1ee95..84deecbba 100644 --- a/lib/syslib/sys_ph2sg.c +++ b/lib/syslib/sys_segctl.c @@ -1,9 +1,10 @@ #include "syslib.h" /*===========================================================================* - * sys_phys2seg * + * sys_segctl * *===========================================================================*/ -PUBLIC int sys_phys2seg(seg, off, phys, size) +PUBLIC int sys_segctl(index, seg, off, phys, size) +int *index; /* return index of remote segment */ u16_t *seg; /* return segment selector here */ vir_bytes *off; /* return offset in segment here */ phys_bytes phys; /* physical address to convert */ @@ -13,7 +14,8 @@ vir_bytes size; /* size of segment */ int s; m.SEG_PHYS = phys; m.SEG_SIZE = size; - s = _taskcall(SYSTASK, SYS_PHYS2SEG, &m); + s = _taskcall(SYSTASK, SYS_SEGCTL, &m); + *index = (int) m.SEG_INDEX; *seg = (u16_t) m.SEG_SELECT; *off = (vir_bytes) m.SEG_OFFSET; return s; diff --git a/lib/syslib/sys_sendsig.c b/lib/syslib/sys_sendsig.c deleted file mode 100755 index 277e18096..000000000 --- a/lib/syslib/sys_sendsig.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "syslib.h" - -PUBLIC int sys_sendsig(proc, smp) -int proc; -struct sigmsg *smp; -{ - message m; - - m.m1_i1 = proc; - m.m1_p1 = (char *) smp; - return(_taskcall(SYSTASK, SYS_SENDSIG, &m)); -} diff --git a/lib/syslib/sys_sigctl.c b/lib/syslib/sys_sigctl.c deleted file mode 100644 index 29cd4fcec..000000000 --- a/lib/syslib/sys_sigctl.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "syslib.h" - -/*===========================================================================* - * sys_sigctl * - *===========================================================================*/ -PUBLIC int sys_sigctl(request, proc_nr, sig_ctxt, flags, k_proc_nr, k_sig_map) -int request; /* control operation requested */ -int proc_nr; /* for which process */ -struct sigmsg *sig_ctxt; /* POSIX style handling */ -int flags; /* flags for POSIX handling */ -int *k_proc_nr; /* return process number here */ -sigset_t *k_sig_map; /* return signal map here */ -{ - message m; - int result; - - m.m_type = SYS_SIGCTL; - m.SIG_REQUEST = request; - m.SIG_PROC = proc_nr; - m.SIG_FLAGS = flags; - m.SIG_CTXT_PTR = (char *) sig_ctxt; - result = _taskcall(SYSTASK, SYS_SIGCTL, &m); - if (request == S_GETSIG && k_proc_nr != 0 && k_sig_map != 0) { - *k_proc_nr = m.SIG_PROC; - *k_sig_map = (sigset_t) m.SIG_MAP; - } - return(result); -} - diff --git a/lib/syslib/sys_sigret.c b/lib/syslib/sys_sigret.c index d65551ced..57afdf4d1 100755 --- a/lib/syslib/sys_sigret.c +++ b/lib/syslib/sys_sigret.c @@ -1,14 +1,20 @@ #include "syslib.h" -PUBLIC int sys_sigreturn(proc, scp, flags) -int proc; -vir_bytes scp; -int flags; +/*===========================================================================* + * sys_sigreturn * + *===========================================================================*/ +PUBLIC int sys_sigreturn(proc_nr, sig_ctxt, flags) +int proc_nr; /* for which process */ +struct sigmsg *sig_ctxt; /* POSIX style handling */ +int flags; /* flags for POSIX handling */ { - message m; + message m; + int result; - m.m1_i1 = proc; - m.m1_i2 = flags; - m.m1_p1 = (char *) scp; - return(_taskcall(SYSTASK, SYS_SIGRETURN, &m)); + m.SIG_PROC = proc_nr; + m.SIG_CTXT_PTR = (char *) sig_ctxt; + m.SIG_FLAGS = flags; + result = _taskcall(SYSTASK, SYS_SIGRETURN, &m); + return(result); } + diff --git a/lib/syslib/sys_sigsend.c b/lib/syslib/sys_sigsend.c new file mode 100644 index 000000000..e879b549d --- /dev/null +++ b/lib/syslib/sys_sigsend.c @@ -0,0 +1,18 @@ +#include "syslib.h" + +/*===========================================================================* + * sys_sigsend * + *===========================================================================*/ +PUBLIC int sys_sigsend(proc_nr, sig_ctxt) +int proc_nr; /* for which process */ +struct sigmsg *sig_ctxt; /* POSIX style handling */ +{ + message m; + int result; + + m.SIG_PROC = proc_nr; + m.SIG_CTXT_PTR = (char *) sig_ctxt; + result = _taskcall(SYSTASK, SYS_SIGSEND, &m); + return(result); +} + diff --git a/lib/syslib/sys_vidcp.c b/lib/syslib/sys_vidcp.c deleted file mode 100644 index 53356b66e..000000000 --- a/lib/syslib/sys_vidcp.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "syslib.h" - -/*===========================================================================* - * sys_vidcopy * - *===========================================================================*/ -PUBLIC int sys_vidcopy(request, src_mem, src_vid, dst_vid, count) -int request; /* MEM_VID_COPY or VID_VID_COPY */ -u16_t *src_mem; /* source address in memory */ -unsigned src_vid; /* source address in video memory */ -unsigned dst_vid; /* destination address in video */ -unsigned count; /* number of words to copy */ -{ -/* Console wants to display something on the screen. */ - message m; - m.VID_REQUEST = request; - m.VID_SRC_ADDR = src_mem; - m.VID_SRC_OFFSET = src_vid; - m.VID_DST_OFFSET = dst_vid; - m.VID_CP_COUNT = count; - return(_taskcall(SYSTASK, SYS_VIDCOPY, &m)); -} - diff --git a/lib/syslib/sys_vircp.c b/lib/syslib/sys_vircp.c index c4e95e036..e5900ccb4 100644 --- a/lib/syslib/sys_vircp.c +++ b/lib/syslib/sys_vircp.c @@ -11,8 +11,8 @@ vir_bytes dst_vir; /* destination virtual address */ phys_bytes bytes; /* how many bytes */ { /* Transfer a block of data. The source and destination can each either be a - * process number or SELF (to set own process number). The virtual address is - * in the data segment (D). + * process number or SELF (to indicate own process number). Virtual addresses + * are offsets within LOCAL_SEG (text, stack, data), REMOTE_SEG, or BIOS_SEG. */ message copy_mess; diff --git a/lib/utils/get_proc_nr.c b/lib/utils/get_proc_nr.c index 3d5227708..6fd0b46b7 100644 --- a/lib/utils/get_proc_nr.c +++ b/lib/utils/get_proc_nr.c @@ -12,7 +12,7 @@ PUBLIC int get_proc_nr(proc_nr, proc_name) int *proc_nr; /* store process number here */ char *proc_name; /* lookup process by name */ { - struct proc proc; + static struct proc proc; message m; int s; if (proc_name != NULL) { /* lookup by name */ @@ -23,6 +23,7 @@ char *proc_name; /* lookup process by name */ m.I_PROC_NR = SELF; m.I_KEY_LEN = SELF; m.I_VAL_PTR = (char *) &proc; + m.I_VAL_LEN = 0; if ((s=_taskcall(SYSTASK, SYS_GETINFO, &m)) != OK) return(s); *proc_nr = proc.p_nr; diff --git a/servers/fs/cmostime.c b/servers/fs/cmostime.c index e63f653a2..514c42d43 100644 --- a/servers/fs/cmostime.c +++ b/servers/fs/cmostime.c @@ -33,8 +33,8 @@ PUBLIC int do_cmostime(void) /* First obtain the machine ID to see if we can read the CMOS clock. Only * for PS_386 and PC_AT this is possible. Otherwise, return an error. */ - sys_vircopy(SELF, BIOS_SEG, (vir_bytes) ADR_MACHINE_ID, - SELF, D, (vir_bytes) &mach_id, LEN_MACHINE_ID); + sys_vircopy(SELF, BIOS_SEG, (vir_bytes) MACHINE_ID_ADDR, + SELF, D, (vir_bytes) &mach_id, MACHINE_ID_SIZE); if (mach_id != PS_386_MACHINE && mach_id != PC_AT_MACHINE) { printf("IS: Machine ID unknown. ID byte = %02x.\n", mach_id); return(EFAULT); diff --git a/servers/fs/device.c b/servers/fs/device.c index 92a591e7d..0e7485650 100644 --- a/servers/fs/device.c +++ b/servers/fs/device.c @@ -206,7 +206,7 @@ PUBLIC int do_setsid() register struct fproc *rfp; /* Only MM may do the SETSID call directly. */ - if (who != MM_PROC_NR) return(ENOSYS); + if (who != PM_PROC_NR) return(ENOSYS); /* Make the process a session leader with no controlling tty. */ rfp = &fproc[m_in.slot1]; diff --git a/servers/fs/main.c b/servers/fs/main.c index acd9e1dd8..4b5f99334 100644 --- a/servers/fs/main.c +++ b/servers/fs/main.c @@ -305,10 +305,10 @@ PRIVATE void load_ram(void) if (sendrec(MEMORY, &m_out) != OK || m_out.REP_STATUS != OK) panic("Can't set RAM disk size", NO_NUM); - /* Tell MM the RAM disk size, and wait for it to come "on-line". */ + /* Tell PM the RAM disk size, and wait for it to come "on-line". */ m_out.MEM_CHUNK_SIZE = ((long) ram_size_kb * 1024) >> CLICK_SHIFT; - if (sendrec(MM_PROC_NR, &m_out) != OK) - panic("FS can't sync up with MM", NO_NUM); + if (sendrec(PM_PROC_NR, &m_out) != OK) + panic("FS can't sync up with PM", NO_NUM); #if ENABLE_CACHE2 /* The RAM disk is a second level block cache while not otherwise used. */ diff --git a/servers/fs/misc.c b/servers/fs/misc.c index 9641cf7fb..085fd65df 100644 --- a/servers/fs/misc.c +++ b/servers/fs/misc.c @@ -171,8 +171,8 @@ PUBLIC int do_reboot() struct super_block *sp; struct inode dummy; - /* Only MM may make this call directly. */ - if (who != MM_PROC_NR) return(EGENERIC); + /* Only PM may make this call directly. */ + if (who != PM_PROC_NR) return(EGENERIC); /* Do exit processing for all leftover processes and servers. */ for (i = 0; i < NR_PROCS; i++) { m_in.slot1 = i; do_exit(); } @@ -212,8 +212,8 @@ PUBLIC int do_fork() register struct fproc *cp; int i; - /* Only MM may make this call directly. */ - if (who != MM_PROC_NR) return(EGENERIC); + /* Only PM may make this call directly. */ + if (who != PM_PROC_NR) return(EGENERIC); /* Copy the parent's fproc struct to the child. */ fproc[m_in.child] = fproc[m_in.parent]; @@ -248,8 +248,8 @@ PUBLIC int do_exec() register int i; long bitmap; - /* Only MM may make this call directly. */ - if (who != MM_PROC_NR) return(EGENERIC); + /* Only PM may make this call directly. */ + if (who != PM_PROC_NR) return(EGENERIC); /* The array of FD_CLOEXEC bits is in the fp_cloexec bit map. */ fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */ @@ -279,8 +279,8 @@ PUBLIC int do_exit() register struct inode *rip; dev_t dev; - /* Only MM may do the EXIT call directly. */ - if (who != MM_PROC_NR) return(EGENERIC); + /* Only PM may do the EXIT call directly. */ + if (who != PM_PROC_NR) return(EGENERIC); /* Nevertheless, pretend that the call came from the user. */ fp = &fproc[m_in.slot1]; /* get_filp() needs 'fp' */ @@ -343,8 +343,8 @@ PUBLIC int do_set() register struct fproc *tfp; - /* Only MM may make this call directly. */ - if (who != MM_PROC_NR) return(EGENERIC); + /* Only PM may make this call directly. */ + if (who != PM_PROC_NR) return(EGENERIC); tfp = &fproc[m_in.slot1]; if (call_nr == SETUID) { diff --git a/servers/fs/pipe.c b/servers/fs/pipe.c index 9262620c7..f805ba782 100644 --- a/servers/fs/pipe.c +++ b/servers/fs/pipe.c @@ -267,7 +267,7 @@ PUBLIC int do_unpause() dev_t dev; message mess; - if (who > MM_PROC_NR) return(EPERM); + if (who > PM_PROC_NR) return(EPERM); proc_nr = m_in.pro; if (proc_nr < 0 || proc_nr >= NR_PROCS) panic("unpause err 1", proc_nr); rfp = &fproc[proc_nr]; diff --git a/servers/fs/read.c b/servers/fs/read.c index 8239b98b7..b44a96030 100644 --- a/servers/fs/read.c +++ b/servers/fs/read.c @@ -54,7 +54,7 @@ int rw_flag; /* READING or WRITING */ int block_size; /* MM loads segments by putting funny things in upper 10 bits of 'fd'. */ - if (who == MM_PROC_NR && (m_in.fd & (~BYTE)) ) { + if (who == PM_PROC_NR && (m_in.fd & (~BYTE)) ) { usr = m_in.fd >> 7; seg = (m_in.fd >> 5) & 03; m_in.fd &= 037; /* get rid of user and segment bits */ diff --git a/servers/fs/stadir.c b/servers/fs/stadir.c index ac534b38d..bb029ed69 100644 --- a/servers/fs/stadir.c +++ b/servers/fs/stadir.c @@ -36,7 +36,7 @@ PUBLIC int do_chdir() int r; register struct fproc *rfp; - if (who == MM_PROC_NR) { + if (who == PM_PROC_NR) { rfp = &fproc[m_in.slot1]; put_inode(fp->fp_rootdir); dup_inode(fp->fp_rootdir = rfp->fp_rootdir); diff --git a/servers/inet/sr.c b/servers/inet/sr.c index 2f809cc91..f8eb38f0b 100644 --- a/servers/inet/sr.c +++ b/servers/inet/sr.c @@ -107,6 +107,7 @@ FORWARD _PROTOTYPE ( int cp_b2u, (acc_t *acc_ptr, int proc, char *dest) ); PRIVATE sr_fd_t sr_fd_table[FD_NR]; PRIVATE mq_t *repl_queue, *repl_queue_tail; PRIVATE cpvec_t cpvec[CPVEC_NR]; +PRIVATE struct vir_cp_req vir_cp_req[CPVEC_NR]; PUBLIC void sr_init() { @@ -650,9 +651,13 @@ int size; { size= (vir_bytes)acc->acc_length; - cpvec[i].cpv_src= (vir_bytes)src; - cpvec[i].cpv_dst= (vir_bytes)ptr2acc_data(acc); - cpvec[i].cpv_size= size; + vir_cp_req[i].count= size; + vir_cp_req[i].src.proc_nr = proc; + vir_cp_req[i].src.segment = D; + vir_cp_req[i].src.offset = (vir_bytes) src; + vir_cp_req[i].dst.proc_nr = this_proc; + vir_cp_req[i].dst.segment = D; + vir_cp_req[i].dst.offset = (vir_bytes) ptr2acc_data(acc); src += size; acc= acc->acc_next; @@ -660,11 +665,9 @@ int size; if (i == CPVEC_NR || acc == NULL) { - mess.m_type= SYS_VCOPY; - mess.m1_i1= proc; - mess.m1_i2= this_proc; - mess.m1_i3= i; - mess.m1_p1= (char *)cpvec; + mess.m_type= SYS_VIRVCOPY; + mess.VCP_VEC_SIZE = i; + mess.VCP_VEC_ADDR = (char *) vir_cp_req; if (sendrec(SYSTASK, &mess) <0) ip_panic(("unable to sendrec")); if (mess.m_type <0) @@ -697,9 +700,13 @@ char *dest; if (size) { - cpvec[i].cpv_src= (vir_bytes)ptr2acc_data(acc); - cpvec[i].cpv_dst= (vir_bytes)dest; - cpvec[i].cpv_size= size; + vir_cp_req[i].src.proc_nr = this_proc; + vir_cp_req[i].src.segment = D; + vir_cp_req[i].src.offset= (vir_bytes)ptr2acc_data(acc); + vir_cp_req[i].dst.proc_nr = proc; + vir_cp_req[i].dst.segment = D; + vir_cp_req[i].dst.offset= (vir_bytes)dest; + vir_cp_req[i].count= size; i++; } @@ -708,11 +715,9 @@ char *dest; if (i == CPVEC_NR || acc == NULL) { - mess.m_type= SYS_VCOPY; - mess.m1_i1= this_proc; - mess.m1_i2= proc; - mess.m1_i3= i; - mess.m1_p1= (char *)cpvec; + mess.m_type= SYS_VIRVCOPY; + mess.VCP_VEC_SIZE = i; + mess.VCP_VEC_ADDR = (char *) vir_cp_req; if (sendrec(SYSTASK, &mess) <0) ip_panic(("unable to sendrec")); if (mess.m_type <0) @@ -746,7 +751,7 @@ assert(!m_cancel); m= m->mq_next; continue; } -assert(m->mq_mess.m_source != MM_PROC_NR); +assert(m->mq_mess.m_source != PM_PROC_NR); assert(m->mq_mess.m_type == REVIVE); result= send(m->mq_mess.m_source, &m->mq_mess); if (result != OK) @@ -758,7 +763,7 @@ assert(m->mq_mess.m_type == REVIVE); repl_queue= NULL; if (m_cancel) { -assert(m_cancel->mq_mess.m_source != MM_PROC_NR); +assert(m_cancel->mq_mess.m_source != PM_PROC_NR); assert(m_cancel->mq_mess.m_type == REVIVE); result= send(m_cancel->mq_mess.m_source, &m_cancel->mq_mess); if (result != OK) diff --git a/servers/is/dmp.c b/servers/is/dmp.c index 80276338b..113f72481 100644 --- a/servers/is/dmp.c +++ b/servers/is/dmp.c @@ -35,7 +35,7 @@ FORWARD _PROTOTYPE( void kmessages_dmp, (void) ); FORWARD _PROTOTYPE( void diagnostics_dmp, (void) ); FORWARD _PROTOTYPE( void sched_dmp, (void) ); FORWARD _PROTOTYPE( void monparams_dmp, (void) ); -FORWARD _PROTOTYPE( void kenviron_dmp, (void) ); +FORWARD _PROTOTYPE( void kenv_dmp, (void) ); FORWARD _PROTOTYPE( void memchunks_dmp, (void) ); /* Some global data that is shared among several dumping procedures. @@ -62,7 +62,7 @@ PUBLIC int do_fkey_pressed(message *m) case F6: irqtab_dmp(); break; case F7: kmessages_dmp(); break; case F9: diagnostics_dmp(); break; - case F10: kenviron_dmp(); break; + case F10: kenv_dmp(); break; case F11: memchunks_dmp(); break; case F12: sched_dmp(); break; default: @@ -253,7 +253,7 @@ PRIVATE void sched_dmp() { struct proc *rdy_head[NR_SCHED_QUEUES]; char *types[] = {"task","higher","high","normal","low","lower","user","idle"}; - struct kenviron kenviron; + struct kinfo kinfo; register struct proc *rp; vir_bytes ptr_diff; int r; @@ -264,13 +264,13 @@ PRIVATE void sched_dmp() return; } /* Then obtain kernel addresses to correct pointer information. */ - if ((r = sys_getkenviron(&kenviron)) != OK) { + if ((r = sys_getkinfo(&kinfo)) != OK) { report("warning: couldn't get kernel addresses", r); return; } /* Update all pointers. Nasty pointer algorithmic ... */ - ptr_diff = (vir_bytes) proc - (vir_bytes) kenviron.proc_addr; + ptr_diff = (vir_bytes) proc - (vir_bytes) kinfo.proc_addr; for (r=0;r 0) { count = MIN(bytes, (phys_bytes) sizeof(zero)); - if (sys_copy(MM_PROC_NR, D, (phys_bytes) zero, - ABS, 0, base, count) != OK) { + if (sys_physcopy(PM_PROC_NR, D, (phys_bytes) zero, + NONE, PHYS_SEG, base, count) != OK) { panic("new_mem can't zero", NO_NUM); } base += count; diff --git a/servers/mm/forkexit.c b/servers/mm/forkexit.c index c791328c0..3de71280d 100644 --- a/servers/mm/forkexit.c +++ b/servers/mm/forkexit.c @@ -64,7 +64,7 @@ PUBLIC int do_fork() /* Create a copy of the parent's core image for the child. */ child_abs = (phys_bytes) child_base << CLICK_SHIFT; parent_abs = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT; - i = sys_physcopy(parent_abs, child_abs, prog_bytes); + i = sys_abscopy(parent_abs, child_abs, prog_bytes); if (i < 0) panic("do_fork can't copy", i); /* Find a slot in 'mproc' for the child process. A slot must exist. */ diff --git a/servers/mm/main.c b/servers/mm/main.c index 9dde099c0..7b7277323 100644 --- a/servers/mm/main.c +++ b/servers/mm/main.c @@ -91,7 +91,7 @@ PRIVATE void get_work() /* Process slot of caller. Misuse MM's own process slot if the kernel is * calling. The can happen in case of pending kernel signals. */ - mp = &mproc[who < 0 ? MM_PROC_NR : who]; + mp = &mproc[who < 0 ? PM_PROC_NR : who]; } diff --git a/servers/mm/misc.c b/servers/mm/misc.c index 1331a44ba..cbf1cb7a4 100644 --- a/servers/mm/misc.c +++ b/servers/mm/misc.c @@ -49,7 +49,7 @@ PUBLIC int do_reboot() case RBT_MONITOR: if (m_in.reboot_size >= sizeof(monitor_code)) return(EINVAL); if (sys_datacopy(who, (vir_bytes) m_in.reboot_code, - MM_PROC_NR, (vir_bytes) monitor_code, + PM_PROC_NR, (vir_bytes) monitor_code, (phys_bytes) (m_in.reboot_size+1)) != OK) return(EFAULT); if (monitor_code[m_in.reboot_size] != 0) return(EINVAL); break; @@ -60,7 +60,7 @@ PUBLIC int do_reboot() check_sig(-1, SIGKILL); /* kill all processes except init */ tell_fs(REBOOT,0,0,0); /* tell FS to prepare for shutdown */ - sys_abort(m_in.reboot_flag, MM_PROC_NR, monitor_code, m_in.reboot_size); + sys_abort(m_in.reboot_flag, PM_PROC_NR, monitor_code, m_in.reboot_size); sys_exit(0); } @@ -85,6 +85,9 @@ PUBLIC int do_svrctl() /* Binary compatibility check. */ if (req == SYSGETENV) { +#if DEAD_CODE + printf("SYSGETENV by %d (fix!)\n", who); +#endif req = MMGETPARAM; } @@ -179,7 +182,7 @@ PUBLIC int do_svrctl() if (mp->mp_effuid != SUPER_USER) return(EPERM); if (sys_datacopy(who, (phys_bytes) ptr, - MM_PROC_NR, (phys_bytes) &swapon, + PM_PROC_NR, (phys_bytes) &swapon, (phys_bytes) sizeof(swapon)) != OK) return(EFAULT); return(swap_on(swapon.file, swapon.offset, swapon.size)); } diff --git a/servers/mm/signal.c b/servers/mm/signal.c index dbe39e46b..96e7b054e 100644 --- a/servers/mm/signal.c +++ b/servers/mm/signal.c @@ -53,7 +53,7 @@ PUBLIC int do_sigaction() if (m_in.sig_nr < 1 || m_in.sig_nr > _NSIG) return (EINVAL); svp = &mp->mp_sigact[m_in.sig_nr]; if ((struct sigaction *) m_in.sig_osa != (struct sigaction *) NULL) { - r = sys_datacopy(MM_PROC_NR,(vir_bytes) svp, + r = sys_datacopy(PM_PROC_NR,(vir_bytes) svp, who, (vir_bytes) m_in.sig_osa, (phys_bytes) sizeof(svec)); if (r != OK) return(r); } @@ -63,7 +63,7 @@ PUBLIC int do_sigaction() /* Read in the sigaction structure. */ r = sys_datacopy(who, (vir_bytes) m_in.sig_nsa, - MM_PROC_NR, (vir_bytes) &svec, (phys_bytes) sizeof(svec)); + PM_PROC_NR, (vir_bytes) &svec, (phys_bytes) sizeof(svec)); if (r != OK) return(r); if (svec.sa_handler == SIG_IGN) { @@ -433,7 +433,7 @@ int signo; /* signal to send to process (1 to _NSIG) */ rmp->mp_sigact[signo].sa_handler = SIG_DFL; } - sys_sendsig(slot, &sm); + sys_sigsend(slot, &sm); sigdelset(&rmp->mp_sigpending, signo); /* If process is hanging on PAUSE, WAIT, SIGSUSPEND, tty, pipe, etc., * release it. diff --git a/servers/mm/utility.c b/servers/mm/utility.c index be37552c2..e82f4f9bd 100644 --- a/servers/mm/utility.c +++ b/servers/mm/utility.c @@ -39,12 +39,12 @@ int mask; /* R_BIT, W_BIT, or X_BIT */ if (access(name_buf, mask) < 0) return(-errno); /* The file is accessible but might not be readable. Make it readable. */ - tell_fs(SETUID, MM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER); + tell_fs(SETUID, PM_PROC_NR, (int) SUPER_USER, (int) SUPER_USER); /* Open the file and fstat it. Restore the ids early to handle errors. */ fd = open(name_buf, O_RDONLY | O_NONBLOCK); save_errno = errno; /* open might fail, e.g. from ENFILE */ - tell_fs(SETUID, MM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid); + tell_fs(SETUID, PM_PROC_NR, (int) mp->mp_effuid, (int) mp->mp_effuid); if (fd < 0) return(-save_errno); if (fstat(fd, s_buf) < 0) panic("allowed: fstat failed", NO_NUM);