IA-PC HPET 아이오와 PC를 HPET (High Precision Event Timer) is a specification which was jointly developed by Intel and Microsoft in the early part of this decade.. (고정밀 이벤트 타이머)이 공동으로 인텔과 마이크로 소프트에 의해 2000 년대의 초기 부분 ..에서 개발한 사양입니다 The latest version is dated October 2004. 최신 버전 2004년 10월 일자입니다. It's stated purpose is to 그것은 목적을 밝혔다는 것입니다
initially supplement and eventually replace the legacy 8254 Programmable Interval Timer and the Real Time Clock Periodic Interrupt generation functions that are currently used as the 'de-facto' timer hardware for IA-PCs. 처음 보완하고 궁극적으로 기존의 대체 8254 프로그래머블 인터벌 타이머와 현재 '님의으로 사용하는 리얼 타임 클럭주기적인 인터럽트 생성 기능 - 아이오와에 대한 사실상의'타이머 하드웨어를 PC에.
The HPET HPET architecture defines a set of timers that can be used by the operating system. 아키텍처는 운영 체제에서 사용할 수있는 타이머의 설정을 정의합니다. A timer block is a combination of a single counter and up to 32 comparators and match registers. 타이머 블록을 단일 창구의 조합 및 최대 32 개의 비교기과 일치하는 레지스터이다. The comparator compares the contents of the match register against the value of a free running monotonic up-counter. 비교를 무료로 실행 단조의 가치에 대해 일치하는 레지스터의 내용을 비교 카운터. When the output of the up-counter equals the value in the match register an interrupt is generated. 언제의 출력을 최대 카운터 경기에서 생성된 인터럽트 레지스터 값을 같습니다. Each of the comparators can output an interrupt. 인터럽트 각 비교기의 출력할 수있습니다. A maximum of 8 timer blocks are supported for a total of 256 timers. 8 타이머 블록의 최대 256 타이머의 총 지원됩니다. Each timer block can have different clocking attributes. 각 타이머 블록을 서로 다른 클럭 특성을 가질 수있습니다. Specific implementations may include only a subset of these timers. 구체적인 구현에서는 이러한 타이머의 하위 집합을 포함할 수있습니다. A minimum of three timers is required. 3 개의 타이머의 최소 필요합니다.
The specification contains the following block diagram of the HPET architecture. 사양 HPET 아키텍처는 다음과 같은 블록 다이어그램이 포함되어있습니다.

