Merge branch 'master' into kqueue
This commit is contained in:
commit
d676463c2e
5
UPDATING
5
UPDATING
@ -31,6 +31,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20190219:
|
||||
drm and drm2 have been removed from the tree. Please see
|
||||
https://wiki.freebsd.org/Graphics for the latest information on
|
||||
migrating to the drm ports.
|
||||
|
||||
20190131:
|
||||
Iflib is no longer unconditionally compiled into the kernel. Drivers
|
||||
using iflib and statically compiled into the kernel, now require
|
||||
|
@ -472,10 +472,31 @@ str_to_event(const char *str, int last)
|
||||
int
|
||||
bindcmd(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
FILE *old;
|
||||
FILE *out;
|
||||
|
||||
if (el == NULL)
|
||||
error("line editing is disabled");
|
||||
return (el_parse(el, argc, __DECONST(const char **, argv)));
|
||||
|
||||
INTOFF;
|
||||
|
||||
out = out1fp();
|
||||
if (out == NULL)
|
||||
error("Out of space");
|
||||
|
||||
el_get(el, EL_GETFP, 1, &old);
|
||||
el_set(el, EL_SETFP, 1, out);
|
||||
|
||||
ret = el_parse(el, argc, __DECONST(const char **, argv));
|
||||
|
||||
el_set(el, EL_SETFP, 1, old);
|
||||
|
||||
fclose(out);
|
||||
|
||||
INTON;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -340,6 +340,12 @@ doformat(struct output *dest, const char *f, va_list ap)
|
||||
}
|
||||
}
|
||||
|
||||
FILE *
|
||||
out1fp(void)
|
||||
{
|
||||
return fwopen(out1, doformat_wr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of write which resumes after a signal is caught.
|
||||
*/
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct output {
|
||||
char *nextc;
|
||||
@ -75,6 +76,7 @@ void out1fmt(const char *, ...) __printflike(1, 2);
|
||||
void out2fmt_flush(const char *, ...) __printflike(1, 2);
|
||||
void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
|
||||
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
|
||||
FILE *out1fp(void);
|
||||
int xwrite(int, const char *, int);
|
||||
|
||||
#define outc(c, file) ((file)->nextc == (file)->bufend ? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
|
||||
|
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 27, 2018
|
||||
.Dd February 20, 2019
|
||||
.Dt ZPOOL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -187,7 +187,7 @@
|
||||
.Op Ar device ...
|
||||
.Nm
|
||||
.Cm status
|
||||
.Op Fl vx
|
||||
.Op Fl Dvx
|
||||
.Op Fl T Cm d Ns | Ns Cm u
|
||||
.Op Ar pool
|
||||
.Ar ...
|
||||
@ -1862,7 +1862,7 @@ section, above, for more information on the available pool properties.
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm status
|
||||
.Op Fl vx
|
||||
.Op Fl Dvx
|
||||
.Op Fl T Cm d Ns | Ns Cm u
|
||||
.Op Ar pool
|
||||
.Ar ...
|
||||
@ -1891,14 +1891,12 @@ done and the estimated time to completion. Both of these are only approximate,
|
||||
because the amount of data in the pool and the other workloads on the system
|
||||
can change.
|
||||
.Bl -tag -width indent
|
||||
.It Fl x
|
||||
Only display status for pools that are exhibiting errors or are otherwise
|
||||
unavailable.
|
||||
Warnings about pools not using the latest on-disk format, having non-native
|
||||
block size or disabled features will not be included.
|
||||
.It Fl v
|
||||
Displays verbose data error information, printing out a complete list of all
|
||||
data errors since the last complete pool scrub.
|
||||
.It Fl D
|
||||
Display a histogram of deduplication statistics, showing the allocated
|
||||
.Pq physically present on disk
|
||||
and referenced
|
||||
.Pq logically referenced in the pool
|
||||
block counts and sizes by reference count.
|
||||
.It Fl T Cm d Ns | Ns Cm u
|
||||
Print a timestamp.
|
||||
.Pp
|
||||
@ -1910,6 +1908,14 @@ Use modifier
|
||||
.Cm u
|
||||
for unixtime
|
||||
.Pq equals Qq Ic date +%s .
|
||||
.It Fl v
|
||||
Displays verbose data error information, printing out a complete list of all
|
||||
data errors since the last complete pool scrub.
|
||||
.It Fl x
|
||||
Only display status for pools that are exhibiting errors or are otherwise
|
||||
unavailable.
|
||||
Warnings about pools not using the latest on-disk format, having non-native
|
||||
block size or disabled features will not be included.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
@ -3040,9 +3040,6 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
|
||||
break;
|
||||
|
||||
timestamp = dt_buf_oldest(buf, dtp);
|
||||
assert(timestamp >= dtp->dt_last_timestamp);
|
||||
dtp->dt_last_timestamp = timestamp;
|
||||
|
||||
if (timestamp == buf->dtbd_timestamp) {
|
||||
/*
|
||||
* We've reached the end of the time covered
|
||||
@ -3056,6 +3053,8 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
assert(timestamp >= dtp->dt_last_timestamp);
|
||||
dtp->dt_last_timestamp = timestamp;
|
||||
|
||||
if ((rval = dt_consume_cpu(dtp, fp,
|
||||
buf->dtbd_cpu, buf, B_TRUE, pf, rf, arg)) != 0)
|
||||
|
@ -79,8 +79,13 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
||||
* immediately retry the allocation.
|
||||
*/
|
||||
tq->tq_maxalloc_wait++;
|
||||
#ifdef __FreeBSD__
|
||||
rv = cv_timedwait(&tq->tq_maxalloc_cv,
|
||||
&tq->tq_lock, hz);
|
||||
#else
|
||||
rv = cv_timedwait(&tq->tq_maxalloc_cv,
|
||||
&tq->tq_lock, ddi_get_lbolt() + hz);
|
||||
#endif
|
||||
tq->tq_maxalloc_wait--;
|
||||
if (rv > 0)
|
||||
goto again; /* signaled */
|
||||
|
@ -1230,8 +1230,6 @@ _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<w
|
||||
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
|
||||
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
|
||||
|
||||
template <size_t _Np>
|
||||
struct __narrow_to_utf8
|
||||
{
|
||||
|
@ -70,6 +70,14 @@ static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
|
||||
|
||||
RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
|
||||
const uint8_t *Loc) const {
|
||||
// There are 4 different TLS variable models with varying degrees of
|
||||
// flexibility and performance. LocalExec and InitialExec models are fast but
|
||||
// less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the
|
||||
// dynamic section to let runtime know about that.
|
||||
if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
|
||||
Type == R_386_TLS_GOTIE)
|
||||
Config->HasStaticTlsModel = true;
|
||||
|
||||
switch (Type) {
|
||||
case R_386_8:
|
||||
case R_386_16:
|
||||
|
@ -76,6 +76,9 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
|
||||
template <class ELFT>
|
||||
RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
|
||||
const uint8_t *Loc) const {
|
||||
if (Type == R_X86_64_GOTTPOFF)
|
||||
Config->HasStaticTlsModel = true;
|
||||
|
||||
switch (Type) {
|
||||
case R_X86_64_8:
|
||||
case R_X86_64_16:
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/Support/CachePruning.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
namespace lld {
|
||||
@ -81,6 +82,7 @@ struct VersionDefinition {
|
||||
// and such fields have the same name as the corresponding options.
|
||||
// Most fields are initialized by the driver.
|
||||
struct Configuration {
|
||||
std::atomic<bool> HasStaticTlsModel{false};
|
||||
uint8_t OSABI = 0;
|
||||
llvm::CachePruningPolicy ThinLTOCachePolicy;
|
||||
llvm::StringMap<uint64_t> SectionStartMap;
|
||||
|
@ -1282,6 +1282,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
|
||||
}
|
||||
if (!Config->ZText)
|
||||
DtFlags |= DF_TEXTREL;
|
||||
if (Config->HasStaticTlsModel)
|
||||
DtFlags |= DF_STATIC_TLS;
|
||||
|
||||
if (DtFlags)
|
||||
addInt(DT_FLAGS, DtFlags);
|
||||
|
@ -18,7 +18,7 @@
|
||||
.Nd secure copy (remote file copy program)
|
||||
.Sh SYNOPSIS
|
||||
.Nm scp
|
||||
.Op Fl 346BCpqrv
|
||||
.Op Fl 346BCpqrTv
|
||||
.Op Fl c Ar cipher
|
||||
.Op Fl F Ar ssh_config
|
||||
.Op Fl i Ar identity_file
|
||||
@ -207,6 +207,16 @@ to use for the encrypted connection.
|
||||
The program must understand
|
||||
.Xr ssh 1
|
||||
options.
|
||||
.It Fl T
|
||||
Disable strict filename checking.
|
||||
By default when copying files from a remote host to a local directory
|
||||
.Nm
|
||||
checks that the received filenames match those requested on the command-line
|
||||
to prevent the remote end from sending unexpected or unwanted files.
|
||||
Because of differences in how various operating systems and shells interpret
|
||||
filename wildcards, these checks may cause wanted files to be rejected.
|
||||
This option disables these checks at the expense of fully trusting that
|
||||
the server will not send unexpected filenames.
|
||||
.It Fl v
|
||||
Verbose mode.
|
||||
Causes
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: scp.c,v 1.197 2018/06/01 04:31:48 dtucker Exp $ */
|
||||
/* $OpenBSD: scp.c,v 1.203 2019/01/27 07:14:11 jmc Exp $ */
|
||||
/*
|
||||
* scp - secure remote copy. This is basically patched BSD rcp which
|
||||
* uses ssh to do the data transfer (instead of using rcmd).
|
||||
@ -94,6 +94,7 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <pwd.h>
|
||||
@ -375,14 +376,14 @@ void verifydir(char *);
|
||||
struct passwd *pwd;
|
||||
uid_t userid;
|
||||
int errs, remin, remout;
|
||||
int pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
||||
int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
||||
|
||||
#define CMDNEEDS 64
|
||||
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
|
||||
|
||||
int response(void);
|
||||
void rsource(char *, struct stat *);
|
||||
void sink(int, char *[]);
|
||||
void sink(int, char *[], const char *);
|
||||
void source(int, char *[]);
|
||||
void tolocal(int, char *[]);
|
||||
void toremote(int, char *[]);
|
||||
@ -421,8 +422,9 @@ main(int argc, char **argv)
|
||||
addargs(&args, "-oRemoteCommand=none");
|
||||
addargs(&args, "-oRequestTTY=no");
|
||||
|
||||
fflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1)
|
||||
fflag = Tflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv,
|
||||
"dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) {
|
||||
switch (ch) {
|
||||
/* User-visible flags. */
|
||||
case '1':
|
||||
@ -501,9 +503,13 @@ main(int argc, char **argv)
|
||||
setmode(0, O_BINARY);
|
||||
#endif
|
||||
break;
|
||||
case 'T':
|
||||
Tflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
@ -534,7 +540,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
if (tflag) {
|
||||
/* Receive data. */
|
||||
sink(argc, argv);
|
||||
sink(argc, argv, NULL);
|
||||
exit(errs != 0);
|
||||
}
|
||||
if (argc < 2)
|
||||
@ -791,7 +797,7 @@ tolocal(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
free(bp);
|
||||
sink(1, argv + argc - 1);
|
||||
sink(1, argv + argc - 1, src);
|
||||
(void) close(remin);
|
||||
remin = remout = -1;
|
||||
}
|
||||
@ -967,7 +973,7 @@ rsource(char *name, struct stat *statp)
|
||||
(sizeof(type) != 4 && sizeof(type) != 8))
|
||||
|
||||
void
|
||||
sink(int argc, char **argv)
|
||||
sink(int argc, char **argv, const char *src)
|
||||
{
|
||||
static BUF buffer;
|
||||
struct stat stb;
|
||||
@ -983,6 +989,7 @@ sink(int argc, char **argv)
|
||||
unsigned long long ull;
|
||||
int setimes, targisdir, wrerrno = 0;
|
||||
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
|
||||
char *src_copy = NULL, *restrict_pattern = NULL;
|
||||
struct timeval tv[2];
|
||||
|
||||
#define atime tv[0]
|
||||
@ -1007,6 +1014,17 @@ sink(int argc, char **argv)
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
||||
targisdir = 1;
|
||||
if (src != NULL && !iamrecursive && !Tflag) {
|
||||
/*
|
||||
* Prepare to try to restrict incoming filenames to match
|
||||
* the requested destination file glob.
|
||||
*/
|
||||
if ((src_copy = strdup(src)) == NULL)
|
||||
fatal("strdup failed");
|
||||
if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) {
|
||||
*restrict_pattern++ = '\0';
|
||||
}
|
||||
}
|
||||
for (first = 1;; first = 0) {
|
||||
cp = buf;
|
||||
if (atomicio(read, remin, cp, 1) != 1)
|
||||
@ -1111,6 +1129,9 @@ sink(int argc, char **argv)
|
||||
run_err("error: unexpected filename: %s", cp);
|
||||
exit(1);
|
||||
}
|
||||
if (restrict_pattern != NULL &&
|
||||
fnmatch(restrict_pattern, cp, 0) != 0)
|
||||
SCREWUP("filename does not match request");
|
||||
if (targisdir) {
|
||||
static char *namebuf;
|
||||
static size_t cursize;
|
||||
@ -1148,7 +1169,7 @@ sink(int argc, char **argv)
|
||||
goto bad;
|
||||
}
|
||||
vect[0] = xstrdup(np);
|
||||
sink(1, vect);
|
||||
sink(1, vect, src);
|
||||
if (setimes) {
|
||||
setimes = 0;
|
||||
if (utimes(vect[0], tv) < 0)
|
||||
@ -1316,7 +1337,7 @@ void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
"usage: scp [-346BCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
" [-l limit] [-o ssh_option] [-P port] [-S program] source ... target\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -44,6 +44,13 @@ FBSD_1.0 {
|
||||
vfork;
|
||||
};
|
||||
|
||||
FBSD_1.6 {
|
||||
x86_pkru_get_perm;
|
||||
x86_pkru_set_perm;
|
||||
x86_pkru_protect_range;
|
||||
x86_pkru_unprotect_range;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* FreeBSD private ABI
|
||||
|
@ -46,6 +46,13 @@ FBSD_1.0 {
|
||||
___tls_get_addr;
|
||||
};
|
||||
|
||||
FBSD_1.6 {
|
||||
x86_pkru_get_perm;
|
||||
x86_pkru_set_perm;
|
||||
x86_pkru_protect_range;
|
||||
x86_pkru_unprotect_range;
|
||||
};
|
||||
|
||||
FBSDprivate_1.0 {
|
||||
/* PSEUDO syscalls */
|
||||
_getlogin;
|
||||
|
@ -70,7 +70,6 @@ _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask)
|
||||
{
|
||||
acl_t acl_new, acl_old;
|
||||
acl_entry_t entry, entry_new;
|
||||
acl_permset_t perm;
|
||||
acl_tag_t tag;
|
||||
int entry_id, have_mask_entry;
|
||||
|
||||
@ -104,16 +103,8 @@ _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask)
|
||||
case ACL_USER_OBJ:
|
||||
case ACL_GROUP_OBJ:
|
||||
case ACL_OTHER:
|
||||
if (acl_get_tag_type(entry, &tag) == -1)
|
||||
goto fail;
|
||||
if (acl_get_permset(entry, &perm) == -1)
|
||||
goto fail;
|
||||
if (acl_create_entry(&acl_new, &entry_new) == -1)
|
||||
goto fail;
|
||||
if (acl_set_tag_type(entry_new, tag) == -1)
|
||||
goto fail;
|
||||
if (acl_set_permset(entry_new, perm) == -1)
|
||||
goto fail;
|
||||
if (acl_copy_entry(entry_new, entry) == -1)
|
||||
goto fail;
|
||||
assert(_entry_brand(entry_new) == ACL_BRAND_POSIX);
|
||||
|
@ -156,6 +156,8 @@ setup_client(int domain, int type, int port)
|
||||
"Will try to connect to host='%s', address_family=%d, "
|
||||
"socket_type=%d\n",
|
||||
host, res->ai_family, res->ai_socktype);
|
||||
/* Avoid a double print when forked by flushing. */
|
||||
fflush(stdout);
|
||||
sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
@ -187,6 +189,8 @@ setup_server(int domain, int type, int port)
|
||||
"Will try to bind socket to host='%s', address_family=%d, "
|
||||
"socket_type=%d\n",
|
||||
host, res->ai_family, res->ai_socktype);
|
||||
/* Avoid a double print when forked by flushing. */
|
||||
fflush(stdout);
|
||||
error = bind(sock, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno));
|
||||
@ -204,11 +208,17 @@ setup_server(int domain, int type, int port)
|
||||
static void
|
||||
server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||
{
|
||||
char *buffer;
|
||||
char *buffer, *buf_window_ptr;
|
||||
int recv_sock;
|
||||
ssize_t received_bytes;
|
||||
size_t buffer_size;
|
||||
ssize_t received_bytes, recv_ret;
|
||||
|
||||
buffer = calloc(len + 1, sizeof(char));
|
||||
/*
|
||||
* Ensure that there isn't excess data sent across the wire by
|
||||
* capturing 10 extra bytes (plus 1 for nul).
|
||||
*/
|
||||
buffer_size = len + 10 + 1;
|
||||
buffer = calloc(buffer_size, sizeof(char));
|
||||
if (buffer == NULL)
|
||||
err(1, "malloc failed");
|
||||
|
||||
@ -216,32 +226,26 @@ server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||
if (recv_sock == -1)
|
||||
err(1, "accept failed");
|
||||
|
||||
/*
|
||||
* XXX: this assumes the simplest case where all data is received in a
|
||||
* single recv(2) call.
|
||||
*/
|
||||
if (recv(recv_sock, buffer, len, 0) == -1)
|
||||
err(1, "recv failed");
|
||||
buf_window_ptr = buffer;
|
||||
received_bytes = 0;
|
||||
do {
|
||||
recv_ret = recv(recv_sock, buf_window_ptr,
|
||||
buffer_size - received_bytes, 0);
|
||||
if (recv_ret <= 0)
|
||||
break;
|
||||
buf_window_ptr += recv_ret;
|
||||
received_bytes += recv_ret;
|
||||
} while (received_bytes < buffer_size);
|
||||
|
||||
atf_utils_create_file(dest_filename, "%s", buffer);
|
||||
|
||||
/*
|
||||
* This recv(2) call helps ensure the amount of sent data is exactly
|
||||
* what was specified by `len`.
|
||||
*/
|
||||
received_bytes = recv(recv_sock, buffer, len, 0);
|
||||
switch (received_bytes) {
|
||||
case -1:
|
||||
err(1, "recv failed");
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
errx(1, "received unexpected data: %s", buffer);
|
||||
}
|
||||
|
||||
(void)close(recv_sock);
|
||||
(void)close(server_sock);
|
||||
free(buffer);
|
||||
|
||||
if (received_bytes != len)
|
||||
errx(1, "received unexpected data: %zd != %zd", received_bytes,
|
||||
len);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -667,10 +671,6 @@ hdtr_positive_test(int domain)
|
||||
offset = 0;
|
||||
nbytes = 0;
|
||||
|
||||
atf_tc_expect_fail(
|
||||
"The header/trailer testcases fail today with a data mismatch; "
|
||||
"bug # 234809");
|
||||
|
||||
for (i = 0; i < nitems(testcases); i++) {
|
||||
struct sf_hdtr hdtr;
|
||||
char *pattern;
|
||||
|
@ -3,7 +3,11 @@
|
||||
.PATH: ${LIBC_SRCTOP}/x86/sys
|
||||
|
||||
SRCS+= \
|
||||
__vdso_gettc.c
|
||||
__vdso_gettc.c \
|
||||
pkru.c
|
||||
|
||||
MAN+= \
|
||||
pkru.3
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64" && ${MK_HYPERV} != "no"
|
||||
CFLAGS+= -DWANT_HYPERV
|
||||
|
206
lib/libc/x86/sys/pkru.3
Normal file
206
lib/libc/x86/sys/pkru.3
Normal file
@ -0,0 +1,206 @@
|
||||
.\" Copyright (c) 2019 The FreeBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This documentation was written by
|
||||
.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
|
||||
.\" from the FreeBSD Foundation.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 16, 2019
|
||||
.Dt PKRU 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm Protection Key Rights for User pages
|
||||
.Nd provide fast user-managed key-based access control for pages
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In machine/sysarch.h
|
||||
.Ft int
|
||||
.Fn x86_pkru_get_perm "unsigned int keyidx" "int *access" "int *modify"
|
||||
.Ft int
|
||||
.Fn x86_pkru_set_perm "unsigned int keyidx" "int access" "int modify"
|
||||
.Ft int
|
||||
.Fo x86_pkru_protect_range
|
||||
.Fa "void *addr"
|
||||
.Fa "unsigned long len"
|
||||
.Fa "unsigned int keyidx"
|
||||
.Fa "int flag"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn x86_pkru_unprotect_range "void *addr" "unsigned long len"
|
||||
.Sh DESCRIPTION
|
||||
The protection keys feature provides an additional mechanism, besides the
|
||||
normal page permissions as established by
|
||||
.Xr mmap 2
|
||||
and
|
||||
.Xr mprotect 2 ,
|
||||
to control access to user-mode addresses.
|
||||
The mechanism gives safety measures which can be used to avoid
|
||||
incidental read or modification of sensitive memory,
|
||||
or as a debugging feature.
|
||||
It cannot guard against conscious accesses since permissions
|
||||
are user-controllable.
|
||||
.Pp
|
||||
If supported by hardware, each mapped user linear address
|
||||
has an associated 4-bit protection key.
|
||||
A new per-thread PKRU hardware register determines, for each protection
|
||||
key, whether user-mode addresses with that protection key may be
|
||||
read or written.
|
||||
.Pp
|
||||
Only one key may apply to a given range at a time.
|
||||
The default protection key index is zero, it is used even if no key
|
||||
was explicitly assigned to the address, or if the key was removed.
|
||||
.Pp
|
||||
The protection prevents the system from accessing user addresses as well
|
||||
as the user applications.
|
||||
When a system call was unable to read or write user memory due to key
|
||||
protection, it returns the
|
||||
.Er EFAULT
|
||||
error code.
|
||||
Note that some side effects may have occurred if this error is reported.
|
||||
.Pp
|
||||
Protection keys require that the system uses 4-level paging
|
||||
(also called long mode),
|
||||
which means that it is only available on amd64 system.
|
||||
Both 64-bit and 32-bit applications can use protection keys.
|
||||
More information about the hardware feature is provided in the IA32 Software
|
||||
Developer's Manual published by Intel Corp.
|
||||
.Pp
|
||||
The key indexes written into the page table entries are managed by the
|
||||
.Fn sysarch
|
||||
syscall.
|
||||
Per-key permissions are managed using the user-mode instructions
|
||||
.Em RDPKRU
|
||||
and
|
||||
.Em WRPKRU.
|
||||
The system provides convenient library helpers for both the syscall and
|
||||
the instructions, described below.
|
||||
.Pp
|
||||
The
|
||||
.Fn x86_pkru_protect_range
|
||||
function assigns key
|
||||
.Fa keyidx
|
||||
to the range starting at
|
||||
.Fa addr
|
||||
and having length
|
||||
.Fa len .
|
||||
Starting address is truncated to the page start,
|
||||
and the end is rounded up to the end of the page.
|
||||
After a successfull call, the range has the specified key assigned,
|
||||
even if the key is zero and it did not change the page table entries.
|
||||
.Pp
|
||||
The
|
||||
.Fa flags
|
||||
argument takes the logical OR of the following values:
|
||||
.Bl -tag -width
|
||||
.It Bq Va AMD64_PKRU_EXCL
|
||||
Only assign the key if the range does not have any other keys assigned
|
||||
(including the zero key).
|
||||
You must first remove any existing key with
|
||||
.Fn x86_pkru_unprotect_range
|
||||
in order for this request to succeed.
|
||||
If the
|
||||
.Va AMD64_PKRU_EXCL
|
||||
flag is not specified,
|
||||
.Fn x86_pkru_protect_range
|
||||
replaces any existing key.
|
||||
.It Bq Va AMD64_PKRU_PERSIST
|
||||
The keys assigned to the range are persistent.
|
||||
They are re-established when the current mapping is destroyed
|
||||
and a new mapping is created in any sub-range of the specified range.
|
||||
You must use a
|
||||
.Fn x86_pkru_unprotect_range
|
||||
call to forget the key.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn x86_pkru_unprotect_range
|
||||
function removes any keys assigned to the specified range.
|
||||
Existing mappings are changed to use key index zero in page table entries.
|
||||
Keys are no longer considered installed for all mappings in the range,
|
||||
for the purposes of
|
||||
.Fn x86_pkru_protect_range
|
||||
with the
|
||||
.Va AMD64_PKRU_EXCL
|
||||
flag.
|
||||
.Pp
|
||||
The
|
||||
.Fn x86_pkru_get_perm
|
||||
function returns access rights for the key specified by the
|
||||
.Fn keyidx
|
||||
argument.
|
||||
If the value pointed to by
|
||||
.Fa access
|
||||
is zero after the call, no read or write permissions is granted for
|
||||
mappings which are assigned the key
|
||||
.Fn keyidx .
|
||||
If
|
||||
.Fa access
|
||||
is not zero, read access is permitted.
|
||||
The non-zero value of the variable pointed to by the
|
||||
.Fa modify
|
||||
argument indicates that write access is permitted.
|
||||
.Pp
|
||||
Conversely, the
|
||||
.Fn x86_pkru_set_perm
|
||||
establishes the access and modify permissions for the given key index
|
||||
as specified by its arguments.
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std
|
||||
.Sh ERRORS
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EOPNOTSUPP
|
||||
The hardware does not support protection keys.
|
||||
.It Bq Er EINVAL
|
||||
The supplied key index is invalid (greater than 15).
|
||||
.It Bq Er EINVAL
|
||||
The supplied
|
||||
.Fa flags
|
||||
argument for
|
||||
.Fn x86_pkru_protect_range
|
||||
has reserved bits set.
|
||||
.It Bq Er EFAULT
|
||||
The supplied address range does not completely fit into the user-managed
|
||||
address range.
|
||||
.It Bq Er ENOMEM
|
||||
The memory shortage prevents the completion of the operation.
|
||||
.It Bq Er EBUSY
|
||||
The
|
||||
.Va AMD64_PKRU_EXCL
|
||||
flag was specified for
|
||||
.Fn x86_pkru_protect_range
|
||||
and the range already has defined protection keys.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mmap 2 ,
|
||||
.Xr mprotect 2 ,
|
||||
.Xr munmap 2 ,
|
||||
.Xr sysarch 2 .
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
functions are non-standard and first appeared in
|
||||
.Fx 13.0 .
|
138
lib/libc/x86/sys/pkru.c
Normal file
138
lib/libc/x86/sys/pkru.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*-
|
||||
* Copyright (c) 2019 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Konstantin Belousov
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/sysarch.h>
|
||||
#include <x86/ifunc.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_PKRU_IDX 0xf
|
||||
#ifdef __i386__
|
||||
#define X86_SET_PKRU I386_SET_PKRU
|
||||
#define X86_CLEAR_PKRU I386_CLEAR_PKRU
|
||||
#else
|
||||
#define X86_SET_PKRU AMD64_SET_PKRU
|
||||
#define X86_CLEAR_PKRU AMD64_CLEAR_PKRU
|
||||
#endif
|
||||
|
||||
static int
|
||||
x86_pkru_get_perm_unsup(u_int keyidx, int *access, int *modify)
|
||||
{
|
||||
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
x86_pkru_get_perm_hw(u_int keyidx, int *access, int *modify)
|
||||
{
|
||||
uint32_t pkru;
|
||||
|
||||
if (keyidx > MAX_PKRU_IDX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
keyidx *= 2;
|
||||
pkru = rdpkru();
|
||||
*access = (pkru & (1 << keyidx)) == 0;
|
||||
*modify = (pkru & (2 << keyidx)) == 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEFINE_UIFUNC(, int, x86_pkru_get_perm, (u_int, int *, int *), static)
|
||||
{
|
||||
|
||||
return ((cpu_stdext_feature2 & CPUID_STDEXT2_OSPKE) == 0 ?
|
||||
x86_pkru_get_perm_unsup : x86_pkru_get_perm_hw);
|
||||
}
|
||||
|
||||
static int
|
||||
x86_pkru_set_perm_unsup(u_int keyidx, int access, int modify)
|
||||
{
|
||||
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
x86_pkru_set_perm_hw(u_int keyidx, int access, int modify)
|
||||
{
|
||||
uint32_t pkru;
|
||||
|
||||
if (keyidx > MAX_PKRU_IDX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
keyidx *= 2;
|
||||
pkru = rdpkru();
|
||||
pkru &= ~(3 << keyidx);
|
||||
if (!access)
|
||||
pkru |= 1 << keyidx;
|
||||
if (!modify)
|
||||
pkru |= 2 << keyidx;
|
||||
wrpkru(pkru);
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEFINE_UIFUNC(, int, x86_pkru_set_perm, (u_int, int, int), static)
|
||||
{
|
||||
|
||||
return ((cpu_stdext_feature2 & CPUID_STDEXT2_OSPKE) == 0 ?
|
||||
x86_pkru_set_perm_unsup : x86_pkru_set_perm_hw);
|
||||
}
|
||||
|
||||
int
|
||||
x86_pkru_protect_range(void *addr, unsigned long len, u_int keyidx, int flags)
|
||||
{
|
||||
struct amd64_set_pkru a64pkru;
|
||||
|
||||
memset(&a64pkru, 0, sizeof(a64pkru));
|
||||
a64pkru.addr = addr;
|
||||
a64pkru.len = len;
|
||||
a64pkru.keyidx = keyidx;
|
||||
a64pkru.flags = flags;
|
||||
return (sysarch(X86_SET_PKRU, &a64pkru));
|
||||
}
|
||||
|
||||
int
|
||||
x86_pkru_unprotect_range(void *addr, unsigned long len)
|
||||
{
|
||||
struct amd64_set_pkru a64pkru;
|
||||
|
||||
memset(&a64pkru, 0, sizeof(a64pkru));
|
||||
a64pkru.addr = addr;
|
||||
a64pkru.len = len;
|
||||
return (sysarch(X86_CLEAR_PKRU, &a64pkru));
|
||||
}
|
@ -96,7 +96,7 @@ vm_extra_pre_umount() {
|
||||
|
||||
# Use the NTP service provided by Amazon
|
||||
sed -i '' -e 's/^pool/#pool/' \
|
||||
-e 's/^#server.*/server 169.254.169.123 iburst/' \
|
||||
-e '1,/^#server/s/^#server.*/server 169.254.169.123 iburst/' \
|
||||
${DESTDIR}/etc/ntp.conf
|
||||
|
||||
# The first time the AMI boots, the installed "first boot" scripts
|
||||
|
@ -349,9 +349,11 @@ getnextinode(ino_t inumber, int rebuildcg)
|
||||
lastinum += fullcnt;
|
||||
}
|
||||
/*
|
||||
* Flush old contents in case they have been updated.
|
||||
* If getblk encounters an error, it will already have zeroed
|
||||
* out the buffer, so we do not need to do so here.
|
||||
*/
|
||||
flush(fswritefd, &inobuf);
|
||||
getblk(&inobuf, blk, size);
|
||||
nextinop = inobuf.b_un.b_buf;
|
||||
}
|
||||
@ -461,6 +463,10 @@ void
|
||||
freeinodebuf(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Flush old contents in case they have been updated.
|
||||
*/
|
||||
flush(fswritefd, &inobuf);
|
||||
if (inobuf.b_un.b_buf != NULL)
|
||||
free((char *)inobuf.b_un.b_buf);
|
||||
inobuf.b_un.b_buf = NULL;
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <fs/cd9660/iso.h>
|
||||
#include <fs/cd9660/cd9660_rrip.h>
|
||||
@ -227,8 +228,8 @@ static int
|
||||
dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||
int use_rrip, int lenskip)
|
||||
{
|
||||
size_t len;
|
||||
char *cp;
|
||||
size_t len, plen;
|
||||
char *cp, *sep;
|
||||
int i, icase;
|
||||
|
||||
if (use_rrip)
|
||||
@ -242,7 +243,14 @@ dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||
} else
|
||||
icase = 0;
|
||||
|
||||
if (strlen(path) != len)
|
||||
sep = strchr(path, '/');
|
||||
if (sep != NULL) {
|
||||
plen = sep - path;
|
||||
} else {
|
||||
plen = strlen(path);
|
||||
}
|
||||
|
||||
if (plen != len)
|
||||
return (0);
|
||||
|
||||
for (i = len; --i >= 0; path++, cp++) {
|
||||
@ -283,6 +291,7 @@ cd9660_open(const char *path, struct open_file *f)
|
||||
struct iso_directory_record rec;
|
||||
struct iso_directory_record *dp = NULL;
|
||||
int rc, first, use_rrip, lenskip;
|
||||
bool isdir = false;
|
||||
|
||||
/* First find the volume descriptor */
|
||||
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
|
||||
@ -372,7 +381,24 @@ cd9660_open(const char *path, struct open_file *f)
|
||||
rec = *dp;
|
||||
while (*path && *path != '/') /* look for next component */
|
||||
path++;
|
||||
if (*path) path++; /* skip '/' */
|
||||
|
||||
if (*path) /* this component was directory */
|
||||
isdir = true;
|
||||
|
||||
while (*path == '/')
|
||||
path++; /* skip '/' */
|
||||
|
||||
if (*path) /* We do have next component. */
|
||||
isdir = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the path had trailing / but the path does point to file,
|
||||
* report the error ENOTDIR.
|
||||
*/
|
||||
if (isdir == true && (isonum_711(rec.flags) & 2) == 0) {
|
||||
rc = ENOTDIR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* allocate file system specific data structure */
|
||||
|
@ -226,17 +226,24 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
p = get_device_type(devstr, type);
|
||||
|
||||
/*
|
||||
* If type is DEV_TYP_STOR we have a disk-like device. If we can parse
|
||||
* the remainder of the string as a standard unit+slice+partition (e.g.,
|
||||
* 0s2a or 1p12), return those results. Otherwise we'll fall through to
|
||||
* the code that parses the legacy format.
|
||||
* If type is DEV_TYP_STOR we have a disk-like device. If the remainder
|
||||
* of the string contains spaces, dots, or a colon in any location other
|
||||
* than the last char, it's legacy format. Otherwise it might be
|
||||
* standard loader(8) format (e.g., disk0s2a or mmc1p12), so try to
|
||||
* parse the remainder of the string as such, and if it works, return
|
||||
* those results. Otherwise we'll fall through to the code that parses
|
||||
* the legacy format.
|
||||
*/
|
||||
if ((*type & DEV_TYP_STOR) && disk_parsedev(&dev, p, NULL) == 0) {
|
||||
if (*type & DEV_TYP_STOR) {
|
||||
size_t len = strlen(p);
|
||||
if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 &&
|
||||
disk_parsedev(&dev, p, NULL) == 0) {
|
||||
*unit = dev.dd.d_unit;
|
||||
*slice = dev.d_slice;
|
||||
*partition = dev.d_partition;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore optional spaces after the device name. */
|
||||
while (*p == ' ')
|
||||
|
@ -233,6 +233,9 @@ initializecpu(void)
|
||||
if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE)
|
||||
cr4 |= CR4_FSGSBASE;
|
||||
|
||||
if (cpu_stdext_feature2 & CPUID_STDEXT2_PKU)
|
||||
cr4 |= CR4_PKE;
|
||||
|
||||
/*
|
||||
* Postpone enabling the SMEP on the boot CPU until the page
|
||||
* tables are switched from the boot loader identity mapping
|
||||
|
@ -48,7 +48,7 @@
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 2003 Networks Associates Technology, Inc.
|
||||
* Copyright (c) 2014-2018 The FreeBSD Foundation
|
||||
* Copyright (c) 2014-2019 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by Jake Burkholder,
|
||||
@ -121,6 +121,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rangeset.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/turnstile.h>
|
||||
@ -155,6 +156,7 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef SMP
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
#include <machine/sysarch.h>
|
||||
#include <machine/tss.h>
|
||||
|
||||
static __inline boolean_t
|
||||
@ -285,6 +287,13 @@ pmap_modified_bit(pmap_t pmap)
|
||||
return (mask);
|
||||
}
|
||||
|
||||
static __inline pt_entry_t
|
||||
pmap_pku_mask_bit(pmap_t pmap)
|
||||
{
|
||||
|
||||
return (pmap->pm_type == PT_X86 ? X86_PG_PKU_MASK : 0);
|
||||
}
|
||||
|
||||
#if !defined(DIAGNOSTIC)
|
||||
#ifdef __GNUC_GNU_INLINE__
|
||||
#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
|
||||
@ -424,6 +433,22 @@ static pml4_entry_t *pti_pml4;
|
||||
static vm_pindex_t pti_pg_idx;
|
||||
static bool pti_finalized;
|
||||
|
||||
struct pmap_pkru_range {
|
||||
struct rs_el pkru_rs_el;
|
||||
u_int pkru_keyidx;
|
||||
int pkru_flags;
|
||||
};
|
||||
|
||||
static uma_zone_t pmap_pkru_ranges_zone;
|
||||
static bool pmap_pkru_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
static pt_entry_t pmap_pkru_get(pmap_t pmap, vm_offset_t va);
|
||||
static void pmap_pkru_on_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
static void *pkru_dup_range(void *ctx, void *data);
|
||||
static void pkru_free_range(void *ctx, void *node);
|
||||
static int pmap_pkru_copy(pmap_t dst_pmap, pmap_t src_pmap);
|
||||
static int pmap_pkru_deassign(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
static void pmap_pkru_deassign_all(pmap_t pmap);
|
||||
|
||||
static int
|
||||
pmap_pcid_save_cnt_proc(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
@ -2846,6 +2871,12 @@ pmap_pinit0(pmap_t pmap)
|
||||
pmap->pm_pcids[i].pm_gen = 1;
|
||||
}
|
||||
pmap_activate_boot(pmap);
|
||||
|
||||
if ((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0) {
|
||||
pmap_pkru_ranges_zone = uma_zcreate("pkru ranges",
|
||||
sizeof(struct pmap_pkru_range), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2934,6 +2965,10 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
|
||||
pmap_pinit_pml4_pti(pml4pgu);
|
||||
pmap->pm_ucr3 = VM_PAGE_TO_PHYS(pml4pgu);
|
||||
}
|
||||
if ((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0) {
|
||||
rangeset_init(&pmap->pm_pkru, pkru_dup_range,
|
||||
pkru_free_range, pmap, M_NOWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
pmap->pm_root.rt_root = 0;
|
||||
@ -3230,6 +3265,9 @@ pmap_release(pmap_t pmap)
|
||||
vm_page_unwire_noq(m);
|
||||
vm_page_free(m);
|
||||
}
|
||||
if (pmap->pm_type == PT_X86 &&
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0)
|
||||
rangeset_fini(&pmap->pm_pkru);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4060,7 +4098,7 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
{
|
||||
pd_entry_t newpde, oldpde;
|
||||
pt_entry_t *firstpte, newpte;
|
||||
pt_entry_t PG_A, PG_G, PG_M, PG_RW, PG_V;
|
||||
pt_entry_t PG_A, PG_G, PG_M, PG_PKU_MASK, PG_RW, PG_V;
|
||||
vm_paddr_t mptepa;
|
||||
vm_page_t mpte;
|
||||
struct spglist free;
|
||||
@ -4073,6 +4111,7 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
PG_RW = pmap_rw_bit(pmap);
|
||||
PG_V = pmap_valid_bit(pmap);
|
||||
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
||||
PG_PKU_MASK = pmap_pku_mask_bit(pmap);
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
oldpde = *pde;
|
||||
@ -4505,6 +4544,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
out:
|
||||
if (anyvalid)
|
||||
pmap_invalidate_all(pmap);
|
||||
pmap_pkru_on_remove(pmap, sva, eva);
|
||||
PMAP_UNLOCK(pmap);
|
||||
pmap_delayed_invl_finished();
|
||||
vm_page_free_pages_toq(&free, true);
|
||||
@ -4816,7 +4856,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
{
|
||||
pd_entry_t newpde;
|
||||
pt_entry_t *firstpte, oldpte, pa, *pte;
|
||||
pt_entry_t PG_G, PG_A, PG_M, PG_RW, PG_V;
|
||||
pt_entry_t PG_G, PG_A, PG_M, PG_RW, PG_V, PG_PKU_MASK;
|
||||
vm_page_t mpte;
|
||||
int PG_PTE_CACHE;
|
||||
|
||||
@ -4825,6 +4865,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
PG_M = pmap_modified_bit(pmap);
|
||||
PG_V = pmap_valid_bit(pmap);
|
||||
PG_RW = pmap_rw_bit(pmap);
|
||||
PG_PKU_MASK = pmap_pku_mask_bit(pmap);
|
||||
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
@ -5052,6 +5093,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
|
||||
|
||||
origpte = *pte;
|
||||
pv = NULL;
|
||||
if (va < VM_MAXUSER_ADDRESS && pmap->pm_type == PT_X86)
|
||||
newpte |= pmap_pkru_get(pmap, va);
|
||||
|
||||
/*
|
||||
* Is the specified virtual address already mapped?
|
||||
@ -5271,6 +5314,25 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
|
||||
" in pmap %p", va, pmap);
|
||||
return (KERN_RESOURCE_SHORTAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* If pkru is not same for the whole pde range, return failure
|
||||
* and let vm_fault() cope. Check after pde allocation, since
|
||||
* it could sleep.
|
||||
*/
|
||||
if (!pmap_pkru_same(pmap, va, va + NBPDR)) {
|
||||
SLIST_INIT(&free);
|
||||
if (pmap_unwire_ptp(pmap, va, pdpg, &free)) {
|
||||
pmap_invalidate_page(pmap, va);
|
||||
vm_page_free_pages_toq(&free, true);
|
||||
}
|
||||
return (KERN_FAILURE);
|
||||
}
|
||||
if (va < VM_MAXUSER_ADDRESS && pmap->pm_type == PT_X86) {
|
||||
newpde &= ~X86_PG_PKU_MASK;
|
||||
newpde |= pmap_pkru_get(pmap, va);
|
||||
}
|
||||
|
||||
pde = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pdpg));
|
||||
pde = &pde[pmap_pde_index(va)];
|
||||
oldpde = *pde;
|
||||
@ -5530,7 +5592,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
|
||||
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||
newpte |= pg_nx;
|
||||
if (va < VM_MAXUSER_ADDRESS)
|
||||
newpte |= PG_U;
|
||||
newpte |= PG_U | pmap_pkru_get(pmap, va);
|
||||
pte_store(pte, newpte);
|
||||
return (mpte);
|
||||
}
|
||||
@ -5906,6 +5968,36 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
PMAP_UNLOCK(dst_pmap);
|
||||
}
|
||||
|
||||
int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap, pmap_t src_pmap)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (dst_pmap->pm_type != src_pmap->pm_type ||
|
||||
dst_pmap->pm_type != PT_X86 ||
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0)
|
||||
return (0);
|
||||
for (;;) {
|
||||
if (dst_pmap < src_pmap) {
|
||||
PMAP_LOCK(dst_pmap);
|
||||
PMAP_LOCK(src_pmap);
|
||||
} else {
|
||||
PMAP_LOCK(src_pmap);
|
||||
PMAP_LOCK(dst_pmap);
|
||||
}
|
||||
error = pmap_pkru_copy(dst_pmap, src_pmap);
|
||||
/* Clean up partial copy on failure due to no memory. */
|
||||
if (error == ENOMEM)
|
||||
pmap_pkru_deassign_all(dst_pmap);
|
||||
PMAP_UNLOCK(src_pmap);
|
||||
PMAP_UNLOCK(dst_pmap);
|
||||
if (error != ENOMEM)
|
||||
break;
|
||||
vm_wait(NULL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero the specified hardware page.
|
||||
*/
|
||||
@ -6305,6 +6397,7 @@ pmap_remove_pages(pmap_t pmap)
|
||||
if (lock != NULL)
|
||||
rw_wunlock(lock);
|
||||
pmap_invalidate_all(pmap);
|
||||
pmap_pkru_deassign_all(pmap);
|
||||
PMAP_UNLOCK(pmap);
|
||||
vm_page_free_pages_toq(&free, true);
|
||||
}
|
||||
@ -8941,6 +9034,285 @@ pmap_pti_remove_kva(vm_offset_t sva, vm_offset_t eva)
|
||||
VM_OBJECT_WUNLOCK(pti_obj);
|
||||
}
|
||||
|
||||
static void *
|
||||
pkru_dup_range(void *ctx __unused, void *data)
|
||||
{
|
||||
struct pmap_pkru_range *node, *new_node;
|
||||
|
||||
new_node = uma_zalloc(pmap_pkru_ranges_zone, M_NOWAIT);
|
||||
if (new_node == NULL)
|
||||
return (NULL);
|
||||
node = data;
|
||||
memcpy(new_node, node, sizeof(*node));
|
||||
return (new_node);
|
||||
}
|
||||
|
||||
static void
|
||||
pkru_free_range(void *ctx __unused, void *node)
|
||||
{
|
||||
|
||||
uma_zfree(pmap_pkru_ranges_zone, node);
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_assign(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, u_int keyidx,
|
||||
int flags)
|
||||
{
|
||||
struct pmap_pkru_range *ppr;
|
||||
int error;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
MPASS(pmap->pm_type == PT_X86);
|
||||
MPASS((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0);
|
||||
if ((flags & AMD64_PKRU_EXCL) != 0 &&
|
||||
!rangeset_check_empty(&pmap->pm_pkru, sva, eva))
|
||||
return (EBUSY);
|
||||
ppr = uma_zalloc(pmap_pkru_ranges_zone, M_NOWAIT);
|
||||
if (ppr == NULL)
|
||||
return (ENOMEM);
|
||||
ppr->pkru_keyidx = keyidx;
|
||||
ppr->pkru_flags = flags & AMD64_PKRU_PERSIST;
|
||||
error = rangeset_insert(&pmap->pm_pkru, sva, eva, ppr);
|
||||
if (error != 0)
|
||||
uma_zfree(pmap_pkru_ranges_zone, ppr);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_deassign(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
MPASS(pmap->pm_type == PT_X86);
|
||||
MPASS((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0);
|
||||
return (rangeset_remove(&pmap->pm_pkru, sva, eva));
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_pkru_deassign_all(pmap_t pmap)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type == PT_X86 &&
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0)
|
||||
rangeset_remove_all(&pmap->pm_pkru);
|
||||
}
|
||||
|
||||
static bool
|
||||
pmap_pkru_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
struct pmap_pkru_range *ppr, *prev_ppr;
|
||||
vm_offset_t va;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type != PT_X86 ||
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0 ||
|
||||
sva >= VM_MAXUSER_ADDRESS)
|
||||
return (true);
|
||||
MPASS(eva <= VM_MAXUSER_ADDRESS);
|
||||
for (va = sva, prev_ppr = NULL; va < eva;) {
|
||||
ppr = rangeset_lookup(&pmap->pm_pkru, va);
|
||||
if ((ppr == NULL) ^ (prev_ppr == NULL))
|
||||
return (false);
|
||||
if (ppr == NULL) {
|
||||
va += PAGE_SIZE;
|
||||
continue;
|
||||
}
|
||||
if (prev_ppr->pkru_keyidx != ppr->pkru_keyidx)
|
||||
return (false);
|
||||
va = ppr->pkru_rs_el.re_end;
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
static pt_entry_t
|
||||
pmap_pkru_get(pmap_t pmap, vm_offset_t va)
|
||||
{
|
||||
struct pmap_pkru_range *ppr;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type != PT_X86 ||
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0 ||
|
||||
va >= VM_MAXUSER_ADDRESS)
|
||||
return (0);
|
||||
ppr = rangeset_lookup(&pmap->pm_pkru, va);
|
||||
if (ppr != NULL)
|
||||
return (X86_PG_PKU(ppr->pkru_keyidx));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
pred_pkru_on_remove(void *ctx __unused, void *r)
|
||||
{
|
||||
struct pmap_pkru_range *ppr;
|
||||
|
||||
ppr = r;
|
||||
return ((ppr->pkru_flags & AMD64_PKRU_PERSIST) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_pkru_on_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type == PT_X86 &&
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0) {
|
||||
rangeset_remove_pred(&pmap->pm_pkru, sva, eva,
|
||||
pred_pkru_on_remove);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_copy(pmap_t dst_pmap, pmap_t src_pmap)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(dst_pmap, MA_OWNED);
|
||||
PMAP_LOCK_ASSERT(src_pmap, MA_OWNED);
|
||||
MPASS(dst_pmap->pm_type == PT_X86);
|
||||
MPASS(src_pmap->pm_type == PT_X86);
|
||||
MPASS((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0);
|
||||
if (src_pmap->pm_pkru.rs_data_ctx == NULL)
|
||||
return (0);
|
||||
return (rangeset_copy(&dst_pmap->pm_pkru, &src_pmap->pm_pkru));
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_pkru_update_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
|
||||
u_int keyidx)
|
||||
{
|
||||
pml4_entry_t *pml4e;
|
||||
pdp_entry_t *pdpe;
|
||||
pd_entry_t newpde, ptpaddr, *pde;
|
||||
pt_entry_t newpte, *ptep, pte;
|
||||
vm_offset_t va, va_next;
|
||||
bool changed;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
MPASS(pmap->pm_type == PT_X86);
|
||||
MPASS(keyidx <= PMAP_MAX_PKRU_IDX);
|
||||
|
||||
for (changed = false, va = sva; va < eva; va = va_next) {
|
||||
pml4e = pmap_pml4e(pmap, va);
|
||||
if ((*pml4e & X86_PG_V) == 0) {
|
||||
va_next = (va + NBPML4) & ~PML4MASK;
|
||||
if (va_next < va)
|
||||
va_next = eva;
|
||||
continue;
|
||||
}
|
||||
|
||||
pdpe = pmap_pml4e_to_pdpe(pml4e, va);
|
||||
if ((*pdpe & X86_PG_V) == 0) {
|
||||
va_next = (va + NBPDP) & ~PDPMASK;
|
||||
if (va_next < va)
|
||||
va_next = eva;
|
||||
continue;
|
||||
}
|
||||
|
||||
va_next = (va + NBPDR) & ~PDRMASK;
|
||||
if (va_next < va)
|
||||
va_next = eva;
|
||||
|
||||
pde = pmap_pdpe_to_pde(pdpe, va);
|
||||
ptpaddr = *pde;
|
||||
if (ptpaddr == 0)
|
||||
continue;
|
||||
|
||||
MPASS((ptpaddr & X86_PG_V) != 0);
|
||||
if ((ptpaddr & PG_PS) != 0) {
|
||||
if (va + NBPDR == va_next && eva >= va_next) {
|
||||
newpde = (ptpaddr & ~X86_PG_PKU_MASK) |
|
||||
X86_PG_PKU(keyidx);
|
||||
if (newpde != ptpaddr) {
|
||||
*pde = newpde;
|
||||
changed = true;
|
||||
}
|
||||
continue;
|
||||
} else if (!pmap_demote_pde(pmap, pde, va)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (va_next > eva)
|
||||
va_next = eva;
|
||||
|
||||
for (ptep = pmap_pde_to_pte(pde, va); va != va_next;
|
||||
ptep++, va += PAGE_SIZE) {
|
||||
pte = *ptep;
|
||||
if ((pte & X86_PG_V) == 0)
|
||||
continue;
|
||||
newpte = (pte & ~X86_PG_PKU_MASK) | X86_PG_PKU(keyidx);
|
||||
if (newpte != pte) {
|
||||
*ptep = newpte;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
pmap_invalidate_range(pmap, sva, eva);
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_check_uargs(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
|
||||
u_int keyidx, int flags)
|
||||
{
|
||||
|
||||
if (pmap->pm_type != PT_X86 || keyidx > PMAP_MAX_PKRU_IDX ||
|
||||
(flags & ~(AMD64_PKRU_PERSIST | AMD64_PKRU_EXCL)) != 0)
|
||||
return (EINVAL);
|
||||
if (eva <= sva || eva > VM_MAXUSER_ADDRESS)
|
||||
return (EFAULT);
|
||||
if ((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0)
|
||||
return (ENOTSUP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pmap_pkru_set(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, u_int keyidx,
|
||||
int flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
sva = trunc_page(sva);
|
||||
eva = round_page(eva);
|
||||
error = pmap_pkru_check_uargs(pmap, sva, eva, keyidx, flags);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
for (;;) {
|
||||
PMAP_LOCK(pmap);
|
||||
error = pmap_pkru_assign(pmap, sva, eva, keyidx, flags);
|
||||
if (error == 0)
|
||||
pmap_pkru_update_range(pmap, sva, eva, keyidx);
|
||||
PMAP_UNLOCK(pmap);
|
||||
if (error != ENOMEM)
|
||||
break;
|
||||
vm_wait(NULL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
pmap_pkru_clear(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
int error;
|
||||
|
||||
sva = trunc_page(sva);
|
||||
eva = round_page(eva);
|
||||
error = pmap_pkru_check_uargs(pmap, sva, eva, 0, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
for (;;) {
|
||||
PMAP_LOCK(pmap);
|
||||
error = pmap_pkru_deassign(pmap, sva, eva);
|
||||
if (error == 0)
|
||||
pmap_pkru_update_range(pmap, sva, eva, 0);
|
||||
PMAP_UNLOCK(pmap);
|
||||
if (error != ENOMEM)
|
||||
break;
|
||||
vm_wait(NULL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#ifdef DDB
|
||||
#include <sys/kdb.h>
|
||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
@ -53,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_kern.h> /* for kernel_map */
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
@ -170,13 +172,16 @@ update_gdt_fsbase(struct thread *td, uint32_t base)
|
||||
int
|
||||
sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
{
|
||||
int error = 0;
|
||||
struct pcb *pcb = curthread->td_pcb;
|
||||
struct pcb *pcb;
|
||||
struct vm_map *map;
|
||||
uint32_t i386base;
|
||||
uint64_t a64base;
|
||||
struct i386_ioperm_args iargs;
|
||||
struct i386_get_xfpustate i386xfpu;
|
||||
struct i386_set_pkru i386pkru;
|
||||
struct amd64_get_xfpustate a64xfpu;
|
||||
struct amd64_set_pkru a64pkru;
|
||||
int error;
|
||||
|
||||
#ifdef CAPABILITY_MODE
|
||||
/*
|
||||
@ -194,11 +199,15 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
case I386_GET_GSBASE:
|
||||
case I386_SET_GSBASE:
|
||||
case I386_GET_XFPUSTATE:
|
||||
case I386_SET_PKRU:
|
||||
case I386_CLEAR_PKRU:
|
||||
case AMD64_GET_FSBASE:
|
||||
case AMD64_SET_FSBASE:
|
||||
case AMD64_GET_GSBASE:
|
||||
case AMD64_SET_GSBASE:
|
||||
case AMD64_GET_XFPUSTATE:
|
||||
case AMD64_SET_PKRU:
|
||||
case AMD64_CLEAR_PKRU:
|
||||
break;
|
||||
|
||||
case I386_SET_IOPERM:
|
||||
@ -214,6 +223,10 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
|
||||
if (uap->op == I386_GET_LDT || uap->op == I386_SET_LDT)
|
||||
return (sysarch_ldt(td, uap, UIO_USERSPACE));
|
||||
|
||||
error = 0;
|
||||
pcb = td->td_pcb;
|
||||
|
||||
/*
|
||||
* XXXKIB check that the BSM generation code knows to encode
|
||||
* the op argument.
|
||||
@ -233,11 +246,27 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
a64xfpu.addr = (void *)(uintptr_t)i386xfpu.addr;
|
||||
a64xfpu.len = i386xfpu.len;
|
||||
break;
|
||||
case I386_SET_PKRU:
|
||||
case I386_CLEAR_PKRU:
|
||||
if ((error = copyin(uap->parms, &i386pkru,
|
||||
sizeof(struct i386_set_pkru))) != 0)
|
||||
return (error);
|
||||
a64pkru.addr = (void *)(uintptr_t)i386pkru.addr;
|
||||
a64pkru.len = i386pkru.len;
|
||||
a64pkru.keyidx = i386pkru.keyidx;
|
||||
a64pkru.flags = i386pkru.flags;
|
||||
break;
|
||||
case AMD64_GET_XFPUSTATE:
|
||||
if ((error = copyin(uap->parms, &a64xfpu,
|
||||
sizeof(struct amd64_get_xfpustate))) != 0)
|
||||
return (error);
|
||||
break;
|
||||
case AMD64_SET_PKRU:
|
||||
case AMD64_CLEAR_PKRU:
|
||||
if ((error = copyin(uap->parms, &a64pkru,
|
||||
sizeof(struct amd64_set_pkru))) != 0)
|
||||
return (error);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -326,6 +355,34 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
a64xfpu.addr, a64xfpu.len);
|
||||
break;
|
||||
|
||||
case I386_SET_PKRU:
|
||||
case AMD64_SET_PKRU:
|
||||
/*
|
||||
* Read-lock the map to synchronize with parallel
|
||||
* pmap_vmspace_copy() on fork.
|
||||
*/
|
||||
map = &td->td_proc->p_vmspace->vm_map;
|
||||
vm_map_lock_read(map);
|
||||
error = pmap_pkru_set(PCPU_GET(curpmap),
|
||||
(vm_offset_t)a64pkru.addr, (vm_offset_t)a64pkru.addr +
|
||||
a64pkru.len, a64pkru.keyidx, a64pkru.flags);
|
||||
vm_map_unlock_read(map);
|
||||
break;
|
||||
|
||||
case I386_CLEAR_PKRU:
|
||||
case AMD64_CLEAR_PKRU:
|
||||
if (a64pkru.flags != 0 || a64pkru.keyidx != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
map = &td->td_proc->p_vmspace->vm_map;
|
||||
vm_map_lock_read(map);
|
||||
error = pmap_pkru_clear(PCPU_GET(curpmap),
|
||||
(vm_offset_t)a64pkru.addr,
|
||||
(vm_offset_t)a64pkru.addr + a64pkru.len);
|
||||
vm_map_unlock(map);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
@ -807,6 +807,20 @@ trap_pfault(struct trapframe *frame, int usermode)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* User-mode protection key violation (PKU). May happen
|
||||
* either from usermode or from kernel if copyin accessed
|
||||
* key-protected mapping.
|
||||
*/
|
||||
if ((frame->tf_err & PGEX_PK) != 0) {
|
||||
if (eva > VM_MAXUSER_ADDRESS) {
|
||||
trap_fatal(frame, eva);
|
||||
return (-1);
|
||||
}
|
||||
rv = KERN_PROTECTION_FAILURE;
|
||||
goto after_vmfault;
|
||||
}
|
||||
|
||||
/*
|
||||
* If nx protection of the usermode portion of kernel page
|
||||
* tables caused trap, panic.
|
||||
@ -842,6 +856,7 @@ trap_pfault(struct trapframe *frame, int usermode)
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
after_vmfault:
|
||||
if (!usermode) {
|
||||
if (td->td_intr_nesting_level == 0 &&
|
||||
curpcb->pcb_onfault != NULL) {
|
||||
@ -885,10 +900,12 @@ trap_fatal(frame, eva)
|
||||
#endif
|
||||
if (type == T_PAGEFLT) {
|
||||
printf("fault virtual address = 0x%lx\n", eva);
|
||||
printf("fault code = %s %s %s, %s\n",
|
||||
printf("fault code = %s %s %s%s%s, %s\n",
|
||||
code & PGEX_U ? "user" : "supervisor",
|
||||
code & PGEX_W ? "write" : "read",
|
||||
code & PGEX_I ? "instruction" : "data",
|
||||
code & PGEX_PK ? " prot key" : " ",
|
||||
code & PGEX_SGX ? " SGX" : " ",
|
||||
code & PGEX_RSV ? "reserved bits in PTE" :
|
||||
code & PGEX_P ? "protection violation" : "page not present");
|
||||
}
|
||||
|
@ -286,17 +286,6 @@ options ACPI_DEBUG
|
||||
# The cpufreq(4) driver provides support for non-ACPI CPU frequency control
|
||||
device cpufreq
|
||||
|
||||
# Direct Rendering modules for 3D acceleration.
|
||||
device drm # DRM core module required by DRM drivers
|
||||
device mach64drm # ATI Rage Pro, Rage Mobility P/M, Rage XL
|
||||
device mgadrm # AGP Matrox G200, G400, G450, G550
|
||||
device r128drm # ATI Rage 128
|
||||
device savagedrm # S3 Savage3D, Savage4
|
||||
device sisdrm # SiS 300/305, 540, 630
|
||||
device tdfxdrm # 3dfx Voodoo 3/4/5 and Banshee
|
||||
device viadrm # VIA
|
||||
options DRM_DEBUG # Include debug printfs (slow)
|
||||
|
||||
#
|
||||
# Network interfaces:
|
||||
#
|
||||
|
@ -627,6 +627,22 @@ cpu_mwait(u_long extensions, u_int hints)
|
||||
__asm __volatile("mwait" : : "a" (hints), "c" (extensions));
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
rdpkru(void)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
__asm __volatile("rdpkru" : "=a" (res) : "c" (0) : "edx");
|
||||
return (res);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wrpkru(uint32_t mask)
|
||||
{
|
||||
|
||||
__asm __volatile("wrpkru" : : "a" (mask), "c" (0), "d" (0));
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* This is defined in <machine/specialreg.h> but is too painful to get to */
|
||||
#ifndef MSR_FSBASE
|
||||
|
@ -66,6 +66,7 @@
|
||||
#define X86_PG_AVAIL2 0x400 /* < programmers use */
|
||||
#define X86_PG_AVAIL3 0x800 /* \ */
|
||||
#define X86_PG_PDE_PAT 0x1000 /* PAT PAT index */
|
||||
#define X86_PG_PKU(idx) ((pt_entry_t)idx << 59)
|
||||
#define X86_PG_NX (1ul<<63) /* No-execute */
|
||||
#define X86_PG_AVAIL(x) (1ul << (x))
|
||||
|
||||
@ -73,6 +74,10 @@
|
||||
#define X86_PG_PDE_CACHE (X86_PG_PDE_PAT | X86_PG_NC_PWT | X86_PG_NC_PCD)
|
||||
#define X86_PG_PTE_CACHE (X86_PG_PTE_PAT | X86_PG_NC_PWT | X86_PG_NC_PCD)
|
||||
|
||||
/* Protection keys indexes */
|
||||
#define PMAP_MAX_PKRU_IDX 0xf
|
||||
#define X86_PG_PKU_MASK X86_PG_PKU(PMAP_MAX_PKRU_IDX)
|
||||
|
||||
/*
|
||||
* Intel extended page table (EPT) bit definitions.
|
||||
*/
|
||||
@ -120,7 +125,7 @@
|
||||
* (PTE) page mappings have identical settings for the following fields:
|
||||
*/
|
||||
#define PG_PTE_PROMOTE (PG_NX | PG_MANAGED | PG_W | PG_G | PG_PTE_CACHE | \
|
||||
PG_M | PG_A | PG_U | PG_RW | PG_V)
|
||||
PG_M | PG_A | PG_U | PG_RW | PG_V | PG_PKU_MASK)
|
||||
|
||||
/*
|
||||
* Page Protection Exception bits
|
||||
@ -131,6 +136,8 @@
|
||||
#define PGEX_U 0x04 /* access from User mode (UPL) */
|
||||
#define PGEX_RSV 0x08 /* reserved PTE field is non-zero */
|
||||
#define PGEX_I 0x10 /* during an instruction fetch */
|
||||
#define PGEX_PK 0x20 /* protection key violation */
|
||||
#define PGEX_SGX 0x40 /* SGX-related */
|
||||
|
||||
/*
|
||||
* undef the PG_xx macros that define bits in the regular x86 PTEs that
|
||||
@ -240,6 +247,8 @@
|
||||
#include <sys/_cpuset.h>
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
#include <sys/_pctrie.h>
|
||||
#include <sys/_rangeset.h>
|
||||
|
||||
#include <vm/_vm_radix.h>
|
||||
|
||||
@ -334,6 +343,7 @@ struct pmap {
|
||||
long pm_eptgen; /* EPT pmap generation id */
|
||||
int pm_flags;
|
||||
struct pmap_pcids pm_pcids[MAXCPU];
|
||||
struct rangeset pm_pkru;
|
||||
};
|
||||
|
||||
/* flags */
|
||||
@ -452,6 +462,10 @@ void pmap_pti_pcid_invalidate(uint64_t ucr3, uint64_t kcr3);
|
||||
void pmap_pti_pcid_invlpg(uint64_t ucr3, uint64_t kcr3, vm_offset_t va);
|
||||
void pmap_pti_pcid_invlrng(uint64_t ucr3, uint64_t kcr3, vm_offset_t sva,
|
||||
vm_offset_t eva);
|
||||
int pmap_pkru_clear(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
int pmap_pkru_set(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
|
||||
u_int keyidx, int flags);
|
||||
int pmap_vmspace_copy(pmap_t dst_pmap, pmap_t src_pmap);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/* Return various clipped indexes for a given VA */
|
||||
|
@ -1088,9 +1088,9 @@ axp8xx_intr(void *arg)
|
||||
if (bootverbose)
|
||||
device_printf(dev, "AXP_IRQSTAT4 val: %x\n", val);
|
||||
if (val & AXP_IRQSTAT4_BATLVL_LO0)
|
||||
devctl_notify("PMU", "Battery", "lower than level 2", NULL);
|
||||
devctl_notify("PMU", "Battery", "shutdown threshold", NULL);
|
||||
if (val & AXP_IRQSTAT4_BATLVL_LO1)
|
||||
devctl_notify("PMU", "Battery", "lower than level 1", NULL);
|
||||
devctl_notify("PMU", "Battery", "warning threshold", NULL);
|
||||
/* Acknowledge */
|
||||
axp8xx_write(dev, AXP_IRQSTAT4, val);
|
||||
}
|
||||
|
@ -71,5 +71,12 @@ void pmap_kremove_device(vm_offset_t, vm_size_t);
|
||||
vm_paddr_t pmap_kextract(vm_offset_t);
|
||||
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
|
||||
|
||||
static inline int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* !_MACHINE_PMAP_H_ */
|
||||
|
@ -171,6 +171,13 @@ struct pcb *pmap_switch(struct thread *, struct thread *);
|
||||
|
||||
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
|
||||
|
||||
static inline int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !LOCORE */
|
||||
|
@ -1089,6 +1089,8 @@ fasttrap_tracepoint_disable(proc_t *p, fasttrap_probe_t *probe, uint_t index)
|
||||
ASSERT(p->p_proc_flag & P_PR_LOCK);
|
||||
#endif
|
||||
p->p_dtrace_count--;
|
||||
|
||||
atomic_add_rel_64(&p->p_fasttrap_tp_gen, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -360,16 +360,13 @@ trim_map_write_start(zio_t *zio)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL);
|
||||
if (ts != NULL) {
|
||||
/*
|
||||
* Loop until all overlapping segments are removed.
|
||||
*/
|
||||
do {
|
||||
while ((ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL)) != NULL) {
|
||||
trim_map_segment_remove(tm, ts, start, end);
|
||||
ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL);
|
||||
} while (ts != NULL);
|
||||
}
|
||||
|
||||
avl_add(&tm->tm_inflight_writes, zio);
|
||||
|
||||
mutex_exit(&tm->tm_lock);
|
||||
|
@ -692,10 +692,12 @@ vdev_geom_attach_by_guids(vdev_t *vd)
|
||||
struct g_geom *gp;
|
||||
struct g_provider *pp, *best_pp;
|
||||
struct g_consumer *cp;
|
||||
const char *vdpath;
|
||||
enum match match, best_match;
|
||||
|
||||
g_topology_assert();
|
||||
|
||||
vdpath = vd->vdev_path + sizeof("/dev/") - 1;
|
||||
cp = NULL;
|
||||
best_pp = NULL;
|
||||
best_match = NO_MATCH;
|
||||
@ -710,6 +712,10 @@ vdev_geom_attach_by_guids(vdev_t *vd)
|
||||
if (match > best_match) {
|
||||
best_match = match;
|
||||
best_pp = pp;
|
||||
} else if (match == best_match) {
|
||||
if (strcmp(pp->name, vdpath) == 0) {
|
||||
best_pp = pp;
|
||||
}
|
||||
}
|
||||
if (match == FULL_MATCH)
|
||||
goto out;
|
||||
@ -794,7 +800,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
/*
|
||||
* We must have a pathname, and it must be absolute.
|
||||
*/
|
||||
if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
|
||||
if (vd->vdev_path == NULL || strncmp(vd->vdev_path, "/dev/", 5) != 0) {
|
||||
vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
|
||||
return (EINVAL);
|
||||
}
|
||||
|
@ -270,7 +270,6 @@ static void
|
||||
vdev_raidz_map_free(raidz_map_t *rm)
|
||||
{
|
||||
int c;
|
||||
size_t size;
|
||||
|
||||
for (c = 0; c < rm->rm_firstdatacol; c++) {
|
||||
if (rm->rm_col[c].rc_abd != NULL)
|
||||
@ -281,11 +280,9 @@ vdev_raidz_map_free(raidz_map_t *rm)
|
||||
rm->rm_col[c].rc_size);
|
||||
}
|
||||
|
||||
size = 0;
|
||||
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
|
||||
if (rm->rm_col[c].rc_abd != NULL)
|
||||
abd_put(rm->rm_col[c].rc_abd);
|
||||
size += rm->rm_col[c].rc_size;
|
||||
}
|
||||
|
||||
if (rm->rm_abd_copy != NULL)
|
||||
@ -571,10 +568,7 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset, boolean_t dofre
|
||||
abd_alloc_linear(rm->rm_col[c].rc_size, B_TRUE);
|
||||
}
|
||||
|
||||
rm->rm_col[c].rc_abd = abd_get_offset(abd, 0);
|
||||
off = rm->rm_col[c].rc_size;
|
||||
|
||||
for (c = c + 1; c < acols; c++) {
|
||||
for (off = 0; c < acols; c++) {
|
||||
rm->rm_col[c].rc_abd = abd_get_offset(abd, off);
|
||||
off += rm->rm_col[c].rc_size;
|
||||
}
|
||||
@ -2023,7 +2017,7 @@ vdev_raidz_io_start(zio_t *zio)
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(zio->io_type == ZIO_TYPE_READ);
|
||||
ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
|
||||
|
||||
/*
|
||||
* Iterate over the columns in reverse order so that we hit the parity
|
||||
@ -2561,7 +2555,7 @@ vdev_raidz_io_done(zio_t *zio)
|
||||
/*
|
||||
* We're here because either:
|
||||
*
|
||||
* total_errors == rm_first_datacol, or
|
||||
* total_errors == rm_firstdatacol, or
|
||||
* vdev_raidz_combrec() failed
|
||||
*
|
||||
* In either case, there is enough bad data to prevent
|
||||
|
@ -967,6 +967,7 @@ fasttrap_pid_probe(struct trapframe *tf)
|
||||
struct reg reg, *rp;
|
||||
proc_t *p = curproc, *pp;
|
||||
struct rm_priotracker tracker;
|
||||
uint64_t gen;
|
||||
uintptr_t pc;
|
||||
uintptr_t new_pc = 0;
|
||||
fasttrap_bucket_t *bucket;
|
||||
@ -1026,8 +1027,22 @@ fasttrap_pid_probe(struct trapframe *tf)
|
||||
while (pp->p_vmspace == pp->p_pptr->p_vmspace)
|
||||
pp = pp->p_pptr;
|
||||
pid = pp->p_pid;
|
||||
if (pp != p) {
|
||||
PROC_LOCK(pp);
|
||||
if ((pp->p_flag & P_WEXIT) != 0) {
|
||||
/*
|
||||
* This can happen if the child was created with
|
||||
* rfork(2). Userspace tracing cannot work reliably in
|
||||
* such a scenario, but we can at least try.
|
||||
*/
|
||||
PROC_UNLOCK(pp);
|
||||
sx_sunlock(&proctree_lock);
|
||||
return (-1);
|
||||
}
|
||||
_PHOLD_LITE(pp);
|
||||
PROC_UNLOCK(pp);
|
||||
}
|
||||
sx_sunlock(&proctree_lock);
|
||||
pp = NULL;
|
||||
|
||||
rm_rlock(&fasttrap_tp_lock, &tracker);
|
||||
#endif
|
||||
@ -1051,11 +1066,32 @@ fasttrap_pid_probe(struct trapframe *tf)
|
||||
if (tp == NULL) {
|
||||
#ifdef illumos
|
||||
mutex_exit(pid_mtx);
|
||||
return (-1);
|
||||
#else
|
||||
rm_runlock(&fasttrap_tp_lock, &tracker);
|
||||
gen = atomic_load_acq_64(&pp->p_fasttrap_tp_gen);
|
||||
if (pp != p)
|
||||
PRELE(pp);
|
||||
if (curthread->t_fasttrap_tp_gen != gen) {
|
||||
/*
|
||||
* At least one tracepoint associated with this PID has
|
||||
* been removed from the table since #BP was raised.
|
||||
* Speculate that we hit a tracepoint that has since
|
||||
* been removed, and retry the instruction.
|
||||
*/
|
||||
curthread->t_fasttrap_tp_gen = gen;
|
||||
#ifdef __amd64
|
||||
tf->tf_rip = pc;
|
||||
#else
|
||||
tf->tf_eip = pc;
|
||||
#endif
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
if (pp != p)
|
||||
PRELE(pp);
|
||||
|
||||
/*
|
||||
* Set the program counter to the address of the traced instruction
|
||||
|
@ -37,7 +37,7 @@ typedef struct kdtrace_proc {
|
||||
u_int64_t p_dtrace_count; /* Number of DTrace tracepoints */
|
||||
void *p_dtrace_helpers; /* DTrace helpers, if any */
|
||||
int p_dtrace_model;
|
||||
|
||||
uint64_t p_fasttrap_tp_gen; /* Tracepoint hash table gen */
|
||||
} kdtrace_proc_t;
|
||||
|
||||
/*
|
||||
@ -86,6 +86,7 @@ typedef struct kdtrace_thread {
|
||||
u_int64_t td_hrtime; /* Last time on cpu. */
|
||||
void *td_dtrace_sscr; /* Saved scratch space location. */
|
||||
void *td_systrace_args; /* syscall probe arguments. */
|
||||
uint64_t td_fasttrap_tp_gen; /* Tracepoint hash table gen. */
|
||||
} kdtrace_thread_t;
|
||||
|
||||
/*
|
||||
@ -113,10 +114,12 @@ typedef struct kdtrace_thread {
|
||||
#define t_dtrace_regv td_dtrace->td_dtrace_regv
|
||||
#define t_dtrace_sscr td_dtrace->td_dtrace_sscr
|
||||
#define t_dtrace_systrace_args td_dtrace->td_systrace_args
|
||||
#define t_fasttrap_tp_gen td_dtrace->td_fasttrap_tp_gen
|
||||
#define p_dtrace_helpers p_dtrace->p_dtrace_helpers
|
||||
#define p_dtrace_count p_dtrace->p_dtrace_count
|
||||
#define p_dtrace_probes p_dtrace->p_dtrace_probes
|
||||
#define p_model p_dtrace->p_dtrace_model
|
||||
#define p_fasttrap_tp_gen p_dtrace->p_fasttrap_tp_gen
|
||||
|
||||
#define DATAMODEL_NATIVE 0
|
||||
#ifdef __amd64__
|
||||
|
@ -1541,55 +1541,6 @@ dev/dcons/dcons_crom.c optional dcons_crom
|
||||
dev/dcons/dcons_os.c optional dcons
|
||||
dev/de/if_de.c optional de pci
|
||||
dev/dme/if_dme.c optional dme
|
||||
dev/drm/ati_pcigart.c optional drm
|
||||
dev/drm/drm_agpsupport.c optional drm
|
||||
dev/drm/drm_auth.c optional drm
|
||||
dev/drm/drm_bufs.c optional drm
|
||||
dev/drm/drm_context.c optional drm
|
||||
dev/drm/drm_dma.c optional drm
|
||||
dev/drm/drm_drawable.c optional drm
|
||||
dev/drm/drm_drv.c optional drm
|
||||
dev/drm/drm_fops.c optional drm
|
||||
dev/drm/drm_hashtab.c optional drm
|
||||
dev/drm/drm_ioctl.c optional drm
|
||||
dev/drm/drm_irq.c optional drm
|
||||
dev/drm/drm_lock.c optional drm
|
||||
dev/drm/drm_memory.c optional drm
|
||||
dev/drm/drm_mm.c optional drm
|
||||
dev/drm/drm_pci.c optional drm
|
||||
dev/drm/drm_scatter.c optional drm
|
||||
dev/drm/drm_sman.c optional drm
|
||||
dev/drm/drm_sysctl.c optional drm
|
||||
dev/drm/drm_vm.c optional drm
|
||||
dev/drm/mach64_dma.c optional mach64drm
|
||||
dev/drm/mach64_drv.c optional mach64drm
|
||||
dev/drm/mach64_irq.c optional mach64drm
|
||||
dev/drm/mach64_state.c optional mach64drm
|
||||
dev/drm/mga_dma.c optional mgadrm
|
||||
dev/drm/mga_drv.c optional mgadrm
|
||||
dev/drm/mga_irq.c optional mgadrm
|
||||
dev/drm/mga_state.c optional mgadrm
|
||||
dev/drm/mga_warp.c optional mgadrm
|
||||
dev/drm/r128_cce.c optional r128drm \
|
||||
compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}"
|
||||
dev/drm/r128_drv.c optional r128drm
|
||||
dev/drm/r128_irq.c optional r128drm
|
||||
dev/drm/r128_state.c optional r128drm
|
||||
dev/drm/savage_bci.c optional savagedrm
|
||||
dev/drm/savage_drv.c optional savagedrm
|
||||
dev/drm/savage_state.c optional savagedrm
|
||||
dev/drm/sis_drv.c optional sisdrm
|
||||
dev/drm/sis_ds.c optional sisdrm
|
||||
dev/drm/sis_mm.c optional sisdrm
|
||||
dev/drm/tdfx_drv.c optional tdfxdrm
|
||||
dev/drm/via_dma.c optional viadrm
|
||||
dev/drm/via_dmablit.c optional viadrm
|
||||
dev/drm/via_drv.c optional viadrm
|
||||
dev/drm/via_irq.c optional viadrm
|
||||
dev/drm/via_map.c optional viadrm
|
||||
dev/drm/via_mm.c optional viadrm
|
||||
dev/drm/via_verifier.c optional viadrm
|
||||
dev/drm/via_video.c optional viadrm
|
||||
dev/drm2/drm_agpsupport.c optional drm2
|
||||
dev/drm2/drm_auth.c optional drm2
|
||||
dev/drm2/drm_bufs.c optional drm2
|
||||
@ -1633,7 +1584,6 @@ dev/drm2/ttm/ttm_execbuf_util.c optional drm2
|
||||
dev/drm2/ttm/ttm_memory.c optional drm2
|
||||
dev/drm2/ttm/ttm_page_alloc.c optional drm2
|
||||
dev/drm2/ttm/ttm_bo_vm.c optional drm2
|
||||
dev/drm2/ati_pcigart.c optional drm2 agp pci
|
||||
dev/ed/if_ed.c optional ed
|
||||
dev/ed/if_ed_novell.c optional ed
|
||||
dev/ed/if_ed_rtl80x9.c optional ed
|
||||
@ -3183,7 +3133,9 @@ dev/syscons/rain/rain_saver.c optional rain_saver
|
||||
dev/syscons/schistory.c optional sc
|
||||
dev/syscons/scmouse.c optional sc
|
||||
dev/syscons/scterm.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvidctl.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/syscons/snake/snake_saver.c optional snake_saver
|
||||
dev/syscons/star/star_saver.c optional star_saver
|
||||
dev/syscons/syscons.c optional sc
|
||||
@ -3911,6 +3863,7 @@ kern/subr_pidctrl.c standard
|
||||
kern/subr_power.c standard
|
||||
kern/subr_prf.c standard
|
||||
kern/subr_prof.c standard
|
||||
kern/subr_rangeset.c standard
|
||||
kern/subr_rman.c standard
|
||||
kern/subr_rtc.c standard
|
||||
kern/subr_sbuf.c standard
|
||||
|
@ -486,10 +486,8 @@ dev/smartpqi/smartpqi_sis.c optional smartpqi
|
||||
dev/smartpqi/smartpqi_tag.c optional smartpqi
|
||||
dev/speaker/spkr.c optional speaker
|
||||
dev/syscons/apm/apm_saver.c optional apm_saver apm
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvesactl.c optional sc vga vesa
|
||||
dev/syscons/scvgarndr.c optional sc vga
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/tpm/tpm.c optional tpm
|
||||
dev/tpm/tpm20.c optional tpm
|
||||
dev/tpm/tpm_crb.c optional tpm acpi
|
||||
|
@ -132,8 +132,6 @@ dev/pci/pci_host_generic_fdt.c optional pci_host_generic pci fdt
|
||||
dev/psci/psci.c optional psci
|
||||
dev/psci/psci_arm.S optional psci
|
||||
dev/syscons/scgfbrndr.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/uart/uart_cpu_fdt.c optional uart fdt
|
||||
|
||||
font.h optional sc \
|
||||
|
@ -309,10 +309,8 @@ dev/sio/sio_pci.c optional sio pci
|
||||
dev/sio/sio_puc.c optional sio puc
|
||||
dev/speaker/spkr.c optional speaker
|
||||
dev/syscons/apm/apm_saver.c optional apm_saver apm
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvesactl.c optional sc vga vesa
|
||||
dev/syscons/scvgarndr.c optional sc vga
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/tpm/tpm.c optional tpm
|
||||
dev/tpm/tpm_acpi.c optional tpm acpi
|
||||
dev/tpm/tpm_isa.c optional tpm isa
|
||||
|
@ -75,8 +75,6 @@ dev/cfe/cfe_env.c optional cfe_env
|
||||
# syscons support
|
||||
dev/fb/fb.c optional sc
|
||||
dev/syscons/scgfbrndr.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
mips/mips/sc_machdep.c optional sc
|
||||
|
||||
# FDT support
|
||||
|
@ -74,8 +74,6 @@ dev/sound/macio/onyx.c optional snd_ai2s iicbus powermac
|
||||
dev/sound/macio/snapper.c optional snd_ai2s iicbus powermac
|
||||
dev/sound/macio/tumbler.c optional snd_ai2s iicbus powermac
|
||||
dev/syscons/scgfbrndr.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/tsec/if_tsec.c optional tsec
|
||||
dev/tsec/if_tsec_fdt.c optional tsec
|
||||
dev/uart/uart_cpu_powerpc.c optional uart
|
||||
|
@ -56,8 +56,6 @@ dev/pcf/pcf_ebus.c optional pcf ebus
|
||||
dev/sound/sbus/cs4231.c optional snd_audiocs ebus | \
|
||||
snd_audiocs sbus
|
||||
dev/syscons/scgfbrndr.c optional sc
|
||||
dev/syscons/scterm-teken.c optional sc
|
||||
dev/syscons/scvtb.c optional sc
|
||||
dev/uart/uart_cpu_sparc64.c optional uart
|
||||
dev/uart/uart_kbd_sun.c optional uart sc | vt
|
||||
dev/vt/hw/ofwfb/ofwfb.c optional vt
|
||||
|
@ -50,8 +50,6 @@ __DEFAULT_YES_OPTIONS = \
|
||||
__DEFAULT_NO_OPTIONS = \
|
||||
EXTRA_TCP_STACKS \
|
||||
KERNEL_RETPOLINE \
|
||||
MODULE_DRM \
|
||||
MODULE_DRM2 \
|
||||
NAND \
|
||||
OFED \
|
||||
RATELIMIT
|
||||
|
@ -1,9 +1,98 @@
|
||||
----------------------------------------
|
||||
08 January 2019. Summary of changes for version 20190108:
|
||||
15 February 2019. Summary of changes for version 20190215:
|
||||
|
||||
This release is available at https://acpica.org/downloads
|
||||
|
||||
|
||||
0) Support for ACPI specification version 6.3:
|
||||
|
||||
Add PCC operation region support for the AML interpreter. This adds PCC
|
||||
operation region support in the AML interpreter and a default handler for
|
||||
acpiexec. The change also renames the PCC region address space keyword to
|
||||
PlatformCommChannel.
|
||||
|
||||
Support for new predefined methods _NBS, _NCH, _NIC, _NIH, and _NIG.
|
||||
These methods provide OSPM with health information and device boot
|
||||
status.
|
||||
|
||||
PDTT: Add TriggerOrder to the PCC Identifier structure. The field value
|
||||
defines if the trigger needs to be invoked by OSPM before or at the end
|
||||
of kernel crash dump processing/handling operation.
|
||||
|
||||
SRAT: Add Generic Affinity Structure subtable. This subtable in the SRAT
|
||||
is used for describing devices such as heterogeneous processors,
|
||||
accelerators, GPUs, and IO devices with integrated compute or DMA
|
||||
engines.
|
||||
|
||||
MADT: Add support for statistical profiling in GICC. Statistical
|
||||
profiling extension (SPE) is an architecture-specific feature for ARM.
|
||||
|
||||
MADT: Add online capable flag. If this bit is set, system hardware
|
||||
supports enabling this processor during OS runtime.
|
||||
|
||||
New Error Disconnect Recover Notification value. There are a number of
|
||||
scenarios where system Firmware in collaboration with hardware may
|
||||
disconnect one or more devices from the rest of the system for purposes
|
||||
of error containment. Firmware can use this new notification value to
|
||||
alert OSPM of such a removal.
|
||||
|
||||
PPTT: New additional fields in Processor Structure Flags. These flags
|
||||
provide more information about processor topology.
|
||||
|
||||
NFIT/Disassembler: Change a field name from "Address Range" to "Region
|
||||
Type".
|
||||
|
||||
HMAT updates: make several existing fields to be reserved as well as
|
||||
rename subtable 0 to "memory proximity domain attributes".
|
||||
|
||||
GTDT: Add support for new GTDT Revision 3. This revision adds information
|
||||
for the EL2 timer.
|
||||
|
||||
iASL: Update the HMAT example template for new fields.
|
||||
|
||||
iASL: Add support for the new revision of the GTDT (Rev 3).
|
||||
|
||||
|
||||
1) ACPICA kernel-resident subsystem:
|
||||
|
||||
AML Parser: fix the main AML parse loop to correctly skip erroneous
|
||||
extended opcodes. AML opcodes come in two lengths: 1-byte opcodes and 2-
|
||||
byte extended opcodes. If an error occurs during an AML table load, the
|
||||
AML parser will continue loading the table by skipping the offending
|
||||
opcode. This implements a "load table at any cost" philosophy.
|
||||
|
||||
|
||||
2) iASL Compiler/Disassembler and Tools:
|
||||
|
||||
iASL: Add checks for illegal object references, such as a reference
|
||||
outside of method to an object within a method. Such an object is only
|
||||
temporary.
|
||||
|
||||
iASL: Emit error for creation of a zero-length operation region. Such a
|
||||
region is rather pointless. If encountered, a runtime error is also
|
||||
implemented in the interpeter.
|
||||
|
||||
Debugger: Fix a possible fault with the "test objects" command.
|
||||
|
||||
iASL: Makefile: support parent directory filenames containing embedded
|
||||
spaces.
|
||||
|
||||
iASL: Update the TPM2 template to revision 4.
|
||||
|
||||
iASL: Add the ability to report specific warnings or remarks as errors.
|
||||
|
||||
Disassembler: Disassemble OEMx tables as actual AML byte code.
|
||||
Previously, these tables were treated as "unknown table".
|
||||
|
||||
iASL: Add definition and disassembly for TPM2 revision 3.
|
||||
|
||||
iASL: Add support for TPM2 rev 3 compilation.
|
||||
|
||||
|
||||
----------------------------------------
|
||||
08 January 2019. Summary of changes for version 20190108:
|
||||
|
||||
|
||||
1) ACPICA kernel-resident subsystem:
|
||||
|
||||
Updated all copyrights to 2019. This affects all source code modules.
|
||||
@ -1218,7 +1307,7 @@ internal cache) is detected and ignored via object poisoning.
|
||||
|
||||
Debugger: Fixed an AML interpreter mutex issue during the single stepping
|
||||
of control methods. If certain debugger commands are executed during
|
||||
stepping, a mutex aquire/release error could occur. Lv Zheng.
|
||||
stepping, a mutex acquire/release error could occur. Lv Zheng.
|
||||
|
||||
Fixed some issues generating ACPICA with the Intel C compiler by
|
||||
restoring the original behavior and compiler-specific include file in
|
||||
@ -6760,7 +6849,7 @@ keyword is not standard across compilers, and this type allows inline to
|
||||
be
|
||||
configured on a per-compiler basis. Lin Ming.
|
||||
|
||||
Made the system global AcpiGbl_SystemAwakeAndRunning publically
|
||||
Made the system global AcpiGbl_SystemAwakeAndRunning publicly
|
||||
available.
|
||||
Added an extern for this boolean in acpixf.h. Some hosts utilize this
|
||||
value
|
||||
@ -11429,7 +11518,7 @@ Removed the length limit (200) on string objects as per the upcoming ACPI
|
||||
1)
|
||||
any implicit conversion of a Buffer to a String, 2) a String object
|
||||
result
|
||||
of the ASL Concatentate operator, 3) the String object result of the ASL
|
||||
of the ASL Concatenate operator, 3) the String object result of the ASL
|
||||
ToString operator.
|
||||
|
||||
Fixed a problem in the Windows OS interface layer (OSL) where a
|
||||
@ -13585,7 +13674,7 @@ next access width boundary (a common coding error.)
|
||||
Renamed OSD_HANDLER to ACPI_OSD_HANDLER, and OSD_EXECUTION_CALLBACK to
|
||||
ACPI_OSD_EXEC_CALLBACK for consistency with other ACPI symbols. Also,
|
||||
these
|
||||
symbols are lowercased by the latest version of the AcpiSrc tool.
|
||||
symbols are lowercase by the latest version of the AcpiSrc tool.
|
||||
|
||||
The prototypes for the PCI interfaces in acpiosxf.h have been updated to
|
||||
rename "Register" to simply "Reg" to prevent certain compilers from
|
||||
@ -14957,8 +15046,8 @@ with the Linux coding style.
|
||||
Removed the non-Linux SourceSafe module revision number from each
|
||||
module header.
|
||||
|
||||
Completed major overhaul of symbols to be lowercased for linux.
|
||||
Doubled the number of symbols that are lowercased.
|
||||
Completed major overhaul of symbols to be lowercase for linux.
|
||||
Doubled the number of symbols that are lowercase.
|
||||
|
||||
Fixed a problem where identifiers within procedure headers and
|
||||
within quotes were not fully lower cased (they were left with a
|
||||
@ -16454,7 +16543,7 @@ Summary of changes for this label: 02_14_02
|
||||
Implemented support in AcpiLoadTable to allow loading of FACS and
|
||||
FADT tables.
|
||||
|
||||
Suport for the now-obsolete interim 0.71 64-bit ACPI tables has
|
||||
Support for the now-obsolete interim 0.71 64-bit ACPI tables has
|
||||
been removed. All 64-bit platforms should be migrated to the ACPI
|
||||
2.0 tables. The actbl71.h header has been removed from the source
|
||||
tree.
|
||||
@ -16804,7 +16893,7 @@ Updated all files to apply cleanly against 2.4.16.
|
||||
|
||||
Added basic PCI Interrupt Routing Table (PRT) support for IA32
|
||||
(acpi_pci.c), and unified the PRT code for IA32 and IA64. This
|
||||
version supports both static and dyanmic PRT entries, but dynamic
|
||||
version supports both static and dynamic PRT entries, but dynamic
|
||||
entries are treated as if they were static (not yet
|
||||
reconfigurable). Architecture- specific code to use this data is
|
||||
absent on IA32 but should be available shortly.
|
||||
@ -16893,7 +16982,7 @@ power-down, and thermal passive cooling issues (coming soon).
|
||||
|
||||
Added additional typechecking for Fields within restricted access
|
||||
Operation Regions. All fields within EC and CMOS regions must be
|
||||
declared with ByteAcc. All fields withing SMBus regions must be
|
||||
declared with ByteAcc. All fields within SMBus regions must be
|
||||
declared with the BufferAcc access type.
|
||||
|
||||
Fixed a problem where the listing file output of control methods
|
||||
@ -17066,7 +17155,7 @@ objects to not be deleted during subsystem termination.
|
||||
|
||||
Fixed a problem with the external AcpiEvaluateObject interface
|
||||
where the subsystem would fault if the named object to be
|
||||
evaluated refered to a constant such as Zero, Ones, etc.
|
||||
evaluated referred to a constant such as Zero, Ones, etc.
|
||||
|
||||
Fixed a problem with IndexFields and BankFields where the
|
||||
subsystem would fault if the index, data, or bank registers were
|
||||
@ -17133,7 +17222,7 @@ sleeps.)
|
||||
The AcpiEnterSleepState and AcpiLeaveSleepState interfaces now
|
||||
support wake-enabled GPEs. This means that upon entering the
|
||||
sleep state, all GPEs that are not wake-enabled are disabled.
|
||||
When leaving the sleep state, these GPEs are reenabled.
|
||||
When leaving the sleep state, these GPEs are re-enabled.
|
||||
|
||||
A local double-precision divide/modulo module has been added to
|
||||
enhance portability to OS kernels where a 64-bit math library is
|
||||
|
@ -305,6 +305,11 @@ const AH_PREDEFINED_NAME AslPredefinedInfo[] =
|
||||
AH_PREDEF ("_MSM", "Memory Set Monitoring", "Sets bandwidth monitoring parameters for a memory device"),
|
||||
AH_PREDEF ("_MTL", "Minimum Throttle Limit", "Returns the minimum throttle limit for a thermal zone"),
|
||||
AH_PREDEF ("_MTP", "Memory Type", "Resource Descriptor field"),
|
||||
AH_PREDEF ("_NBS", "NVDIMM Boot Status", "Returns information about NVDIMM device’s status at boot time"),
|
||||
AH_PREDEF ("_NCH", "NVDIMM Current Health Information", "Returns current health information of the NVDIMM device"),
|
||||
AH_PREDEF ("_NIC", "NVDIMM Health Error Injection Capabilities", "Returns health error injection capabilities that are supported by the platform"),
|
||||
AH_PREDEF ("_NIG", "NVDIMM Inject Health Error Status","Returns currently active health errors and their error attributes that are injected by _NIH"),
|
||||
AH_PREDEF ("_NIH", "NVDIMM Inject/Clear Health Errors", "Returns the status of injecting or clearing Health Errors"),
|
||||
AH_PREDEF ("_NTT", "Notification Temperature Threshold", "Returns a threshold for device temperature change that requires platform notification"),
|
||||
AH_PREDEF ("_OFF", "Power Off", "Sets a power resource to the off state"),
|
||||
AH_PREDEF ("_ON_", "Power On", "Sets a power resource to the on state"),
|
||||
@ -393,7 +398,7 @@ const AH_PREDEFINED_NAME AslPredefinedInfo[] =
|
||||
AH_PREDEF ("_SDD", "Set Device Data", "Sets data for a SATA device"),
|
||||
AH_PREDEF ("_SEG", "PCI Segment", "Returns a device's PCI Segment Group number"),
|
||||
AH_PREDEF ("_SHL", "Set Hardware Limit", "Sets the hardware limit enforced by the Power Meter"),
|
||||
AH_PREDEF ("_SHR", "Sharable", "Interrupt share status, Resource Descriptor field"),
|
||||
AH_PREDEF ("_SHR", "Shareable", "Interrupt share status, Resource Descriptor field"),
|
||||
AH_PREDEF ("_SI_", "System Indicators", "Predefined scope"),
|
||||
AH_PREDEF ("_SIZ", "Size", "DMA transfer size, Resource Descriptor field"),
|
||||
AH_PREDEF ("_SLI", "System Locality Information", "Returns a list of NUMA system localities"),
|
||||
|
@ -226,7 +226,7 @@ AcpiAhMatchUuid (
|
||||
|
||||
for (Info = Gbl_AcpiUuids; Info->Description; Info++)
|
||||
{
|
||||
/* Null string means desciption is a UUID class */
|
||||
/* Null string means description is a UUID class */
|
||||
|
||||
if (!Info->String)
|
||||
{
|
||||
|
@ -1216,7 +1216,7 @@ AcpiDmCreateSubobjectForExternal (
|
||||
*
|
||||
* DESCRIPTION: Add one external to the namespace by resolvign the external
|
||||
* (by performing a namespace lookup) and annotating the resulting
|
||||
* namespace node with the approperiate information if the type
|
||||
* namespace node with the appropriate information if the type
|
||||
* is ACPI_TYPE_REGION or ACPI_TYPE_METHOD.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -906,7 +906,7 @@ AcpiDmUpdateResourceName (
|
||||
*
|
||||
* PARAMETERS: BitIndex - Index into the resource descriptor
|
||||
* Resource - Pointer to the raw resource data
|
||||
* ResourceIndex - Index correspoinding to the resource type
|
||||
* ResourceIndex - Index corresponding to the resource type
|
||||
*
|
||||
* RETURN: Pointer to the resource tag (ACPI_NAME). NULL if no match.
|
||||
*
|
||||
|
@ -320,7 +320,7 @@ static const char *AcpiDmHestNotifySubnames[] =
|
||||
|
||||
static const char *AcpiDmHmatSubnames[] =
|
||||
{
|
||||
"Memory Subystem Address Range",
|
||||
"Memory Proximity Domain Attributes",
|
||||
"System Locality Latency and Bandwidth Information",
|
||||
"Memory Side Cache Information",
|
||||
"Unknown Structure Type" /* Reserved */
|
||||
@ -400,6 +400,7 @@ static const char *AcpiDmSratSubnames[] =
|
||||
"Processor Local x2APIC Affinity",
|
||||
"GICC Affinity",
|
||||
"GIC ITS Affinity", /* Acpi 6.2 */
|
||||
"Generic Initiator Affinity", /* Acpi 6.3 */
|
||||
"Unknown Subtable Type" /* Reserved */
|
||||
};
|
||||
|
||||
|
@ -1106,9 +1106,26 @@ AcpiDmDumpGtdt (
|
||||
return;
|
||||
}
|
||||
|
||||
/* Subtables */
|
||||
/* Rev 3 fields */
|
||||
|
||||
Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
|
||||
|
||||
if (Table->Revision > 2)
|
||||
{
|
||||
SubtableLength = sizeof (ACPI_GTDT_EL2);
|
||||
Status = AcpiDmDumpTable (Length, Offset, Subtable,
|
||||
SubtableLength, AcpiDmTableInfoGtdtEl2);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Offset += SubtableLength;
|
||||
}
|
||||
|
||||
Subtable = ACPI_ADD_PTR (ACPI_GTDT_HEADER, Table, Offset);
|
||||
|
||||
/* Subtables */
|
||||
|
||||
while (Offset < Table->Length)
|
||||
{
|
||||
/* Common subtable header */
|
||||
@ -1406,7 +1423,7 @@ AcpiDmDumpHmat (
|
||||
case ACPI_HMAT_TYPE_ADDRESS_RANGE:
|
||||
|
||||
InfoTable = AcpiDmTableInfoHmat0;
|
||||
Length = sizeof (ACPI_HMAT_ADDRESS_RANGE);
|
||||
Length = sizeof (ACPI_HMAT_PROXIMITY_DOMAIN);
|
||||
break;
|
||||
|
||||
case ACPI_HMAT_TYPE_LOCALITY:
|
||||
|
@ -333,6 +333,11 @@ AcpiDmDumpSrat (
|
||||
InfoTable = AcpiDmTableInfoSrat4;
|
||||
break;
|
||||
|
||||
case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
|
||||
|
||||
InfoTable = AcpiDmTableInfoSrat5;
|
||||
break;
|
||||
|
||||
default:
|
||||
AcpiOsPrintf ("\n**** Unknown SRAT subtable type 0x%X\n",
|
||||
Subtable->Type);
|
||||
|
@ -814,6 +814,15 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoGtdt[] =
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
/* GDTD EL2 timer info. This table is appended to AcpiDmTableInfoGtdt for rev 3 and later */
|
||||
|
||||
ACPI_DMTABLE_INFO AcpiDmTableInfoGtdtEl2[] =
|
||||
{
|
||||
{ACPI_DMT_UINT32, ACPI_GTDT_EL2_OFFSET (VirtualEL2TimerGsiv), "Virtual EL2 Timer GSIV", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_GTDT_EL2_OFFSET (VirtualEL2TimerFlags), "Virtual EL2 Timer Flags", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
/* GTDT Subtable header (one per Subtable) */
|
||||
|
||||
ACPI_DMTABLE_INFO AcpiDmTableInfoGtdtHdr[] =
|
||||
@ -1105,20 +1114,18 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoHmatHdr[] =
|
||||
|
||||
/* HMAT subtables */
|
||||
|
||||
/* 0x00: Memory Subsystem Address Range */
|
||||
/* 0x00: Memory proximity domain attributes */
|
||||
|
||||
ACPI_DMTABLE_INFO AcpiDmTableInfoHmat0[] =
|
||||
{
|
||||
{ACPI_DMT_UINT16, ACPI_HMAT0_OFFSET (Flags), "Flags (decoded below)", 0},
|
||||
{ACPI_DMT_FLAG0, ACPI_HMAT0_FLAG_OFFSET (Flags,0), "Processor Proximity Domain Valid", 0},
|
||||
{ACPI_DMT_FLAG1, ACPI_HMAT0_FLAG_OFFSET (Flags,0), "Memory Proximity Domain Valid", 0},
|
||||
{ACPI_DMT_FLAG2, ACPI_HMAT0_FLAG_OFFSET (Flags,0), "Reservation Hint", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_HMAT0_OFFSET (Reserved1), "Reserved1", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_HMAT0_OFFSET (ProcessorPD), "Processor Proximity Domain", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_HMAT0_OFFSET (MemoryPD), "Memory Proximity Domain", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_HMAT0_OFFSET (Reserved2), "Reserved2", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_HMAT0_OFFSET (PhysicalAddressBase), "Physical Address Range Base", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_HMAT0_OFFSET (PhysicalAddressLength), "Physical Address Range Size", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_HMAT0_OFFSET (Reserved3), "Reserved3", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_HMAT0_OFFSET (Reserved4), "Reserved4", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
|
@ -535,6 +535,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt0[] =
|
||||
{ACPI_DMT_UINT8, ACPI_MADT0_OFFSET (Id), "Local Apic ID", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_MADT0_OFFSET (LapicFlags), "Flags (decoded below)", DT_FLAG},
|
||||
{ACPI_DMT_FLAG0, ACPI_MADT0_FLAG_OFFSET (LapicFlags,0), "Processor Enabled", 0},
|
||||
{ACPI_DMT_FLAG1, ACPI_MADT0_FLAG_OFFSET (LapicFlags,0), "Runtime Online Capable", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
@ -683,7 +684,8 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoMadt11[] =
|
||||
{ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (GicrBaseAddress), "Redistributor Base Address", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_MADT11_OFFSET (ArmMpidr), "ARM MPIDR", 0},
|
||||
{ACPI_DMT_UINT8, ACPI_MADT11_OFFSET (EfficiencyClass), "Efficiency Class", 0},
|
||||
{ACPI_DMT_UINT24, ACPI_MADT11_OFFSET (Reserved2[0]), "Reserved", 0},
|
||||
{ACPI_DMT_UINT8, ACPI_MADT11_OFFSET (Reserved2[0]), "Reserved", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_MADT11_OFFSET (SpeInterrupt), "SPE Overflow Interrupt", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
@ -946,7 +948,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoNfit0[] =
|
||||
{ACPI_DMT_FLAG1, ACPI_NFIT0_FLAG_OFFSET (Flags,0), "Proximity Domain Valid", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_NFIT0_OFFSET (Reserved), "Reserved", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_NFIT0_OFFSET (ProximityDomain), "Proximity Domain", 0},
|
||||
{ACPI_DMT_UUID, ACPI_NFIT0_OFFSET (RangeGuid[0]), "Address Range GUID", 0},
|
||||
{ACPI_DMT_UUID, ACPI_NFIT0_OFFSET (RangeGuid[0]), "Region Type GUID", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_NFIT0_OFFSET (Address), "Address Range Base", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_NFIT0_OFFSET (Length), "Address Range Length", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_NFIT0_OFFSET (MemoryMapping), "Memory Map Attribute", 0},
|
||||
@ -1246,6 +1248,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPdtt0[] =
|
||||
{ACPI_DMT_UINT8, ACPI_PDTT0_OFFSET (Flags), "Flags (Decoded Below)", DT_FLAG},
|
||||
{ACPI_DMT_FLAG0, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Runtime Trigger", 0},
|
||||
{ACPI_DMT_FLAG1, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Wait for Completion", 0},
|
||||
{ACPI_DMT_FLAG2, ACPI_PDTT0_FLAG_OFFSET (Flags,0), "Trigger Order", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
@ -1348,6 +1351,9 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPptt0[] =
|
||||
{ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Flags), "Flags (decoded below)", 0},
|
||||
{ACPI_DMT_FLAG0, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "Physical package", 0},
|
||||
{ACPI_DMT_FLAG1, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "ACPI Processor ID valid", 0},
|
||||
{ACPI_DMT_FLAG2, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "Processor is a thread", 0},
|
||||
{ACPI_DMT_FLAG3, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "Node is a leaf", 0},
|
||||
{ACPI_DMT_FLAG4, ACPI_PPTT0_FLAG_OFFSET (Flags,0), "Identical Implementation", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (Parent), "Parent", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (AcpiProcessorId), "ACPI Processor ID", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_PPTT0_OFFSET (NumberOfPrivResources), "Private Resource Number", 0},
|
||||
@ -1390,12 +1396,12 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoPptt1[] =
|
||||
ACPI_DMTABLE_INFO AcpiDmTableInfoPptt2[] =
|
||||
{
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (Reserved), "Reserved", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_PPTT2_OFFSET (VendorId), "VENDOR_ID", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_PPTT2_OFFSET (Level1Id), "LEVEL_1_ID", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_PPTT2_OFFSET (Level2Id), "LEVEL_2_ID", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (MajorRev), "MAJOR_REV", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (MinorRev), "MINOR_REV", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (SpinRev), "SPIN_REV", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_PPTT2_OFFSET (VendorId), "Vendor ID", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_PPTT2_OFFSET (Level1Id), "Level1 ID", 0},
|
||||
{ACPI_DMT_UINT64, ACPI_PPTT2_OFFSET (Level2Id), "Level2 ID", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (MajorRev), "Major revision", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (MinorRev), "Minor revision", 0},
|
||||
{ACPI_DMT_UINT16, ACPI_PPTT2_OFFSET (SpinRev), "Spin revision", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
@ -1473,7 +1479,7 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSbst[] =
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* SDEI - Software Delegated Execption Interface Descriptor Table
|
||||
* SDEI - Software Delegated Exception Interface Descriptor Table
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -368,6 +368,20 @@ ACPI_DMTABLE_INFO AcpiDmTableInfoSrat4[] =
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
/* 5: Generic Initiator Affinity Structure (ACPI 6.3) */
|
||||
|
||||
ACPI_DMTABLE_INFO AcpiDmTableInfoSrat5[] =
|
||||
{
|
||||
{ACPI_DMT_UINT8, ACPI_SRAT5_OFFSET (Reserved), "Reserved1", 0},
|
||||
{ACPI_DMT_UINT8, ACPI_SRAT5_OFFSET (DeviceHandleType), "Device Handle Type", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_SRAT5_OFFSET (ProximityDomain), "Proximity Domain", 0},
|
||||
{ACPI_DMT_BUF16, ACPI_SRAT5_OFFSET (DeviceHandle), "Device Handle", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_SRAT5_OFFSET (Flags), "Flags (decoded below)", DT_FLAG},
|
||||
{ACPI_DMT_FLAG0, ACPI_SRAT5_FLAG_OFFSET (Flags,0), "Enabled", 0},
|
||||
{ACPI_DMT_UINT32, ACPI_SRAT5_OFFSET (Reserved1), "Reserved2", 0},
|
||||
ACPI_DMT_TERMINATOR
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
|
@ -494,6 +494,7 @@ CmDoCompile (
|
||||
UtEndEvent (Event);
|
||||
|
||||
UtEndEvent (FullCompile);
|
||||
AslCheckExpectedExceptions ();
|
||||
CmCleanupAndExit ();
|
||||
return (0);
|
||||
|
||||
@ -811,7 +812,6 @@ CmCleanupAndExit (
|
||||
BOOLEAN DeleteAmlFile = FALSE;
|
||||
|
||||
|
||||
AslCheckExpectedExceptions ();
|
||||
AePrintErrorLog (ASL_FILE_STDERR);
|
||||
if (AslGbl_DebugFlag)
|
||||
{
|
||||
|
@ -702,7 +702,7 @@ OpnDoPackage (
|
||||
|
||||
|
||||
/*
|
||||
* aslopt - optmization
|
||||
* aslopt - optimization
|
||||
*/
|
||||
void
|
||||
OptOptimizeNamePath (
|
||||
@ -1153,7 +1153,7 @@ OtXrefWalkPart1 (
|
||||
|
||||
|
||||
/*
|
||||
* aslutils - common compiler utilites
|
||||
* aslutils - common compiler utilities
|
||||
*/
|
||||
void
|
||||
DbgPrint (
|
||||
|
@ -692,7 +692,7 @@ NamePathTail [.]{NameSeg}
|
||||
"IPMI" { count (0); return (PARSEOP_REGIONSPACE_IPMI); }
|
||||
"GeneralPurposeIo" { count (0); return (PARSEOP_REGIONSPACE_GPIO); } /* ACPI 5.0 */
|
||||
"GenericSerialBus" { count (0); return (PARSEOP_REGIONSPACE_GSBUS); } /* ACPI 5.0 */
|
||||
"PCC" { count (0); return (PARSEOP_REGIONSPACE_PCC); } /* ACPI 5.0 */
|
||||
"PlatformCommChannel" { count (0); return (PARSEOP_REGIONSPACE_PCC); } /* ACPI 5.0 */
|
||||
"FFixedHW" { count (0); return (PARSEOP_REGIONSPACE_FFIXEDHW); }
|
||||
|
||||
/* ResourceTypeKeyword: Resource Usage - Resource Descriptors */
|
||||
@ -816,6 +816,13 @@ NamePathTail [.]{NameSeg}
|
||||
s=UtLocalCacheCalloc (ACPI_NAME_SIZE + 1);
|
||||
if (strcmp (AslCompilertext, "\\"))
|
||||
{
|
||||
/*
|
||||
* According to the ACPI specification,
|
||||
* NameSegments must have length of 4. If
|
||||
* the NameSegment has length less than 4,
|
||||
* they are padded with underscores to meet
|
||||
* the required length.
|
||||
*/
|
||||
strcpy (s, "____");
|
||||
AcpiUtStrupr (AslCompilertext);
|
||||
}
|
||||
|
@ -331,8 +331,8 @@ LdLoadFieldElements (
|
||||
* The name already exists in this scope
|
||||
* But continue processing the elements
|
||||
*/
|
||||
AslDualParseOpError (ASL_WARNING, ASL_MSG_EXTERN_COLLISION, Child,
|
||||
Child->Asl.Value.String, ASL_MSG_EXTERN_FOUND_HERE, Node->Op,
|
||||
AslDualParseOpError (ASL_WARNING, ASL_MSG_NAME_EXISTS, Child,
|
||||
Child->Asl.Value.String, ASL_MSG_FOUND_HERE, Node->Op,
|
||||
Node->Op->Asl.ExternalName);
|
||||
}
|
||||
}
|
||||
@ -575,7 +575,7 @@ LdNamespace1Begin (
|
||||
if (Status == AE_NOT_FOUND)
|
||||
{
|
||||
/*
|
||||
* This is either a foward reference or the object truly
|
||||
* This is either a forward reference or the object truly
|
||||
* does not exist. The two cases can only be differentiated
|
||||
* during the cross-reference stage later. Mark the Op/Name
|
||||
* as not-found for now to indicate the need for further
|
||||
|
@ -353,15 +353,17 @@ const char *AslCompilerMsgs [] =
|
||||
/* ASL_MSG_NULL_RESOURCE_TEMPLATE */ "Empty Resource Template (END_TAG only)",
|
||||
/* ASL_MSG_FOUND_HERE */ "Original name creation/declaration below: ",
|
||||
/* ASL_MSG_ILLEGAL_RECURSION */ "Illegal recursive call to method that creates named objects",
|
||||
/* ASL_MSG_EXTERN_COLLISION */ "A name cannot be defined and declared external in the same table",
|
||||
/* ASL_MSG_FOUND_HERE_EXTERN */ "Remove one of the declarations indicated above or below:",
|
||||
/* ASL_MSG_PLACE_HOLDER_00 */ "", /* TODO: fill in this slot with a new error message */
|
||||
/* ASL_MSG_PLACE_HOLDER_01 */ "", /* TODO: fill in this slot with a new error message */
|
||||
/* ASL_MSG_OEM_TABLE_ID */ "Invalid OEM Table ID",
|
||||
/* ASL_MSG_OEM_ID */ "Invalid OEM ID",
|
||||
/* ASL_MSG_UNLOAD */ "Unload is not supported by all operating systems",
|
||||
/* ASL_MSG_OFFSET */ "Unnecessary/redundant use of Offset operator",
|
||||
/* ASL_MSG_LONG_SLEEP */ "Very long Sleep, greater than 1 second",
|
||||
/* ASL_MSG_PREFIX_NOT_EXIST */ "One or more prefix Scopes do not exist",
|
||||
/* ASL_MSG_NAMEPATH_NOT_EXIST */ "One or more objects within the Pathname do not exist"
|
||||
/* ASL_MSG_NAMEPATH_NOT_EXIST */ "One or more objects within the Pathname do not exist",
|
||||
/* ASL_MSG_REGION_LENGTH */ "Operation Region declared with zero length",
|
||||
/* ASL_MSG_TEMPORARY_OBJECT */ "Object is created temporarily in another method and cannot be accessed"
|
||||
};
|
||||
|
||||
/* Table compiler */
|
||||
|
@ -355,8 +355,8 @@ typedef enum
|
||||
ASL_MSG_NULL_RESOURCE_TEMPLATE,
|
||||
ASL_MSG_FOUND_HERE,
|
||||
ASL_MSG_ILLEGAL_RECURSION,
|
||||
ASL_MSG_EXTERN_COLLISION,
|
||||
ASL_MSG_EXTERN_FOUND_HERE,
|
||||
ASL_MSG_PLACE_HOLDER_00,
|
||||
ASL_MSG_PLACE_HOLDER_01,
|
||||
ASL_MSG_OEM_TABLE_ID,
|
||||
ASL_MSG_OEM_ID,
|
||||
ASL_MSG_UNLOAD,
|
||||
@ -364,6 +364,8 @@ typedef enum
|
||||
ASL_MSG_LONG_SLEEP,
|
||||
ASL_MSG_PREFIX_NOT_EXIST,
|
||||
ASL_MSG_NAMEPATH_NOT_EXIST,
|
||||
ASL_MSG_REGION_LENGTH,
|
||||
ASL_MSG_TEMPORARY_OBJECT,
|
||||
|
||||
/* These messages are used by the Data Table compiler only */
|
||||
|
||||
|
@ -657,6 +657,7 @@ OpnDoRegion (
|
||||
ACPI_PARSE_OBJECT *Op)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *Next;
|
||||
ACPI_ADR_SPACE_TYPE SpaceId;
|
||||
|
||||
|
||||
/* Opcode is parent node */
|
||||
@ -667,6 +668,7 @@ OpnDoRegion (
|
||||
/* Second child is the space ID */
|
||||
|
||||
Next = Next->Asl.Next;
|
||||
SpaceId = (ACPI_ADR_SPACE_TYPE) Next->Common.Value.Integer;
|
||||
|
||||
/* Third child is the region offset */
|
||||
|
||||
@ -677,7 +679,13 @@ OpnDoRegion (
|
||||
Next = Next->Asl.Next;
|
||||
if (Next->Asl.ParseOpcode == PARSEOP_INTEGER)
|
||||
{
|
||||
/* Check for zero length */
|
||||
|
||||
Op->Asl.Value.Integer = Next->Asl.Value.Integer;
|
||||
if (!Op->Asl.Value.Integer && (SpaceId < ACPI_NUM_PREDEFINED_REGIONS))
|
||||
{
|
||||
AslError (ASL_ERROR, ASL_MSG_REGION_LENGTH, Op, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -814,7 +814,7 @@ OptOptimizeNamePath (
|
||||
ACPI_FREE (ExternalNameString);
|
||||
|
||||
/*
|
||||
* Attempt an optmization depending on the type of namepath
|
||||
* Attempt an optimization depending on the type of namepath
|
||||
*/
|
||||
if (Flags & (AML_NAMED | AML_CREATE))
|
||||
{
|
||||
|
@ -449,7 +449,7 @@ ApCheckPredefinedReturnValue (
|
||||
* DESCRIPTION: Check for a predefined name for a static object (created via
|
||||
* the ASL Name operator). If it is a predefined ACPI name, ensure
|
||||
* that the name does not require any arguments (which would
|
||||
* require a control method implemenation of the name), and that
|
||||
* require a control method implementation of the name), and that
|
||||
* the type of the object is one of the expected types for the
|
||||
* predefined name.
|
||||
*
|
||||
|
@ -239,7 +239,7 @@ OpcDoFprintf (
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Convert printf macro to a Store AML operation. The printf
|
||||
* macro parse tree is layed out as follows:
|
||||
* macro parse tree is laid out as follows:
|
||||
*
|
||||
* Op - printf parse op
|
||||
* Op->Child - Format string
|
||||
|
@ -866,7 +866,7 @@ UartSerialBusTerm
|
||||
OptionalBitsPerByte /* 05: BitsPerByte */
|
||||
OptionalStopBits /* 06: StopBits */
|
||||
',' ByteConstExpr /* 08: LinesInUse */
|
||||
OptionalEndian /* 09: Endianess */
|
||||
OptionalEndian /* 09: Endianness */
|
||||
OptionalParityType /* 10: Parity */
|
||||
OptionalFlowControl /* 11: FlowControl */
|
||||
',' WordConstExpr /* 13: Rx BufferSize */
|
||||
@ -891,7 +891,7 @@ UartSerialBusTermV2
|
||||
OptionalBitsPerByte /* 05: BitsPerByte */
|
||||
OptionalStopBits /* 06: StopBits */
|
||||
',' ByteConstExpr /* 08: LinesInUse */
|
||||
OptionalEndian /* 09: Endianess */
|
||||
OptionalEndian /* 09: Endianness */
|
||||
OptionalParityType /* 10: Parity */
|
||||
OptionalFlowControl /* 11: FlowControl */
|
||||
',' WordConstExpr /* 13: Rx BufferSize */
|
||||
|
@ -610,7 +610,7 @@ loop:
|
||||
|
||||
/*
|
||||
* Check for nested comment -- can help catch cases where a previous
|
||||
* comment was accidently left unterminated
|
||||
* comment was accidentally left unterminated
|
||||
*/
|
||||
if ((c1 == '/') && (c == '*'))
|
||||
{
|
||||
|
@ -174,6 +174,12 @@ XfNamespaceLocateEnd (
|
||||
UINT32 Level,
|
||||
void *Context);
|
||||
|
||||
static BOOLEAN
|
||||
XfValidateCrossReference (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
const ACPI_OPCODE_INFO *OpInfo,
|
||||
ACPI_NAMESPACE_NODE *Node);
|
||||
|
||||
static ACPI_PARSE_OBJECT *
|
||||
XfGetParentMethod (
|
||||
ACPI_PARSE_OBJECT *Op);
|
||||
@ -408,6 +414,7 @@ XfGetParentMethod (
|
||||
return (NULL); /* No parent method found */
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfNamespaceLocateBegin
|
||||
@ -488,7 +495,7 @@ XfNamespaceLocateBegin (
|
||||
Node->ArgCount = (UINT8)
|
||||
(((UINT8) NextOp->Asl.Value.Integer) & 0x07);
|
||||
|
||||
/* We will track all posible ArgXs */
|
||||
/* We will track all possible ArgXs */
|
||||
|
||||
for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
|
||||
{
|
||||
@ -776,6 +783,15 @@ XfNamespaceLocateBegin (
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* Check for an attempt to access an object in another method */
|
||||
|
||||
if (!XfValidateCrossReference (Op, OpInfo, Node))
|
||||
{
|
||||
AslError (ASL_ERROR, ASL_MSG_TEMPORARY_OBJECT, Op,
|
||||
Op->Asl.ExternalName);
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* Object was found above, check for an illegal forward reference */
|
||||
|
||||
if (Op->Asl.CompileFlags & OP_NOT_FOUND_DURING_LOAD)
|
||||
@ -1234,3 +1250,103 @@ XfNamespaceLocateEnd (
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: XfValidateCrossReference
|
||||
*
|
||||
* PARAMETERS: Op - Parse Op that references the object
|
||||
* OpInfo - Parse Op info struct
|
||||
* Node - Node for the referenced object
|
||||
*
|
||||
* RETURN: TRUE if the reference is legal, FALSE otherwise
|
||||
*
|
||||
* DESCRIPTION: Determine if a reference to another object is allowed.
|
||||
*
|
||||
* EXAMPLE:
|
||||
* Method (A) {Name (INT1, 1)} Declaration of object INT1
|
||||
* Method (B) (Store (2, \A.INT1)} Illegal reference to object INT1
|
||||
* (INT1 is temporary, valid only during
|
||||
* execution of A)
|
||||
*
|
||||
* NOTES:
|
||||
* A null pointer returned by either XfGetParentMethod or
|
||||
* UtGetParentMethod indicates that the parameter object is not
|
||||
* within a control method.
|
||||
*
|
||||
* Five cases are handled: Case(Op, Node)
|
||||
* 1) Case(0,0): Op is not within a method, Node is not --> OK
|
||||
* 2) Case(0,1): Op is not within a method, but Node is --> Illegal
|
||||
* 3) Case(1,0): Op is within a method, Node is not --> OK
|
||||
* 4) Case(1,1): Both are within the same method --> OK
|
||||
* 5) Case(1,1): Both are in methods, but not same method --> Illegal
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static BOOLEAN
|
||||
XfValidateCrossReference (
|
||||
ACPI_PARSE_OBJECT *Op,
|
||||
const ACPI_OPCODE_INFO *OpInfo,
|
||||
ACPI_NAMESPACE_NODE *Node)
|
||||
{
|
||||
ACPI_PARSE_OBJECT *ReferencingMethodOp;
|
||||
ACPI_NAMESPACE_NODE *ReferencedMethodNode;
|
||||
|
||||
|
||||
/* Ignore actual named (and related) object declarations */
|
||||
|
||||
if (OpInfo->Flags & (AML_NAMED | AML_CREATE | AML_DEFER | AML_HAS_ARGS))
|
||||
{
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* 1) Search upwards in parse tree for owner of the referencing object
|
||||
* 2) Search upwards in namespace to find the owner of the referenced object
|
||||
*/
|
||||
ReferencingMethodOp = XfGetParentMethod (Op);
|
||||
ReferencedMethodNode = UtGetParentMethod (Node);
|
||||
|
||||
if (!ReferencingMethodOp && !ReferencedMethodNode)
|
||||
{
|
||||
/*
|
||||
* 1) Case (0,0): Both Op and Node are not within methods
|
||||
* --> OK
|
||||
*/
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
if (!ReferencingMethodOp && ReferencedMethodNode)
|
||||
{
|
||||
/*
|
||||
* 2) Case (0,1): Op is not in a method, but Node is within a
|
||||
* method --> illegal
|
||||
*/
|
||||
return (FALSE);
|
||||
}
|
||||
else if (ReferencingMethodOp && !ReferencedMethodNode)
|
||||
{
|
||||
/*
|
||||
* 3) Case (1,0): Op is within a method, but Node is not
|
||||
* --> OK
|
||||
*/
|
||||
return (TRUE);
|
||||
}
|
||||
else if (ReferencingMethodOp->Asl.Node == ReferencedMethodNode)
|
||||
{
|
||||
/*
|
||||
* 4) Case (1,1): Both Op and Node are within the same method
|
||||
* --> OK
|
||||
*/
|
||||
return (TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* 5) Case (1,1), Op and Node are in different methods
|
||||
* --> Illegal
|
||||
*/
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
|
@ -168,7 +168,7 @@
|
||||
*
|
||||
* DESCRIPTION: Process a single line comment of a c Style comment. This
|
||||
* function captures a line of a c style comment in a char* and
|
||||
* places the comment in the approperiate global buffer.
|
||||
* places the comment in the appropriate global buffer.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -294,7 +294,7 @@ CvProcessComment (
|
||||
* RETURN: none
|
||||
*
|
||||
* DESCRIPTION: Process a single line comment. This function captures a comment
|
||||
* in a char* and places the comment in the approperiate global
|
||||
* in a char* and places the comment in the appropriate global
|
||||
* buffer through CvPlaceComment
|
||||
*
|
||||
******************************************************************************/
|
||||
@ -333,7 +333,7 @@ CvProcessCommentType2 (
|
||||
*
|
||||
* would be lexically analyzed as a single comment.
|
||||
*
|
||||
* Create a new string with the approperiate spaces. Since we need
|
||||
* Create a new string with the appropriate spaces. Since we need
|
||||
* to account for the proper spacing, the actual comment,
|
||||
* extra 2 spaces so that this comment can be converted to the "/ *"
|
||||
* style and the null terminator, the string would look something
|
||||
@ -380,7 +380,7 @@ CvProcessCommentType2 (
|
||||
* RETURN: TotalCommentLength - Length of all comments within this op.
|
||||
*
|
||||
* DESCRIPTION: Calculate the length that the each comment takes up within Op.
|
||||
* Comments look like the follwoing: [0xA9 OptionBtye comment 0x00]
|
||||
* Comments look like the following: [0xA9 OptionBtye comment 0x00]
|
||||
* therefore, we add 1 + 1 + strlen (comment) + 1 to get the actual
|
||||
* length of this comment.
|
||||
*
|
||||
@ -963,7 +963,7 @@ CvAppendInlineComment (
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Given type and CommentString, this function places the
|
||||
* CommentString in the approperiate global comment list or char*
|
||||
* CommentString in the appropriate global comment list or char*
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -276,7 +276,7 @@ CvInitFileTree (
|
||||
AcpiGbl_FileTreeRoot->File = AcpiGbl_OutputFile;
|
||||
|
||||
/*
|
||||
* Set this to true because we dont need to output
|
||||
* Set this to true because we don't need to output
|
||||
* an include statement for the topmost file
|
||||
*/
|
||||
AcpiGbl_FileTreeRoot->IncludeWritten = TRUE;
|
||||
@ -514,7 +514,7 @@ CvFileAddressLookup(
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Takes a given parse op, looks up its Op->Common.Aml field
|
||||
* within the file tree and fills in approperiate file information
|
||||
* within the file tree and fills in appropriate file information
|
||||
* from a matching node within the tree.
|
||||
* This is referred as ASL_CV_LABEL_FILENODE.
|
||||
*
|
||||
@ -1005,7 +1005,7 @@ CvCaptureComments (
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Transfer all of the commments stored in global containers to the
|
||||
* DESCRIPTION: Transfer all of the comments stored in global containers to the
|
||||
* given Op. This will be invoked shortly after the parser creates
|
||||
* a ParseOp.
|
||||
* This is referred as ASL_CV_TRANSFER_COMMENTS.
|
||||
|
@ -372,7 +372,7 @@ DtDoOperator (
|
||||
*
|
||||
* RETURN: Table offset associated with the label
|
||||
*
|
||||
* DESCRIPTION: Lookup a lable and return its value.
|
||||
* DESCRIPTION: Lookup a label and return its value.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
|
@ -375,7 +375,7 @@ DtParseLine (
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/* All lines after "Raw Table Data" are ingored */
|
||||
/* All lines after "Raw Table Data" are ignored */
|
||||
|
||||
if (strstr (LineBuffer, ACPI_RAW_TABLE_DATA_HEADER))
|
||||
{
|
||||
|
@ -831,7 +831,7 @@ DtCompileDrtm (
|
||||
DtInsertSubtable (ParentTable, Subtable);
|
||||
|
||||
/*
|
||||
* Using ACPI_SUB_PTR, We needn't define a seperate structure. Care
|
||||
* Using ACPI_SUB_PTR, We needn't define a separate structure. Care
|
||||
* should be taken to avoid accessing ACPI_TABLE_HADER fields.
|
||||
*/
|
||||
#if 0
|
||||
@ -1002,8 +1002,15 @@ DtCompileGtdt (
|
||||
ACPI_SUBTABLE_HEADER *GtdtHeader;
|
||||
ACPI_DMTABLE_INFO *InfoTable;
|
||||
UINT32 GtCount;
|
||||
ACPI_TABLE_HEADER *Header;
|
||||
|
||||
|
||||
ParentTable = DtPeekSubtable ();
|
||||
|
||||
Header = ACPI_CAST_PTR (ACPI_TABLE_HEADER, ParentTable->Buffer);
|
||||
|
||||
/* Compile the main table */
|
||||
|
||||
Status = DtCompileTable (PFieldList, AcpiDmTableInfoGtdt,
|
||||
&Subtable);
|
||||
if (ACPI_FAILURE (Status))
|
||||
@ -1011,6 +1018,21 @@ DtCompileGtdt (
|
||||
return (Status);
|
||||
}
|
||||
|
||||
/* GTDT revision 3 later contains 2 extra fields before subtables */
|
||||
|
||||
if (Header->Revision > 2)
|
||||
{
|
||||
ParentTable = DtPeekSubtable ();
|
||||
DtInsertSubtable (ParentTable, Subtable);
|
||||
|
||||
Status = DtCompileTable (PFieldList,
|
||||
AcpiDmTableInfoGtdtEl2, &Subtable);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return (Status);
|
||||
}
|
||||
}
|
||||
|
||||
ParentTable = DtPeekSubtable ();
|
||||
DtInsertSubtable (ParentTable, Subtable);
|
||||
|
||||
|
@ -1733,6 +1733,11 @@ DtCompileSrat (
|
||||
InfoTable = AcpiDmTableInfoSrat4;
|
||||
break;
|
||||
|
||||
case ACPI_SRAT_TYPE_GENERIC_AFFINITY:
|
||||
|
||||
InfoTable = AcpiDmTableInfoSrat5;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
DtFatal (ASL_MSG_UNKNOWN_SUBTABLE, SubtableStart, "SRAT");
|
||||
|
@ -545,34 +545,35 @@ const unsigned char TemplateFpdt[] =
|
||||
|
||||
const unsigned char TemplateGtdt[] =
|
||||
{
|
||||
0x47,0x54,0x44,0x54,0xe0,0x00,0x00,0x00, /* 00000000 "GTDT...." */
|
||||
0x02,0xb0,0x4c,0x49,0x4e,0x41,0x52,0x4f, /* 00000008 "..LINARO" */
|
||||
0x52,0x54,0x53,0x4d,0x56,0x45,0x56,0x38, /* 00000010 "RTSMVEV8" */
|
||||
0x01,0x00,0x00,0x00,0x49,0x4e,0x54,0x4c, /* 00000018 "....INTL" */
|
||||
0x24,0x04,0x14,0x20,0x00,0x00,0x00,0x00, /* 00000020 "$.. ...." */
|
||||
0x47,0x54,0x44,0x54,0xE8,0x00,0x00,0x00, /* 00000000 "GTDT...." */
|
||||
0x03,0x5D,0x4C,0x49,0x4E,0x41,0x52,0x4F, /* 00000008 ".]LINARO" */
|
||||
0x52,0x54,0x53,0x4D,0x56,0x45,0x56,0x38, /* 00000010 "RTSMVEV8" */
|
||||
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
|
||||
0x08,0x01,0x19,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
|
||||
0x1d,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
|
||||
0x1e,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */
|
||||
0x1b,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000040 "........" */
|
||||
0x1a,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000048 "........" */
|
||||
0x1D,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
|
||||
0x1E,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000038 "........" */
|
||||
0x1B,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000040 "........" */
|
||||
0x1A,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000048 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000050 "........" */
|
||||
0x02,0x00,0x00,0x00,0x60,0x00,0x00,0x00, /* 00000058 "....`..." */
|
||||
0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000060 ".d......" */
|
||||
0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000068 "........" */
|
||||
0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000070 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
|
||||
0x43,0x00,0x00,0x00,0x21,0x00,0x00,0x00, /* 00000060 "C...!..." */
|
||||
0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000068 ".d......" */
|
||||
0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, /* 00000070 "........" */
|
||||
0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000078 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000088 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000090 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000098 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000a0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000a8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000b0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000b8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x1c,0x00,0x00, /* 000000c0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000c8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000d0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000d8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000A0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000B8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, /* 000000C0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x1C,0x00,0x00, /* 000000C8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00 /* 000000E0 "........" */
|
||||
};
|
||||
|
||||
const unsigned char TemplateHest[] =
|
||||
@ -662,10 +663,10 @@ const unsigned char TemplateHest[] =
|
||||
const unsigned char TemplateHmat[] =
|
||||
{
|
||||
0x48,0x4D,0x41,0x54,0x9C,0x00,0x00,0x00, /* 00000000 "HMAT...." */
|
||||
0x00,0x54,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".TINTEL " */
|
||||
0x02,0x4D,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".MINTEL " */
|
||||
0x54,0x45,0x4D,0x50,0x4C,0x41,0x54,0x45, /* 00000010 "TEMPLATE" */
|
||||
0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
|
||||
0x03,0x03,0x17,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
|
||||
0x08,0x01,0x19,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
|
||||
0x00,0x00,0x00,0x00,0x28,0x00,0x00,0x00, /* 00000028 "....(..." */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
|
||||
@ -817,10 +818,10 @@ const unsigned char TemplateLpit[] =
|
||||
const unsigned char TemplateMadt[] =
|
||||
{
|
||||
0x41,0x50,0x49,0x43,0x5A,0x01,0x00,0x00, /* 00000000 "APICZ..." */
|
||||
0x03,0xEA,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
|
||||
0x05,0xEF,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
|
||||
0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
|
||||
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
|
||||
0x10,0x04,0x15,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
|
||||
0x08,0x01,0x19,0x20,0x00,0x00,0x00,0x00, /* 00000020 "... ...." */
|
||||
0x01,0x00,0x00,0x00,0x00,0x08,0x00,0x00, /* 00000028 "........" */
|
||||
0x01,0x00,0x00,0x00,0x01,0x0C,0x01,0x00, /* 00000030 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
|
||||
@ -1375,11 +1376,11 @@ const unsigned char TemplateSpmi[] =
|
||||
|
||||
const unsigned char TemplateSrat[] =
|
||||
{
|
||||
0x53,0x52,0x41,0x54,0x9E,0x00,0x00,0x00, /* 00000000 "SRAT...." */
|
||||
0x03,0x55,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 ".UINTEL " */
|
||||
0x53,0x52,0x41,0x54,0xBE,0x00,0x00,0x00, /* 00000000 "SRAT...." */
|
||||
0x03,0xE6,0x49,0x4E,0x54,0x45,0x4C,0x20, /* 00000008 "..INTEL " */
|
||||
0x54,0x65,0x6D,0x70,0x6C,0x61,0x74,0x65, /* 00000010 "Template" */
|
||||
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
|
||||
0x03,0x03,0x17,0x20,0x01,0x00,0x00,0x00, /* 00000020 "... ...." */
|
||||
0x29,0x06,0x18,0x20,0x01,0x00,0x00,0x00, /* 00000020 ").. ...." */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028 "........" */
|
||||
0x00,0x10,0x00,0x00,0x01,0x00,0x00,0x00, /* 00000030 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000038 "........" */
|
||||
@ -1394,7 +1395,11 @@ const unsigned char TemplateSrat[] =
|
||||
0x03,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000080 "........" */
|
||||
0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000088 "........" */
|
||||
0x00,0x00,0x04,0x0C,0x00,0x00,0x00,0x00, /* 00000090 "........" */
|
||||
0x00,0x00,0x01,0x00,0x00,0x00 /* 00000098 "......" */
|
||||
0x00,0x00,0x01,0x00,0x00,0x00,0x05,0x20, /* 00000098 "....... " */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000A8 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000B0 "........" */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00 /* 000000B8 "......" */
|
||||
};
|
||||
|
||||
const unsigned char TemplateStao[] =
|
||||
|
@ -410,7 +410,7 @@ AcpiDbDecodeAndDisplayObject (
|
||||
|
||||
default:
|
||||
|
||||
/* Is not a recognizeable object */
|
||||
/* Is not a recognizable object */
|
||||
|
||||
AcpiOsPrintf (
|
||||
"Not a known ACPI internal object, descriptor type %2.2X\n",
|
||||
@ -866,7 +866,7 @@ AcpiDbDisplayObjectType (
|
||||
*
|
||||
* DESCRIPTION: Display the result of an AML opcode
|
||||
*
|
||||
* Note: Curently only displays the result object if we are single stepping.
|
||||
* Note: Currently only displays the result object if we are single stepping.
|
||||
* However, this output may be useful in other contexts and could be enabled
|
||||
* to do so if needed.
|
||||
*
|
||||
|
@ -331,12 +331,12 @@ AcpiDbExecuteMethod (
|
||||
}
|
||||
|
||||
ACPI_EXCEPTION ((AE_INFO, Status,
|
||||
"while executing %s from debugger", Info->Pathname));
|
||||
"while executing %s from AML Debugger", Info->Pathname));
|
||||
|
||||
if (Status == AE_BUFFER_OVERFLOW)
|
||||
{
|
||||
ACPI_ERROR ((AE_INFO,
|
||||
"Possible overflow of internal debugger "
|
||||
"Possible buffer overflow within AML Debugger "
|
||||
"buffer (size 0x%X needed 0x%X)",
|
||||
ACPI_DEBUG_BUFFER_SIZE, (UINT32) ReturnObj->Length));
|
||||
}
|
||||
|
@ -1175,7 +1175,7 @@ AcpiDbBusWalk (
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Display info about system busses.
|
||||
* DESCRIPTION: Display info about system buses.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -420,7 +420,7 @@ AcpiDbDisplayInternalObject (
|
||||
|
||||
AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc));
|
||||
|
||||
/* Decode the refererence */
|
||||
/* Decode the reference */
|
||||
|
||||
switch (ObjDesc->Reference.Class)
|
||||
{
|
||||
|
@ -154,6 +154,7 @@
|
||||
#include <contrib/dev/acpica/include/acdebug.h>
|
||||
#include <contrib/dev/acpica/include/acnamesp.h>
|
||||
#include <contrib/dev/acpica/include/acpredef.h>
|
||||
#include <contrib/dev/acpica/include/acinterp.h>
|
||||
|
||||
|
||||
#define _COMPONENT ACPI_CA_DEBUGGER
|
||||
@ -192,6 +193,10 @@ static ACPI_STATUS
|
||||
AcpiDbTestPackageType (
|
||||
ACPI_NAMESPACE_NODE *Node);
|
||||
|
||||
static ACPI_STATUS
|
||||
AcpiDbTestFieldUnitType (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc);
|
||||
|
||||
static ACPI_STATUS
|
||||
AcpiDbReadFromObject (
|
||||
ACPI_NAMESPACE_NODE *Node,
|
||||
@ -241,7 +246,7 @@ static ACPI_DB_ARGUMENT_INFO AcpiDbTestTypes [] =
|
||||
static ACPI_HANDLE ReadHandle = NULL;
|
||||
static ACPI_HANDLE WriteHandle = NULL;
|
||||
|
||||
/* ASL Definitions of the debugger read/write control methods */
|
||||
/* ASL Definitions of the debugger read/write control methods. AML below. */
|
||||
|
||||
#if 0
|
||||
DefinitionBlock ("ssdt.aml", "SSDT", 2, "Intel", "DEBUG", 0x00000001)
|
||||
@ -407,10 +412,8 @@ AcpiDbTestAllObjects (
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Test one namespace object. Supported types are Integer,
|
||||
* String, Buffer, BufferField, and FieldUnit. All other object
|
||||
* types are simply ignored.
|
||||
*
|
||||
* Note: Support for Packages is not implemented.
|
||||
* String, Buffer, Package, BufferField, and FieldUnit.
|
||||
* All other object types are simply ignored.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -423,7 +426,6 @@ AcpiDbTestOneObject (
|
||||
{
|
||||
ACPI_NAMESPACE_NODE *Node;
|
||||
ACPI_OPERAND_OBJECT *ObjDesc;
|
||||
ACPI_OPERAND_OBJECT *RegionObj;
|
||||
ACPI_OBJECT_TYPE LocalType;
|
||||
UINT32 BitLength = 0;
|
||||
UINT32 ByteLength = 0;
|
||||
@ -466,19 +468,22 @@ AcpiDbTestOneObject (
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_FIELD_UNIT:
|
||||
case ACPI_TYPE_BUFFER_FIELD:
|
||||
case ACPI_TYPE_LOCAL_REGION_FIELD:
|
||||
case ACPI_TYPE_LOCAL_INDEX_FIELD:
|
||||
case ACPI_TYPE_LOCAL_BANK_FIELD:
|
||||
|
||||
LocalType = ACPI_TYPE_INTEGER;
|
||||
if (ObjDesc)
|
||||
{
|
||||
LocalType = ACPI_TYPE_FIELD_UNIT;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER_FIELD:
|
||||
/*
|
||||
* Returned object will be a Buffer if the field length
|
||||
* The returned object will be a Buffer if the field length
|
||||
* is larger than the size of an Integer (32 or 64 bits
|
||||
* depending on the DSDT version).
|
||||
*/
|
||||
LocalType = ACPI_TYPE_INTEGER;
|
||||
if (ObjDesc)
|
||||
{
|
||||
BitLength = ObjDesc->CommonField.BitLength;
|
||||
ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
|
||||
if (BitLength > AcpiGbl_IntegerBitWidth)
|
||||
@ -490,7 +495,7 @@ AcpiDbTestOneObject (
|
||||
|
||||
default:
|
||||
|
||||
/* Ignore all other types */
|
||||
/* Ignore all non-data types - Methods, Devices, Scopes, etc. */
|
||||
|
||||
return (AE_OK);
|
||||
}
|
||||
@ -502,40 +507,10 @@ AcpiDbTestOneObject (
|
||||
|
||||
if (!ObjDesc)
|
||||
{
|
||||
AcpiOsPrintf (" Ignoring, no attached object\n");
|
||||
AcpiOsPrintf (" No attached sub-object, ignoring\n");
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for unsupported region types. Note: AcpiExec simulates
|
||||
* access to SystemMemory, SystemIO, PCI_Config, and EC.
|
||||
*/
|
||||
switch (Node->Type)
|
||||
{
|
||||
case ACPI_TYPE_LOCAL_REGION_FIELD:
|
||||
|
||||
RegionObj = ObjDesc->Field.RegionObj;
|
||||
switch (RegionObj->Region.SpaceId)
|
||||
{
|
||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
case ACPI_ADR_SPACE_PCI_CONFIG:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
AcpiOsPrintf (" %s space is not supported in this command [%4.4s]\n",
|
||||
AcpiUtGetRegionName (RegionObj->Region.SpaceId),
|
||||
RegionObj->Region.Node->Name.Ascii);
|
||||
return (AE_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* At this point, we have resolved the object to one of the major types */
|
||||
|
||||
switch (LocalType)
|
||||
@ -560,6 +535,11 @@ AcpiDbTestOneObject (
|
||||
Status = AcpiDbTestPackageType (Node);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_FIELD_UNIT:
|
||||
|
||||
Status = AcpiDbTestFieldUnitType (ObjDesc);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
AcpiOsPrintf (" Ignoring, type not implemented (%2.2X)",
|
||||
@ -572,24 +552,8 @@ AcpiDbTestOneObject (
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
Status = AE_OK;
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
switch (Node->Type)
|
||||
{
|
||||
case ACPI_TYPE_LOCAL_REGION_FIELD:
|
||||
|
||||
RegionObj = ObjDesc->Field.RegionObj;
|
||||
AcpiOsPrintf (" (%s)",
|
||||
AcpiUtGetRegionName (RegionObj->Region.SpaceId));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Exit:
|
||||
AcpiOsPrintf ("\n");
|
||||
return (Status);
|
||||
}
|
||||
@ -639,7 +603,7 @@ AcpiDbTestIntegerType (
|
||||
return (Status);
|
||||
}
|
||||
|
||||
AcpiOsPrintf (" (%4.4X/%3.3X) %8.8X%8.8X",
|
||||
AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT " %8.8X%8.8X",
|
||||
BitLength, ACPI_ROUND_BITS_UP_TO_BYTES (BitLength),
|
||||
ACPI_FORMAT_UINT64 (Temp1->Integer.Value));
|
||||
|
||||
@ -761,8 +725,8 @@ AcpiDbTestBufferType (
|
||||
|
||||
/* Emit a few bytes of the buffer */
|
||||
|
||||
AcpiOsPrintf (" (%4.4X/%3.3X)", BitLength, Temp1->Buffer.Length);
|
||||
for (i = 0; ((i < 4) && (i < ByteLength)); i++)
|
||||
AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT, BitLength, Temp1->Buffer.Length);
|
||||
for (i = 0; ((i < 8) && (i < ByteLength)); i++)
|
||||
{
|
||||
AcpiOsPrintf (" %2.2X", Temp1->Buffer.Pointer[i]);
|
||||
}
|
||||
@ -876,7 +840,7 @@ AcpiDbTestStringType (
|
||||
return (Status);
|
||||
}
|
||||
|
||||
AcpiOsPrintf (" (%4.4X/%3.3X) \"%s\"", (Temp1->String.Length * 8),
|
||||
AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT " \"%s\"", (Temp1->String.Length * 8),
|
||||
Temp1->String.Length, Temp1->String.Pointer);
|
||||
|
||||
/* Write a new value */
|
||||
@ -966,12 +930,79 @@ AcpiDbTestPackageType (
|
||||
return (Status);
|
||||
}
|
||||
|
||||
AcpiOsPrintf (" %8.8X Elements", Temp1->Package.Count);
|
||||
AcpiOsPrintf (" %.2X Elements", Temp1->Package.Count);
|
||||
AcpiOsFree (Temp1);
|
||||
return (Status);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiDbTestFieldUnitType
|
||||
*
|
||||
* PARAMETERS: ObjDesc - A field unit object
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Test read/write on a named field unit.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static ACPI_STATUS
|
||||
AcpiDbTestFieldUnitType (
|
||||
ACPI_OPERAND_OBJECT *ObjDesc)
|
||||
{
|
||||
ACPI_OPERAND_OBJECT *RegionObj;
|
||||
UINT32 BitLength = 0;
|
||||
UINT32 ByteLength = 0;
|
||||
ACPI_STATUS Status = AE_OK;
|
||||
ACPI_OPERAND_OBJECT *RetBufferDesc;
|
||||
|
||||
|
||||
/* Supported spaces are memory/io/pci_config */
|
||||
|
||||
RegionObj = ObjDesc->Field.RegionObj;
|
||||
switch (RegionObj->Region.SpaceId)
|
||||
{
|
||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
case ACPI_ADR_SPACE_PCI_CONFIG:
|
||||
|
||||
/* Need the interpreter to execute */
|
||||
|
||||
AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
|
||||
AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
|
||||
|
||||
/* Exercise read-then-write */
|
||||
|
||||
Status = AcpiExReadDataFromField (NULL, ObjDesc, &RetBufferDesc);
|
||||
if (Status == AE_OK)
|
||||
{
|
||||
AcpiExWriteDataToField (RetBufferDesc, ObjDesc, NULL);
|
||||
AcpiUtRemoveReference (RetBufferDesc);
|
||||
}
|
||||
|
||||
AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
|
||||
AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
|
||||
|
||||
BitLength = ObjDesc->CommonField.BitLength;
|
||||
ByteLength = ACPI_ROUND_BITS_UP_TO_BYTES (BitLength);
|
||||
|
||||
AcpiOsPrintf (ACPI_DEBUG_LENGTH_FORMAT " [%s]", BitLength,
|
||||
ByteLength, AcpiUtGetRegionName (RegionObj->Region.SpaceId));
|
||||
return (Status);
|
||||
|
||||
default:
|
||||
|
||||
AcpiOsPrintf (
|
||||
" %s address space is not supported in this command [%4.4s]",
|
||||
AcpiUtGetRegionName (RegionObj->Region.SpaceId),
|
||||
RegionObj->Region.Node->Name.Ascii);
|
||||
return (AE_OK);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: AcpiDbReadFromObject
|
||||
|
@ -1053,7 +1053,7 @@ AcpiDmGetHardwareIdType (
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark this node as convertable to an EISA ID string */
|
||||
/* Mark this node as convertible to an EISA ID string */
|
||||
|
||||
Op->Common.DisasmOpcode = ACPI_DASM_EISAID;
|
||||
break;
|
||||
|
@ -1075,7 +1075,7 @@ AcpiDmIsValidTarget (
|
||||
*
|
||||
* DESCRIPTION: Determine if the Target duplicates the operand, in order to
|
||||
* detect if the expression can be converted to a compound
|
||||
* assigment. (+=, *=, etc.)
|
||||
* assignment. (+=, *=, etc.)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -1131,7 +1131,7 @@ AcpiDmIsTargetAnOperand (
|
||||
}
|
||||
}
|
||||
|
||||
/* Supress the duplicate operand at the top-level */
|
||||
/* Suppress the duplicate operand at the top-level */
|
||||
|
||||
if (TopLevel)
|
||||
{
|
||||
|
@ -232,7 +232,7 @@ AcpiDmDumpName (
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Diplay the pathname associated with a named object. Two
|
||||
* DESCRIPTION: Display the pathname associated with a named object. Two
|
||||
* versions. One searches the parse tree (for parser-only
|
||||
* applications suchas AcpiDump), and the other searches the
|
||||
* ACPI namespace (the parse tree is probably deleted)
|
||||
|
@ -342,7 +342,7 @@ AcpiDmBitList (
|
||||
*
|
||||
* FUNCTION: AcpiDmResourceTemplate
|
||||
*
|
||||
* PARAMETERS: Info - Curent parse tree walk info
|
||||
* PARAMETERS: Info - Current parse tree walk info
|
||||
* ByteData - Pointer to the byte list data
|
||||
* ByteCount - Length of the byte list
|
||||
*
|
||||
@ -555,7 +555,7 @@ AcpiDmIsResourceTemplate (
|
||||
|
||||
/*
|
||||
* Not a template if declared buffer length != actual length of the
|
||||
* intialization byte list. Because the resource macros will create
|
||||
* initialization byte list. Because the resource macros will create
|
||||
* a buffer of the exact required length (buffer length will be equal
|
||||
* to the actual length).
|
||||
*
|
||||
|
@ -388,7 +388,7 @@ AcpiDmFixedIoDescriptor (
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Decode a Start Dependendent functions descriptor
|
||||
* DESCRIPTION: Decode a Start Dependent functions descriptor
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -685,6 +685,12 @@ AcpiDsCreateField (
|
||||
Info.RegionNode = RegionNode;
|
||||
|
||||
Status = AcpiDsGetFieldNames (&Info, WalkState, Arg->Common.Next);
|
||||
if (Info.RegionNode->Type == ACPI_ADR_SPACE_PLATFORM_COMM &&
|
||||
!(RegionNode->Object->Field.InternalPccBuffer
|
||||
= ACPI_ALLOCATE_ZEROED(Info.RegionNode->Object->Region.Length)))
|
||||
{
|
||||
return_ACPI_STATUS (AE_NO_MEMORY);
|
||||
}
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
|
@ -521,6 +521,7 @@ AcpiDsEvalRegionOperands (
|
||||
ACPI_OPERAND_OBJECT *OperandDesc;
|
||||
ACPI_NAMESPACE_NODE *Node;
|
||||
ACPI_PARSE_OBJECT *NextOp;
|
||||
ACPI_ADR_SPACE_TYPE SpaceId;
|
||||
|
||||
|
||||
ACPI_FUNCTION_TRACE_PTR (DsEvalRegionOperands, Op);
|
||||
@ -535,6 +536,7 @@ AcpiDsEvalRegionOperands (
|
||||
/* NextOp points to the op that holds the SpaceID */
|
||||
|
||||
NextOp = Op->Common.Value.Arg;
|
||||
SpaceId = (ACPI_ADR_SPACE_TYPE) NextOp->Common.Value.Integer;
|
||||
|
||||
/* NextOp points to address op */
|
||||
|
||||
@ -572,6 +574,15 @@ AcpiDsEvalRegionOperands (
|
||||
ObjDesc->Region.Length = (UINT32) OperandDesc->Integer.Value;
|
||||
AcpiUtRemoveReference (OperandDesc);
|
||||
|
||||
/* A zero-length operation region is unusable. Just warn */
|
||||
|
||||
if (!ObjDesc->Region.Length && (SpaceId < ACPI_NUM_PREDEFINED_REGIONS))
|
||||
{
|
||||
ACPI_WARNING ((AE_INFO,
|
||||
"Operation Region [%4.4s] has zero length (SpaceId %X)",
|
||||
Node->Name.Ascii, SpaceId));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the address and save it
|
||||
* (at top of stack - 1)
|
||||
|
@ -167,7 +167,7 @@
|
||||
* FUNCTION: AcpiDsLoad2BeginOp
|
||||
*
|
||||
* PARAMETERS: WalkState - Current state of the parse tree walk
|
||||
* OutOp - Wher to return op if a new one is created
|
||||
* OutOp - Where to return op if a new one is created
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
|
@ -1012,7 +1012,7 @@ AcpiEvGpeDispatch (
|
||||
GpeDevice, GpeNumber,
|
||||
GpeEventInfo->Dispatch.Handler->Context);
|
||||
|
||||
/* If requested, clear (if level-triggered) and reenable the GPE */
|
||||
/* If requested, clear (if level-triggered) and re-enable the GPE */
|
||||
|
||||
if (ReturnValue & ACPI_REENABLE_GPE)
|
||||
{
|
||||
|
@ -409,7 +409,7 @@ AcpiEvAddressSpaceDispatch (
|
||||
/*
|
||||
* For handlers other than the default (supplied) handlers, we must
|
||||
* exit the interpreter because the handler *might* block -- we don't
|
||||
* know what it will do, so we can't hold the lock on the intepreter.
|
||||
* know what it will do, so we can't hold the lock on the interpreter.
|
||||
*/
|
||||
AcpiExExitInterpreter();
|
||||
}
|
||||
|
@ -724,24 +724,6 @@ AcpiEvInitializeRegion (
|
||||
HandlerObj = ObjDesc->CommonNotify.Handler;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
/*
|
||||
* If we are executing module level code, the original
|
||||
* Node's object was replaced by this Method object and we
|
||||
* saved the handler in the method object.
|
||||
*
|
||||
* Note: Only used for the legacy MLC support. Will
|
||||
* be removed in the future.
|
||||
*
|
||||
* See AcpiNsExecModuleCode
|
||||
*/
|
||||
if (!AcpiGbl_ExecuteTablesAsMethods &&
|
||||
ObjDesc->Method.InfoFlags & ACPI_METHOD_MODULE_LEVEL)
|
||||
{
|
||||
HandlerObj = ObjDesc->Method.Dispatch.Handler;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Ignore other objects */
|
||||
|
@ -885,9 +885,9 @@ ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
|
||||
* DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
|
||||
* processing. Intended for use by asynchronous host-installed
|
||||
* GPE handlers. The GPE is only reenabled if the EnableForRun bit
|
||||
* GPE handlers. The GPE is only re-enabled if the EnableForRun bit
|
||||
* is set in the GPE info.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -708,7 +708,7 @@ AcpiExConvertToString (
|
||||
{
|
||||
if (Base == 16)
|
||||
{
|
||||
/* Emit 0x prefix for explict/implicit hex conversion */
|
||||
/* Emit 0x prefix for explicit/implicit hex conversion */
|
||||
|
||||
*NewBuf++ = '0';
|
||||
*NewBuf++ = 'x';
|
||||
|
@ -187,6 +187,17 @@ const UINT8 AcpiProtocolLengths[] =
|
||||
0xFF /* F - ATTRIB_RAW_PROCESS_BYTES */
|
||||
};
|
||||
|
||||
#define PCC_MASTER_SUBSPACE 3
|
||||
|
||||
/*
|
||||
* The following macros determine a given offset is a COMD field.
|
||||
* According to the specification, generic subspaces (types 0-2) contains a
|
||||
* 2-byte COMD field at offset 4 and master subspaces (type 3) contains a 4-byte
|
||||
* COMD field starting at offset 12.
|
||||
*/
|
||||
#define GENERIC_SUBSPACE_COMMAND(a) (4 == a || a == 5)
|
||||
#define MASTER_SUBSPACE_COMMAND(a) (12 <= a && a <= 15)
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
@ -337,6 +348,23 @@ AcpiExReadDataFromField (
|
||||
Status = AcpiExReadGpio (ObjDesc, Buffer);
|
||||
goto Exit;
|
||||
}
|
||||
else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
|
||||
(ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_PLATFORM_COMM))
|
||||
{
|
||||
/*
|
||||
* Reading from a PCC field unit does not require the handler because
|
||||
* it only requires reading from the InternalPccBuffer.
|
||||
*/
|
||||
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
|
||||
"PCC FieldRead bits %u\n", ObjDesc->Field.BitLength));
|
||||
|
||||
memcpy (Buffer, ObjDesc->Field.RegionObj->Field.InternalPccBuffer +
|
||||
ObjDesc->Field.BaseByteOffset, (ACPI_SIZE) ACPI_ROUND_BITS_UP_TO_BYTES (
|
||||
ObjDesc->Field.BitLength));
|
||||
|
||||
*RetBufferDesc = BufferDesc;
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
|
||||
"FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n",
|
||||
@ -393,6 +421,7 @@ AcpiExWriteDataToField (
|
||||
{
|
||||
ACPI_STATUS Status;
|
||||
UINT32 BufferLength;
|
||||
UINT32 DataLength;
|
||||
void *Buffer;
|
||||
|
||||
|
||||
@ -439,6 +468,39 @@ AcpiExWriteDataToField (
|
||||
Status = AcpiExWriteSerialBus (SourceDesc, ObjDesc, ResultDesc);
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
else if ((ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
|
||||
(ObjDesc->Field.RegionObj->Region.SpaceId == ACPI_ADR_SPACE_PLATFORM_COMM))
|
||||
{
|
||||
/*
|
||||
* According to the spec a write to the COMD field will invoke the
|
||||
* region handler. Otherwise, write to the PccInternal buffer. This
|
||||
* implementation will use the offsets specified rather than the name
|
||||
* of the field. This is considered safer because some firmware tools
|
||||
* are known to obfiscate named objects.
|
||||
*/
|
||||
DataLength = (ACPI_SIZE) ACPI_ROUND_BITS_UP_TO_BYTES (
|
||||
ObjDesc->Field.BitLength);
|
||||
memcpy (ObjDesc->Field.RegionObj->Field.InternalPccBuffer +
|
||||
ObjDesc->Field.BaseByteOffset,
|
||||
SourceDesc->Buffer.Pointer, DataLength);
|
||||
|
||||
if ((ObjDesc->Field.RegionObj->Region.Address == PCC_MASTER_SUBSPACE &&
|
||||
MASTER_SUBSPACE_COMMAND (ObjDesc->Field.BaseByteOffset)) ||
|
||||
GENERIC_SUBSPACE_COMMAND (ObjDesc->Field.BaseByteOffset))
|
||||
{
|
||||
/* Perform the write */
|
||||
|
||||
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
|
||||
"PCC COMD field has been written. Invoking PCC handler now.\n"));
|
||||
|
||||
Status = AcpiExAccessRegion (
|
||||
ObjDesc, 0, (UINT64 *) ObjDesc->Field.RegionObj->Field.InternalPccBuffer,
|
||||
ACPI_WRITE);
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
return (AE_OK);
|
||||
}
|
||||
|
||||
|
||||
/* Get a pointer to the data to be written */
|
||||
|
||||
|
@ -165,7 +165,7 @@
|
||||
* FUNCTION: AcpiExReadGpio
|
||||
*
|
||||
* PARAMETERS: ObjDesc - The named field to read
|
||||
* Buffer - Where the return data is returnd
|
||||
* Buffer - Where the return data is returned
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user