Split of architecture-dependent and -independent functions for i386,

mainly in the kernel and headers. This split based on work by
Ingmar Alting <iaalting@cs.vu.nl> done for his Minix PowerPC architecture
port.

 . kernel does not program the interrupt controller directly, do any
   other architecture-dependent operations, or contain assembly any more,
   but uses architecture-dependent functions in arch/$(ARCH)/.
 . architecture-dependent constants and types defined in arch/$(ARCH)/include.
 . <ibm/portio.h> moved to <minix/portio.h>, as they have become, for now,
   architecture-independent functions.
 . int86, sdevio, readbios, and iopenable are now i386-specific kernel calls
   and live in arch/i386/do_* now.
 . i386 arch now supports even less 86 code; e.g. mpx86.s and klib86.s have
   gone, and 'machine.protected' is gone (and always taken to be 1 in i386).
   If 86 support is to return, it should be a new architecture.
 . prototypes for the architecture-dependent functions defined in
   kernel/arch/$(ARCH)/*.c but used in kernel/ are in kernel/proto.h
 . /etc/make.conf included in makefiles and shell scripts that need to
   know the building architecture; it defines ARCH=<arch>, currently only
   i386.
 . some basic per-architecture build support outside of the kernel (lib)
 . in clock.c, only dequeue a process if it was ready
 . fixes for new include files

files deleted:
 . mpx/klib.s - only for choosing between mpx/klib86 and -386
 . klib86.s - only for 86

i386-specific files files moved (or arch-dependent stuff moved) to arch/i386/:
 . mpx386.s (entry point)
 . klib386.s
 . sconst.h
 . exception.c
 . protect.c
 . protect.h
 . i8269.c
This commit is contained in:
Ben Gras
2006-12-22 15:22:27 +00:00
parent f7984144d5
commit 6f77685609
100 changed files with 1528 additions and 1633 deletions

View File

@@ -1,15 +1,18 @@
# Makefile for system library implementation
include /etc/make.conf
# Directories
u = /usr
i = $u/include
a = ../arch
# Programs, flags, etc.
CC = exec cc $(CFLAGS) -c
CCNOPROF = exec cc $(CFLAGSNOPROF) -c # no call profiling for these
CPP = $l/cpp
LD = $(CC) -.o
CFLAGS = -I$i $(CPROFILE)
CFLAGS = -I$i $(CPROFILE) -I$a/$(ARCH)/include
CFLAGSNOPROF = -I$i
LDFLAGS = -i
@@ -31,8 +34,6 @@ OBJECTS = \
$(SYSTEM)(do_irqctl.o) \
$(SYSTEM)(do_devio.o) \
$(SYSTEM)(do_vdevio.o) \
$(SYSTEM)(do_int86.o) \
$(SYSTEM)(do_sdevio.o) \
$(SYSTEM)(do_copy.o) \
$(SYSTEM)(do_vcopy.o) \
$(SYSTEM)(do_umap.o) \
@@ -44,19 +45,17 @@ OBJECTS = \
$(SYSTEM)(do_getksig.o) \
$(SYSTEM)(do_endksig.o) \
$(SYSTEM)(do_kill.o) \
$(SYSTEM)(do_readbios.o) \
$(SYSTEM)(do_sigsend.o) \
$(SYSTEM)(do_sigreturn.o) \
$(SYSTEM)(do_abort.o) \
$(SYSTEM)(do_getinfo.o) \
$(SYSTEM)(do_iopenable.o) \
$(SYSTEM)(do_vm.o) \
$(SYSTEM)(do_vm_setbuf.o) \
$(SYSTEM)(do_sprofile.o) \
$(SYSTEM)(do_cprofile.o) \
$(SYSTEM)(do_profbuf.o)
$(SYSTEM): $(OBJECTS)
build $(SYSTEM): $(OBJECTS)
aal cr $@ *.o
clean:
@@ -102,15 +101,9 @@ $(SYSTEM)(do_irqctl.o): do_irqctl.c
$(SYSTEM)(do_devio.o): do_devio.c
$(CC) do_devio.c
$(SYSTEM)(do_sdevio.o): do_sdevio.c
$(CC) do_sdevio.c
$(SYSTEM)(do_vdevio.o): do_vdevio.c
$(CC) do_vdevio.c
$(SYSTEM)(do_int86.o): do_int86.c
$(CC) do_int86.c
$(SYSTEM)(do_copy.o): do_copy.c
$(CC) do_copy.c
@@ -144,9 +137,6 @@ $(SYSTEM)(do_getinfo.o): do_getinfo.c
$(SYSTEM)(do_abort.o): do_abort.c
$(CC) do_abort.c
$(SYSTEM)(do_readbios.o): do_readbios.c
$(CC) do_readbios.c
$(SYSTEM)(do_setgrant.o): do_setgrant.c
$(CC) do_setgrant.c
@@ -159,9 +149,6 @@ $(SYSTEM)(do_safecopy.o): do_safecopy.c
$(SYSTEM)(do_segctl.o): do_segctl.c
$(CC) do_segctl.c
$(SYSTEM)(do_iopenable.o): do_iopenable.c
$(CC) do_iopenable.c
$(SYSTEM)(do_vm.o): do_vm.o
do_vm.o: do_vm.c
$(CC) do_vm.c

View File

@@ -10,6 +10,7 @@
#include "../system.h"
#include <minix/devio.h>
#include <minix/endpoint.h>
#include <minix/portio.h>
#if USE_DEVIO
@@ -66,16 +67,17 @@ doit:
/* Process a single I/O request for byte, word, and long values. */
if (io_dir == _DIO_INPUT) {
switch (io_type) {
/* maybe "it" should not be called ports */
case _DIO_BYTE: m_ptr->DIO_VALUE = inb(m_ptr->DIO_PORT); break;
case _DIO_WORD: m_ptr->DIO_VALUE = inw(m_ptr->DIO_PORT); break;
case _DIO_LONG: m_ptr->DIO_VALUE = inl(m_ptr->DIO_PORT); break;
case _DIO_LONG: m_ptr->DIO_VALUE = inl(m_ptr->DIO_PORT); break;
default: return(EINVAL);
}
} else {
switch (io_type) {
case _DIO_BYTE: outb(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
case _DIO_BYTE: outb(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
case _DIO_WORD: outw(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
case _DIO_LONG: outl(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
case _DIO_LONG: outl(m_ptr->DIO_PORT, m_ptr->DIO_VALUE); break;
default: return(EINVAL);
}
}

View File

@@ -33,23 +33,18 @@ register message *m_ptr; /* pointer to request message */
rp = proc_addr(proc);
sp = (reg_t) m_ptr->PR_STACK_PTR;
rp->p_reg.sp = sp; /* set the stack pointer */
#if (CHIP == M68000)
rp->p_splow = sp; /* set the stack pointer low water */
#ifdef FPP
/* Initialize fpp for this process */
fpp_new_state(rp);
#endif
#endif
#if (CHIP == INTEL) /* wipe extra LDT entries */
phys_memset(vir2phys(&rp->p_ldt[EXTRA_LDT_INDEX]), 0,
(LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0]));
#if (_MINIX_CHIP == _CHIP_INTEL)
/* wipe extra LDT entries */
phys_memset(vir2phys(&rp->p_seg.p_ldt[EXTRA_LDT_INDEX]), 0,
(LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_seg.p_ldt[0]));
#endif
rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR; /* set pc */
rp->p_rts_flags &= ~RECEIVING; /* PM does not reply to EXEC call */
if (rp->p_rts_flags == 0) lock_enqueue(rp);
/* Save command name for debugging, ps(1) output, etc. */
phys_name = numap_local(who_p, (vir_bytes) m_ptr->PR_NAME_PTR,
(vir_bytes) P_NAME_LEN - 1);
(vir_bytes) P_NAME_LEN - 1);
if (phys_name != 0) {
phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) P_NAME_LEN - 1);
for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {}
@@ -57,6 +52,7 @@ register message *m_ptr; /* pointer to request message */
} else {
strncpy(rp->p_name, "<unset>", P_NAME_LEN);
}
return(OK);
}
#endif /* USE_EXEC */

