Merge svn+ssh://svn.freebsd.org/base/head@206571

This commit is contained in:
Marcel Moolenaar 2010-04-13 23:54:40 +00:00
commit e936c9680d
316 changed files with 26191 additions and 15997 deletions

View file

@ -668,7 +668,8 @@ ld_fs: movw %ax,%fs
movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx
wrmsr
.globl ld_fsbase
ld_fsbase: wrmsr
1:
/* Restore %gs and gsbase */
movw TF_GS(%rsp),%si
@ -685,7 +686,8 @@ ld_gs: movw %si,%gs
movl $MSR_KGSBASE,%ecx
movl PCB_GSBASE(%r8),%eax
movl PCB_GSBASE+4(%r8),%edx
wrmsr
.globl ld_gsbase
ld_gsbase: wrmsr
1: .globl ld_es
ld_es: movw TF_ES(%rsp),%es
.globl ld_ds
@ -798,6 +800,30 @@ gs_load_fault:
call trap
movw $KUG32SEL,TF_GS(%rsp)
jmp doreti
ALIGN_TEXT
.globl fsbase_load_fault
fsbase_load_fault:
movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi
call trap
movq PCPU(CURTHREAD),%r8
movq TD_PCB(%r8),%r8
movq $0,PCB_FSBASE(%r8)
jmp doreti
ALIGN_TEXT
.globl gsbase_load_fault
gsbase_load_fault:
popfq
movl $T_PROTFLT,TF_TRAPNO(%rsp)
movq %rsp, %rdi
call trap
movq PCPU(CURTHREAD),%r8
movq TD_PCB(%r8),%r8
movq $0,PCB_GSBASE(%r8)
jmp doreti
#ifdef HWPMC_HOOKS
ENTRY(end_exceptions)
#endif

View file

@ -424,13 +424,14 @@ sigreturn(td, uap)
error = copyin(uap->sigcntxp, &uc, sizeof(uc));
if (error != 0) {
printf("sigreturn (pid %d): copyin failed\n", p->p_pid);
uprintf("pid %d (%s): sigreturn copyin failed\n",
p->p_pid, td->td_name);
return (error);
}
ucp = &uc;
if ((ucp->uc_mcontext.mc_flags & ~_MC_FLAG_MASK) != 0) {
printf("sigreturn (pid %d): mc_flags %x\n", p->p_pid,
ucp->uc_mcontext.mc_flags);
uprintf("pid %d (%s): sigreturn mc_flags %x\n", p->p_pid,
td->td_name, ucp->uc_mcontext.mc_flags);
return (EINVAL);
}
regs = td->td_frame;
@ -449,8 +450,8 @@ sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(rflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
printf("sigreturn (pid %d): rflags = 0x%lx\n", p->p_pid,
rflags);
uprintf("pid %d (%s): sigreturn rflags = 0x%lx\n", p->p_pid,
td->td_name, rflags);
return (EINVAL);
}
@ -461,7 +462,8 @@ sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("sigreturn (pid %d): cs = 0x%x\n", p->p_pid, cs);
uprintf("pid %d (%s): sigreturn cs = 0x%x\n", p->p_pid,
td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@ -473,7 +475,8 @@ sigreturn(td, uap)
ret = set_fpcontext(td, &ucp->uc_mcontext);
if (ret != 0) {
printf("sigreturn (pid %d): set_fpcontext\n", p->p_pid);
uprintf("pid %d (%s): sigreturn set_fpcontext err %d\n",
p->p_pid, td->td_name, ret);
return (ret);
}
bcopy(&ucp->uc_mcontext.mc_rdi, regs, sizeof(*regs));

View file

@ -303,7 +303,7 @@ trap(struct trapframe *frame)
* enabled later.
*/
if (ISPL(frame->tf_cs) == SEL_UPL)
printf(
uprintf(
"pid %ld (%s): trap %d with interrupts disabled\n",
(long)curproc->p_pid, curthread->td_name, type);
else if (type != T_NMI && type != T_BPTFLT &&
@ -566,6 +566,14 @@ trap(struct trapframe *frame)
frame->tf_gs = _ugssel;
goto out;
}
if (frame->tf_rip == (long)ld_gsbase) {
frame->tf_rip = (long)gsbase_load_fault;
goto out;
}
if (frame->tf_rip == (long)ld_fsbase) {
frame->tf_rip = (long)fsbase_load_fault;
goto out;
}
if (PCPU_GET(curpcb)->pcb_onfault != NULL) {
frame->tf_rip =
(long)PCPU_GET(curpcb)->pcb_onfault;

View file

@ -565,7 +565,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
printf("freebsd4_freebsd32_sigreturn: eflags = 0x%x\n", eflags);
uprintf("pid %d (%s): freebsd4_freebsd32_sigreturn eflags = 0x%x\n",
td->td_proc->p_pid, td->td_name, eflags);
return (EINVAL);
}
@ -576,7 +577,8 @@ freebsd4_freebsd32_sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("freebsd4_sigreturn: cs = 0x%x\n", cs);
uprintf("pid %d (%s): freebsd4_sigreturn cs = 0x%x\n",
td->td_proc->p_pid, td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;
@ -647,7 +649,8 @@ freebsd32_sigreturn(td, uap)
* one less debugger trap, so allowing it is fairly harmless.
*/
if (!EFL_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF)) {
printf("freebsd32_sigreturn: eflags = 0x%x\n", eflags);
uprintf("pid %d (%s): freebsd32_sigreturn eflags = 0x%x\n",
td->td_proc->p_pid, td->td_name, eflags);
return (EINVAL);
}
@ -658,7 +661,8 @@ freebsd32_sigreturn(td, uap)
*/
cs = ucp->uc_mcontext.mc_cs;
if (!CS_SECURE(cs)) {
printf("sigreturn: cs = 0x%x\n", cs);
uprintf("pid %d (%s): sigreturn cs = 0x%x\n",
td->td_proc->p_pid, td->td_name, cs);
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGBUS;
ksi.ksi_code = BUS_OBJERR;

View file

@ -83,10 +83,14 @@ void ld_ds(void) __asm(__STRING(ld_ds));
void ld_es(void) __asm(__STRING(ld_es));
void ld_fs(void) __asm(__STRING(ld_fs));
void ld_gs(void) __asm(__STRING(ld_gs));
void ld_fsbase(void) __asm(__STRING(ld_fsbase));
void ld_gsbase(void) __asm(__STRING(ld_gsbase));
void ds_load_fault(void) __asm(__STRING(ds_load_fault));
void es_load_fault(void) __asm(__STRING(es_load_fault));
void fs_load_fault(void) __asm(__STRING(fs_load_fault));
void gs_load_fault(void) __asm(__STRING(gs_load_fault));
void fsbase_load_fault(void) __asm(__STRING(fsbase_load_fault));
void gsbase_load_fault(void) __asm(__STRING(gsbase_load_fault));
void dump_add_page(vm_paddr_t);
void dump_drop_page(vm_paddr_t);
void initializecpu(void);

View file

@ -43,17 +43,20 @@ struct pmc_mdep;
#include <dev/hwpmc/hwpmc_core.h>
#include <dev/hwpmc/hwpmc_piv.h>
#include <dev/hwpmc/hwpmc_tsc.h>
#include <dev/hwpmc/hwpmc_uncore.h>
/*
* Intel processors implementing V2 and later of the Intel performance
* measurement architecture have PMCs of the following classes: TSC,
* IAF and IAP.
* IAF, IAP, UCF and UCP.
*/
#define PMC_MDEP_CLASS_INDEX_TSC 0
#define PMC_MDEP_CLASS_INDEX_K8 1
#define PMC_MDEP_CLASS_INDEX_P4 1
#define PMC_MDEP_CLASS_INDEX_IAP 1
#define PMC_MDEP_CLASS_INDEX_IAF 2
#define PMC_MDEP_CLASS_INDEX_UCP 3
#define PMC_MDEP_CLASS_INDEX_UCF 4
/*
* On the amd64 platform we support the following PMCs.
@ -63,12 +66,16 @@ struct pmc_mdep;
* PIV Intel P4/HTT and P4/EMT64
* IAP Intel Core/Core2/Atom CPUs in 64 bits mode.
* IAF Intel fixed-function PMCs in Core2 and later CPUs.
* UCP Intel Uncore programmable PMCs.
* UCF Intel Uncore fixed-function PMCs.
*/
union pmc_md_op_pmcallocate {
struct pmc_md_amd_op_pmcallocate pm_amd;
struct pmc_md_iaf_op_pmcallocate pm_iaf;
struct pmc_md_iap_op_pmcallocate pm_iap;
struct pmc_md_ucf_op_pmcallocate pm_ucf;
struct pmc_md_ucp_op_pmcallocate pm_ucp;
struct pmc_md_p4_op_pmcallocate pm_p4;
uint64_t __pad[4];
};
@ -83,6 +90,8 @@ union pmc_md_pmc {
struct pmc_md_amd_pmc pm_amd;
struct pmc_md_iaf_pmc pm_iaf;
struct pmc_md_iap_pmc pm_iap;
struct pmc_md_ucf_pmc pm_ucf;
struct pmc_md_ucp_pmc pm_ucp;
struct pmc_md_p4_pmc pm_p4;
};

View file

@ -721,6 +721,8 @@ bs_c_8_proto(f);
#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
#define BUS_SPACE_MAXSIZE 0xFFFFFFFF
#define BUS_SPACE_UNRESTRICTED (~0)
#include <machine/bus_dma.h>
#endif /* _MACHINE_BUS_H_ */

View file

@ -0,0 +1,69 @@
# $FreeBSD$
NO_MAN=
WITHOUT_SSP=
BUILDING_EFI=
.include <bsd.own.mk>
PROG= loader.sym
INTERNALPROG=
# architecture-specific loader code
SRCS= main.c exec.c conf.c vers.c reloc.c start.S elf32_freebsd.c
SRCS+= i386_copy.c bootinfo.c autoload.c devicename.c efimd.c
CFLAGS+= -I${.CURDIR}/../../efi/include
CFLAGS+= -I${.CURDIR}/../../efi/include/i386
.if ${MK_FORTH} != "no"
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH
CFLAGS+= -I${.CURDIR}/../../ficl
CFLAGS+= -I${.CURDIR}/../../ficl/i386
LIBFICL= ${.OBJDIR}/../../ficl/libficl.a
.endif
# Include bcache code.
HAVE_BCACHE= yes
# Always add MI sources
.PATH: ${.CURDIR}/../../common
.include "${.CURDIR}/../../common/Makefile.inc"
CFLAGS+= -I${.CURDIR}/../../common
FILES= loader.efi
FILESMODE_loader.efi= ${BINMODE}
LDSCRIPT= ${.CURDIR}/ldscript.${MACHINE_ARCH}
LDFLAGS= -Wl,-T${LDSCRIPT} -shared -symbolic
${PROG}: ${LDSCRIPT}
CLEANFILES= vers.c loader.efi
NEWVERSWHAT= "EFI loader" ${MACHINE_ARCH}
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
OBJCOPY?= objcopy
OBJDUMP?= objdump
loader.efi: loader.sym
if [ `${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*' | wc -l` != 0 ]; then \
${OBJDUMP} -t ${.ALLSRC} | fgrep '*UND*'; \
exit 1; \
fi
${OBJCOPY} -j .data -j .dynamic -j .dynstr -j .dynsym -j .hash \
-j .rel.dyn -j .reloc -j .sdata -j .text -j set_Xcommand_set \
--target=efi-app-ia32 ${.ALLSRC} ${.TARGET}
LIBEFI= ${.OBJDIR}/../../efi/libefi/libefi.a
CFLAGS+= -I${.CURDIR}/../libi386
CFLAGS+= -I${.CURDIR}/../btx/lib
DPADD= ${LIBFICL} ${LIBEFI} ${LIBSTAND}
LDADD= ${LIBFICL} ${LIBEFI} -lstand
.include <bsd.prog.mk>

View file

@ -0,0 +1,35 @@
/*-
* Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* 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 ``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 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$");
int
i386_autoload(void)
{
return (0);
}

View file

@ -0,0 +1,297 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* 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 <stand.h>
#include <string.h>
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/linker.h>
#include <efi.h>
#include <efilib.h>
#include "bootstrap.h"
#include "libi386.h"
#include <machine/bootinfo.h>
/*
* Return a 'boothowto' value corresponding to the kernel arguments in
* (kargs) and any relevant environment variables.
*/
static struct
{
const char *ev;
int mask;
} howto_names[] = {
{ "boot_askname", RB_ASKNAME},
{ "boot_cdrom", RB_CDROM},
{ "boot_ddb", RB_KDB},
{ "boot_dfltroot", RB_DFLTROOT},
{ "boot_gdb", RB_GDB},
{ "boot_multicons", RB_MULTIPLE},
{ "boot_mute", RB_MUTE},
{ "boot_pause", RB_PAUSE},
{ "boot_serial", RB_SERIAL},
{ "boot_single", RB_SINGLE},
{ "boot_verbose", RB_VERBOSE},
{ NULL, 0}
};
static const char howto_switches[] = "aCdrgDmphsv";
static int howto_masks[] = {
RB_ASKNAME, RB_CDROM, RB_KDB, RB_DFLTROOT, RB_GDB, RB_MULTIPLE,
RB_MUTE, RB_PAUSE, RB_SERIAL, RB_SINGLE, RB_VERBOSE
};
int
bi_getboothowto(char *kargs)
{
const char *sw;
char *opts;
int howto, i;
howto = 0;
/* Get the boot options from the environment first. */
for (i = 0; howto_names[i].ev != NULL; i++) {
if (getenv(howto_names[i].ev) != NULL)
howto |= howto_names[i].mask;
}
/* Parse kargs */
if (kargs == NULL)
return (howto);
opts = strchr(kargs, '-');
while (opts != NULL) {
while (*(++opts) != '\0') {
sw = strchr(howto_switches, *opts);
if (sw == NULL)
break;
howto |= howto_masks[sw - howto_switches];
}
opts = strchr(opts, '-');
}
return (howto);
}
/*
* Copy the environment into the load area starting at (addr).
* Each variable is formatted as <name>=<value>, with a single nul
* separating each variable, and a double nul terminating the environment.
*/
vm_offset_t
bi_copyenv(vm_offset_t start)
{
struct env_var *ep;
vm_offset_t addr, last;
size_t len;
addr = last = start;
/* Traverse the environment. */
for (ep = environ; ep != NULL; ep = ep->ev_next) {
len = strlen(ep->ev_name);
if (i386_copyin(ep->ev_name, addr, len) != len)
break;
addr += len;
if (i386_copyin("=", addr, 1) != 1)
break;
addr++;
if (ep->ev_value != NULL) {
len = strlen(ep->ev_value);
if (i386_copyin(ep->ev_value, addr, len) != len)
break;
addr += len;
}
if (i386_copyin("", addr, 1) != 1)
break;
last = ++addr;
}
if (i386_copyin("", last++, 1) != 1)
last = start;
return(last);
}
/*
* Copy module-related data into the load area, where it can be
* used as a directory for loaded modules.
*
* Module data is presented in a self-describing format. Each datum
* is preceded by a 32-bit identifier and a 32-bit size field.
*
* Currently, the following data are saved:
*
* MOD_NAME (variable) module name (string)
* MOD_TYPE (variable) module type (string)
* MOD_ARGS (variable) module parameters (string)
* MOD_ADDR sizeof(vm_offset_t) module load address
* MOD_SIZE sizeof(size_t) module size
* MOD_METADATA (variable) type-specific metadata
*/
#define COPY32(v, a) { \
u_int32_t x = (v); \
i386_copyin(&x, a, sizeof(x)); \
a += sizeof(x); \
}
#define MOD_STR(t, a, s) { \
COPY32(t, a); \
COPY32(strlen(s) + 1, a); \
i386_copyin(s, a, strlen(s) + 1); \
a += roundup(strlen(s) + 1, sizeof(u_int64_t));\
}
#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s)
#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s)
#define MOD_ARGS(a, s) MOD_STR(MODINFO_ARGS, a, s)
#define MOD_VAR(t, a, s) { \
COPY32(t, a); \
COPY32(sizeof(s), a); \
i386_copyin(&s, a, sizeof(s)); \
a += roundup(sizeof(s), sizeof(u_int64_t)); \
}
#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s)
#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s)
#define MOD_METADATA(a, mm) { \
COPY32(MODINFO_METADATA | mm->md_type, a); \
COPY32(mm->md_size, a); \
i386_copyin(mm->md_data, a, mm->md_size); \
a += roundup(mm->md_size, sizeof(u_int64_t));\
}
#define MOD_END(a) { \
COPY32(MODINFO_END, a); \
COPY32(0, a); \
}
vm_offset_t
bi_copymodules(vm_offset_t addr)
{
struct preloaded_file *fp;
struct file_metadata *md;
/* Start with the first module on the list, should be the kernel. */
for (fp = file_findfile(NULL, NULL); fp != NULL; fp = fp->f_next) {
/* The name field must come first. */
MOD_NAME(addr, fp->f_name);
MOD_TYPE(addr, fp->f_type);
if (fp->f_args)
MOD_ARGS(addr, fp->f_args);
MOD_ADDR(addr, fp->f_addr);
MOD_SIZE(addr, fp->f_size);
for (md = fp->f_metadata; md != NULL; md = md->md_next) {
if (!(md->md_type & MODINFOMD_NOCOPY))
MOD_METADATA(addr, md);
}
}
MOD_END(addr);
return(addr);
}
/*
* Load the information expected by the kernel.
*
* - The kernel environment is copied into kernel space.
* - Module metadata are formatted and placed in kernel space.
*/
int
bi_load(struct preloaded_file *fp, uint64_t *bi_addr)
{
struct bootinfo bi;
struct preloaded_file *xp;
struct file_metadata *md;
struct devdesc *rootdev;
char *rootdevname;
vm_offset_t addr, ssym, esym;
bzero(&bi, sizeof(struct bootinfo));
bi.bi_version = 1;
// bi.bi_boothowto = bi_getboothowto(fp->f_args);
/*
* Allow the environment variable 'rootdev' to override the supplied
* device. This should perhaps go to MI code and/or have $rootdev
* tested/set by MI code before launching the kernel.
*/
rootdevname = getenv("rootdev");
i386_getdev((void**)&rootdev, rootdevname, NULL);
if (rootdev != NULL) {
/* Try reading /etc/fstab to select the root device. */
getrootmount(i386_fmtdev(rootdev));
free(rootdev);
}
md = file_findmetadata(fp, MODINFOMD_SSYM);
ssym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
md = file_findmetadata(fp, MODINFOMD_ESYM);
esym = (md != NULL) ? *((vm_offset_t *)&(md->md_data)) : 0;
if (ssym != 0 && esym != 0) {
bi.bi_symtab = ssym;
bi.bi_esymtab = esym;
}
/* Find the last module in the chain. */
addr = 0;
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
if (addr < (xp->f_addr + xp->f_size))
addr = xp->f_addr + xp->f_size;
}
addr = (addr + 15) & ~15;
/* Copy module list and metadata. */
bi.bi_modulep = addr;
addr = bi_copymodules(addr);
if (addr <= bi.bi_modulep) {
addr = bi.bi_modulep;
bi.bi_modulep = 0;
}
addr = (addr + 15) & ~15;
/* Copy our environment. */
bi.bi_envp = addr;
addr = bi_copyenv(addr);
if (addr <= bi.bi_envp) {
addr = bi.bi_envp;
bi.bi_envp = 0;
}
addr = (addr + PAGE_MASK) & ~PAGE_MASK;
bi.bi_kernend = addr;
return (ldr_bootinfo(&bi, bi_addr));
}

77
sys/boot/i386/efi/conf.c Normal file
View file

@ -0,0 +1,77 @@
/*-
* Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* 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 ``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 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 <stand.h>
#include <bootstrap.h>
#include <efi.h>
#include <efilib.h>
struct devsw *devsw[] = {
&efipart_dev,
&efinet_dev,
NULL
};
struct fs_ops *file_system[] = {
&dosfs_fsops,
&ufs_fsops,
&cd9660_fsops,
&nfs_fsops,
&gzipfs_fsops,
NULL
};
struct netif_driver *netif_drivers[] = {
&efinetif,
NULL
};
#ifdef notyet
extern struct file_format amd64_elf;
extern struct file_format amd64_elf_obj;
#endif
extern struct file_format i386_elf;
extern struct file_format i386_elf_obj;
struct file_format *file_formats[] = {
#ifdef notyet
&amd64_elf,
&amd64_elf_obj,
#endif
&i386_elf,
&i386_elf_obj,
NULL
};
extern struct console efi_console;
struct console *consoles[] = {
&efi_console,
NULL
};

View file

@ -0,0 +1,169 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* 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 <stand.h>
#include <string.h>
#include <sys/disklabel.h>
#include "bootstrap.h"
#include <efi.h>
#include <efilib.h>
static int i386_parsedev(struct devdesc **, const char *, const char **);
/*
* Point (dev) at an allocated device specifier for the device matching the
* path in (devspec). If it contains an explicit device specification,
* use that. If not, use the default device.
*/
int
i386_getdev(void **vdev, const char *devspec, const char **path)
{
struct devdesc **dev = (struct devdesc **)vdev;
int rv;
/*
* If it looks like this is just a path and no device, then
* use the current device instead.
*/
if (devspec == NULL || *devspec == '/' || !strchr(devspec, ':')) {
rv = i386_parsedev(dev, getenv("currdev"), NULL);
if (rv == 0 && path != NULL)
*path = devspec;
return (rv);
}
/* Parse the device name off the beginning of the devspec. */
return (i386_parsedev(dev, devspec, path));
}
/*
* Point (dev) at an allocated device specifier matching the string version
* at the beginning of (devspec). Return a pointer to the remaining
* text in (path).
*
* In all cases, the beginning of (devspec) is compared to the names
* of known devices in the device switch, and then any following text
* is parsed according to the rules applied to the device type.
*
* For disk-type devices, the syntax is:
*
* fs<unit>:
*/
static int
i386_parsedev(struct devdesc **dev, const char *devspec, const char **path)
{
struct devdesc *idev;
struct devsw *dv;
char *cp;
const char *np;
int i, err;
/* minimum length check */
if (strlen(devspec) < 2)
return (EINVAL);
/* look for a device that matches */
for (i = 0; devsw[i] != NULL; i++) {
dv = devsw[i];
if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
break;
}
if (devsw[i] == NULL)
return (ENOENT);
idev = malloc(sizeof(struct devdesc));
if (idev == NULL)
return (ENOMEM);
idev->d_dev = dv;
idev->d_type = dv->dv_type;
idev->d_unit = -1;
err = 0;
np = devspec + strlen(dv->dv_name);
if (*np != '\0' && *np != ':') {
idev->d_unit = strtol(np, &cp, 0);
if (cp == np) {
idev->d_unit = -1;
free(idev);
return (EUNIT);
}
}
if (*cp != '\0' && *cp != ':') {
free(idev);
return (EINVAL);
}
if (path != NULL)
*path = (*cp == 0) ? cp : cp + 1;
if (dev != NULL)
*dev = idev;
else
free(idev);
return (0);
}
char *
i386_fmtdev(void *vdev)
{
struct devdesc *dev = (struct devdesc *)vdev;
static char buf[32]; /* XXX device length constant? */
switch(dev->d_type) {
case DEVT_NONE:
strcpy(buf, "(no device)");
break;
default:
sprintf(buf, "%s%d:", dev->d_dev->dv_name, dev->d_unit);
break;
}
return(buf);
}
/*
* Set currdev to suit the value being supplied in (value)
*/
int
i386_setcurrdev(struct env_var *ev, int flags, const void *value)
{
struct devdesc *ncurr;
int rv;
rv = i386_parsedev(&ncurr, value, NULL);
if (rv != 0)
return(rv);
free(ncurr);
env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
return (0);
}

139
sys/boot/i386/efi/efimd.c Normal file
View file

@ -0,0 +1,139 @@
/*-
* Copyright (c) 2004, 2006 Marcel Moolenaar
* All rights reserved.
*
* 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 ``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 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 <stand.h>
#include <efi.h>
#include <efilib.h>
#include <libi386.h>
#include <machine/bootinfo.h>
#define EFI_INTEL_FPSWA \
{0xc41b6531,0x97b9,0x11d3,{0x9a,0x29,0x00,0x90,0x27,0x3f,0xc1,0x4d}}
static EFI_GUID fpswa_guid = EFI_INTEL_FPSWA;
/* DIG64 Headless Console & Debug Port Table. */
#define HCDP_TABLE_GUID \
{0xf951938d,0x620b,0x42ef,{0x82,0x79,0xa8,0x4b,0x79,0x61,0x78,0x98}}
static EFI_GUID hcdp_guid = HCDP_TABLE_GUID;
static UINTN mapkey;
uint64_t
ldr_alloc(vm_offset_t va)
{
return (0);
}
int
ldr_bootinfo(struct bootinfo *bi, uint64_t *bi_addr)
{
VOID *fpswa;
EFI_MEMORY_DESCRIPTOR *mm;
EFI_PHYSICAL_ADDRESS addr;
EFI_HANDLE handle;
EFI_STATUS status;
size_t bisz;
UINTN mmsz, pages, sz;
UINT32 mmver;
bi->bi_systab = (uint64_t)ST;
bi->bi_hcdp = (uint64_t)efi_get_table(&hcdp_guid);
sz = sizeof(EFI_HANDLE);
status = BS->LocateHandle(ByProtocol, &fpswa_guid, 0, &sz, &handle);
if (status == 0)
status = BS->HandleProtocol(handle, &fpswa_guid, &fpswa);
bi->bi_fpswa = (status == 0) ? (uint64_t)fpswa : 0;
bisz = (sizeof(struct bootinfo) + 0x0f) & ~0x0f;
/*
* Allocate enough pages to hold the bootinfo block and the memory
* map EFI will return to us. The memory map has an unknown size,
* so we have to determine that first. Note that the AllocatePages
* call can itself modify the memory map, so we have to take that
* into account as well. The changes to the memory map are caused
* by splitting a range of free memory into two (AFAICT), so that
* one is marked as being loader data.
*/
sz = 0;
BS->GetMemoryMap(&sz, NULL, &mapkey, &mmsz, &mmver);
sz += mmsz;
sz = (sz + 15) & ~15;
pages = EFI_SIZE_TO_PAGES(sz + bisz);
status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, pages,
&addr);
if (EFI_ERROR(status)) {
printf("%s: AllocatePages() returned 0x%lx\n", __func__,
(long)status);
return (ENOMEM);
}
/*
* Read the memory map and stash it after bootinfo. Align the
* memory map on a 16-byte boundary (the bootinfo block is page
* aligned).
*/
*bi_addr = addr;
mm = (void *)(addr + bisz);
sz = (EFI_PAGE_SIZE * pages) - bisz;
status = BS->GetMemoryMap(&sz, mm, &mapkey, &mmsz, &mmver);
if (EFI_ERROR(status)) {
printf("%s: GetMemoryMap() returned 0x%lx\n", __func__,
(long)status);
return (EINVAL);
}
bi->bi_memmap = (uint64_t)mm;
bi->bi_memmap_size = sz;
bi->bi_memdesc_size = mmsz;
bi->bi_memdesc_version = mmver;
bcopy(bi, (void *)(*bi_addr), sizeof(*bi));
return (0);
}
int
ldr_enter(const char *kernel)
{
EFI_STATUS status;
status = BS->ExitBootServices(IH, mapkey);
if (EFI_ERROR(status)) {
printf("%s: ExitBootServices() returned 0x%lx\n", __func__,
(long)status);
return (EINVAL);
}
return (0);
}

