at_rtc: check in ACPI FADT boot flags if the RTC is present
Or else disable the device. Note that the detection can be bypassed by setting the hw.atrtc.enable option in the loader configuration file. More information can be found on atrtc(4). Sponsored by: Citrix Systems R&D Reviewed by: ian Differential revision: https://reviews.freebsd.org/D14399
This commit is contained in:
parent
c2272faa06
commit
4a6d4e7b58
@ -33,13 +33,18 @@
|
||||
.Sh SYNOPSIS
|
||||
This driver is a mandatory part of i386/amd64 kernels.
|
||||
.Pp
|
||||
The following tunable is settable from the
|
||||
The following tunables are settable from the
|
||||
.Xr loader 8 :
|
||||
.Bl -ohang
|
||||
.It Va hint.atrtc. Ns Ar X Ns Va .clock
|
||||
controls event timers functionality support.
|
||||
Setting to 0, disables it.
|
||||
Default value is 1.
|
||||
.It Va hw.atrtc.enable
|
||||
Forces enabling or disabling of the device(s).
|
||||
Setting to 0 disables it, setting to 1 enables it, bypassing any platform
|
||||
configuration hints.
|
||||
Default value is -1 (autodetect).
|
||||
.El
|
||||
.Sh DESCRIPTION
|
||||
This driver uses RTC hardware to supply kernel with time-of-day clock
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_acpi.h"
|
||||
#include "opt_isa.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -55,6 +56,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/intr_machdep.h>
|
||||
#include "clock_if.h"
|
||||
|
||||
#ifdef DEV_ACPI
|
||||
#include <contrib/dev/acpica/include/acpi.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* atrtc_lock protects low-level access to individual hardware registers.
|
||||
* atrtc_time_lock protects the entire sequence of accessing multiple registers
|
||||
@ -63,6 +68,10 @@ __FBSDID("$FreeBSD$");
|
||||
static struct mtx atrtc_lock;
|
||||
MTX_SYSINIT(atrtc_lock_init, &atrtc_lock, "atrtc", MTX_SPIN);
|
||||
|
||||
/* Force RTC enabled/disabled. */
|
||||
static int atrtc_enabled = -1;
|
||||
TUNABLE_INT("hw.atrtc.enabled", &atrtc_enabled);
|
||||
|
||||
struct mtx atrtc_time_lock;
|
||||
MTX_SYSINIT(atrtc_time_lock_init, &atrtc_time_lock, "atrtc_time", MTX_DEF);
|
||||
|
||||
@ -249,11 +258,43 @@ static struct isa_pnp_id atrtc_ids[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static bool
|
||||
atrtc_acpi_disabled(void)
|
||||
{
|
||||
#ifdef DEV_ACPI
|
||||
ACPI_TABLE_FADT *fadt;
|
||||
vm_paddr_t physaddr;
|
||||
uint16_t flags;
|
||||
|
||||
physaddr = acpi_find_table(ACPI_SIG_FADT);
|
||||
if (physaddr == 0)
|
||||
return (false);
|
||||
|
||||
fadt = acpi_map_table(physaddr, ACPI_SIG_FADT);
|
||||
if (fadt == NULL) {
|
||||
printf("at_rtc: unable to map FADT ACPI table\n");
|
||||
return (false);
|
||||
}
|
||||
|
||||
flags = fadt->BootFlags;
|
||||
acpi_unmap_table(fadt);
|
||||
|
||||
if (flags & ACPI_FADT_NO_CMOS_RTC)
|
||||
return (true);
|
||||
#endif
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int
|
||||
atrtc_probe(device_t dev)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
||||
if ((atrtc_enabled == -1 && atrtc_acpi_disabled()) ||
|
||||
(atrtc_enabled == 0))
|
||||
return (ENXIO);
|
||||
|
||||
result = ISA_PNP_PROBE(device_get_parent(dev), dev, atrtc_ids);
|
||||
/* ENOENT means no PnP-ID, device is hinted. */
|
||||
if (result == ENOENT) {
|
||||
|
Loading…
Reference in New Issue
Block a user