View File

@@ -8,9 +8,6 @@
#include "../system.h"
#include <signal.h>
#if (CHIP == INTEL)
#include "../protect.h"
#endif
#include <minix/endpoint.h>
@@ -23,7 +20,7 @@ PUBLIC int do_fork(m_ptr)
register message *m_ptr; /* pointer to request message */
{
/* Handle sys_fork(). PR_ENDPT has forked. The child is PR_SLOT. */
#if (CHIP == INTEL)
#if (_MINIX_CHIP == _CHIP_INTEL)
reg_t old_ldt_sel;
#endif
register struct proc *rpc; /* child process pointer */
@@ -42,10 +39,10 @@ register message *m_ptr; /* pointer to request message */
/* Copy parent 'proc' struct to child. And reinitialize some fields. */
gen = _ENDPOINT_G(rpc->p_endpoint);
#if (CHIP == INTEL)
old_ldt_sel = rpc->p_ldt_sel; /* backup local descriptors */
#if (_MINIX_CHIP == _CHIP_INTEL)
old_ldt_sel = rpc->p_seg.p_ldt_sel; /* backup local descriptors */
*rpc = *rpp; /* copy 'proc' struct */
rpc->p_ldt_sel = old_ldt_sel; /* restore descriptors */
rpc->p_seg.p_ldt_sel = old_ldt_sel; /* restore descriptors */
#else
*rpc = *rpp; /* copy 'proc' struct */
#endif

View File

@@ -11,9 +11,14 @@
#include "../system.h"
#if !( POWERPC )
static unsigned long bios_buf[1024]; /* 4K, what about alignment */
static vir_bytes bios_buf_vir, bios_buf_len;
#endif /* #if !( POWERPC ) */
#if USE_GETINFO
/*===========================================================================*
@@ -119,6 +124,8 @@ register message *m_ptr; /* pointer to request message */
break;
}
#endif
#if !( POWERPC )
case GET_BIOSBUFFER:
bios_buf_vir = (vir_bytes)bios_buf;
bios_buf_len = sizeof(bios_buf);
@@ -135,7 +142,8 @@ register message *m_ptr; /* pointer to request message */
length = sizeof(bios_buf_vir);
src_phys = vir2phys(&bios_buf_vir);
break;
#endif /* #if !( POWERPC ) */
case GET_IRQACTIDS: {
length = sizeof(irq_actids);
src_phys = vir2phys(irq_actids);

View File

@@ -1,45 +0,0 @@
/* The kernel call implemented in this file:
* m_type: SYS_INT86
*
* The parameters for this kernel call are:
* m1_p1: INT86_REG86
*/
#include "../system.h"
#include <minix/type.h>
#include <minix/endpoint.h>
#include <ibm/int86.h>
struct reg86u reg86;
/*===========================================================================*
* do_int86 *
*===========================================================================*/
PUBLIC int do_int86(m_ptr)
register message *m_ptr; /* pointer to request message */
{
vir_bytes caller_vir;
phys_bytes caller_phys, kernel_phys;
caller_vir = (vir_bytes) m_ptr->INT86_REG86;
caller_phys = umap_local(proc_addr(who_p), D, caller_vir, sizeof(reg86));
if (0 == caller_phys) return(EFAULT);
kernel_phys = vir2phys(&reg86);
phys_copy(caller_phys, kernel_phys, (phys_bytes) sizeof(reg86));
level0(int86);
/* Copy results back to the caller */
phys_copy(kernel_phys, caller_phys, (phys_bytes) sizeof(reg86));
/* The BIOS call eats interrupts. Call get_randomness to generate some
* entropy. Normally, get_randomness is called from an interrupt handler.
* Figuring out the exact source is too complicated. CLOCK_IRQ is normally
* not very random.
*/
lock(0, "do_int86");
get_randomness(CLOCK_IRQ);
unlock(0);
return(OK);
}

View File

@@ -1,34 +0,0 @@
/* The system call implemented in this file:
* m_type: SYS_IOPENABLE
*
* The parameters for this system call are:
* m2_i2: IO_ENDPT (process to give I/O Protection Level bits)
*
* Author:
* Jorrit N. Herder <jnherder@cs.vu.nl>
*/
#include "../system.h"
#include "../kernel.h"
/*===========================================================================*
* do_iopenable *
*===========================================================================*/
PUBLIC int do_iopenable(m_ptr)
register message *m_ptr; /* pointer to request message */
{
int proc_nr;
#if 1 /* ENABLE_USERPRIV && ENABLE_USERIOPL */
if (m_ptr->IO_ENDPT == SELF) {
proc_nr = who_p;
} else if(!isokendpt(m_ptr->IO_ENDPT, &proc_nr))
return(EINVAL);
enable_iop(proc_addr(proc_nr));
return(OK);
#else
return(EPERM);
#endif
}

View File

@@ -48,13 +48,10 @@ struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */
src_phys = umap_local(proc_addr(who_p), D, (vir_bytes) map_ptr,
sizeof(rp->p_memmap));
if (src_phys == 0) return(EFAULT);
phys_copy(src_phys,vir2phys(rp->p_memmap),(phys_bytes)sizeof(rp->p_memmap));
phys_copy(src_phys,vir2phys(rp->p_memmap),
(phys_bytes)sizeof(rp->p_memmap));
#if (CHIP != M68000)
alloc_segments(rp);
#else
pmmu_init_proc(rp);
#endif
old_flags = rp->p_rts_flags; /* save the previous value of the flags */
if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);