View file

@ -0,0 +1,87 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* 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 <sys/exec.h>
#include <sys/linker.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <machine/elf.h>
#include <stand.h>
#include "bootstrap.h"
#include "../libi386/libi386.h"
#include "../btx/lib/btxv86.h"
extern void __exec(caddr_t addr, ...);
static int elf32_exec(struct preloaded_file *amp);
static int elf32_obj_exec(struct preloaded_file *amp);
struct file_format i386_elf = { elf32_loadfile, elf32_exec };
struct file_format i386_elf_obj = { elf32_obj_loadfile, elf32_obj_exec };
/*
* There is an ELF kernel and one or more ELF modules loaded.
* We wish to start executing the kernel image, so make such
* preparations as are required, and do so.
*/
static int
elf32_exec(struct preloaded_file *fp)
{
struct file_metadata *md;
Elf_Ehdr *ehdr;
vm_offset_t entry, bootinfop, modulep, kernend;
int boothowto, err, bootdev;
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE);
ehdr = (Elf_Ehdr *)&(md->md_data);
err = bi_load(fp->f_args, &boothowto, &bootdev, &bootinfop, &modulep, &kernend);
if (err != 0)
return(err);
entry = ehdr->e_entry & 0xffffff;
printf("Start @ 0x%lx ...\n", entry);
ldr_enter(fp->f_name);
dev_cleanup();
__exec((void *)entry, boothowto, bootdev, 0, 0, 0, bootinfop, modulep, kernend);
panic("exec returned");
}
static int
elf32_obj_exec(struct preloaded_file *fp)
{
return (EFTYPE);
}

59
sys/boot/i386/efi/exec.c Normal file
View file

@ -0,0 +1,59 @@
/*-
* Copyright (c) 2010 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* 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 ``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 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 <stand.h>
#include <machine/elf.h>
#include "../btx/lib/btxv86.h"
#include "../../common/bootstrap.h"
uint32_t __base;
struct __v86 __v86;
void
__v86int()
{
printf("%s\n", __func__);
exit(1);
}
void
__exec(caddr_t addr, ...)
{
/* XXX this is wrong */
__asm __volatile("movl %cr0, %eax");
__asm __volatile("andl $0x7fffffff, %eax");
__asm __volatile("mov %eax, %cr0");
__asm __volatile("xorl %eax, %eax");
__asm __volatile("mov %eax, %cr3");
__asm __volatile("movl %cr0, %eax");
__asm __volatile("andl $0xfffffffe, %eax");
__asm __volatile("movl %eax, %cr0");
__asm __volatile("jmp %0" :: "r" (addr));
}

View file

@ -0,0 +1,59 @@
/*-
* Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
* 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$");
/*
* MD primitives supporting placement of module data
*
* XXX should check load address/size against memory top.
*/
#include <stand.h>
#include "libi386.h"
#include "btxv86.h"
ssize_t
i386_copyin(const void *src, vm_offset_t dest, const size_t len)
{
bcopy(src, PTOV(dest), len);
return(len);
}
ssize_t
i386_copyout(const vm_offset_t src, void *dest, const size_t len)
{
bcopy(PTOV(src), dest, len);
return(len);
}
ssize_t
i386_readin(const int fd, vm_offset_t dest, const size_t len)
{
return (read(fd, PTOV(dest), len));
}

View file

@ -0,0 +1,75 @@
/* $FreeBSD$ */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0;
ImageBase = .;
. = SIZEOF_HEADERS;
. = ALIGN(4096);
.eh_frame : {
*(.eh_frame)
}
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.plt)
} =0x00300000010070000002000001000400
. = ALIGN(4096);
.data : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
*(.opd)
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
*(.plabel)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
}
. = ALIGN(4096);
set_Xcommand_set : {
__start_set_Xcommand_set = .;
*(set_Xcommand_set)
__stop_set_Xcommand_set = .;
}
. = ALIGN(4096);
__gp = .;
.sdata : {
*(.got.plt .got)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
. = ALIGN(4096);
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
.rel.dyn : {
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.got)
*(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
*(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
*(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
*(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
*(.rel.plt)
*(.relset_*)
*(.rel.dyn .rel.dyn.*)
}
. = ALIGN(4096);
.reloc : { *(.reloc) }
. = ALIGN(4096);
.hash : { *(.hash) }
. = ALIGN(4096);
.dynsym : { *(.dynsym) }
. = ALIGN(4096);
.dynstr : { *(.dynstr) }
}

View file

@ -0,0 +1,72 @@
/* $FreeBSD$ */
OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0;
ImageBase = .;
. = SIZEOF_HEADERS;
. = ALIGN(4096);
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.plt)
} =0x00300000010070000002000001000400
. = ALIGN(4096);
.data : {
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
*(.sbss2 .sbss2.* .gnu.linkonce.sb2.*)
*(.opd)
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
*(.plabel)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
}
. = ALIGN(4096);
set_Xcommand_set : {
__start_set_Xcommand_set = .;
*(set_Xcommand_set)
__stop_set_Xcommand_set = .;
}
. = ALIGN(4096);
__gp = .;
.sdata : {
*(.got.plt .got)
*(.sdata .sdata.* .gnu.linkonce.s.*)
*(dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
. = ALIGN(4096);
.dynamic : { *(.dynamic) }
. = ALIGN(4096);
.rel.dyn : {
*(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
*(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
*(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
*(.rel.got)
*(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*)
*(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*)
*(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*)
*(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*)
*(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
*(.rel.plt)
*(.relset_*)
*(.rel.dyn .rel.dyn.*)
}
. = ALIGN(4096);
.reloc : { *(.reloc) }
. = ALIGN(4096);
.hash : { *(.hash) }
. = ALIGN(4096);
.dynsym : { *(.dynsym) }
. = ALIGN(4096);
.dynstr : { *(.dynstr) }
}

371
sys/boot/i386/efi/main.c Normal file
View file

@ -0,0 +1,371 @@
/*-
* Copyright (c) 2008-2010 Rui Paulo
* Copyright (c) 2006 Marcel Moolenaar
* All rights reserved.
*
* 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 ``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 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 <stand.h>
#include <string.h>
#include <setjmp.h>
#include <efi.h>
#include <efilib.h>
#include <bootstrap.h>
#include "../libi386/libi386.h"
extern char bootprog_name[];
extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
struct devdesc currdev; /* our current device */
struct arch_switch archsw; /* MI/MD interface boundary */
EFI_GUID acpi = ACPI_TABLE_GUID;
EFI_GUID acpi20 = ACPI_20_TABLE_GUID;
EFI_GUID devid = DEVICE_PATH_PROTOCOL;
EFI_GUID imgid = LOADED_IMAGE_PROTOCOL;
EFI_GUID mps = MPS_TABLE_GUID;
EFI_GUID netid = EFI_SIMPLE_NETWORK_PROTOCOL;
EFI_GUID smbios = SMBIOS_TABLE_GUID;
EFI_STATUS
main(int argc, CHAR16 *argv[])
{
char vendor[128];
EFI_LOADED_IMAGE *img;
int i;
/*
* XXX Chicken-and-egg problem; we want to have console output
* early, but some console attributes may depend on reading from
* eg. the boot device, which we can't do yet. We can use
* printf() etc. once this is done.
*/
cons_probe();
/*
* March through the device switch probing for things.
*/
for (i = 0; devsw[i] != NULL; i++)
if (devsw[i]->dv_init != NULL)
(devsw[i]->dv_init)();
/* Get our loaded image protocol interface structure. */
BS->HandleProtocol(IH, &imgid, (VOID**)&img);
printf("Image base: 0x%lx\n", (u_long)img->ImageBase);
printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16,
ST->Hdr.Revision & 0xffff);
printf("EFI Firmware: ");
/* printf doesn't understand EFI Unicode */
ST->ConOut->OutputString(ST->ConOut, ST->FirmwareVendor);
printf(" (rev %d.%02d)\n", ST->FirmwareRevision >> 16,
ST->FirmwareRevision & 0xffff);
printf("\n");
printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit);
currdev.d_type = currdev.d_dev->dv_type;
/*
* Disable the watchdog timer. By default the boot manager sets
* the timer to 5 minutes before invoking a boot option. If we
* want to return to the boot manager, we have to disable the
* watchdog timer and since we're an interactive program, we don't
* want to wait until the user types "quit". The timer may have
* fired by then. We don't care if this fails. It does not prevent
* normal functioning in any way...
*/
BS->SetWatchdogTimer(0, 0, 0, NULL);
env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&currdev),
i386_setcurrdev, env_nounset);
env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&currdev), env_noset,
env_nounset);
setenv("LINES", "24", 1); /* optional */
archsw.arch_autoload = i386_autoload;
archsw.arch_getdev = i386_getdev;
archsw.arch_copyin = i386_copyin;
archsw.arch_copyout = i386_copyout;
archsw.arch_readin = i386_readin;
interact(); /* doesn't return */
return (EFI_SUCCESS); /* keep compiler happy */
}
COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
static int
command_reboot(int argc, char *argv[])
{
int i;
for (i = 0; devsw[i] != NULL; ++i)
if (devsw[i]->dv_cleanup != NULL)
(devsw[i]->dv_cleanup)();
RS->ResetSystem(EfiResetCold, EFI_SUCCESS, 23,
(CHAR16 *)"Reboot from the loader");
/* NOTREACHED */
return (CMD_ERROR);
}
COMMAND_SET(quit, "quit", "exit the loader", command_quit);
static int
command_quit(int argc, char *argv[])
{
exit(0);
return (CMD_OK);
}
COMMAND_SET(memmap, "memmap", "print memory map", command_memmap);
static int
command_memmap(int argc, char *argv[])
{
UINTN sz;
EFI_MEMORY_DESCRIPTOR *map, *p;
UINTN key, dsz;
UINT32 dver;
EFI_STATUS status;
int i, ndesc;
static char *types[] = {
"Reserved",
"LoaderCode",
"LoaderData",
"BootServicesCode",
"BootServicesData",
"RuntimeServicesCode",
"RuntimeServicesData",
"ConventionalMemory",
"UnusableMemory",
"ACPIReclaimMemory",
"ACPIMemoryNVS",
"MemoryMappedIO",
"MemoryMappedIOPortSpace",
"PalCode"
};
sz = 0;
status = BS->GetMemoryMap(&sz, 0, &key, &dsz, &dver);
if (status != EFI_BUFFER_TOO_SMALL) {
printf("Can't determine memory map size\n");
return CMD_ERROR;
}
map = malloc(sz);
status = BS->GetMemoryMap(&sz, map, &key, &dsz, &dver);
if (EFI_ERROR(status)) {
printf("Can't read memory map\n");
return CMD_ERROR;
}
ndesc = sz / dsz;
printf("%23s %12s %12s %8s %4s\n",
"Type", "Physical", "Virtual", "#Pages", "Attr");
for (i = 0, p = map; i < ndesc;
i++, p = NextMemoryDescriptor(p, dsz)) {
printf("%23s %012lx %012lx %08lx ",
types[p->Type],
p->PhysicalStart,
p->VirtualStart,
p->NumberOfPages);
if (p->Attribute & EFI_MEMORY_UC)
printf("UC ");
if (p->Attribute & EFI_MEMORY_WC)
printf("WC ");
if (p->Attribute & EFI_MEMORY_WT)
printf("WT ");
if (p->Attribute & EFI_MEMORY_WB)
printf("WB ");
if (p->Attribute & EFI_MEMORY_UCE)
printf("UCE ");
if (p->Attribute & EFI_MEMORY_WP)
printf("WP ");
if (p->Attribute & EFI_MEMORY_RP)
printf("RP ");
if (p->Attribute & EFI_MEMORY_XP)
printf("XP ");
printf("\n");
}
return CMD_OK;
}
COMMAND_SET(configuration, "configuration",
"print configuration tables", command_configuration);
static const char *
guid_to_string(EFI_GUID *guid)
{
static char buf[40];
sprintf(buf, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid->Data1, guid->Data2, guid->Data3, guid->Data4[0],
guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4],
guid->Data4[5], guid->Data4[6], guid->Data4[7]);
return (buf);
}
static int
command_configuration(int argc, char *argv[])
{
int i;
printf("NumberOfTableEntries=%ld\n", ST->NumberOfTableEntries);
for (i = 0; i < ST->NumberOfTableEntries; i++) {
EFI_GUID *guid;
printf(" ");
guid = &ST->ConfigurationTable[i].VendorGuid;
if (!memcmp(guid, &mps, sizeof(EFI_GUID)))
printf("MPS Table");
else if (!memcmp(guid, &acpi, sizeof(EFI_GUID)))
printf("ACPI Table");
else if (!memcmp(guid, &acpi20, sizeof(EFI_GUID)))
printf("ACPI 2.0 Table");
else if (!memcmp(guid, &smbios, sizeof(EFI_GUID)))
printf("SMBIOS Table");
else
printf("Unknown Table (%s)", guid_to_string(guid));
printf(" at %p\n", ST->ConfigurationTable[i].VendorTable);
}
return CMD_OK;
}
COMMAND_SET(mode, "mode", "change or display text modes", command_mode);
static int
command_mode(int argc, char *argv[])
{
unsigned int cols, rows, mode;
int i;
char *cp;
char rowenv[8];
EFI_STATUS status;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
conout = ST->ConOut;
if (argc > 1) {
mode = strtol(argv[1], &cp, 0);
if (cp[0] != '\0') {
printf("Invalid mode\n");
return (CMD_ERROR);
}
status = conout->QueryMode(conout, mode, &cols, &rows);
if (EFI_ERROR(status)) {
printf("invalid mode %d\n", mode);
return (CMD_ERROR);
}
status = conout->SetMode(conout, mode);
if (EFI_ERROR(status)) {
printf("couldn't set mode %d\n", mode);
return (CMD_ERROR);
}
sprintf(rowenv, "%d", rows);
setenv("LINES", rowenv, 1);
return (CMD_OK);
}
for (i = 0; ; i++) {
status = conout->QueryMode(conout, i, &cols, &rows);
if (EFI_ERROR(status))
break;
printf("Mode %d: %d columns, %d rows\n", i, cols, rows);
}
if (i != 0)
printf("Choose the mode with \"col <mode number>\"\n");
return (CMD_OK);
}
COMMAND_SET(nvram, "nvram", "get or set NVRAM variables", command_nvram);
static int
command_nvram(int argc, char *argv[])
{
CHAR16 var[128];
CHAR16 *data;
EFI_STATUS status;
EFI_GUID varguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
unsigned int varsz;
unsigned int datasz;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
int i;
conout = ST->ConOut;
/* Initiate the search */
status = RS->GetNextVariableName(&varsz, NULL, NULL);
for (; status != EFI_NOT_FOUND; ) {
status = RS->GetNextVariableName(&varsz, var,
&varguid);
//if (EFI_ERROR(status))
//break;
conout->OutputString(conout, var);
printf("=");
datasz = 0;
status = RS->GetVariable(var, &varguid, NULL, &datasz,
NULL);
/* XXX: check status */
data = malloc(datasz);
status = RS->GetVariable(var, &varguid, NULL, &datasz,
data);
if (EFI_ERROR(status))
printf("<error retrieving variable>");
else {
for (i = 0; i < datasz; i++) {
if (isalnum(data[i]) || isspace(data[i]))
printf("%c", data[i]);
else
printf("\\x%02x", data[i]);
}
}
/* XXX */
pager_output("\n");
free(data);
}
return (CMD_OK);
}

103
sys/boot/i386/efi/reloc.c Normal file
View file

@ -0,0 +1,103 @@
/*-
* Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* 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/types.h>
#include <sys/elf32.h>
#include <efi.h>
/*
* XXX: we can't include sys/systm.h.
*/
#ifndef CTASSERT /* Allow lint to override */
#define CTASSERT(x) _CTASSERT(x, __LINE__)
#define _CTASSERT(x, y) __CTASSERT(x, y)
#define __CTASSERT(x, y) typedef char __assert ## y[(x) ? 1 : -1]
#endif
/*
* A simple relocator for IA32 EFI binaries.
*/
EFI_STATUS
_reloc(unsigned long ImageBase, Elf32_Dyn *dynamic, EFI_HANDLE image_handle,
EFI_SYSTEM_TABLE *system_table)
{
unsigned long relsz, relent;
unsigned long *newaddr;
Elf32_Rel *rel;
Elf32_Dyn *dynp;
/*
* Find the relocation address, its size and the relocation entry.
*/
relsz = 0;
relent = 0;
for (dynp = dynamic; dynp->d_tag != DT_NULL; dynp++) {
switch (dynp->d_tag) {
case DT_REL:
rel = (Elf32_Rel *) ((unsigned long) dynp->d_un.d_ptr +
ImageBase);
break;
case DT_RELSZ:
relsz = dynp->d_un.d_val;
break;
case DT_RELENT:
relent = dynp->d_un.d_val;
break;
default:
break;
}
}
/*
* Perform the actual relocation.
* XXX: We are reusing code for the amd64 version of this, but
* we must make sure the relocation types are the same.
*/
CTASSERT(R_386_NONE == R_X86_64_NONE);
CTASSERT(R_386_RELATIVE == R_X86_64_RELATIVE);
for (; relsz > 0; relsz -= relent) {
switch (ELF32_R_TYPE(rel->r_info)) {
case R_386_NONE:
/* No relocation needs be performed. */
break;
case R_386_RELATIVE:
/* Address relative to the base address. */
newaddr = (unsigned long *)(ImageBase + rel->r_offset);
*newaddr += ImageBase;
break;
default:
/* XXX: do we need other relocations ? */
return (EFI_LOAD_ERROR);
}
rel = (Elf32_Rel *) ((caddr_t) rel + relent);
}
return (EFI_SUCCESS);
}

70
sys/boot/i386/efi/start.S Normal file
View file

@ -0,0 +1,70 @@
/*-
* Copyright (c) 2008-2010 Rui Paulo <rpaulo@FreeBSD.org>
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
.text
#include <machine/asm.h>
#define EFI_SUCCESS 0
/*
* EFI entry point.
* _start(EFI_IMAGE image_handle, EFI_SYSTEM_TABLE *system_table);
*
* We calculate the base address along with _DYNAMIC, relocate us and finally
* pass control to efi_main.
*/
ENTRY(_start)
pushl %ebp
movl %esp, %ebp
pushl 12(%ebp) /* image_handle */
pushl 8(%ebp) /* system_table */
call 0f
0: popl %eax
movl %eax, %ebx
addl $ImageBase-0b, %eax
addl $_DYNAMIC-0b, %ebx
pushl %ebx /* dynamic */
pushl %eax /* ImageBase */
call _reloc
cmpl $EFI_SUCCESS, %eax
jne 1f
popl %ebx /* remove ImageBase from the stack */
popl %ebx /* remove dynamic from the stack */
call efi_main
1: leave
ret
END(_start)
.data
.section .reloc, "a"
.long 0
.long 10
.word 0

View file

@ -0,0 +1,7 @@
$FreeBSD$
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important. Make sure the current version number is on line 6.
1.1: Keep in sync with i386 version.
0.1: Initial i386 version. Derived from ia64.

View file

@ -997,6 +997,11 @@ dacleanup(struct cam_periph *periph)
xpt_print(periph->path, "can't remove sysctl context\n");
}
/*
* Nullify our periph pointer here to try and catch
* race conditions in callbacks/downcalls.
*/
softc->disk->d_drv1 = NULL;
disk_destroy(softc->disk);
callout_drain(&softc->sendordered_c);
free(softc, M_DEVBUF);

View file

