View | Details | Raw Unified | Return to bug 207419 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/x86/isa/atrtc.c (-6 / +128 lines)
Lines 31-36 Link Here
31
__FBSDID("$FreeBSD$");
31
__FBSDID("$FreeBSD$");
32
32
33
#include "opt_isa.h"
33
#include "opt_isa.h"
34
#include "opt_acpi.h"
34
35
35
#include <sys/param.h>
36
#include <sys/param.h>
36
#include <sys/systm.h>
37
#include <sys/systm.h>
Lines 53-67 __FBSDID("$FreeBSD$"); Link Here
53
#include <machine/intr_machdep.h>
54
#include <machine/intr_machdep.h>
54
#include "clock_if.h"
55
#include "clock_if.h"
55
56
57
#include <contrib/dev/acpica/include/acpi.h>
58
#include <contrib/dev/acpica/include/accommon.h>
59
#include <dev/acpica/acpivar.h>
60
56
#define	RTC_LOCK	do { if (!kdb_active) mtx_lock_spin(&clock_lock); } while (0)
61
#define	RTC_LOCK	do { if (!kdb_active) mtx_lock_spin(&clock_lock); } while (0)
57
#define	RTC_UNLOCK	do { if (!kdb_active) mtx_unlock_spin(&clock_lock); } while (0)
62
#define	RTC_UNLOCK	do { if (!kdb_active) mtx_unlock_spin(&clock_lock); } while (0)
58
63
64
#define IO_DELAY()	(void)inb(0x84)
65
#define IO_RTC_ADDR	(IO_RTC + 0)
66
#define IO_RTC_DATA	(IO_RTC + 1)
67
59
int	atrtcclock_disable = 0;
68
int	atrtcclock_disable = 0;
60
69
61
static	int	rtc_reg = -1;
70
static	int	rtc_reg = -1;
62
static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
71
static	u_char	rtc_statusa = RTCSA_DIVIDER | RTCSA_NOPROF;
63
static	u_char	rtc_statusb = RTCSB_24HR;
72
static	u_char	rtc_statusb = RTCSB_24HR;
64
73
74
#ifndef ATRTC_VERBOSE
75
#define ATRTC_VERBOSE 1
76
#endif
77
78
static unsigned int atrtc_verbose = ATRTC_VERBOSE;
79
SYSCTL_UINT(_debug, OID_AUTO, atrtc_verbose, CTLFLAG_RWTUN,
80
	&atrtc_verbose, 0, "AT-RTC Debug Level (0-2)");
