Restore the ABI of the cpuctl(4) ioctl request CPUCTL_CPUID, use
separate argument structure with added level_type field for CPUID_CPUID_COUNT request. Reviewed by: attilio (previous version) Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
8c0ddf28da
commit
cef789cd61
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=267673
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 30, 2009
|
||||
.Dd June 20, 2014
|
||||
.Dt CPUCTL 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -65,7 +65,7 @@ All of the supported operations are invoked using the
|
||||
.Xr ioctl 2
|
||||
system call.
|
||||
Currently, the following ioctls are defined:
|
||||
.Bl -tag -width CPUCTL_UPDATE
|
||||
.Bl -tag -width CPUCTL_CPUID_COUNT
|
||||
.It Dv CPUCTL_RDMSR Fa cpuctl_msr_args_t *args
|
||||
.It Dv CPUCTL_WRMSR Fa cpuctl_msr_args_t *args
|
||||
Read/write CPU machine specific register.
|
||||
@ -86,29 +86,60 @@ Set/clear MSR bits according to the mask given in the
|
||||
.Va data
|
||||
field.
|
||||
.It Dv CPUCTL_CPUID Fa cpuctl_cpuid_args_t *args
|
||||
.It Dv CPUCTL_CPUID_COUNT Fa cpuctl_cpuid_args_t *args
|
||||
Retrieve CPUID information.
|
||||
Arguments are supplied in
|
||||
the following struct:
|
||||
Arguments are supplied in the following structure:
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
int level; /* CPUID level */
|
||||
uint32_t data[4];
|
||||
} cpuctl_cpuid_args_t;
|
||||
.Ed
|
||||
It is equivalent to the
|
||||
.Dv CPUCTL_CPUID_COUNT
|
||||
request with
|
||||
.Va level_type
|
||||
set to 0.
|
||||
.It Dv CPUCTL_CPUID_COUNT Fa cpuctl_cpuid_count_args_t *args
|
||||
Retrieve CPUID information.
|
||||
Arguments are supplied in the following structure:
|
||||
.Bd -literal
|
||||
typedef struct {
|
||||
int level; /* CPUID level */
|
||||
int level_type; /* CPUID level type */
|
||||
uint32_t data[4];
|
||||
} cpuctl_cpuid_args_t;
|
||||
} cpuctl_cpuid_count_args_t;
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Va level
|
||||
field indicates the CPUID level to retrieve.
|
||||
field indicates the CPUID level to retrieve,
|
||||
it is loaded into the
|
||||
.Va %eax
|
||||
register before the CPUID instruction is executed,
|
||||
The
|
||||
.Va level_type
|
||||
field indicates the CPUID level type to retrieve.
|
||||
It is overriden to 0 for
|
||||
.Va CPUCTL_CPUID .
|
||||
Finally, the
|
||||
field indicates the CPUID level type to retrieve,
|
||||
it is loaded into the
|
||||
.Va %ecx
|
||||
register.
|
||||
.Pp
|
||||
The
|
||||
.Va data
|
||||
field is used to store the received CPUID data.
|
||||
That is,
|
||||
.Va data[0]
|
||||
contains the value of
|
||||
.Va %eax
|
||||
register after the CPUID instruction is executed,
|
||||
.Va data[1]
|
||||
is for
|
||||
.Va %ebx ,
|
||||
.Va data[2]
|
||||
for
|
||||
.Va %ecx ,
|
||||
and
|
||||
.Va data[3]
|
||||
for
|
||||
.Va %edx .
|
||||
.It Dv CPUCTL_UPDATE cpuctl_update_args_t *args
|
||||
Update CPU firmware (microcode).
|
||||
The structure is defined in
|
||||
|
@ -69,7 +69,7 @@ static int cpuctl_do_msr(int cpu, cpuctl_msr_args_t *data, u_long cmd,
|
||||
struct thread *td);
|
||||
static int cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data,
|
||||
struct thread *td);
|
||||
static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_args_t *data,
|
||||
static int cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
|
||||
struct thread *td);
|
||||
static int cpuctl_do_update(int cpu, cpuctl_update_args_t *data,
|
||||
struct thread *td);
|
||||
@ -180,8 +180,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
ret = cpuctl_do_update(cpu, (cpuctl_update_args_t *)data, td);
|
||||
break;
|
||||
case CPUCTL_CPUID_COUNT:
|
||||
ret = cpuctl_do_cpuid_count(cpu, (cpuctl_cpuid_args_t *)data,
|
||||
td);
|
||||
ret = cpuctl_do_cpuid_count(cpu,
|
||||
(cpuctl_cpuid_count_args_t *)data, td);
|
||||
break;
|
||||
default:
|
||||
ret = EINVAL;
|
||||
@ -195,7 +195,8 @@ cpuctl_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
|
||||
* Actually perform cpuid operation.
|
||||
*/
|
||||
static int
|
||||
cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
|
||||
cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_count_args_t *data,
|
||||
struct thread *td)
|
||||
{
|
||||
int is_bound = 0;
|
||||
int oldcpu;
|
||||
@ -218,10 +219,15 @@ cpuctl_do_cpuid_count(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
|
||||
static int
|
||||
cpuctl_do_cpuid(int cpu, cpuctl_cpuid_args_t *data, struct thread *td)
|
||||
{
|
||||
cpuctl_cpuid_count_args_t cdata;
|
||||
int error;
|
||||
|
||||
cdata.level = data->level;
|
||||
/* Override the level type. */
|
||||
data->level_type = 0;
|
||||
return (cpuctl_do_cpuid_count(cpu, data, td));
|
||||
cdata.level_type = 0;
|
||||
error = cpuctl_do_cpuid_count(cpu, &cdata, td);
|
||||
bcopy(cdata.data, data->data, sizeof(data->data)); /* Ignore error */
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -36,10 +36,15 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
int level; /* CPUID level */
|
||||
int level_type; /* CPUID level type */
|
||||
uint32_t data[4];
|
||||
} cpuctl_cpuid_args_t;
|
||||
|
||||
typedef struct {
|
||||
int level; /* CPUID level */
|
||||
int level_type; /* CPUID level type */
|
||||
uint32_t data[4];
|
||||
} cpuctl_cpuid_count_args_t;
|
||||
|
||||
typedef struct {
|
||||
void *data;
|
||||
size_t size;
|
||||
@ -51,6 +56,6 @@ typedef struct {
|
||||
#define CPUCTL_UPDATE _IOWR('c', 4, cpuctl_update_args_t)
|
||||
#define CPUCTL_MSRSBIT _IOWR('c', 5, cpuctl_msr_args_t)
|
||||
#define CPUCTL_MSRCBIT _IOWR('c', 6, cpuctl_msr_args_t)
|
||||
#define CPUCTL_CPUID_COUNT _IOWR('c', 7, cpuctl_cpuid_args_t)
|
||||
#define CPUCTL_CPUID_COUNT _IOWR('c', 7, cpuctl_cpuid_count_args_t)
|
||||
|
||||
#endif /* _CPUCTL_H_ */
|
||||
|
@ -175,7 +175,7 @@ do_cpuid_count(const char *cmdarg, const char *dev)
|
||||
{
|
||||
char *cmdarg1, *endptr, *endptr1;
|
||||
unsigned int level, level_type;
|
||||
cpuctl_cpuid_args_t args;
|
||||
cpuctl_cpuid_count_args_t args;
|
||||
int fd, error;
|
||||
|
||||
assert(cmdarg != NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user