@ -180,6 +180,7 @@ struct ia32_sigframe3 {
#endif
struct ksiginfo;
struct image_params;
extern char ia32_sigcode[];
extern char freebsd4_ia32_sigcode[];
extern int sz_ia32_sigcode;

View file

@ -110,12 +110,14 @@ __FBSDID("$FreeBSD$");
/*
* Various conversion macros
*/
#define T2J(x) (((x) * 100UL) / (stathz ? stathz : hz)) /* ticks to jiffies */
#define T2J(x) ((long)(((x) * 100ULL) / (stathz ? stathz : hz))) /* ticks to jiffies */
#define T2CS(x) ((unsigned long)(((x) * 100ULL) / (stathz ? stathz : hz))) /* ticks to centiseconds */
#define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */
#define B2K(x) ((x) >> 10) /* bytes to kbytes */
#define B2P(x) ((x) >> PAGE_SHIFT) /* bytes to pages */
#define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */
#define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */
#define TV2J(x) ((x)->tv_sec * 100UL + (x)->tv_usec / 10000)
/**
* @brief Mapping of ki_stat in struct kinfo_proc to the linux state
@ -505,9 +507,10 @@ linprocfs_douptime(PFS_FILL_ARGS)
getmicrouptime(&tv);
read_cpu_time(cp_time);
sbuf_printf(sb, "%lld.%02ld %ld.%02ld\n",
sbuf_printf(sb, "%lld.%02ld %ld.%02lu\n",
(long long)tv.tv_sec, tv.tv_usec / 10000,
T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100);
T2S(cp_time[CP_IDLE] / mp_ncpus),
T2CS(cp_time[CP_IDLE] / mp_ncpus) % 100);
return (0);
}
@ -613,9 +616,17 @@ linprocfs_doprocstat(PFS_FILL_ARGS)
struct kinfo_proc kp;
char state;
static int ratelimit = 0;
vm_offset_t startcode, startdata;
PROC_LOCK(p);
fill_kinfo_proc(p, &kp);
if (p->p_vmspace) {
startcode = (vm_offset_t)p->p_vmspace->vm_taddr;
startdata = (vm_offset_t)p->p_vmspace->vm_daddr;
} else {
startcode = 0;
startdata = 0;
};
sbuf_printf(sb, "%d", p->p_pid);
#define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg)
PS_ADD("comm", "(%s)", p->p_comm);
@ -634,30 +645,27 @@ linprocfs_doprocstat(PFS_FILL_ARGS)
PS_ADD("pgrp", "%d", p->p_pgid);
PS_ADD("session", "%d", p->p_session->s_sid);
PROC_UNLOCK(p);
PS_ADD("tty", "%d", 0); /* XXX */
PS_ADD("tty", "%d", kp.ki_tdev);
PS_ADD("tpgid", "%d", kp.ki_tpgid);
PS_ADD("flags", "%u", 0); /* XXX */
PS_ADD("minflt", "%lu", kp.ki_rusage.ru_minflt);
PS_ADD("cminflt", "%lu", kp.ki_rusage_ch.ru_minflt);
PS_ADD("majflt", "%lu", kp.ki_rusage.ru_majflt);
PS_ADD("cmajflt", "%lu", kp.ki_rusage_ch.ru_majflt);
PS_ADD("utime", "%ld", T2J(tvtohz(&kp.ki_rusage.ru_utime)));
PS_ADD("stime", "%ld", T2J(tvtohz(&kp.ki_rusage.ru_stime)));
PS_ADD("cutime", "%ld", T2J(tvtohz(&kp.ki_rusage_ch.ru_utime)));
PS_ADD("cstime", "%ld", T2J(tvtohz(&kp.ki_rusage_ch.ru_stime)));
PS_ADD("utime", "%ld", TV2J(&kp.ki_rusage.ru_utime));
PS_ADD("stime", "%ld", TV2J(&kp.ki_rusage.ru_stime));
PS_ADD("cutime", "%ld", TV2J(&kp.ki_rusage_ch.ru_utime));
PS_ADD("cstime", "%ld", TV2J(&kp.ki_rusage_ch.ru_stime));
PS_ADD("priority", "%d", kp.ki_pri.pri_user);
PS_ADD("nice", "%d", kp.ki_nice); /* 19 (nicest) to -19 */
PS_ADD("0", "%d", 0); /* removed field */
PS_ADD("itrealvalue", "%d", 0); /* XXX */
/* XXX: starttime is not right, it is the _same_ for _every_ process.
It should be the number of jiffies between system boot and process
start. */
PS_ADD("starttime", "%lu", T2J(tvtohz(&kp.ki_start)));
PS_ADD("starttime", "%lu", TV2J(&kp.ki_start) - TV2J(&boottime));
PS_ADD("vsize", "%ju", P2K((uintmax_t)kp.ki_size));
PS_ADD("rss", "%ju", (uintmax_t)kp.ki_rssize);
PS_ADD("rlim", "%lu", kp.ki_rusage.ru_maxrss);
PS_ADD("startcode", "%u", (unsigned)0);
PS_ADD("endcode", "%u", 0); /* XXX */
PS_ADD("startcode", "%ju", (uintmax_t)startcode);
PS_ADD("endcode", "%ju", (uintmax_t)startdata);
PS_ADD("startstack", "%u", 0); /* XXX */
PS_ADD("kstkesp", "%u", 0); /* XXX */
PS_ADD("kstkeip", "%u", 0); /* XXX */
@ -800,7 +808,7 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
*/
sbuf_printf(sb, "VmSize:\t%8ju kB\n", B2K((uintmax_t)kp.ki_size));
sbuf_printf(sb, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */
sbuf_printf(sb, "VmRss:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize));
sbuf_printf(sb, "VmRSS:\t%8ju kB\n", P2K((uintmax_t)kp.ki_rssize));
sbuf_printf(sb, "VmData:\t%8ju kB\n", P2K((uintmax_t)kp.ki_dsize));
sbuf_printf(sb, "VmStk:\t%8ju kB\n", P2K((uintmax_t)kp.ki_ssize));
sbuf_printf(sb, "VmExe:\t%8ju kB\n", P2K((uintmax_t)kp.ki_tsize));

View file

@ -1190,7 +1190,7 @@ iwn6000fw.fwo optional iwn6000fw | iwnfw \
clean "iwn6000fw.fwo"
iwn6000.fw optional iwn6000fw | iwnfw \
dependency ".PHONY" \
compile-with "uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.176.4.1.fw.uu" \
compile-with "uudecode -o ${.TARGET} $S/contrib/dev/iwn/iwlwifi-6000-9.193.4.1.fw.uu" \
no-obj no-implicit-rule \
clean "iwn6000.fw"
dev/ixgb/if_ixgb.c optional ixgb
@ -2358,7 +2358,7 @@ net80211/ieee80211_action.c optional wlan
net80211/ieee80211_ageq.c optional wlan
net80211/ieee80211_adhoc.c optional wlan
net80211/ieee80211_ageq.c optional wlan
net80211/ieee80211_amrr.c optional wlan wlan_amrr
net80211/ieee80211_amrr.c optional wlan | wlan_amrr
net80211/ieee80211_crypto.c optional wlan
net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp
net80211/ieee80211_crypto_none.c optional wlan
@ -2380,6 +2380,7 @@ net80211/ieee80211_phy.c optional wlan
net80211/ieee80211_power.c optional wlan
net80211/ieee80211_proto.c optional wlan
net80211/ieee80211_radiotap.c optional wlan
net80211/ieee80211_ratectl.c optional wlan
net80211/ieee80211_regdomain.c optional wlan
net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt
net80211/ieee80211_scan.c optional wlan

View file

@ -198,6 +198,7 @@ dev/hptrr/hptrr_config.c optional hptrr
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_intel.c optional hwpmc
dev/hwpmc/hwpmc_core.c optional hwpmc
dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_tsc.c optional hwpmc
dev/hwpmc/hwpmc_x86.c optional hwpmc

View file

@ -179,6 +179,7 @@ dev/hptrr/hptrr_config.c optional hptrr
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_intel.c optional hwpmc
dev/hwpmc/hwpmc_core.c optional hwpmc
dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_pentium.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_ppro.c optional hwpmc

View file

@ -99,6 +99,7 @@ dev/fe/if_fe_cbus.c optional fe isa
dev/hwpmc/hwpmc_amd.c optional hwpmc
dev/hwpmc/hwpmc_intel.c optional hwpmc
dev/hwpmc/hwpmc_core.c optional hwpmc
dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_pentium.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_ppro.c optional hwpmc

View file

@ -79,6 +79,7 @@ sparc64/pci/ofw_pcib.c optional pci
sparc64/pci/ofw_pcib_subr.c optional pci
sparc64/pci/ofw_pcibus.c optional pci
sparc64/pci/psycho.c optional pci
sparc64/pci/sbbc.c optional uart sbbc
sparc64/pci/schizo.c optional pci
sparc64/sbus/dma_sbus.c optional sbus
sparc64/sbus/sbus.c optional sbus

View file

@ -108,3 +108,11 @@ CFLAGS+= -restrict
${MACHINE_ARCH} != "arm" && ${MACHINE_ARCH} != "mips"
CFLAGS+= -fstack-protector
.endif
#
# Enable CTF conversation on request.
#
.if defined(WITH_CTF)
.undef NO_CTF
.endif

View file

@ -19,6 +19,10 @@ MKMODULESENV+= KERNBUILDDIR="${.CURDIR}" SYSDIR="${SYSDIR}"
MKMODULESENV+= CONF_CFLAGS="${CONF_CFLAGS}"
.endif
.if defined(WITH_CTF)
MKMODULESENV+= WITH_CTF="${WITH_CTF}"
.endif
.MAIN: all
.for target in all clean cleandepend cleandir clobber depend install \
@ -90,9 +94,7 @@ ${FULLKERNEL}: ${SYSTEM_DEP} vers.o
@rm -f ${.TARGET}
@echo linking ${.TARGET}
${SYSTEM_LD}
.if defined(CTFMERGE)
${SYSTEM_CTFMERGE}
.endif
@${SYSTEM_CTFMERGE}
.if !defined(DEBUG)
${OBJCOPY} --strip-debug ${.TARGET}
.endif
@ -240,9 +242,7 @@ kernel-reinstall:
config.o env.o hints.o vers.o vnode_if.o:
${NORMAL_C}
.if defined(CTFCONVERT)
${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.endif
@[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
config.ln env.ln hints.ln vers.ln vnode_if.ln:
${NORMAL_LINT}

View file

@ -128,11 +128,7 @@ NORMAL_C_NOWERROR= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
NORMAL_M= ${AWK} -f $S/tools/makeobjops.awk ${.IMPSRC} -c ; \
${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.PREFIX}.c
.if defined(CTFCONVERT)
NORMAL_CTFCONVERT= ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
.else
NORMAL_CTFCONVERT=
.endif
NORMAL_CTFCONVERT= @[ -z "${CTFCONVERT}" -o -n "${NO_CTF}" ] || ${CTFCONVERT} ${CTFFLAGS} ${.TARGET}
NORMAL_LINT= ${LINT} ${LINTFLAGS} ${CFLAGS:M-[DIU]*} ${.IMPSRC}
@ -141,10 +137,7 @@ SYSTEM_CFILES= config.c env.c hints.c vnode_if.c
SYSTEM_DEP= Makefile ${SYSTEM_OBJS}
SYSTEM_OBJS= locore.o ${MDOBJS} ${OBJS}
SYSTEM_OBJS+= ${SYSTEM_CFILES:.c=.o}
.if defined(CTFMERGE)
SYSTEM_CTFMERGE= ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
LD+= -g
.endif
SYSTEM_CTFMERGE= [ -z "${CTFMERGE}" -o -n "${NO_CTF}" ] || ${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${SYSTEM_OBJS} vers.o
.if ${MACHINE_ARCH} == XXX_ALTIX_TODO
SYSTEM_LDFLAGS= -r
.else

View file

@ -69,6 +69,11 @@ OBJCOPY?= objcopy
.error "Do not use KMODDEPS on 5.0+; use MODULE_VERSION/MODULE_DEPEND"
.endif
# Enable CTF conversion on request.
.if defined(WITH_CTF)
.undef NO_CTF
.endif
.include <bsd.init.mk>
.SUFFIXES: .out .o .c .cc .cxx .C .y .l .s .S

View file

@ -1,3 +1,78 @@
----------------------------------------
31 March 2010. Summary of changes for version 20100331:
1) ACPI CA Core Subsystem:
Completed a major update for the GPE support in order to improve support for
shared GPEs and to simplify both host OS and ACPICA code. Added a reference
count mechanism to support shared GPEs that require multiple device drivers.
Several external interfaces have changed. One external interface has been
removed. One new external interface was added. Most of the GPE external
interfaces now use the GPE spinlock instead of the events mutex (and the
Flags parameter for many GPE interfaces has been removed.) See the updated
ACPICA Programmer Reference for details. Matthew Garrett, Bob Moore, Rafael
Wysocki. ACPICA BZ 831.
Changed:
AcpiEnableGpe, AcpiDisableGpe, AcpiClearGpe, AcpiGetGpeStatus
Removed:
AcpiSetGpeType
New:
AcpiSetGpe
Implemented write support for DataTable operation regions. These regions are
defined via the DataTableRegion() operator. Previously, only read support was
implemented. The ACPI specification allows DataTableRegions to be read/write,
however.
Implemented a new subsystem option to force a copy of the DSDT to local
memory. Optionally copy the entire DSDT to local memory (instead of simply
mapping it.) There are some (albeit very rare) BIOSs that corrupt or replace
the original DSDT, creating the need for this option. Default is FALSE, do
not copy the DSDT.
Implemented detection of a corrupted or replaced DSDT. This change adds
support to detect a DSDT that has been corrupted and/or replaced from outside
the OS (by firmware). This is typically catastrophic for the system, but has
been seen on some machines. Once this problem has been detected, the DSDT
copy option can be enabled via system configuration. Lin Ming, Bob Moore.
Fixed two problems with AcpiReallocateRootTable during the root table copy.
When copying the root table to the new allocation, the length used was
incorrect. The new size was used instead of the current table size, meaning
too much data was copied. Also, the count of available slots for ACPI tables
was not set correctly. Alexey Starikovskiy, Bob Moore.
Example Code and Data Size: These are the sizes for the OS-independent
acpica.lib produced by the Microsoft Visual C++ 6.0 32-bit compiler. The
debug version of the code includes the debug output trace mechanism and has a
much larger code and data size.
Previous Release:
Non-Debug Version: 87.5K Code, 18.4K Data, 105.9K Total
Debug Version: 163.4K Code, 51.1K Data, 214.5K Total
Current Release:
Non-Debug Version: 87.9K Code, 18.6K Data, 106.5K Total
Debug Version: 163.5K Code, 51.3K Data, 214.8K Total
2) iASL Compiler/Disassembler and Tools:
iASL: Implement limited typechecking for values returned from predefined
control methods. The type of any returned static (unnamed) object is now
validated. For example, Return(1). ACPICA BZ 786.
iASL: Fixed a predefined name object verification regression. Fixes a problem
introduced in version 20100304. An error is incorrectly generated if a
predefined name is declared as a static named object with a value defined
using the keywords "Zero", "One", or "Ones". Lin Ming.
iASL: Added Windows 7 support for the -g option (get local ACPI tables) by
reducing the requested registry access rights. ACPICA BZ 842.
Disassembler: fixed a possible fault when generating External() statements.
Introduced in commit ae7d6fd: Properly handle externals with parent-prefix
(carat). Fixes a string length allocation calculation. Lin Ming.
----------------------------------------
04 March 2010. Summary of changes for version 20100304:

View file

@ -270,6 +270,15 @@ AcpiDmNormalizeParentPrefix (
}
Length = (ACPI_STRLEN (ParentPath) + ACPI_STRLEN (Path) + 1);
if (ParentPath[1])
{
/*
* If ParentPath is not just a simple '\', increment the length
* for the required dot separator (ParentPath.Path)
*/
Length++;
}
Fullpath = ACPI_ALLOCATE_ZEROED (Length);
if (!Fullpath)
{

View file

@ -1156,6 +1156,12 @@ AnMethodAnalysisWalkEnd (
case PARSEOP_RETURN:
/*
* If the parent is a predefined method name, attempt to typecheck
* the return value. Only static types can be validated.
*/
ApCheckPredefinedReturnValue (Op, MethodInfo);
/*
* The parent block does not "exit" and continue execution -- the
* method is terminated here with the Return() statement.

View file

@ -461,6 +461,11 @@ ApCheckForPredefinedMethod (
ACPI_PARSE_OBJECT *Op,
ASL_METHOD_INFO *MethodInfo);
void
ApCheckPredefinedReturnValue (
ACPI_PARSE_OBJECT *Op,
ASL_METHOD_INFO *MethodInfo);
UINT32
ApCheckForPredefinedName (
ACPI_PARSE_OBJECT *Op,

View file

@ -296,7 +296,11 @@ ApCheckForPredefinedMethod (
if (MethodInfo->NumReturnNoValue &&
PredefinedNames[Index].Info.ExpectedBtypes)
{
sprintf (MsgBuffer, "%4.4s", PredefinedNames[Index].Info.Name);
ApGetExpectedTypes (StringBuffer,
PredefinedNames[Index].Info.ExpectedBtypes);
sprintf (MsgBuffer, "%s required for %4.4s",
StringBuffer, PredefinedNames[Index].Info.Name);
AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
MsgBuffer);
@ -306,6 +310,90 @@ ApCheckForPredefinedMethod (
}
/*******************************************************************************
*
* FUNCTION: ApCheckPredefinedReturnValue
*
* PARAMETERS: Op - A parse node of type "RETURN".
* MethodInfo - Saved info about this method
*
* RETURN: None
*
* DESCRIPTION: If method is a predefined name, attempt to validate the return
* value. Only "static" types can be validated - a simple return
* of an integer/string/buffer/package or a named reference to
* a static object. Values such as a Localx or Argx or a control
* method invocation are not checked.
*
******************************************************************************/
void
ApCheckPredefinedReturnValue (
ACPI_PARSE_OBJECT *Op,
ASL_METHOD_INFO *MethodInfo)
{
UINT32 Index;
ACPI_PARSE_OBJECT *ReturnValueOp;
/* Check parent method for a match against the predefined name list */
Index = ApCheckForPredefinedName (MethodInfo->Op,
MethodInfo->Op->Asl.NameSeg);
switch (Index)
{
case ACPI_NOT_RESERVED_NAME: /* No underscore or _Txx or _xxx name not matched */
case ACPI_PREDEFINED_NAME: /* Resource Name or reserved scope name */
case ACPI_COMPILER_RESERVED_NAME: /* A _Txx that was not emitted by compiler */
case ACPI_EVENT_RESERVED_NAME: /* _Lxx, _Exx, and _Qxx methods */
/* Just return, nothing to do */
return;
default: /* a real predefined ACPI name */
/* Exit if no return value expected */
if (!PredefinedNames[Index].Info.ExpectedBtypes)
{
return;
}
/* Get the object returned, it is the next argument */
ReturnValueOp = Op->Asl.Child;
switch (ReturnValueOp->Asl.ParseOpcode)
{
case PARSEOP_ZERO:
case PARSEOP_ONE:
case PARSEOP_ONES:
case PARSEOP_INTEGER:
case PARSEOP_STRING_LITERAL:
case PARSEOP_BUFFER:
case PARSEOP_PACKAGE:
/* Static data return object - check against expected type */
ApCheckObjectType (ReturnValueOp,
PredefinedNames[Index].Info.ExpectedBtypes);
break;
default:
/*
* All other ops are very difficult or impossible to typecheck at
* compile time. These include all Localx, Argx, and method
* invocations. Also, NAMESEG and NAMESTRING because the type of
* any named object can be changed at runtime (for example,
* CopyObject will change the type of the target object.)
*/
break;
}
}
}
/*******************************************************************************
*
* FUNCTION: ApCheckForPredefinedObject
@ -441,7 +529,7 @@ ApCheckForPredefinedName (
*
* RETURN: None
*
* DESCRIPTION: Check for the "special" predefined names -
* DESCRIPTION: Check for the "special" predefined names -
* _Lxx, _Exx, _Qxx, and _T_x
*
******************************************************************************/
@ -512,7 +600,7 @@ ApCheckForSpecialName (
*
* FUNCTION: ApCheckObjectType
*
* PARAMETERS: Op - A parse node
* PARAMETERS: Op - Current parse node
* ExpectedBtypes - Bitmap of expected return type(s)
*
* RETURN: None
@ -529,11 +617,13 @@ ApCheckObjectType (
UINT32 ExpectedBtypes)
{
UINT32 ReturnBtype;
char TypeBuffer[48]; /* Room for 5 types */
switch (Op->Asl.ParseOpcode)
{
case PARSEOP_ZERO:
case PARSEOP_ONE:
case PARSEOP_ONES:
case PARSEOP_INTEGER:
ReturnBtype = ACPI_RTYPE_INTEGER;
break;
@ -552,11 +642,11 @@ ApCheckObjectType (
default:
/* Not one of the supported object types */
goto TypeErrorExit;
}
/* Is the object one of the expected types? */
/* Exit if the object is one of the expected types */
if (ReturnBtype & ExpectedBtypes)
{
@ -568,10 +658,13 @@ TypeErrorExit:
/* Format the expected types and emit an error message */
ApGetExpectedTypes (TypeBuffer, ExpectedBtypes);
ApGetExpectedTypes (StringBuffer, ExpectedBtypes);
sprintf (MsgBuffer, "found %s, requires %s",
UtGetOpName (Op->Asl.ParseOpcode), StringBuffer);
AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op,
TypeBuffer);
MsgBuffer);
}

View file

@ -243,13 +243,6 @@ AcpiEvInitializeRegion (
return (AE_OK);
}
ACPI_STATUS
AcpiEvCheckForWakeOnlyGpe (
ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
return (AE_OK);
}
void
AcpiExDoDebugObject (
ACPI_OPERAND_OBJECT *SourceDesc,

View file

@ -507,7 +507,7 @@ char *AslMessages [] = {
/* ASL_MSG_RESERVED_ARG_COUNT_HI */ "Reserved method has too many arguments",
/* ASL_MSG_RESERVED_ARG_COUNT_LO */ "Reserved method has too few arguments",
/* ASL_MSG_RESERVED_METHOD */ "Reserved name must be a control method",
/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name, must be",
/* ASL_MSG_RESERVED_OPERAND_TYPE */ "Invalid object type for reserved name",
/* ASL_MSG_RESERVED_RETURN_VALUE */ "Reserved method must return a value",
/* ASL_MSG_RESERVED_USE */ "Invalid use of reserved name",
/* ASL_MSG_RESERVED_WORD */ "Use of reserved name",

View file

@ -848,13 +848,12 @@ AcpiDbDisplayGpes (
Block, GpeBlock, GpeBlock->Node, Buffer);
AcpiOsPrintf (" Registers: %u (%u GPEs)\n",
GpeBlock->RegisterCount,
ACPI_MUL_8 (GpeBlock->RegisterCount));
GpeBlock->RegisterCount, GpeBlock->GpeCount);
AcpiOsPrintf (" GPE range: 0x%X to 0x%X\n",
AcpiOsPrintf (" GPE range: 0x%X to 0x%X on interrupt %u\n",
GpeBlock->BlockBaseNumber,
GpeBlock->BlockBaseNumber +
(GpeBlock->RegisterCount * 8) -1);
GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1),
GpeXruptInfo->InterruptNumber);
AcpiOsPrintf (
" RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n",
@ -871,9 +870,12 @@ AcpiDbDisplayGpes (
GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
AcpiOsPrintf (
" Reg %u: WakeEnable %2.2X, RunEnable %2.2X Status %8.8X%8.8X Enable %8.8X%8.8X\n",
i, GpeRegisterInfo->EnableForWake,
" Reg %u: (GPE %.2X-%.2X) RunEnable %2.2X WakeEnable %2.2X"
" Status %8.8X%8.8X Enable %8.8X%8.8X\n",
i, GpeRegisterInfo->BaseGpeNumber,
GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
GpeRegisterInfo->EnableForRun,
GpeRegisterInfo->EnableForWake,
ACPI_FORMAT_UINT64 (GpeRegisterInfo->StatusAddress.Address),
ACPI_FORMAT_UINT64 (GpeRegisterInfo->EnableAddress.Address));
@ -886,17 +888,19 @@ AcpiDbDisplayGpes (
if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
{
/* This GPE is not used (no method or handler) */
/* This GPE is not used (no method or handler), ignore it */
continue;
}
AcpiOsPrintf (
" GPE %.3X: %p Flags %2.2X: ",
GpeBlock->BlockBaseNumber + GpeIndex,
GpeEventInfo,
" GPE %.2X: %p RunRefs %2.2X WakeRefs %2.2X Flags %2.2X (",
GpeBlock->BlockBaseNumber + GpeIndex, GpeEventInfo,
GpeEventInfo->RuntimeCount, GpeEventInfo->WakeupCount,
GpeEventInfo->Flags);
/* Decode the flags byte */
if (GpeEventInfo->Flags & ACPI_GPE_LEVEL_TRIGGERED)
{
AcpiOsPrintf ("Level, ");
@ -906,38 +910,13 @@ AcpiDbDisplayGpes (
AcpiOsPrintf ("Edge, ");
}
switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
case ACPI_GPE_TYPE_WAKE:
AcpiOsPrintf ("WakeOnly: ");
break;
case ACPI_GPE_TYPE_RUNTIME:
AcpiOsPrintf (" RunOnly: ");
break;
case ACPI_GPE_TYPE_WAKE_RUN:
AcpiOsPrintf (" WakeRun: ");
break;
default:
AcpiOsPrintf (" NotUsed: ");
break;
}
if (GpeEventInfo->Flags & ACPI_GPE_WAKE_ENABLED)
{
AcpiOsPrintf ("[Wake 1 ");
AcpiOsPrintf ("CanWake, ");
}
else
{
AcpiOsPrintf ("[Wake 0 ");
}
if (GpeEventInfo->Flags & ACPI_GPE_RUN_ENABLED)
{
AcpiOsPrintf ("Run 1], ");
}
else
{
AcpiOsPrintf ("Run 0], ");
AcpiOsPrintf ("RunOnly, ");
}
switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK)
@ -957,7 +936,7 @@ AcpiDbDisplayGpes (
break;
}
AcpiOsPrintf ("\n");
AcpiOsPrintf (")\n");
}
}
Block++;

View file

@ -132,73 +132,22 @@ AcpiEvAsynchEnableGpe (
void *Context);
/*******************************************************************************
*
* FUNCTION: AcpiEvSetGpeType
*
* PARAMETERS: GpeEventInfo - GPE to set
* Type - New type
*
* RETURN: Status
*
* DESCRIPTION: Sets the new type for the GPE (wake, run, or wake/run)
*
******************************************************************************/
ACPI_STATUS
AcpiEvSetGpeType (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
UINT8 Type)
{
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (EvSetGpeType);
/* Validate type and update register enable masks */
switch (Type)
{
case ACPI_GPE_TYPE_WAKE:
case ACPI_GPE_TYPE_RUNTIME:
case ACPI_GPE_TYPE_WAKE_RUN:
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Disable the GPE if currently enabled */
Status = AcpiEvDisableGpe (GpeEventInfo);
/* Clear the type bits and insert the new Type */
GpeEventInfo->Flags &= ~ACPI_GPE_TYPE_MASK;
GpeEventInfo->Flags |= Type;
return_ACPI_STATUS (Status);
}
/*******************************************************************************
*
* FUNCTION: AcpiEvUpdateGpeEnableMasks
*
* PARAMETERS: GpeEventInfo - GPE to update
* Type - What to do: ACPI_GPE_DISABLE or
* ACPI_GPE_ENABLE
*
* RETURN: Status
*
* DESCRIPTION: Updates GPE register enable masks based on the GPE type
* DESCRIPTION: Updates GPE register enable masks based upon whether there are
* references (either wake or run) to this GPE
*
******************************************************************************/
ACPI_STATUS
AcpiEvUpdateGpeEnableMasks (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
UINT8 Type)
ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_GPE_REGISTER_INFO *GpeRegisterInfo;
UINT8 RegisterBit;
@ -216,36 +165,21 @@ AcpiEvUpdateGpeEnableMasks (
RegisterBit = (UINT8)
(1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber));
/* 1) Disable case. Simply clear all enable bits */
/* Clear the wake/run bits up front */
if (Type == ACPI_GPE_DISABLE)
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
/* Set the mask bits only if there are references to this GPE */
if (GpeEventInfo->RuntimeCount)
{
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
return_ACPI_STATUS (AE_OK);
ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
}
/* 2) Enable case. Set/Clear the appropriate enable bits */
switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
if (GpeEventInfo->WakeupCount)
{
case ACPI_GPE_TYPE_WAKE:
ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
break;
case ACPI_GPE_TYPE_RUNTIME:
ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, RegisterBit);
}
return_ACPI_STATUS (AE_OK);
@ -257,19 +191,19 @@ AcpiEvUpdateGpeEnableMasks (
* FUNCTION: AcpiEvEnableGpe
*
* PARAMETERS: GpeEventInfo - GPE to enable
* WriteToHardware - Enable now, or just mark data structs
* (WAKE GPEs should be deferred)
*
* RETURN: Status
*
* DESCRIPTION: Enable a GPE based on the GPE type
* DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless
* of type or number of references.
*
* Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
ACPI_STATUS
AcpiEvEnableGpe (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
BOOLEAN WriteToHardware)
ACPI_GPE_EVENT_INFO *GpeEventInfo)
{
ACPI_STATUS Status;
@ -277,54 +211,37 @@ AcpiEvEnableGpe (
ACPI_FUNCTION_TRACE (EvEnableGpe);
/* Make sure HW enable masks are updated */
/*
* We will only allow a GPE to be enabled if it has either an
* associated method (_Lxx/_Exx) or a handler. Otherwise, the
* GPE will be immediately disabled by AcpiEvGpeDispatch the
* first time it fires.
*/
if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK))
{
return_ACPI_STATUS (AE_NO_HANDLER);
}
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE);
/* Ensure the HW enable masks are current */
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/* Mark wake-enabled or HW enable, or both */
/* Clear the GPE (of stale events) */
switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
case ACPI_GPE_TYPE_WAKE:
ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
/*lint -fallthrough */
case ACPI_GPE_TYPE_RUNTIME:
ACPI_SET_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
if (WriteToHardware)
{
/* Clear the GPE (of stale events), then enable it */
Status = AcpiHwClearGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/* Enable the requested runtime GPE */
Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
}
break;
default:
return_ACPI_STATUS (AE_BAD_PARAMETER);
return_ACPI_STATUS (Status);
}
return_ACPI_STATUS (AE_OK);
/* Enable the requested GPE */
Status = AcpiHwWriteGpeEnableReg (GpeEventInfo);
return_ACPI_STATUS (Status);
}
@ -336,7 +253,10 @@ AcpiEvEnableGpe (
*
* RETURN: Status
*
* DESCRIPTION: Disable a GPE based on the GPE type
* DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE,
* regardless of the type or number of references.
*
* Note: The GPE lock should be already acquired when this function is called.
*
******************************************************************************/
@ -356,40 +276,14 @@ AcpiEvDisableGpe (
* the GPE behind our back.
*/
/* Make sure HW enable masks are updated */
/* Ensure the HW enable masks are current */
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
/* Clear the appropriate enabled flags for this GPE */
switch (GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK)
{
case ACPI_GPE_TYPE_WAKE:
ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_WAKE_ENABLED);
/*lint -fallthrough */
case ACPI_GPE_TYPE_RUNTIME:
/* Disable the requested runtime GPE */
ACPI_CLEAR_BIT (GpeEventInfo->Flags, ACPI_GPE_RUN_ENABLED);
break;
default:
break;
}
/*
* Always H/W disable this GPE, even if we don't know the GPE type.
* Simply clear the enable bit for this particular GPE, but do not
@ -403,6 +297,49 @@ AcpiEvDisableGpe (
}
/*******************************************************************************
*
* FUNCTION: AcpiEvLowGetGpeInfo
*
* PARAMETERS: GpeNumber - Raw GPE number
* GpeBlock - A GPE info block
*
* RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
* is not within the specified GPE block)
*
* DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
* the low-level implementation of EvGetGpeEventInfo.
*
******************************************************************************/
ACPI_GPE_EVENT_INFO *
AcpiEvLowGetGpeInfo (
UINT32 GpeNumber,
ACPI_GPE_BLOCK_INFO *GpeBlock)
{
UINT32 GpeIndex;
/*
* Validate that the GpeNumber is within the specified GpeBlock.
* (Two steps)
*/
if (!GpeBlock ||
(GpeNumber < GpeBlock->BlockBaseNumber))
{
return (NULL);
}
GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
if (GpeIndex >= GpeBlock->GpeCount)
{
return (NULL);
}
return (&GpeBlock->EventInfo[GpeIndex]);
}
/*******************************************************************************
*
* FUNCTION: AcpiEvGetGpeEventInfo
@ -426,7 +363,7 @@ AcpiEvGetGpeEventInfo (
UINT32 GpeNumber)
{
ACPI_OPERAND_OBJECT *ObjDesc;
ACPI_GPE_BLOCK_INFO *GpeBlock;
ACPI_GPE_EVENT_INFO *GpeInfo;
UINT32 i;
@ -441,16 +378,11 @@ AcpiEvGetGpeEventInfo (
for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
{
GpeBlock = AcpiGbl_GpeFadtBlocks[i];
if (GpeBlock)
GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
AcpiGbl_GpeFadtBlocks[i]);
if (GpeInfo)
{
if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
(GpeNumber < GpeBlock->BlockBaseNumber +
(GpeBlock->RegisterCount * 8)))
{
return (&GpeBlock->EventInfo[GpeNumber -
GpeBlock->BlockBaseNumber]);
}
return (GpeInfo);
}
}
@ -468,15 +400,7 @@ AcpiEvGetGpeEventInfo (
return (NULL);
}
GpeBlock = ObjDesc->Device.GpeBlock;
if ((GpeNumber >= GpeBlock->BlockBaseNumber) &&
(GpeNumber < GpeBlock->BlockBaseNumber + (GpeBlock->RegisterCount * 8)))
{
return (&GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber]);
}
return (NULL);
return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
}
@ -654,9 +578,9 @@ AcpiEvAsynchExecuteGpeMethod (
return_VOID;
}
/* Set the GPE flags for return to enabled state */
/* Update the GPE register masks for return to enabled state */
(void) AcpiEvEnableGpe (GpeEventInfo, FALSE);
(void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
/*
* Take a snapshot of the GPE info for this level - we copy the info to
@ -872,15 +796,18 @@ AcpiEvGpeDispatch (
default:
/* No handler or method to run! */
/*
* No handler or method to run!
* 03/2010: This case should no longer be possible. We will not allow
* a GPE to be enabled if it has no handler or method.
*/
ACPI_ERROR ((AE_INFO,
"No handler or method for GPE[0x%2X], disabling event",
GpeNumber));
/*
* Disable the GPE. The GPE will remain disabled until the ACPICA
* Core Subsystem is restarted, or a handler is installed.
* Disable the GPE. The GPE will remain disabled a handler
* is installed or ACPICA is restarted.
*/
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))

View file

@ -124,7 +124,7 @@
/* Local prototypes */
static ACPI_STATUS
AcpiEvSaveMethodInfo (
AcpiEvMatchGpeMethod (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *ObjDesc,
@ -194,8 +194,7 @@ AcpiEvValidGpeEvent (
while (GpeBlock)
{
if ((&GpeBlock->EventInfo[0] <= GpeEventInfo) &&
(&GpeBlock->EventInfo[((ACPI_SIZE)
GpeBlock->RegisterCount) * 8] > GpeEventInfo))
(&GpeBlock->EventInfo[GpeBlock->GpeCount] > GpeEventInfo))
{
return (TRUE);
}
@ -328,7 +327,7 @@ AcpiEvDeleteGpeHandlers (
/*******************************************************************************
*
* FUNCTION: AcpiEvSaveMethodInfo
* FUNCTION: AcpiEvMatchGpeMethod
*
* PARAMETERS: Callback from WalkNamespace
*
@ -340,8 +339,7 @@ AcpiEvDeleteGpeHandlers (
* information for quick lookup during GPE dispatch
*
* The name of each GPE control method is of the form:
* "_Lxx" or "_Exx"
* Where:
* "_Lxx" or "_Exx", where:
* L - means that the GPE is level triggered
* E - means that the GPE is edge triggered
* xx - is the GPE number [in HEX]
@ -349,38 +347,44 @@ AcpiEvDeleteGpeHandlers (
******************************************************************************/
static ACPI_STATUS
AcpiEvSaveMethodInfo (
AcpiEvMatchGpeMethod (
ACPI_HANDLE ObjHandle,
UINT32 Level,
void *ObjDesc,
void **ReturnValue)
{
ACPI_NAMESPACE_NODE *MethodNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, ObjHandle);
ACPI_GPE_BLOCK_INFO *GpeBlock = (void *) ObjDesc;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
UINT32 GpeNumber;
char Name[ACPI_NAME_SIZE + 1];
UINT8 Type;
ACPI_STATUS Status;
ACPI_FUNCTION_TRACE (EvSaveMethodInfo);
ACPI_FUNCTION_TRACE (EvMatchGpeMethod);
/*
* _Lxx and _Exx GPE method support
* Match and decode the _Lxx and _Exx GPE method names
*
* 1) Extract the name from the object and convert to a string
* 1) Extract the method name and null terminate it
*/
ACPI_MOVE_32_TO_32 (
Name, &((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Integer);
ACPI_MOVE_32_TO_32 (Name, &MethodNode->Name.Integer);
Name[ACPI_NAME_SIZE] = 0;
/* 2) Name must begin with an underscore */
if (Name[0] != '_')
{
return_ACPI_STATUS (AE_OK); /* Ignore this method */
}
/*
* 2) Edge/Level determination is based on the 2nd character
* 3) Edge/Level determination is based on the 2nd character
* of the method name
*
* NOTE: Default GPE type is RUNTIME. May be changed later to WAKE
* if a _PRW object is found that points to this GPE.
* NOTE: Default GPE type is RUNTIME only. Later, if a _PRW object is
* found that points to this GPE, the ACPI_GPE_CAN_WAKE flag is set.
*/
switch (Name[1])
{
@ -393,16 +397,15 @@ AcpiEvSaveMethodInfo (
break;
default:
/* Unknown method type, just ignore it! */
/* Unknown method type, just ignore it */
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Ignoring unknown GPE method type: %s "
"(name not of form _Lxx or _Exx)",
Name));
"(name not of form _Lxx or _Exx)", Name));
return_ACPI_STATUS (AE_OK);
}
/* Convert the last two characters of the name to the GPE Number */
/* 4) The last two characters of the name are the hex GPE Number */
GpeNumber = ACPI_STRTOUL (&Name[2], NULL, 16);
if (GpeNumber == ACPI_UINT32_MAX)
@ -411,45 +414,34 @@ AcpiEvSaveMethodInfo (
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Could not extract GPE number from name: %s "
"(name is not of form _Lxx or _Exx)",
Name));
"(name is not of form _Lxx or _Exx)", Name));
return_ACPI_STATUS (AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
if ((GpeNumber < GpeBlock->BlockBaseNumber) ||
(GpeNumber >= (GpeBlock->BlockBaseNumber +
(GpeBlock->RegisterCount * 8))))
GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
if (!GpeEventInfo)
{
/*
* Not valid for this GPE block, just ignore it. However, it may be
* valid for a different GPE block, since GPE0 and GPE1 methods both
* appear under \_GPE.
* This GpeNumber is not valid for this GPE block, just ignore it.
* However, it may be valid for a different GPE block, since GPE0
* and GPE1 methods both appear under \_GPE.
*/
return_ACPI_STATUS (AE_OK);
}
/*
* Now we can add this information to the GpeEventInfo block for use
* during dispatch of this GPE. Default type is RUNTIME, although this may
* change when the _PRW methods are executed later.
* Add the GPE information from above to the GpeEventInfo block for
* use during dispatch of this GPE.
*/
GpeEventInfo = &GpeBlock->EventInfo[GpeNumber - GpeBlock->BlockBaseNumber];
GpeEventInfo->Flags = (UINT8)
(Type | ACPI_GPE_DISPATCH_METHOD | ACPI_GPE_TYPE_RUNTIME);
GpeEventInfo->Dispatch.MethodNode = (ACPI_NAMESPACE_NODE *) ObjHandle;
/* Update enable mask, but don't enable the HW GPE as of yet */
Status = AcpiEvEnableGpe (GpeEventInfo, FALSE);
GpeEventInfo->Flags = (UINT8) (Type | ACPI_GPE_DISPATCH_METHOD);
GpeEventInfo->Dispatch.MethodNode = MethodNode;
ACPI_DEBUG_PRINT ((ACPI_DB_LOAD,
"Registered GPE method %s as GPE number 0x%.2X\n",
Name, GpeNumber));
return_ACPI_STATUS (Status);
return_ACPI_STATUS (AE_OK);
}
@ -464,7 +456,7 @@ AcpiEvSaveMethodInfo (
*
* DESCRIPTION: Called from AcpiWalkNamespace. Expects each object to be a
* Device. Run the _PRW method. If present, extract the GPE
* number and mark the GPE as a WAKE GPE.
* number and mark the GPE as a CAN_WAKE GPE.
*
******************************************************************************/
@ -495,7 +487,7 @@ AcpiEvMatchPrwAndGpe (
ACPI_BTYPE_PACKAGE, &PkgDesc);
if (ACPI_FAILURE (Status))
{
/* Ignore all errors from _PRW, we don't want to abort the subsystem */
/* Ignore all errors from _PRW, we don't want to abort the walk */
return_ACPI_STATUS (AE_OK);
}
@ -561,25 +553,17 @@ AcpiEvMatchPrwAndGpe (
* 2) The GPE index(number) is within the range of the Gpe Block
* associated with the GPE device.
*/
if ((GpeDevice == TargetGpeDevice) &&
(GpeNumber >= GpeBlock->BlockBaseNumber) &&
(GpeNumber < GpeBlock->BlockBaseNumber +
(GpeBlock->RegisterCount * 8)))
if (GpeDevice != TargetGpeDevice)
{
GpeEventInfo = &GpeBlock->EventInfo[GpeNumber -
GpeBlock->BlockBaseNumber];
goto Cleanup;
}
/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
GpeEventInfo = AcpiEvLowGetGpeInfo (GpeNumber, GpeBlock);
if (GpeEventInfo)
{
/* This GPE can wake the system */
GpeEventInfo->Flags &= ~(ACPI_GPE_WAKE_ENABLED | ACPI_GPE_RUN_ENABLED);
Status = AcpiEvSetGpeType (GpeEventInfo, ACPI_GPE_TYPE_WAKE);
if (ACPI_FAILURE (Status))
{
goto Cleanup;
}
Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_DISABLE);
GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
}
Cleanup:
@ -880,7 +864,7 @@ AcpiEvDeleteGpeBlock (
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
}
AcpiCurrentGpeCount -= GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH;
AcpiCurrentGpeCount -= GpeBlock->GpeCount;
/* Free the GpeBlock */
@ -925,8 +909,8 @@ AcpiEvCreateGpeInfoBlocks (
/* Allocate the GPE register information block */
GpeRegisterInfo = ACPI_ALLOCATE_ZEROED (
(ACPI_SIZE) GpeBlock->RegisterCount *
sizeof (ACPI_GPE_REGISTER_INFO));
(ACPI_SIZE) GpeBlock->RegisterCount *
sizeof (ACPI_GPE_REGISTER_INFO));
if (!GpeRegisterInfo)
{
ACPI_ERROR ((AE_INFO,
@ -938,10 +922,8 @@ AcpiEvCreateGpeInfoBlocks (
* Allocate the GPE EventInfo block. There are eight distinct GPEs
* per register. Initialization to zeros is sufficient.
*/
GpeEventInfo = ACPI_ALLOCATE_ZEROED (
((ACPI_SIZE) GpeBlock->RegisterCount *
ACPI_GPE_REGISTER_WIDTH) *
sizeof (ACPI_GPE_EVENT_INFO));
GpeEventInfo = ACPI_ALLOCATE_ZEROED ((ACPI_SIZE) GpeBlock->GpeCount *
sizeof (ACPI_GPE_EVENT_INFO));
if (!GpeEventInfo)
{
ACPI_ERROR ((AE_INFO,
@ -1080,6 +1062,7 @@ AcpiEvCreateGpeBlock (
/* Initialize the new GPE block */
GpeBlock->Node = GpeDevice;
GpeBlock->GpeCount = (UINT16) (RegisterCount * ACPI_GPE_REGISTER_WIDTH);
GpeBlock->RegisterCount = RegisterCount;
GpeBlock->BlockBaseNumber = GpeBlockBaseNumber;
@ -1110,7 +1093,7 @@ AcpiEvCreateGpeBlock (
Status = AcpiNsWalkNamespace (ACPI_TYPE_METHOD, GpeDevice,
ACPI_UINT32_MAX, ACPI_NS_WALK_NO_UNLOCK,
AcpiEvSaveMethodInfo, NULL, GpeBlock, NULL);
AcpiEvMatchGpeMethod, NULL, GpeBlock, NULL);
/* Return the new block */
@ -1122,15 +1105,13 @@ AcpiEvCreateGpeBlock (
ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
"GPE %02X to %02X [%4.4s] %u regs on int 0x%X\n",
(UINT32) GpeBlock->BlockBaseNumber,
(UINT32) (GpeBlock->BlockBaseNumber +
((GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH) -1)),
GpeDevice->Name.Ascii,
GpeBlock->RegisterCount,
(UINT32) (GpeBlock->BlockBaseNumber + (GpeBlock->GpeCount - 1)),
GpeDevice->Name.Ascii, GpeBlock->RegisterCount,
InterruptNumber));
/* Update global count of currently available GPEs */
AcpiCurrentGpeCount += RegisterCount * ACPI_GPE_REGISTER_WIDTH;
AcpiCurrentGpeCount += GpeBlock->GpeCount;
return_ACPI_STATUS (AE_OK);
}
@ -1161,6 +1142,8 @@ AcpiEvInitializeGpeBlock (
ACPI_GPE_WALK_INFO GpeInfo;
UINT32 WakeGpeCount;
UINT32 GpeEnabledCount;
UINT32 GpeIndex;
UINT32 GpeNumber;
UINT32 i;
UINT32 j;
@ -1193,39 +1176,65 @@ AcpiEvInitializeGpeBlock (
Status = AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
AcpiEvMatchPrwAndGpe, NULL, &GpeInfo, NULL);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status, "While executing _PRW methods"));
}
}
/*
* Enable all GPEs in this block that have these attributes:
* 1) are "runtime" or "run/wake" GPEs, and
* 2) have a corresponding _Lxx or _Exx method
*
* Any other GPEs within this block must be enabled via the
* AcpiEnableGpe() external interface.
* Enable all GPEs that have a corresponding method and are not
* capable of generating wakeups. Any other GPEs within this block
* must be enabled via the AcpiEnableGpe interface.
*/
WakeGpeCount = 0;
GpeEnabledCount = 0;
if (GpeDevice == AcpiGbl_FadtGpeDevice)
{
GpeDevice = NULL;
}
for (i = 0; i < GpeBlock->RegisterCount; i++)
{
for (j = 0; j < 8; j++)
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
{
/* Get the info block for this particular GPE */
GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
ACPI_GPE_REGISTER_WIDTH) + j];
GpeIndex = (i * ACPI_GPE_REGISTER_WIDTH) + j;
GpeEventInfo = &GpeBlock->EventInfo[GpeIndex];
if (((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_METHOD) &&
(GpeEventInfo->Flags & ACPI_GPE_TYPE_RUNTIME))
{
GpeEnabledCount++;
}
/* Ignore GPEs that can wake the system */
if (GpeEventInfo->Flags & ACPI_GPE_TYPE_WAKE)
if (GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)
{
WakeGpeCount++;
if (AcpiGbl_LeaveWakeGpesDisabled)
{
continue;
}
}
/* Ignore GPEs that have no corresponding _Lxx/_Exx method */
if (!(GpeEventInfo->Flags & ACPI_GPE_DISPATCH_METHOD))
{
continue;
}
/* Enable this GPE */
GpeNumber = GpeIndex + GpeBlock->BlockBaseNumber;
Status = AcpiEnableGpe (GpeDevice, GpeNumber,
ACPI_GPE_TYPE_RUNTIME);
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
"Could not enable GPE 0x%02X", GpeNumber));
continue;
}
GpeEnabledCount++;
}
}
@ -1233,16 +1242,7 @@ AcpiEvInitializeGpeBlock (
"Found %u Wake, Enabled %u Runtime GPEs in this block\n",
WakeGpeCount, GpeEnabledCount));
/* Enable all valid runtime GPEs found above */
Status = AcpiHwEnableRuntimeGpeBlock (NULL, GpeBlock, NULL);
if (ACPI_FAILURE (Status))
{
ACPI_ERROR ((AE_INFO, "Could not enable GPEs in GpeBlock %p",
GpeBlock));
}
return_ACPI_STATUS (Status);
return_ACPI_STATUS (AE_OK);
}

View file

@ -705,7 +705,7 @@ AcpiInstallGpeHandler (
/* Parameter validation */
if ((!Address) || (Type > ACPI_GPE_XRUPT_TYPE_MASK))
if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK))
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}