81
#define ATRTC_DBG_PRINTF(level, format, ...) \
82
	if (atrtc_verbose >= level) printf(format, ##__VA_ARGS__)
83
65
/*
84
/*
66
 * RTC support routines
85
 * RTC support routines
67
 */
86
 */
Lines 73-82 rtcin(int reg) Link Here
73
92
74
	RTC_LOCK;
93
	RTC_LOCK;
75
	if (rtc_reg != reg) {
94
	if (rtc_reg != reg) {
76
		inb(0x84);
95
		IO_DELAY();
77
		outb(IO_RTC, reg);
96
		outb(IO_RTC, reg);
78
		rtc_reg = reg;
97
		rtc_reg = reg;
79
		inb(0x84);
98
		IO_DELAY();
80
	}
99
	}
81
	val = inb(IO_RTC + 1);
100
	val = inb(IO_RTC + 1);
82
	RTC_UNLOCK;
101
	RTC_UNLOCK;
Lines 89-104 writertc(int reg, u_char val) Link Here
89
108
90
	RTC_LOCK;
109
	RTC_LOCK;
91
	if (rtc_reg != reg) {
110
	if (rtc_reg != reg) {
92
		inb(0x84);
111
		IO_DELAY();
93
		outb(IO_RTC, reg);
112
		outb(IO_RTC, reg);
94
		rtc_reg = reg;
113
		rtc_reg = reg;
95
		inb(0x84);
114
		IO_DELAY();
96
	}
115
	}
97
	outb(IO_RTC + 1, val);
116
	outb(IO_RTC + 1, val);
98
	inb(0x84);
117
	IO_DELAY();
99
	RTC_UNLOCK;
118
	RTC_UNLOCK;
100
}
119
}
101
120
121
static void
122
acpi_cmos_read(ACPI_PHYSICAL_ADDRESS address, UINT8 *buf, UINT32 buflen)
123
{
124
	UINT32 offset;
125
126
	for (offset = 0; offset < buflen; ++offset) {
127
		buf[offset] = rtcin(address + offset) & 0xff;
128
	}
129
}
130
131
static void
132
acpi_cmos_write(ACPI_PHYSICAL_ADDRESS address, const UINT8 *buf, UINT32 buflen)
133
{
134
	UINT32 offset;
135
136
	for (offset = 0; offset < buflen; ++offset) {
137
		writertc(address + offset, buf[offset]);
138
	}
139
}
140
102
static __inline int
141
static __inline int
103
readrtc(int port)
142
readrtc(int port)
104
{
143
{
Lines 161-169 struct atrtc_softc { Link Here
161
	struct resource *intr_res;
200
	struct resource *intr_res;
162
	void *intr_handler;
201
	void *intr_handler;
163
	struct eventtimer et;
202
	struct eventtimer et;
203
	ACPI_HANDLE acpi_handle;	/* Handle of the PNP0B00 node */
204
	int acpi_handle_registered;	/* 0 = acpi_handle not registered */
164
};
205
};
165
206
166
static int
207
static int
208
acpi_check_rtc_access(int is_read, u_long addr, u_long len)
209
{
210
	int retval = 1;	/* Success */
211
212
	if (is_read) {
213
		/* Reading 0x0C will muck with interrupts */
214
		if (addr + len - 1 >= 0x0C && addr <= 0x0c)
215
			retval = 0;
216
	} else {
217
		/* Allow single-byte writes to alarm registers and
218
		 * addr >= 0x30, else deny.
219
		 */
220
		if (!((len == 1 && (addr <= 5 && (addr & 1))) || addr >= 0x30))
221
			retval = 0;
222
	}
223
	return retval;
224
}
225
226
static ACPI_STATUS
227
acpi_rtc_cmos_handler(UINT32 func, ACPI_PHYSICAL_ADDRESS addr,
228
    UINT32 bitwidth, UINT64 *value, void *context, void *region_context)
229
{
230
	struct atrtc_softc *sc;
231
	UINT32 bytewidth = bitwidth >> 3;
232
233
	sc = (struct atrtc_softc *)context;
234
	if (!value || !sc) {
235
		ATRTC_DBG_PRINTF(1, "NULL parameter.\n");
236
		return AE_BAD_PARAMETER;
237
	}
238
	if (bitwidth == 0 || bitwidth > 32 || (bitwidth & 0x07) ||
239
			addr + bytewidth - 1 > 63) {
240
		ATRTC_DBG_PRINTF(1,
241
			"Invalid bitwidth (%u) or addr (0x%08lx).\n",
242
			bitwidth, addr);
243
		return AE_BAD_PARAMETER;
244
	}
245
	if (!acpi_check_rtc_access(func == ACPI_READ, addr, bytewidth)) {
246
		ATRTC_DBG_PRINTF(1, "Bad CMOS %s access at addr 0x%08lx.\n",
247
			func == ACPI_READ ? "read" : "write", addr);
248
		return AE_BAD_PARAMETER;
249
	}
250
251
	switch (func) {
252
		case ACPI_READ:
253
			acpi_cmos_read(addr, (UINT8 *)value, bytewidth);
254
			break;
255
		case ACPI_WRITE:
256
			acpi_cmos_write(addr, (const UINT8 *)value, bytewidth);
257
			break;
258
		default:
259
			ATRTC_DBG_PRINTF(1, "Invalid function: %d.\n", func);
260
			return AE_BAD_PARAMETER;
261
	}
262
	ATRTC_DBG_PRINTF(1, "%-5s%02u addr=%04lx val=%08x\n",
263
			func == ACPI_READ ? "READ" : "WRITE", bytewidth,
264
			addr, *((UINT32 *)value));
265
	return AE_OK;
266
}
267
268
static int
167
rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
269
rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
168
{
270
{
169
271
Lines 245-254 atrtc_attach(device_t dev) Link Here
245
	int i;
347
	int i;
246
348
247
	sc = device_get_softc(dev);
349
	sc = device_get_softc(dev);
350
	sc->acpi_handle = acpi_get_handle(dev);
248
	sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
351
	sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid,
249
	    IO_RTC, IO_RTC + 1, 2, RF_ACTIVE);
352
	    IO_RTC, IO_RTC + 1, 2, RF_ACTIVE);
250
	if (sc->port_res == NULL)
353
	if (sc->port_res == NULL)
251
		device_printf(dev, "Warning: Couldn't map I/O.\n");
354
		device_printf(dev, "Warning: Couldn't map I/O.\n");
355
	if (ACPI_FAILURE(AcpiInstallAddressSpaceHandler(sc->acpi_handle,
356
					ACPI_ADR_SPACE_CMOS,
357
					acpi_rtc_cmos_handler, NULL, sc)))
358
	{
359
		device_printf(dev, "Warning: Couldn't register ACPI CMOS address space handler.\n");
360
		/* I assume the softc was memset() to 0? */
361
	} else
362
		sc->acpi_handle_registered = 1;
252
	atrtc_start();
363
	atrtc_start();
253
	clock_register(dev, 1000000);
364
	clock_register(dev, 1000000);
254
	bzero(&sc->et, sizeof(struct eventtimer));
365
	bzero(&sc->et, sizeof(struct eventtimer));
Lines 286-291 atrtc_attach(device_t dev) Link Here
286
	return(0);
397
	return(0);
287
}
398
}
288
399
400
static int atrtc_detach(device_t dev)
401
{
402
	struct atrtc_softc *sc;
403
404
	sc = device_get_softc(dev);
405
	if (sc->acpi_handle_registered)
406
		AcpiRemoveAddressSpaceHandler(sc->acpi_handle,
407
				ACPI_ADR_SPACE_CMOS, acpi_rtc_cmos_handler);
408
	return bus_generic_detach(dev);
409
}
410
289
static int
411
static int
290
atrtc_resume(device_t dev)
412
atrtc_resume(device_t dev)
291
{
413
{
Lines 366-372 static device_method_t atrtc_methods[] = { Link Here
366
	/* Device interface */
488
	/* Device interface */
367
	DEVMETHOD(device_probe,		atrtc_probe),
489
	DEVMETHOD(device_probe,		atrtc_probe),
368
	DEVMETHOD(device_attach,	atrtc_attach),
490
	DEVMETHOD(device_attach,	atrtc_attach),
369
	DEVMETHOD(device_detach,	bus_generic_detach),
491
	DEVMETHOD(device_detach,	atrtc_detach),
370
	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
492
	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
371
	DEVMETHOD(device_suspend,	bus_generic_suspend),
493
	DEVMETHOD(device_suspend,	bus_generic_suspend),
372
		/* XXX stop statclock? */
494
		/* XXX stop statclock? */

Return to bug 207419