翻譯

Translate to EnglishÜbersetzen Sie zum Deutsch/GermanΜεταφράστε στα ελληνικά/GreekПереведите к русскому/RussianOversetter til Norsk/NorwegianÖversätta till Svensk/Swedishहिन्दी अनुवाद करने के लिए/Hindi
Tradueix al català/CatalanTulkot uz latviešu/LatvianPreložiť do slovenčiny/SlovakVertaal aan het Nederlands/Dutchترجمة الى العربية/ArabicTraduzca al Español/SpanishTraduisez au Français/French
Traduca ad Italiano/ItalianTraduza ao Português/Portuguese日本語に翻訳しなさい /Japanese한국어에게 번역하십시오/Korean中文翻译/Chinese Simplified中文翻译/Chinese TraditionalПереклад на українську/Ukrainian
»

Linux HPET技術支持

愛阿華州-個人電腦HPET((高精確性事件計時員)是一規格說明英特爾和微軟共同在早的部份這decade.形成.給最新版本註明日期2004年10月.它’s表明用途是向

開始時補充和最終取代遺產8254可程式化的時間間隔計時員和即時鐘週期中斷產生功能為愛阿華州-個人電腦現時使用作為‘de-facto’計時員硬體.

HPET建築學定義一套能被作業系統使用的計時員.一計時員塊是一個單一的櫃台和多達32比較測定機和登記比賽的結合.比較測定機比較反對價值相符登記的目錄的一免費櫃台升起單調的.當輸出的時候的沿著-櫃台對等在一中斷是的相符登記中價值產生.比較測定機的每一個能使出一中斷.一最大限度的8計時員塊為總共256個計時員被支持.每一計時員塊能有不同記計時卡屬性.特有工具可以包含僅一個這些計時員的用戶電話機.一最低限度的三個計時員被要求.

規格說明含有下列的HPET建築學的方塊圖.

硬體方塊圖

可以被使某些計時員能產生一週期中斷.如果一個計時員準備好是週期,每次,一相符發生因此計算這個計時員產生一interrupt.下次的它的時期被被加入相符登記.一64小塊通常很開是沿著-櫃台但是32-位工具被規格說明允許和沿著-櫃台64-位能也在32-位方式中被驅動.沿著-在一最低限度的10 MHz運作櫃台.哪一個是與更老RTC((即時鐘)相比快得多和能在一高分辨得多因此生產週期中斷.把登記和這些計時員聯繫起來被把映射到記憶空間.

(提出配置和力量界面)官能性告訴HPET記憶-的位置的作業系統BIOS使用ACPI繪製登記空間的地圖.這裡是一個一張從一塊英特爾DX48BT2((AKA 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                          ........
$


事實上,時代週刊堵住((認為在AML旁邊硬體塊是disassember)請參看頁的HPET v1.0a一個人小塊的詳細故障的規格說明30.指出為了依靠一作業系統的努力獲得成功,僅一事件計時員塊需求在HPET表中被描繪.這個是此種情況這裡.為非遺產平台,Block在HPET中描繪的事件計時員歲,其提供官能性取代8254//RTC週期中斷邏輯的那個.

其它事件時代週刊塊在ACPI namespace中被描繪.這裡是從拆卸ACPI DSDT桌子有關部份.

            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)
                    }
                }
            }


為HPET指出分配PNPID((PNP0103).因為沒有_UID被指定,它意味著事實上沒有其它HPET計時員塊.

當這塊挑剔母板是向上在淺頂軟呢男帽11下面踢的時候,這裡是一份HPET-相關訊息outputted的清單.

$ 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
$


當ACPI HPET桌子是閱讀的時候,第一線是outputted.當ACPI HPET桌子是變為記憶繪製的地圖的時候,第二切分節奏在身邊是outputted …/arch/x86/kernel/acpi/boot.c.當HPET遺產中斷被開始作為全球性鐘和HPET被登記的時候,下一個線是outputted.當仁檢查保證至少一計時員留待userspace((/dev/hpet)的時候,下列的線是outputted.下一個的二行輸出來自HPET裝置司機…/drivers/char/hpet.c.它展示2個計時員已經分配中斷和二做not..

當它和HPET關聯時,這裡是有關的部份從/proc/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


這裡是從/proc/sys/dev/hpet/proc/driver/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

HPET司機((/dev/hpet)對即時鐘司機有一相似API.它是一項能支撐許多HPET裝置的個性裝置.仁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 )


向HPET userspace界面在頭球/usr/include/linux/hpet.h中被定義.目前的套支持運算是:

#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 */


下列的例子展示怎樣使用出版界面訪問一HPET在中間2和每秒99次和認為一簡單週期信號是操作者hpet_alarm.

#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;
}


當它是隨著一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
$


好,我認為我已經為你提供充足資訊,因此現在你應該你自己能離開和用HPET界面做試驗.

順便一提,並非所有VMware產品支撐HPET.現時ESX不向作業系統客人提供一事實上HPET在虛擬機機器中和在有些情形下可以是對由於計時員漂移完全嚴重損壞HPET必要的.取得詳細相關資訊請參看VMware TimeKeeping.

附言我受試驗在一塊英特爾DX48BT2母板上跑步一2.6.29.5-191仁上述例子.
 

留下一回答