View file

@ -305,70 +305,20 @@ AcpiEnableEvent (
ACPI_EXPORT_SYMBOL (AcpiEnableEvent)
/*******************************************************************************
*
* FUNCTION: AcpiSetGpeType
*
* PARAMETERS: GpeDevice - Parent GPE Device
* GpeNumber - GPE level within the GPE block
* Type - New GPE type
*
* RETURN: Status
*
* DESCRIPTION: Set the type of an individual GPE
*
******************************************************************************/
ACPI_STATUS
AcpiSetGpeType (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT8 Type)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_FUNCTION_TRACE (AcpiSetGpeType);
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
if (!GpeEventInfo)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
if ((GpeEventInfo->Flags & ACPI_GPE_TYPE_MASK) == Type)
{
return_ACPI_STATUS (AE_OK);
}
/* Set the new type (will disable GPE if currently enabled) */
Status = AcpiEvSetGpeType (GpeEventInfo, Type);
UnlockAndExit:
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiSetGpeType)
/*******************************************************************************
*
* FUNCTION: AcpiEnableGpe
*
* PARAMETERS: GpeDevice - Parent GPE Device
* PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
* Flags - Just enable, or also wake enable?
* Called from ISR or not
* GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
* or both
*
* RETURN: Status
*
* DESCRIPTION: Enable an ACPI event (general purpose)
* DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
* hardware-enabled (for runtime GPEs), or the GPE register mask
* is updated (for wake GPEs).
*
******************************************************************************/
@ -376,26 +326,25 @@ ACPI_STATUS
AcpiEnableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags)
UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiEnableGpe);
/* Use semaphore lock if not executing at interrupt level */
/* Parameter validation */
if (Flags & ACPI_NOT_ISR)
if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
{
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
@ -405,15 +354,55 @@ AcpiEnableGpe (
goto UnlockAndExit;
}
/* Perform the enable */
if (GpeType & ACPI_GPE_TYPE_RUNTIME)
{
if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
{
Status = AE_LIMIT; /* Too many references */
goto UnlockAndExit;
}
Status = AcpiEvEnableGpe (GpeEventInfo, TRUE);
GpeEventInfo->RuntimeCount++;
if (GpeEventInfo->RuntimeCount == 1)
{
Status = AcpiEvEnableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
GpeEventInfo->RuntimeCount--;
goto UnlockAndExit;
}
}
}
if (GpeType & ACPI_GPE_TYPE_WAKE)
{
/* The GPE must have the ability to wake the system */
if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
{
Status = AE_TYPE;
goto UnlockAndExit;
}
if (GpeEventInfo->WakeupCount == ACPI_UINT8_MAX)
{
Status = AE_LIMIT; /* Too many references */
goto UnlockAndExit;
}
/*
* Update the enable mask on the first wakeup reference. Wake GPEs
* are only hardware-enabled just before sleeping.
*/
GpeEventInfo->WakeupCount++;
if (GpeEventInfo->WakeupCount == 1)
{
(void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
}
}
UnlockAndExit:
if (Flags & ACPI_NOT_ISR)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
@ -424,14 +413,16 @@ ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
*
* FUNCTION: AcpiDisableGpe
*
* PARAMETERS: GpeDevice - Parent GPE Device
* PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
* Flags - Just disable, or also wake disable?
* Called from ISR or not
* GpeType - ACPI_GPE_TYPE_RUNTIME or ACPI_GPE_TYPE_WAKE
* or both
*
* RETURN: Status
*
* DESCRIPTION: Disable an ACPI event (general purpose)
* DESCRIPTION: Remove a reference to a GPE. When the last reference is
* removed, only then is the GPE disabled (for runtime GPEs), or
* the GPE mask bit disabled (for wake GPEs)
*
******************************************************************************/
@ -439,26 +430,25 @@ ACPI_STATUS
AcpiDisableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags)
UINT8 GpeType)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiDisableGpe);
/* Use semaphore lock if not executing at interrupt level */
/* Parameter validation */
if (Flags & ACPI_NOT_ISR)
if (!GpeType || (GpeType & ~ACPI_GPE_TYPE_WAKE_RUN))
{
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
@ -468,19 +458,127 @@ AcpiDisableGpe (
goto UnlockAndExit;
}
Status = AcpiEvDisableGpe (GpeEventInfo);
/* Hardware-disable a runtime GPE on removal of the last reference */
if (GpeType & ACPI_GPE_TYPE_RUNTIME)
{
if (!GpeEventInfo->RuntimeCount)
{
Status = AE_LIMIT; /* There are no references to remove */
goto UnlockAndExit;
}
GpeEventInfo->RuntimeCount--;
if (!GpeEventInfo->RuntimeCount)
{
Status = AcpiEvDisableGpe (GpeEventInfo);
if (ACPI_FAILURE (Status))
{
GpeEventInfo->RuntimeCount++;
goto UnlockAndExit;
}
}
}
/*
* Update masks for wake GPE on removal of the last reference.
* No need to hardware-disable wake GPEs here, they are not currently
* enabled.
*/
if (GpeType & ACPI_GPE_TYPE_WAKE)
{
if (!GpeEventInfo->WakeupCount)
{
Status = AE_LIMIT; /* There are no references to remove */
goto UnlockAndExit;
}
GpeEventInfo->WakeupCount--;
if (!GpeEventInfo->WakeupCount)
{
(void) AcpiEvUpdateGpeEnableMasks (GpeEventInfo);
}
}
UnlockAndExit:
if (Flags & ACPI_NOT_ISR)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
/*******************************************************************************
*
* FUNCTION: AcpiSetGpe
*
* PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
* Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
*
* RETURN: Status
*
* DESCRIPTION: Enable or disable an individual GPE. This function bypasses
* the reference count mechanism used in the AcpiEnableGpe and
* AcpiDisableGpe interfaces -- and should be used with care.
*
* Note: Typically used to disable a runtime GPE for short period of time,
* then re-enable it, without disturbing the existing reference counts. This
* is useful, for example, in the Embedded Controller (EC) driver.
*
******************************************************************************/
ACPI_STATUS
AcpiSetGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT8 Action)
{
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_STATUS Status;
ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiSetGpe);
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
if (!GpeEventInfo)
{
Status = AE_BAD_PARAMETER;
goto UnlockAndExit;
}
/* Perform the action */
switch (Action)
{
case ACPI_GPE_ENABLE:
Status = AcpiEvEnableGpe (GpeEventInfo);
break;
case ACPI_GPE_DISABLE:
Status = AcpiEvDisableGpe (GpeEventInfo);
break;
default:
Status = AE_BAD_PARAMETER;
break;
}
UnlockAndExit:
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiSetGpe)
/*******************************************************************************
*
* FUNCTION: AcpiDisableEvent
@ -592,9 +690,8 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
*
* FUNCTION: AcpiClearGpe
*
* PARAMETERS: GpeDevice - Parent GPE Device
* PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
* Flags - Called from an ISR or not
*
* RETURN: Status
*
@ -605,26 +702,17 @@ ACPI_EXPORT_SYMBOL (AcpiClearEvent)
ACPI_STATUS
AcpiClearGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags)
UINT32 GpeNumber)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiClearGpe);
/* Use semaphore lock if not executing at interrupt level */
if (Flags & ACPI_NOT_ISR)
{
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@ -638,10 +726,7 @@ AcpiClearGpe (
Status = AcpiHwClearGpe (GpeEventInfo);
UnlockAndExit:
if (Flags & ACPI_NOT_ISR)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
@ -700,9 +785,8 @@ ACPI_EXPORT_SYMBOL (AcpiGetEventStatus)
*
* FUNCTION: AcpiGetGpeStatus
*
* PARAMETERS: GpeDevice - Parent GPE Device
* PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1
* GpeNumber - GPE level within the GPE block
* Flags - Called from an ISR or not
* EventStatus - Where the current status of the event will
* be returned
*
@ -716,26 +800,17 @@ ACPI_STATUS
AcpiGetGpeStatus (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags,
ACPI_EVENT_STATUS *EventStatus)
{
ACPI_STATUS Status = AE_OK;
ACPI_GPE_EVENT_INFO *GpeEventInfo;
ACPI_CPU_FLAGS Flags;
ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
/* Use semaphore lock if not executing at interrupt level */
if (Flags & ACPI_NOT_ISR)
{
Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
}
}
Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
/* Ensure that we have a valid GPE number */
@ -751,10 +826,7 @@ AcpiGetGpeStatus (
Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
UnlockAndExit:
if (Flags & ACPI_NOT_ISR)
{
(void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
}
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
return_ACPI_STATUS (Status);
}
@ -823,21 +895,15 @@ AcpiInstallGpeBlock (
goto UnlockAndExit;
}
/* Run the _PRW methods and enable the GPEs */
Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
if (ACPI_FAILURE (Status))
{
goto UnlockAndExit;
}
/* Get the DeviceObject attached to the node */
/* Install block in the DeviceObject attached to the node */
ObjDesc = AcpiNsGetAttachedObject (Node);
if (!ObjDesc)
{
/* No object, create a new one */
/*
* No object, create a new one (Device nodes do not always have
* an attached object)
*/
ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
if (!ObjDesc)
{
@ -850,17 +916,20 @@ AcpiInstallGpeBlock (
/* Remove local reference to the object */
AcpiUtRemoveReference (ObjDesc);
if (ACPI_FAILURE (Status))
{
goto UnlockAndExit;
}
}
/* Install the GPE block in the DeviceObject */
/* Now install the GPE block in the DeviceObject */
ObjDesc->Device.GpeBlock = GpeBlock;
/* Run the _PRW methods and enable the runtime GPEs in the new block */
Status = AcpiEvInitializeGpeBlock (Node, GpeBlock);
UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
@ -1018,8 +1087,7 @@ AcpiEvGetGpeDevice (
/* Increment Index by the number of GPEs in this block */
Info->NextBlockBaseIndex +=
(GpeBlock->RegisterCount * ACPI_GPE_REGISTER_WIDTH);
Info->NextBlockBaseIndex += GpeBlock->GpeCount;
if (Info->Index < Info->NextBlockBaseIndex)
{

View file

@ -235,7 +235,7 @@ AcpiExDoDebugObject (
AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
AcpiUtDumpBuffer2 (SourceDesc->Buffer.Pointer,
(SourceDesc->Buffer.Length < 256) ?
(SourceDesc->Buffer.Length < 256) ?
SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY);
break;

View file

@ -168,10 +168,10 @@ AcpiExUnlinkMutex (
(ObjDesc->Mutex.Prev)->Mutex.Next = ObjDesc->Mutex.Next;
/*
* Migrate the previous sync level associated with this mutex to the
* previous mutex on the list so that it may be preserved. This handles
* the case where several mutexes have been acquired at the same level,
* but are not released in opposite order.
* Migrate the previous sync level associated with this mutex to
* the previous mutex on the list so that it may be preserved.
* This handles the case where several mutexes have been acquired
* at the same level, but are not released in opposite order.
*/
(ObjDesc->Mutex.Prev)->Mutex.OriginalSyncLevel =
ObjDesc->Mutex.OriginalSyncLevel;
@ -187,8 +187,8 @@ AcpiExUnlinkMutex (
*
* FUNCTION: AcpiExLinkMutex
*
* PARAMETERS: ObjDesc - The mutex to be linked
* Thread - Current executing thread object
* PARAMETERS: ObjDesc - The mutex to be linked
* Thread - Current executing thread object
*
* RETURN: None
*
@ -228,9 +228,9 @@ AcpiExLinkMutex (
*
* FUNCTION: AcpiExAcquireMutexObject
*
* PARAMETERS: TimeDesc - Timeout in milliseconds
* PARAMETERS: Timeout - Timeout in milliseconds
* ObjDesc - Mutex object
* Thread - Current thread state
* ThreadId - Current thread state
*
* RETURN: Status
*
@ -337,11 +337,12 @@ AcpiExAcquireMutex (
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Must have a valid thread ID */
/* Must have a valid thread state struct */
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot acquire Mutex [%4.4s], null thread info",
ACPI_ERROR ((AE_INFO,
"Cannot acquire Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@ -488,7 +489,8 @@ AcpiExReleaseMutex (
if (!OwnerThread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], not acquired",
ACPI_ERROR ((AE_INFO,
"Cannot release Mutex [%4.4s], not acquired",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_MUTEX_NOT_ACQUIRED);
}
@ -497,7 +499,8 @@ AcpiExReleaseMutex (
if (!WalkState->Thread)
{
ACPI_ERROR ((AE_INFO, "Cannot release Mutex [%4.4s], null thread info",
ACPI_ERROR ((AE_INFO,
"Cannot release Mutex [%4.4s], null thread info",
AcpiUtGetNodeName (ObjDesc->Mutex.Node)));
return_ACPI_STATUS (AE_AML_INTERNAL);
}
@ -553,6 +556,7 @@ AcpiExReleaseMutex (
OwnerThread->CurrentSyncLevel = PreviousSyncLevel;
}
return_ACPI_STATUS (Status);
}
@ -561,7 +565,7 @@ AcpiExReleaseMutex (
*
* FUNCTION: AcpiExReleaseAllMutexes
*
* PARAMETERS: Thread - Current executing thread object
* PARAMETERS: Thread - Current executing thread object
*
* RETURN: Status
*
@ -620,5 +624,3 @@ AcpiExReleaseAllMutexes (
Thread->CurrentSyncLevel = ObjDesc->Mutex.OriginalSyncLevel;
}
}

View file

@ -206,33 +206,6 @@ AcpiExOpcode_2A_0T_0R (
break;
}
#ifdef ACPI_GPE_NOTIFY_CHECK
/*
* GPE method wake/notify check. Here, we want to ensure that we
* don't receive any "DeviceWake" Notifies from a GPE _Lxx or _Exx
* GPE method during system runtime. If we do, the GPE is marked
* as "wake-only" and disabled.
*
* 1) Is the Notify() value == DeviceWake?
* 2) Is this a GPE deferred method? (An _Lxx or _Exx method)
* 3) Did the original GPE happen at system runtime?
* (versus during wake)
*
* If all three cases are true, this is a wake-only GPE that should
* be disabled at runtime.
*/
if (Value == 2) /* DeviceWake */
{
Status = AcpiEvCheckForWakeOnlyGpe (WalkState->GpeEventInfo);
if (ACPI_FAILURE (Status))
{
/* AE_WAKE_ONLY_GPE only error, means ignore this notify */
return_ACPI_STATUS (AE_OK)
}
}
#endif
/*
* Dispatch the notify to the appropriate handler
* NOTE: the request is queued for execution after this method

View file

@ -608,8 +608,10 @@ AcpiExDataTableSpaceHandler (
ACPI_FUNCTION_TRACE (ExDataTableSpaceHandler);
/* Perform the memory read or write */
/*
* Perform the memory read or write. The BitWidth was already
* validated.
*/
switch (Function)
{
case ACPI_READ:
@ -619,9 +621,14 @@ AcpiExDataTableSpaceHandler (
break;
case ACPI_WRITE:
ACPI_MEMCPY (ACPI_PHYSADDR_TO_PTR (Address), ACPI_CAST_PTR (char, Value),
ACPI_DIV_8 (BitWidth));
break;
default:
return_ACPI_STATUS (AE_SUPPORT);
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
return_ACPI_STATUS (AE_OK);

View file

@ -171,13 +171,11 @@ AcpiEvQueueNotifyRequest (
*/
ACPI_STATUS
AcpiEvUpdateGpeEnableMasks (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
UINT8 Type);
ACPI_GPE_EVENT_INFO *GpeEventInfo);
ACPI_STATUS
AcpiEvEnableGpe (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
BOOLEAN WriteToHardware);
ACPI_GPE_EVENT_INFO *GpeEventInfo);
ACPI_STATUS
AcpiEvDisableGpe (
@ -188,6 +186,11 @@ AcpiEvGetGpeEventInfo (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber);
ACPI_GPE_EVENT_INFO *
AcpiEvLowGetGpeInfo (
UINT32 GpeNumber,
ACPI_GPE_BLOCK_INFO *GpeBlock);
/*
* evgpeblk
@ -234,15 +237,6 @@ UINT32
AcpiEvGpeDetect (
ACPI_GPE_XRUPT_INFO *GpeXruptList);
ACPI_STATUS
AcpiEvSetGpeType (
ACPI_GPE_EVENT_INFO *GpeEventInfo,
UINT8 Type);
ACPI_STATUS
AcpiEvCheckForWakeOnlyGpe (
ACPI_GPE_EVENT_INFO *GpeEventInfo);
ACPI_STATUS
AcpiEvGpeInitialize (
void);

View file

@ -162,7 +162,7 @@
#define AE_NO_GLOBAL_LOCK (ACPI_STATUS) (0x0017 | AE_CODE_ENVIRONMENTAL)
#define AE_ABORT_METHOD (ACPI_STATUS) (0x0018 | AE_CODE_ENVIRONMENTAL)
#define AE_SAME_HANDLER (ACPI_STATUS) (0x0019 | AE_CODE_ENVIRONMENTAL)
#define AE_WAKE_ONLY_GPE (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
#define AE_NO_HANDLER (ACPI_STATUS) (0x001A | AE_CODE_ENVIRONMENTAL)
#define AE_OWNER_ID_LIMIT (ACPI_STATUS) (0x001B | AE_CODE_ENVIRONMENTAL)
#define AE_CODE_ENV_MAX 0x001B

View file

@ -191,6 +191,14 @@ UINT8 ACPI_INIT_GLOBAL (AcpiGbl_UseDefaultRegisterWidths, TRUE);
*/
UINT8 ACPI_INIT_GLOBAL (AcpiGbl_EnableAmlDebugObject, FALSE);
/*
* Optionally copy the entire DSDT to local memory (instead of simply
* mapping it.) There are some BIOSs that corrupt or replace the original
* DSDT, creating the need for this option. Default is FALSE, do not copy
* the DSDT.
*/
UINT8 ACPI_INIT_GLOBAL (AcpiGbl_CopyDsdtLocally, FALSE);
/* AcpiGbl_FADT is a local copy of the FADT, converted to a common format. */
@ -223,6 +231,11 @@ ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1aEnable;
ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bStatus;
ACPI_EXTERN ACPI_GENERIC_ADDRESS AcpiGbl_XPm1bEnable;
/* DSDT information. Used to check for DSDT corruption */
ACPI_EXTERN ACPI_TABLE_HEADER *AcpiGbl_DSDT;
ACPI_EXTERN ACPI_TABLE_HEADER AcpiGbl_OriginalDsdtHeader;
/*
* Handle both ACPI 1.0 and ACPI 2.0 Integer widths. The integer width is
* determined by the revision of the DSDT: If the DSDT revision is less than

View file

@ -561,6 +561,8 @@ typedef struct acpi_gpe_event_info
struct acpi_gpe_register_info *RegisterInfo; /* Backpointer to register info */
UINT8 Flags; /* Misc info about this GPE */
UINT8 GpeNumber; /* This GPE */
UINT8 RuntimeCount; /* References to a run GPE */
UINT8 WakeupCount; /* References to a wake GPE */
} ACPI_GPE_EVENT_INFO;
@ -590,6 +592,7 @@ typedef struct acpi_gpe_block_info
ACPI_GPE_EVENT_INFO *EventInfo; /* One for each GPE */
ACPI_GENERIC_ADDRESS BlockAddress; /* Base address of the block */
UINT32 RegisterCount; /* Number of register pairs in block */
UINT16 GpeCount; /* Number of individual GPEs in block */
UINT8 BlockBaseNumber;/* Base GPE number for this block */
} ACPI_GPE_BLOCK_INFO;

View file

@ -120,7 +120,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20100304
#define ACPI_CA_VERSION 0x20100331
#include <contrib/dev/acpica/include/actypes.h>
#include <contrib/dev/acpica/include/actbl.h>
@ -146,6 +146,7 @@ extern UINT8 AcpiGbl_UseDefaultRegisterWidths;
extern ACPI_NAME AcpiGbl_TraceMethodName;
extern UINT32 AcpiGbl_TraceFlags;
extern UINT8 AcpiGbl_EnableAmlDebugObject;
extern UINT8 AcpiGbl_CopyDsdtLocally;
/*
@ -463,34 +464,32 @@ AcpiGetEventStatus (
* GPE Interfaces
*/
ACPI_STATUS
AcpiSetGpeType (
AcpiSetGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT8 Type);
UINT8 Action);
ACPI_STATUS
AcpiEnableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags);
UINT8 GpeType);
ACPI_STATUS
AcpiDisableGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags);
UINT8 GpeType);
ACPI_STATUS
AcpiClearGpe (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags);
UINT32 GpeNumber);
ACPI_STATUS
AcpiGetGpeStatus (
ACPI_HANDLE GpeDevice,
UINT32 GpeNumber,
UINT32 Flags,
ACPI_EVENT_STATUS *EventStatus);
ACPI_STATUS

View file

@ -230,6 +230,14 @@ AcpiTbVerifyChecksum (
ACPI_TABLE_HEADER *Table,
UINT32 Length);
void
AcpiTbCheckDsdtHeader (
void);
ACPI_TABLE_HEADER *
AcpiTbCopyDsdt (
UINT32 TableIndex);
void
AcpiTbInstallTable (
ACPI_PHYSICAL_ADDRESS Address,

View file

@ -742,53 +742,42 @@ typedef UINT32 ACPI_EVENT_STATUS;
#define ACPI_GPE_MAX 0xFF
#define ACPI_NUM_GPE 256
/* Actions for AcpiSetGpe */
#define ACPI_GPE_ENABLE 0
#define ACPI_GPE_DISABLE 1
/* GpeTypes for AcpiEnableGpe and AcpiDisableGpe */
#define ACPI_GPE_TYPE_WAKE (UINT8) 0x01
#define ACPI_GPE_TYPE_RUNTIME (UINT8) 0x02
#define ACPI_GPE_TYPE_WAKE_RUN (UINT8) 0x03
/*
* GPE info flags - Per GPE
* +-+-+-+---+---+-+
* |7|6|5|4:3|2:1|0|
* +-+-+-+---+---+-+
* | | | | | |
* | | | | | +--- Interrupt type: Edge or Level Triggered
* | | | | +--- Type: Wake-only, Runtime-only, or wake/runtime
* | | | +--- Type of dispatch -- to method, handler, or none
* | | +--- Enabled for runtime?
* | +--- Enabled for wake?
* +--- Unused
* +-------+---+-+-+
* | 7:4 |3:2|1|0|
* +-------+---+-+-+
* | | | |
* | | | +--- Interrupt type: edge or level triggered
* | | +----- GPE can wake the system
* | +-------- Type of dispatch:to method, handler, or none
* +-------------- <Reserved>
*/
#define ACPI_GPE_XRUPT_TYPE_MASK (UINT8) 0x01
#define ACPI_GPE_LEVEL_TRIGGERED (UINT8) 0x01
#define ACPI_GPE_EDGE_TRIGGERED (UINT8) 0x00
#define ACPI_GPE_TYPE_MASK (UINT8) 0x06
#define ACPI_GPE_TYPE_WAKE_RUN (UINT8) 0x06
#define ACPI_GPE_TYPE_WAKE (UINT8) 0x02
#define ACPI_GPE_TYPE_RUNTIME (UINT8) 0x04 /* Default */
#define ACPI_GPE_CAN_WAKE (UINT8) 0x02
#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x18
#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x08
#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x10
#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00 /* Default */
#define ACPI_GPE_RUN_ENABLE_MASK (UINT8) 0x20
#define ACPI_GPE_RUN_ENABLED (UINT8) 0x20
#define ACPI_GPE_RUN_DISABLED (UINT8) 0x00 /* Default */
#define ACPI_GPE_WAKE_ENABLE_MASK (UINT8) 0x40
#define ACPI_GPE_WAKE_ENABLED (UINT8) 0x40
#define ACPI_GPE_WAKE_DISABLED (UINT8) 0x00 /* Default */
#define ACPI_GPE_ENABLE_MASK (UINT8) 0x60 /* Both run/wake */
#define ACPI_GPE_DISPATCH_MASK (UINT8) 0x0C
#define ACPI_GPE_DISPATCH_HANDLER (UINT8) 0x04
#define ACPI_GPE_DISPATCH_METHOD (UINT8) 0x08
#define ACPI_GPE_DISPATCH_NOT_USED (UINT8) 0x00
/*
* Flags for GPE and Lock interfaces
*/
#define ACPI_EVENT_WAKE_ENABLE 0x2 /* AcpiGpeEnable */
#define ACPI_EVENT_WAKE_DISABLE 0x2 /* AcpiGpeDisable */
#define ACPI_NOT_ISR 0x1
#define ACPI_ISR 0x0

View file

@ -114,7 +114,7 @@
*****************************************************************************/
#ifndef __ACFREEBSD_H__
#define __ACFREEBSD_H__
#define __ACFREEBSD_H__
/* FreeBSD uses GCC */
@ -123,11 +123,11 @@
#include <sys/types.h>
#include <machine/acpica_machdep.h>
#define ACPI_UINTPTR_T uintptr_t
#define ACPI_UINTPTR_T uintptr_t
#define ACPI_USE_DO_WHILE_0
#define ACPI_USE_LOCAL_CACHE
#define ACPI_USE_SYSTEM_CLIBRARY
#define ACPI_USE_DO_WHILE_0
#define ACPI_USE_LOCAL_CACHE
#define ACPI_USE_SYSTEM_CLIBRARY
#ifdef _KERNEL
@ -139,18 +139,18 @@
#include "opt_acpi.h"
#define ACPI_THREAD_ID lwpid_t
#define ACPI_MUTEX_TYPE ACPI_OSL_MUTEX
#define ACPI_THREAD_ID lwpid_t
#define ACPI_MUTEX_TYPE ACPI_OSL_MUTEX
#ifdef ACPI_DEBUG
#define ACPI_DEBUG_OUTPUT /* for backward compatibility */
#define ACPI_DISASSEMBLER
#define ACPI_DEBUG_OUTPUT /* for backward compatibility */
#define ACPI_DISASSEMBLER
#endif
#ifdef ACPI_DEBUG_OUTPUT
#include "opt_ddb.h"
#ifdef DDB
#define ACPI_DEBUGGER
#define ACPI_DEBUGGER
#endif /* DDB */
#endif /* ACPI_DEBUG_OUTPUT */
@ -158,7 +158,7 @@
#undef DEBUGGER_THREADING
#endif /* DEBUGGER_THREADING */
#define DEBUGGER_THREADING 0 /* integrated with DDB */
#define DEBUGGER_THREADING 0 /* integrated with DDB */
#else /* _KERNEL */
@ -166,12 +166,12 @@
#include <ctype.h>
#endif
#define ACPI_THREAD_ID pthread_t
#define ACPI_THREAD_ID pthread_t
#define ACPI_USE_STANDARD_HEADERS
#define ACPI_USE_STANDARD_HEADERS
#define ACPI_FLUSH_CPU_CACHE()
#define __cdecl
#define ACPI_FLUSH_CPU_CACHE()
#define __cdecl
#endif /* _KERNEL */

View file

@ -120,6 +120,7 @@
#include <contrib/dev/acpica/include/acparser.h>
#include <contrib/dev/acpica/include/acdispat.h>
#include <contrib/dev/acpica/include/acinterp.h>
#include <contrib/dev/acpica/include/actables.h>
#include <contrib/dev/acpica/include/amlcode.h>
@ -334,6 +335,10 @@ AcpiPsExecuteMethod (
ACPI_FUNCTION_TRACE (PsExecuteMethod);
/* Quick validation of DSDT header */
AcpiTbCheckDsdtHeader ();
/* Validate the Info and method Node */
if (!Info || !Info->ResolvedNode)

View file

@ -393,6 +393,88 @@ AcpiTbChecksum (
}
/*******************************************************************************
*
* FUNCTION: AcpiTbCheckDsdtHeader
*
* PARAMETERS: None
*
* RETURN: None
*
* DESCRIPTION: Quick compare to check validity of the DSDT. This will detect
* if the DSDT has been replaced from outside the OS and/or if
* the DSDT header has been corrupted.
*
******************************************************************************/
void
AcpiTbCheckDsdtHeader (
void)
{
/* Compare original length and checksum to current values */
if (AcpiGbl_OriginalDsdtHeader.Length != AcpiGbl_DSDT->Length ||
AcpiGbl_OriginalDsdtHeader.Checksum != AcpiGbl_DSDT->Checksum)
{
ACPI_ERROR ((AE_INFO,
"The DSDT has been corrupted or replaced - old, new headers below"));
AcpiTbPrintTableHeader (0, &AcpiGbl_OriginalDsdtHeader);
AcpiTbPrintTableHeader (0, AcpiGbl_DSDT);
/* Disable further error messages */
AcpiGbl_OriginalDsdtHeader.Length = AcpiGbl_DSDT->Length;
AcpiGbl_OriginalDsdtHeader.Checksum = AcpiGbl_DSDT->Checksum;
}
}
/*******************************************************************************
*
* FUNCTION: AcpiTbCopyDsdt
*
* PARAMETERS: TableDesc - Installed table to copy
*
* RETURN: None
*
* DESCRIPTION: Implements a subsystem option to copy the DSDT to local memory.
* Some very bad BIOSs are known to either corrupt the DSDT or
* install a new, bad DSDT. This copy works around the problem.
*
******************************************************************************/
ACPI_TABLE_HEADER *
AcpiTbCopyDsdt (
UINT32 TableIndex)
{
ACPI_TABLE_HEADER *NewTable;
ACPI_TABLE_DESC *TableDesc;
TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex];
NewTable = ACPI_ALLOCATE (TableDesc->Length);
if (!NewTable)
{
ACPI_ERROR ((AE_INFO, "Could not copy DSDT of length 0x%X",
TableDesc->Length));
return (NULL);
}
ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length);
AcpiTbDeleteTable (TableDesc);
TableDesc->Pointer = NewTable;
TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED;
ACPI_INFO ((AE_INFO,
"Forced DSDT copy: length 0x%05X copied locally, original unmapped",
NewTable->Length));
return (NewTable);
}
/*******************************************************************************
*
* FUNCTION: AcpiTbInstallTable

View file

@ -265,6 +265,7 @@ AcpiReallocateRootTable (
{
ACPI_TABLE_DESC *Tables;
ACPI_SIZE NewSize;
ACPI_SIZE CurrentSize;
ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
@ -279,9 +280,15 @@ AcpiReallocateRootTable (
return_ACPI_STATUS (AE_SUPPORT);
}
NewSize = ((ACPI_SIZE) AcpiGbl_RootTableList.Count +
ACPI_ROOT_TABLE_SIZE_INCREMENT) *
sizeof (ACPI_TABLE_DESC);
/*
* Get the current size of the root table and add the default
* increment to create the new table size.
*/
CurrentSize = (ACPI_SIZE)
AcpiGbl_RootTableList.Count * sizeof (ACPI_TABLE_DESC);
NewSize = CurrentSize +
(ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC));
/* Create new array and copy the old array */
@ -291,10 +298,16 @@ AcpiReallocateRootTable (
return_ACPI_STATUS (AE_NO_MEMORY);
}
ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, NewSize);
ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize);
AcpiGbl_RootTableList.Size = AcpiGbl_RootTableList.Count;
/*
* Update the root table descriptor. The new size will be the current
* number of tables plus the increment, independent of the reserved
* size of the original table list.
*/
AcpiGbl_RootTableList.Tables = Tables;
AcpiGbl_RootTableList.Size =
AcpiGbl_RootTableList.Count + ACPI_ROOT_TABLE_SIZE_INCREMENT;
AcpiGbl_RootTableList.Flags =
ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE;
@ -534,6 +547,7 @@ AcpiTbLoadNamespace (
{
ACPI_STATUS Status;
UINT32 i;
ACPI_TABLE_HEADER *NewDsdt;
ACPI_FUNCTION_TRACE (TbLoadNamespace);
@ -542,30 +556,50 @@ AcpiTbLoadNamespace (
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
/*
* Load the namespace. The DSDT is required, but any SSDT and PSDT tables
* are optional.
* Load the namespace. The DSDT is required, but any SSDT and
* PSDT tables are optional. Verify the DSDT.
*/
if (!AcpiGbl_RootTableList.Count ||
!ACPI_COMPARE_NAME (
&(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature),
ACPI_SIG_DSDT) ||
ACPI_FAILURE (AcpiTbVerifyTable (
ACPI_FAILURE (AcpiTbVerifyTable (
&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT])))
{
Status = AE_NO_ACPI_TABLES;
goto UnlockAndExit;
}
/* A valid DSDT is required */
/*
* Save the DSDT pointer for simple access. This is the mapped memory
* address. We must take care here because the address of the .Tables
* array can change dynamically as tables are loaded at run-time. Note:
* .Pointer field is not validated until after call to AcpiTbVerifyTable.
*/
AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer;
Status = AcpiTbVerifyTable (
&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]);
if (ACPI_FAILURE (Status))
/*
* Optionally copy the entire DSDT to local memory (instead of simply
* mapping it.) There are some BIOSs that corrupt or replace the original
* DSDT, creating the need for this option. Default is FALSE, do not copy
* the DSDT.
*/
if (AcpiGbl_CopyDsdtLocally)
{
Status = AE_NO_ACPI_TABLES;
goto UnlockAndExit;
NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT);
if (NewDsdt)
{
AcpiGbl_DSDT = NewDsdt;
}
}
/*
* Save the original DSDT header for detection of table corruption
* and/or replacement of the DSDT from outside the OS.
*/
ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT,
sizeof (ACPI_TABLE_HEADER));
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
/* Load and parse tables */

View file

@ -916,6 +916,7 @@ AcpiUtInitGlobals (
/* Miscellaneous variables */
AcpiGbl_DSDT = NULL;
AcpiGbl_CmSingleStep = FALSE;
AcpiGbl_DbTerminateThreads = FALSE;
AcpiGbl_Shutdown = FALSE;

View file

@ -1,39 +1,39 @@
Copyright (c) 2006-2009, Intel Corporation.
Copyright (c) 2006-2010, Intel Corporation.
All rights reserved.
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
* Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Intel Corporation nor the names of its suppliers
may be used to endorse or promote products derived from this software
without specific prior written permission.
* No reverse engineering, decompilation, or disassembly of this software
* Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Intel Corporation nor the names of its suppliers
may be used to endorse or promote products derived from this software
without specific prior written permission.
* No reverse engineering, decompilation, or disassembly of this software
is permitted.
Limited patent license. Intel Corporation grants a world-wide,
royalty-free, non-exclusive license under patents it now or hereafter
owns or controls to make, have made, use, import, offer to sell and
sell ("Utilize") this software, but solely to the extent that any
such patent is necessary to Utilize the software alone, or in
combination with an operating system licensed under an approved Open
Source license as listed by the Open Source Initiative at
http://opensource.org/licenses. The patent license shall not apply to
any other combinations which include this software. No hardware per
Limited patent license. Intel Corporation grants a world-wide,
royalty-free, non-exclusive license under patents it now or hereafter
owns or controls to make, have made, use, import, offer to sell and
sell ("Utilize") this software, but solely to the extent that any
such patent is necessary to Utilize the software alone, or in
combination with an operating system licensed under an approved Open
Source license as listed by the Open Source Initiative at
http://opensource.org/licenses. The patent license shall not apply to
any other combinations which include this software. No hardware per
se is licensed hereunder.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
COPYRIGHT OWNER 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.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1880,7 +1880,7 @@ aac_init(struct aac_softc *sc)
ip->InitFlags = 0;
if (sc->flags & AAC_FLAGS_NEW_COMM) {
ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED;
ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
device_printf(sc->aac_dev, "New comm. interface enabled\n");
}
@ -2004,7 +2004,7 @@ aac_setup_intr(struct aac_softc *sc)
}
if (sc->flags & AAC_FLAGS_NEW_COMM) {
if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
INTR_MPSAFE|INTR_TYPE_BIO, NULL,
INTR_MPSAFE|INTR_TYPE_BIO, NULL,
aac_new_intr, sc, &sc->aac_intr)) {
device_printf(sc->aac_dev, "can't set up interrupt\n");
return (EINVAL);

View file

@ -395,7 +395,7 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
srb->cdb_len);
/* Set command */
fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ?
fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ?
ScsiPortCommandU64 : ScsiPortCommand;
/* Map the s/g list. XXX 32bit addresses only! */
@ -512,7 +512,7 @@ aac_cam_complete(struct aac_command *cm)
scsi_sense_len = sizeof(struct scsi_sense_data);
bzero(&ccb->csio.sense_data, scsi_sense_len);
sense_len = (srbr->sense_len >
sense_len = (srbr->sense_len >
scsi_sense_len) ? scsi_sense_len :
srbr->sense_len;
bcopy(&srbr->sense[0], &ccb->csio.sense_data,

View file

@ -62,62 +62,62 @@ aac_print_queues(struct aac_softc *sc)
device_printf(sc->aac_dev, "FIB queue header at %p queues at %p\n",
&sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
&sc->aac_queues->qt_HostNormCmdQueue[0]);
device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
device_printf(sc->aac_dev, "HOST_NORM_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
AAC_CONSUMER_INDEX],
AAC_CONSUMER_INDEX],
AAC_HOST_NORM_CMD_ENTRIES);
device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
device_printf(sc->aac_dev, "HOST_HIGH_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
AAC_CONSUMER_INDEX],
AAC_CONSUMER_INDEX],
AAC_HOST_HIGH_CMD_ENTRIES);
device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
device_printf(sc->aac_dev, "ADAP_NORM_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
AAC_CONSUMER_INDEX],
AAC_CONSUMER_INDEX],
AAC_ADAP_NORM_CMD_ENTRIES);
device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
device_printf(sc->aac_dev, "ADAP_HIGH_CMD %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
AAC_CONSUMER_INDEX],
AAC_CONSUMER_INDEX],
AAC_ADAP_HIGH_CMD_ENTRIES);
device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_HOST_NORM_RESP_ENTRIES);
device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_HOST_HIGH_RESP_ENTRIES);
device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_ADAP_NORM_RESP_ENTRIES);
device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
AAC_PRODUCER_INDEX],
sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
AAC_CONSUMER_INDEX],
AAC_ADAP_HIGH_RESP_ENTRIES);
device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
device_printf(sc->aac_dev, "AACQ_FREE %d/%d\n",
sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
device_printf(sc->aac_dev, "AACQ_BIO %d/%d\n",
sc->aac_qstat[AACQ_BIO].q_length, sc->aac_qstat[AACQ_BIO].q_max);
device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
device_printf(sc->aac_dev, "AACQ_READY %d/%d\n",
sc->aac_qstat[AACQ_READY].q_length,
sc->aac_qstat[AACQ_READY].q_max);
device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
device_printf(sc->aac_dev, "AACQ_BUSY %d/%d\n",
sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
}
@ -225,8 +225,8 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
if (br->Command == VM_CtBlockRead) {
device_printf(sc->aac_dev,
" BlockRead: container %d 0x%x/%d\n",
br->ContainerId, br->BlockNumber,
" BlockRead: container %d 0x%x/%d\n",
br->ContainerId, br->BlockNumber,
br->ByteCount);
sg = &br->SgMap;
}
@ -234,7 +234,7 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
device_printf(sc->aac_dev,
" BlockWrite: container %d 0x%x/%d "
"(%s)\n", bw->ContainerId,
bw->BlockNumber, bw->ByteCount,
bw->BlockNumber, bw->ByteCount,
bw->Stable == CSTABLE ? "stable" :
"unstable");
sg = &bw->SgMap;
@ -267,7 +267,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
switch(aif->data.EN.type) {
case AifEnGeneric: /* Generic notification */
device_printf(sc->aac_dev, "(Generic) %.*s\n",
device_printf(sc->aac_dev, "(Generic) %.*s\n",
(int)sizeof(aif->data.EN.data.EG),
aif->data.EN.data.EG.text);
break;
@ -281,21 +281,21 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
case AifEnContainerChange: /* Adapter specific container
* configuration change */
device_printf(sc->aac_dev, "(ContainerChange) "
"container %d,%d\n",
aif->data.EN.data.ECC.container[0],
"container %d,%d\n",
aif->data.EN.data.ECC.container[0],
aif->data.EN.data.ECC.container[1]);
break;
case AifEnDeviceFailure: /* SCSI device failed */
device_printf(sc->aac_dev, "(DeviceFailure) "
"handle %d\n",
"handle %d\n",
aif->data.EN.data.EDF.deviceHandle);
break;
case AifEnMirrorFailover: /* Mirror failover started */
device_printf(sc->aac_dev, "(MirrorFailover) "
"container %d failed, "
"migrating from slice %d to %d\n",
aif->data.EN.data.EMF.container,
aif->data.EN.data.EMF.failedSlice,
aif->data.EN.data.EMF.container,
aif->data.EN.data.EMF.failedSlice,
aif->data.EN.data.EMF.creatingSlice);
break;
case AifEnContainerEvent: /* Significant container
@ -325,7 +325,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
device_printf(sc->aac_dev, "(EnclosureManagement) "
"EMPID %d unit %d "
"event %d\n", aif->data.EN.data.EEE.empID,
aif->data.EN.data.EEE.unitID,
aif->data.EN.data.EEE.unitID,
aif->data.EN.data.EEE.eventType);
break;
case AifEnBatteryEvent: /* Significant NV battery
@ -348,14 +348,14 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
break;
case AifEnClusterEvent: /* Some cluster event */
device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
aif->data.EN.data.ECLE.eventType);
break;
case AifEnDiskSetEvent: /* A disk set event occured. */
device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
"diskset %jd creator %jd\n",
aif->data.EN.data.EDS.eventType,
(intmax_t)aif->data.EN.data.EDS.DsNum,
aif->data.EN.data.EDS.eventType,
(intmax_t)aif->data.EN.data.EDS.DsNum,
(intmax_t)aif->data.EN.data.EDS.CreatorId);
break;
case AifDenMorphComplete: /* A morph operation
@ -392,7 +392,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
}
device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
aif->seqNumber, status,
aif->seqNumber, status,
aif->data.PR[0].currentTick,
aif->data.PR[0].finalTick);
switch(aif->data.PR[0].jd.type) {
@ -418,12 +418,12 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
break;
case AifJobCtrZero: /* Container clear operation */
device_printf(sc->aac_dev,
"(ContainerZero) container %d\n",
"(ContainerZero) container %d\n",
aif->data.PR[0].jd.client.container.src);
break;
case AifJobCtrCopy: /* Container copy operation */
device_printf(sc->aac_dev,
"(ContainerCopy) container %d to %d\n",
"(ContainerCopy) container %d to %d\n",
aif->data.PR[0].jd.client.container.src,
aif->data.PR[0].jd.client.container.dst);
break;
@ -456,12 +456,12 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
case AifJobCtrScrubRaid5: /* Container Scrub Raid5
* operation */
device_printf(sc->aac_dev,
"(ContainerScrubRaid5) container %d\n",
"(ContainerScrubRaid5) container %d\n",
aif->data.PR[0].jd.client.container.src);
break;
case AifJobCtrMorph: /* Container morph operation */
device_printf(sc->aac_dev,
"(ContainerMorph) container %d\n",
"(ContainerMorph) container %d\n",
aif->data.PR[0].jd.client.container.src);
/* XXX two containers? */
break;
@ -476,13 +476,13 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
case AifJobCtrRebuildMirror: /* Container Rebuild Mirror
* operation */
device_printf(sc->aac_dev,
"(ContainerRebuildMirror) container "
"(ContainerRebuildMirror) container "
"%d\n",
aif->data.PR[0].jd.client.container.src);
break;
case AifJobCtrCrazyCache: /* crazy cache */
device_printf(sc->aac_dev,
"(ContainerCrazyCache) container %d\n",
"(ContainerCrazyCache) container %d\n",
aif->data.PR[0].jd.client.container.src);
/* XXX two containers? */
break;

View file

@ -87,7 +87,7 @@ DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
/*
* Handle open from generic layer.
*
* This is called by the diskslice code on first open in order to get the
* This is called by the diskslice code on first open in order to get the
* basic device geometry paramters.
*/
static int

View file

@ -177,7 +177,7 @@ struct aac_ident
{0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
"IBM ServeRAID 8i"},
{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
"Adaptec SAS RAID 4000SAS"},
"Adaptec RAID 4000"},
{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
"Adaptec SAS RAID 4800SAS"},
{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
@ -353,7 +353,7 @@ aac_pci_attach(device_t dev)
/* assume failure is 'not configured' */
error = ENXIO;
/*
/*
* Verify that the adapter is correctly set up in PCI space.
*/
command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
@ -401,7 +401,7 @@ aac_pci_attach(device_t dev)
/*
* Allocate the parent bus DMA tag appropriate for our PCI interface.
*
*
* Note that some of these controllers are 64-bit capable.
*/
if (bus_dma_tag_create(NULL, /* parent */
@ -419,7 +419,7 @@ aac_pci_attach(device_t dev)
goto out;
}
/*
/*
* Detect the hardware interface version, set up the bus interface
* indirection.
*/

View file

@ -34,40 +34,42 @@
* relevant only to FSA operations.
*/
static struct aac_code_lookup aac_command_status_table[] = {
{"OK", 0},
{"operation not permitted", 1},
{"not found", 2},
{"I/O error", 5},
{"device not configured", 6},
{"too big", 7},
{"permission denied", 13},
{"file exists", 17},
{"cross-device link", 18},
{"operation not supported by device", 19},
{"not a directory", 20},
{"is a directory", 21},
{"invalid argument", 22},
{"file too large", 27},
{"no space on device", 28},
{"readonly filesystem", 30},
{"too many links", 31},
{"operation would block", 35},
{"file name too long", 63},
{"directory not empty", 66},
{"quota exceeded", 69},
{"stale file handle", 70},
{"too many levels of remote in path", 71},
{"bad file handle", 10001},
{"not sync", 10002},
{"bad cookie", 10003},
{"operation not supported", 10004},
{"too small", 10005},
{"server fault", 10006},
{"bad type", 10007},
{"jukebox", 10008},
{"not mounted", 10009},
{"in maintenance mode", 10010},
{"stale ACL", 10011},
{"OK", ST_OK},
{"operation not permitted", ST_PERM},
{"not found", ST_NOENT},
{"I/O error", ST_IO},
{"device not configured", ST_NXIO},
{"too big", ST_E2BIG},
{"permission denied", ST_ACCES},
{"file exists", ST_EXIST},
{"cross-device link", ST_XDEV},
{"operation not supported by device", ST_NODEV},
{"not a directory", ST_NOTDIR},
{"is a directory", ST_ISDIR},
{"invalid argument", ST_INVAL},
{"file too large", ST_FBIG},
{"no space on device", ST_NOSPC},
{"readonly filesystem", ST_ROFS},
{"too many links", ST_MLINK},
{"operation would block", ST_WOULDBLOCK},
{"file name too long", ST_NAMETOOLONG},
{"directory not empty", ST_NOTEMPTY},
{"quota exceeded", ST_DQUOT},
{"stale file handle", ST_STALE},
{"too many levels of remote in path", ST_REMOTE},
{"device busy (spinning up)", ST_NOT_READY},
{"bad file handle", ST_BADHANDLE},
{"not sync", ST_NOT_SYNC},
{"bad cookie", ST_BAD_COOKIE},
{"operation not supported", ST_NOTSUPP},
{"too small", ST_TOOSMALL},
{"server fault", ST_SERVERFAULT},
{"bad type", ST_BADTYPE},
{"jukebox", ST_JUKEBOX},
{"not mounted", ST_NOTMOUNTED},
{"in maintenance mode", ST_MAINTMODE},
{"stale ACL", ST_STALEACL},
{"bus reset - command aborted", ST_BUS_RESET},
{NULL, 0},
{"unknown command status", 0}
};

View file

@ -220,20 +220,20 @@ typedef enum {
IsAdapterPaused = 704,
SendHostTime = 705,
RequestSupplementAdapterInfo = 706, /* Supp. Info for set in UCC
* use only if supported
* use only if supported
* (RequestAdapterInfo first) */
LastMiscCommand = 707,
OnLineDiagnostic = 800,
FduAdapterTest = 801,
OnLineDiagnostic = 800,
FduAdapterTest = 801,
RequestCompatibilityId = 802,
AdapterEnvironmentInfo = 803, /* temp. sensors */
NvsramEventLog = 900,
ResetNvsramEventLogPointers = 901,
EnableEventLog = 902,
DisableEventLog = 903,
EncryptedKeyTransportFIB= 904,
KeyableFeaturesFIB= 905
EncryptedKeyTransportFIB= 904,
KeyableFeaturesFIB= 905
} AAC_FibCommands;
/*
@ -283,7 +283,7 @@ typedef enum {
#define AAC_ERROR_FIB_DEALLOCATION_FAILED 0x08
/*
* Adapter Init Structure: this is passed to the adapter with the
* Adapter Init Structure: this is passed to the adapter with the
* AAC_MONKER_INITSTRUCT command to point it at our control structures.
*/
struct aac_adapter_init {
@ -306,7 +306,7 @@ struct aac_adapter_init {
u_int32_t HostElapsedSeconds;
/* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
u_int32_t InitFlags; /* flags for supported features */
#define INITFLAGS_NEW_COMM_SUPPORTED 1
#define AAC_INITFLAGS_NEW_COMM_SUPPORTED 1
u_int32_t MaxIoCommands; /* max outstanding commands */
u_int32_t MaxIoSize; /* largest I/O command */
u_int32_t MaxFibSize; /* largest FIB to adapter */
@ -329,14 +329,14 @@ typedef enum {
CT_MORPH,
CT_PASSTHRU,
CT_RAID4,
CT_RAID10, /* stripe of mirror */
CT_RAID00, /* stripe of stripe */
CT_VOLUME_OF_MIRRORS, /* volume of mirror */
CT_PSEUDO_RAID3, /* really raid4 */
CT_RAID50, /* stripe of raid5 */
CT_RAID5D, /* raid5 distributed hot-sparing */
CT_RAID10, /* stripe of mirror */
CT_RAID00, /* stripe of stripe */
CT_VOLUME_OF_MIRRORS, /* volume of mirror */
CT_PSEUDO_RAID3, /* really raid4 */
CT_RAID50, /* stripe of raid5 */
CT_RAID5D, /* raid5 distributed hot-sparing */
CT_RAID5D0,
CT_RAID1E, /* extended raid1 mirroring */
CT_RAID1E, /* extended raid1 mirroring */
CT_RAID6,
CT_RAID60,
} AAC_FSAVolType;
@ -345,23 +345,23 @@ typedef enum {
* Host-addressable object types
*/
typedef enum {
FT_REG = 1, /* regular file */
FT_DIR, /* directory */
FT_BLK, /* "block" device - reserved */
FT_CHR, /* "character special" device - reserved */
FT_LNK, /* symbolic link */
FT_SOCK, /* socket */
FT_FIFO, /* fifo */
FT_FILESYS, /* ADAPTEC's "FSA"(tm) filesystem */
FT_DRIVE, /* physical disk - addressable in scsi by b/t/l */
FT_SLICE, /* virtual disk - raw volume - slice */
FT_PARTITION, /* FSA partition - carved out of a slice - building
FT_REG = 1, /* regular file */
FT_DIR, /* directory */
FT_BLK, /* "block" device - reserved */
FT_CHR, /* "character special" device - reserved */
FT_LNK, /* symbolic link */
FT_SOCK, /* socket */
FT_FIFO, /* fifo */
FT_FILESYS, /* ADAPTEC's "FSA"(tm) filesystem */
FT_DRIVE, /* physical disk - addressable in scsi by b/t/l */
FT_SLICE, /* virtual disk - raw volume - slice */
FT_PARTITION, /* FSA partition - carved out of a slice - building
* block for containers */
FT_VOLUME, /* Container - Volume Set */
FT_STRIPE, /* Container - Stripe Set */
FT_MIRROR, /* Container - Mirror Set */
FT_RAID5, /* Container - Raid 5 Set */
FT_DATABASE /* Storage object with "foreign" content manager */
FT_VOLUME, /* Container - Volume Set */
FT_STRIPE, /* Container - Stripe Set */
FT_MIRROR, /* Container - Mirror Set */
FT_RAID5, /* Container - Raid 5 Set */
FT_DATABASE /* Storage object with "foreign" content manager */
} AAC_FType;
/*
@ -467,7 +467,7 @@ typedef enum {
CPU_MIPS,
CPU_XSCALE,
CPU__last
} AAC_CpuType;
} AAC_CpuType;
typedef enum {
CPUI960_JX = 1,
@ -544,7 +544,7 @@ typedef enum {
* XXX the aac-2622 with no battery present reports PLATFORM_BAT_OPT_PRESENT
*/
typedef enum
{
{
PLATFORM_BAT_REQ_PRESENT = 1, /* BATTERY REQUIRED AND PRESENT */
PLATFORM_BAT_REQ_NOTPRESENT, /* BATTERY REQUIRED AND NOT PRESENT */
PLATFORM_BAT_OPT_PRESENT, /* BATTERY OPTIONAL AND PRESENT */
@ -552,9 +552,9 @@ typedef enum
PLATFORM_BAT_NOT_SUPPORTED /* BATTERY NOT SUPPORTED */
} AAC_BatteryPlatform;
/*
/*
* options supported by this board
* there has to be a one to one mapping of these defines and the ones in
* there has to be a one to one mapping of these defines and the ones in
* fsaapi.h, search for FSA_SUPPORT_SNAPSHOT
*/
#define AAC_SUPPORTED_SNAPSHOT 0x01
@ -577,24 +577,24 @@ typedef enum
#define AAC_SUPPORTED_64BIT_ARRAYSIZE 0x40000
#define AAC_SUPPORTED_HEAT_SENSOR 0x80000
/*
/*
* Structure used to respond to a RequestAdapterInfo fib.
*/
struct aac_adapter_info {
AAC_Platform PlatformBase; /* adapter type */
AAC_Platform PlatformBase; /* adapter type */
AAC_CpuType CpuArchitecture; /* adapter CPU type */
AAC_CpuSubType CpuVariant; /* adapter CPU subtype */
u_int32_t ClockSpeed; /* adapter CPU clockspeed */
u_int32_t ExecutionMem; /* adapter Execution Memory
AAC_CpuSubType CpuVariant; /* adapter CPU subtype */
u_int32_t ClockSpeed; /* adapter CPU clockspeed */
u_int32_t ExecutionMem; /* adapter Execution Memory
* size */
u_int32_t BufferMem; /* adapter Data Memory */
u_int32_t TotalMem; /* adapter Total Memory */
u_int32_t BufferMem; /* adapter Data Memory */
u_int32_t TotalMem; /* adapter Total Memory */
struct FsaRevision KernelRevision; /* adapter Kernel Software
* Revision */
struct FsaRevision MonitorRevision; /* adapter Monitor/Diagnostic
* Software Revision */
struct FsaRevision HardwareRevision;/* TBD */
struct FsaRevision BIOSRevision; /* adapter BIOS Revision */
struct FsaRevision BIOSRevision; /* adapter BIOS Revision */
u_int32_t ClusteringEnabled;
u_int32_t ClusterChannelMask;
u_int64_t SerialNumber;
@ -604,7 +604,7 @@ struct aac_adapter_info {
AAC_OemFlavor OemVariant;
} __packed;
/*
/*
* Structure used to respond to a RequestSupplementAdapterInfo fib.
*/
struct vpd_info {
@ -692,7 +692,7 @@ struct aac_supplement_adapter_info {
#define AAC_KERNEL_PANIC 0x00000100
/*
* Data types relating to control and monitoring of the NVRAM/WriteCache
* Data types relating to control and monitoring of the NVRAM/WriteCache
* subsystem.
*/
@ -867,7 +867,7 @@ typedef enum {
AifEnGeneric = 1, /* Generic notification */
AifEnTaskComplete, /* Task has completed */
AifEnConfigChange, /* Adapter config change occurred */
AifEnContainerChange, /* Adapter specific container
AifEnContainerChange, /* Adapter specific container
* configuration change */
AifEnDeviceFailure, /* SCSI device failed */
AifEnMirrorFailover, /* Mirror failover started */
@ -881,7 +881,7 @@ typedef enum {
AifEnBatteryEvent, /* Significant NV battery event */
AifEnAddContainer, /* A new container was created. */
AifEnDeleteContainer, /* A container was deleted. */
AifEnSMARTEvent, /* SMART Event */
AifEnSMARTEvent, /* SMART Event */
AifEnBatteryNeedsRecond, /* The battery needs reconditioning */
AifEnClusterEvent, /* Some cluster event */
AifEnDiskSetEvent, /* A disk set event occured. */
@ -967,7 +967,7 @@ struct aac_AifEventNotify {
/*
* Adapter Initiated FIB command structures. Start with the adapter
* initiated FIBs that really come from the adapter, and get responded
* to by the host.
* to by the host.
*/
#define AAC_AIF_REPORT_MAX_SIZE 64
@ -1081,6 +1081,7 @@ typedef enum {
ST_DQUOT = 69,
ST_STALE = 70,
ST_REMOTE = 71,
ST_NOT_READY = 72,
ST_BADHANDLE = 10001,
ST_NOT_SYNC = 10002,
ST_BAD_COOKIE = 10003,
@ -1091,7 +1092,8 @@ typedef enum {
ST_JUKEBOX = 10008,
ST_NOTMOUNTED = 10009,
ST_MAINTMODE = 10010,
ST_STALEACL = 10011
ST_STALEACL = 10011,
ST_BUS_RESET = 20001
} AAC_FSAStatus;
/*
@ -1120,7 +1122,7 @@ typedef enum _VM_COMMANDS {
VM_CtHostRead64,
VM_CtHostWrite64,
VM_DrvErrTblLog, /* drive error table/log type of command */
VM_NameServe64
VM_NameServe64
} AAC_VMCommand;
/*
@ -1526,7 +1528,7 @@ enum {
/*
* The adapter can request the host print a message by setting the
* DB_PRINTF flag in DOORBELL0. The driver responds by collecting the
* message from the printf buffer, clearing the DB_PRINTF flag in
* message from the printf buffer, clearing the DB_PRINTF flag in
* DOORBELL0 and setting it in DOORBELL1.
* (ODBR and IDBR respectively for the i960Rx adapters)
*/

View file

@ -56,7 +56,7 @@
*/
/*
* The firmware interface allows for a 16-bit s/g list length. We limit
* The firmware interface allows for a 16-bit s/g list length. We limit
* ourselves to a reasonable maximum and ensure alignment.
*/
#define AAC_MAXSGENTRIES 64 /* max S/G entries, limit 65535 */
@ -78,7 +78,7 @@
#define AAC_PRINTF_BUFSIZE 256
/*
* We wait this many seconds for the adapter to come ready if it is still
* We wait this many seconds for the adapter to come ready if it is still
* booting
*/
#define AAC_BOOT_TIMEOUT (3 * 60)
@ -126,7 +126,7 @@ struct aac_sim
/*
* Per-disk structure
*/
struct aac_disk
struct aac_disk
{
device_t ad_dev;
struct aac_softc *ad_controller;
@ -216,7 +216,7 @@ struct aac_common {
AAC_QUEUE_ALIGN];
/* buffer for text messages from the controller */
char ac_printf[AAC_PRINTF_BUFSIZE];
char ac_printf[AAC_PRINTF_BUFSIZE];
/* fib for synchronous commands */
struct aac_fib ac_sync_fib;
@ -225,7 +225,7 @@ struct aac_common {
/*
* Interface operations
*/
struct aac_interface
struct aac_interface
{
int (*aif_get_fwstatus)(struct aac_softc *sc);
void (*aif_qnotify)(struct aac_softc *sc, int qbit);
@ -300,7 +300,7 @@ struct aac_fib_context {
/*
* Per-controller structure.
*/
struct aac_softc
struct aac_softc
{
/* bus connections */
device_t aac_dev;
@ -347,7 +347,7 @@ struct aac_softc
struct aac_command *aac_commands;
/* command management */
TAILQ_HEAD(,aac_command) aac_free; /* command structures
TAILQ_HEAD(,aac_command) aac_free; /* command structures
* available for reuse */
TAILQ_HEAD(,aac_command) aac_ready; /* commands on hold for
* controller resources */
@ -416,7 +416,7 @@ struct aac_softc
struct callout aac_daemontime; /* clock daemon callout */
u_int32_t aac_max_fibs; /* max. FIB count */
u_int32_t aac_max_fibs; /* max. FIB count */
u_int32_t aac_max_fibs_alloc; /* max. alloc. per alloc_commands() */
u_int32_t aac_max_fib_size; /* max. FIB size */
u_int32_t aac_sg_tablesize; /* max. sg count from host */
@ -447,7 +447,7 @@ extern void aac_free(struct aac_softc *sc);
extern int aac_attach(struct aac_softc *sc);
extern int aac_detach(device_t dev);
extern int aac_shutdown(device_t dev);
extern int aac_suspend(device_t dev);
extern int aac_suspend(device_t dev);
extern int aac_resume(device_t dev);
extern void aac_new_intr(void *arg);
extern int aac_filter(void *arg);
@ -561,7 +561,7 @@ aac_dequeue_ ## name (struct aac_softc *sc) \
if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) { \
if ((cm->cm_flags & AAC_ON_ ## index) == 0) { \
printf("command %p not in queue, flags = %#x, " \
"bit = %#x\n", cm, cm->cm_flags, \
"bit = %#x\n", cm, cm->cm_flags, \
AAC_ON_ ## index); \
panic("command not in queue"); \
} \

View file

@ -2640,25 +2640,6 @@ acpi_resync_clock(struct acpi_softc *sc)
inittodr(time_second + sc->acpi_sleep_delay);
}
/* Initialize a device's wake GPE. */
int
acpi_wake_init(device_t dev, int type)
{
struct acpi_prw_data prw;
/* Evaluate _PRW to find the GPE. */
if (acpi_parse_prw(acpi_get_handle(dev), &prw) != 0)
return (ENXIO);
/* Set the requested type for the GPE (runtime, wake, or both). */
if (ACPI_FAILURE(AcpiSetGpeType(prw.gpe_handle, prw.gpe_bit, type))) {
device_printf(dev, "set GPE type failed\n");
return (ENXIO);
}
return (0);
}
/* Enable or disable the device's wake GPE. */
int
acpi_wake_set_enable(device_t dev, int enable)
@ -2673,14 +2654,16 @@ acpi_wake_set_enable(device_t dev, int enable)
flags = acpi_get_flags(dev);
if (enable) {
status = AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
status = AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit,
ACPI_GPE_TYPE_WAKE_RUN);
if (ACPI_FAILURE(status)) {
device_printf(dev, "enable wake failed\n");
return (ENXIO);
}
acpi_set_flags(dev, flags | ACPI_FLAG_WAKE_ENABLED);
} else {
status = AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
status = AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit,
ACPI_GPE_TYPE_WAKE);
if (ACPI_FAILURE(status)) {
device_printf(dev, "disable wake failed\n");
return (ENXIO);
@ -2710,7 +2693,7 @@ acpi_wake_sleep_prep(ACPI_HANDLE handle, int sstate)
* and set _PSW.
*/
if (sstate > prw.lowest_wake) {
AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
AcpiDisableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_GPE_TYPE_WAKE);
if (bootverbose)
device_printf(dev, "wake_prep disabled wake for %s (S%d)\n",
acpi_name(handle), sstate);
@ -2747,7 +2730,7 @@ acpi_wake_run_prep(ACPI_HANDLE handle, int sstate)
* clear _PSW and turn off any power resources it used.
*/
if (sstate > prw.lowest_wake) {
AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_NOT_ISR);
AcpiEnableGpe(prw.gpe_handle, prw.gpe_bit, ACPI_GPE_TYPE_WAKE_RUN);
if (bootverbose)
device_printf(dev, "run_prep re-enabled %s\n", acpi_name(handle));
} else {

View file

@ -164,7 +164,6 @@ acpi_button_attach(device_t dev)
}
/* Enable the GPE for wake/runtime. */
acpi_wake_init(dev, ACPI_GPE_TYPE_WAKE_RUN);
acpi_wake_set_enable(dev, 1);
return_VALUE (0);

View file

@ -518,14 +518,8 @@ acpi_ec_attach(device_t dev)
}
/* Enable runtime GPEs for the handler. */
Status = AcpiSetGpeType(sc->ec_gpehandle, sc->ec_gpebit,
ACPI_GPE_TYPE_RUNTIME);
if (ACPI_FAILURE(Status)) {
device_printf(dev, "AcpiSetGpeType failed: %s\n",
AcpiFormatException(Status));
goto error;
}
Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit,
ACPI_GPE_TYPE_RUNTIME);
if (ACPI_FAILURE(Status)) {
device_printf(dev, "AcpiEnableGpe failed: %s\n",
AcpiFormatException(Status));
@ -575,7 +569,7 @@ acpi_ec_shutdown(device_t dev)
/* Disable the GPE so we don't get EC events during shutdown. */
sc = device_get_softc(dev);
AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR);
AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_GPE_TYPE_RUNTIME);
return (0);
}

View file

@ -115,7 +115,6 @@ acpi_lid_attach(device_t dev)
acpi_lid_notify_handler, sc);
/* Enable the GPE for wake/runtime. */
acpi_wake_init(dev, ACPI_GPE_TYPE_WAKE_RUN);
acpi_wake_set_enable(dev, 1);
return (0);

View file

@ -332,7 +332,6 @@ int acpi_ReqSleepState(struct acpi_softc *sc, int state);
int acpi_AckSleepState(struct apm_clone_data *clone, int error);
ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state);
void acpi_resync_clock(struct acpi_softc *sc);
int acpi_wake_init(device_t dev, int type);
int acpi_wake_set_enable(device_t dev, int enable);
int acpi_parse_prw(ACPI_HANDLE h, struct acpi_prw_data *prw);
ACPI_STATUS acpi_Startup(void);

0
sys/dev/ath/ath_hal/ar5416/ar9160.ini Executable file → Normal file
View file

View file

@ -378,8 +378,8 @@ ar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
case HAL_ANT_VARIABLE:
/* Restore original chainmask settings */
/* XXX */
ahp->ah_tx_chainmask = AR5416_DEFAULT_TXCHAINMASK;
ahp->ah_rx_chainmask = AR5416_DEFAULT_RXCHAINMASK;
ahp->ah_tx_chainmask = AR9285_DEFAULT_TXCHAINMASK;
ahp->ah_rx_chainmask = AR9285_DEFAULT_RXCHAINMASK;
break;
}
return AH_TRUE;

View file

@ -3654,8 +3654,14 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m,
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
if (vap->iv_opmode == IEEE80211_M_IBSS &&
vap->iv_state == IEEE80211_S_RUN) {
uint32_t rstamp = sc->sc_lastrs->rs_tstamp;
u_int64_t tsf = ath_extend_tsf(rstamp,
uint32_t rstamp;
uint64_t tsf;
if (sc->sc_lastrs == NULL)
break;
rstamp = sc->sc_lastrs->rs_tstamp;
tsf = ath_extend_tsf(rstamp,
ath_hal_gettsf64(sc->sc_ah));
/*
* Handle ibss merge as needed; check the tsf on the

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -64,8 +64,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_phy.h>
#include <net80211/ieee80211_ratectl.h>
#include <net/bpf.h>
@ -112,9 +112,6 @@ static void bwi_set_channel(struct ieee80211com *);
static void bwi_scan_end(struct ieee80211com *);
static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
static void bwi_updateslot(struct ifnet *);
static struct ieee80211_node *bwi_node_alloc(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
static void bwi_newassoc(struct ieee80211_node *, int);
static int bwi_media_change(struct ifnet *);
static void bwi_calibrate(void *);
@ -525,7 +522,6 @@ bwi_attach(struct bwi_softc *sc)
ic->ic_vap_delete = bwi_vap_delete;
ic->ic_raw_xmit = bwi_raw_xmit;
ic->ic_updateslot = bwi_updateslot;
ic->ic_node_alloc = bwi_node_alloc;
ic->ic_scan_start = bwi_scan_start;
ic->ic_scan_end = bwi_scan_end;
ic->ic_set_channel = bwi_set_channel;
@ -621,10 +617,7 @@ bwi_vap_create(struct ieee80211com *ic,
#if 0
vap->iv_update_beacon = bwi_beacon_update;
#endif
ieee80211_amrr_init(&bvp->bv_amrr, vap,
IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
500 /*ms*/);
ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, bwi_media_change, ieee80211_media_status);
@ -637,7 +630,7 @@ bwi_vap_delete(struct ieee80211vap *vap)
{
struct bwi_vap *bvp = BWI_VAP(vap);
ieee80211_amrr_cleanup(&bvp->bv_amrr);
ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(bvp, M_80211_VAP);
}
@ -1831,7 +1824,7 @@ bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
#endif
if (vap->iv_opmode == IEEE80211_M_STA) {
/* fake a join to init the tx rate */
bwi_newassoc(ni, 1);
ic->ic_newassoc(ni, 1);
}
callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
@ -1842,25 +1835,6 @@ back:
return error;
}
/* ARGUSED */
static struct ieee80211_node *
bwi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
{
struct bwi_node *bn;
bn = malloc(sizeof(struct bwi_node), M_80211_NODE, M_NOWAIT | M_ZERO);
return bn != NULL ? &bn->ni : NULL;
}
static void
bwi_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211vap *vap = ni->ni_vap;
ieee80211_amrr_node_init(&BWI_VAP(vap)->bv_amrr,
&BWI_NODE(ni)->amn, ni);
}
static int
bwi_media_change(struct ifnet *ifp)
{
@ -3012,7 +2986,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
rate = rate_fb = tp->ucastrate;
} else {
rix = ieee80211_amrr_choose(ni, &BWI_NODE(ni)->amn);
rix = ieee80211_ratectl_rate(ni, NULL, pkt_len);
rate = ni->ni_txrate;
if (rix > 0) {
@ -3369,6 +3343,7 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
struct bwi_txbuf *tb;
int ring_idx, buf_idx;
struct ieee80211_node *ni;
struct ieee80211vap *vap;
if (tx_id == 0) {
if_printf(ifp, "%s: zero tx id\n", __func__);
@ -3394,9 +3369,9 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
ni = tb->tb_ni;
if (tb->tb_ni != NULL) {
struct bwi_node *bn = (struct bwi_node *) tb->tb_ni;
const struct bwi_txbuf_hdr *hdr =
mtod(tb->tb_mbuf, const struct bwi_txbuf_hdr *);
vap = ni->ni_vap;
/* NB: update rate control only for unicast frames */
if (hdr->txh_mac_ctrl & htole32(BWI_TXH_MAC_C_ACK)) {
@ -3407,8 +3382,9 @@ _bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
* well so to avoid over-aggressive downshifting we
* treat any number of retries as "1".
*/
ieee80211_amrr_tx_complete(&bn->amn, acked,
data_txcnt > 1);
ieee80211_ratectl_tx_complete(vap, ni,
(data_txcnt > 1) ? IEEE80211_RATECTL_TX_SUCCESS :
IEEE80211_RATECTL_TX_FAILURE, &acked, NULL);
}
/*

View file

@ -533,15 +533,8 @@ struct bwi_rx_radiotap_hdr {
/* TODO: sq */
};
struct bwi_node {
struct ieee80211_node ni; /* must be the first */
struct ieee80211_amrr_node amn;
};
#define BWI_NODE(ni) ((struct bwi_node *)(ni))
struct bwi_vap {
struct ieee80211vap bv_vap;
struct ieee80211_amrr bv_amrr;
int (*bv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};

View file

@ -67,8 +67,8 @@ __FBSDID("$FreeBSD$");
#include <net80211/ieee80211_var.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
#include <net80211/ieee80211_amrr.h>
#include <net80211/ieee80211_phy.h>
#include <net80211/ieee80211_ratectl.h>
#include <dev/bwn/if_bwnreg.h>
#include <dev/bwn/if_bwnvar.h>
@ -180,18 +180,14 @@ static void bwn_addchannels(struct ieee80211_channel [], int, int *,
const struct bwn_channelinfo *, int);
static int bwn_raw_xmit(struct ieee80211_node *, struct mbuf *,
const struct ieee80211_bpf_params *);
static void bwn_newassoc(struct ieee80211_node *, int);
static void bwn_updateslot(struct ifnet *);
static void bwn_update_promisc(struct ifnet *);
static void bwn_wme_init(struct bwn_mac *);
static int bwn_wme_update(struct ieee80211com *);
static struct ieee80211_node *bwn_node_alloc(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
static void bwn_wme_clear(struct bwn_softc *);
static void bwn_wme_load(struct bwn_mac *);
static void bwn_wme_loadparams(struct bwn_mac *,
const struct wmeParams *, uint16_t);
static void bwn_node_cleanup(struct ieee80211_node *);
static void bwn_scan_start(struct ieee80211com *);
static void bwn_scan_end(struct ieee80211com *);
static void bwn_set_channel(struct ieee80211com *);
@ -1088,15 +1084,10 @@ bwn_attach_post(struct bwn_softc *sc)
/* override default methods */
ic->ic_raw_xmit = bwn_raw_xmit;
ic->ic_newassoc = bwn_newassoc;
ic->ic_updateslot = bwn_updateslot;
ic->ic_update_promisc = bwn_update_promisc;
ic->ic_wme.wme_update = bwn_wme_update;
ic->ic_node_alloc = bwn_node_alloc;
sc->sc_node_cleanup = ic->ic_node_cleanup;
ic->ic_node_cleanup = bwn_node_cleanup;
ic->ic_scan_start = bwn_scan_start;
ic->ic_scan_end = bwn_scan_end;
ic->ic_set_channel = bwn_set_channel;
@ -2771,20 +2762,6 @@ bwn_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
return (0);
}
/*
* Setup driver-specific state for a newly associated node.
* Note that we're called also on a re-associate, the isnew
* param tells us if this is the first time or not.
*/
static void
bwn_newassoc(struct ieee80211_node *ni, int isnew)
{
struct ieee80211vap *vap = ni->ni_vap;
ieee80211_amrr_node_init(&BWN_VAP(vap)->bv_amrr,
&BWN_NODE(ni)->bn_amn, ni);
}
/*
* Callback from the 802.11 layer to update the slot time
* based on the current setting. We use it to notify the
@ -2857,32 +2834,6 @@ bwn_wme_update(struct ieee80211com *ic)
return (0);
}
static struct ieee80211_node *
bwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN])
{
struct ieee80211com *ic = vap->iv_ic;
struct bwn_softc *sc = ic->ic_ifp->if_softc;
const size_t space = sizeof(struct bwn_node);
struct bwn_node *bn;
bn = malloc(space, M_80211_NODE, M_NOWAIT|M_ZERO);
if (bn == NULL) {
/* XXX stat+msg */
return (NULL);
}
DPRINTF(sc, BWN_DEBUG_NODE, "%s: bn %p\n", __func__, bn);
return (&bn->bn_node);
}
static void
bwn_node_cleanup(struct ieee80211_node *ni)
{
struct ieee80211com *ic = ni->ni_ic;
struct bwn_softc *sc = ic->ic_ifp->if_softc;
sc->sc_node_cleanup(ni);
}
static void
bwn_scan_start(struct ieee80211com *ic)
{
@ -3018,10 +2969,7 @@ bwn_vap_create(struct ieee80211com *ic,
/* override max aid so sta's cannot assoc when we're out of sta id's */
vap->iv_max_aid = BWN_STAID_MAX;
ieee80211_amrr_init(&bvp->bv_amrr, vap,
IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD,
IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD,
500 /*ms*/);
ieee80211_ratectl_init(vap);
/* complete setup */
ieee80211_vap_attach(vap, ieee80211_media_change,
@ -3034,7 +2982,7 @@ bwn_vap_delete(struct ieee80211vap *vap)
{
struct bwn_vap *bvp = BWN_VAP(vap);
ieee80211_amrr_cleanup(&bvp->bv_amrr);
ieee80211_ratectl_deinit(vap);
ieee80211_vap_detach(vap);
free(bvp, M_80211_VAP);
}
@ -9040,12 +8988,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
struct bwn_dma_ring *dr;
struct bwn_dmadesc_generic *desc;
struct bwn_dmadesc_meta *meta;
struct bwn_node *bn;
struct bwn_pio_txqueue *tq;
struct bwn_pio_txpkt *tp = NULL;
struct bwn_softc *sc = mac->mac_sc;
struct bwn_stats *stats = &mac->mac_stats;
struct ieee80211_node *ni;
struct ieee80211vap *vap;
int slot;
BWN_ASSERT_LOCKED(mac->mac_sc);
@ -9074,9 +9022,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
dr->getdesc(dr, slot, &desc, &meta);
if (meta->mt_islast) {
ni = meta->mt_ni;
bn = (struct bwn_node *)ni;
ieee80211_amrr_tx_complete(&bn->bn_amn,
status->ack, 0);
vap = ni->ni_vap;
ieee80211_ratectl_tx_complete(vap, ni,
status->ack ?
IEEE80211_RATECTL_TX_SUCCESS :
IEEE80211_RATECTL_TX_FAILURE,
NULL, 0);
break;
}
slot = bwn_dma_nextslot(dr, slot);
@ -9092,8 +9043,12 @@ bwn_handle_txeof(struct bwn_mac *mac, const struct bwn_txstatus *status)
return;
}
ni = tp->tp_ni;
bn = (struct bwn_node *)ni;
ieee80211_amrr_tx_complete(&bn->bn_amn, status->ack, 0);
vap = ni->ni_vap;
ieee80211_ratectl_tx_complete(vap, ni,
status->ack ?
IEEE80211_RATECTL_TX_SUCCESS :
IEEE80211_RATECTL_TX_FAILURE,
NULL, 0);
}
bwn_pio_handle_txeof(mac, status);
}
@ -9678,7 +9633,7 @@ bwn_set_txhdr(struct bwn_mac *mac, struct ieee80211_node *ni,
else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE)
rate = rate_fb = tp->ucastrate;
else {
rix = ieee80211_amrr_choose(ni, &BWN_NODE(ni)->bn_amn);
rix = ieee80211_ratectl_rate(ni, NULL, 0);
rate = ni->ni_txrate;
if (rix > 0)

View file

@ -883,18 +883,11 @@ struct bwn_mac {
TAILQ_ENTRY(bwn_mac) mac_list;
};
struct bwn_node {
struct ieee80211_node bn_node; /* must be the first */
struct ieee80211_amrr_node bn_amn;
};
#define BWN_NODE(ni) ((struct bwn_node *)(ni))
/*
* Driver-specific vap state.
*/
struct bwn_vap {
struct ieee80211vap bv_vap; /* base class */
struct ieee80211_amrr bv_amrr;
int (*bv_newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};

View file

@ -139,7 +139,7 @@ enum {
#define FL_Q_SIZE 4096
#define JUMBO_Q_SIZE 1024
#define RSPQ_Q_SIZE 1024
#define RSPQ_Q_SIZE 2048
#define TX_ETH_Q_SIZE 1024
#define TX_OFLD_Q_SIZE 1024
#define TX_CTRL_Q_SIZE 256
@ -179,6 +179,7 @@ struct sge_rspq {
uint32_t offload_bundles;
uint32_t pure_rsps;
uint32_t unhandled_irqs;
uint32_t starved;
bus_addr_t phys_addr;
bus_dma_tag_t desc_tag;

View file

@ -2398,25 +2398,33 @@ cxgb_tick_handler(void *arg, int count)
if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map)
check_t3b2_mac(sc);
cause = t3_read_reg(sc, A_SG_INT_CAUSE);
reset = 0;
if (cause & F_FLEMPTY) {
cause = t3_read_reg(sc, A_SG_INT_CAUSE) & (F_RSPQSTARVE | F_FLEMPTY);
if (cause) {
struct sge_qset *qs = &sc->sge.qs[0];
uint32_t mask, v;
i = 0;
reset |= F_FLEMPTY;
v = t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) & ~0xff00;
cause = (t3_read_reg(sc, A_SG_RSPQ_FL_STATUS) >>
S_FL0EMPTY) & 0xffff;
while (cause) {
qs->fl[i].empty += (cause & 1);
if (i)
qs++;
i ^= 1;
cause >>= 1;
mask = 1;
for (i = 0; i < SGE_QSETS; i++) {
if (v & mask)
qs[i].rspq.starved++;
mask <<= 1;
}
mask <<= SGE_QSETS; /* skip RSPQXDISABLED */
for (i = 0; i < SGE_QSETS * 2; i++) {
if (v & mask) {
qs[i / 2].fl[i % 2].empty++;
}
mask <<= 1;
}
/* clear */
t3_write_reg(sc, A_SG_RSPQ_FL_STATUS, v);
t3_write_reg(sc, A_SG_INT_CAUSE, cause);
}
t3_write_reg(sc, A_SG_INT_CAUSE, reset);
for (i = 0; i < sc->params.nports; i++) {
struct port_info *pi = &sc->port[i];

View file

@ -3586,6 +3586,9 @@ t3_add_configured_sysctls(adapter_t *sc)
SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "credits",
CTLFLAG_RD, &qs->rspq.credits,
0, "#credits");
SYSCTL_ADD_UINT(ctx, rspqpoidlist, OID_AUTO, "starved",
CTLFLAG_RD, &qs->rspq.starved,
0, "#times starved");
SYSCTL_ADD_XLONG(ctx, rspqpoidlist, OID_AUTO, "phys_addr",
CTLFLAG_RD, &qs->rspq.phys_addr,
"physical_address_of the queue");

View file

@ -93,7 +93,7 @@ int em_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
char em_driver_version[] = "7.0.0";
char em_driver_version[] = "7.0.4";
/*********************************************************************
@ -192,7 +192,7 @@ static int em_suspend(device_t);
static int em_resume(device_t);
static void em_start(struct ifnet *);
static void em_start_locked(struct ifnet *, struct tx_ring *);
#if __FreeBSD_version >= 800000
#ifdef EM_MULTIQUEUE
static int em_mq_start(struct ifnet *, struct mbuf *);
static int em_mq_start_locked(struct ifnet *,
struct tx_ring *, struct mbuf *);
@ -797,7 +797,7 @@ em_resume(device_t dev)
* the packet is requeued.
**********************************************************************/
#if __FreeBSD_version >= 800000
#ifdef EM_MULTIQUEUE
static int
em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
{
@ -812,10 +812,18 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
return (err);
}
/* Call cleanup if number of TX descriptors low */
if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
em_txeof(txr);
enq = 0;
if (m == NULL)
if (m == NULL) {
next = drbr_dequeue(ifp, txr->br);
else
} else if (drbr_needs_enqueue(ifp, txr->br)) {
if ((err = drbr_enqueue(ifp, txr->br, m)) != 0)
return (err);
next = drbr_dequeue(ifp, txr->br);
} else
next = m;
/* Process the queue */
@ -830,12 +838,17 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
ETHER_BPF_MTAP(ifp, next);
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
break;
if (txr->tx_avail < EM_MAX_SCATTER) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
next = drbr_dequeue(ifp, txr->br);
}
if (enq > 0) {
/* Set the watchdog */
txr->watchdog_check = TRUE;
txr->watchdog_time = ticks;
}
return (err);
}
@ -860,8 +873,7 @@ em_mq_start(struct ifnet *ifp, struct mbuf *m)
txr = &adapter->tx_rings[i];
if (EM_TX_TRYLOCK(txr)) {
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
error = em_mq_start_locked(ifp, txr, m);
error = em_mq_start_locked(ifp, txr, m);
EM_TX_UNLOCK(txr);
} else
error = drbr_enqueue(ifp, txr->br, m);
@ -888,7 +900,7 @@ em_qflush(struct ifnet *ifp)
if_qflush(ifp);
}
#endif /* FreeBSD_version */
#endif /* EM_MULTIQUEUE */
static void
em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
@ -905,8 +917,15 @@ em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
if (!adapter->link_active)
return;
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
/* Call cleanup if number of TX descriptors low */
if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
em_txeof(txr);
while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
if (txr->tx_avail < EM_MAX_SCATTER) {
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
break;
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
if (m_head == NULL)
break;
@ -926,6 +945,7 @@ em_start_locked(struct ifnet *ifp, struct tx_ring *txr)
ETHER_BPF_MTAP(ifp, m_head);
/* Set timeout in case hardware has problems transmitting. */
txr->watchdog_time = ticks;
txr->watchdog_check = TRUE;
}
@ -1118,6 +1138,10 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
reinit = 1;
}
if (mask & IFCAP_VLAN_HWFILTER) {
ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
reinit = 1;
}
if ((mask & IFCAP_WOL) &&
(ifp->if_capabilities & IFCAP_WOL) != 0) {
if (mask & IFCAP_WOL_MCAST)
@ -1228,8 +1252,18 @@ em_init_locked(struct adapter *adapter)
/* Setup VLAN support, basic and offload if available */
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
/* Use real VLAN Filter support */
em_setup_vlan_hw_support(adapter);
/* Use real VLAN Filter support? */
if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
/* Use real VLAN Filter support */
em_setup_vlan_hw_support(adapter);
else {
u32 ctrl;
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
ctrl |= E1000_CTRL_VME;
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
}
}
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
@ -1337,11 +1371,13 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
}
EM_CORE_UNLOCK(adapter);
EM_RX_LOCK(rxr);
rx_done = em_rxeof(rxr, count);
EM_RX_UNLOCK(rxr);
EM_TX_LOCK(txr);
em_txeof(txr);
#if __FreeBSD_version >= 800000
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
em_mq_start_locked(ifp, txr, NULL);
#else
@ -1409,28 +1445,28 @@ em_handle_que(void *context, int pending)
struct ifnet *ifp = adapter->ifp;
struct tx_ring *txr = adapter->tx_rings;
struct rx_ring *rxr = adapter->rx_rings;
u32 loop = EM_MAX_LOOP;
bool more_rx, more_tx;
bool more_rx;
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
EM_TX_LOCK(txr);
do {
more_rx = em_rxeof(rxr, adapter->rx_process_limit);
more_tx = em_txeof(txr);
} while (loop-- && (more_rx || more_tx));
EM_RX_LOCK(rxr);
more_rx = em_rxeof(rxr, adapter->rx_process_limit);
EM_RX_UNLOCK(rxr);
#if __FreeBSD_version >= 800000
EM_TX_LOCK(txr);
em_txeof(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
em_mq_start_locked(ifp, txr, NULL);
#else
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
em_start_locked(ifp, txr);
#endif
if (more_rx || more_tx)
taskqueue_enqueue(adapter->tq, &adapter->que_task);
EM_TX_UNLOCK(txr);
if (more_rx) {
taskqueue_enqueue(adapter->tq, &adapter->que_task);
return;
}
}
em_enable_intr(adapter);
@ -1448,17 +1484,12 @@ em_msix_tx(void *arg)
{
struct tx_ring *txr = arg;
struct adapter *adapter = txr->adapter;
bool more;
++txr->tx_irq;
EM_TX_LOCK(txr);
more = em_txeof(txr);
em_txeof(txr);
EM_TX_UNLOCK(txr);
if (more)
taskqueue_enqueue(txr->tq, &txr->tx_task);
else
/* Reenable this interrupt */
E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims);
E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims);
return;
}
@ -1475,8 +1506,10 @@ em_msix_rx(void *arg)
struct adapter *adapter = rxr->adapter;
bool more;
EM_RX_LOCK(rxr);
++rxr->rx_irq;
more = em_rxeof(rxr, adapter->rx_process_limit);
EM_RX_UNLOCK(rxr);
if (more)
taskqueue_enqueue(rxr->tq, &rxr->rx_task);
else
@ -1513,14 +1546,16 @@ em_handle_rx(void *context, int pending)
{
struct rx_ring *rxr = context;
struct adapter *adapter = rxr->adapter;
u32 loop = EM_MAX_LOOP;
bool more;
do {
more = em_rxeof(rxr, adapter->rx_process_limit);
} while (loop-- && more);
/* Reenable this interrupt */
E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
EM_RX_LOCK(rxr);
more = em_rxeof(rxr, adapter->rx_process_limit);
EM_RX_UNLOCK(rxr);
if (more)
taskqueue_enqueue(rxr->tq, &rxr->rx_task);
else
/* Reenable this interrupt */
E1000_WRITE_REG(&adapter->hw, E1000_IMS, rxr->ims);
}
static void
@ -1529,16 +1564,13 @@ em_handle_tx(void *context, int pending)
struct tx_ring *txr = context;
struct adapter *adapter = txr->adapter;
struct ifnet *ifp = adapter->ifp;
u32 loop = EM_MAX_LOOP;
bool more;
if (!EM_TX_TRYLOCK(txr))
return;
do {
more = em_txeof(txr);
} while (loop-- && more);
#if __FreeBSD_version >= 800000
em_txeof(txr);
#ifdef EM_MULTIQUEUE
if (!drbr_empty(ifp, txr->br))
em_mq_start_locked(ifp, txr, NULL);
#else
@ -1706,13 +1738,6 @@ em_xmit(struct tx_ring *txr, struct mbuf **m_headp)
txd_upper = txd_lower = txd_used = txd_saved = 0;
do_tso = ((m_head->m_pkthdr.csum_flags & CSUM_TSO) != 0);
/*
* Force a cleanup if number of TX descriptors
* available hits the threshold
*/
if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD)
em_txeof(txr);
/*
* TSO workaround:
* If an mbuf is only header we need
@ -2642,7 +2667,7 @@ em_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capabilities = ifp->if_capenable = 0;
#if __FreeBSD_version >= 800000
#ifdef EM_MULTIQUEUE
/* Multiqueue tx functions */
ifp->if_transmit = em_mq_start;
ifp->if_qflush = em_qflush;
@ -2656,12 +2681,23 @@ em_setup_interface(device_t dev, struct adapter *adapter)
ifp->if_capenable |= IFCAP_TSO4;
/*
* Tell the upper layer(s) we support long frames.
* Tell the upper layer(s) we
* support full VLAN capability
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
/*
** Dont turn this on by default, if vlans are
** created on another pseudo device (eg. lagg)
** then vlan events are not passed thru, breaking
** operation, but with HW FILTER off it works. If
** using vlans directly on the em driver you can
** enable this and get full hardware tag filtering.
*/
ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
#ifdef DEVICE_POLLING
ifp->if_capabilities |= IFCAP_POLLING;
#endif
@ -3681,6 +3717,8 @@ em_refresh_mbufs(struct rx_ring *rxr, int limit)
rxr->next_to_refresh = i;
}
update:
bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map,
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
if (cleaned != -1) /* Update tail index */
E1000_WRITE_REG(&adapter->hw,
E1000_RDT(rxr->me), cleaned);
@ -3972,7 +4010,7 @@ em_initialize_receive_unit(struct adapter *adapter)
** When using MSIX interrupts we need to throttle
** using the EITR register (82574 only)
*/
if (adapter->msix)
if (hw->mac.type == e1000_82574)
for (int i = 0; i < 4; i++)
E1000_WRITE_REG(hw, E1000_EITR_82574(i),
DEFAULT_ITR);
@ -4015,6 +4053,9 @@ em_initialize_receive_unit(struct adapter *adapter)
E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
(hw->mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
/* Strip the CRC */
rctl |= E1000_RCTL_SECRC;
/* Make sure VLAN Filters are off */
rctl &= ~E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_SBP;
@ -4046,15 +4087,15 @@ static int
em_rxeof(struct rx_ring *rxr, int count)
{
struct adapter *adapter = rxr->adapter;
struct ifnet *ifp = adapter->ifp;;
struct ifnet *ifp = adapter->ifp;
struct mbuf *mp, *sendmp;
u8 status;
u8 status = 0;
u16 len;
int i, processed, rxdone = 0;
bool eop;
struct e1000_rx_desc *cur;
EM_RX_LOCK(rxr);
EM_RX_LOCK_ASSERT(rxr);
for (i = rxr->next_to_check, processed = 0; count != 0;) {
@ -4109,6 +4150,10 @@ em_rxeof(struct rx_ring *rxr, int count)
E1000_RXD_SPC_VLAN_MASK);
rxr->fmp->m_flags |= M_VLANTAG;
}
#ifdef EM_MULTIQUEUE
rxr->fmp->m_pkthdr.flowid = curcpu;
rxr->fmp->m_flags |= M_FLOWID;
#endif
#ifndef __NO_STRICT_ALIGNMENT
skip:
#endif
@ -4162,8 +4207,11 @@ skip:
rxr->next_to_check = i;
EM_RX_UNLOCK(rxr);
#ifdef DEVICE_POLLING
return (rxdone);
#else
return ((status & E1000_RXD_STAT_DD) ? TRUE : FALSE);
#endif
}
#ifndef __NO_STRICT_ALIGNMENT
@ -4346,7 +4394,7 @@ em_enable_intr(struct adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
u32 ims_mask = IMS_ENABLE_MASK;
if (adapter->msix) {
if (hw->mac.type == e1000_82574) {
E1000_WRITE_REG(hw, EM_EIAC, EM_MSIX_MASK);
ims_mask |= EM_MSIX_MASK;
}
@ -4358,7 +4406,7 @@ em_disable_intr(struct adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
if (adapter->msix)
if (hw->mac.type == e1000_82574)
E1000_WRITE_REG(hw, EM_EIAC, 0);
E1000_WRITE_REG(&adapter->hw, E1000_IMC, 0xffffffff);
}

View file

@ -223,7 +223,7 @@
#define HW_DEBUGOUT1(S, A) if (DEBUG_HW) printf(S "\n", A)
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
#define EM_MAX_SCATTER 64
#define EM_MAX_SCATTER 32
#define EM_VFTA_SIZE 128
#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
@ -453,5 +453,6 @@ struct em_buffer {
#define EM_RX_UNLOCK(_sc) mtx_unlock(&(_sc)->rx_mtx)
#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
#define EM_RX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->rx_mtx, MA_OWNED)
#endif /* _EM_H_DEFINED_ */

View file

@ -99,7 +99,7 @@ int igb_display_debug_stats = 0;
/*********************************************************************
* Driver version:
*********************************************************************/
char igb_driver_version[] = "version - 1.9.3";
char igb_driver_version[] = "version - 1.9.4";
/*********************************************************************
@ -1055,6 +1055,10 @@ igb_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
reinit = 1;
}
if (mask & IFCAP_VLAN_HWFILTER) {
ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
reinit = 1;
}
if (mask & IFCAP_LRO) {
ifp->if_capenable ^= IFCAP_LRO;
reinit = 1;
@ -1110,6 +1114,19 @@ igb_init_locked(struct adapter *adapter)
E1000_WRITE_REG(&adapter->hw, E1000_VET, ETHERTYPE_VLAN);
/* Use real VLAN Filter support? */
if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
/* Use real VLAN Filter support */
igb_setup_vlan_hw_support(adapter);
else {
u32 ctrl;
ctrl = E1000_READ_REG(&adapter->hw, E1000_CTRL);
ctrl |= E1000_CTRL_VME;
E1000_WRITE_REG(&adapter->hw, E1000_CTRL, ctrl);
}
}
/* Set hardware offload abilities */
ifp->if_hwassist = 0;
if (ifp->if_capenable & IFCAP_TXCSUM) {
@ -1436,7 +1453,7 @@ igb_msix_que(void *arg)
if (adapter->hw.mac.type == e1000_82575)
newitr |= newitr << 16;
else
newitr |= 0x8000000;
newitr |= E1000_EITR_CNT_IGNR;
/* save for next interrupt */
que->eitr_setting = newitr;
@ -2340,7 +2357,7 @@ igb_configure_queues(struct adapter *adapter)
if (hw->mac.type == e1000_82575)
newitr |= newitr << 16;
else
newitr |= 0x8000000;
newitr |= E1000_EITR_CNT_IGNR;
for (int i = 0; i < adapter->num_queues; i++) {
que = &adapter->queues[i];
@ -2669,12 +2686,23 @@ igb_setup_interface(device_t dev, struct adapter *adapter)
#endif
/*
* Tell the upper layer(s) we support long frames.
* Tell the upper layer(s) we
* support full VLAN capability.
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU;
/*
** Dont turn this on by default, if vlans are
** created on another pseudo device (eg. lagg)
** then vlan events are not passed thru, breaking
** operation, but with HW FILTER off it works. If
** using vlans directly on the em driver you can
** enable this and get full hardware tag filtering.
*/
ifp->if_capabilities |= IFCAP_VLAN_HWFILTER;
/*
* Specify the media types supported by this adapter and register
* callbacks to update media and link information
@ -3779,6 +3807,9 @@ igb_setup_receive_ring(struct rx_ring *rxr)
/* Update descriptor */
rxr->rx_base[j].read.pkt_addr = htole64(pseg[0].ds_addr);
}
/* Setup our descriptor indices */
rxr->next_to_check = 0;
rxr->next_to_refresh = 0;
rxr->lro_enabled = FALSE;
@ -4672,10 +4703,12 @@ igb_update_stats_counters(struct adapter *adapter)
{
struct ifnet *ifp;
if(adapter->hw.phy.media_type == e1000_media_type_copper ||
if (adapter->hw.phy.media_type == e1000_media_type_copper ||
(E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_LU)) {
adapter->stats.symerrs += E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
adapter->stats.sec += E1000_READ_REG(&adapter->hw, E1000_SEC);
adapter->stats.symerrs +=
E1000_READ_REG(&adapter->hw, E1000_SYMERRS);
adapter->stats.sec +=
E1000_READ_REG(&adapter->hw, E1000_SEC);
}
adapter->stats.crcerrs += E1000_READ_REG(&adapter->hw, E1000_CRCERRS);
adapter->stats.mpc += E1000_READ_REG(&adapter->hw, E1000_MPC);

View file

@ -763,8 +763,8 @@ vesa_get_bpscanline(struct vesa_mode *vmode)
static int
vesa_bios_init(void)
{
static struct vesa_info buf;
struct vesa_mode vmode;
struct vesa_info *buf;
video_info_t *p;
x86regs_t regs;
size_t bsize;
@ -800,7 +800,7 @@ vesa_bios_init(void)
x86bios_init_regs(&regs);
regs.R_AX = 0x4f00;
vmbuf = x86bios_alloc(&offs, sizeof(buf));
vmbuf = x86bios_alloc(&offs, sizeof(*buf));
if (vmbuf == NULL)
return (1);
@ -813,23 +813,23 @@ vesa_bios_init(void)
if (regs.R_AX != 0x004f || bcmp("VESA", vmbuf, 4) != 0)
goto fail;
bcopy(vmbuf, &buf, sizeof(buf));
vesa_adp_info = buf = malloc(sizeof(*buf), M_DEVBUF, M_WAITOK);
bcopy(vmbuf, buf, sizeof(*buf));
vesa_adp_info = &buf;
if (bootverbose) {
printf("VESA: information block\n");
hexdump(&buf, sizeof(buf), NULL, HD_OMIT_CHARS);
hexdump(buf, sizeof(*buf), NULL, HD_OMIT_CHARS);
}
vers = buf.v_version = le16toh(buf.v_version);
buf.v_oemstr = le32toh(buf.v_oemstr);
buf.v_flags = le32toh(buf.v_flags);
buf.v_modetable = le32toh(buf.v_modetable);
buf.v_memsize = le16toh(buf.v_memsize);
buf.v_revision = le16toh(buf.v_revision);
buf.v_venderstr = le32toh(buf.v_venderstr);
buf.v_prodstr = le32toh(buf.v_prodstr);
buf.v_revstr = le32toh(buf.v_revstr);
vers = buf->v_version = le16toh(buf->v_version);
buf->v_oemstr = le32toh(buf->v_oemstr);
buf->v_flags = le32toh(buf->v_flags);
buf->v_modetable = le32toh(buf->v_modetable);
buf->v_memsize = le16toh(buf->v_memsize);
buf->v_revision = le16toh(buf->v_revision);
buf->v_venderstr = le32toh(buf->v_venderstr);
buf->v_prodstr = le32toh(buf->v_prodstr);
buf->v_revstr = le32toh(buf->v_revstr);
if (vers < 0x0102) {
printf("VESA: VBE version %d.%d is not supported; "
@ -839,21 +839,21 @@ vesa_bios_init(void)
return (1);
}
VESA_STRCPY(vesa_oemstr, buf.v_oemstr);
VESA_STRCPY(vesa_oemstr, buf->v_oemstr);
if (vers >= 0x0200) {
VESA_STRCPY(vesa_venderstr, buf.v_venderstr);
VESA_STRCPY(vesa_prodstr, buf.v_prodstr);
VESA_STRCPY(vesa_revstr, buf.v_revstr);
VESA_STRCPY(vesa_venderstr, buf->v_venderstr);
VESA_STRCPY(vesa_prodstr, buf->v_prodstr);
VESA_STRCPY(vesa_revstr, buf->v_revstr);
}
is_via_cle266 = strncmp(vesa_oemstr, VESA_VIA_CLE266,
sizeof(VESA_VIA_CLE266)) == 0;
if (buf.v_modetable == 0)
if (buf->v_modetable == 0)
goto fail;
msize = (size_t)buf.v_memsize * 64 * 1024;
msize = (size_t)buf->v_memsize * 64 * 1024;
vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf.v_modetable));
vesa_vmodetab = x86bios_offset(BIOS_SADDRTOLADDR(buf->v_modetable));
for (i = 0, modes = 0; (i < (M_VESA_MODE_MAX - M_VESA_BASE + 1)) &&
(vesa_vmodetab[i] != 0xffff); ++i) {
@ -1016,12 +1016,16 @@ vesa_bios_init(void)
if (!has_vesa_bios)
goto fail;
x86bios_free(vmbuf, sizeof(buf));
x86bios_free(vmbuf, sizeof(*buf));
return (0);
fail:
if (vmbuf != NULL)
x86bios_free(vmbuf, sizeof(buf));
if (vesa_adp_info != NULL) {
free(vesa_adp_info, M_DEVBUF);
vesa_adp_info = NULL;
}
if (vesa_oemstr != NULL) {
free(vesa_oemstr, M_DEVBUF);
vesa_oemstr = NULL;
@ -1875,6 +1879,8 @@ vesa_unload(void)
}
splx(s);
if (vesa_adp_info != NULL)
free(vesa_adp_info, M_DEVBUF);
if (vesa_oemstr != NULL)
free(vesa_oemstr, M_DEVBUF);
if (vesa_venderstr != NULL)

File diff suppressed because it is too large Load diff

View file

@ -46,6 +46,7 @@ struct pmc_md_iaf_op_pmcallocate {
*/
struct pmc_md_iap_op_pmcallocate {
uint32_t pm_iap_config;
uint32_t pm_iap_rsp;
};
#define IAP_EVSEL(C) ((C) & 0xFF)
@ -59,6 +60,8 @@ struct pmc_md_iap_op_pmcallocate {
#define IAP_INV (1 << 23)
#define IAP_CMASK(C) (((C) & 0xFF) << 24)
#define IA_OFFCORE_RSP_MASK 0xF7FF
#ifdef _KERNEL
/*
@ -76,16 +79,15 @@ struct pmc_md_iap_op_pmcallocate {
/*
* Programmable counters.
*/
#define IAP_PMC0 0x0C1
#define IAP_PMC1 0x0C2
#define IAP_PMC0 0x0C1
#define IAP_EVSEL0 0x186
#define IAP_EVSEL1 0x187
/*
* Simplified programming interface in Intel Performance Architecture
* v2 and later.
*/
#define IA_GLOBAL_STATUS 0x38E
#define IA_GLOBAL_CTRL 0x38F
#define IA_GLOBAL_OVF_CTRL 0x390
@ -93,12 +95,19 @@ struct pmc_md_iap_op_pmcallocate {
#define IA_GLOBAL_STATUS_FLAG_CONDCHG (1ULL << 63)
#define IA_GLOBAL_STATUS_FLAG_OVFBUF (1ULL << 62)
/*
* Offcore response configuration.
*/
#define IA_OFFCORE_RSP0 0x1A6
#define IA_OFFCORE_RSP1 0x1A7
struct pmc_md_iaf_pmc {
uint64_t pm_iaf_ctrl;
};
struct pmc_md_iap_pmc {
uint32_t pm_iap_evsel;
uint32_t pm_iap_rsp;
};
/*

View file

@ -133,8 +133,14 @@ pmc_intel_initialize(void)
case 0x1A:
case 0x1E: /* Per Intel document 253669-032 9/2009, pages A-2 and A-57 */
case 0x1F: /* Per Intel document 253669-032 9/2009, pages A-2 and A-57 */
case 0x2E:
cputype = PMC_CPU_INTEL_COREI7;
nclasses = 3;
nclasses = 5;
break;
case 0x25: /* Per Intel document 253669-033US 12/2009. */
case 0x2C: /* Per Intel document 253669-033US 12/2009. */
cputype = PMC_CPU_INTEL_WESTMERE;
nclasses = 5;
break;
}
break;
@ -176,6 +182,7 @@ pmc_intel_initialize(void)
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
case PMC_CPU_INTEL_COREI7:
case PMC_CPU_INTEL_WESTMERE:
error = pmc_core_initialize(pmc_mdep, ncpus);
break;
@ -226,6 +233,22 @@ pmc_intel_initialize(void)
KASSERT(0, ("[intel,%d] Unknown CPU type", __LINE__));
}
/*
* Init the uncore class.
*/
#if defined(__i386__) || defined(__amd64__)
switch (cputype) {
/*
* Intel Corei7 and Westmere processors.
*/
case PMC_CPU_INTEL_COREI7:
case PMC_CPU_INTEL_WESTMERE:
error = pmc_uncore_initialize(pmc_mdep, ncpus);
break;
default:
break;
}
#endif
error:
if (error) {
@ -247,6 +270,8 @@ pmc_intel_finalize(struct pmc_mdep *md)
case PMC_CPU_INTEL_CORE:
case PMC_CPU_INTEL_CORE2:
case PMC_CPU_INTEL_CORE2EXTREME:
case PMC_CPU_INTEL_COREI7:
case PMC_CPU_INTEL_WESTMERE:
pmc_core_finalize(md);
break;
@ -269,4 +294,18 @@ pmc_intel_finalize(struct pmc_mdep *md)
default:
KASSERT(0, ("[intel,%d] unknown CPU type", __LINE__));
}
/*
* Uncore.
*/
#if defined(__i386__) || defined(__amd64__)
switch (md->pmd_cputype) {
case PMC_CPU_INTEL_COREI7:
case PMC_CPU_INTEL_WESTMERE:
pmc_uncore_finalize(md);
break;
default:
break;
}
#endif
}

1121
sys/dev/hwpmc/hwpmc_uncore.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,120 @@
/*-
* Copyright (c) 2010 Fabien Thomas
* All rights reserved.
*
* 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.
*
* $FreeBSD$
*/
#ifndef _DEV_HWPMC_UNCORE_H_
#define _DEV_HWPMC_UNCORE_H_ 1
/*
* Fixed-function PMCs.
*/
struct pmc_md_ucf_op_pmcallocate {
uint16_t pm_ucf_flags; /* additional flags */
};
#define UCF_EN 0x1
#define UCF_PMI 0x4
/*
* Programmable PMCs.
*/
struct pmc_md_ucp_op_pmcallocate {
uint32_t pm_ucp_config;
};
#define UCP_EVSEL(C) ((C) & 0xFF)
#define UCP_UMASK(C) ((C) & 0xFF00)
#define UCP_CTRR (1 << 17)
#define UCP_EDGE (1 << 18)
#define UCP_INT (1 << 20)
#define UCP_EN (1 << 22)
#define UCP_INV (1 << 23)
#define UCP_CMASK(C) (((C) & 0xFF) << 24)
#ifdef _KERNEL
#define DCTL_FLAG_UNC_PMI (1ULL << 13)
/*
* Fixed-function counters.
*/
#define UCF_MASK 0xF
#define UCF_CTR0 0x394
#define UCF_OFFSET 32
#define UCF_CTRL 0x395
/*
* Programmable counters.
*/
#define UCP_PMC0 0x3B0
#define UCP_EVSEL0 0x3C0
#define UCP_OPCODE_MATCH 0x396
/*
* Simplified programming interface in Intel Performance Architecture
* v2 and later.
*/
#define UC_GLOBAL_STATUS 0x392
#define UC_GLOBAL_CTRL 0x391
#define UC_GLOBAL_OVF_CTRL 0x393
#define UC_GLOBAL_STATUS_FLAG_CLRCHG (1ULL << 63)
#define UC_GLOBAL_STATUS_FLAG_OVFPMI (1ULL << 61)
#define UC_GLOBAL_CTRL_FLAG_FRZ (1ULL << 63)
#define UC_GLOBAL_CTRL_FLAG_ENPMICORE0 (1ULL << 48)
struct pmc_md_ucf_pmc {
uint64_t pm_ucf_ctrl;
};
struct pmc_md_ucp_pmc {
uint32_t pm_ucp_evsel;
};
/*
* Prototypes.
*/
int pmc_uncore_initialize(struct pmc_mdep *_md, int _maxcpu);
void pmc_uncore_finalize(struct pmc_mdep *_md);
void pmc_uncore_mark_started(int _cpu, int _pmc);
int pmc_ucf_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width);
void pmc_ucf_finalize(struct pmc_mdep *_md);
int pmc_ucp_initialize(struct pmc_mdep *_md, int _maxcpu, int _npmc, int _width,
int _flags);
void pmc_ucp_finalize(struct pmc_mdep *_md);
#endif /* _KERNEL */
#endif /* _DEV_HWPMC_UNCORE_H */

File diff suppressed because it is too large Load diff

Some files were not shown because too many files have changed in this diff Show more