View File

@@ -30,7 +30,7 @@ PUBLIC int do_nice(message *m_ptr)
if (pri == PRIO_STOP) {
/* Take process off the scheduling queues. */
lock_dequeue(rp);
if(rp->p_rts_flags == 0) lock_dequeue(rp);
rp->p_rts_flags |= NO_PRIORITY;
return(OK);
}
@@ -48,7 +48,7 @@ PUBLIC int do_nice(message *m_ptr)
/* Make sure the process is not running while changing its priority.
* Put the process back in its new queue if it is runnable.
*/
lock_dequeue(rp);
if(rp->p_rts_flags == 0) lock_dequeue(rp);
rp->p_rts_flags &= ~NO_PRIORITY;
rp->p_max_priority = rp->p_priority = new_q;
if (! rp->p_rts_flags) lock_enqueue(rp);

View File

@@ -1,39 +0,0 @@
/* The kernel call implemented in this file:
* m_type: SYS_READBIOS
*
* The parameters for this kernel call are:
* m2_i1: RDB_SIZE number of bytes to copy
* m2_l1: RDB_ADDR absolute address in BIOS area
* m2_p1: RDB_BUF buffer address in requesting process
*/
#include "../system.h"
#include <minix/type.h>
/*===========================================================================*
* do_readbios *
*===========================================================================*/
PUBLIC int do_readbios(m_ptr)
register message *m_ptr; /* pointer to request message */
{
int proc_nr;
struct proc *p;
phys_bytes address, phys_buf, phys_bios;
vir_bytes buf;
size_t size;
address = m_ptr->RDB_ADDR;
buf = (vir_bytes)m_ptr->RDB_BUF;
size = m_ptr->RDB_SIZE;
okendpt(m_ptr->m_source, &proc_nr);
p = proc_addr(proc_nr);
phys_buf = umap_local(p, D, buf, size);
if (phys_buf == 0)
return EFAULT;
phys_bios = umap_bios(p, address, size);
if (phys_bios == 0)
return EPERM;
phys_copy(phys_bios, phys_buf, size);
return 0;
}

