Compare commits
8 Commits
clang-arm-
...
v3.1.7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ec255bb5e | ||
|
|
cd445fe22a | ||
|
|
64b1205e6c | ||
|
|
94881e6d4a | ||
|
|
6677a8c8e0 | ||
|
|
255ad2ab37 | ||
|
|
7dc782dd1a | ||
|
|
e9eb2c4f8b |
@@ -150,7 +150,7 @@
|
||||
/* Some limits. */
|
||||
#define MAX_INODE_NR ((ino_t) 037777777777) /* largest inode number */
|
||||
#define MAX_FILE_POS ((off_t) 0x7FFFFFFF) /* largest legal file offset */
|
||||
#define UMAX_FILE_POS ((unsigned) 0x7FFFFFF) /* largest legal file offset */
|
||||
#define UMAX_FILE_POS ((unsigned) 0x7FFFFFFF) /* largest legal file offset */
|
||||
|
||||
#define MAX_SYM_LOOPS 8 /* how many symbolic links are recursed */
|
||||
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
#include <minix/cpufeature.h>
|
||||
#include <a.out.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <machine/vm.h>
|
||||
|
||||
#include <sys/sigcontext.h>
|
||||
|
||||
#include "archconst.h"
|
||||
#include "proto.h"
|
||||
@@ -23,6 +27,9 @@
|
||||
#include "apic.h"
|
||||
#endif
|
||||
|
||||
PRIVATE int osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
|
||||
|
||||
|
||||
/* set MP and NE flags to handle FPU exceptions in native mode. */
|
||||
#define CR0_MP_NE 0x0022
|
||||
/* set CR4.OSFXSR[bit 9] if FXSR is supported. */
|
||||
@@ -194,6 +201,59 @@ PRIVATE void fpu_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
PUBLIC void save_fpu(struct proc *pr)
|
||||
{
|
||||
if(!fpu_presence)
|
||||
return;
|
||||
|
||||
/* If the process hasn't touched the FPU, there is nothing to do. */
|
||||
|
||||
if(!(pr->p_misc_flags & MF_USED_FPU))
|
||||
return;
|
||||
|
||||
/* Save changed FPU context. */
|
||||
|
||||
if(osfxsr_feature) {
|
||||
fxsave(pr->p_fpu_state.fpu_save_area_p);
|
||||
fninit();
|
||||
} else {
|
||||
fnsave(pr->p_fpu_state.fpu_save_area_p);
|
||||
}
|
||||
|
||||
/* Clear MF_USED_FPU to signal there is no unsaved FPU state. */
|
||||
|
||||
pr->p_misc_flags &= ~MF_USED_FPU;
|
||||
}
|
||||
|
||||
PUBLIC void restore_fpu(struct proc *pr)
|
||||
{
|
||||
/* If the process hasn't touched the FPU, enable the FPU exception
|
||||
* and don't restore anything.
|
||||
*/
|
||||
if(!(pr->p_misc_flags & MF_USED_FPU)) {
|
||||
write_cr0(read_cr0() | I386_CR0_TS);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the process has touched the FPU, disable the FPU
|
||||
* exception (both for the kernel and for the process once
|
||||
* it's scheduled), and initialize or restore the FPU state.
|
||||
*/
|
||||
|
||||
clts();
|
||||
|
||||
if(!(pr->p_misc_flags & MF_FPU_INITIALIZED)) {
|
||||
fninit();
|
||||
pr->p_misc_flags |= MF_FPU_INITIALIZED;
|
||||
} else {
|
||||
if(osfxsr_feature) {
|
||||
fxrstor(pr->p_fpu_state.fpu_save_area_p);
|
||||
} else {
|
||||
frstor(pr->p_fpu_state.fpu_save_area_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUBLIC void arch_init(void)
|
||||
{
|
||||
#ifdef CONFIG_APIC
|
||||
@@ -438,3 +498,36 @@ PUBLIC struct proc * arch_finish_switch_to_user(void)
|
||||
*((reg_t *)stk) = (reg_t) proc_ptr;
|
||||
return proc_ptr;
|
||||
}
|
||||
|
||||
PUBLIC void fpu_sigcontext(struct proc *pr, struct sigframe *fr, struct sigcontext *sc)
|
||||
{
|
||||
int fp_error;
|
||||
|
||||
if (osfxsr_feature) {
|
||||
fp_error = sc->sc_fpu_state.xfp_regs.fp_status &
|
||||
~sc->sc_fpu_state.xfp_regs.fp_control;
|
||||
} else {
|
||||
fp_error = sc->sc_fpu_state.fpu_regs.fp_status &
|
||||
~sc->sc_fpu_state.fpu_regs.fp_control;
|
||||
}
|
||||
|
||||
if (fp_error & 0x001) { /* Invalid op */
|
||||
/*
|
||||
* swd & 0x240 == 0x040: Stack Underflow
|
||||
* swd & 0x240 == 0x240: Stack Overflow
|
||||
* User must clear the SF bit (0x40) if set
|
||||
*/
|
||||
fr->sf_code = FPE_FLTINV;
|
||||
} else if (fp_error & 0x004) {
|
||||
fr->sf_code = FPE_FLTDIV; /* Divide by Zero */
|
||||
} else if (fp_error & 0x008) {
|
||||
fr->sf_code = FPE_FLTOVF; /* Overflow */
|
||||
} else if (fp_error & 0x012) {
|
||||
fr->sf_code = FPE_FLTUND; /* Denormal, Underflow */
|
||||
} else if (fp_error & 0x020) {
|
||||
fr->sf_code = FPE_FLTRES; /* Precision */
|
||||
} else {
|
||||
fr->sf_code = 0; /* XXX - probably should be used for FPE_INTOVF or
|
||||
* FPE_INTDIV */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
.globl _getcr3val
|
||||
.globl _write_cr0 /* write a value in cr0 */
|
||||
.globl _read_cr3
|
||||
.globl _write_cr3
|
||||
.globl _read_cr4
|
||||
.globl _write_cr4
|
||||
|
||||
@@ -50,6 +51,11 @@
|
||||
.globl _fninit /* non-waiting FPU initialization */
|
||||
.globl _fnstsw /* store status word (non-waiting) */
|
||||
.globl _fnstcw /* store control word (non-waiting) */
|
||||
.globl _fxsave
|
||||
.globl _fnsave
|
||||
.globl _fxrstor
|
||||
.globl _frstor
|
||||
.globl _clts
|
||||
|
||||
/*
|
||||
* The routines only guarantee to preserve the registers the C compiler
|
||||
@@ -655,6 +661,10 @@ _fninit:
|
||||
fninit
|
||||
ret
|
||||
|
||||
_clts:
|
||||
clts
|
||||
ret
|
||||
|
||||
_fnstsw:
|
||||
xor %eax, %eax
|
||||
|
||||
@@ -671,6 +681,40 @@ _fnstcw:
|
||||
pop %eax
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* fxsave */
|
||||
/*===========================================================================*/
|
||||
_fxsave:
|
||||
mov 4(%esp), %eax
|
||||
fxsave (%eax) /* Do not change the operand! (gas2ack) */
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* fnsave */
|
||||
/*===========================================================================*/
|
||||
_fnsave:
|
||||
mov 4(%esp), %eax
|
||||
fnsave (%eax) /* Do not change the operand! (gas2ack) */
|
||||
fwait /* required for compatibility with processors prior pentium */
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* fxrstor */
|
||||
/*===========================================================================*/
|
||||
_fxrstor:
|
||||
mov 4(%esp), %eax
|
||||
fxrstor (%eax) /* Do not change the operand! (gas2ack) */
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* frstor */
|
||||
/*===========================================================================*/
|
||||
_frstor:
|
||||
mov 4(%esp), %eax
|
||||
frstor (%eax) /* Do not change the operand! (gas2ack) */
|
||||
ret
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/* read_cr0 */
|
||||
/*===========================================================================*/
|
||||
@@ -745,6 +789,22 @@ _write_cr4:
|
||||
0:
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* write_cr3 */
|
||||
/*===========================================================================*/
|
||||
/* PUBLIC void write_cr3(unsigned long value); */
|
||||
_write_cr3:
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
mov 8(%ebp), %eax
|
||||
|
||||
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
|
||||
mov %eax, %cr3
|
||||
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* getcr3val */
|
||||
/*===========================================================================*/
|
||||
@@ -847,3 +907,4 @@ _switch_address_space:
|
||||
mov %edx, _ptproc
|
||||
0:
|
||||
ret
|
||||
|
||||
|
||||
@@ -45,11 +45,25 @@ PUBLIC void vm_init(struct proc *newptproc)
|
||||
{
|
||||
if(vm_running)
|
||||
panic("vm_init: vm_running");
|
||||
|
||||
/* switch_address_space() checks what is in cr3, and doesn't do
|
||||
* anything if it's the same as the cr3 of its argument, newptproc.
|
||||
* If MINIX was previously booted, this could very well be the case.
|
||||
*
|
||||
* The first time switch_address_space() is called, we want to
|
||||
* force it to do something (load cr3 and set newptproc), so we
|
||||
* zero cr3, and force paging off to make that a safe thing to do.
|
||||
*
|
||||
* After that, vm_enable_paging() enables paging with the page table
|
||||
* of newptproc loaded.
|
||||
*/
|
||||
|
||||
vm_stop();
|
||||
write_cr3(0);
|
||||
switch_address_space(newptproc);
|
||||
assert(ptproc == newptproc);
|
||||
vm_enable_paging();
|
||||
vm_running = 1;
|
||||
|
||||
}
|
||||
|
||||
/* This function sets up a mapping from within the kernel's address
|
||||
@@ -254,6 +268,11 @@ PRIVATE char *cr4_str(u32_t e)
|
||||
return str;
|
||||
}
|
||||
|
||||
PUBLIC void vm_stop(void)
|
||||
{
|
||||
write_cr0(read_cr0() & ~I386_CR0_PG);
|
||||
}
|
||||
|
||||
PRIVATE void vm_enable_paging(void)
|
||||
{
|
||||
u32_t cr0, cr4;
|
||||
@@ -813,7 +832,7 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
||||
|
||||
if((r=lin_lin_copy(procs[_SRC_], phys_addr[_SRC_],
|
||||
procs[_DST_], phys_addr[_DST_], bytes)) != OK) {
|
||||
struct proc *target;
|
||||
struct proc *target = NULL;
|
||||
phys_bytes lin;
|
||||
if(r != EFAULT_SRC && r != EFAULT_DST)
|
||||
panic("lin_lin_copy failed: %d", r);
|
||||
@@ -821,8 +840,6 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
||||
return r;
|
||||
}
|
||||
|
||||
assert(procs[_SRC_] && procs[_DST_]);
|
||||
|
||||
if(r == EFAULT_SRC) {
|
||||
lin = phys_addr[_SRC_];
|
||||
target = procs[_SRC_];
|
||||
@@ -833,6 +850,9 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
||||
panic("r strange: %d", r);
|
||||
}
|
||||
|
||||
assert(caller);
|
||||
assert(target);
|
||||
|
||||
vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL);
|
||||
return VMSUSPEND;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ begbss:
|
||||
.globl _params_offset
|
||||
.globl _mon_ds
|
||||
.globl _switch_to_user
|
||||
.globl _lazy_fpu
|
||||
.globl _save_fpu
|
||||
|
||||
.globl _hwint00 /* handlers for hardware interrupts */
|
||||
.globl _hwint01
|
||||
@@ -589,33 +589,16 @@ _inval_opcode:
|
||||
|
||||
_copr_not_available:
|
||||
TEST_INT_IN_KERNEL(4, copr_not_available_in_kernel)
|
||||
clts
|
||||
cld /* set direction flag to a known value */
|
||||
cld /* set direction flag to a known value */
|
||||
SAVE_PROCESS_CTX_NON_LAZY(0)
|
||||
/* stop user process cycles */
|
||||
push %ebp
|
||||
mov $0, %ebp
|
||||
call _context_stop
|
||||
pop %ebp
|
||||
lea P_MISC_FLAGS(%ebp), %ebx
|
||||
movw (%ebx), %cx
|
||||
and $MF_FPU_INITIALIZED, %cx
|
||||
jnz 0f /* jump if FPU is already initialized */
|
||||
orw $MF_FPU_INITIALIZED, (%ebx)
|
||||
fninit
|
||||
jmp copr_return
|
||||
0: /* load FPU context for current process */
|
||||
mov %ss:FP_SAVE_AREA_P(%ebp), %eax
|
||||
cmp $0, _osfxsr_feature
|
||||
jz fp_l_no_fxsr /* FXSR is not avaible. */
|
||||
|
||||
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
|
||||
fxrstor (%eax)
|
||||
jmp copr_return
|
||||
fp_l_no_fxsr:
|
||||
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
|
||||
frstor (%eax)
|
||||
copr_return:
|
||||
orw $MF_USED_FPU, (%ebx) /* fpu was used during last execution */
|
||||
orw $MF_USED_FPU, (%ebx)
|
||||
mov $0, %ebp
|
||||
jmp _switch_to_user
|
||||
|
||||
copr_not_available_in_kernel:
|
||||
@@ -656,51 +639,6 @@ _machine_check:
|
||||
_simd_exception:
|
||||
EXCEPTION_NO_ERR_CODE(SIMD_EXCEPTION_VECTOR)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* lazy_fpu */
|
||||
/*===========================================================================*/
|
||||
/* void lazy_fpu(struct proc *pptr)
|
||||
* It's called, when we are on kernel stack.
|
||||
* Actualy lazy code is just few lines, which check MF_USED_FPU,
|
||||
* another part is save_init_fpu().
|
||||
*/
|
||||
_lazy_fpu:
|
||||
push %ebp
|
||||
mov %esp, %ebp
|
||||
push %eax
|
||||
push %ebx
|
||||
push %ecx
|
||||
cmp $0, _fpu_presence /* Do we have FPU? */
|
||||
jz no_fpu_available
|
||||
mov 8(%ebp), %eax /* Get pptr */
|
||||
lea P_MISC_FLAGS(%eax), %ebx
|
||||
movw (%ebx), %cx
|
||||
and $MF_USED_FPU, %cx
|
||||
jz 0f /* Don't save FPU */
|
||||
mov %ss:FP_SAVE_AREA_P(%eax), %eax
|
||||
cmp $0, _osfxsr_feature
|
||||
jz fp_s_no_fxsr /* FXSR is not avaible. */
|
||||
|
||||
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
|
||||
fxsave (%eax)
|
||||
fninit
|
||||
jmp fp_saved
|
||||
fp_s_no_fxsr:
|
||||
/* DO NOT CHANGE THE OPERAND!!! gas2ack does not handle it yet */
|
||||
fnsave (%eax)
|
||||
fwait /* required for compatibility with processors prior pentium */
|
||||
fp_saved:
|
||||
andw $~MF_USED_FPU, (%ebx)
|
||||
0: mov %cr0, %eax
|
||||
or $0x00000008, %eax /* Set TS flag */
|
||||
mov %eax, %cr0
|
||||
no_fpu_available:
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
/*===========================================================================*/
|
||||
/* reload_cr3 */
|
||||
/*===========================================================================*/
|
||||
|
||||
@@ -74,6 +74,7 @@ _PROTOTYPE( reg_t read_cr2, (void) );
|
||||
_PROTOTYPE( void write_cr0, (unsigned long value) );
|
||||
_PROTOTYPE( unsigned long read_cr4, (void) );
|
||||
_PROTOTYPE( void write_cr4, (unsigned long value) );
|
||||
_PROTOTYPE( void write_cr3, (unsigned long value) );
|
||||
_PROTOTYPE( unsigned long read_cpu_flags, (void) );
|
||||
_PROTOTYPE( void phys_insb, (u16_t port, phys_bytes buf, size_t count) );
|
||||
_PROTOTYPE( void phys_insw, (u16_t port, phys_bytes buf, size_t count) );
|
||||
@@ -86,6 +87,11 @@ _PROTOTYPE( void reload_ds, (void) );
|
||||
_PROTOTYPE( void ia32_msr_read, (u32_t reg, u32_t * hi, u32_t * lo) );
|
||||
_PROTOTYPE( void ia32_msr_write, (u32_t reg, u32_t hi, u32_t lo) );
|
||||
_PROTOTYPE( void fninit, (void));
|
||||
_PROTOTYPE( void clts, (void));
|
||||
_PROTOTYPE( void fxsave, (void *));
|
||||
_PROTOTYPE( void fnsave, (void *));
|
||||
_PROTOTYPE( void fxrstor, (void *));
|
||||
_PROTOTYPE( void frstor, (void *));
|
||||
_PROTOTYPE( unsigned short fnstsw, (void));
|
||||
_PROTOTYPE( void fnstcw, (unsigned short* cw));
|
||||
|
||||
|
||||
@@ -140,10 +140,18 @@
|
||||
SAVE_TRAP_CTX(displ, %ebp, %esi) ;
|
||||
|
||||
#define SAVE_PROCESS_CTX(displ) \
|
||||
SAVE_PROCESS_CTX_NON_LAZY(displ) ;\
|
||||
SAVE_PROCESS_CTX_NON_LAZY(displ) ;\
|
||||
push %eax ;\
|
||||
push %ebx ;\
|
||||
push %ecx ;\
|
||||
push %edx ;\
|
||||
push %ebp ;\
|
||||
call _lazy_fpu ;\
|
||||
add $4, %esp ;
|
||||
call _save_fpu ;\
|
||||
pop %ebp ;\
|
||||
pop %edx ;\
|
||||
pop %ecx ;\
|
||||
pop %ebx ;\
|
||||
pop %eax ;
|
||||
|
||||
/*
|
||||
* clear the IF flag in eflags which are stored somewhere in memory, e.g. on
|
||||
|
||||
@@ -45,7 +45,6 @@ EXTERN time_t boottime;
|
||||
EXTERN char params_buffer[512]; /* boot monitor parameters */
|
||||
EXTERN int minix_panicing;
|
||||
EXTERN char fpu_presence;
|
||||
EXTERN char osfxsr_feature; /* FXSAVE/FXRSTOR instructions support (SSEx) */
|
||||
EXTERN int verboseboot; /* verbose boot, init'ed in cstart */
|
||||
#define MAGICTEST 0xC0FFEE23
|
||||
EXTERN u32_t magictest; /* global magic number */
|
||||
|
||||
@@ -241,6 +241,7 @@ check_misc_flags:
|
||||
* restore_user_context() carries out the actual mode switch from kernel
|
||||
* to userspace. This function does not return
|
||||
*/
|
||||
restore_fpu(proc_ptr);
|
||||
restore_user_context(proc_ptr);
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
||||
@@ -146,6 +146,7 @@ struct proc {
|
||||
#define proc_is_preempted(p) ((p)->p_rts_flags & RTS_PREEMPTED)
|
||||
#define proc_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM)
|
||||
#define proc_ptr_ok(p) ((p)->p_magic == PMAGIC)
|
||||
#define proc_used_fpu(p) ((p)->p_misc_flags & (MF_FPU_INITIALIZED|MF_USED_FPU))
|
||||
|
||||
/* test whether the process is scheduled by the kernel's default policy */
|
||||
#define proc_kernel_scheduler(p) ((p)->p_scheduler == NULL || \
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <minix/safecopies.h>
|
||||
#include <machine/archtypes.h>
|
||||
#include <sys/sigcontext.h>
|
||||
#include <a.out.h>
|
||||
|
||||
/* Struct declarations. */
|
||||
@@ -28,6 +29,9 @@ _PROTOTYPE( void cycles_accounting_init, (void) );
|
||||
_PROTOTYPE( void context_stop, (struct proc * p) );
|
||||
/* this is a wrapper to make calling it from assembly easier */
|
||||
_PROTOTYPE( void context_stop_idle, (void) );
|
||||
_PROTOTYPE( void restore_fpu, (struct proc *) );
|
||||
_PROTOTYPE( void save_fpu, (struct proc *) );
|
||||
_PROTOTYPE( void fpu_sigcontext, (struct proc *, struct sigframe *fr, struct sigcontext *sc) );
|
||||
|
||||
/* main.c */
|
||||
_PROTOTYPE( void main, (void) );
|
||||
@@ -138,6 +142,7 @@ _PROTOTYPE( int data_copy_vmcheck, (struct proc *,
|
||||
endpoint_t to, vir_bytes to_addr, size_t bytes));
|
||||
_PROTOTYPE( void alloc_segments, (struct proc *rp) );
|
||||
_PROTOTYPE( void vm_init, (struct proc *first) );
|
||||
_PROTOTYPE( void vm_stop, (void) );
|
||||
_PROTOTYPE( phys_bytes umap_local, (register struct proc *rp, int seg,
|
||||
vir_bytes vir_addr, vir_bytes bytes));
|
||||
_PROTOTYPE( phys_bytes umap_remote, (const struct proc* rp, int seg,
|
||||
|
||||
@@ -50,7 +50,6 @@ PUBLIC int do_setalarm(struct proc * caller, message * m_ptr)
|
||||
reset_timer(tp);
|
||||
} else {
|
||||
tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_uptime();
|
||||
assert(tp->tmr_exp_time > get_uptime());
|
||||
set_timer(tp, tp->tmr_exp_time, tp->tmr_func);
|
||||
}
|
||||
return(OK);
|
||||
|
||||
@@ -27,9 +27,6 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
struct sigcontext sc, *scp;
|
||||
struct sigframe fr, *frp;
|
||||
int proc_nr, r;
|
||||
#if (_MINIX_CHIP == _CHIP_INTEL)
|
||||
unsigned short int fp_error;
|
||||
#endif
|
||||
|
||||
if (!isokendpt(m_ptr->SIG_ENDPT, &proc_nr)) return(EINVAL);
|
||||
if (iskerneln(proc_nr)) return(EPERM);
|
||||
@@ -69,38 +66,7 @@ PUBLIC int do_sigsend(struct proc * caller, message * m_ptr)
|
||||
rp->p_reg.fp = (reg_t) &frp->sf_fp;
|
||||
fr.sf_scp = scp;
|
||||
|
||||
#if (_MINIX_CHIP == _CHIP_INTEL)
|
||||
if (osfxsr_feature == 1) {
|
||||
fp_error = sc.sc_fpu_state.xfp_regs.fp_status &
|
||||
~sc.sc_fpu_state.xfp_regs.fp_control;
|
||||
} else {
|
||||
fp_error = sc.sc_fpu_state.fpu_regs.fp_status &
|
||||
~sc.sc_fpu_state.fpu_regs.fp_control;
|
||||
}
|
||||
|
||||
if (fp_error & 0x001) { /* Invalid op */
|
||||
/*
|
||||
* swd & 0x240 == 0x040: Stack Underflow
|
||||
* swd & 0x240 == 0x240: Stack Overflow
|
||||
* User must clear the SF bit (0x40) if set
|
||||
*/
|
||||
fr.sf_code = FPE_FLTINV;
|
||||
} else if (fp_error & 0x004) {
|
||||
fr.sf_code = FPE_FLTDIV; /* Divide by Zero */
|
||||
} else if (fp_error & 0x008) {
|
||||
fr.sf_code = FPE_FLTOVF; /* Overflow */
|
||||
} else if (fp_error & 0x012) {
|
||||
fr.sf_code = FPE_FLTUND; /* Denormal, Underflow */
|
||||
} else if (fp_error & 0x020) {
|
||||
fr.sf_code = FPE_FLTRES; /* Precision */
|
||||
} else {
|
||||
fr.sf_code = 0; /* XXX - probably should be used for FPE_INTOVF or
|
||||
* FPE_INTDIV */
|
||||
}
|
||||
|
||||
#else
|
||||
fr.sf_code = 0;
|
||||
#endif
|
||||
fpu_sigcontext(rp, &fr, &sc);
|
||||
|
||||
fr.sf_signo = smsg.sm_signo;
|
||||
fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
|
||||
|
||||
@@ -226,7 +226,11 @@ register struct inode *rip; /* pointer to inode to be released */
|
||||
if (rip->i_nlinks == NO_LINK) {
|
||||
/* i_nlinks == NO_LINK means free the inode. */
|
||||
/* return all the disk blocks */
|
||||
if (truncate_inode(rip, (off_t) 0) != OK) return;
|
||||
|
||||
/* Ignore errors by truncate_inode in case inode is a block
|
||||
* special or character special file.
|
||||
*/
|
||||
(void) truncate_inode(rip, (off_t) 0);
|
||||
rip->i_mode = I_NOT_ALLOC; /* clear I_TYPE field */
|
||||
rip->i_dirt = DIRTY;
|
||||
free_inode(rip->i_dev, rip->i_num);
|
||||
@@ -257,8 +261,9 @@ PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
|
||||
|
||||
register struct inode *rip;
|
||||
register struct super_block *sp;
|
||||
int major, minor, inumb;
|
||||
int major, minor;
|
||||
bit_t b;
|
||||
ino_t inumb;
|
||||
|
||||
sp = get_super(dev); /* get pointer to super_block */
|
||||
if (sp->s_rd_only) { /* can't allocate an inode on a read only device. */
|
||||
@@ -276,7 +281,7 @@ PUBLIC struct inode *alloc_inode(dev_t dev, mode_t bits)
|
||||
return(NULL);
|
||||
}
|
||||
sp->s_isearch = b; /* next time start here */
|
||||
inumb = (int) b; /* be careful not to pass unshort as param */
|
||||
inumb = (ino_t) b; /* be careful not to pass unshort as param */
|
||||
|
||||
/* Try to acquire a slot in the inode table. */
|
||||
if ((rip = get_inode(NO_DEV, inumb)) == NULL) {
|
||||
@@ -339,7 +344,7 @@ PRIVATE void free_inode(
|
||||
|
||||
/* Locate the appropriate super_block. */
|
||||
sp = get_super(dev);
|
||||
if (inumb > sp->s_ninodes) return;
|
||||
if (inumb == 0 || inumb > sp->s_ninodes) return;
|
||||
b = (bit_t) inumb;
|
||||
free_bit(sp, IMAP, b);
|
||||
if (b < sp->s_isearch) sp->s_isearch = b;
|
||||
|
||||
@@ -245,14 +245,14 @@ char file_name[NAME_MAX]; /* name of file to be removed */
|
||||
{
|
||||
/* Unlink 'file_name'; rip must be the inode of 'file_name' or NULL. */
|
||||
|
||||
ino_t numb; /* inode number */
|
||||
ino_t inumb; /* inode number */
|
||||
int r;
|
||||
|
||||
/* If rip is not NULL, it is used to get faster access to the inode. */
|
||||
if (rip == NULL) {
|
||||
/* Search for file in directory and try to get its inode. */
|
||||
err_code = search_dir(dirp, file_name, &numb, LOOK_UP, IGN_PERM);
|
||||
if (err_code == OK) rip = get_inode(dirp->i_dev, (int) numb);
|
||||
err_code = search_dir(dirp, file_name, &inumb, LOOK_UP, IGN_PERM);
|
||||
if (err_code == OK) rip = get_inode(dirp->i_dev, inumb);
|
||||
if (err_code != OK || rip == NULL) return(err_code);
|
||||
} else {
|
||||
dup_inode(rip); /* inode will be returned with put_inode */
|
||||
@@ -284,7 +284,7 @@ PUBLIC int fs_rename()
|
||||
int odir, ndir; /* TRUE iff {old|new} file is dir */
|
||||
int same_pdir; /* TRUE iff parent dirs are the same */
|
||||
char old_name[NAME_MAX], new_name[NAME_MAX];
|
||||
ino_t numb;
|
||||
ino_t inumb;
|
||||
phys_bytes len;
|
||||
|
||||
/* Copy the last component of the old name */
|
||||
@@ -423,16 +423,16 @@ PUBLIC int fs_rename()
|
||||
* otherwise first try to create the new name entry to make sure
|
||||
* the rename will succeed.
|
||||
*/
|
||||
numb = old_ip->i_num; /* inode number of old file */
|
||||
inumb = old_ip->i_num; /* inode number of old file */
|
||||
|
||||
if(same_pdir) {
|
||||
r = search_dir(old_dirp, old_name, NULL, DELETE, IGN_PERM);
|
||||
/* shouldn't go wrong. */
|
||||
if(r == OK)
|
||||
(void) search_dir(old_dirp, new_name, &numb, ENTER,
|
||||
(void) search_dir(old_dirp, new_name, &inumb, ENTER,
|
||||
IGN_PERM);
|
||||
} else {
|
||||
r = search_dir(new_dirp, new_name, &numb, ENTER, IGN_PERM);
|
||||
r = search_dir(new_dirp, new_name, &inumb, ENTER, IGN_PERM);
|
||||
if(r == OK)
|
||||
(void) search_dir(old_dirp, old_name, NULL, DELETE,
|
||||
IGN_PERM);
|
||||
@@ -443,9 +443,9 @@ PUBLIC int fs_rename()
|
||||
|
||||
if(r == OK && odir && !same_pdir) {
|
||||
/* Update the .. entry in the directory (still points to old_dirp).*/
|
||||
numb = new_dirp->i_num;
|
||||
inumb = new_dirp->i_num;
|
||||
(void) unlink_file(old_ip, NULL, dot2);
|
||||
if(search_dir(old_ip, dot2, &numb, ENTER, IGN_PERM) == OK) {
|
||||
if(search_dir(old_ip, dot2, &inumb, ENTER, IGN_PERM) == OK) {
|
||||
/* New link created. */
|
||||
new_dirp->i_nlinks++;
|
||||
new_dirp->i_dirt = DIRTY;
|
||||
|
||||
@@ -363,7 +363,7 @@ int chk_perm; /* check permissions when string is looked up*/
|
||||
* the directory, find the inode, open it, and return a pointer to its inode
|
||||
* slot.
|
||||
*/
|
||||
ino_t numb;
|
||||
ino_t inumb;
|
||||
struct inode *rip;
|
||||
|
||||
/* If 'string' is empty, return an error. */
|
||||
@@ -376,12 +376,12 @@ int chk_perm; /* check permissions when string is looked up*/
|
||||
if (dirp == NULL) return(NULL);
|
||||
|
||||
/* If 'string' is not present in the directory, signal error. */
|
||||
if ( (err_code = search_dir(dirp, string, &numb, LOOK_UP, chk_perm)) != OK) {
|
||||
if ( (err_code = search_dir(dirp, string, &inumb, LOOK_UP, chk_perm)) != OK) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* The component has been found in the directory. Get inode. */
|
||||
if ( (rip = get_inode(dirp->i_dev, (int) numb)) == NULL) {
|
||||
if ( (rip = get_inode(dirp->i_dev, inumb)) == NULL) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
@@ -468,17 +468,17 @@ char string[NAME_MAX+1]; /* component extracted from 'old_name' */
|
||||
/*===========================================================================*
|
||||
* search_dir *
|
||||
*===========================================================================*/
|
||||
PUBLIC int search_dir(ldir_ptr, string, numb, flag, check_permissions)
|
||||
PUBLIC int search_dir(ldir_ptr, string, inumb, flag, check_permissions)
|
||||
register struct inode *ldir_ptr; /* ptr to inode for dir to search */
|
||||
char string[NAME_MAX]; /* component to search for */
|
||||
ino_t *numb; /* pointer to inode number */
|
||||
ino_t *inumb; /* pointer to inode number */
|
||||
int flag; /* LOOK_UP, ENTER, DELETE or IS_EMPTY */
|
||||
int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||
{
|
||||
/* This function searches the directory whose inode is pointed to by 'ldip':
|
||||
* if (flag == ENTER) enter 'string' in the directory with inode # '*numb';
|
||||
* if (flag == ENTER) enter 'string' in the directory with inode # '*inumb';
|
||||
* if (flag == DELETE) delete 'string' from the directory;
|
||||
* if (flag == LOOK_UP) search for 'string' and return inode # in 'numb';
|
||||
* if (flag == LOOK_UP) search for 'string' and return inode # in 'inumb';
|
||||
* if (flag == IS_EMPTY) return OK if only . and .. in dir else ENOTEMPTY;
|
||||
*
|
||||
* if 'string' is dot1 or dot2, no access permissions are checked.
|
||||
@@ -563,7 +563,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||
ldir_ptr->i_dirt = DIRTY;
|
||||
} else {
|
||||
sp = ldir_ptr->i_sp; /* 'flag' is LOOK_UP */
|
||||
*numb = (ino_t) conv4(sp->s_native,
|
||||
*inumb = (ino_t) conv4(sp->s_native,
|
||||
(int) dp->d_ino);
|
||||
}
|
||||
put_block(bp, DIRECTORY_BLOCK);
|
||||
@@ -603,7 +603,7 @@ int check_permissions; /* check permissions when flag is !IS_EMPTY */
|
||||
(void) memset(dp->d_name, 0, (size_t) NAME_MAX); /* clear entry */
|
||||
for (i = 0; i < NAME_MAX && string[i]; i++) dp->d_name[i] = string[i];
|
||||
sp = ldir_ptr->i_sp;
|
||||
dp->d_ino = conv4(sp->s_native, (int) *numb);
|
||||
dp->d_ino = conv4(sp->s_native, (int) *inumb);
|
||||
bp->b_dirt = DIRTY;
|
||||
put_block(bp, DIRECTORY_BLOCK);
|
||||
ldir_ptr->i_update |= CTIME | MTIME; /* mark mtime for update later */
|
||||
|
||||
@@ -253,6 +253,12 @@ PRIVATE int mount_fs(endpoint_t fs_e)
|
||||
/* Get vnode of mountpoint */
|
||||
if ((vp = eat_path(PATH_NOFLAGS)) == NULL) return(err_code);
|
||||
|
||||
if (vp->v_ref_count != 1) {
|
||||
put_vnode(vp);
|
||||
return(EBUSY);
|
||||
}
|
||||
|
||||
|
||||
/* Tell FS on which vnode it is mounted (glue into mount tree) */
|
||||
if ((r = req_mountpoint(vp->v_fs_e, vp->v_inode_nr)) != OK) {
|
||||
put_vnode(vp);
|
||||
|
||||
@@ -51,7 +51,7 @@ image: includes
|
||||
|
||||
# rebuild the program or system libraries
|
||||
includes:
|
||||
cd ../include && $(MAKE) install
|
||||
cd .. && $(MAKE) includes
|
||||
|
||||
depend: includes
|
||||
cd ../ && $(MAKE) depend
|
||||
|
||||
@@ -32,7 +32,6 @@ flex-2.5.4
|
||||
fltk-1.1.7
|
||||
fltk-2.0.0-5220
|
||||
gawk-3.1.4
|
||||
gcc-4.1.1
|
||||
gcc-4.4.3
|
||||
gcc-libs
|
||||
gettext-0.14
|
||||
|
||||
Reference in New Issue
Block a user