Add initial support for the floating point implementation register.
- Save the current FIR in the global 'cpuinfo' structure in a new 'fpu_id' member. - Decode flags in the FIR when displaying other CPU flags during boot. - Use the existing "dummy" slot in the floating point register structure to export the FIR in process core dumps and via ptrace(). Note that while the FIR register is not volatile, this practice of storing the FIR in the floating-point register set is used in other OS's. Reviewed by: kan MFC after: 1 month Sponsored by: DARPA / AFRL Differential Revision: https://reviews.freebsd.org/D10617
This commit is contained in:
parent
d8e073a985
commit
4a0f7f1c10
@ -75,6 +75,7 @@ struct mips_cpuinfo {
|
||||
u_int8_t dc_nways;
|
||||
u_int16_t dc_nsets;
|
||||
} l2;
|
||||
u_int32_t fpu_id;
|
||||
};
|
||||
|
||||
extern struct mips_cpuinfo cpuinfo;
|
||||
|
@ -134,7 +134,7 @@ struct trapframe {
|
||||
f_register_t f30;
|
||||
f_register_t f31;
|
||||
register_t fsr;
|
||||
register_t fdummy;
|
||||
register_t fir;
|
||||
};
|
||||
|
||||
#endif /* !_MACHINE_FRAME_H_ */
|
||||
|
@ -52,6 +52,7 @@ extern int vm_page_dump_size;
|
||||
extern vm_offset_t kstack0;
|
||||
extern vm_offset_t kernel_kseg0_end;
|
||||
|
||||
uint32_t MipsFPID(void);
|
||||
void MipsSaveCurFPState(struct thread *);
|
||||
void fork_trampoline(void);
|
||||
uintptr_t MipsEmulateBranch(struct trapframe *, uintptr_t, int, uintptr_t);
|
||||
|
@ -160,7 +160,7 @@
|
||||
#define F30 (FPBASE+30)
|
||||
#define F31 (FPBASE+31)
|
||||
#define FSR (FPBASE+32)
|
||||
#define FSR_DUMMY (FPBASE+33) /* For 8 byte alignment */
|
||||
#define FIR (FPBASE+33)
|
||||
|
||||
#define NUMFPREGS 34
|
||||
|
||||
@ -204,5 +204,6 @@
|
||||
#define F30_NUM (30)
|
||||
#define F31_NUM (31)
|
||||
#define FSR_NUM (32)
|
||||
#define FIR_NUM (33)
|
||||
|
||||
#endif /* !_MACHINE_REGNUM_H_ */
|
||||
|
@ -184,6 +184,10 @@ mips_get_identity(struct mips_cpuinfo *cpuinfo)
|
||||
cfg3 = mips_rd_config3();
|
||||
}
|
||||
|
||||
/* Save FP implementation revision if FP is present. */
|
||||
if (cfg1 & MIPS_CONFIG1_FP)
|
||||
cpuinfo->fpu_id = MipsFPID();
|
||||
|
||||
/* Check to see if UserLocal register is implemented. */
|
||||
if (cfg3 & MIPS_CONFIG3_ULR) {
|
||||
/* UserLocal register is implemented, enable it. */
|
||||
@ -474,6 +478,19 @@ cpu_identify(void)
|
||||
printf(" Config1=0x%b\n", cfg1,
|
||||
"\20\7COP2\6MDMX\5PerfCount\4WatchRegs\3MIPS16\2EJTAG\1FPU");
|
||||
|
||||
if (cpuinfo.fpu_id != 0)
|
||||
printf(" FPU ID=0x%b\n", cpuinfo.fpu_id,
|
||||
"\020"
|
||||
"\020S"
|
||||
"\021D"
|
||||
"\022PS"
|
||||
"\0233D"
|
||||
"\024W"
|
||||
"\025L"
|
||||
"\026F64"
|
||||
"\0272008"
|
||||
"\034UFRP");
|
||||
|
||||
/* If config register selection 2 does not exist, exit. */
|
||||
if (!(cfg1 & MIPS_CONFIG_CM))
|
||||
return;
|
||||
|
@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm_extern.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/uio.h>
|
||||
#include <machine/cpuinfo.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/sigframe.h>
|
||||
@ -378,7 +379,8 @@ fill_fpregs(struct thread *td, struct fpreg *fpregs)
|
||||
{
|
||||
if (td == PCPU_GET(fpcurthread))
|
||||
MipsSaveCurFPState(td);
|
||||
memcpy(fpregs, &td->td_frame->f0, sizeof(struct fpreg));
|
||||
memcpy(fpregs, &td->td_frame->f0, sizeof(struct fpreg));
|
||||
fpregs->r_regs[FIR_NUM] = cpuinfo.fpu_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -524,6 +524,44 @@ LEAF(MipsSwitchFPState)
|
||||
.set pop
|
||||
END(MipsSwitchFPState)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* MipsFPID --
|
||||
*
|
||||
* Read and return the floating point implementation register.
|
||||
*
|
||||
* uint32_t
|
||||
* MipsFPID(void)
|
||||
*
|
||||
* Results:
|
||||
* Floating point implementation register.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------------
|
||||
*/
|
||||
LEAF(MipsFPID)
|
||||
.set push
|
||||
.set hardfloat
|
||||
mfc0 t1, MIPS_COP_0_STATUS # Save the status register.
|
||||
HAZARD_DELAY
|
||||
#if defined(__mips_n64)
|
||||
or t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR
|
||||
#else
|
||||
or t0, t1, MIPS_SR_COP_1_BIT
|
||||
#endif
|
||||
mtc0 t0, MIPS_COP_0_STATUS # Enable the coprocessor
|
||||
HAZARD_DELAY
|
||||
ITLBNOPFIX
|
||||
cfc1 v0, MIPS_FPU_ID
|
||||
mtc0 t1, MIPS_COP_0_STATUS # Restore the status register.
|
||||
ITLBNOPFIX
|
||||
j ra
|
||||
nop
|
||||
.set pop
|
||||
END(MipsFPID)
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* MipsSaveCurFPState --
|
||||
|
Loading…
Reference in New Issue
Block a user