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:
John Baldwin 2017-05-09 17:35:16 +00:00
parent d8e073a985
commit 4a0f7f1c10
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=318067
7 changed files with 63 additions and 3 deletions

View File

@ -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;

View File

@ -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_ */

View File

@ -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);

View File

@ -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_ */

View File

@ -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;

View File

@ -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;
}

View File

@ -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 --