Merge branch 'freebsd/current/main' into hardened/current/master

This commit is contained in:
HardenedBSD Sync Services 2024-10-15 06:01:41 -06:00
commit f512e3bce6
No known key found for this signature in database
32 changed files with 580 additions and 155 deletions

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= cache

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= concat

View File

@ -1,13 +1,11 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc ${SRCTOP}/sys/geom/eli ${SRCTOP}/sys/crypto/sha2
.PATH: ${SRCTOP}/sys/geom/eli
GEOM_CLASS= eli
SRCS= g_eli_crypto.c
SRCS+= g_eli_hmac.c
SRCS+= g_eli_key.c
SRCS+= pkcs5v2.c
SRCS+= sha256c.c
SRCS+= sha512c.c
LIBADD= md crypto

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= journal
SRCS+= geom_journal_ufs.c

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= label

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= mirror

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= mountver

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= multipath

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= nop

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= part

View File

@ -1,8 +1,5 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= raid
LIBADD= md
.include <bsd.lib.mk>

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= raid3

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= shsec

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= stripe

View File

@ -1,5 +1,4 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc
GEOM_CLASS= union

View File

@ -1,5 +1,5 @@
PACKAGE=geom
.PATH: ${.CURDIR:H:H}/misc ${SRCTOP}/sys/geom/virstor
.PATH: ${SRCTOP}/sys/geom/virstor
GEOM_CLASS= virstor

View File

@ -15,6 +15,7 @@ ATF_TESTS_C+= memset2_test
ATF_TESTS_C+= memset_s_test
ATF_TESTS_C+= strncmp_test
ATF_TESTS_C+= stpncpy_test
ATF_TESTS_C+= strnlen_test
ATF_TESTS_C+= strcmp2_test
ATF_TESTS_C+= strcspn_test
ATF_TESTS_C+= strerror2_test

View File

@ -0,0 +1,141 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 Strahinja Stanisic <strajabot@FreeBSD.org>
*/
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdalign.h>
#include <stdint.h>
#include <atf-c.h>
ATF_TC(strnlen_alignments);
ATF_TC_HEAD(strnlen_alignments, tc)
{
atf_tc_set_md_var(tc, "descr", "Test strnlen(3) with different alignments");
}
ATF_TC_BODY(strnlen_alignments, tc)
{
size_t (*strnlen_fn)(const char*, size_t) = strnlen;
char alignas(16) buffer[1 + 16 + 64 + 1 + 1];
memset(buffer, '/', sizeof(buffer));
for (int align = 1; align < 1 + 16; align++) {
char *s = buffer + align;
for (size_t maxlen = 0; maxlen <= 64; maxlen++) {
for (size_t len = 0; len <= maxlen; len++) {
/* returns length */
/* without sentinels */
s[len] = '\0';
size_t val = strnlen_fn(s, maxlen);
if (val != len) {
fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
align, maxlen, len);
atf_tc_fail("returned incorrect len");
}
/* with sentinels */
s[-1] = '\0';
s[maxlen + 1] = '\0';
val = strnlen_fn(s, maxlen);
if (val != len) {
fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
align, maxlen, len);
atf_tc_fail("returned incorrect len (sentinels)");
}
/* cleanup */
s[-1] = '/';
s[len] = '/';
s[maxlen + 1] = '/';
}
/* returns maxlen */
/* without sentinels */
size_t val = strnlen_fn(s, maxlen);
if (val != maxlen) {
fprintf(stderr, "align = %d, maxlen = %zu",
align, maxlen);
atf_tc_fail("should return maxlen");
}
/* with sentinels */
s[-1] = '\0';
s[maxlen + 1] = '\0';
val = strnlen_fn(s, maxlen);
if (val != maxlen) {
fprintf(stderr, "align = %d, maxlen = %zu",
align, maxlen);
atf_tc_fail("should return maxlen (sentinels)");
}
/* cleanup */
s[-1] = '/';
s[maxlen + 1] = '/';
}
}
}
ATF_TC(strnlen_size_max);
ATF_TC_HEAD(strnlen_size_max, tc)
{
atf_tc_set_md_var(tc, "descr", "Test strnlen(3) with maxlen=SIZE_MAX");
}
ATF_TC_BODY(strnlen_size_max, tc)
{
size_t (*strnlen_fn)(const char*, size_t) = strnlen;
char alignas(16) buffer[1 + 16 + 64 + 1 + 1];
memset(buffer, '/', sizeof(buffer));
for (int align = 1; align < 1 + 16; align++) {
char* s = buffer + align;
for (size_t len = 0; len <= 64; len++) {
/* returns length */
/* without sentinels */
s[len] = '\0';
size_t val = strnlen_fn(s, SIZE_MAX);
if (val != len) {
fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
align, SIZE_MAX, len);
atf_tc_fail("returned incorrect len (SIZE_MAX)");
}
/* with sentinels */
s[-1] = '\0';
val = strnlen_fn(s, SIZE_MAX);
if (val != len) {
fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
align, SIZE_MAX, len);
atf_tc_fail("returned incorrect len (sentinels) (SIZE_MAX)");
}
/* cleanup */
s[-1] = '/';
s[len] = '/';
}
}
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, strnlen_alignments);
ATF_TP_ADD_TC(tp, strnlen_size_max);
return atf_no_error();
}