View File

@@ -247,7 +247,6 @@ int access; /* CPF_READ for a copy from granter to grantee, CPF_WRITE
PUBLIC int do_safecopy(m_ptr)
register message *m_ptr; /* pointer to request message */
{
static endpoint_t new_granter;
static int access, src_seg, dst_seg;
/* Set src and dst parameters.

View File

@@ -1,126 +0,0 @@
/* The kernel call implemented in this file:
* m_type: SYS_SDEVIO
*
* The parameters for this kernel call are:
* m2_i3: DIO_REQUEST (request input or output)
* m2_i1: DIO_TYPE (flag indicating byte, word, or long)
* m2_l1: DIO_PORT (port to read/ write)
* m2_p1: DIO_VEC_ADDR (virtual address of buffer)
* m2_l2: DIO_VEC_SIZE (number of elements)
* m2_i2: DIO_VEC_PROC (process where buffer is)
*/
#include "../system.h"
#include <minix/devio.h>
#include <minix/endpoint.h>
#if USE_SDEVIO
/*===========================================================================*
* do_sdevio *
*===========================================================================*/
PUBLIC int do_sdevio(m_ptr)
register message *m_ptr; /* pointer to request message */
{
int proc_nr, proc_nr_e = m_ptr->DIO_VEC_ENDPT;
int count = m_ptr->DIO_VEC_SIZE;
long port = m_ptr->DIO_PORT;
phys_bytes phys_buf;
int i, req_type, req_dir, io_type, size, nr_io_range;
struct proc *rp;
struct priv *privp;
struct io_range *iorp;
/* Allow safe copies and accesses to SELF */
if ((m_ptr->DIO_REQUEST & _DIO_SAFEMASK) != _DIO_SAFE &&
proc_nr_e != SELF)
{
static int first= 1;
if (first)
{
first= 0;
kprintf("do_sdevio: for %d, req %d\n",
m_ptr->m_source, m_ptr->DIO_REQUEST);
}
}
/* Check if process endpoint is OK.
* A driver may directly provide a pointer to a buffer at the user-process
* that initiated the device I/O. Kernel processes, of course, are denied.
*/
if (proc_nr_e == SELF)
proc_nr = who_p;
else
if(!isokendpt(proc_nr_e, &proc_nr))
return(EINVAL);
if (iskerneln(proc_nr)) return(EPERM);
/* Extract direction (in or out) and type (size). */
req_dir = m_ptr->DIO_REQUEST & _DIO_DIRMASK;
req_type = m_ptr->DIO_REQUEST & _DIO_TYPEMASK;
/* Check for 'safe' variants. */
if((m_ptr->DIO_REQUEST & _DIO_SAFEMASK) == _DIO_SAFE) {
/* Map grant address to physical address. */
if ((phys_buf = umap_verify_grant(proc_addr(proc_nr), who_e,
(vir_bytes) m_ptr->DIO_VEC_ADDR,
(vir_bytes) m_ptr->DIO_OFFSET, count,
req_dir == _DIO_INPUT ? CPF_WRITE : CPF_READ)) == 0)
return(EPERM);
} else {
if(proc_nr != who_p)
kprintf("unsafe sdevio by %d in %d\n", who_e, proc_nr_e);
/* Get and check physical address. */
if ((phys_buf = numap_local(proc_nr,
(vir_bytes) m_ptr->DIO_VEC_ADDR, count)) == 0)
return(EFAULT);
}
rp= proc_addr(who_p);
if (privp && privp->s_flags & CHECK_IO_PORT)
{
switch (io_type)
{
case _DIO_BYTE: size= 1; break;
case _DIO_WORD: size= 2; break;
case _DIO_LONG: size= 4; break;
default: size= 4; break; /* Be conservative */
}
port= m_ptr->DIO_PORT;
nr_io_range= privp->s_nr_io_range;
for (i= 0, iorp= privp->s_io_tab; i<nr_io_range; i++, iorp++)
{
if (port >= iorp->ior_base && port+size-1 <= iorp->ior_limit)
break;
}
if (i >= nr_io_range)
{
kprintf(
"do_sdevio: I/O port check failed for proc %d, port 0x%x\n",
m_ptr->m_source, port);
return EPERM;
}
}
/* Perform device I/O for bytes and words. Longs are not supported. */
if (req_dir == _DIO_INPUT) {
switch (req_type) {
case _DIO_BYTE: phys_insb(port, phys_buf, count); break;
case _DIO_WORD: phys_insw(port, phys_buf, count); break;
default: return(EINVAL);
}
} else if (req_dir == _DIO_OUTPUT) {
switch (req_type) {
case _DIO_BYTE: phys_outsb(port, phys_buf, count); break;
case _DIO_WORD: phys_outsw(port, phys_buf, count); break;
default: return(EINVAL);
}
}
else {
return(EINVAL);
}
return(OK);
}
#endif /* USE_SDEVIO */

View File

@@ -9,7 +9,6 @@
* m4_l5: SEG_INDEX (return index into remote memory map here)
*/
#include "../system.h"
#include "../protect.h"
#if USE_SEGCTL
@@ -22,7 +21,7 @@ register message *m_ptr; /* pointer to request message */
/* Return a segment selector and offset that can be used to reach a physical
* address, for use by a driver doing memory I/O in the A0000 - DFFFF range.
*/
u16_t selector;
u32_t selector;
vir_bytes offset;
int i, index;
register struct proc *rp;
@@ -44,30 +43,9 @@ register message *m_ptr; /* pointer to request message */
}
if (index < 0) return(ENOSPC);
if (! machine.prot) {
selector = phys / HCLICK_SIZE;
offset = phys % HCLICK_SIZE;
result = OK;
} else {
/* Check if the segment size can be recorded in bytes, that is, check
* if descriptor's limit field can delimited the allowed memory region
* precisely. This works up to 1MB. If the size is larger, 4K pages
* instead of bytes are used.
*/
if (size < BYTE_GRAN_MAX) {
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys, size,
USER_PRIVILEGE);
selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
offset = 0;
result = OK;
} else {
init_dataseg(&rp->p_ldt[EXTRA_LDT_INDEX+i], phys & ~0xFFFF, 0,
USER_PRIVILEGE);
selector = ((EXTRA_LDT_INDEX+i)*0x08) | (1*0x04) | USER_PRIVILEGE;
offset = phys & 0xFFFF;
result = OK;
}
}
offset = alloc_remote_segment(&selector, &rp->p_seg,
i, phys, size, USER_PRIVILEGE);
result = OK;
/* Request successfully done. Now return the result. */
m_ptr->SEG_INDEX = index | REMOTE_SEG;

