Intermediate update---please await next commit.
This commit is contained in:
parent
614f49b557
commit
1cb880b158
15 changed files with 176 additions and 89 deletions
|
@ -879,7 +879,7 @@ int value; /* required status */
|
||||||
* ticks. Disabling the alarm is not needed, because a static flag is used
|
* ticks. Disabling the alarm is not needed, because a static flag is used
|
||||||
* and a leftover timeout cannot do any harm.
|
* and a leftover timeout cannot do any harm.
|
||||||
*/
|
*/
|
||||||
static int timeout_flag = 0; /* must be static, not cancelled */
|
static int timeout_flag; /* must be static, not cancelled */
|
||||||
int s;
|
int s;
|
||||||
timeout_flag = 0;
|
timeout_flag = 0;
|
||||||
sys_flagalrm(TIMEOUT_TICKS, &timeout_flag);
|
sys_flagalrm(TIMEOUT_TICKS, &timeout_flag);
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "../drivers.h"
|
#include "../drivers.h"
|
||||||
#include "../libdriver/driver.h"
|
#include "../libdriver/driver.h"
|
||||||
|
#include "../../kernel/const.h"
|
||||||
|
#include "../../kernel/type.h"
|
||||||
#include <sys/ioc_memory.h>
|
#include <sys/ioc_memory.h>
|
||||||
|
|
||||||
#define NR_DEVS 7 /* number of minor devices */
|
#define NR_DEVS 7 /* number of minor devices */
|
||||||
|
@ -28,8 +30,10 @@ PRIVATE int m_seg[NR_DEVS]; /* segment index of each device */
|
||||||
PRIVATE int m_device; /* current device */
|
PRIVATE int m_device; /* current device */
|
||||||
PRIVATE struct kinfo kinfo; /* need kernel info */
|
PRIVATE struct kinfo kinfo; /* need kernel info */
|
||||||
PRIVATE struct machine machine; /* need machine info */
|
PRIVATE struct machine machine; /* need machine info */
|
||||||
PRIVATE struct psinfo psinfo = { NR_TASKS, NR_PROCS, 0, 0, 0 };
|
PRIVATE struct memory mem[NR_MEMS]; /* physical memory chunks */
|
||||||
|
|
||||||
|
FORWARD _PROTOTYPE( int alloc_mem, (phys_bytes size, phys_bytes *base) );
|
||||||
|
FORWARD _PROTOTYPE( char *m_name, (void) );
|
||||||
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
|
FORWARD _PROTOTYPE( struct device *m_prepare, (int device) );
|
||||||
FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, off_t position,
|
FORWARD _PROTOTYPE( int m_transfer, (int proc_nr, int opcode, off_t position,
|
||||||
iovec_t *iov, unsigned nr_req) );
|
iovec_t *iov, unsigned nr_req) );
|
||||||
|
@ -37,8 +41,6 @@ FORWARD _PROTOTYPE( int m_do_open, (struct driver *dp, message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void m_init, (void) );
|
FORWARD _PROTOTYPE( void m_init, (void) );
|
||||||
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr) );
|
FORWARD _PROTOTYPE( int m_ioctl, (struct driver *dp, message *m_ptr) );
|
||||||
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
|
FORWARD _PROTOTYPE( void m_geometry, (struct partition *entry) );
|
||||||
FORWARD _PROTOTYPE( char *m_name, (void) );
|
|
||||||
|
|
||||||
|
|
||||||
/* Entry points to this driver. */
|
/* Entry points to this driver. */
|
||||||
PRIVATE struct driver m_dtab = {
|
PRIVATE struct driver m_dtab = {
|
||||||
|
@ -63,13 +65,17 @@ PRIVATE char zero[ZERO_BUF_SIZE];
|
||||||
PRIVATE char random[RANDOM_BUF_SIZE];
|
PRIVATE char random[RANDOM_BUF_SIZE];
|
||||||
|
|
||||||
|
|
||||||
|
#define click_to_round_k(n) \
|
||||||
|
((unsigned) ((((unsigned long) (n) << CLICK_SHIFT) + 512) / 1024))
|
||||||
|
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* main *
|
* main *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void main(void)
|
PUBLIC void main(void)
|
||||||
{
|
{
|
||||||
m_init();
|
m_init(); /* initialize the memory driver */
|
||||||
driver_task(&m_dtab);
|
driver_task(&m_dtab); /* start driver's main loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,8 +115,7 @@ off_t position; /* offset on device to read or write */
|
||||||
iovec_t *iov; /* pointer to read or write request vector */
|
iovec_t *iov; /* pointer to read or write request vector */
|
||||||
unsigned nr_req; /* length of request vector */
|
unsigned nr_req; /* length of request vector */
|
||||||
{
|
{
|
||||||
/* Read or write /dev/null, /dev/mem, /dev/kmem, /dev/ram, or /dev/boot. */
|
/* Read or write one the driver's minor devices. */
|
||||||
int device;
|
|
||||||
phys_bytes mem_phys, user_phys;
|
phys_bytes mem_phys, user_phys;
|
||||||
int seg;
|
int seg;
|
||||||
unsigned count, left, chunk;
|
unsigned count, left, chunk;
|
||||||
|
@ -120,8 +125,7 @@ unsigned nr_req; /* length of request vector */
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
/* Get minor device number and check for /dev/null. */
|
/* Get minor device number and check for /dev/null. */
|
||||||
device = m_device;
|
dv = &m_geom[m_device];
|
||||||
dv = &m_geom[device];
|
|
||||||
dv_size = cv64ul(dv->dv_size);
|
dv_size = cv64ul(dv->dv_size);
|
||||||
|
|
||||||
while (nr_req > 0) {
|
while (nr_req > 0) {
|
||||||
|
@ -130,7 +134,7 @@ unsigned nr_req; /* length of request vector */
|
||||||
count = iov->iov_size;
|
count = iov->iov_size;
|
||||||
user_vir = iov->iov_addr;
|
user_vir = iov->iov_addr;
|
||||||
|
|
||||||
switch (device) {
|
switch (m_device) {
|
||||||
|
|
||||||
/* No copying; ignore request. */
|
/* No copying; ignore request. */
|
||||||
case NULL_DEV:
|
case NULL_DEV:
|
||||||
|
@ -143,7 +147,7 @@ unsigned nr_req; /* length of request vector */
|
||||||
case BOOT_DEV:
|
case BOOT_DEV:
|
||||||
if (position >= dv_size) return(OK); /* check for EOF */
|
if (position >= dv_size) return(OK); /* check for EOF */
|
||||||
if (position + count > dv_size) count = dv_size - position;
|
if (position + count > dv_size) count = dv_size - position;
|
||||||
seg = m_seg[device];
|
seg = m_seg[m_device];
|
||||||
|
|
||||||
if (opcode == DEV_GATHER) { /* copy actual data */
|
if (opcode == DEV_GATHER) { /* copy actual data */
|
||||||
sys_vircopy(SELF,seg,position, proc_nr,D,user_vir, count);
|
sys_vircopy(SELF,seg,position, proc_nr,D,user_vir, count);
|
||||||
|
@ -242,12 +246,12 @@ message *m_ptr;
|
||||||
PRIVATE void m_init()
|
PRIVATE void m_init()
|
||||||
{
|
{
|
||||||
/* Initialize this task. All minor devices are initialized one by one. */
|
/* Initialize this task. All minor devices are initialized one by one. */
|
||||||
int i,s;
|
int i, s;
|
||||||
|
|
||||||
/* Print welcome message. */
|
/* Get memory addresses from the kernel. */
|
||||||
printf("MEMORY: user-level memory (RAM, etc.) driver is alive\n");
|
if (OK != (s=sys_getmemchunks(&mem))) {
|
||||||
|
server_panic("MEM","Couldn't get memory chunks.",s);
|
||||||
/* Get kernel info for memory addresses of kernel and boot device. */
|
}
|
||||||
if (OK != (s=sys_getkinfo(&kinfo))) {
|
if (OK != (s=sys_getkinfo(&kinfo))) {
|
||||||
server_panic("MEM","Couldn't get kernel information.",s);
|
server_panic("MEM","Couldn't get kernel information.",s);
|
||||||
}
|
}
|
||||||
|
@ -270,8 +274,6 @@ PRIVATE void m_init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
psinfo.proc = kinfo.proc_addr;
|
|
||||||
|
|
||||||
/* Initialize /dev/random and /dev/zero. */
|
/* Initialize /dev/random and /dev/zero. */
|
||||||
for (i=0; i<ZERO_BUF_SIZE; i++) {
|
for (i=0; i<ZERO_BUF_SIZE; i++) {
|
||||||
zero[i] = '\0';
|
zero[i] = '\0';
|
||||||
|
@ -301,6 +303,9 @@ PRIVATE void m_init()
|
||||||
#error /* memory limit not set up */
|
#error /* memory limit not set up */
|
||||||
#endif /* !(CHIP == M68000) */
|
#endif /* !(CHIP == M68000) */
|
||||||
#endif /* !(CHIP == INTEL) */
|
#endif /* !(CHIP == INTEL) */
|
||||||
|
|
||||||
|
/* Initialization succeeded. Print welcome message. */
|
||||||
|
printf("User-space memory driver (RAM disk, etc.) has been initialized.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -308,19 +313,19 @@ PRIVATE void m_init()
|
||||||
* m_ioctl *
|
* m_ioctl *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE int m_ioctl(dp, m_ptr)
|
PRIVATE int m_ioctl(dp, m_ptr)
|
||||||
struct driver *dp;
|
struct driver *dp; /* pointer to driver structure */
|
||||||
message *m_ptr; /* pointer to read or write message */
|
message *m_ptr; /* pointer to control message */
|
||||||
{
|
{
|
||||||
/* Set parameters for the RAM disk. */
|
/* I/O controls for the memory driver. Currently there is one I/O control:
|
||||||
|
* - MIOCRAMSIZE: to set the size of the RAM disk.
|
||||||
|
*/
|
||||||
struct device *dv;
|
struct device *dv;
|
||||||
|
|
||||||
if ((dv = m_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
|
if ((dv = m_prepare(m_ptr->DEVICE)) == NIL_DEV) return(ENXIO);
|
||||||
|
|
||||||
switch (m_ptr->REQUEST) {
|
switch (m_ptr->REQUEST) {
|
||||||
case MIOCRAMSIZE: {
|
case MIOCRAMSIZE: {
|
||||||
/* FS wants to create a new RAM disk with the given size. */
|
/* FS wants to create a new RAM disk with the given size. */
|
||||||
unsigned long ramdev_size;
|
phys_bytes ramdev_size;
|
||||||
phys_bytes ramdev_base;
|
phys_bytes ramdev_base;
|
||||||
int s;
|
int s;
|
||||||
|
|
||||||
|
@ -328,39 +333,21 @@ message *m_ptr; /* pointer to read or write message */
|
||||||
|
|
||||||
/* Try to allocate a piece of memory for the RAM disk. */
|
/* Try to allocate a piece of memory for the RAM disk. */
|
||||||
ramdev_size = m_ptr->POSITION;
|
ramdev_size = m_ptr->POSITION;
|
||||||
|
if (OK != (s=alloc_mem(ramdev_size, &ramdev_base)))
|
||||||
|
server_panic("MEM","Couldn't allocate kernel memory", s);
|
||||||
|
dv->dv_base = cvul64(ramdev_base);
|
||||||
|
dv->dv_size = cvul64(ramdev_size);
|
||||||
|
printf("Test MEM: base 0x%06x, size 0x%06x\n", dv->dv_base, dv->dv_size);
|
||||||
|
|
||||||
if (OK != (s=sys_kmalloc(ramdev_size, &ramdev_base)))
|
if (OK != (s=sys_kmalloc(ramdev_size, &ramdev_base)))
|
||||||
server_panic("MEM","Couldn't allocate kernel memory", s);
|
server_panic("MEM","Couldn't allocate kernel memory", s);
|
||||||
dv->dv_base = cvul64(ramdev_base);
|
dv->dv_base = cvul64(ramdev_base);
|
||||||
dv->dv_size = cvul64(ramdev_size);
|
dv->dv_size = cvul64(ramdev_size);
|
||||||
|
printf("Real MEM: base 0x%06x, size 0x%06x\n", dv->dv_base, dv->dv_size);
|
||||||
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, (vir_bytes *) &s,
|
if (OK != (s=sys_segctl(&m_seg[RAM_DEV], (u16_t *) &s, (vir_bytes *) &s,
|
||||||
ramdev_base, ramdev_size))) {
|
ramdev_base, ramdev_size))) {
|
||||||
server_panic("MEM","Couldn't install remote segment.",s);
|
server_panic("MEM","Couldn't install remote segment.",s);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Perhaps it is cleaner to move all code relating to psinfo to the info
|
|
||||||
* server??? (Note that psinfo is global; psinfo.proc is set in m_init.)
|
|
||||||
* This requires changes to ioctl as well.
|
|
||||||
*/
|
|
||||||
case MIOCSPSINFO: {
|
|
||||||
/* MM or FS set the address of their process table. */
|
|
||||||
phys_bytes psinfo_phys;
|
|
||||||
|
|
||||||
if (m_ptr->PROC_NR == PM_PROC_NR) {
|
|
||||||
psinfo.mproc = (vir_bytes) m_ptr->ADDRESS;
|
|
||||||
} else if (m_ptr->PROC_NR == FS_PROC_NR) {
|
|
||||||
psinfo.fproc = (vir_bytes) m_ptr->ADDRESS;
|
|
||||||
} else {
|
|
||||||
return(EPERM);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MIOCGPSINFO: {
|
|
||||||
/* The ps program wants the process table addresses. */
|
|
||||||
if (sys_datacopy(SELF, (vir_bytes) &psinfo,
|
|
||||||
m_ptr->PROC_NR, (vir_bytes) m_ptr->ADDRESS,
|
|
||||||
sizeof(psinfo)) != OK) return(EFAULT);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,3 +369,27 @@ struct partition *entry;
|
||||||
entry->heads = 64;
|
entry->heads = 64;
|
||||||
entry->sectors = 32;
|
entry->sectors = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* malloc_mem *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE int alloc_mem(chunk_size, chunk_base)
|
||||||
|
phys_bytes chunk_size; /* number of bytes requested */
|
||||||
|
phys_bytes *chunk_base; /* base of memory area found */
|
||||||
|
{
|
||||||
|
/* Request a piece of memory from one of the free memory chunks. */
|
||||||
|
phys_clicks tot_clicks;
|
||||||
|
struct memory *memp;
|
||||||
|
|
||||||
|
tot_clicks = (chunk_size+ CLICK_SIZE-1) >> CLICK_SHIFT;
|
||||||
|
memp = &mem[NR_MEMS];
|
||||||
|
while ((--memp)->size < tot_clicks) {
|
||||||
|
if (memp == mem) {
|
||||||
|
return(ENOMEM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memp->size -= tot_clicks;
|
||||||
|
*chunk_base = (memp->base + memp->size) << CLICK_SHIFT;
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,12 @@
|
||||||
#include <net/gen/ether.h>
|
#include <net/gen/ether.h>
|
||||||
#include <net/gen/eth_io.h>
|
#include <net/gen/eth_io.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioc_memory.h>
|
||||||
|
#include "../../kernel/type.h"
|
||||||
|
|
||||||
#if __minix_vmd
|
#if __minix_vmd
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
@ -731,7 +737,8 @@ re_t *rep;
|
||||||
{
|
{
|
||||||
size_t rx_bufsize, tx_bufsize, tot_bufsize;
|
size_t rx_bufsize, tx_bufsize, tot_bufsize;
|
||||||
phys_bytes buf;
|
phys_bytes buf;
|
||||||
int i;
|
static struct memory chunk;
|
||||||
|
int fd, s, i;
|
||||||
|
|
||||||
/* Allocate receive and transmit buffers */
|
/* Allocate receive and transmit buffers */
|
||||||
tx_bufsize= ETH_MAX_PACK_SIZE_TAGGED;
|
tx_bufsize= ETH_MAX_PACK_SIZE_TAGGED;
|
||||||
|
@ -742,9 +749,26 @@ re_t *rep;
|
||||||
#if __minix_vmd
|
#if __minix_vmd
|
||||||
buf= (phys_bytes)kalloc_dma_128K(tot_bufsize, FALSE /* not low */);
|
buf= (phys_bytes)kalloc_dma_128K(tot_bufsize, FALSE /* not low */);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Now try to allocate a kernel memory buffer. */
|
/* Now try to allocate a kernel memory buffer. */
|
||||||
|
chunk.size = tot_bufsize;
|
||||||
|
#if DEAD_CODE
|
||||||
|
fd = open("/dev/mem", O_RDONLY);
|
||||||
|
if (fd <0) {
|
||||||
|
printf("RTL8139: warning, couldn't open: %d\n", fd);
|
||||||
|
} else {
|
||||||
|
if (OK != (s=ioctl(fd, MIOCGETCHUNK, &chunk)))
|
||||||
|
printf("RTL8139: ioctl failed: %d\n", s);
|
||||||
|
else
|
||||||
|
printf("RTL8139: %uK buffer from mem at 0x06%x\n",
|
||||||
|
chunk.size, chunk.base);
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (OK != (i=sys_kmalloc(tot_bufsize, &buf)))
|
if (OK != (i=sys_kmalloc(tot_bufsize, &buf)))
|
||||||
server_panic("RTL8139","Couldn't allocate kernel buffer",i);
|
server_panic("RTL8139","Couldn't allocate kernel buffer",i);
|
||||||
|
printf("RTL8139: real %uK buffer at 0x%06x\n", tot_bufsize, buf);
|
||||||
#endif
|
#endif
|
||||||
for (i= 0; i<N_TX_BUF; i++)
|
for (i= 0; i<N_TX_BUF; i++)
|
||||||
{
|
{
|
||||||
|
@ -824,7 +848,7 @@ re_t *rep;
|
||||||
if (!(rl_inb(port, RL_BMCR) & MII_CTRL_RST))
|
if (!(rl_inb(port, RL_BMCR) & MII_CTRL_RST))
|
||||||
break;
|
break;
|
||||||
} while (! timeout);
|
} while (! timeout);
|
||||||
sys_flagalrm(0, &timeout);
|
sys_flagalrm(0, &timeout); /* for correctness */
|
||||||
if (rl_inb(port, RL_BMCR) & MII_CTRL_RST)
|
if (rl_inb(port, RL_BMCR) & MII_CTRL_RST)
|
||||||
server_panic("rtl8139","reset PHY failed to complete", NO_NUM);
|
server_panic("rtl8139","reset PHY failed to complete", NO_NUM);
|
||||||
#endif
|
#endif
|
||||||
|
@ -837,7 +861,7 @@ re_t *rep;
|
||||||
if (!(rl_inb(port, RL_CR) & RL_CR_RST))
|
if (!(rl_inb(port, RL_CR) & RL_CR_RST))
|
||||||
break;
|
break;
|
||||||
} while (! timeout);
|
} while (! timeout);
|
||||||
sys_flagalrm(0, &timeout);
|
sys_flagalrm(0, &timeout); /* for correctness */
|
||||||
if (rl_inb(port, RL_CR) & RL_CR_RST)
|
if (rl_inb(port, RL_CR) & RL_CR_RST)
|
||||||
server_panic("rtl8139","reset failed to complete", NO_NUM);
|
server_panic("rtl8139","reset failed to complete", NO_NUM);
|
||||||
|
|
||||||
|
@ -1779,7 +1803,7 @@ re_t *rep;
|
||||||
if (!(rl_inb(port, RL_CR) & RL_CR_RE))
|
if (!(rl_inb(port, RL_CR) & RL_CR_RE))
|
||||||
break;
|
break;
|
||||||
} while (! timeout);
|
} while (! timeout);
|
||||||
sys_flagalrm(0, &timeout);
|
sys_flagalrm(0, &timeout); /* for correctness */
|
||||||
if (rl_inb(port, RL_CR) & RL_CR_RE)
|
if (rl_inb(port, RL_CR) & RL_CR_RE)
|
||||||
server_panic("rtl8139","cannot disable receiver", NO_NUM);
|
server_panic("rtl8139","cannot disable receiver", NO_NUM);
|
||||||
|
|
||||||
|
@ -2141,7 +2165,7 @@ re_t *rep;
|
||||||
if (!(rl_inb(port, RL_CR) & RL_CR_TE))
|
if (!(rl_inb(port, RL_CR) & RL_CR_TE))
|
||||||
break;
|
break;
|
||||||
} while (! timeout);
|
} while (! timeout);
|
||||||
sys_flagalrm(0, &timeout);
|
sys_flagalrm(0, &timeout); /* for correctness */
|
||||||
if (rl_inb(port, RL_CR) & RL_CR_TE)
|
if (rl_inb(port, RL_CR) & RL_CR_TE)
|
||||||
{
|
{
|
||||||
server_panic("rtl8139","cannot disable transmitter",
|
server_panic("rtl8139","cannot disable transmitter",
|
||||||
|
@ -2583,7 +2607,7 @@ u16_t w;
|
||||||
if (inb_reg3(dep, 1) & 1)
|
if (inb_reg3(dep, 1) & 1)
|
||||||
break;
|
break;
|
||||||
} while (! timeout);
|
} while (! timeout);
|
||||||
sys_flagalrm(0, &timeout);
|
sys_flagalrm(0, &timeout); /* for correctness */
|
||||||
if (!(inb_reg3(dep, 1) & 1))
|
if (!(inb_reg3(dep, 1) & 1))
|
||||||
server_panic("set_ee_word","device remains busy", NO_NUM);
|
server_panic("set_ee_word","device remains busy", NO_NUM);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,5 @@
|
||||||
#include <minix/ioctl.h>
|
#include <minix/ioctl.h>
|
||||||
|
|
||||||
#define MIOCRAMSIZE _IOW('m', 3, u32_t)
|
#define MIOCRAMSIZE _IOW('m', 3, u32_t)
|
||||||
#define MIOCSPSINFO _IOW('m', 4, void *)
|
|
||||||
#define MIOCGPSINFO _IOR('m', 5, struct psinfo)
|
|
||||||
#define MIOCINT86 _IORW('m', 6, struct mio_int86)
|
|
||||||
#define MIOCGLDT86 _IORW('m', 7, struct mio_ldt86)
|
|
||||||
#define MIOCSLDT86 _IOW('m', 8, struct mio_ldt86)
|
|
||||||
|
|
||||||
#endif /* _S_I_MEMORY_H */
|
#endif /* _S_I_MEMORY_H */
|
||||||
|
|
|
@ -33,10 +33,13 @@
|
||||||
/* How many IRQ hooks are there in total. */
|
/* How many IRQ hooks are there in total. */
|
||||||
#define NR_IRQ_HOOKS 16
|
#define NR_IRQ_HOOKS 16
|
||||||
|
|
||||||
|
/* How many notification buffers (12B each) should there be? */
|
||||||
|
#define NR_NOTIFY_BUFS 128
|
||||||
|
|
||||||
/* Program stack words and masks. */
|
/* Program stack words and masks. */
|
||||||
#define INIT_PSW 0x0200 /* initial psw */
|
#define INIT_PSW 0x0200 /* initial psw */
|
||||||
#define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */
|
#define INIT_TASK_PSW 0x1200 /* initial psw for tasks (with IOPL 1) */
|
||||||
#define TRACEBIT 0x100 /* OR this with psw in proc[] for tracing */
|
#define TRACEBIT 0x0100 /* OR this with psw in proc[] for tracing */
|
||||||
#define SETPSW(rp, new) /* permits only certain bits to be set */ \
|
#define SETPSW(rp, new) /* permits only certain bits to be set */ \
|
||||||
((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xCD5 | (new) & 0xCD5)
|
((rp)->p_reg.psw = (rp)->p_reg.psw & ~0xCD5 | (new) & 0xCD5)
|
||||||
#define IF_MASK 0x00000200
|
#define IF_MASK 0x00000200
|
||||||
|
|
|
@ -66,6 +66,8 @@ FORWARD _PROTOTYPE( void cp_mess, (int src, struct proc *src_p, message *src_m,
|
||||||
#define clear_bit(mask, n) ((mask) &= ~(1 << (n)))
|
#define clear_bit(mask, n) ((mask) &= ~(1 << (n)))
|
||||||
#define isset_bit(mask, n) ((mask) & (1 << (n)))
|
#define isset_bit(mask, n) ((mask) & (1 << (n)))
|
||||||
|
|
||||||
|
/* Declare buffer space for notifications. */
|
||||||
|
PRIVATE struct notification notify_buf[NR_NOTIFY_BUFS];
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* lock_notify *
|
* lock_notify *
|
||||||
|
@ -87,7 +89,7 @@ int notify_type; /* notification to be sent */
|
||||||
unsigned int notify_bit; /* bit for this notification */
|
unsigned int notify_bit; /* bit for this notification */
|
||||||
|
|
||||||
/* Get notify bit and process pointer. */
|
/* Get notify bit and process pointer. */
|
||||||
notify_bit = (unsigned int) (notify_type - NOTIFICATION);
|
notify_bit = (unsigned int) (notify_type & ~NOTIFICATION);
|
||||||
rp = proc_addr(proc_nr);
|
rp = proc_addr(proc_nr);
|
||||||
|
|
||||||
/* If this call would compete with other process-switching functions, put
|
/* If this call would compete with other process-switching functions, put
|
||||||
|
@ -181,7 +183,11 @@ message *m_ptr; /* pointer to message in the caller's space */
|
||||||
* reply and may not block if the caller doesn't do receive(). Users also
|
* reply and may not block if the caller doesn't do receive(). Users also
|
||||||
* may only use sendrec() to protect the process manager and file system.
|
* may only use sendrec() to protect the process manager and file system.
|
||||||
*/
|
*/
|
||||||
|
#if DEAD_CODE
|
||||||
if ((iskernel(src_dst) || isuserp(caller_ptr)) && function != BOTH) {
|
if ((iskernel(src_dst) || isuserp(caller_ptr)) && function != BOTH) {
|
||||||
|
#else
|
||||||
|
if (iskernel(src_dst) && function != BOTH) {
|
||||||
|
#endif
|
||||||
result = ECALLDENIED; /* BOTH was required */
|
result = ECALLDENIED; /* BOTH was required */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,10 +365,10 @@ int may_block; /* (dis)allow blocking */
|
||||||
* priority of other messages.
|
* priority of other messages.
|
||||||
*/
|
*/
|
||||||
if (caller_ptr->p_ntf_blocked && isrxhardware(src)) {
|
if (caller_ptr->p_ntf_blocked && isrxhardware(src)) {
|
||||||
for (i=0; i<NR_NOTIFICATIONS; i++) {
|
for (i=0; i<NR_NOTIFY_TYPES; i++) {
|
||||||
if (isset_bit(caller_ptr->p_ntf_blocked, i)) {
|
if (isset_bit(caller_ptr->p_ntf_blocked, i)) {
|
||||||
m.m_source = HARDWARE;
|
m.m_source = HARDWARE;
|
||||||
m.m_type = NOTIFICATION + i;
|
m.m_type = NOTIFICATION | i;
|
||||||
CopyMess(HARDWARE, proc_addr(HARDWARE), &m, caller_ptr, m_ptr);
|
CopyMess(HARDWARE, proc_addr(HARDWARE), &m, caller_ptr, m_ptr);
|
||||||
clear_bit(caller_ptr->p_ntf_blocked, i);
|
clear_bit(caller_ptr->p_ntf_blocked, i);
|
||||||
return(OK);
|
return(OK);
|
||||||
|
@ -599,7 +605,7 @@ PUBLIC void unhold()
|
||||||
if (switching) return;
|
if (switching) return;
|
||||||
rp = held_head;
|
rp = held_head;
|
||||||
do {
|
do {
|
||||||
for (i=0; i<NR_NOTIFICATIONS; i++) {
|
for (i=0; i<NR_NOTIFY_TYPES; i++) {
|
||||||
if (isset_bit(rp->p_ntf_held,i)) {
|
if (isset_bit(rp->p_ntf_held,i)) {
|
||||||
clear_bit(rp->p_ntf_held,i);
|
clear_bit(rp->p_ntf_held,i);
|
||||||
if (! rp->p_ntf_held) /* proceed to next in queue? */
|
if (! rp->p_ntf_held) /* proceed to next in queue? */
|
||||||
|
@ -608,7 +614,7 @@ PUBLIC void unhold()
|
||||||
#if DEAD_CODE
|
#if DEAD_CODE
|
||||||
unlock(); /* reduce latency; held queue may change! */
|
unlock(); /* reduce latency; held queue may change! */
|
||||||
#endif
|
#endif
|
||||||
lock_notify(proc_number(rp), NOTIFICATION + i);
|
lock_notify(proc_number(rp), NOTIFICATION | i);
|
||||||
#if DEAD_CODE
|
#if DEAD_CODE
|
||||||
lock(); /* protect the held queue again */
|
lock(); /* protect the held queue again */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,17 +31,19 @@ struct proc {
|
||||||
|
|
||||||
reg_t *p_stguard; /* stack guard word */
|
reg_t *p_stguard; /* stack guard word */
|
||||||
|
|
||||||
int p_nr; /* number of this process (for fast access) */
|
proc_nr_t p_nr; /* number of this process (for fast access) */
|
||||||
|
|
||||||
notify_mask_t p_ntf_blocked; /* bit mask for blocked notifications */
|
notify_mask_t p_ntf_blocked; /* bit mask for blocked notifications */
|
||||||
notify_mask_t p_ntf_held; /* bit mask for held up notify() calls */
|
notify_mask_t p_ntf_held; /* bit mask for held up notify() calls */
|
||||||
struct proc *p_ntf_nextheld; /* next in chain of held-up int processes */
|
struct proc *p_ntf_nextheld; /* next in chain of held-up int processes */
|
||||||
|
|
||||||
|
struct notification *p_ntfq; /* queue of pending notifications */
|
||||||
|
|
||||||
int p_flags; /* SENDING, RECEIVING, etc. */
|
int p_flags; /* SENDING, RECEIVING, etc. */
|
||||||
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* local memory map (T, D, S) */
|
struct mem_map p_memmap[NR_LOCAL_SEGS]; /* local memory map (T, D, S) */
|
||||||
struct far_mem p_farmem[NR_REMOTE_SEGS]; /* remote memory map */
|
struct far_mem p_farmem[NR_REMOTE_SEGS]; /* remote memory map */
|
||||||
short p_type; /* task, system, driver, server, user, idle */
|
char p_type; /* task, system, driver, server, user, idle */
|
||||||
short p_priority; /* scheduling priority */
|
char p_priority; /* scheduling priority */
|
||||||
|
|
||||||
clock_t user_time; /* user time in ticks */
|
clock_t user_time; /* user time in ticks */
|
||||||
clock_t sys_time; /* sys time in ticks */
|
clock_t sys_time; /* sys time in ticks */
|
||||||
|
|
|
@ -27,7 +27,8 @@ register message *m_ptr; /* pointer to request message */
|
||||||
int r = OK;
|
int r = OK;
|
||||||
irq_hook_t *hook_ptr;
|
irq_hook_t *hook_ptr;
|
||||||
|
|
||||||
irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID;
|
/* Hook identifiers start at 1 and end at NR_IRQ_HOOKS. */
|
||||||
|
irq_hook_id = (unsigned) m_ptr->IRQ_HOOK_ID - 1;
|
||||||
irq_vec = (unsigned) m_ptr->IRQ_VECTOR;
|
irq_vec = (unsigned) m_ptr->IRQ_VECTOR;
|
||||||
|
|
||||||
/* See what is requested and take needed actions. */
|
/* See what is requested and take needed actions. */
|
||||||
|
@ -36,7 +37,8 @@ register message *m_ptr; /* pointer to request message */
|
||||||
/* Enable or disable IRQs. This is straightforward. */
|
/* Enable or disable IRQs. This is straightforward. */
|
||||||
case IRQ_ENABLE:
|
case IRQ_ENABLE:
|
||||||
case IRQ_DISABLE:
|
case IRQ_DISABLE:
|
||||||
if (irq_hook_id >= NR_IRQ_HOOKS) return(EINVAL);
|
if (irq_hook_id >= NR_IRQ_HOOKS ||
|
||||||
|
irq_hooks[irq_hook_id].proc_nr == NONE) return(EINVAL);
|
||||||
if (irq_hooks[irq_hook_id].proc_nr != m_ptr->m_source) return(EPERM);
|
if (irq_hooks[irq_hook_id].proc_nr != m_ptr->m_source) return(EPERM);
|
||||||
if (m_ptr->IRQ_REQUEST == IRQ_ENABLE)
|
if (m_ptr->IRQ_REQUEST == IRQ_ENABLE)
|
||||||
enable_irq(&irq_hooks[irq_hook_id]);
|
enable_irq(&irq_hooks[irq_hook_id]);
|
||||||
|
@ -72,15 +74,15 @@ register message *m_ptr; /* pointer to request message */
|
||||||
put_irq_handler(hook_ptr, irq_vec, generic_handler);
|
put_irq_handler(hook_ptr, irq_vec, generic_handler);
|
||||||
|
|
||||||
/* Return index of the IRQ hook in use. */
|
/* Return index of the IRQ hook in use. */
|
||||||
m_ptr->IRQ_HOOK_ID = irq_hook_id;
|
m_ptr->IRQ_HOOK_ID = irq_hook_id + 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IRQ_RMPOLICY:
|
case IRQ_RMPOLICY:
|
||||||
if(irq_hook_id < 0 || irq_hook_id >= NR_IRQ_HOOKS ||
|
if (irq_hook_id >= NR_IRQ_HOOKS ||
|
||||||
irq_hooks[irq_hook_id].proc_nr == NONE) {
|
irq_hooks[irq_hook_id].proc_nr == NONE) {
|
||||||
r = EINVAL;
|
r = EINVAL;
|
||||||
} else {
|
} else {
|
||||||
if(m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
|
if (m_ptr->m_source != irq_hooks[irq_hook_id].proc_nr) {
|
||||||
r = EPERM;
|
r = EPERM;
|
||||||
} else {
|
} else {
|
||||||
r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
|
r = rm_irq_handler(irq_vec, irq_hooks[irq_hook_id].id);
|
||||||
|
|
|
@ -8,11 +8,16 @@ typedef _PROTOTYPE( void task_t, (void) );
|
||||||
*/
|
*/
|
||||||
typedef long karg_t; /* use largest type here */
|
typedef long karg_t; /* use largest type here */
|
||||||
|
|
||||||
typedef unsigned int notify_mask_t; /* bit mask for notifications */
|
/* Process related types.
|
||||||
|
* A process number defines the index into the process table. With a signed
|
||||||
|
* short we can support up to 256 user processes and more kernel tasks than
|
||||||
|
* one can ever create.
|
||||||
|
*/
|
||||||
|
typedef int proc_nr_t; /* process table entry number */
|
||||||
typedef unsigned long send_mask_t; /* bit mask for sender */
|
typedef unsigned long send_mask_t; /* bit mask for sender */
|
||||||
|
|
||||||
struct system_image {
|
struct system_image {
|
||||||
int proc_nr; /* process number to use */
|
proc_nr_t proc_nr; /* process number to use */
|
||||||
task_t *initial_pc; /* start function for tasks */
|
task_t *initial_pc; /* start function for tasks */
|
||||||
int type; /* type of process */
|
int type; /* type of process */
|
||||||
int priority; /* scheduling priority */
|
int priority; /* scheduling priority */
|
||||||
|
@ -26,6 +31,18 @@ struct memory {
|
||||||
phys_clicks size; /* size of memory chunk */
|
phys_clicks size; /* size of memory chunk */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef unsigned long notify_mask_t; /* bit mask for notifications */
|
||||||
|
typedef char notify_type_t; /* notification type */
|
||||||
|
typedef char notify_flags_t; /* notification flags */
|
||||||
|
typedef int notify_arg_t; /* notification argument */
|
||||||
|
|
||||||
|
struct notification {
|
||||||
|
proc_nr_t n_source; /* sender of notification */
|
||||||
|
notify_type_t n_type; /* notification type */
|
||||||
|
notify_arg_t n_arg; /* notification argument */
|
||||||
|
notify_flags_t n_fags; /* notification flags */
|
||||||
|
struct notification* n_next; /* pointer to next notification */
|
||||||
|
};
|
||||||
|
|
||||||
#if (CHIP == INTEL)
|
#if (CHIP == INTEL)
|
||||||
typedef unsigned reg_t; /* machine register */
|
typedef unsigned reg_t; /* machine register */
|
||||||
|
|
|
@ -25,7 +25,7 @@ all: \
|
||||||
|
|
||||||
OBJECTS = \
|
OBJECTS = \
|
||||||
$(LIBRARY)(__sigreturn.o) \
|
$(LIBRARY)(__sigreturn.o) \
|
||||||
$(LIBRARY)(_sendrec.o) \
|
$(LIBRARY)(_ipc.o) \
|
||||||
$(LIBRARY)(brksize.o) \
|
$(LIBRARY)(brksize.o) \
|
||||||
|
|
||||||
$(LIBRARY): $(OBJECTS)
|
$(LIBRARY): $(OBJECTS)
|
||||||
|
@ -35,8 +35,8 @@ $(LIBRARY): $(OBJECTS)
|
||||||
$(LIBRARY)(__sigreturn.o): __sigreturn.s
|
$(LIBRARY)(__sigreturn.o): __sigreturn.s
|
||||||
$(CC1) __sigreturn.s
|
$(CC1) __sigreturn.s
|
||||||
|
|
||||||
$(LIBRARY)(_sendrec.o): _sendrec.s
|
$(LIBRARY)(_ipc.o): _ipc.s
|
||||||
$(CC1) _sendrec.s
|
$(CC1) _ipc.s
|
||||||
|
|
||||||
$(LIBRARY)(brksize.o): brksize.s
|
$(LIBRARY)(brksize.o): brksize.s
|
||||||
$(CC1) brksize.s
|
$(CC1) brksize.s
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
.sect .text; .sect .rom; .sect .data; .sect .bss
|
.sect .text; .sect .rom; .sect .data; .sect .bss
|
||||||
.define __send, __receive, __sendrec
|
.define __send, __nb_send, __receive, __nb_receive, __sendrec, __notify
|
||||||
|
|
||||||
! See ../h/com.h for C definitions
|
! See ../h/com.h for C definitions
|
||||||
SEND = 1
|
SEND = 1
|
||||||
RECEIVE = 2
|
RECEIVE = 2
|
||||||
BOTH = 3
|
BOTH = 3
|
||||||
|
NOTIFY = 4
|
||||||
NB_SEND = 1 + 16 ! SEND | 0xF0
|
NB_SEND = 1 + 16 ! SEND | 0xF0
|
||||||
NB_RECEIVE = 2 + 16 ! RECEIVE | 0xF0
|
NB_RECEIVE = 2 + 16 ! RECEIVE | 0xF0
|
||||||
SYSVEC = 33
|
SYSVEC = 33
|
||||||
|
@ -17,7 +18,7 @@ MESSAGE = 12
|
||||||
!*========================================================================*
|
!*========================================================================*
|
||||||
! _send(), _nb_send(), _receive(), _nb_receive(), and _sendrec() all
|
! _send(), _nb_send(), _receive(), _nb_receive(), and _sendrec() all
|
||||||
! save ebp, but destroy eax and ecx.
|
! save ebp, but destroy eax and ecx.
|
||||||
.define __send, __nb_send, __receive, __nb_receive, __sendrec
|
.define __send, __nb_send, __receive, __nb_receive, __sendrec, __notify
|
||||||
.sect .text
|
.sect .text
|
||||||
__send:
|
__send:
|
||||||
push ebp
|
push ebp
|
||||||
|
@ -78,3 +79,16 @@ __sendrec:
|
||||||
pop ebx
|
pop ebx
|
||||||
pop ebp
|
pop ebp
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
__notify:
|
||||||
|
push ebp
|
||||||
|
mov ebp, esp
|
||||||
|
push ebx
|
||||||
|
mov eax, SRCDEST(ebp) ! eax = dest-src
|
||||||
|
mov ebx, MESSAGE(ebp) ! ebx = message pointer
|
||||||
|
mov ecx, NOTIFY ! _notify(srcdest, ptr)
|
||||||
|
int SYSVEC ! trap to the kernel
|
||||||
|
pop ebx
|
||||||
|
pop ebp
|
||||||
|
ret
|
||||||
|
|
|
@ -325,6 +325,19 @@ PRIVATE void kenv_dmp()
|
||||||
printf("- bootdev_size: %5u\n", kinfo.bootdev_size);
|
printf("- bootdev_size: %5u\n", kinfo.bootdev_size);
|
||||||
printf("- params_base: %5u\n", kinfo.params_base);
|
printf("- params_base: %5u\n", kinfo.params_base);
|
||||||
printf("- params_size: %5u\n", kinfo.params_size);
|
printf("- params_size: %5u\n", kinfo.params_size);
|
||||||
|
printf("- notify_held: %8u\n", kinfo.notify_held);
|
||||||
|
printf("- notify_blocked:%8u\n", kinfo.notify_blocked);
|
||||||
|
printf("- notify_switch: %8u\n", kinfo.notify_switching);
|
||||||
|
printf("- notify_reenter:%8u\n", kinfo.notify_reenter);
|
||||||
|
printf("- notify_ok: %8u\n", kinfo.notify_ok);
|
||||||
|
printf("- notify_unhold: %8u\n", kinfo.notify_unhold);
|
||||||
|
printf("- hard_int: %8u\n", kinfo.notify_int);
|
||||||
|
printf("- hard_stop: %8u\n", kinfo.notify_stop);
|
||||||
|
printf("- sync_alarm: %8u\n", kinfo.notify_alarm);
|
||||||
|
printf("- ksig_pending: %8u\n", kinfo.notify_sig);
|
||||||
|
printf("- new_kmess: %8u\n", kinfo.notify_kmess);
|
||||||
|
printf("- nr_procs: %3u\n", kinfo.nr_procs);
|
||||||
|
printf("- nr_tasks: %3u\n", kinfo.nr_tasks);
|
||||||
printf("- version: %.6s\n", kinfo.version);
|
printf("- version: %.6s\n", kinfo.version);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ _PROTOTYPE( void main, (void) );
|
||||||
/* misc.c */
|
/* misc.c */
|
||||||
_PROTOTYPE( int do_reboot, (void) );
|
_PROTOTYPE( int do_reboot, (void) );
|
||||||
_PROTOTYPE( int do_getsysinfo, (void) );
|
_PROTOTYPE( int do_getsysinfo, (void) );
|
||||||
|
_PROTOTYPE( int do_getprocnr, (void) );
|
||||||
_PROTOTYPE( int do_svrctl, (void) );
|
_PROTOTYPE( int do_svrctl, (void) );
|
||||||
_PROTOTYPE( int do_mstats, (void) );
|
_PROTOTYPE( int do_mstats, (void) );
|
||||||
|
|
||||||
|
|
|
@ -96,11 +96,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = {
|
||||||
|
|
||||||
no_sys, /* 78 = cmostime */
|
no_sys, /* 78 = cmostime */
|
||||||
do_getsysinfo, /* 79 = getsysinfo */
|
do_getsysinfo, /* 79 = getsysinfo */
|
||||||
#if ENABLE_MESSAGE_STATS
|
do_getprocnr, /* 80 = getprocnr */
|
||||||
do_mstats, /* 80 = mstats */
|
|
||||||
#else
|
|
||||||
no_sys,
|
|
||||||
#endif
|
|
||||||
no_sys, /* 81 = unused */
|
no_sys, /* 81 = unused */
|
||||||
no_sys, /* 82 = unused */
|
no_sys, /* 82 = unused */
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,7 @@ usage:
|
||||||
@echo "Root privileges are required." >&2
|
@echo "Root privileges are required." >&2
|
||||||
@echo " " >&2
|
@echo " " >&2
|
||||||
@echo "Usage:" >&2
|
@echo "Usage:" >&2
|
||||||
|
@echo " make includes # Install include files" >&2
|
||||||
@echo " make libraries # Make system libraries" >&2
|
@echo " make libraries # Make system libraries" >&2
|
||||||
@echo " make programs # Compile and install all programs" >&2
|
@echo " make programs # Compile and install all programs" >&2
|
||||||
@echo " make fresh # Make clean, libraries, and programs" >&2
|
@echo " make fresh # Make clean, libraries, and programs" >&2
|
||||||
|
@ -51,13 +52,15 @@ image: programs
|
||||||
|
|
||||||
|
|
||||||
# rebuild the program or system libraries
|
# rebuild the program or system libraries
|
||||||
programs:
|
includes:
|
||||||
cd ../include && $(MAKE) install
|
cd ../include && $(MAKE) install
|
||||||
|
|
||||||
|
programs: includes
|
||||||
cd ../kernel && $(MAKE)
|
cd ../kernel && $(MAKE)
|
||||||
cd ../servers && $(MAKE) install
|
cd ../servers && $(MAKE) install
|
||||||
cd ../drivers && $(MAKE) install
|
cd ../drivers && $(MAKE) install
|
||||||
|
|
||||||
libraries:
|
libraries: includes
|
||||||
cd ../lib && $(MAKE) install
|
cd ../lib && $(MAKE) install
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue