summaryrefslogtreecommitdiffstats
path: root/sys/isa/atrtc.c
Commit message (Collapse)AuthorAgeFilesLines
* atrtc.c is a repocopy of the RTC device driver from i386/isa/clock.cphk2008-04-141-599/+29
| | | | | In addition to the device driver functionality, it exposes a number of functions which various other bits of code use to fondle the RTC chip.
* Move i386 to generic RTC handling code.phk2008-04-121-103/+168
| | | | | | | | | | | | | | | | | | | | | | | | Make clock_if.m and subr_rtc.c standard on i386 Add hints for "atrtc" driver, for non-PnP, non-ACPI systems. NB: Make sure to install GENERIC.hints into /boot/device.hints in these! Nuke MD inittodr(), resettodr() functions. Don't attach to PHP0B00 in the "attimer" dummy driver any more, and remove comments that no longer apply for that reason. Add new "atrtc" device driver, which handles IBM PC AT Real Time Clock compatible devices using subr_rtc and clock_if. This driver is not entirely clean: other code still fondles the hardware to get a statclock interrupt on non-ACPI timer systems. Wrap some overly long lines. After it has settled in -current, this will be ported to amd64. Technically this is MFC'able, but I fail to see a good reason.
* Back in the good old days, PC's had random pieces of rock forphk2008-03-261-122/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | frequency generation and what frequency the generated was anyones guess. In general the 32.768kHz RTC clock x-tal was the best, because that was a regular wrist-watch Xtal, whereas the X-tal generating the ISA bus frequency was much lower quality, often costing as much as several cents a piece, so it made good sense to check the ISA bus frequency against the RTC clock. The other relevant property of those machines, is that they typically had no more than 16MB RAM. These days, CPU chips croak if their clocks are not tightly within specs and all necessary frequencies are derived from the master crystal by means if PLL's. Considering that it takes on average 1.5 second to calibrate the frequency of the i8254 counter, that more likely than not, we will not actually use the result of the calibration, and as the final clincher, we seldom use the i8254 for anything besides BEL in syscons anyway, it has become time to drop the calibration code. If you need to tell the system what frequency your i8254 runs, you can do so from the loader using hw.i8254.freq or using the sysctl kern.timecounter.tc.i8254.frequency.
* The "free-lance" timer in the i8254 is only used for the speakerphk2008-03-261-36/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | these days, so de-generalize the acquire_timer/release_timer api to just deal with speakers. The new (optional) MD functions are: timer_spkr_acquire() timer_spkr_release() and timer_spkr_setfreq() the last of which configures the timer to generate a tone of a given frequency, in Hz instead of 1/1193182th of seconds. Drop entirely timer2 on pc98, it is not used anywhere at all. Move sysbeep() to kern/tty_cons.c and use the timer_spkr*() if they exist, and do nothing otherwise. Remove prototypes and empty acquire-/release-timer() and sysbeep() functions from the non-beeping archs. This eliminate the need for the speaker driver to know about i8254frequency at all. In theory this makes the speaker driver MI, contingent on the timer_spkr_*() functions existing but the driver does not know this yet and still attaches to the ISA bus. Syscons is more tricky, in one function, sc_tone(), it knows the hz and things are just fine. In the other function, sc_bell() it seems to get the period from the KDMKTONE ioctl in terms if 1/1193182th second, so we hardcode the 1193182 and leave it at that. It's probably not important. Change a few other sysbeep() uses which obviously knew that the argument was in terms of i8254 frequency, and leave alone those that look like people thought sysbeep() took frequency in hertz. This eliminates the knowledge of i8254_freq from all but the actual clock.c code and the prof_machdep.c on amd64 and i386, where I think it would be smart to ask for help from the timecounters anyway [TBD].
* Rename timer0_max_count to i8254_max_count.phk2008-03-261-49/+50
| | | | | Rename timer0_real_max_count to i8254_real_max_count and make it static. Rename timer_freq to i8254_freq and make it a loader tunable.
* The RTC related pscnt and psdiv variables have no business being public.phk2008-03-261-2/+2
|
* Use cpu_spinwait() (i.e., "pause") when spinning on rdtsc during DELAY().jhb2008-01-171-0/+1
| | | | MFC after: 1 week
* Split /dev/nvram driver out of isa/clock.c for i386 and amd64. I have notpeter2007-10-261-96/+1
| | | | | | | | refactored it to be a generic device. Instead of being part of the standard kernel, there is now a 'nvram' device for i386/amd64. It is in DEFAULTS like io and mem, and can be turned off with 'nodevice nvram'. This matches the previous behavior when it was first committed.
* It seems that some i386 mothermoards either do not implement thedwmalone2007-07-271-1/+2
| | | | | | | | | | | | | | | | | | day of week field correctly, or they remember bad values that are written into the day of week field. For this reason, ignore the day of week field when reading the clock on i386 rather than bailing if it is set incorrectly. Problems were seen on a number of platforms, including VMWare, qemu, EPIA ME6000, Epox-3PTA and ABIT-SL30T. This is a slightly different fix to that proposed by Ted in his PR, but the same basic idea. PR: 111117 Submitted by: Ted Faber <faber@lunabase.org> Approved by: re (rwatson) MFC after: 3 weeks
* If clock_ct_to_ts fails to convert time time from the real time clock,dwmalone2007-07-231-3/+6
| | | | | | | | | print a one line error message. Add some comments on not being able to trust the day of week field (I'll act on these comments in a follow up commit). Approved by: re MFC after: 3 weeks
* Prototype (but functional) Linux-ish /dev/nvram interface to the extrapeter2007-06-151-0/+99
| | | | | | | | | | | | 114 bytes of cmos ram in the PC clock chip. The big difference between this and the Linux version is that we do not recalculate the checksums for bytes 16..31. We use this at work when cloning identical machines - we can copy the bios settings as well. Reading /dev/nvram gives 114 bytes of data but you can seek/read/write whichever bytes you like. Yes, this is a "foot, gun, fire!" type of device.
* Despite several examples in the kernel, the third argument ofdwmalone2007-06-041-1/+1
| | | | | | | | | | | | | sysctl_handle_int is not sizeof the int type you want to export. The type must always be an int or an unsigned int. Remove the instances where a sizeof(variable) is passed to stop people accidently cut and pasting these examples. In a few places this was sysctl_handle_int was being used on 64 bit types, which would truncate the value to be exported. In these cases use sysctl_handle_quad to export them and change the format to Q so that sysctl(1) can still print them.
* Partial fix for a bug in rev.1.231. If suspend/resume clobbers thebde2007-03-051-0/+1
| | | | | | | | | | | | | | | | | RTC state, then it may clobber the RTC index register, so the index register must be restored before using it to restore control registers in rtc_restore(). The following problems remain: - rtc_restore() is only called if pmtimer is configured. Buggy suspend/resumes are more likely to clobber the index register than a control register, so pmtimer is more needed than it used to be. - pmtimer doesn't exist for amd64. - Restoring of the RTC state may race with rtcintr(). If an RTC interrupt is handled before the state is restored, then rtcin(RTC_INTR) in rtcintr() may read from the wrong register, so rtcintr() may spin forever. This may be mitigated by the most common state clobbering being to turn off RTC interrupts.
* style(9).nyan2007-03-041-2/+2
|
* o break newbus api: add a new argument of type driver_filter_t topiso2007-02-231-6/+8
| | | | | | | | | | | | | bus_setup_intr() o add an int return code to all fast handlers o retire INTR_FAST/IH_FAST For more info: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=465712+0+current/freebsd-current Reviewed by: many Approved by: re@
* Cleaned up declaration and initialization of clock_lock. It is onlybde2007-01-231-13/+10
| | | | | | | | | | | | | | | | | | | | used by clock code, so don't export it to the world for machdep.c to initialize. There is a minor problem initializing it before it is used, since although clock initialization is split up so that parts of it can be done early, the first part was never done early enough to actually work. Split it up a bit more and do the first part as late as possible to document the necessary order. The functions that implement the split are still bogusly exported. Cleaned up initialization of the i8254 clock hardware using the new split. Actually initialize it early enough, and don't work around it not being initialized in DELAY() when DELAY() is called early for initialization of some console drivers. This unfortunately moves a little more code before the early debugger breakpoint so that it is harder to debug. The ordering of console and related initialization is delicate because we want to do as little as possible before the breakpoint, but must initialize a console.
* Optimized RTC accesses by avoiding null writes to the index registerbde2006-12-031-9/+16
| | | | | | | | | | | | | | | | | | | | | | | | | and by only delaying when an RTC register is written to. The delay after writing to the data register is now not just a workaround. This reduces the number of ISA accesses in the usual case from 4 to 1. The usual case is 2 rtcin()'s for each RTC interrupt. The index register is almost always RTC_INTR for this. The 3 extra ISA accesses were 1 for writing the index and 2 for delays. Some delays are needed in theory, but in practice they now just slow down slow accesses some more since almost eveyone including us does them wrong so modern systems enforce sufficient delays in hardware. I used to have the delays ifdefed out, but with the index register optimization the delays are rarely executed so the old magic ones can be kept or even implemented non- magically without significant cost. Optimizing RTC interrupt handling is more interesting than it used to be because RTC interrupts are currently needed to fix the more efficient apic timer interrupts on some systems. apic_timer_hz is normally 2000 so the RTC interrupt rate needs to be 2048 to keep the apic timer firing on such systems. Without these changes, each RTC interrupt normally took 10 ISA accesses (2 PIC accesses and 2 sets of 4 RTC accesses). Each ISA access takes 1-1.5uS so 10 of then at 2048 Hz takes 2-3% of a CPU. Now 4 of them take 0.8-1.2% of a CPU.
* Use calendaric calculation support from subr_clock.c instead of home-rolled.phk2006-10-021-88/+33
| | | | Eventually, this RTC should probably use subr_rtc.c as well
* Second part of a little cleanup in the calendar/timezone/RTC handling.phk2006-10-021-3/+0
| | | | | | | | | | | Split subr_clock.c in two parts (by repo-copy): subr_clock.c contains generic RTC and calendaric stuff. etc. subr_rtc.c contains the newbus'ified RTC interface. Centralize the machdep.{adjkerntz,disable_rtc_set,wall_cmos_clock} sysctls and associated variables into subr_clock.c. They are not machine dependent and we have generic code that relies on being present so they are not even optional.
* First part of a little cleanup in the calendar/timezone/RTC handling.phk2006-10-021-0/+1
| | | | | | Move relevant variables to <sys/clock.h> and fix #includes as necessary. Use libkern's much more time- & spamce-efficient BCD routines.
* Eliminate one set of XBOX #ifdefs. The Xbox code just needs to set aimp2006-08-091-9/+0
| | | | | different TIMER_FREQ value than default. Accomplish this via the config file rather than via an #ifdef.
* Tweak how the MD code calls the fooclock() methods some. Instead ofjhb2005-12-221-6/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | passing a pointer to an opaque clockframe structure and requiring the MD code to supply CLKF_FOO() macros to extract needed values out of the opaque structure, just pass the needed values directly. In practice this means passing the pair (usermode, pc) to hardclock() and profclock() and passing the boolean (usermode) to hardclock_cpu() and hardclock_process(). Other details: - Axe clockframe and CLKF_FOO() macros on all architectures. Basically, all the archs were taking a trapframe and converting it into a clockframe one way or another. Now they can just extract the PC and usermode values directly out of the trapframe and pass it to fooclock(). - Renamed hardclock_process() to hardclock_cpu() as the latter is more accurate. - On Alpha, we now run profclock() at hz (profhz == hz) rather than at the slower stathz. - On Alpha, for the TurboLaser machines that don't have an 8254 timecounter, call hardclock() directly. This removes an extra conditional check from every clock interrupt on Alpha on the BSP. There is probably room for even further pruning here by changing Alpha to use the simplified timecounter we use on x86 with the lapic timer since we don't get interrupts from the 8254 on Alpha anyway. - On x86, clkintr() shouldn't ever be called now unless using_lapic_timer is false, so add a KASSERT() to that affect and remove a condition to slightly optimize the non-lapic case. - Change prototypeof arm_handler_execute() so that it's first arg is a trapframe pointer rather than a void pointer for clarity. - Use KCOUNT macro in profclock() to lookup the kernel profiling bucket. Tested on: alpha, amd64, arm, i386, ia64, sparc64 Reviewed by: bde (mostly)
* MFamd64 rev 1.223: Use the TSC to implement DELAY() if not marked brokenpeter2005-12-131-0/+15
| | | | and it has been calibrated.
* Add support for XBOX to the FreeBSD port. The xbox architecture isimp2005-11-091-0/+10
| | | | | | | | | | | | | | | | | | | | nearly identical to wintel/ia32, with a couple of tweaks. Since it is so similar to ia32, it is optionally added to a i386 kernel. This port is preliminary, but seems to work well. Further improvements will improve the interaction with syscons(4), port Linux nforce driver and future versions of the xbox. This supports the 64MB and 128MB boxes. You'll need the most recent CVS version of Cromwell (the Linux BIOS for the XBOX) to boot. Rink will be maintaining this port, and is interested in feedback. He's setup a website http://xbox-bsd.nl to report the latest developments. Any silly mistakes are my fault. Submitted by: Rink P.W. Springer rink at stack dot nl and Ed Schouten ed at fxq dot nl
* Fixup some more fallout from the lapic/i8254 changes:jhb2005-07-131-24/+20
| | | | | | | | | | | | - Make sure timer0_max_count is set to a correct value in the lapic case. - Revert i8254_restore() to explicitly reprogram timer 0 rather than calling set_timer_freq() to do it. set_timer_freq() only reprograms the counter if the max count changes which it never does on resume. This unbreaks suspend/resume for several people. Tested by: marks, others Reviewed by: bde MFC after: 3 days
* Remove a || 1 that crept into the i8254 commit and was subsequentlyjhb2005-07-051-1/+1
| | | | | | | | | copied and pasted. I had actually tested without this change in my trees as had the other testers. Reported by: bde, Rostislav Krasny rosti dot bsd at gmail dot com Approved by: re (scottl) Pointy hat to: jhb
* Use a simpler implementation for the i8254 timecounter when using the lapicjhb2005-07-011-12/+35
| | | | | | | | | | timer since irq0 isn't being driven at hz in that case and we don't need to try to handle edge cases with rollover, etc. that require irq0 to be firing for the timecounter to actually work. Submitted by: phk Tested by: schweikh Approved by: re (scottl)
* - Move timerreg.h to <arch>/include and split i8253 specific defines intonyan2005-05-141-8/+8
| | | | | | | | | i8253reg.h, and add some defines to control a speaker. - Move PPI related defines from i386/isa/spkr.c into ppireg.h and use them. - Move IO_{PPI,TIMER} defines into ppireg.h and timerreg.h respectively. - Use isa/isareg.h rather than <arch>/isa/isa.h. Tested on: i386, pc98
* Replace spl protection in rtcin() and writertc() with spinlocksmdodd2005-04-121-6/+6
| | | | using the existing clock_lock mutex.
* - Don't enable periodic interrupts from the RTC by default in rtc_statusb.jhb2005-03-241-22/+26
| | | | | | | | Instead, explicitly enable them when we setup the interrupt handler. Also, move the setting of stathz and profhz down to the same place so that the code flow is simpler and easier to follow. - Don't setup an interrupt handler for IRQ0 if we are using the lapic timer as it doesn't do anything productive in that case.
* Whitespace sync with amd64. (Rather than re-add the extra blank linespeter2005-03-111-3/+0
| | | | on amd64, I'm removing them here)
* - Remove the BURN_BRIDGES marked support for hooking into the ISA timer 0jhb2005-03-091-144/+2
| | | | | | | | interrupt. - Remove the timer_func variable as it now has a static value of hardclock() and is only used in one place. Axe borrowed from: phk
* Use the local APIC timer to drive the various kernel clocks on SMP machinesjhb2005-02-081-19/+19
| | | | | | | | | | | | | | | | | | | | | | | rather than forwarding interrupts from the clock devices around using IPIs: - Add an IDT vector that pushes a clock frame and calls lapic_handle_timer(). - Add functions to program the local APIC timer including setting the divisor, and setting up the timer to either down a periodic countdown or one-shot countdown. - Add a lapic_setup_clock() function that the BSP calls from cpu_init_clocks() to setup the local APIC timer if it is going to be used. The setup uses a one-shot countdown to calibrate the timer. We then program the timer on each CPU to fire at a frequency of hz * 3. stathz is defined as freq / 23 (hz * 3 / 23), and profhz is defined as freq / 2 (hz * 3 / 2). This gives the clocks relatively prime divisors while keeping a low LCM for the frequency of the clock interrupts. Thanks to Peter Jeremy for suggesting this approach. - Remove the hardclock and statclock forwarding code including the two associated IPIs. The bitmap IPI handler has now effectively degenerated to just IPI_AST. - When the local APIC timer is used we don't turn the RTC on at all, but we still enable interrupts on the ISA timer 0 (i8254) for timecounting purposes.
* Anytime we write to the RTC's status B register to possibly enablejhb2005-02-031-0/+3
| | | | | | | | | | | interrupts, read from the interrupt status register to clear any pending interrupts. Otherwise in some rare cases the RTC would never fire any interrupts as it constantly thinks it has an interrupt pending. PR: i386/17800 PR: kern/76776 Submitted by: Jose M. Alcaide jose at we dot lc dot ehu dot es MFC after: 2 weeks
* Partially revert previous commit. Calling getit() unconditionally fixedmarcel2004-07-111-11/+22
| | | | | | | | | | | | | | a problem that could also be fixed differently without reverting previous attempts to fix DELAY while the debugger is active (rev 1.204). The bug was that the i8254 implements a countdown timer, while for (k)db_active a countup timer was implemented. This resulted in premature termination and consequently the breakage of DELAY. The fix (relative to rev 1.211) is to implement a countdown timer for the kdb_active case. As such the ability to step clock initialization is preserved and DELAY does what is expected of it. Blushed: bde :-) Submitted by: bde
* Call getit() unconditionally and only grab clock_lock when themarcel2004-07-101-20/+13
| | | | | | debugger is not active. The fixes breakages of DELAY() when running in the debugger, because not calling getit() when the debugger is active yields a DELAY that doesn't.
* Add some missing <sys/module.h> includes which are masked by thephk2004-05-301-0/+1
| | | | one on death-row in <sys/kernel.h>
* Trim unused includes.jhb2004-05-111-1/+0
|
* - The i8254 uses IRQ 0, not IRQ 8. Correct i8254_intsrc to reference thejhb2004-04-271-4/+6
| | | | | | | | correct interrupt source. - Cache a pointer to the i8254_intsrc's pending method to avoid several pointer indirections in i8254_get_timecount(). Reported by: bde
* Remove advertising clause from University of California Regent'simp2004-04-071-4/+0
| | | | | | | license, per letter dated July 22, 1999 and email from Peter Wemm, Alan Cox and Robert Watson. Approved by: core, peter, alc, rwatson
* Don't disable the TSC with statclock_disable.phk2003-11-131-9/+9
|
* New APIC support code:jhb2003-11-031-182/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - The apic interrupt entry points have been rewritten so that each entry point can serve 32 different vectors. When the entry is executed, it uses one of the 32-bit ISR registers to determine which vector in its assigned range was triggered. Thus, the apic code can support 159 different interrupt vectors with only 5 entry points. - We now always to disable the local APIC to work around an errata in certain PPros and then re-enable it again if we decide to use the APICs to route interrupts. - We no longer map IO APICs or local APICs using special page table entries. Instead, we just use pmap_mapdev(). We also no longer export the virtual address of the local APIC as a global symbol to the rest of the system, but only in local_apic.c. To aid this, the APIC ID of each CPU is exported as a per-CPU variable. - Interrupt sources are provided for each intpin on each IO APIC. Currently, each source is given a unique interrupt vector meaning that PCI interrupts are not shared on most machines with an I/O APIC. That mapping for interrupt sources to interrupt vectors is up to the APIC enumerator driver however. - We no longer probe to see if we need to use mixed mode to route IRQ 0, instead we always use mixed mode to route IRQ 0 for now. This can be disabled via the 'NO_MIXED_MODE' kernel option. - The npx(4) driver now always probes to see if a built-in FPU is present since this test can now be performed with the new APIC code. However, an SMP kernel will panic if there is more than one CPU and a built-in FPU is not found. - PCI interrupts are now properly routed when using APICs to route interrupts, so remove the hack to psuedo-route interrupts when the intpin register was read. - The apic.h header was moved to apicreg.h and a new apicvar.h header that declares the APIs used by the new APIC code was added.
* Per TRB vote: restore the aquire_timer0 and associated goo. This willimp2003-09-241-2/+146
| | | | | | | | be gone in FreeBSD 6, so put BURN_BRIDGES around it. The TRB also felt that if something better comes along sooner, it can be used to replace this code. Delayed by: BSDcon and subsequent disk crash.
* clock.c:bde2003-09-071-2/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | Quick fix for calling DELAY() for ddb input in some (atkbd-based) console drivers. ddb must not use any normal locks, but DELAY() normally calls getit() which needs clock_lock. One problem with using normal locks in ddb is that deadlock is possible, but deadlock on clock_lock is unlikely becaluse clock_lock is bogusly recursive, apparently just to hide the problem of ddb using it. The i8254 clock hardware has mostly write-only registers so it is important for it to use a lock that gives exclusive access. (atkbd hardware is also unfriendly to reentrant software but that problem is more local and already solved.) I mostly saw the symptoms of the bug caused by unlocking in getit() running cpu_unpend(). cpu_unpend() should not be called while in ddb and Debugger() calls for failing assertions about this caused a breakpoint within ddb. ddb must also not call getit() because ddb may be being used to step through clock initialization code that has stopped or otherwise mangled the clock. If the clock is stopped, then getit() always returns the same value and DELAY() takes forever if it trusts getit(). The quick fix is implement DELAY(n) as (n * timer_freq / 1000000) inb(0x84)'s if ddb is active. machdep.c: Don't permit recursion on clock_lock.
* Give timecounters a numeric quality field.phk2003-08-161-1/+2
| | | | | | | | | | | | | | | | A timecounter will be selected when registered if its quality is not negative and no less than the current timecounters. Add a sysctl to report all available timecounters and their qualities. Give the dummy timecounter a solid negative quality of minus a million. Give the i8254 zero and the ACPI 1000. The TSC gets 800, unless APM or SMP forces it negative. Other timecounters default to zero quality and thereby retain current selection behaviour.
* remove acquire_timer0() and release_timer0() and related stuff.phk2003-08-151-134/+2
|
* Dont initialize a TSC timecounter until we know if it is broken or not.phk2003-08-061-0/+1
|
* Use __FBSDID().obrien2003-06-021-1/+3
|
* Don't rely on boolean expression evaluating to 1 or 0 by default.phk2003-05-311-1/+1
| | | | Found by: FlexeLint
* Deprecate machine/limits.h in favor of new sys/limits.h.kan2003-04-291-1/+1
| | | | | | | Change all in-tree consumers to include <sys/limits.h> Discussed on: standards@ Partially submitted by: Craig Rodrigues <rodrigc@attbi.com>
OpenPOWER on IntegriCloud