View File

@@ -40,7 +40,7 @@ message *m_ptr; /* pointer to request message */
sc.sc_psw = rp->p_reg.psw;
#if (CHIP == INTEL)
#if (_MINIX_CHIP == _CHIP_INTEL)
/* Don't panic kernel if user gave bad selectors. */
sc.sc_cs = rp->p_reg.cs;
sc.sc_ds = rp->p_reg.ds;
@@ -52,7 +52,11 @@ message *m_ptr; /* pointer to request message */
#endif
/* Restore the registers. */
#if _MINIX_CHIP == _CHIP_POWERPC
memcpy(&rp->p_reg, &sc.sc_regs, sizeof(struct stackframe_s));
#else
memcpy(&rp->p_reg, &sc.sc_regs, sizeof(struct sigregs));
#endif
return(OK);
}
#endif /* USE_SIGRETURN */

View File

@@ -45,6 +45,11 @@ message *m_ptr; /* pointer to request message */
/* Copy the registers to the sigcontext structure. */
memcpy(&sc.sc_regs, (char *) &rp->p_reg, sizeof(struct sigregs));
#ifdef POWERPC
memcpy(&sc.sc_regs, (char *) &rp->p_reg, struct(stackframe_s));
#else
memcpy(&sc.sc_regs, (char *) &rp->p_reg, sizeof(struct sigregs));
#endif
/* Finish the sigcontext initialization. */
sc.sc_flags = 0; /* unused at this time */
@@ -73,6 +78,16 @@ message *m_ptr; /* pointer to request message */
if (dst_phys == 0) return(EFAULT);
phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe));
#if ( _MINIX_CHIP == _CHIP_POWERPC ) /* stuff that can't be done in the assembler code. */
/* When the signal handlers C code is called it will write this value
* into the signal frame (over the sf_retadr value).
*/
rp->p_reg.lr = smsg.sm_sigreturn;
/* The first (and only) parameter for the user signal handler function.
*/
rp->p_reg.retreg = smsg.sm_signo; /* note the retreg == first argument */
#endif
/* Reset user registers to execute the signal handler. */
rp->p_reg.sp = (reg_t) frp;
rp->p_reg.pc = (reg_t) smsg.sm_sighandler;