View File

@ -26,7 +26,7 @@ CLOUDWARE_TYPES?= AZURE \
BASIC-CLOUDINIT \
EC2 \
GCE \
OCI \
ORACLE \
VAGRANT
AZURE_FORMAT= vhdf
AZURE_FSLIST?= ufs zfs
@ -46,9 +46,9 @@ EC2-SMALL_DESC= Amazon EC2 small image
GCE_FORMAT= raw
GCE_FSLIST?= ufs zfs
GCE_DESC= Google Compute Engine image
OCI_FORMAT= qcow2
OCI_FSLIST?= ufs
OCI_DESC= Oracle Cloud Infrastructure image
ORACLE_FORMAT= qcow2
ORACLE_FSLIST?= ufs
ORACLE_DESC= Oracle Cloud Infrastructure image
OPENSTACK_FORMAT=qcow2
OPENSTACK_FSLIST?= ufs
OPENSTACK_DESC= OpenStack platform image

View File

@ -113,4 +113,4 @@ PORTBRANCH="main"
## If WITH_CLOUDWARE is set to a non-empty value, this is a list of providers
## to create disk images.
#CLOUDWARE="EC2 GCE OCI VAGRANT-VIRTUALBOX VAGRANT-VMWARE"
#CLOUDWARE="EC2 GCE ORACLE VAGRANT-VIRTUALBOX VAGRANT-VMWARE"

View File

@ -68,15 +68,15 @@ EOF
# S14 Root user login must be disabled on serial-over-ssh console
pw -R ${DESTDIR} usermod root -w no
# OCI requirements override the default FreeBSD cloud-init settings
cat <<-'EOF' >> ${DESTDIR}/usr/local/etc/cloud/cloud.cfg.d/98_oci.cfg
# Oracle requirements override the default FreeBSD cloud-init settings
cat <<-'EOF' >> ${DESTDIR}/usr/local/etc/cloud/cloud.cfg.d/98_oracle.cfg
disable_root: true
system_info:
distro: freebsd
default_user:
name: freebsd
lock_passwd: True
gecos: "OCI Default User"
gecos: "Oracle Cloud Default User"
groups: [wheel]
sudo: ["ALL=(ALL) NOPASSWD:ALL"]
shell: /bin/sh

View File

