On PIIX4 based SMP systems use the PMTMR register for timecounting.

It is about 2.5 microseconds or roughly 3 times faster to use this
"PIIX" timecounter than the "i8254" timecounter.  Resolution is
also 3 times better.

The code cheats and don't register the PCI device, because other pieces
of code want to use it too.

Originally spotted by:  msmith
This commit is contained in:
Poul-Henning Kamp 1999-09-20 07:52:39 +00:00
parent abad681b03
commit 24514292fa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=51451
3 changed files with 90 additions and 0 deletions

View File

@ -141,6 +141,7 @@ i386/i386/initcpu.c standard
i386/i386/machdep.c standard
i386/i386/math_emulate.c optional math_emulate
i386/i386/mem.c standard
i386/i386/mp_clock.c optional smp
i386/i386/mp_machdep.c optional smp
i386/i386/mpapic.c optional smp
i386/i386/mpboot.s optional smp

View File

@ -141,6 +141,7 @@ i386/i386/initcpu.c standard
i386/i386/machdep.c standard
i386/i386/math_emulate.c optional math_emulate
i386/i386/mem.c standard
i386/i386/mp_clock.c optional smp
i386/i386/mp_machdep.c optional smp
i386/i386/mpapic.c optional smp
i386/i386/mpboot.s optional smp

88
sys/i386/i386/mp_clock.c Normal file
View File

@ -0,0 +1,88 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@FreeBSD.ORG> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $FreeBSD$
*
*/
#include "opt_bus.h"
#include "opt_pci.h"
#include "opt_smp.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
#include <pci/pcivar.h>
#include <pci/pcireg.h>
static unsigned piix_get_timecount(struct timecounter *tc);
static u_int32_t piix_timecounter_address;
static struct timecounter piix_timecounter = {
piix_get_timecount,
0,
0xffffff,
14318182/4,
"PIIX"
};
SYSCTL_OPAQUE(_debug, OID_AUTO, piix_timecounter, CTLFLAG_RD,
&piix_timecounter, sizeof(piix_timecounter), "S,timecounter", "");
static unsigned
piix_get_timecount(struct timecounter *tc)
{
return (inl(piix_timecounter_address));
}
static int
piix_probe (device_t dev)
{
u_int32_t d;
switch (pci_get_devid(dev)) {
case 0x71138086:
d = pci_read_config(dev, 0x4, 2);
if (!(d & 1))
return 0; /* IO space not mapped */
d = pci_read_config(dev, 0x40, 4);
piix_timecounter_address = (d & 0xffc0) + 8;
init_timecounter(&piix_timecounter);
return (ENXIO);
};
return (ENXIO);
}
static int
piix_attach (device_t dev)
{
return 0;
}
static device_method_t piix_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, piix_probe),
DEVMETHOD(device_attach, piix_attach),
{ 0, 0 }
};
static driver_t piix_driver = {
"piix",
piix_methods,
1,
};
static devclass_t piix_devclass;
DRIVER_MODULE(piix, pci, piix_driver, piix_devclass, 0, 0);