From f5ca793c8c8002851d83a2344485614bfb640465 Mon Sep 17 00:00:00 2001 From: Yuan Liu Date: Mon, 28 Oct 2019 09:22:26 +0800 Subject: [PATCH] doc: add system timer virtualization Signed-off-by: Yuan Liu --- .../hld/hld-emulated-devices.rst | 1 + .../hld/images/hld-dm-timer-image1.png | Bin 0 -> 55840 bytes doc/developer-guides/hld/system-timer-hld.rst | 201 ++++++++++++++++++ 3 files changed, 202 insertions(+) create mode 100644 doc/developer-guides/hld/images/hld-dm-timer-image1.png create mode 100644 doc/developer-guides/hld/system-timer-hld.rst diff --git a/doc/developer-guides/hld/hld-emulated-devices.rst b/doc/developer-guides/hld/hld-emulated-devices.rst index 78e1c55ba..5c5338205 100644 --- a/doc/developer-guides/hld/hld-emulated-devices.rst +++ b/doc/developer-guides/hld/hld-emulated-devices.rst @@ -16,6 +16,7 @@ documented in this section. Watchdoc virtualization AHCI virtualization GVT-g GPU Virtualization + System timer virtualization UART emulation in hypervisor RTC emulation in hypervisor Hostbridge emulation diff --git a/doc/developer-guides/hld/images/hld-dm-timer-image1.png b/doc/developer-guides/hld/images/hld-dm-timer-image1.png new file mode 100644 index 0000000000000000000000000000000000000000..e9241c6c98a72a6f678393371d279fe9a0b4879b GIT binary patch literal 55840 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 MZOlrJ|9OV literal 0 HcmV?d00001 diff --git a/doc/developer-guides/hld/system-timer-hld.rst b/doc/developer-guides/hld/system-timer-hld.rst new file mode 100644 index 000000000..60f4764f4 --- /dev/null +++ b/doc/developer-guides/hld/system-timer-hld.rst @@ -0,0 +1,201 @@ +.. _system-timer-hld: + +System timer virtualization +########################### + +ACRN supports RTC (Real-time clock), HPET (High Precision Event Timer) +and PIT (Programmable interval timer) devices for VM system timer. +Different timer devices support different resolutions, HPET device can +support higher resolution than RTC and PIT. + +System timer virtualization architecture + +|image0| + +- In UOS, vRTC, vHPET and vPIT are used by clock event module and clock + source module in kernel space. + +- In SOS, all of vRTC, vHPET and vPIT devices are created by device + model in initialization phase and using timer\_create and + timerfd\_create interfaces to setup native timers for trigger timeout + mechanism. + +System Timer initialization +=========================== + +Device model initializes vRTC, vHEPT and vPIT devices automatically when +ACRN device model starts booting initialization, and the initialization +flow goes from vrtc\_init to vpit\_init and ends with vhept\_init, see +below code snippets.:: + + static int + vm_init_vdevs(struct vmctx ctx)* + { + int ret; + ... + + ret = vrtc_init(ctx); + if (ret < 0) + goto vrtc_fail; + + ret = vpit_init(ctx); + if (ret < 0) + goto vpit_fail; + + ret = vhpet_init(ctx); + if (ret < 0) + goto vhpet_fail; + ... + } + +PIT emulation +============= + +ACRN emulated Intel 8253 Programmable Interval Timer, the chip has three +independent 16-bit down counters that can be read on the fly. There are +three mode registers and three countdown registers. The countdown +registers are addressed directly, via the first three I/O ports.The +three mode registers are accessed via the fourth I/O port, with two bits +in the mode byte indicating the register. + +I/O ports definition:: + + #define IO_TIMER1_PORT 0x40 /* 8253 Timer #1 */ + #define NMISC_PORT 0x61 + #define TIMER_REG_CNTR0 0 /* timer 0 counter port */ + #define TIMER_REG_CNTR1 1 /* timer 1 counter port */ + #define TIMER_REG_CNTR2 2 /* timer 2 counter port */ + #define TIMER_REG_MODE 3 /* timer mode port */ + + /* + * The outputs of the three timers are connected as follows: + * + * timer 0 -> irq 0 + * timer 1 -> dma chan 0 (for dram refresh) + * timer 2 -> speaker (via keyboard controller) + * + * Timer 0 is used to call hard clock. + * Timer 2 is used to generate console beeps. + */ + #define TIMER_CNTR0 (IO_TIMER1_PORT + TIMER_REG_CNTR0) + #define TIMER_CNTR1 (IO_TIMER1_PORT + TIMER_REG_CNTR1) + #define TIMER_CNTR2 (IO_TIMER1_PORT + TIMER_REG_CNTR2) + #define TIMER_MODE (IO_TIMER1_PORT + TIMER_REG_MODE) + +RTC emulation +============= + +ACRN supports RTC (Real-Time Clock) that can only be accessed through +I/O ports (0x70 and 0x71). + +0x70 is used to access CMOS address register, 0x71 is used to access +CMOS data register, user need to set CMOS address register then +read/write CMOS data register for CMOS accessing. + +The RTC ACPI description as below:: + + #define IO_RTC 0x070 /* RTC */ + + static void + rtc_dsdt(void) + { + dsdt_line(""); + dsdt_line("Device (RTC)"); + dsdt_line("{"); + dsdt_line(" Name (\_HID, EisaId (\\"PNP0B00\\"))"); + dsdt_line(" Name (\_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(IO_RTC, 2); + dsdt_fixed_irq(8); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); + } + +HPET emulation +============== + +ACRN supports HPET (High Precision Event Timer) that is high resolution +timer than RTC and PIT. Its frequency is 16.7Mhz and using MMIO to +access HPET device, the base address is 0xfed00000 and size is 1024 +bytes. Accesses to the HPET should be 4 or 8 bytes wide.:: + + #define HPET_FREQ (16777216) /* 16.7 (2^24) Mhz */ + #define VHPET_BASE (0xfed00000) + #define VHPET_SIZE (1024) + +HPET registers definition:: + + /* General registers */ + #define HPET_CAPABILITIES 0x0 /* General capabilities and ID register */ + #define HPET_CAP_VENDOR_ID 0xffff0000 + #define HPET_CAP_LEG_RT 0x00008000 + #define HPET_CAP_COUNT_SIZE 0x00002000 /* 1 = 64-bit, 0 = 32-bit */ + #define HPET_CAP_NUM_TIM 0x00001f00 + #define HPET_CAP_REV_ID 0x000000ff + #define HPET_PERIOD 0x4 /* Period (1/hz) of timer */ + #define HPET_CONFIG 0x10 /* General configuration register */ + #define HPET_CNF_LEG_RT 0x00000002 + #define HPET_CNF_ENABLE 0x00000001 + #define HPET_ISR 0x20 /* General interrupt status register */ + #define HPET_MAIN_COUNTER 0xf0 /* Main counter register */ + + /* Timer registers */ + #define HPET_TIMER_CAP_CNF(x) ((x) * 0x20 + 0x100) + #define HPET_TCAP_INT_ROUTE 0xffffffff00000000 + #define HPET_TCAP_FSB_INT_DEL 0x00008000 + #define HPET_TCNF_FSB_EN 0x00004000 + #define HPET_TCNF_INT_ROUTE 0x00003e00 + #define HPET_TCNF_32MODE 0x00000100 + #define HPET_TCNF_VAL_SET 0x00000040 + #define HPET_TCAP_SIZE 0x00000020 /* 1 = 64-bit, 0 = 32-bit */ + #define HPET_TCAP_PER_INT 0x00000010 /* Supports periodic interrupts */ + #define HPET_TCNF_TYPE 0x00000008 /* 1 = periodic, 0 = one-shot */ + #define HPET_TCNF_INT_ENB 0x00000004 + #define HPET_TCNF_INT_TYPE 0x00000002 /* 1 = level triggered, 0 = edge */ + #define HPET_TIMER_COMPARATOR(x) ((x) * 0x20 + 0x108) + #define HPET_TIMER_FSB_VAL(x) ((x) * 0x20 + 0x110) + #define HPET_TIMER_FSB_ADDR(x) ((x) * 0x20 + 0x114) + +ACPI device description:: + + static int + basl\_fwrite\_hpet(FILE \*fp, struct vmctx \*ctx) + { + EFPRINTF(fp, "/\*\\n"); + EFPRINTF(fp, " \* dm HPET template\\n"); + EFPRINTF(fp, " \*/\\n"); + EFPRINTF(fp, "[0004]\\t\\tSignature : \\"HPET\\"\\n"); + EFPRINTF(fp, "[0004]\\t\\tTable Length : 00000000\\n"); + EFPRINTF(fp, "[0001]\\t\\tRevision : 01\\n"); + EFPRINTF(fp, "[0001]\\t\\tChecksum : 00\\n"); + EFPRINTF(fp, "[0006]\\t\\tOem ID : \\"DM \\"\\n"); + EFPRINTF(fp, "[0008]\\t\\tOem Table ID : \\"DMHPET \\"\\n"); + EFPRINTF(fp, "[0004]\\t\\tOem Revision : 00000001\\n"); + + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\\t\\tAsl Compiler ID : \\"xxxx\\"\\n"); + EFPRINTF(fp, "[0004]\\t\\tAsl Compiler Revision : 00000000\\n"); + EFPRINTF(fp, "\\n"); + EFPRINTF(fp, "[0004]\\t\\tTimer Block ID : %08X\\n", (uint32\_t)vhpet_capabilities());* + EFPRINTF(fp, "[0012]\\t\\tTimer Block Register : [Generic Address Structure]\\n"); + EFPRINTF(fp, "[0001]\\t\\tSpace ID : 00 [SystemMemory]\\n");* + EFPRINTF(fp, "[0001]\\t\\tBit Width : 00\\n");* + EFPRINTF(fp, "[0001]\\t\\tBit Offset : 00\\n");* + EFPRINTF(fp, "[0001]\\t\\tEncoded Access Width : 00 [Undefined/Legacy]\\n"); + EFPRINTF(fp, "[0008]\\t\\tAddress : %016X\\n", VHPET_BASE); + EFPRINTF(fp, "\\n"); + EFPRINTF(fp, "[0001]\\t\\tHPET Number : 00\\n"); + EFPRINTF(fp, "[0002]\\t\\tMinimum Clock Ticks : 0000\\n"); + EFPRINTF(fp, "[0004]\\t\\tFlags (decoded below) : 00000001\\n"); + EFPRINTF(fp, "\\t\\t\\t4K Page Protect : 1\\n"); + EFPRINTF(fp, "\\t\\t\\t64K Page Protect : 0\\n"); + EFPRINTF(fp, "\\n"); + EFFLUSH(fp); + return 0; + } + +.. |image0| image:: ./images/hld-dm-timer-image1.png + :width: 8.00000in + :height: 4.63887in