@echo "Master Makefile for MINIX commands and utilities." >&2
@echo "Usage:" >&2
@echo " make world # Compile everything (libraries & commands)" >&2
+ @echo " make includes # Install include files from src/" >&2
@echo " make libraries # Compile and install libraries" >&2
@echo " make commands # Compile commands, but don't install" >&2
@echo " make install # Compile and install commands" >&2
# 'make install' target.
world: etcfiles includes libraries commands install
+includes:
+ cd include && $(MAKE) install
+
libraries:
cd lib && $(MAKE) install
etcfiles::
cd etc && $(MAKE) install
-includes::
- cd include && $(MAKE) install
-
all install clean::
cd boot && $(MAKE) $@
test ! -f commands/Makefile || { cd commands && $(MAKE) $@; }
cat >&2 <<EOF
Usage: $0 [-n] key ...
Where key is one of the following:
- ram mem kmem null # One of these makes all these memory devices
+ ram mem kmem null boot random zero # One of these makes all these memory devices
fd0 fd1 ... # Floppy devices for drive 0, 1, ...
fd0p0 fd1p0 ... # Make floppy partitions fd0p[0-3], fd1p[0-3], ...
c0d0 c0d1 ... # Make disks c0d0, c0d1, ...
esac
case $dev in
- ram|mem|kmem|null)
+ ram|mem|kmem|null|boot|random|urandom|zero)
# Memory devices.
#
$e mknod ram b 1 0; $e chmod 600 ram
$e mknod boot b 1 4; $e chmod 600 ram
$e mknod random c 1 5; $e chmod 644 random
$e mknod urandom c 1 5; $e chmod 644 urandom
- $e chgrp kmem ram mem kmem null boot random urandom
+ $e mknod zero c 1 6; $e chmod 644 zero
+ $e chgrp kmem ram mem kmem null boot random urandom zero
;;
fd[0-3])
# Floppy disk drive n.
-rw-r--r-- root operator /etc/termcap
-rw-r--r-- root operator /etc/ttytab
-rw-r--r-- root operator /etc/utmp
-dr-xr-xr-x root operator /fd0
-dr-xr-xr-x root operator /fd1
dr-xr-xr-x root operator /mnt
dr-xr-xr-x root operator /root
drwxrwxrwx root operator /tmp
unsigned state; /* drive state: deaf, initialized, dead */
unsigned base; /* base register of the register file */
unsigned irq; /* interrupt request line */
+ int irq_hook_id; /* id of irq hook at the kernel */
unsigned lcylinders; /* logical number of cylinders (BIOS) */
unsigned lheads; /* logical number of heads */
unsigned lsectors; /* logical number of sectors per track */
/* Register function key for debugging dumps. */
fkey_enable(SF8);
-#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);
/* 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);
+ if ((s=sys_irqsetpolicy(wn->irq, IRQ_REENABLE, &wn->irq_hook_id)) != OK)
+ server_panic("AT", "coudn't set IRQ policy", s);
+ if ((s=sys_irqenable(&wn->irq_hook_id)) != OK)
+ server_panic("AT", "coudn't enable IRQ line", s);
return(OK);
}
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 {
struct device fl_part[NR_PARTITIONS]; /* partition's base & size */
} floppy[NR_DRIVES];
+PRIVATE int irq_hook_id; /* id of irq hook at the kernel */
PRIVATE int motor_status; /* bitmap of current motor status */
PRIVATE int need_reset; /* set to 1 when controller must be reset */
PRIVATE unsigned f_drive; /* selected drive */
PRIVATE struct density *prev_dp;/* previous density parameters */
PRIVATE unsigned f_sectors; /* equal to f_dp->secpt (needed a lot) */
PRIVATE u16_t f_busy; /* BSY_IDLE, BSY_IO, BSY_WAKEN */
-#if DEAD_CODE
-PRIVATE irq_hook_t f_hook; /* interrupt hook */
-#endif
PRIVATE struct device *f_dv; /* device's base and size */
PRIVATE struct disk_parameter_s fmt_param; /* parameters for format */
PRIVATE u8_t f_results[MAX_RESULTS];/* the controller can give lots of output */
FORWARD _PROTOTYPE( int seek, (void) );
FORWARD _PROTOTYPE( int fdc_transfer, (int opcode) );
FORWARD _PROTOTYPE( int fdc_results, (void) );
-#if DEAD_CODE
-FORWARD _PROTOTYPE( int f_handler, (irq_hook_t *hook) );
-#endif
FORWARD _PROTOTYPE( int fdc_command, (u8_t *cmd, int len) );
FORWARD _PROTOTYPE( void fdc_out, (int val) );
FORWARD _PROTOTYPE( int recalibrate, (void) );
/* Initialize the floppy structure and the timers. */
struct floppy *fp;
- int irqs;
+ int s;
f_next_timeout = TMR_NEVER;
tmr_inittimer(&f_tmr_timeout);
}
/* Set IRQ policy, only request notifications. */
- if ((irqs=sys_irqsetpolicy(FLOPPY_IRQ, 0, SELF, 0, 0, 0 )) != OK)
- server_panic("FLOPPY", "Couldn't set IRQ policy", irqs);
- if ((irqs=sys_irqenable(FLOPPY_IRQ)) != OK)
- server_panic("FLOPPY", "Couldn't enable IRQs", irqs);
+ if ((s=sys_irqsetpolicy(FLOPPY_IRQ, 0, &irq_hook_id )) != OK)
+ server_panic("FLOPPY", "Couldn't set IRQ policy", s);
+ if ((s=sys_irqenable(&irq_hook_id)) != OK)
+ server_panic("FLOPPY", "Couldn't enable IRQs", s);
printf("FLOPPY: user-level floppy disk driver initialized\n");
driver_task(&f_dtab);
int s, result_nr, status;
static int timeout; /* must be static if not cancelled */
- int irqs;
/* Extract bytes from FDC until it says it has no more. The loop is
* really an outer loop on result_nr and an inner loop on status.
continue;
}
if (status == MASTER) { /* all read */
- if ((irqs=sys_irqenable(FLOPPY_IRQ)) != OK)
- server_panic("FLOPPY", "Couldn't enable IRQs", irqs);
+ if ((s=sys_irqenable(&irq_hook_id)) != OK)
+ server_panic("FLOPPY", "Couldn't enable IRQs", s);
/* Disabling the alarm is not needed, because a static flag
* is used and a leftover timeout cannot do any harm. It is
} while (! timeout);
need_reset = TRUE; /* controller chip must be reset */
- if ((irqs=sys_irqenable(FLOPPY_IRQ)) != OK)
- server_panic("FLOPPY", "Couldn't enable IRQs", irqs);
+ if ((s=sys_irqenable(&irq_hook_id)) != OK)
+ server_panic("FLOPPY", "Couldn't enable IRQs", s);
return(ERR_STATUS);
}
-#if DEAD_CODE
-/*==========================================================================*
- * f_handler *
- *==========================================================================*/
-PRIVATE int f_handler(hook)
-irq_hook_t *hook;
-{
-/* FDC interrupt, send message to floppy task. */
-#if DEAD_CODE
- f_busy = BSY_IDLE;
-#endif
- notify(FLOPPY, HARD_INT);
- return 0;
-}
-#endif
-
/*===========================================================================*
* fdc_command *
caller = mess.m_source;
proc_nr = mess.PROC_NR;
-#if DEAD_CODE /* drivers, like TTY can have any number */
- /* Check if legitimate caller: FS or a task. */
- if (caller != FS_PROC_NR && caller >= 0) {
- printf("%s: got message from %d\n", (*dp->dr_name)(), caller);
- continue;
- }
-#endif
-
/* Now carry out the work. */
switch(mess.m_type) {
case DEV_OPEN: r = (*dp->dr_open)(dp, &mess); break;
if (OK != sys_datacopy(mp->m_source, (vir_bytes) mp->ADDRESS,
SELF, (vir_bytes) iovec, iovec_size))
server_panic((*dp->dr_name)(),"bad I/O vector by", mp->m_source);
-#if DEAD_CODE
- sys_umap(mp->m_source, (vir_bytes) mp->ADDRESS,
- iovec_size, &user_iovec_phys);
- if (user_iovec_phys == 0)
- server_panic((*dp->dr_name)(),"bad I/O vector by", mp->m_source);
- iovec_phys = vir2phys(iovec);
- phys_copy(user_iovec_phys, iovec_phys, (phys_bytes) iovec_size);
-#endif
iov = iovec;
}
if (mp->m_source >= 0) {
sys_datacopy(SELF, (vir_bytes) iovec,
mp->m_source, (vir_bytes) mp->ADDRESS, iovec_size);
-#if DEAD_CODE
- phys_copy(iovec_phys, user_iovec_phys, (phys_bytes) iovec_size);
-#endif
}
return(r);
}
/* Decode the message parameters. */
if ((dv = (*dp->dr_prepare)(mp->DEVICE)) == NIL_DEV) return(ENXIO);
-#if DEAD_CODE
- sys_umap(mp->PROC_NR, D, (vir_bytes) mp->ADDRESS, sizeof(entry), &user_phys);
- if (user_phys == 0) return(EFAULT);
- entry_phys = vir2phys(&entry);
-#endif
-
if (mp->REQUEST == DIOCSETP) {
/* Copy just this one partition table entry. */
-#if DEAD_CODE
- phys_copy(user_phys, entry_phys, (phys_bytes) sizeof(entry));
-#endif
if (OK != (s=sys_datacopy(mp->PROC_NR, (vir_bytes) mp->ADDRESS,
SELF, (vir_bytes) &entry, sizeof(entry))))
return s;
entry.base = dv->dv_base;
entry.size = dv->dv_size;
(*dp->dr_geometry)(&entry);
-#if DEAD_CODE
- phys_copy(entry_phys, user_phys, (phys_bytes) sizeof(entry));
-#endif
if (OK != (s=sys_datacopy(SELF, (vir_bytes) &entry,
mp->PROC_NR, (vir_bytes) mp->ADDRESS, sizeof(entry))))
return s;
PRIVATE int user_left; /* bytes of output left in user buf */
PRIVATE vir_bytes user_vir; /* address of remainder of user buf */
PRIVATE int writing; /* nonzero while write is in progress */
+PRIVATE int irq_hook_id; /* id of irq hook at kernel */
FORWARD _PROTOTYPE( void do_cancel, (message *m_ptr) );
FORWARD _PROTOTYPE( void output_done, (void) );
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
+ /* Get the base port for first printer. */
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 */
sys_outb(port_base + 2, SELECT);
- sys_irqsetpolicy(PRINTER_IRQ, SELF, 0, 0, 0, 0);
- sys_irqenable(PRINTER_IRQ);
+ sys_irqsetpolicy(PRINTER_IRQ, 0, &irq_hook_id);
+ sys_irqenable(&irq_hook_id);
}
* interrupt status does not affect the printer.
*/
sys_outb(port_base + 2, SELECT);
- sys_irqenable(PRINTER_IRQ);
+ sys_irqenable(&irq_hook_id);
return;
}
* pr_restart, since they are not synchronized with printer
* interrupts. It may happen after a spurious interrupt.
*/
- sys_irqenable(PRINTER_IRQ);
+ sys_irqenable(&irq_hook_id);
return;
}
if ((status & STATUS_MASK) == NORMAL_STATUS) {
/* Error. This would be better ignored (treat as busy). */
done_status = status;
output_done();
- sys_irqenable(PRINTER_IRQ);
+ sys_irqenable(&irq_hook_id);
return;
}
}
/* Finished printing chunk OK. */
done_status = OK;
output_done();
- sys_irqenable(PRINTER_IRQ);
+ sys_irqenable(&irq_hook_id);
}
$m/syslib.h $s/types.h \
$m/utils.h $m/serverassert.h $m/devio.h
-tty.o: $a
-console.o: $a
+tty.o: tty.h $a
+console.o: tty.h $a
vidcopy.o: # nothing
-keyboard.o: $a
-rs232.o: $a $i/termios.h $i/signal.h
+keyboard.o: tty.h $a
+rs232.o: tty.h $a $i/termios.h $i/signal.h
{
/* Initialize the keyboard driver. */
static int count = 0;
+ int irq_hook_id;
int i;
tp->tty_devread = kb_read; /* input function */
}
/* Set interrupt handler and enable keyboard IRQ. */
- if ((i=sys_irqsetpolicy(KEYBOARD_IRQ, IRQ_REENABLE, SELF, 0, 0, 0)) != OK)
+ if ((i=sys_irqsetpolicy(KEYBOARD_IRQ, IRQ_REENABLE, &irq_hook_id)) != OK)
server_panic("TTY", "Couldn't set keyboard IRQ policy", i);
- if ((i=sys_irqenable(KEYBOARD_IRQ)) != OK)
+ if ((i=sys_irqenable(&irq_hook_id)) != OK)
server_panic("TTY", "Couldn't enable keyboard IRQs", i);
}
}
{
/* A process wants to read from a terminal. */
int r, status;
+ phys_bytes phys_addr;
/* Check if there is already a process hanging in a read, check if the
* parameters are correct, do I/O.
} else
if (m_ptr->COUNT <= 0) {
r = EINVAL;
-#if DEAD_CODE /* to be replaced by check on tp->tty_instatus !!! */
} else
- if (numap_local(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS, m_ptr->COUNT) == 0) {
+ if (sys_umap(m_ptr->PROC_NR, D, (vir_bytes) m_ptr->ADDRESS, m_ptr->COUNT,
+ &phys_addr) != OK) {
r = EFAULT;
-#endif
} else {
/* Copy information from the message to the tty struct. */
tp->tty_inrepcode = TASK_REPLY;
}
/* Anything waiting in the input buffer? Clear it out... */
- tp->tty_instatus = OK; /* start with OK, check later */
in_transfer(tp);
/* ...then go back for more. */
- if (tp->tty_instatus == OK)
- handle_events(tp);
+ handle_events(tp);
if (tp->tty_inleft == 0)
return; /* already done */
/* There were no bytes in the input queue available, so either suspend
* the caller or break off the read if nonblocking.
*/
- if (tp->tty_instatus != OK) { /* error occurred */
- r = tp->tty_instatus;
- tp->tty_inleft = tp->tty_incum = 0; /* cancel the read */
- }
if (m_ptr->TTY_FLAGS & O_NONBLOCK) {
r = EAGAIN; /* cancel the read */
tp->tty_inleft = tp->tty_incum = 0;
{
/* A process wants to write on a terminal. */
int r;
+ phys_bytes phys_addr;
/* Check if there is already a process hanging in a write, check if the
* parameters are correct, do I/O.
} else
if (m_ptr->COUNT <= 0) {
r = EINVAL;
-#if DEAD_CODE /* to be replaced by check on tp->tty_outstatus (!!!) */
} else
- if (numap_local(m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS, m_ptr->COUNT) == 0) {
+ if (sys_umap(m_ptr->PROC_NR, D, (vir_bytes) m_ptr->ADDRESS, m_ptr->COUNT,
+ &phys_addr) != OK) {
r = EFAULT;
-#endif
} else {
/* Copy message parameters to the tty structure. */
tp->tty_outrepcode = TASK_REPLY;
tp->tty_outleft = m_ptr->COUNT;
/* Try to write. */
- tp->tty_outstatus = OK; /* start with OK, check later */
handle_events(tp);
if (tp->tty_outleft == 0) return; /* already done */
/* None or not all the bytes could be written, so either suspend the
* caller or break off the write if nonblocking.
*/
- if (tp->tty_outstatus != OK) { /* error occurred */
- r = tp->tty_outstatus;
- tp->tty_outleft = tp->tty_outcum = 0; /* cancel the write */
- }
- else if (m_ptr->TTY_FLAGS & O_NONBLOCK) { /* cancel the write */
+ if (m_ptr->TTY_FLAGS & O_NONBLOCK) { /* cancel the write */
r = tp->tty_outcum > 0 ? tp->tty_outcum : EAGAIN;
tp->tty_outleft = tp->tty_outcum = 0;
} else {
vir_bytes tty_in_vir; /* virtual address where data is to go */
int tty_inleft; /* how many chars are still needed */
int tty_incum; /* # chars input so far */
- int tty_instatus; /* status of last sys_vircopy() action */
char tty_outrepcode; /* reply code, TASK_REPLY or REVIVE */
char tty_outcaller; /* process that made the call (usually FS) */
char tty_outproc; /* process that wants to write to tty */
vir_bytes tty_out_vir; /* virtual address where data comes from */
int tty_outleft; /* # chars yet to be output */
int tty_outcum; /* # chars output so far */
- int tty_outstatus; /* status of last sys_vircopy() action */
char tty_iocaller; /* process that made the call (usually FS) */
char tty_ioproc; /* process that wants to do an ioctl */
int tty_ioreq; /* ioctl request code */
* blocking notifications are delivered. The lowest numbers go first. The
* offset are used for the per-process notification bit maps.
*/
-#define NR_NOTIFICATIONS 5 /* max. is # bits in notify_mask_t */
+#define NR_NOTIFICATIONS 5 /* number of bits in notify_mask_t */
# define NOTIFICATION 333 /* offset for notification types */
# define HARD_INT NOTIFICATION + 0 /* hardware interrupt */
# define SYN_ALARM NOTIFICATION + 1 /* synchronous alarm */
# define KMEM_DEV 2 /* minor device for /dev/kmem */
# 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 RANDOM_DEV 5 /* minor device for /dev/(u)random */
+# define URANDOM_DEV RANDOM_DEV
# define ZERO_DEV 6 /* minor device for /dev/zero */
/* Full device numbers that are special to the boot monitor and FS. */
# define IRQ_DISABLE 3 /* disable interrupts */
#define IRQ_VECTOR m5_c2 /* irq vector */
#define IRQ_POLICY m5_i1 /* options for IRQCTL request */
-# define IRQ_READ_PORT 0x001 /* read port and return value */
-# define IRQ_WRITE_PORT 0x002 /* write given value to port */
-# define IRQ_STROBE 0x010 /* write masked value back to port */
-# define IRQ_ECHO_VAL 0x020 /* write value read back to port */
-# define IRQ_REENABLE 0x040 /* reenable IRQ line after interrupt */
+# define IRQ_REENABLE 0x001 /* reenable IRQ line after interrupt */
# define IRQ_BYTE 0x100 /* byte values */
# define IRQ_WORD 0x200 /* word values */
# define IRQ_LONG 0x400 /* long values */
#define IRQ_PROC_NR m5_i2 /* process number, SELF, NONE */
-#define IRQ_PORT m5_l1 /* port to read or write */
-#define IRQ_VIR_ADDR m5_l2 /* address to store value read */
-#define IRQ_MASK_VAL m5_l3 /* value or strobe mask */
+#define IRQ_HOOK_ID m5_l3 /* id of irq hook at kernel */
/* Names of message field and paramaters for SYS_EXIT request. */
#define EXIT_STATUS m2_i1 /* zero for normal exit, non-zero else */
# define GET_PROCNR 3 /* find nr of process with name */
# define GET_MONPARAMS 4 /* get monitor parameters */
# define GET_KENV 5 /* get kernel environment string */
-# define GET_IRQTAB 6 /* get the IRQ table */
+# define GET_IRQHOOKS 6 /* get the IRQ table */
# define GET_KMESSAGES 7 /* get kernel messages */
# define GET_MEMCHUNKS 8 /* get base+size of mem chunks */
# define GET_KADDRESSES 9 /* get various kernel addresses */
_PROTOTYPE(int sys_syncalrm, (int proc_nr, clock_t exp_time, int abs_time) );
/* Shorthands for sys_irqctl() system call. */
-#define sys_irqdisable(irq_vec) \
- sys_irqctl(IRQ_DISABLE, irq_vec, 0, 0, 0, 0, 0)
-#define sys_irqenable(irq_vec) \
- sys_irqctl(IRQ_ENABLE, irq_vec, 0, 0, 0, 0, 0)
-#define sys_irqsetpolicy(irq_vec, policy, proc_nr, port, val_ptr, mask_val) \
- sys_irqctl(IRQ_SETPOLICY, irq_vec, policy, proc_nr, port, val_ptr, mask_val)
+#define sys_irqdisable(hook_id) \
+ sys_irqctl(IRQ_DISABLE, 0, 0, hook_id)
+#define sys_irqenable(hook_id) \
+ sys_irqctl(IRQ_ENABLE, 0, 0, hook_id)
+#define sys_irqsetpolicy(irq_vec, policy, hook_id) \
+ sys_irqctl(IRQ_SETPOLICY, irq_vec, policy, hook_id)
_PROTOTYPE ( int sys_irqctl, (int request, int irq_vec, int policy,
- int proc_nr, long port, void *val_ptr, long mask_val) );
+ int *irq_hook_id) );
/* Shorthands for sys_vircopy() and sys_physcopy() system calls. */
#define sys_biosin(bios_vir, dst_vir, bytes) \
#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)
#define sys_getimage(dst) sys_getinfo(GET_IMAGE, dst, 0,0,0)
-#define sys_getirqtab(dst) sys_getinfo(GET_IRQTAB, dst, 0,0,0)
+#define sys_getirqhooks(dst) sys_getinfo(GET_IRQHOOKS, dst, 0,0,0)
#define sys_getmemchunks(dst) sys_getinfo(GET_MEMCHUNKS, dst, 0,0,0)
#define sys_getmonparams(v,vl) sys_getinfo(GET_MONPARAMS, v,vl, 0,0)
#define sys_getkenv(k,kl,v,vl) sys_getinfo(GET_KENV, v,vl, k,kl)
# What to make.
kernel build: $(HEAD) $(OBJS) $(SYS)
- $(LD) $(LDFLAGS) -o $@ $(HEAD) $(OBJS) $(SYS) $(CLOCK) $(LIBS)
+ $(LD) $(LDFLAGS) -o kernel $(HEAD) $(OBJS) $(SYS) $(CLOCK) $(LIBS)
install -S 0 $@
$(SYS):
system/system.a: proc.h protect.h system.h sendmask.h
system/system.a: $s/ptrace.h $s/sigcontext.h
system/system.a: $i/signal.h $i/unistd.h
-system/system.a: system/alarms.c
+system/system.a: system/clock.c
system/system.a: system/copying.c
system/system.a: system/devio.c
system/system.a: system/irqctl.c
/* How many elements in vector of virtual copy requests. */
#define VCOPY_VEC_SIZE 16
+/* How many IRQ hooks are there in total. */
+#define NR_IRQ_HOOKS 16
+
/* Program stack words and masks. */
#define INIT_PSW 0x0200 /* initial psw */
#define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */
#if (CHIP == INTEL)
/* 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 */
+EXTERN irq_hook_t irq_hooks[NR_IRQ_HOOKS]; /* hooks for general use */
+EXTERN irq_hook_t *irq_handlers[NR_IRQ_VECTORS];/* list of IRQ handlers */
EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */
EXTERN int irq_use; /* bit map of all in-use irq's */
if ((unsigned) irq >= NR_IRQ_VECTORS)
panic("invalid call to put_irq_handler", irq);
- line = &irq_hooks[irq];
+ line = &irq_handlers[irq];
id = 1;
while (*line != NULL) {
if (hook == *line) return; /* extra initialization */
#include "proc.h"
#include "sendmask.h"
-/* Prototype declarations for PRIVATE function. */
-FORWARD _PROTOTYPE( void announce, (void)); /* display user message */
+/* Prototype declarations for PRIVATE functions. */
+FORWARD _PROTOTYPE( void announce, (void));
+FORWARD _PROTOTYPE( void shutdown, (struct timer *tp));
+
#define STOP_TICKS (5*HZ) /* time allowed to stop */
/*===========================================================================*
shutdown(&shutdown_timer); /* TTY isn't scheduled */
} else {
kprintf("\nNotifying system services about MINIX shutdown.\n", NO_ARG);
+ kprintf("Known bug: hitting a key before done will hang the monitor.\n", NO_ARG);
stop_sequence(&shutdown_timer);
}
}
/*==========================================================================*
* shutdown *
*==========================================================================*/
-PUBLIC void shutdown(tp)
+PRIVATE void shutdown(tp)
timer_t *tp;
{
/* This function is called from prepare_shutdown or stop_sequence to bring
* down MINIX. How to shutdown is in the argument: RBT_REBOOT, RBT_HALT,
* RBT_RESET.
*/
- int quiet, code;
static u16_t magic = STOP_MEM_CHECK;
int how = tmr_arg(tp)->ta_int;
* panic abort MINIX due to a fatal error
* bad_assertion for debugging
* bad_compare for debugging
- *
- * Changes:
- * Oct 04, 2004 moved panic() to this file (Jorrit N. Herder)
- * Sep 30, 2004 removed mem_init(), env_parse to lib (Jorrit N. Herder)
*/
#include "kernel.h"
outb INT_CTLMASK /* disable the irq */;\
movb al, ENABLE ;\
outb INT_CTL /* reenable master 8259 */;\
- push (_irq_hooks+4*irq) /* irq_hooks[irq] */;\
+ push (_irq_handlers+4*irq) /* irq_handlers[irq] */;\
sti /* enable interrupts */;\
- call _intr_handle /* intr_handle(irq_hooks[irq]) */;\
+ call _intr_handle /* intr_handle(irq_handlers[irq]) */;\
cli /* disable interrupts */;\
pop ecx ;\
cmp (_irq_actids+4*irq), 0 /* interrupt still active? */;\
outb INT2_CTLMASK /* disable the irq */;\
movb al, ENABLE ;\
outb INT_CTL /* reenable master 8259 */;\
- push (_irq_hooks+4*irq) /* irq_hooks[irq] */;\
+ push (_irq_handlers+4*irq) /* irq_handlers[irq] */;\
outb INT2_CTL /* reenable slave 8259 */;\
sti /* enable interrupts */;\
- call _intr_handle /* intr_handle(irq_hooks[irq]) */;\
+ call _intr_handle /* intr_handle(irq_handlers[irq]) */;\
cli /* disable interrupts */;\
pop ecx ;\
cmp (_irq_actids+4*irq), 0 /* interrupt still active? */;\
#define irq_mode_pci(irq) ((void)0)
#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include <minix/utils.h>
INIT_SERVER_ASSERT
PUBLIC void lock_pick_proc()
{
/* Safe gateway to pick_proc() for tasks. */
-
switching = TRUE;
pick_proc();
switching = FALSE;
struct proc *rp; /* this process is now runnable */
{
/* Safe gateway to ready() for tasks. */
-
switching = TRUE;
ready(rp);
switching = FALSE;
struct proc *rp; /* this process is no longer runnable */
{
/* Safe gateway to unready() for tasks. */
-
switching = TRUE;
unready(rp);
switching = FALSE;
PUBLIC void lock_sched()
{
/* Safe gateway to sched() for tasks. */
-
switching = TRUE;
sched();
switching = FALSE;
while ( (rp = held_head) != NIL_PROC);
}
-#if (CHIP == M68000)
-/*==========================================================================*
- * cp_mess *
- *==========================================================================*/
-PRIVATE void cp_mess(src, src_p, src_m, dst_p, dst_m)
-int src; /* sender process */
-register struct proc *src_p; /* source proc entry */
-message *src_m; /* source message */
-register struct proc *dst_p; /* destination proc entry */
-message *dst_m; /* destination buffer */
-{
- /* convert virtual address to physical address */
- /* The caller has already checked if all addresses are within bounds */
-
- src_m = (message *)((char *)src_m + (((phys_bytes)src_p->p_map[D].mem_phys
- - src_p->p_map[D].mem_vir) << CLICK_SHIFT));
- dst_m = (message *)((char *)dst_m + (((phys_bytes)dst_p->p_map[D].mem_phys
- - dst_p->p_map[D].mem_vir) << CLICK_SHIFT));
-
-#ifdef NEEDFSTRUCOPY
- phys_copy(src_m,dst_m,(phys_bytes) sizeof(message));
-#else
- *dst_m = *src_m;
-#endif
- dst_m->m_source = src;
-}
-#endif
unsigned p_pendcount; /* count of pending and unfinished signals */
char p_name[PROC_NAME_LEN]; /* name of the process, including \0 */
-#if ENABLE_MESSAGE_STATS
- int msg_unreplied[NR_TASKS+NR_PROCS];
-#endif
};
/* Guard word for task stacks. */
(char *s1, register const char *s2, register const size_t n));
_PROTOTYPE( unsigned long kstrtoul,
(const char *string, char ** const end, int base) );
-
-/* kprintf.c */
#define NO_ARG 0
#define karg(arg) (karg_t) (arg)
_PROTOTYPE( void kprintf, (const char *fmt, karg_t arg) );
_PROTOTYPE( void main, (void) );
_PROTOTYPE( void prepare_shutdown, (int how) );
_PROTOTYPE( void stop_sequence, (struct timer *tp) );
-_PROTOTYPE( void shutdown, (struct timer *tp) );
/* misc.c */
_PROTOTYPE( void panic, (_CONST char *s, int n) );
_PROTOTYPE( void lock_sched, (void) );
_PROTOTYPE( void lock_unready, (struct proc *rp) );
-/* sb16_dsp.c, sb16_mixer.c */
-_PROTOTYPE( void sb16dsp_task, (void) );
-_PROTOTYPE( void sb16mix_task, (void) );
-
/* start.c */
_PROTOTYPE( void cstart, (U16_t cs, U16_t ds, U16_t mds,
U16_t parmoff, U16_t parmsize) );
vir_bytes vir_addr, vir_bytes bytes) );
_PROTOTYPE( phys_bytes umap_bios, (struct proc *rp, vir_bytes vir_addr,
vir_bytes bytes) );
-_PROTOTYPE( int vir_copy, (int src_proc, vir_bytes src_vir,
- int dst_proc, vir_bytes dst_vir, vir_bytes bytes) );
_PROTOTYPE( int generic_handler, (irq_hook_t *hook) );
-_PROTOTYPE( void timed_interrupt, (struct timer *tp) );
/* table.c */
_PROTOTYPE( void mapdrivers, (void) );
#include "kernel.h"
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
#include <stddef.h>
#include <minix/com.h>
#include <minix/keymap.h>
* (LOW_USER+1) + 1. This means that there are bits for each task, driver, and
* server process, INIT, and one bit to represent all ordinary user processes.
*
- * NOTE: the send masks definitions must be updated!!!
+ * PLEASE NOTE: the send masks definitions are a mess and must be updated!!!
+ * this will be done when dynamic driver loading is implemented
*
* Changes:
* May 01, 2004 created and sendmask definitions (Jorrit N. Herder)
register struct proc *rp;
int i;
- /* Initialize IRQ table. */
- for (i=0; i<NR_IRQ_VECTORS; i++)
- irqtab[i].proc_nr = NONE;
+ /* Initialize IRQ handler hooks. Mark all hooks available. */
+ for (i=0; i<NR_IRQ_HOOKS; i++) {
+ irq_hooks[i].proc_nr = NONE;
+ }
/* Initialize all alarm timers for all processes. */
for (rp=BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) {
/* Copying. */
map(SYS_UMAP, do_umap); /* map virtual to physical address */
- map(SYS_VIRCOPY, do_vircopy); /* use virtual addressing */
+ map(SYS_VIRCOPY, do_vircopy); /* use pure virtual addressing */
map(SYS_PHYSCOPY, do_physcopy); /* use physical addressing */
map(SYS_VIRVCOPY, do_virvcopy); /* vector with copy requests */
* interrupts are transformed into messages to a driver. The IRQ line will be
* reenabled if the policy says so.
*/
- irq_policy_t policy = irqtab[hook->irq].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
- * port and optionally (2b) strobe the port high or (2c) low with the value
- * 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.
- */
- long port = irqtab[hook->irq].port;
- phys_bytes addr = irqtab[hook->irq].addr;
- long mask_val = irqtab[hook->irq].mask_val;
-
- /* Read a value from the given port. Possibly also strobe the port with the
- * read value. Strobe it high by using the mask provided by the caller;
- * strobe it low by writing back the value we read.
- */
- if (policy & (IRQ_READ_PORT|IRQ_STROBE|IRQ_ECHO_VAL)) {
- switch(policy & (IRQ_BYTE|IRQ_WORD|IRQ_LONG)) {
- case IRQ_BYTE: { /* byte values */
- u8_t byteval = inb(port);
- if (policy & IRQ_STROBE) outb(port, byteval | mask_val);
- if (policy & IRQ_ECHO_VAL) outb(port, byteval);
- if (policy & IRQ_READ_PORT)
- phys_copy(vir2phys(&byteval), addr, sizeof(u8_t));
- break;
- } case IRQ_WORD: { /* word values */
- u16_t wordval = inw(port);
- if (policy & IRQ_STROBE) outw(port, wordval | mask_val);
- if (policy & IRQ_ECHO_VAL) outw(port, wordval);
- if (policy & IRQ_READ_PORT)
- phys_copy(vir2phys(&wordval), addr, sizeof(u16_t));
- break;
- } case IRQ_LONG: { /* long values */
- u32_t longval = inl(port);
- if (policy & IRQ_STROBE) outl(port, longval | mask_val);
- if (policy & IRQ_ECHO_VAL) outl(port, longval);
- if (policy & IRQ_READ_PORT)
- phys_copy(vir2phys(&longval), addr, sizeof(u32_t));
- break;
- } default: /* do nothing */ ; /* wrong type flags */
- }
- }
- /* Write a value to some port. This is straightforward. Note that both
- * reading and writing is not possible, hence 'else if' instead of 'if'.
- */
- else if (policy & (IRQ_WRITE_PORT)) {
- switch(policy & (IRQ_BYTE|IRQ_WORD|IRQ_LONG)) {
- case IRQ_BYTE: outb(port, (u8_t) mask_val); break;
- case IRQ_WORD: outw(port, (u16_t) mask_val); break;
- case IRQ_LONG: outl(port, (u32_t) mask_val); break;
- 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.
- */
- notify(proc_nr, HARD_INT);
- return(policy & IRQ_REENABLE);
+ notify(hook->proc_nr, HARD_INT);
+ return(hook->policy & IRQ_REENABLE);
}
}
-#if ENABLE_MESSAGE_STATS
-
-/*===========================================================================*
- * do_mstats *
- *===========================================================================*/
-PRIVATE int do_mstats(m_ptr)
-message *m_ptr; /* pointer to request message */
-{
- int r = 0;
-
- if(m_ptr->m1_i1 > 0) {
- struct message_statentry *dest;
- struct proc *p;
- p = proc_addr(m_ptr->m1_i3);
- dest = proc_vir2phys(p, m_ptr->m1_p1);
- r = mstat_copy(dest, m_ptr->m1_i1);
- }
-
- if(m_ptr->m1_i2) {
- mstat_reset();
- }
-
- return r;
-}
-
-#endif /* ENABLE_MESSAGE_STATS */
-
/*===========================================================================*
* umap_remote *
*===========================================================================*/
return(OK);
}
-/*==========================================================================*
- * vir_copy *
- *==========================================================================*/
-PUBLIC int vir_copy(src_proc, src_vir, dst_proc, dst_vir, bytes)
-int src_proc; /* source process */
-vir_bytes src_vir; /* source virtual address within D seg */
-int dst_proc; /* destination process */
-vir_bytes dst_vir; /* destination virtual address within D seg */
-vir_bytes bytes; /* # of bytes to copy */
-{
-/* Copy bytes from one process to another. Meant for the easy cases, where
- * speed isn't required. (One can normally do without one of the umaps.)
- */
- phys_bytes src_phys, dst_phys;
-
- src_phys = umap_local(proc_addr(src_proc), D, src_vir, bytes);
- dst_phys = umap_local(proc_addr(dst_proc), D, dst_vir, bytes);
- if (src_phys == 0 || dst_phys == 0) return(EFAULT);
- phys_copy(src_phys, dst_phys, (phys_bytes) bytes);
- return(OK);
-}
-
-
CFLAGS = -I$i
LDFLAGS = -i
-SYS = alarms.o copying.o debugging.o devio.o irqctl.o proctl.o \
+SYS = clock.o copying.o debugging.o devio.o irqctl.o proctl.o \
sysctl.o misc.o sigctl.o tracing.o \
# What to make.
# Dependencies from src/kernel/system.h
b = $k/system.h $h/com.h $k/proc.h $k/assert.h
-alarms.o: $a $b
+clock.o: $a $b
copying.o: $a $b
debugging.o: $a $b
devio.o: $a $b $h/devio.h
PUBLIC int do_umap(m_ptr)
register message *m_ptr; /* pointer to request message */
{
-/* Same as umap_local(), for non-kernel processes. */
+/* Map virtual address to physical, for non-kernel processes. */
+ int seg_type = m_ptr->CP_SRC_SPACE & SEGMENT_TYPE;
+ int seg_index = m_ptr->CP_SRC_SPACE & SEGMENT_INDEX;
+ vir_bytes offset = m_ptr->CP_SRC_ADDR;
+ int count = m_ptr->CP_NR_BYTES;
int proc_nr = (int) m_ptr->CP_SRC_PROC_NR;
+ phys_bytes phys_addr;
+
+ /* Verify process number. */
if (proc_nr == SELF) proc_nr = m_ptr->m_source;
if (! isokprocn(proc_nr)) return(EINVAL);
- m_ptr->CP_DST_ADDR = umap_local(proc_addr(proc_nr),
- (int) m_ptr->CP_SRC_SPACE,
- (vir_bytes) m_ptr->CP_SRC_ADDR,
- (vir_bytes) m_ptr->CP_NR_BYTES);
- return(OK);
+ /* See which mapping should be made. */
+ switch(seg_type) {
+ case LOCAL_SEG:
+ phys_addr = umap_local(proc_addr(proc_nr), seg_index, offset, count);
+ break;
+ case REMOTE_SEG:
+ phys_addr = umap_remote(proc_addr(proc_nr), seg_index, offset, count);
+ break;
+ case BIOS_SEG:
+ phys_addr = umap_bios(proc_addr(proc_nr), offset, count);
+ break;
+ default:
+ return(EINVAL);
+ }
+ m_ptr->CP_DST_ADDR = phys_addr;
+ return (phys_addr == 0) ? EFAULT: OK;
}
* The parameters for this system call are:
* m5_c1: IRQ_REQUEST (control operation to perform)
* m5_c2: IRQ_VECTOR (irq line that must be controlled)
- * m5_i1: IRQ_POLICY (flags to control the IRQCTL request)
- * m5_i2: IRQ_PROC_NR (process number to notify)
- * m5_l1: IRQ_PORT (port to write to / read from)
- * m5_l2: IRQ_VIR_ADDR (virtual address at caller)
- * m5_l3: IRQ_MASK_VAL (value to be written or strobe mask)
+ * m5_i1: IRQ_POLICY (irq policy allows reenabling interrupts)
+ * m5_l3: IRQ_HOOK_ID (index of irq hook assigned at kernel)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
#include "../kernel.h"
#include "../system.h"
-
/*===========================================================================*
- * do_irqctl *
+ * do_irqctl *
*===========================================================================*/
PUBLIC int do_irqctl(m_ptr)
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 */
-#endif
-
- /* Check if IRQ line is acceptable. */
- if ((unsigned) irq >= NR_IRQ_VECTORS) {
- kprintf("ST: irq line %d is not acceptable!\n", irq);
- return(EINVAL);
- }
+ int irq_vec;
+ int irq_hook_id;
+ int proc_nr;
+ irq_hook_t *hook_ptr;
/* See what is requested and take needed actions. */
switch(m_ptr->IRQ_REQUEST) {
/* Enable or disable IRQs. This is straightforward. */
case IRQ_ENABLE: {
- enable_irq(&irqtab[irq].hook);
+ irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
+ if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL);
+ enable_irq(&irq_hooks[irq_hook_id]);
break;
}
case IRQ_DISABLE: {
- disable_irq(&irqtab[irq].hook);
+ irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
+ if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL);
+ disable_irq(&irq_hooks[irq_hook_id]);
break;
}
/* Control IRQ policies. Set a policy and needed details in the IRQ table.
* This policy is used by a generic function to handle hardware interrupts.
- * The generic_handler() is contained in system.c.
*/
case IRQ_SETPOLICY: {
- if (proc_nr == NONE) { /* remove irqtab entry */
- if (irqtab[irq].proc_nr != m_ptr->m_source) {
- return(EPERM); /* only owner may do so */
- }
- kprintf("ST: notify: cannot remove entry for IRQ %d\n",irq);
- return(ENOSYS); /* not yet supported */
+ /* Check if IRQ line is acceptable. */
+ irq_vec = (unsigned) m_ptr->IRQ_VECTOR;
+ if ((unsigned) irq_vec >= NR_IRQ_VECTORS) {
+ kprintf("ST: irq line %d is not acceptable!\n", irq_vec);
+ return(EINVAL);
}
- else { /* install generic handler */
- if (irqtab[irq].proc_nr != NONE) { /* IRQ entry already taken */
- kprintf("ST: notify: slot for IRQ %d already taken\n", irq);
- return(EBUSY); /* cannot overwrite entry */
- }
- if (proc_nr == SELF) /* check for magic proc nr */
- proc_nr = m_ptr->m_source; /* set caller's proc nr */
- if (! isokprocn(proc_nr)) { /* check if proc nr is ok */
- 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));
- break;
- case IRQ_WORD: phys_addr=numap_local(proc_nr,vir_addr,sizeof(u16_t));
- break;
- case IRQ_LONG: phys_addr=numap_local(proc_nr,vir_addr,sizeof(u32_t));
- break;
- default: return(EINVAL); /* wrong type flags */
- }
- 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);
+
+ /* Find a free IRQ hook for this mapping. */
+ hook_ptr = NULL;
+ for (irq_hook_id=0; irq_hook_id<NR_IRQ_HOOKS; irq_hook_id++) {
+ if (irq_hooks[irq_hook_id].proc_nr == NONE) {
+ hook_ptr = &irq_hooks[irq_hook_id]; /* free hook */
+ break;
+ }
}
+ if (hook_ptr == NULL) return(ENOSPC);
+
+ /* Only caller can request IRQ mappings. Install handler. */
+ hook_ptr->proc_nr = m_ptr->m_source; /* process to notify */
+ hook_ptr->policy = m_ptr->IRQ_POLICY; /* policy for interrupts */
+ put_irq_handler(hook_ptr, irq_vec, generic_handler);
+
+ /* Return index of the IRQ hook in use. */
+ m_ptr->IRQ_HOOK_ID = irq_hook_id;
break;
}
default:
-/* The system call implemented in this file:
- * m_type: SYS_TIMES
- *
- * The parameters for this system call are:
- * m4_l1: T_PROC_NR (get info for this process)
- * m4_l1: T_USER_TIME (return values ...)
- * m4_l2: T_SYSTEM_TIME
- * m4_l3: T_CHILD_UTIME
- * m4_l4: T_CHILD_STIME
- * m4_l5: T_BOOT_TICKS
- */
-
#include "../kernel.h"
#include "../system.h"
#include <unistd.h>
INIT_ASSERT
-/*===========================================================================*
- * do_times *
- *===========================================================================*/
-PUBLIC int do_times(m_ptr)
-register message *m_ptr; /* pointer to request message */
-{
-/* Handle sys_times(). Retrieve the accounting information. */
-
- register struct proc *rp;
- int proc_nr;
-
- /* Insert the times needed by the SYS_TIMES system call in the message. */
- proc_nr = (m_ptr->T_PROC_NR == SELF) ? m_ptr->m_source : m_ptr->T_PROC_NR;
- if (isokprocn(proc_nr)) {
- rp = proc_addr(m_ptr->T_PROC_NR);
-
- lock(); /* halt the volatile time counters in rp */
- m_ptr->T_USER_TIME = rp->user_time;
- m_ptr->T_SYSTEM_TIME = rp->sys_time;
- unlock();
- m_ptr->T_CHILD_UTIME = rp->child_utime;
- m_ptr->T_CHILD_STIME = rp->child_stime;
- }
- m_ptr->T_BOOT_TICKS = get_uptime();
- return(OK);
-}
-
/*===========================================================================*
* do_unused *
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
-
-
/*===========================================================================*
* do_getinfo *
*===========================================================================*/
src_phys = vir2phys(image);
break;
}
- case GET_IRQTAB: {
- length = sizeof(struct irqtab) * NR_IRQ_VECTORS;
- src_phys = vir2phys(irqtab);
+ case GET_IRQHOOKS: {
+ length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
+ src_phys = vir2phys(irq_hooks);
break;
}
case GET_MEMCHUNKS: {
} else { /* lookup nr by name */
int proc_found = FALSE;
struct proc *pp;
+ struct vir_addr vsrc, vdst;
char key[8]; /* storage for process name to lookup */
#if DEAD_CODE
/* GET_PROCNR functionality will be moved to the Process Manager! */
#endif
proc_nr = m_ptr->m_source; /* only caller can request copy */
if (m_ptr->I_KEY_LEN > sizeof(key)) return(EINVAL);
+ vsrc.proc_nr = proc_nr; vsrc.segment = D; vsrc.offset = (vir_bytes) m_ptr->I_KEY_PTR;
+ vdst.proc_nr = SYSTASK, vdst.segment = D; vdst.offset = (vir_bytes) key;
+ if (virtual_copy(&vsrc, &vdst, m_ptr->I_KEY_LEN) != OK) return(EFAULT);
+#if DEAD_CODE
if (vir_copy(proc_nr, (vir_bytes) m_ptr->I_KEY_PTR, SYSTASK,
(vir_bytes) key, m_ptr->I_KEY_LEN) != OK) return(EFAULT);
+#endif
for (pp=BEG_PROC_ADDR; pp<END_PROC_ADDR; pp++) {
if (kstrncmp(pp->p_name, key, m_ptr->I_KEY_LEN) == 0) {
src_phys = vir2phys(&(pp->p_nr));
* m2_p1: CTL_ARG_PTR (argument pointer)
*/
+/* NOTE: this call will radically change! */
/*===========================================================================*
* do_svrctl *
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
-
/*===========================================================================*
* do_segctl *
*===========================================================================*/
#define TYPE_H
typedef _PROTOTYPE( void task_t, (void) );
-typedef _PROTOTYPE( int (*rdwt_t), (message *m_ptr) );
-typedef _PROTOTYPE( void (*watchdog_t), (void) );
/* Type accepted by kprintf(). This is a hack to accept both integers and
* char pointers in the same argument.
phys_clicks size; /* size of memory chunk */
};
-struct bios {
- phys_bytes bios_addr; /* physical address at BIOS */
- size_t bios_length; /* size of value */
-};
-
#if (CHIP == INTEL)
typedef u16_t port_t;
u8_t base_high;
};
+typedef unsigned long irq_policy_t;
+
typedef struct irq_hook {
- struct irq_hook *next;
- int (*handler)(struct irq_hook *);
- int irq;
- int id;
+ struct irq_hook *next; /* next hook in chain */
+ int (*handler)(struct irq_hook *); /* interrupt handler */
+ int irq; /* IRQ vector number */
+ int id; /* id of this hook */
+ int proc_nr; /* NONE if not in use */
+ irq_policy_t policy; /* bit mask for policy */
} irq_hook_t;
typedef int (*irq_handler_t)(struct irq_hook *);
-/* The IRQ table is used to handle harware interrupts based on a policy set
- * by a device driver. The policy is stored with a SYS_IRQCTL system call and
- * used by a generic function to handle hardware interrupts in an appropriate
- * way for the device.
- */
-typedef unsigned long irq_policy_t;
-struct irqtab {
- irq_hook_t hook; /* its irq hook */
- irq_policy_t policy; /* bit mask for the policy */
- int proc_nr; /* process number to be notified */
- long port; /* port to be read or written */
- phys_bytes addr; /* absolute address to store or get value */
- long mask_val; /* mask for strobing or value to be written */
-};
-
#endif /* (CHIP == INTEL) */
#if (CHIP == M68000)
/*===========================================================================*
* sys_irqctl *
*===========================================================================*/
-PUBLIC int sys_irqctl(req, irq_vec, policy, proc_nr, port, val_ptr, mask_val)
+PUBLIC int sys_irqctl(req, irq_vec, policy, hook_id)
int req; /* IRQ control request */
int irq_vec; /* IRQ vector to control */
int policy; /* bit mask for policy flags */
-int proc_nr; /* process number to notify */
-long port; /* port to read or write */
-void *val_ptr; /* address store value read */
-long mask_val; /* strobe mask or value to write */
+int *hook_id; /* ID of IRQ hook at kernel */
{
message m_irq;
int s;
m_irq.IRQ_REQUEST = req;
m_irq.IRQ_VECTOR = irq_vec;
m_irq.IRQ_POLICY = policy;
- m_irq.IRQ_PROC_NR = proc_nr;
- m_irq.IRQ_PORT = port;
- m_irq.IRQ_VIR_ADDR = (vir_bytes) val_ptr;
- m_irq.IRQ_MASK_VAL = mask_val;
+ m_irq.IRQ_HOOK_ID = *hook_id;
- return _taskcall(SYSTASK, SYS_IRQCTL, &m_irq);
+ s = _taskcall(SYSTASK, SYS_IRQCTL, &m_irq);
+ if (req == IRQ_SETPOLICY) *hook_id = m_irq.IRQ_HOOK_ID;
+ return(s);
}
PRIVATE void irqtab_dmp()
{
int i,j,r;
- struct irqtab irqtab[NR_IRQ_VECTORS];
- struct irqtab *e; /* irq tab entry */
+ struct irq_hook irqhooks[NR_IRQ_HOOKS];
+ struct irq_hook *e; /* irq tab entry */
int p; /* policy */
char *irq[] = {
"clock", /* 00 */
"at_wini_1", /* 15 */
};
- if ((r = sys_getirqtab(irqtab)) != OK) {
- report("warning: couldn't get copy of irqtab", r);
+ if ((r = sys_getirqhooks(irqhooks)) != OK) {
+ report("warning: couldn't get copy of irq hooks", r);
return;
}
printf("IRQ table dump showing hardware interrupt policies for each IRQ vector.\n");
+#if 0
printf("-irq name/nr- -pnr- --port-- msk_val --addr-- -type-rdp-str-ech-wrp-ena- \n");
for (i=0; i<NR_IRQ_VECTORS; i++) {
e = &irqtab[i];
printf("%9s %2d ", irq[i], i);
if (e->proc_nr!=NONE) printf("%4d ", e->proc_nr);
else printf(" ");
- printf(" 0x%06x 0x%05x 0x%06x %c%c%c %d %d %d %d %d\n",
+ printf(" 0x%06x 0x%05x 0x%06x %c%c%c %d\n",
e->port, e->mask_val, e->addr,
(p&IRQ_BYTE)?'B':'-', (p&IRQ_WORD)?'W':'-', (p&IRQ_LONG)?'L':'-',
- ((p&IRQ_READ_PORT) != 0),
- ((p&IRQ_STROBE) != 0),
- ((p&IRQ_ECHO_VAL) != 0),
- ((p&IRQ_WRITE_PORT) != 0),
((p&IRQ_REENABLE) != 0)
);
}
+#endif
printf("\n");
}
usage:
@echo " " >&2
- @echo "Master Makefile to create new MINIX configuration. Root privileges required." >&2
+ @echo "Master Makefile to create new MINIX configuration." >& 2
+ @echo "Root privileges are required." >&2
+ @echo " " >&2
@echo "Usage:" >&2
@echo " make libraries # Make system libraries" >&2
@echo " make programs # Compile and install all programs" >&2