View File

@@ -59,7 +59,7 @@ register message *m_ptr; /* pointer to request message */
sprof_mem_size = m_ptr->PROF_MEM_SIZE;
init_cmos_clock(m_ptr->PROF_FREQ);
init_profile_clock(m_ptr->PROF_FREQ);
sprofiling = 1;
@@ -78,7 +78,7 @@ register message *m_ptr; /* pointer to request message */
sprofiling = 0;
stop_cmos_clock();
stop_profile_clock();
phys_copy(vir2phys((vir_bytes) &sprof_info),
sprof_info_addr, (phys_bytes) sizeof(sprof_info));

View File

@@ -102,7 +102,7 @@ register message *m_ptr;
tr_addr > sizeof(struct stackframe_s) - sizeof(reg_t))
return(EIO);
i = (int) tr_addr;
#if (CHIP == INTEL)
#if (_MINIX_CHIP == _CHIP_INTEL)
/* Altering segment registers might crash the kernel when it
* tries to load them prior to restarting a process, so do
* not allow it.

View File

@@ -43,9 +43,11 @@ register message *m_ptr; /* pointer to request message */
case REMOTE_SEG:
phys_addr = umap_remote(proc_addr(proc_nr), seg_index, offset, count);
break;
#if _MINIX_CHIP == _CHIP_INTEL
case BIOS_SEG:
phys_addr = umap_bios(proc_addr(proc_nr), offset, count);
break;
#endif
case GRANT_SEG:
phys_addr = umap_grant(proc_addr(proc_nr), offset, count);
break;