Some of the timers may be enabled to generate a periodic interrupt. 일부 타이머를 주기적으로 인터럽트를 생성하는 활성화할 수있습니다. If a timer is set to be periodic, its period is added to the match register each time a match occurs, thus computing the next time for this timer to generate an interrupt.. 만약 타이머를 설정하면, 그 기간이 일치하도록 추가됩니다 때마다 발생 일치 등록, 그래서 .. 인터럽트 생성이 타이머에 대한 다음 번에 컴퓨팅 정기 수 An up-counter is usually 64 bits wide but 32-bit implementations are permitted by the specification and 64-bit up-counters can also be driven in 32-bit mode. 최대 카운터 일반적으로 64 비트 폭하지만, 32도 32에서 구동 될 수있는 비트 구현 사양 및 64 비트를 카운터에 의해 허용되는 비트 모드입니다. Up-counters run at a minimum of 10 MHz. 최대 10 MHz의 카운터 최소 실행합니다. which is much faster than the older 이는 훨씬 빠르게 세 이상 RTC 의 RTC (Real Time Clock) and can thus produce periodic interrupts at a much higher resolution. (리얼 타임 클럭), 따라서 훨씬 더 높은 해상도에서 주기적으로 인터럽트를 생성할 수있습니다. The registers associated with these timers are mapped to memory space. 이러한 타이머 레지스터와 관련된 메모리 공간에 매핑됩니다.
The BIOS uses BIOS를 사용하여 ACPI ACPI를 ( Advanced Configuration and Power Interface) functionality to inform the operating system of the location of the HPET memory-mapped register space. (고급 구성 및 전원 인터페이스) 기능을 HPET 메모리 위치의 운영 체제에 알려 - 등록 공간을 매핑된. Here is an example of a disassembled ACPI HPET table from an Intel DX48BT2 (AKA BoneTrail) motherboard. 여기에 인텔 DX48BT2 (일명 BoneTrail)에서 분해가 ACPI HPET 예를 들어 테이블의 마더보드입니다.
$ cat /sys/firmware/acpi/tables/HPET > /var/tmp/hpet.out $ iasl -d /var/tmp/hpet.out $ cat /var/tmp/hpet.dsl /* * Intel ACPI Component Architecture * AML Disassembler version 20090123 * * Disassembly of /var/tmp/hpet.out, Sun Jul 5 19:34:47 2009 * * ACPI Data Table [HPET] * * Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue */ [000h 000 4] Signature : "HPET" /* High Precision Event Timer table */ [004h 004 4] Table Length : 00000038 [008h 008 1] Revision : 01 [009h 009 1] Checksum : CE [00Ah 010 6] Oem ID : "INTEL " [010h 016 8] Oem Table ID : "DX48BT2 " [018h 024 4] Oem Revision : 0000076E [01Ch 028 4] Asl Compiler ID : "MSFT" [020h 032 4] Asl Compiler Revision : 01000013 [024h 036 4] Hardware Block ID : 8086A301 [028h 040 12] Timer Block Register :[028h 040 1] Space ID : 00 (SystemMemory) [029h 041 1] Bit Width : 00 [02Ah 042 1] Bit Offset : 00 [02Bh 043 1] Access Width : 00 [02Ch 044 8] Address : 00000000FED00000 [034h 052 1] Sequence Number : 00 [035h 053 2] Minimum Clock Ticks : 0001 [037h 055 1] Flags (decoded below) : 00 Page Protect : 0 4K Page Protect : 0 64K Page Protect : 0 Raw Table Data 0000: 48 50 45 54 38 00 00 00 01 CE 49 4E 54 45 4C 20 HPET8.....INTEL 0010: 44 58 34 38 42 54 32 20 6E 07 00 00 4D 53 46 54 DX48BT2 n...MSFT 0020: 13 00 00 01 01 A3 86 80 00 00 00 00 00 00 D0 FE ................ 0030: 00 00 00 00 00 01 00 00 ........ $
See page 30 of the HPET v1.0a specification for a detailed breakdown of the individual bits in the Event Time Block (called Hardware Block by the AML disassember). 이벤트 시간 블록 개별 비트에 대한 자세한 분석을위한 HPET v1.0a 사양의 30 페이지를 참조하십시오 (하드웨어 블록 disassember에 의해 급성 골수성 백혈병이라고도 함). Note that only one Event Timer Block need be described in the HPET table in order to bootstrap an operating system. 하기 위해서는 운영 체제를 부트 스트랩가 단 하나의 이벤트 HPET 타이머 블록 테이블에 설명되어있을 필요가없습니다. This is the case here. 이 사건은 여기서이다. For non-legacy platforms, the Event Timer Block described in the HPET is the one that provides functionality to replace the 8254/RTC Periodic Interrupt Logic. 이외의 레거시 플랫폼, 이벤트 타이머 블록 HPET에서 설명하는 한 8254/RTC주기적인 인터럽트 로직을 대체하는 기능을 제공합니다.
Other Event Time Blocks are described in the ACPI namespace. 기타 이벤트 타임 블록 ACPI를 네임 스페이스에 설명되어있습니다. Here is the relevant section from the disassembled ACPI DSDT table. 여기 분해 DSDT ACPI를 테이블에서 관련 섹션이있습니다.
Device (HPET)
{
Name (_HID, EisaId ("PNP0103"))
Name (_CRS, ResourceTemplate ()
{
Memory32Fixed (ReadOnly,
0xFED00000, // Address Base
0x00004000, // Address Length
)
})
Method (_STA, 0, NotSerialized)
{
If (HPEE)
{
Return (0x0F)
}
Else
{
Return (Zero)
}
}
}
Note the assigned PNPID ( PNP0103 ) for the HPET. 참고 PNPID (PNP0103) HPET에 할당됩니다. Because no _UID is specified it means that there are no other HPET timer blocks. _UID 없기 때문에 그것은 거기에 다른 HPET 타이머를 차단하는 방법을 지정합니다.
Here is a list of the HPET-related messages outputted when this particular motherboard is booted up under Fedora 11. 여기 HPET의 목록과 관련된 메시지가 출력이 특정 마더보드에 페도라 11 아래에 부팅입니다.
$ dmesg | grep -i HPET ACPI: HPET CFBF2000, 0038 (r1 INTEL DX48BT2 76E MSFT 1000013) ACPI: HPET id: 0x8086a301 base: 0xfed00000 hpet clockevent registered HPET: 4 timers in total, 0 timers will be used for per-cpu timer hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0 hpet0: 4 comparators, 64-bit 14.318180 MHz counter rtc0: alarms up to one month, 114 bytes nvram, hpet irqs $
The first line is outputted when the ACPI HPET table is read. 첫 번째 라인을 때가 ACPI HPET 테이블을 읽어 출력됩니다. The second line is outputted when the ACPI HPET table is mapped into memory by …/arch/x86/kernel/acpi/boot.c . 두번째 라인은 언제가 ACPI HPET 테이블을 메모리로 매핑됩니다 ... / arch/x86/kernel/acpi/boot.c 출력됩니다. The next line is outputted when the HPET legacy interrupts are started and HPET is registered as the global clock. 다음 라인을 때 HPET 기존 인터럽트 시작하는 HPET 글로벌 클럭으로 등록되어 출력됩니다. The following line is outputted when the kernel checks to ensure that at least one timer is reserved for userspace ( /dev/hpet .) The next two lines of output comes from the HPET device driver ( …/drivers/char/hpet.c .) It shows that 2 timers have allocated interrupts and two do not.. 다음 명령줄을 할 때 커널이 수표는 적어도 하나의 타이머에 대한 userspace (는 / dev / hpet.) 출력의 다음 두 줄을 HPET 장치 드라이버에서 (.. / 드라이버 / 숯불 / hpet.c 제공을 위해 예약되어 출력됩니다. ) 그 2 타이머 인터럽트를 할당하고 두 .. 안 보여
Here is the relevant part of the output from /proc/time_list as it relates to HPET: 여기에서 출력 관련 부분은 / proc /로 HPET에 관한 time_list :
Tick Device: mode: 1 Broadcast device Clock Event Device: hpet max_delta_ns: 149983005959 min_delta_ns: 5000 mult: 61496114 shift: 32 mode: 3 next_event: 9223372036854775807 nsecs set_next_event: hpet_legacy_next_event set_mode: hpet_legacy_set_mode event_handler: tick_handle_oneshot_broadcast tick_broadcast_mask: 00000000 tick_broadcast_oneshot_mask: 00000000
Here is the output from /proc/sys/dev/hpet and /proc/driver/rtc : 여기에서 출력은 / proc / sys 인는 / dev / hpet 및은 / proc / 드라이버 / RTC를 :
$ cat /proc/sys/dev/hpet/max-user-freq 64 $ cat /proc/driver/rtc rtc_time : 06:34:31 rtc_date : 2009-07-06 alrm_time : **:24:40 alrm_date : ****-**-** alarm_IRQ : no alrm_pending : no 24hr : yes periodic_IRQ : no update_IRQ : no HPET_emulated : yes DST_enable : no periodic_freq : 1024 batt_status : okay
The HPET driver ( /dev/hpet ) has a similar API to the Real Time Clock driver. HPET 드라이버 (는 / dev / hpet) 리얼 타임 클록 드라이버와 유사한 API를하고있다. It is a character device which can support any number of HPET devices. 그것은 HPET 장치를 지원할 수 어떤 숫자 문자 장치입니다. The kernel API has three interfaces exported from the driver: 커널 API를 세 가지 인터페이스 드라이버에서 수출하고있다 :
hpet_register( struct hpet_task *tp, int periodic ) hpet_unregister( struct hpet_task *tp ) hpet_control( struct hpet_task *tp, unsigned int cmd, unsigned long arg )
The userspace interface to HPET is defined in the header /usr/include/linux/hpet.h . HPET에 userspace 인터페이스 헤더는 / usr / 정의가 포함되어 / 리눅스 / hpet.h. The current set of supported operations is: 지원하는 운영의 현재 설정됩니다 :
#define HPET_IE_ON _IO('h', 0x01) /* interrupt on */
#define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */
#define HPET_INFO _IOR('h', 0x03, struct hpet_info) /* get information */
#define HPET_EPI _IO('h', 0x04) /* enable periodic */
#define HPET_DPI _IO('h', 0x05) /* disable periodic */
#define HPET_IRQFREQ _IOW('h', 0x6, unsigned long) /* set frequency */
The following example shows how to use the published interface to access a HPET and call a simple periodic signal handler hpet_alarm between 2 and 99 times a second. 다음 예제에서는 HPET 접근과 2 사이에 간단하게 주기적으로 신호 처리기 hpet_alarm 호출하면 게시된 인터페이스를 사용하는 방법을 보여줍니다 99 번 2.
#include <stdio.h>
#include <stdlib.h;>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/time.h>
#include <linux/hpet.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <signal.h>
static uint16_t hpet_sigio_count;
static uint64_t secs;
static void
hpet_alarm(int val)
{
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
if (!secs) secs = t.tv_sec;
fprintf(stderr, "hpet_alarm called. iteration: %2d secs: %ld nsecs: %ld \n",
hpet_sigio_count, (t.tv_sec - secs) , t.tv_sec * 100000 + t.tv_nsec );
hpet_sigio_count++;
}
int
main(int argc, const char **argv)
{
struct sigaction old, new;
struct hpet_info info;
int frequency;
int iterations;
int retval = 0;
int fd;
int r, i, value;
if (argc != 3) {
fprintf(stderr, "Usage: %s frequency(1-64) iterations(10-99)\n", argv[0]);
return -1;
}
frequency = atoi(argv[1]);
iterations = atoi(argv[2]);
if (frequency > 64 || frequency < 1 ) {
fprintf(stderr, "ERROR: Invalid value for frequency\n");
return -1;
}
if (iterations < 10 || iterations > 99 ) {
fprintf(stderr, "ERROR: Invalid value for iterations\n");
return -1;
}
hpet_sigio_count = 0;
sigemptyset(&new.sa_mask);
new.sa_flags = 0;
new.sa_handler = hpet_alarm;
sigaction(SIGIO, NULL, &old);
sigaction(SIGIO, &new, NULL);
fd = open("/dev/hpet", O_RDONLY);
if (fd < 0) {
fprintf(stderr, "ERROR: Failed to open /dev/hpet\n");
return -1;
}
if ((fcntl(fd, F_SETOWN, getpid()) == 1) ||
((value = fcntl(fd, F_GETFL)) == 1) ||
(fcntl(fd, F_SETFL, value | O_ASYNC) == 1)) {
fprintf(stderr, "ERROR: fcntl failed\n");
retval = 1;
goto fail;
}
if (ioctl(fd, HPET_IRQFREQ, frequency) < 0) {
fprintf(stderr, "ERROR: Could not set /dev/hpet to have a %2dHz timer\n", frequency);
retval = 2;
goto fail;
}
if (ioctl(fd, HPET_INFO, &info) < 0) {
fprintf(stderr, "ERROR: failed to get info\n");
retval = 3;
goto fail;
}
fprintf(stdout, "\nhi_ireqfreq: 0x%lx hi_flags: %0x%lx hi_hpet: 0x%x hi_timer: 0x%x\n\n",
info.hi_ireqfreq, info.hi_flags, info.hi_hpet, info.hi_timer);
r = ioctl(fd, HPET_EPI, 0);
if (info.hi_flags && (r < 0)) {
fprintf(stderr, "ERROR: HPET_EPI failed\n");
retval = 4;
goto fail;
}
if (ioctl(fd, HPET_IE_ON, 0) < 0) {
fprintf(stderr, "ERROR: HPET_IE_ON failed\n");
retval = 5;
goto fail;
}
/* wait for specified number of signal interrupts */
for (i = 0; i < iterations; i++) {
(void) pause();
}
if (ioctl(fd, HPET_IE_OFF, 0) < 0) {
fprintf(stderr, "ERROR: HPET_IE_OFF failed\n");
retval = 6;
}
fail:
sigaction(SIGIO, &old, NULL);
if (fd > 0)
close(fd);
return retval;
}
Here is the output from this example when it is invoked with a frequency of 32 and an iteration count of 64. 이곳 때 예를 들어 32의 빈도와 64의 반복 횟수와 호출로부터 출력합니다.
$ sudo ./hpet_example 32 64 hi_ireqfreq: 0x20 hi_flags: 00 hi_hpet: 0x2 hi_timer: 0x4a1cb9c8 hpet_alarm called. iteration: 0 secs: 0 nsecs: 124683205055050 hpet_alarm called. iteration: 1 secs: 0 nsecs: 124683236313149 hpet_alarm called. iteration: 2 secs: 0 nsecs: 124683267566342 hpet_alarm called. iteration: 3 secs: 0 nsecs: 124683298821905 hpet_alarm called. iteration: 4 secs: 0 nsecs: 124683330077493 hpet_alarm called. iteration: 5 secs: 0 nsecs: 124683361341893 hpet_alarm called. iteration: 6 secs: 0 nsecs: 124683392590764 hpet_alarm called. iteration: 7 secs: 0 nsecs: 124683423849157 hpet_alarm called. iteration: 8 secs: 0 nsecs: 124683455101917 hpet_alarm called. iteration: 9 secs: 0 nsecs: 124683486357683 hpet_alarm called. iteration: 10 secs: 0 nsecs: 124683517617931 hpet_alarm called. iteration: 11 secs: 0 nsecs: 124683548872198 hpet_alarm called. iteration: 12 secs: 1 nsecs: 124682580229541 hpet_alarm called. iteration: 13 secs: 1 nsecs: 124682611481235 hpet_alarm called. iteration: 14 secs: 1 nsecs: 124682642740016 hpet_alarm called. iteration: 15 secs: 1 nsecs: 124682673992697 hpet_alarm called. iteration: 16 secs: 1 nsecs: 124682705247479 hpet_alarm called. iteration: 17 secs: 1 nsecs: 124682736504664 hpet_alarm called. iteration: 18 secs: 1 nsecs: 124682767758840 hpet_alarm called. iteration: 19 secs: 1 nsecs: 124682799014280 hpet_alarm called. iteration: 20 secs: 1 nsecs: 124682830270129 hpet_alarm called. iteration: 21 secs: 1 nsecs: 124682861530334 hpet_alarm called. iteration: 22 secs: 1 nsecs: 124682892784577 hpet_alarm called. iteration: 23 secs: 1 nsecs: 124682924038220 hpet_alarm called. iteration: 24 secs: 1 nsecs: 124682955294110 hpet_alarm called. iteration: 25 secs: 1 nsecs: 124682986550572 hpet_alarm called. iteration: 26 secs: 1 nsecs: 124683017805756 hpet_alarm called. iteration: 27 secs: 1 nsecs: 124683049061117 hpet_alarm called. iteration: 28 secs: 1 nsecs: 124683080318331 hpet_alarm called. iteration: 29 secs: 1 nsecs: 124683111576954 hpet_alarm called. iteration: 30 secs: 1 nsecs: 124683142828988 hpet_alarm called. iteration: 31 secs: 1 nsecs: 124683174083954 hpet_alarm called. iteration: 32 secs: 1 nsecs: 124683205337967 hpet_alarm called. iteration: 33 secs: 1 nsecs: 124683236593144 hpet_alarm called. iteration: 34 secs: 1 nsecs: 124683267851530 hpet_alarm called. iteration: 35 secs: 1 nsecs: 124683299104054 hpet_alarm called. iteration: 36 secs: 1 nsecs: 124683330358748 hpet_alarm called. iteration: 37 secs: 1 nsecs: 124683361617445 hpet_alarm called. iteration: 38 secs: 1 nsecs: 124683392870249 hpet_alarm called. iteration: 39 secs: 1 nsecs: 124683424124489 hpet_alarm called. iteration: 40 secs: 1 nsecs: 124683455379717 hpet_alarm called. iteration: 41 secs: 1 nsecs: 124683486634424 hpet_alarm called. iteration: 42 secs: 1 nsecs: 124683517889149 hpet_alarm called. iteration: 43 secs: 1 nsecs: 124683549144315 hpet_alarm called. iteration: 44 secs: 2 nsecs: 124682580500695 hpet_alarm called. iteration: 45 secs: 2 nsecs: 124682611761325 hpet_alarm called. iteration: 46 secs: 2 nsecs: 124682643011863 hpet_alarm called. iteration: 47 secs: 2 nsecs: 124682674265864 hpet_alarm called. iteration: 48 secs: 2 nsecs: 124682705521034 hpet_alarm called. iteration: 49 secs: 2 nsecs: 124682736776049 hpet_alarm called. iteration: 50 secs: 2 nsecs: 124682768030654 hpet_alarm called. iteration: 51 secs: 2 nsecs: 124682799285398 hpet_alarm called. iteration: 52 secs: 2 nsecs: 124682830544701 hpet_alarm called. iteration: 53 secs: 2 nsecs: 124682861797319 hpet_alarm called. iteration: 54 secs: 2 nsecs: 124682893051578 hpet_alarm called. iteration: 55 secs: 2 nsecs: 124682924306748 hpet_alarm called. iteration: 56 secs: 2 nsecs: 124682955562132 hpet_alarm called. iteration: 57 secs: 2 nsecs: 124682986823545 hpet_alarm called. iteration: 58 secs: 2 nsecs: 124683018073636 hpet_alarm called. iteration: 59 secs: 2 nsecs: 124683049327560 hpet_alarm called. iteration: 60 secs: 2 nsecs: 124683080586707 hpet_alarm called. iteration: 61 secs: 2 nsecs: 124683111841132 hpet_alarm called. iteration: 62 secs: 2 nsecs: 124683143095147 hpet_alarm called. iteration: 63 secs: 2 nsecs: 124683174349985 hpet_alarm called. iteration: 64 secs: 2 nsecs: 124683205607103 $
Well, I think that I have provided you with enough information so that you should now be able to go away and experiment with the HPET interface yourself. 글쎄, 나는 정보가 충분하므로 당신이 지금은 멀리 가서 실험 HPET와 직접 인터페이스를 할 수 있어야 귀하 께서 제공하신 것 같아요.
By the way, not all VMware products support HPET. 그건 그렇고, 모든 VM웨어의 제품을 지원 HPET. Currently ESX does not provide a virtual HPET to guest operating systems and in some cases it may be necessary to disable HPET altogether because of timer drift in virtual machines. 현재 ESX 게스트 운영 체제 및 가상 HPET를 제공하지 않습니다 그것을 해제하는 HPET 타이머를 완전히 드리프트 때문에 가상 머신에 필요한있을 수있는 몇 가지 경우이다. See 보다 VMware TimeKeeping VM웨어의 측정 for more information. 자세한 내용은.
PS I tested the the above example on an Intel DX48BT2 motherboard running a 2.6.29.5-191 kernel. 추신 : 제가 인텔 DX48BT2 메인 보드 2.6.29.5-191 커널을 실행하는 위의 예제 테스트.





















