doc: add module design for peripheral vrtc device

GAI Tooling Notice: These contents may have been developed with support from one
or more generative artificial intelligence solutions.

This patch is to add doxygen style comments for some elements in vp-dm_vperipheral
vrtc module.

Tracked-On: #8665

Signed-off-by: Haiwei Li <haiwei.li@intel.com>
This commit is contained in:
Haiwei Li 2024-08-06 15:03:44 +08:00 committed by acrnsi-robot
parent 48a102e6b0
commit 172c56fe0a
2 changed files with 146 additions and 12 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2014, Neel Natu (neel@freebsd.org)
* Copyright (c) 2022 Intel Corporation.
* Copyright (c) 2024 Intel Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -34,6 +34,20 @@
#include "mc146818rtc.h"
/**
* @addtogroup vp-dm_vperipheral
*
* @{
*/
/**
* @file
* @brief Implementation of virtual RTC device.
*
* This file provides the implementation of the virtual RTC device. The virtual RTC device is used to provide the RTC
* service to the guest VMs. It is a part of the virtual peripheral devices.
*/
/* #define DEBUG_RTC */
#ifdef DEBUG_RTC
# define RTC_DEBUG pr_info
@ -489,8 +503,34 @@ static void vrtc_set_reg_b(struct acrn_vrtc *vrtc, uint8_t newval)
}
/**
* @brief Read from the virtual RTC device.
*
* This function reads the value from the RTC register specified by the address port. To read from the virtual RTC
* device, the guest writes the register index to the RTC address port and then reads the register value from the RTC
* data port. This function is used to simulate the behavior of reading in a virtualized environment.
*
* - If the accessed port is CMOS_ADDR_PORT, it will set the value as index cached in last write (0 by default) and
* return.
* - If the accessed port is CMOS_DATA_PORT,
* - For Service VM, it will directly read the value from the physical CMOS register.
* - For a non-Service VM, it will return false indicating the read operation failed if the address is greater than
* RTC_CENTURY. Otherwise, the read operation will be emulated.
*
* @param[inout] vcpu Pointer to the virtual CPU that is reading from the virtual RTC. The value read from the virtual
* RTC will be stored in the PIO request.
* @param[in] addr The address port to read from.
* @param[in] width The width of the data to be read. This is not used in this function.
*
* @return A boolean value indicating whether the read operation is successful.
*
* @retval true Successfully read from the virtual RTC device.
* @retval false Failed to read from the virtual RTC device.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
* @pre addr == 0x70U || addr == 0x71U
*
* @post N/A
*/
static bool vrtc_read(struct acrn_vcpu *vcpu, uint16_t addr, __unused size_t width)
{
@ -536,8 +576,39 @@ static inline bool vrtc_is_time_register(uint32_t offset)
}
/**
* @brief Write a value to the virtual RTC.
*
* This function writes a specified value to the virtual RTC at a given offset. To write to the virtual RTC, the guest
* writes the register index to the RTC address port and then writes the register value to the RTC data port. This
* function is used to simulate the behavior of writing in a virtualized environment.
*
* - If the accessed port is CMOS_ADDR_PORT and the width is 1 byte, it will store the value as the index and return.
* - If the accessed port is CMOS_DATA_PORT,
* - For Service VM, it will directly write the value to the physical CMOS register. If the physical date/time is
* changed, for RT VMs and pre-launched VMs, the RTC/TSC snapshots will be updated. Those snapshots are used to
* emulate the virtual date/time for non-Service VM.
* - For a non-Service VM, it will ignore the write to the RTC_STATUSA, RTC_INTR and RTC_STATUSD. Otherwise, it will
* update the virtual register value and RTC time. And for Post-launched VM, it will send a VM event to notify the
* VM of the change in the RTC time if the address port is in the range of the time registers.
*
* @param[inout] vcpu Pointer to the virtual CPU that is writing to the virtual RTC.
* @param[in] addr The address port to write to.
* @param[in] width Width of the value to be written to the virtual RTC.
* @param[in] value Value to be written to the virtual RTC.
*
* @return A boolean value indicating whether the write operation is handled successfully, which is always true in
* current design. It either updates the physical registers, updates the virtual registers, or ignores the
* write.
*
* @retval true The write operation is handled successfully.
*
* @pre vcpu != NULL
* @pre vcpu->vm != NULL
* @pre addr == 0x70U || addr == 0x71U
*
* @post N/A
*
* @remark N/A
*/
static bool vrtc_write(struct acrn_vcpu *vcpu, uint16_t addr, size_t width,
uint32_t value)
@ -707,6 +778,29 @@ void resume_vrtc(void)
calibrate_setup_timer();
}
/**
* @brief Initialize the virtual RTC.
*
* This function initializes the virtual RTC (Real-Time Clock) device for the given virtual machine. It sets up the
* necessary data structures and state required for the RTC to function correctly. This function should be called during
* the initialization phase of the virtual machine.
*
* - When Service VM's vRTC device is initialized, a periodic timer (every 3 hours) is set up to calibrate the virtual
* date/time of other VMs. When the calibration timer is triggered, for RT VMs and pre-launched VMs, the TSC/RTC
* snapshots are updated to reflect the physical TSC/RTC-time at that moment.
* - When non-Service VM's vRTC device is initialized, the TSC/RTC snapshots are initialized to reflect the physical
* TSC/RTC-time at the moment.
*
* @param[inout] vm The virtual machine that contains the virtual RTC to be initialized.
*
* @return None
*
* @pre vm != NULL
*
* @post N/A
*
* @remark N/A
*/
void vrtc_init(struct acrn_vm *vm)
{
struct vm_io_range range = {
@ -725,3 +819,7 @@ void vrtc_init(struct acrn_vm *vm)
vm->vrtc.base_tsc = cpu_ticks();
}
}
/**
* @}
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022 Intel Corporation.
* Copyright (C) 2024 Intel Corporation.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -7,6 +7,25 @@
#ifndef VRTC_H
#define VRTC_H
/**
* @defgroup vp-dm_vperipheral vp-dm.vperipheral
* @ingroup vp-dm
* @brief Implementation of virtual peripheral devices in hypervisor.
*
* This module implements the virtualization of all peripheral devices in hypervisor. The virtual device initial
* function is usually called by the VM initialization function and registers their port IO and memory IO access
* functions. So when a guest VM accesses its peripheral device by port IO or memory IO, it would cause VM exit and then
* call their registered functions.
* @{
*/
/**
* @file
* @brief Definitions for the virtual RTC device.
*
* This file defines types and data structure for the virtual RTC device.
*/
typedef int32_t time_t;
/* Register layout of the RTC */
@ -29,17 +48,34 @@ struct rtcdev {
uint8_t century;
};
/**
* @brief Data structure to illustrate a virtual RTC device.
*
* This structure contains the information of a virtual RTC device.
*
* @consistency self.vm->vrtc == self
* @alignment N/A
*
* @remark N/A
*/
struct acrn_vrtc {
struct acrn_vm *vm;
uint32_t addr; /* RTC register to read or write */
time_t base_rtctime; /* Base time calulated from physical rtc register. */
time_t offset_rtctime; /* RTC offset against base time. */
time_t last_rtctime; /* Last RTC time, to keep monotonicity. */
uint64_t base_tsc; /* Base tsc value */
struct rtcdev rtcdev; /* RTC register */
struct acrn_vm *vm; /**< Pointer to the VM that owns the virtual RTC device. */
/**
* @brief The RTC register to read or write.
*
* To access RTC registers, the guest writes the register index to the RTC address port and then reads/writes
* the register value from/to the RTC data port. This field is used to store the register index.
*/
uint32_t addr;
time_t base_rtctime; /**< Base time calculated from physical RTC register. */
time_t offset_rtctime; /**< RTC offset against base time. */
time_t last_rtctime; /**< Last RTC time, to keep monotonicity. */
uint64_t base_tsc; /**< Base TSC value. */
struct rtcdev rtcdev; /**< Register layout of RTC. */
};
#endif /* VRTC_H */
/**
* @}
*/