View File

@@ -11,6 +11,7 @@
#include "../system.h"
#include <minix/devio.h>
#include <minix/endpoint.h>
#include <minix/portio.h>
#if USE_VDEVIO
@@ -112,16 +113,22 @@ register message *m_ptr; /* pointer to request message */
lock(13, "do_vdevio");
switch (io_type) {
case _DIO_BYTE: /* byte values */
if (io_in) for (i=0; i<vec_size; i++) pvb[i].value = inb(pvb[i].port);
else for (i=0; i<vec_size; i++) outb(pvb[i].port, pvb[i].value);
if (io_in) for (i=0; i<vec_size; i++)
pvb[i].value = inb( pvb[i].port);
else for (i=0; i<vec_size; i++)
outb( pvb[i].port, pvb[i].value);
break;
case _DIO_WORD: /* word values */
if (io_in) for (i=0; i<vec_size; i++) pvw[i].value = inw(pvw[i].port);
else for (i=0; i<vec_size; i++) outw(pvw[i].port, pvw[i].value);
if (io_in) for (i=0; i<vec_size; i++)
pvw[i].value = inw( pvw[i].port);
else for (i=0; i<vec_size; i++)
outw( pvw[i].port, pvw[i].value);
break;
default: /* long values */
if (io_in) for (i=0; i<vec_size; i++) pvl[i].value = inl(pvl[i].port);
else for (i=0; i<vec_size; i++) outl(pvb[i].port, pvl[i].value);
if (io_in) for (i=0; i<vec_size; i++)
pvl[i].value = inl(pvl[i].port);
else for (i=0; i<vec_size; i++)
outl( pvb[i].port, pvl[i].value);
}
unlock(13);

View File

