1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openeuler-stratovirt

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Это зеркальный репозиторий, синхронизируется ежедневно с исходного репозитория.
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
test_helper.rs 4.6 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
yexiao Отправлено год назад 8c394a6
// Copyright (c) 2023 Huawei Technologies Co.,Ltd. All rights reserved.
//
// StratoVirt is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan
// PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
// http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY
// KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
use std::sync::{Arc, Mutex, RwLock};
use std::time::{Duration, Instant};
use once_cell::sync::{Lazy, OnceCell};
#[derive(Default, Clone, Copy)]
struct MsixMsg {
addr: u64,
data: u32,
}
impl MsixMsg {
fn new(addr: u64, data: u32) -> Self {
MsixMsg { addr, data }
}
}
#[derive(Default, Clone, Copy, Debug)]
struct IntxInfo {
irq: u32,
level: i8,
}
impl IntxInfo {
fn new(irq: u32, level: i8) -> Self {
IntxInfo { irq, level }
}
}
static TEST_ENABLED: OnceCell<bool> = OnceCell::new();
static TEST_BASE_TIME: OnceCell<Instant> = OnceCell::new();
static mut TEST_CLOCK: Option<Arc<RwLock<u64>>> = None;
static TEST_MSIX_LIST: Lazy<Mutex<Vec<MsixMsg>>> = Lazy::new(|| Mutex::new(Vec::new()));
static TEST_INTX_LIST: Lazy<Mutex<Vec<IntxInfo>>> = Lazy::new(|| Mutex::new(Vec::new()));
pub fn set_test_enabled() {
if let Err(_e) = TEST_ENABLED.set(true) {
panic!("Failed to enable test server.");
}
if let Err(_e) = TEST_BASE_TIME.set(Instant::now()) {
panic!("Failed to initialize clock");
}
// SAFETY: This module is only used for test.
unsafe {
if TEST_CLOCK.is_none() {
TEST_CLOCK = Some(Arc::new(RwLock::new(0)));
}
}
}
pub fn is_test_enabled() -> bool {
*TEST_ENABLED.get_or_init(|| false)
}
pub fn set_test_clock(value: u64) {
// SAFETY: This module is only used for test.
unsafe {
if TEST_CLOCK.is_none() {
panic!("TEST_CLOCK has not been initialized.");
}
if value <= get_test_clock() {
return;
}
let mut test_clock = TEST_CLOCK.as_ref().unwrap().write().unwrap();
*test_clock = value;
}
}
pub fn get_test_clock() -> u64 {
// SAFETY: This module is only used for test.
unsafe {
if TEST_CLOCK.is_none() {
panic!("TEST_CLOCK has not been initialized.");
}
*TEST_CLOCK.as_ref().unwrap().read().unwrap()
}
}
pub fn get_test_time() -> Instant {
// SAFETY: This module is only used for test.
unsafe {
if TEST_CLOCK.is_none() {
panic!("TEST_CLOCK has not been initialized.");
}
TEST_BASE_TIME
.get()
.unwrap()
.checked_add(Duration::from_nanos(get_test_clock()))
.unwrap()
}
}
pub fn add_msix_msg(addr: u64, data: u32) {
let new_msg = MsixMsg::new(addr, data);
let mut msix_list_lock = TEST_MSIX_LIST.lock().unwrap();
for msg in msix_list_lock.iter() {
if new_msg.addr == msg.addr && new_msg.data == msg.data {
return;
}
}
msix_list_lock.push(new_msg);
}
pub fn has_msix_msg(addr: u64, data: u32) -> bool {
let target_msg = MsixMsg::new(addr, data);
let mut target_index: Option<usize> = None;
let mut msix_list_lock = TEST_MSIX_LIST.lock().unwrap();
for (index, msg) in msix_list_lock.iter().enumerate() {
if target_msg.addr == msg.addr && target_msg.data == msg.data {
target_index = Some(index);
break;
}
}
match target_index {
Some(i) => {
msix_list_lock.remove(i);
true
}
None => false,
}
}
pub fn trigger_intx(irq: u32, change: i8) {
let new_intx = IntxInfo::new(irq, change);
let mut intx_list_lock = TEST_INTX_LIST.lock().unwrap();
for intx in intx_list_lock.iter_mut() {
if intx.irq == new_intx.irq {
intx.level += new_intx.level;
return;
}
}
intx_list_lock.push(new_intx);
}
pub fn query_intx(irq: u32) -> bool {
let mut intx_list_lock = TEST_INTX_LIST.lock().unwrap();
for intx in intx_list_lock.iter_mut() {
if intx.irq == irq {
return intx.level > 0;
}
}
false
}
pub fn eoi_intx(irq: u32) -> bool {
let mut intx_list_lock = TEST_INTX_LIST.lock().unwrap();
for intx in intx_list_lock.iter_mut() {
if intx.irq == irq {
if intx.level == 0 {
return false;
} else {
intx.level -= 1;
return true;
}
}
}
false
}

Комментарий ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/openeuler-stratovirt.git
git@gitlife.ru:oschina-mirror/openeuler-stratovirt.git
oschina-mirror
openeuler-stratovirt
openeuler-stratovirt
master