@ -13,7 +13,7 @@ MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps
.src.LC_CTYPE:
localedef ${LOCALEDEF_ENDIAN} -D -U -c -w ${MAPLOC}/widths.txt \
-f ${MAPLOC}/map.${.IMPSRC:T:R:E} \
-i ${.IMPSRC} ${.OBJDIR}/${.IMPSRC:T:R} || true
-i ${.IMPSRC} ${.OBJDIR}/${.IMPSRC:T:R}
LOCALES+= C.UTF-8
.if ${MK_LOCALES} != no
@ -254,7 +254,7 @@ SYMPAIRS+= be_BY.CP1131.src ru_RU.KOI8-R.src
${t:S/src$/LC_CTYPE/}: $s
localedef ${LOCALEDEF_ENDIAN} -D -U -c -w ${MAPLOC}/widths.txt \
-f ${MAPLOC}/map.${.TARGET:T:R:C/^.*\.//} \
-i ${.ALLSRC} ${.OBJDIR}/${.TARGET:T:R} || true
-i ${.ALLSRC} ${.OBJDIR}/${.TARGET:T:R}
.endfor
.include <bsd.prog.mk>

View File

@ -110,6 +110,11 @@ UINT16 boot_current;
*/
EFI_LOADED_IMAGE *boot_img;
/*
* RSDP base table.
*/
ACPI_TABLE_RSDP *rsdp;
static bool
has_keyboard(void)
{
@ -723,14 +728,209 @@ setenv_int(const char *key, int val)
setenv(key, buf, 1);
}
static void *
acpi_map_sdt(vm_offset_t addr)
{
/* PA == VA */
return ((void *)addr);
}
static int
acpi_checksum(void *p, size_t length)
{
uint8_t *bp;
uint8_t sum;
bp = p;
sum = 0;
while (length--)
sum += *bp++;
return (sum);
}
static void *
acpi_find_table(uint8_t *sig)
{
int entries, i, addr_size;
ACPI_TABLE_HEADER *sdp;
ACPI_TABLE_RSDT *rsdt;
ACPI_TABLE_XSDT *xsdt;
vm_offset_t addr;
if (rsdp == NULL)
return (NULL);
rsdt = (ACPI_TABLE_RSDT *)(uintptr_t)rsdp->RsdtPhysicalAddress;
xsdt = (ACPI_TABLE_XSDT *)(uintptr_t)rsdp->XsdtPhysicalAddress;
if (rsdp->Revision < 2) {
sdp = (ACPI_TABLE_HEADER *)rsdt;
addr_size = sizeof(uint32_t);
} else {
sdp = (ACPI_TABLE_HEADER *)xsdt;
addr_size = sizeof(uint64_t);
}
entries = (sdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
for (i = 0; i < entries; i++) {
if (addr_size == 4)
addr = le32toh(rsdt->TableOffsetEntry[i]);
else
addr = le64toh(xsdt->TableOffsetEntry[i]);
if (addr == 0)
continue;
sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
if (acpi_checksum(sdp, sdp->Length)) {
printf("RSDT entry %d (sig %.4s) is corrupt", i,
sdp->Signature);
continue;
}
if (memcmp(sig, sdp->Signature, 4) == 0)
return (sdp);
}
return (NULL);
}
/*
* Parse ConOut (the list of consoles active) and see if we can find a
* serial port and/or a video port. It would be nice to also walk the
* ACPI name space to map the UID for the serial port to a port. The
* latter is especially hard. Also check for ConIn as well. This will
* be enough to determine if we have serial, and if we don't, we default
* to video. If there's a dual-console situation with ConIn, this will
* currently fail.
* Convert the InterfaceType in the SPCR. These are encoded the same for DBG2
* tables as well (though we don't parse those here).
*/
static const char *
acpi_uart_type(UINT8 t)
{
static const char *types[] = {
[0] = "ns8250", /* Full 16550 */
[1] = "ns8250", /* DBGP Rev 1 16550 subset */
[3] = "pl011", /* Arm PL011 */
[5] = "ns8250", /* Nvidia 16550 */
[0x12] = "ns8250", /* 16550 defined in SerialPort */
};
if (t >= nitems(types))
return (NULL);
return (types[t]);
}
static int
acpi_uart_baud(UINT8 b)
{
static int baud[] = { 0, -1, -1, 9600, 19200, -1, 57600, 115200 };
if (b > 7)
return (-1);
return (baud[b]);
}
static int
acpi_uart_regionwidth(UINT8 rw)
{
if (rw == 0)
return (1);
if (rw > 4)
return (-1);
return (1 << (rw - 1));
}
static const char *
acpi_uart_parity(UINT8 p)
{
/* Some of these SPCR entires get this wrong, hard wire none */
return ("none");
}
/*
* See if we can find a SPCR ACPI table in the static tables. If so, then it
* describes the serial console that's been redirected to, so we know that at
* least there's a serial console. this is most important for embedded systems
* that don't have traidtional PC serial ports.
*
* All the two letter variables in this function correspond to their usage in
* the uart(4) console string. We use io == -1 to select between I/O ports and
* memory mapped addresses. Set both hw.uart.console and hw.uart.consol.extra
* to communicate settings from SPCR to the kernel.
*/
static int
check_acpi_spcr(void)
{
ACPI_TABLE_SPCR *spcr;
int br, db, io, rs, rw, sb, xo, pv, pd;
uintmax_t mm;
const char *dt, *pa;
char *val = NULL;
spcr = acpi_find_table(ACPI_SIG_SPCR);
if (spcr == NULL)
return (0);
dt = acpi_uart_type(spcr->InterfaceType);
if (dt == NULL) { /* Kernel can't use unknown types */
printf("UART Type %d not known\n", spcr->InterfaceType);
return (0);
}
/* I/O vs Memory mapped vs PCI device */
io = -1;
pv = spcr->PciVendorId;
pd = spcr->PciDeviceId;
if (pv == 0xffff && pd == 0xffff) {
if (spcr->SerialPort.SpaceId == 1)
io = spcr->SerialPort.Address;
else {
mm = spcr->SerialPort.Address;
rs = ffs(spcr->SerialPort.BitWidth) - 4;
rw = acpi_uart_regionwidth(spcr->SerialPort.AccessWidth);
}
} else {
/* XXX todo: bus:device:function + flags and segment */
}
/* Uart settings */
pa = acpi_uart_parity(spcr->Parity);
sb = spcr->StopBits;
db = 8;
/*
* UartClkFreq is 3 and newer. We always use it then (it's only valid if
* it isn't 0, but if it is 0, we want to use 0 to have the kernel
* guess).
*/
if (spcr->Header.Revision <= 2)
xo = 0;
else
xo = spcr->UartClkFreq;
/*
* PreciseBaudrate, when non-zero, is to be preferred. It's only valid,
* though, for rev 4 and newer. So when it's 0 or the version is too
* old, we do the old-style table lookup. Otherwise we believe it.
*/
if (spcr->Header.Revision <= 3 || spcr->PreciseBaudrate == 0)
br = acpi_uart_baud(spcr->BaudRate);
else
br = spcr->PreciseBaudrate;
if (io != -1) {
asprintf(&val, "db:%d,dt:%s,io:%#x,pa:%s,br:%d,xo=%d",
db, dt, io, pa, br, xo);
} else if (pv != 0xffff && pd != 0xffff) {
asprintf(&val, "db:%d,dt:%s,pv:%#x,pd:%#x,pa:%s,br:%d,xo=%d",
db, dt, pv, pd, pa, br, xo);
} else {
asprintf(&val, "db:%d,dt:%s,mm:%#jx,rs:%d,rw:%d,pa:%s,br:%d,xo=%d",
db, dt, mm, rs, rw, pa, br, xo);
}
env_setenv("hw.uart.console", EV_VOLATILE, val, NULL, NULL);
free(val);
return (RB_SERIAL);
}
/*
* Parse ConOut (the list of consoles active) and see if we can find a serial
* port and/or a video port. It would be nice to also walk the ACPI DSDT to map
* the UID for the serial port to a port since there's no standard mapping. Also
* check for ConIn as well. This will be enough to determine if we have serial,
* and if we don't, we default to video. If there's a dual-console situation
* with only ConIn defined, this will currently fail.
*/
int
parse_uefi_con_out(void)
@ -744,7 +944,12 @@ parse_uefi_con_out(void)
UART_DEVICE_PATH *uart;
bool pci_pending;
how = 0;
/*
* A SPCR in the ACPI fixed tables documents a serial port used for the
* console. It may mirror a video console, or may be stand alone. If it
* is present, we return RB_SERIAL and will use it for the kernel.
*/
how = check_acpi_spcr();
sz = sizeof(buf);
rv = efi_global_getenv("ConOut", buf, &sz);
if (rv != EFI_SUCCESS)
@ -753,18 +958,18 @@ parse_uefi_con_out(void)
rv = efi_global_getenv("ConIn", buf, &sz);
if (rv != EFI_SUCCESS) {
/*
* If we don't have any ConOut default to both. If we have GOP
* make video primary, otherwise just make serial primary. In
* either case, try to use both the 'efi' console which will use
* the GOP, if present and serial. If there's an EFI BIOS that
* omits this, but has a serial port redirect, we'll
* unavioidably get doubled characters (but we'll be right in
* all the other more common cases).
* If we don't have any Con* variable use both. If we have GOP
* make video primary, otherwise set serial primary. In either
* case, try to use both the 'efi' console which will use the
* GOP, if present and serial. If there's an EFI BIOS that omits
* this, but has a serial port redirect, we'll unavioidably get
* doubled characters, but we'll be right in all the other more
* common cases.
*/
if (efi_has_gop())
how = RB_MULTIPLE;
how |= RB_MULTIPLE;
else
how = RB_MULTIPLE | RB_SERIAL;
how |= RB_MULTIPLE | RB_SERIAL;
setenv("console", "efi,comconsole", 1);
goto out;
}
@ -915,7 +1120,6 @@ ptov(uintptr_t x)
static void
acpi_detect(void)
{
ACPI_TABLE_RSDP *rsdp;
char buf[24];
int revision;

View File

@ -350,7 +350,9 @@ struct l_statx {
#define LINUX_ST_RELATIME 0x1000 /* No native analogue */
#define LINUX_ST_NOSYMFOLLOW 0x2000
#ifndef lower_32_bits
#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
#endif
#ifdef KTRACE
#define linux_ktrsigset(s, l) \

View File

@ -571,7 +571,7 @@ uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int
error = UART_PROBE(sc);
bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
return ((error) ? error : BUS_PROBE_DEFAULT);
return ((error) ? error : 0);
}
int

View File

@ -167,28 +167,46 @@ uart_cpu_acpi_spcr(int devtype, struct uart_devinfo *di)
if (error != 0)
goto out;
switch (spcr->BaudRate) {
case 0:
/* Special value; means "keep current value unchanged". */
di->baudrate = 0;
break;
case 3:
di->baudrate = 9600;
break;
case 4:
di->baudrate = 19200;
break;
case 6:
di->baudrate = 57600;
break;
case 7:
di->baudrate = 115200;
break;
default:
printf("SPCR has reserved BaudRate value: %d!\n",
(int)spcr->BaudRate);
goto out;
/*
* SPCR Rev 4 and newer allow a precise baudrate to be passed in for
* things like 1.5M or 2.0M. If we have that, then use that value,
* otherwise try to decode the older enumeration.
*/
if (spcr->Header.Revision >= 4 && spcr->PreciseBaudrate != 0) {
di->baudrate = spcr->PreciseBaudrate;
} else {
switch (spcr->BaudRate) {
case 0:
/* Special value; means "keep current value unchanged". */
di->baudrate = 0;
break;
case 3:
di->baudrate = 9600;
break;
case 4:
di->baudrate = 19200;
break;
case 6:
di->baudrate = 57600;
break;
case 7:
di->baudrate = 115200;
break;
default:
printf("SPCR has reserved BaudRate value: %d!\n",
(int)spcr->BaudRate);
goto out;
}
}
/*
* Rev 3 and newer can specify a rclk, use it if it's there. It's
* defined to be 0 when it's not known, and we've initialized rclk to 0
* in uart_cpu_acpi_init_devinfo, so we don't have to test for it.
*/
if (spcr->Header.Revision >= 3)
di->bas.rclk = spcr->UartClkFreq;
/*
* If no rclk is set, then we will assume the BIOS has configured the
* hardware at the stated baudrate, so we can use it to guess the rclk

View File

@ -231,6 +231,24 @@ uart_pl011_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
__uart_setreg(bas, UART_IFLS, FIFO_IFLS_BITS);
__uart_setreg(bas, UART_CR, ctrl);
/*
* Loader tells us to infer the rclk when it sets xo to 0 in
* hw.uart.console. The APCI SPCR code does likewise. We know the
* baudrate was set by the firmware, so calculate rclk from baudrate and
* the divisor register. If 'div' is actually 0, the resulting 0 value
* will have us fall back to other rclk methods. This method should be
* good to 5% or better because the error in baud rates needs to be
* below this for devices to communicate.
*/
if (bas->rclk == 0 && baudrate > 0 && bas->rclk_guess) {
uint32_t div;
div = ((__uart_getreg(bas, UART_IBRD) & IBRD_BDIVINT) << 6) |
(__uart_getreg(bas, UART_FBRD) & FBRD_BDIVFRAC);
bas->rclk = (div * baudrate) / 4;
}
}
static void

View File

@ -87,7 +87,7 @@ static void acpi_print_facs(ACPI_TABLE_FACS *facs);
static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp, const char *elm);
static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
void (*action)(ACPI_SUBTABLE_HEADER *));
static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
@ -275,7 +275,7 @@ acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
if (addr != 0) {
facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 ||
if (memcmp(facs->Signature, ACPI_SIG_FACS, ACPI_NAMESEG_SIZE) != 0 ||
facs->Length < 64)
errx(1, "FACS is corrupt");
acpi_print_facs(facs);
@ -2545,8 +2545,51 @@ acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
printf(END_COMMENT);
}
static struct {
const char *sig;
void (*fnp)(ACPI_TABLE_HEADER *);
} known[] = {
{ ACPI_SIG_BERT, acpi_handle_bert },
{ ACPI_SIG_DMAR, acpi_handle_dmar },
{ ACPI_SIG_ECDT, acpi_handle_ecdt },
{ ACPI_SIG_EINJ, acpi_handle_einj },
{ ACPI_SIG_ERST, acpi_handle_erst },
{ ACPI_SIG_FADT, acpi_handle_fadt },
{ ACPI_SIG_HEST, acpi_handle_hest },
{ ACPI_SIG_HPET, acpi_handle_hpet },
{ ACPI_SIG_IVRS, acpi_handle_ivrs },
{ ACPI_SIG_LPIT, acpi_handle_lpit },
{ ACPI_SIG_MADT, acpi_handle_madt },
{ ACPI_SIG_MCFG, acpi_handle_mcfg },
{ ACPI_SIG_NFIT, acpi_handle_nfit },
{ ACPI_SIG_SLIT, acpi_handle_slit },
{ ACPI_SIG_SPCR, acpi_handle_spcr },
{ ACPI_SIG_SRAT, acpi_handle_srat },
{ ACPI_SIG_TCPA, acpi_handle_tcpa },
{ ACPI_SIG_TPM2, acpi_handle_tpm2 },
{ ACPI_SIG_WDDT, acpi_handle_wddt },
};
static void
acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
acpi_report_sdp(ACPI_TABLE_HEADER *sdp)
{
for (u_int i = 0; i < nitems(known); i++) {
if (memcmp(sdp->Signature, known[i].sig, ACPI_NAMESEG_SIZE) != 0) {
known[i].fnp(sdp);
return;
}
}
/*
* Otherwise, do a generic thing.
*/
printf(BEGIN_COMMENT);
acpi_print_sdt(sdp);
printf(END_COMMENT);
}
static void
acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp, const char *tbl)
{
ACPI_TABLE_HEADER *sdp;
ACPI_TABLE_RSDT *rsdt;
@ -2554,7 +2597,14 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
vm_offset_t addr;
int entries, i;
acpi_print_rsdt(rsdp);
if (tbl == NULL) {
acpi_print_rsdt(rsdp);
} else {
if (memcmp(tbl, rsdp->Signature, ACPI_NAMESEG_SIZE) == 0) {
acpi_print_rsdt(rsdp);
return;
}
}
rsdt = (ACPI_TABLE_RSDT *)rsdp;
xsdt = (ACPI_TABLE_XSDT *)rsdp;
entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
@ -2571,49 +2621,9 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
sdp->Signature);
continue;
}
if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
acpi_handle_bert(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
acpi_handle_einj(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
acpi_handle_erst(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
acpi_handle_fadt(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
acpi_handle_madt(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
acpi_handle_hest(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
acpi_handle_hpet(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
acpi_handle_ecdt(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
acpi_handle_mcfg(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
acpi_handle_slit(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
acpi_handle_srat(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
acpi_handle_tcpa(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
acpi_handle_dmar(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_IVRS, 4))
acpi_handle_ivrs(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
acpi_handle_nfit(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
acpi_handle_wddt(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
acpi_handle_lpit(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
acpi_handle_tpm2(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
acpi_handle_spcr(sdp);
else {
printf(BEGIN_COMMENT);
acpi_print_sdt(sdp);
printf(END_COMMENT);
}
if (tbl != NULL && memcmp(sdp->Signature, tbl, ACPI_NAMESEG_SIZE) != 0)
continue;
acpi_report_sdp(sdp);
}
}
@ -2631,13 +2641,13 @@ sdt_load_devmem(void)
acpi_print_rsd_ptr(rp);
if (rp->Revision < 2) {
rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
if (memcmp(rsdp->Signature, "RSDT", ACPI_NAMESEG_SIZE) != 0 ||
acpi_checksum(rsdp, rsdp->Length) != 0)
errx(1, "RSDT is corrupted");
addr_size = sizeof(uint32_t);
} else {
rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
if (memcmp(rsdp->Signature, "XSDT", ACPI_NAMESEG_SIZE) != 0 ||
acpi_checksum(rsdp, rsdp->Length) != 0)
errx(1, "XSDT is corrupted");
addr_size = sizeof(uint64_t);
@ -2801,9 +2811,9 @@ aml_disassemble_separate(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
}
void
sdt_print_all(ACPI_TABLE_HEADER *rsdp)
sdt_print_all(ACPI_TABLE_HEADER *rsdp, const char *tbl)
{
acpi_handle_rsdt(rsdp);
acpi_handle_rsdt(rsdp, tbl);
}
/* Fetch a table matching the given signature via the RSDT. */

View File

@ -42,7 +42,7 @@
#include "acpidump.h"
static char hint_acpi_0_rsdp[] = "hint.acpi.0.rsdp";
static char acpi_rsdp[] = "acpi.rsdp";
static char machdep_acpi_root[] = "machdep.acpi_root";
static int acpi_mem_fd = -1;
@ -172,7 +172,7 @@ acpi_find_rsd_ptr(void)
addr = 0;
/* Attempt to use kenv or sysctl to find RSD PTR record. */
if (kenv(KENV_GET, hint_acpi_0_rsdp, buf, 20) > 0)
if (kenv(KENV_GET, acpi_rsdp, buf, 20) > 0)
addr = strtoul(buf, NULL, 0);
if (addr == 0) {
len = sizeof(addr);

View File

@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd June 29, 2020
.Dd October 5, 2024
.Dt ACPIDUMP 8
.Os
.Sh NAME
@ -36,11 +36,12 @@
.Sh SYNOPSIS
.Nm
.Op Fl d
.Op Fl t
.Op Fl h
.Op Fl v
.Op Fl f Ar dsdt_input
.Op Fl h
.Op Fl o Ar dsdt_output
.Op Fl t
.Op Fl T Ar table_name
.Op Fl v
.Sh DESCRIPTION
The
.Nm
@ -88,38 +89,75 @@ called SDTs
and their header has a common format which consists of items
such as Signature, Length, Revision, Checksum, OEMID, OEM Table ID,
OEM Revision, Creator ID and Creator Revision.
.Pp
When invoked with the
.Fl t
flag, the
.Nm
utility dumps contents of the following tables:
utility dumps contents of all the ACPI tables, except the DSDT and SSDT.
The following SDTs are reported in detail, while the remainder will only report
the common header information:
.Pp
.Bl -tag -offset indent -width 12345 -compact
.It BERT
.It DMAR
.It DSDT
.It ECDT
.It EINJ
.It ERST
.It FACS
.It FADT
.It HEST
.It HPET
.It LPIT
.It MADT
.It MCFG
.It NFIT
.It BERT Boot Error Record Table
Reports any previous boot errors.
.It DMAR DMA Remapping Table
Contains information about the DMA remapping necessary for the system
for I/O virtualization on Intel CPUS.
.It DSDT Differentiated System Description Table
Contains the main AML for the system.
.It ECDT Embedded Controller Boot Resources Table
Contains information about accessing the embedded controller
prior to the OS decoding the DSDT for all its details.
.It EINJ Error Injection Table
Use to inject hardware errors to the error reporting mechanisms.
.It ERST Error Record Serialization Table
Information to retrieve and manage errors reported from the hardware.
.It FACS Firmware ACPI Control Structure
Information for the OS to interact with the firmware for things
like suspend / resume and prevent mutual access to resources
shared between the OS and the firmware.
.It FACP Fixed ACPI Description Table (FADT)
Information related to power management, and other CPU related data.
.It HEST Hardware Error Source Table
Describes the possible sources of hardware errors to the OS.
.It HPET High Precision Event Timer Table
Describes the high precision timers in the system.
.It IVRS I/O Virtualization Reporting Structure
Information for hypvervisors to use to share I/O resources on AMD
processors.
.It LPIT Low Power Idle Table
Power management information for reducing power usage of the system.
.It MADT Multiple APIC Description Table
Describes all the Advanced Programmable Interrupt Controllers and
Intel Streamlined Advanced Programmable Interrupt Controller present
in the system.
.It MCFG PCI Express Memory-mapped Configuration
PCI config space base address register.
.It NFIT NVDIMM Firmware Interface Table
NVDIMM information in the system.
.It RSD PTR
.It RSDT
.It SLIT
.It SRAT
.It TCPA
.It TPM2
.It WDDT
Pointer to the RSDT.
.It RSDT Root System Description Table
An array of physical pointers to other system description tables,
the FACP (Fixed ACPI Description Table).
.It SLIT System Locality Distance Information Table
Provides information about the cost of communicating between different
parts of the system (NUMA).
.It SPCR Serial Port Console Redirection
Contains informatiom about any serial port that the firmware used as
a reporting console.
.It SRAT System Resource Affinity Table
Defines the domains of locality in the system for processors, memory
and generic initiators (eg PCIe root complexes).
.It TCPA Trusted Computing Platform Alliance
Information about the TPM elements of the system.
.It TPM2 Trusted Platform Module 2
Additional information about newer TPM hardware.
.It WDDT Watchdog Timer Description Table
Information about how to manage watchdog timers in the system.
.El
.Pp
The RSDT contains a pointer to the physical memory address of the FACP
(Fixed ACPI Description Table).
The FACP defines static system information about power management support
(ACPI Hardware Register Implementation)
such as interrupt mode (INT_MODEL),
@ -138,6 +176,9 @@ Concatenate the DSDT and the SSDT's into single image and disassemble the image
and print the results to stdout.
.It Fl t
Dump the contents of the various fixed tables listed above.
.It Fl T ar table_name
Dump the contents of the specific table.
All ACPI tables are exactly 4 characters long.
.It Fl h
Displays usage and exit.
.It Fl s

View File

@ -45,7 +45,7 @@ usage(const char *progname)
{
fprintf(stderr, "usage: %s [-d] [-t] [-h] [-v] [-f dsdt_input] "
"[-o dsdt_output]\n", progname);
"[-o dsdt_output] [-T table_name]\n", progname);
fprintf(stderr, "To send ASL:\n\t%s -dt | gzip -c9 > foo.asl.gz\n",
progname);
exit(1);
@ -58,6 +58,7 @@ main(int argc, char *argv[])
int c;
char *progname;
char *dsdt_input_file, *dsdt_output_file;
char *tbl = NULL;
dsdt_input_file = dsdt_output_file = NULL;
progname = argv[0];
@ -65,11 +66,18 @@ main(int argc, char *argv[])
if (argc < 2)
usage(progname);
while ((c = getopt(argc, argv, "dhtvsf:o:")) != -1) {
while ((c = getopt(argc, argv, "df:ho:tT:vs")) != -1) {
switch (c) {
case 'd':
dflag = 1;
break;
case 'T':
tbl = optarg;
if (strlen(tbl) != 4) {
warnx("Illegal table name %s", tbl);
usage(progname);
}
break;
case 't':
tflag = 1;
break;
@ -113,10 +121,10 @@ main(int argc, char *argv[])
}
/* Display misc. SDT tables (only available when using /dev/mem) */
if (tflag) {
if (tflag || tbl != NULL) {
if (vflag)
warnx("printing various SDT tables");
sdt_print_all(rsdt);
sdt_print_all(rsdt, tbl);
}
/* Translate RSDT to DSDT pointer */

View File

@ -140,7 +140,7 @@ ACPI_TABLE_HEADER *dsdt_load_file(char *);
void dsdt_save_file(char *, ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *);
/* Print out as many fixed tables as possible, given the RSD PTR */
void sdt_print_all(ACPI_TABLE_HEADER *);
void sdt_print_all(ACPI_TABLE_HEADER *, const char *);
/* Disassemble the AML in the DSDT */
void aml_disassemble(ACPI_TABLE_HEADER *, ACPI_TABLE_HEADER *);