@@ -6,23 +6,13 @@
* m4_l2: Map (TRUE) or unmap (FALSE) (VM_MAP_MAPUNMAP)
* m4_l3: Base address (VM_MAP_BASE)
* m4_l4: Size (VM_MAP_SIZE)
* m4_l5: Memory address (VM_MAP_ADDR)
* m4_l5: address (VM_MAP_ADDR)
*/
#include "../system.h"
#include <sys/vm.h>
PRIVATE int vm_needs_init= 1;
PRIVATE u32_t vm_cr3;
FORWARD _PROTOTYPE( void vm_init, (void) );
FORWARD _PROTOTYPE( void phys_put32, (phys_bytes addr, u32_t value) );
FORWARD _PROTOTYPE( u32_t phys_get32, (phys_bytes addr) );
FORWARD _PROTOTYPE( void vm_set_cr3, (u32_t value) );
FORWARD _PROTOTYPE( void set_cr3, (void) );
FORWARD _PROTOTYPE( void vm_enable_paging, (void) );
FORWARD _PROTOTYPE( void map_range, (u32_t base, u32_t size,
u32_t offset) );
#include <sys/vm.h>
/*===========================================================================*
* do_vm_map *
@@ -35,11 +25,10 @@ message *m_ptr; /* pointer to request message */
struct proc *pp;
/* do_serial_debug= 1; */
if (vm_needs_init)
{
vm_needs_init= 0;
vm_init();
vm_needs_init= 0;
vm_init();
}
if (m_ptr->VM_MAP_ENDPT == SELF) {
@@ -63,17 +52,17 @@ message *m_ptr; /* pointer to request message */
{
pp->p_misc_flags |= MF_VM;
map_range(p_phys, size, offset);
vm_map_range(p_phys, size, offset);
}
else
{
map_range(p_phys, size, p_phys);
vm_map_range(p_phys, size, p_phys);
}
vm_set_cr3(vm_cr3);
return OK;
}
/*===========================================================================*
* vm_map_default *
*===========================================================================*/
@@ -88,137 +77,7 @@ struct proc *pp;
base_clicks= pp->p_memmap[D].mem_phys;
size_clicks= pp->p_memmap[S].mem_phys+pp->p_memmap[S].mem_len -
base_clicks;
map_range(base_clicks << CLICK_SHIFT, size_clicks << CLICK_SHIFT,
base_clicks << CLICK_SHIFT);
vm_set_cr3(vm_cr3);
vm_map_range(base_clicks << CLICK_SHIFT,
size_clicks << CLICK_SHIFT, base_clicks << CLICK_SHIFT);
}
PRIVATE void vm_init(void)
{
int o;
phys_bytes p, pt_size;
phys_bytes vm_dir_base, vm_pt_base, phys_mem;
u32_t entry;
unsigned pages;
if (!vm_size)
panic("vm_init: no space for page tables", NO_NUM);
/* Align page directory */
o= (vm_base % PAGE_SIZE);
if (o != 0)
o= PAGE_SIZE-o;
vm_dir_base= vm_base+o;
/* Page tables start after the page directory */
vm_pt_base= vm_dir_base+PAGE_SIZE;
pt_size= (vm_base+vm_size)-vm_pt_base;
pt_size -= (pt_size % PAGE_SIZE);
/* Compute the number of pages based on vm_mem_high */
pages= (vm_mem_high-1)/PAGE_SIZE + 1;
if (pages * I386_VM_PT_ENT_SIZE > pt_size)
panic("vm_init: page table too small", NO_NUM);
for (p= 0; p*I386_VM_PT_ENT_SIZE < pt_size; p++)
{
phys_mem= p*PAGE_SIZE;
entry= phys_mem | I386_VM_USER | I386_VM_WRITE |
I386_VM_PRESENT;
if (phys_mem >= vm_mem_high)
entry= 0;
phys_put32(vm_pt_base + p*I386_VM_PT_ENT_SIZE, entry);
}
for (p= 0; p < I386_VM_DIR_ENTRIES; p++)
{
phys_mem= vm_pt_base + p*PAGE_SIZE;
entry= phys_mem | I386_VM_USER | I386_VM_WRITE |
I386_VM_PRESENT;
if (phys_mem >= vm_pt_base + pt_size)
entry= 0;
phys_put32(vm_dir_base + p*I386_VM_PT_ENT_SIZE, entry);
}
vm_set_cr3(vm_dir_base);
level0(vm_enable_paging);
}
PRIVATE void phys_put32(addr, value)
phys_bytes addr;
u32_t value;
{
phys_copy(vir2phys((vir_bytes)&value), addr, sizeof(value));
}
PRIVATE u32_t phys_get32(addr)
phys_bytes addr;
{
u32_t value;
phys_copy(addr, vir2phys((vir_bytes)&value), sizeof(value));
return value;
}
PRIVATE void vm_set_cr3(value)
u32_t value;
{
vm_cr3= value;
level0(set_cr3);
}
PRIVATE void set_cr3()
{
write_cr3(vm_cr3);
}
PRIVATE void vm_enable_paging(void)
{
u32_t cr0;
cr0= read_cr0();
write_cr0(cr0 | I386_CR0_PG);
}
PRIVATE void map_range(base, size, offset)
u32_t base;
u32_t size;
u32_t offset;
{
u32_t curr_pt, curr_pt_addr, entry;
int dir_ent, pt_ent;
if (base % PAGE_SIZE != 0)
panic("map_range: bad base", base);
if (size % PAGE_SIZE != 0)
panic("map_range: bad size", size);
if (offset % PAGE_SIZE != 0)
panic("map_range: bad offset", offset);
curr_pt= -1;
curr_pt_addr= 0;
while (size != 0)
{
dir_ent= (base >> I386_VM_DIR_ENT_SHIFT);
pt_ent= (base >> I386_VM_PT_ENT_SHIFT) & I386_VM_PT_ENT_MASK;
if (dir_ent != curr_pt)
{
/* Get address of page table */
curr_pt= dir_ent;
curr_pt_addr= phys_get32(vm_cr3 +
dir_ent * I386_VM_PT_ENT_SIZE);
curr_pt_addr &= I386_VM_ADDR_MASK;
}
entry= offset | I386_VM_USER | I386_VM_WRITE |
I386_VM_PRESENT;
#if 0 /* Do we need this for memory mapped I/O? */
entry |= I386_VM_PCD | I386_VM_PWT;
#endif
phys_put32(curr_pt_addr + pt_ent * I386_VM_PT_ENT_SIZE, entry);
offset += PAGE_SIZE;
base += PAGE_SIZE;
size -= PAGE_SIZE;
}
}