mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 02:46:47 +00:00
修复内核的clippy检查报错 (#637)
修复内核的clippy检查报错 --------- Co-authored-by: Samuel Dai <947309196@qq.com> Co-authored-by: Donkey Kane <109840258+xiaolin2004@users.noreply.github.com> Co-authored-by: themildwind <107623059+themildwind@users.noreply.github.com> Co-authored-by: GnoCiYeH <heyicong@dragonos.org> Co-authored-by: MemoryShore <105195940+MemoryShore@users.noreply.github.com> Co-authored-by: 曾俊 <110876916+ZZJJWarth@users.noreply.github.com> Co-authored-by: sun5etop <146408999+sun5etop@users.noreply.github.com> Co-authored-by: hmt <114841534+1037827920@users.noreply.github.com> Co-authored-by: laokengwt <143977175+laokengwt@users.noreply.github.com> Co-authored-by: TTaq <103996388+TTaq@users.noreply.github.com> Co-authored-by: Jomo <2512364506@qq.com> Co-authored-by: Samuel Dai <samuka007@qq.com> Co-authored-by: sspphh <112558065+sspphh@users.noreply.github.com>
This commit is contained in:
parent
4695947e1b
commit
b5b571e026
@ -61,8 +61,8 @@ impl<T: BitOps> BitMapCore<T> {
|
||||
pub(crate) fn first_index(&self, data: &[T]) -> Option<usize> {
|
||||
for (i, element) in data.iter().enumerate() {
|
||||
let bit = <T as BitOps>::first_index(element);
|
||||
if bit.is_some() {
|
||||
return Some(i * T::bit_size() + bit.unwrap());
|
||||
if let Some(b) = bit {
|
||||
return Some(i * T::bit_size() + b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,10 +237,8 @@ impl<T: BitOps> BitMapCore<T> {
|
||||
if element == mask {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if element != &T::make_mask(T::bit_size()) {
|
||||
return false;
|
||||
}
|
||||
} else if element != &T::make_mask(T::bit_size()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,6 +309,9 @@ pub trait BitMapOps<T: BitOps> {
|
||||
/// 判断bitmap是否为空
|
||||
fn is_empty(&self) -> bool;
|
||||
|
||||
/// # Safety
|
||||
/// *不应直接修改字节数组*
|
||||
///
|
||||
/// 将bitmap转换为字节数组
|
||||
unsafe fn as_bytes(&self) -> &[u8];
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ use uuid::Uuid;
|
||||
#[proc_macro_attribute]
|
||||
pub fn unified_init(args: TokenStream, input: TokenStream) -> TokenStream {
|
||||
do_unified_init(args, input)
|
||||
.unwrap_or_else(|e| e.to_compile_error().into())
|
||||
.unwrap_or_else(|e| e.to_compile_error())
|
||||
.into()
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ fn do_unified_init(args: TokenStream, input: TokenStream) -> syn::Result<proc_ma
|
||||
|
||||
// 在旁边添加一个UnifiedInitializer
|
||||
let initializer =
|
||||
generate_unified_initializer(&function, &target_slice, function.sig.ident.to_string())?;
|
||||
generate_unified_initializer(&function, target_slice, function.sig.ident.to_string())?;
|
||||
|
||||
// 拼接
|
||||
let mut output = proc_macro2::TokenStream::new();
|
||||
@ -80,7 +80,7 @@ fn do_unified_init(args: TokenStream, input: TokenStream) -> syn::Result<proc_ma
|
||||
/// ```
|
||||
fn check_function_signature(function: &ItemFn) -> syn::Result<()> {
|
||||
// 检查函数签名
|
||||
if function.sig.inputs.len() != 0 {
|
||||
if !function.sig.inputs.is_empty() {
|
||||
return Err(syn::Error::new(
|
||||
function.sig.inputs.span(),
|
||||
"Expected no arguments",
|
||||
@ -111,7 +111,7 @@ fn check_function_signature(function: &ItemFn) -> syn::Result<()> {
|
||||
if let syn::GenericArgument::Type(type_arg) = generic_args.args.first().unwrap()
|
||||
{
|
||||
if let syn::Type::Tuple(tuple) = type_arg {
|
||||
if tuple.elems.len() != 0 {
|
||||
if !tuple.elems.is_empty() {
|
||||
return Err(syn::Error::new(tuple.span(), "Expected empty tuple"));
|
||||
}
|
||||
} else {
|
||||
@ -166,7 +166,7 @@ fn generate_unified_initializer(
|
||||
let initializer_name = format!(
|
||||
"unified_initializer_{}_{}",
|
||||
raw_initializer_name,
|
||||
Uuid::new_v4().to_simple().to_string().to_ascii_uppercase()[..8].to_string()
|
||||
&Uuid::new_v4().to_simple().to_string().to_ascii_uppercase()[..8]
|
||||
)
|
||||
.to_ascii_uppercase();
|
||||
|
||||
|
@ -48,7 +48,7 @@ fn riscv64_do_interrupt(_trap_frame: &mut TrapFrame) {
|
||||
fn riscv64_do_exception(trap_frame: &mut TrapFrame) {
|
||||
kdebug!(
|
||||
"riscv64_do_exception: from_user: {}",
|
||||
trap_frame.from_user()
|
||||
trap_frame.is_from_user()
|
||||
);
|
||||
let code = trap_frame.cause.code();
|
||||
|
||||
|
@ -108,7 +108,7 @@ impl TrapFrame {
|
||||
/// 中断栈帧在栈上的大小
|
||||
pub const SIZE_ON_STACK: usize = align_up(Self::SIZE, STACK_ALIGN);
|
||||
/// 判断当前中断是否来自用户模式
|
||||
pub fn from_user(&self) -> bool {
|
||||
pub fn is_from_user(&self) -> bool {
|
||||
self.status.spp() == riscv::register::sstatus::SPP::User
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use core::hint::spin_loop;
|
||||
|
||||
use x86::cpuid::{cpuid, CpuIdResult};
|
||||
|
||||
use crate::smp::cpu::ProcessorId;
|
||||
@ -14,5 +16,7 @@ pub fn current_cpu_id() -> ProcessorId {
|
||||
pub unsafe fn cpu_reset() -> ! {
|
||||
// 重启计算机
|
||||
unsafe { x86::io::outb(0x64, 0xfe) };
|
||||
loop {}
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ pub enum LocalApicTimerMode {
|
||||
|
||||
impl LocalApicTimer {
|
||||
/// 定时器中断的间隔
|
||||
pub const INTERVAL_MS: u64 = 1000 / HZ as u64;
|
||||
pub const INTERVAL_MS: u64 = 1000 / HZ;
|
||||
pub const DIVISOR: u64 = 4;
|
||||
|
||||
/// IoApicManager 初值为0或false
|
||||
@ -244,7 +244,7 @@ impl LocalApicTimer {
|
||||
|
||||
fn set_divisor(&mut self, divisor: u32) {
|
||||
self.divisor = divisor;
|
||||
CurrentApic.set_timer_divisor(divisor as u32);
|
||||
CurrentApic.set_timer_divisor(divisor);
|
||||
}
|
||||
|
||||
fn set_initial_cnt(&mut self, initial_count: u64) {
|
||||
@ -307,10 +307,7 @@ impl CurrentApic {
|
||||
unsafe { wrmsr(IA32_X2APIC_DIV_CONF, divisor.into()) };
|
||||
} else {
|
||||
unsafe {
|
||||
self.write_xapic_register(
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_CLKDIV,
|
||||
divisor.into(),
|
||||
)
|
||||
self.write_xapic_register(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_CLKDIV, divisor)
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -318,7 +315,7 @@ impl CurrentApic {
|
||||
fn set_timer_initial_count(&self, initial_count: u64) {
|
||||
if self.x2apic_enabled() {
|
||||
unsafe {
|
||||
wrmsr(IA32_X2APIC_INIT_COUNT.into(), initial_count);
|
||||
wrmsr(IA32_X2APIC_INIT_COUNT, initial_count);
|
||||
}
|
||||
} else {
|
||||
unsafe {
|
||||
|
@ -86,14 +86,13 @@ impl IoApic {
|
||||
}
|
||||
return false;
|
||||
})
|
||||
.map(|x| {
|
||||
.and_then(|x| {
|
||||
if let acpi::madt::MadtEntry::IoApic(x) = x {
|
||||
Some(x.io_apic_address)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.flatten()
|
||||
.unwrap();
|
||||
|
||||
let phys_base = PhysAddr::new(io_apic_paddr as usize);
|
||||
@ -193,6 +192,7 @@ impl IoApic {
|
||||
/// * `active_high` - 是否为高电平有效
|
||||
/// * `dest_logic` - 是否为逻辑模式
|
||||
/// * `mask` - 是否屏蔽
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn install(
|
||||
&mut self,
|
||||
rte_index: u8,
|
||||
@ -335,7 +335,9 @@ impl IrqChipData for IoApicChipData {
|
||||
}
|
||||
|
||||
impl IoApicChipData {
|
||||
const DEFAULT: Self = Self::new(0, 0, 0, false, false, false, true);
|
||||
const fn default() -> Self {
|
||||
Self::new(0, 0, 0, false, false, false, true)
|
||||
}
|
||||
|
||||
const fn new(
|
||||
rte_index: u8,
|
||||
@ -412,7 +414,7 @@ pub fn ioapic_init(ignore: &'static [IrqNumber]) {
|
||||
let irq_data = desc.irq_data();
|
||||
let mut chip_info_guard = irq_data.chip_info_write_irqsave();
|
||||
chip_info_guard.set_chip(Some(ioapic_ir_chip()));
|
||||
let chip_data = IoApicChipData::DEFAULT;
|
||||
let chip_data = IoApicChipData::default();
|
||||
chip_data.inner().rte_index = IoApic::vector_rte_index(i as u8);
|
||||
chip_data.inner().vector = i as u8;
|
||||
chip_info_guard.set_chip_data(Some(Arc::new(chip_data)));
|
||||
@ -426,14 +428,13 @@ pub fn ioapic_init(ignore: &'static [IrqNumber]) {
|
||||
}
|
||||
|
||||
fn register_handler(desc: &Arc<IrqDesc>, level_triggered: bool) {
|
||||
let fasteoi: bool;
|
||||
if level_triggered {
|
||||
let fasteoi: bool = if level_triggered {
|
||||
desc.modify_status(IrqLineStatus::empty(), IrqLineStatus::IRQ_LEVEL);
|
||||
fasteoi = true;
|
||||
true
|
||||
} else {
|
||||
desc.modify_status(IrqLineStatus::IRQ_LEVEL, IrqLineStatus::empty());
|
||||
fasteoi = false;
|
||||
}
|
||||
false
|
||||
};
|
||||
|
||||
let handler: &dyn IrqFlowHandler = if fasteoi {
|
||||
fast_eoi_irq_handler()
|
||||
@ -536,7 +537,7 @@ impl IrqChip for IoApicChip {
|
||||
chip_data_inner.level_triggered = level_triggered;
|
||||
chip_data_inner.sync_to_chip()?;
|
||||
|
||||
return Ok(IrqChipSetMaskResult::SetMaskOk);
|
||||
return Ok(IrqChipSetMaskResult::Success);
|
||||
}
|
||||
|
||||
fn irq_set_affinity(
|
||||
@ -560,14 +561,14 @@ impl IrqChip for IoApicChip {
|
||||
let mut chip_data_inner = chip_data.inner();
|
||||
let origin_dest = chip_data_inner.dest;
|
||||
if origin_dest == dest {
|
||||
return Ok(IrqChipSetMaskResult::SetMaskOk);
|
||||
return Ok(IrqChipSetMaskResult::Success);
|
||||
}
|
||||
|
||||
chip_data_inner.dest = dest;
|
||||
|
||||
chip_data_inner.sync_to_chip()?;
|
||||
|
||||
return Ok(IrqChipSetMaskResult::SetMaskOk);
|
||||
return Ok(IrqChipSetMaskResult::Success);
|
||||
}
|
||||
|
||||
fn irq_unmask(&self, irq: &Arc<IrqData>) -> Result<(), SystemError> {
|
||||
|
@ -205,14 +205,13 @@ pub(super) fn irq_msi_compose_msg(cfg: &HardwareIrqConfig, msg: &mut MsiMsg, dma
|
||||
// todo: 判断vmx是否支持 extended destination mode
|
||||
// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/apic.c?fi=__irq_msi_compose_msg#2580
|
||||
address_lo.set_virt_destid_8_14(cfg.apic_id.data() >> 8);
|
||||
} else {
|
||||
if unlikely(cfg.apic_id.data() > 0xff) {
|
||||
kwarn!(
|
||||
"irq_msi_compose_msg: Invalid APIC ID: {}",
|
||||
cfg.apic_id.data()
|
||||
);
|
||||
}
|
||||
} else if unlikely(cfg.apic_id.data() > 0xff) {
|
||||
kwarn!(
|
||||
"irq_msi_compose_msg: Invalid APIC ID: {}",
|
||||
cfg.apic_id.data()
|
||||
);
|
||||
}
|
||||
|
||||
msg.address_hi = address_hi.into();
|
||||
msg.address_lo = address_lo.into();
|
||||
msg.data = arch_data.into();
|
||||
|
@ -118,9 +118,9 @@ pub enum LVTRegister {
|
||||
ErrorReg = 0x837,
|
||||
}
|
||||
|
||||
impl Into<u32> for LVTRegister {
|
||||
fn into(self) -> u32 {
|
||||
self as u32
|
||||
impl From<LVTRegister> for u32 {
|
||||
fn from(val: LVTRegister) -> Self {
|
||||
val as u32
|
||||
}
|
||||
}
|
||||
|
||||
@ -454,9 +454,9 @@ impl CurrentApic {
|
||||
}
|
||||
|
||||
pub(self) unsafe fn write_xapic_register(&self, reg: XApicOffset, value: u32) {
|
||||
current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
|
||||
if let Some(xapic) = current_xapic_instance().borrow_mut().as_mut() {
|
||||
xapic.write(reg, value);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// 屏蔽类8259A芯片
|
||||
@ -524,10 +524,8 @@ impl LocalAPIC for CurrentApic {
|
||||
fn send_eoi(&self) {
|
||||
if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
|
||||
X2Apic.send_eoi();
|
||||
} else {
|
||||
current_xapic_instance().borrow().as_ref().map(|xapic| {
|
||||
xapic.send_eoi();
|
||||
});
|
||||
} else if let Some(xapic) = current_xapic_instance().borrow().as_ref() {
|
||||
xapic.send_eoi();
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,10 +580,8 @@ impl LocalAPIC for CurrentApic {
|
||||
fn set_lvt(&mut self, lvt: LVT) {
|
||||
if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
|
||||
X2Apic.set_lvt(lvt);
|
||||
} else {
|
||||
current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
|
||||
xapic.set_lvt(lvt);
|
||||
});
|
||||
} else if let Some(xapic) = current_xapic_instance().borrow_mut().as_mut() {
|
||||
xapic.set_lvt(lvt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,20 +600,16 @@ impl LocalAPIC for CurrentApic {
|
||||
fn mask_all_lvt(&mut self) {
|
||||
if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
|
||||
X2Apic.mask_all_lvt();
|
||||
} else {
|
||||
current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
|
||||
xapic.mask_all_lvt();
|
||||
});
|
||||
} else if let Some(xapic) = current_xapic_instance().borrow_mut().as_mut() {
|
||||
xapic.mask_all_lvt();
|
||||
}
|
||||
}
|
||||
|
||||
fn write_icr(&self, icr: Icr) {
|
||||
if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
|
||||
X2Apic.write_icr(icr);
|
||||
} else {
|
||||
current_xapic_instance().borrow().as_ref().map(|xapic| {
|
||||
xapic.write_icr(icr);
|
||||
});
|
||||
} else if let Some(xapic) = current_xapic_instance().borrow().as_ref() {
|
||||
xapic.write_icr(icr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,13 +22,10 @@ impl LocalAPIC for X2Apic {
|
||||
fn init_current_cpu(&mut self) -> bool {
|
||||
unsafe {
|
||||
// 设置 x2APIC 使能位
|
||||
wrmsr(
|
||||
IA32_APIC_BASE.into(),
|
||||
rdmsr(IA32_APIC_BASE.into()) | 1 << 10,
|
||||
);
|
||||
wrmsr(IA32_APIC_BASE, rdmsr(IA32_APIC_BASE) | 1 << 10);
|
||||
|
||||
assert!(
|
||||
(rdmsr(IA32_APIC_BASE.into()) & 0xc00) == 0xc00,
|
||||
(rdmsr(IA32_APIC_BASE) & 0xc00) == 0xc00,
|
||||
"x2APIC enable failed."
|
||||
);
|
||||
|
||||
@ -40,17 +37,17 @@ impl LocalAPIC for X2Apic {
|
||||
1 << 8
|
||||
};
|
||||
|
||||
wrmsr(IA32_X2APIC_SIVR.into(), val);
|
||||
wrmsr(IA32_X2APIC_SIVR, val);
|
||||
|
||||
assert!(
|
||||
(rdmsr(IA32_X2APIC_SIVR.into()) & 0x100) == 0x100,
|
||||
(rdmsr(IA32_X2APIC_SIVR) & 0x100) == 0x100,
|
||||
"x2APIC software enable failed."
|
||||
);
|
||||
kinfo!("x2APIC software enabled.");
|
||||
|
||||
if self.support_eoi_broadcast_suppression() {
|
||||
assert!(
|
||||
(rdmsr(IA32_X2APIC_SIVR.into()) & 0x1000) == 0x1000,
|
||||
(rdmsr(IA32_X2APIC_SIVR) & 0x1000) == 0x1000,
|
||||
"x2APIC EOI broadcast suppression enable failed."
|
||||
);
|
||||
kinfo!("x2APIC EOI broadcast suppression enabled.");
|
||||
@ -66,26 +63,26 @@ impl LocalAPIC for X2Apic {
|
||||
/// 发送 EOI (End Of Interrupt)
|
||||
fn send_eoi(&self) {
|
||||
unsafe {
|
||||
wrmsr(IA32_X2APIC_EOI.into(), 0);
|
||||
wrmsr(IA32_X2APIC_EOI, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取 x2APIC 版本
|
||||
fn version(&self) -> u8 {
|
||||
unsafe { (rdmsr(IA32_X2APIC_VERSION.into()) & 0xff) as u8 }
|
||||
unsafe { (rdmsr(IA32_X2APIC_VERSION) & 0xff) as u8 }
|
||||
}
|
||||
|
||||
fn support_eoi_broadcast_suppression(&self) -> bool {
|
||||
unsafe { ((rdmsr(IA32_X2APIC_VERSION.into()) >> 24) & 1) == 1 }
|
||||
unsafe { ((rdmsr(IA32_X2APIC_VERSION) >> 24) & 1) == 1 }
|
||||
}
|
||||
|
||||
fn max_lvt_entry(&self) -> u8 {
|
||||
unsafe { ((rdmsr(IA32_X2APIC_VERSION.into()) >> 16) & 0xff) as u8 + 1 }
|
||||
unsafe { ((rdmsr(IA32_X2APIC_VERSION) >> 16) & 0xff) as u8 + 1 }
|
||||
}
|
||||
|
||||
/// 获取 x2APIC 的 APIC ID
|
||||
fn id(&self) -> ApicId {
|
||||
unsafe { ApicId::new(rdmsr(IA32_X2APIC_APICID.into()) as u32) }
|
||||
unsafe { ApicId::new(rdmsr(IA32_X2APIC_APICID) as u32) }
|
||||
}
|
||||
|
||||
/// 设置 Local Vector Table (LVT) 寄存器
|
||||
|
@ -91,9 +91,9 @@ pub enum XApicOffset {
|
||||
LOCAL_APIC_OFFSET_Local_APIC_CLKDIV = 0x3e0,
|
||||
}
|
||||
|
||||
impl Into<u32> for XApicOffset {
|
||||
fn into(self) -> u32 {
|
||||
self as u32
|
||||
impl From<XApicOffset> for u32 {
|
||||
fn from(val: XApicOffset) -> Self {
|
||||
val as u32
|
||||
}
|
||||
}
|
||||
|
||||
@ -223,14 +223,11 @@ impl LocalAPIC for XApic {
|
||||
return false;
|
||||
}
|
||||
// 设置 Spurious Interrupt Vector Register
|
||||
let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR.into());
|
||||
let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
||||
|
||||
self.write(
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR.into(),
|
||||
val | ENABLE,
|
||||
);
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR, val | ENABLE);
|
||||
|
||||
let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR.into());
|
||||
let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR);
|
||||
if val & ENABLE == 0 {
|
||||
kerror!("xAPIC software enable failed.");
|
||||
|
||||
@ -246,23 +243,19 @@ impl LocalAPIC for XApic {
|
||||
self.mask_all_lvt();
|
||||
|
||||
// 清除错误状态寄存器(需要连续写入两次)
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR.into(), 0);
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR.into(), 0);
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR, 0);
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR, 0);
|
||||
|
||||
// 确认任何未完成的中断
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI.into(), 0);
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI, 0);
|
||||
|
||||
// 发送 Init Level De-Assert 信号以同步仲裁ID
|
||||
self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32, 0);
|
||||
self.write(
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32.into(),
|
||||
0,
|
||||
);
|
||||
self.write(
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into(),
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0,
|
||||
BCAST | INIT | LEVEL,
|
||||
);
|
||||
while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into()) & DELIVS != 0
|
||||
{
|
||||
while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & DELIVS != 0 {
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
@ -274,34 +267,28 @@ impl LocalAPIC for XApic {
|
||||
fn send_eoi(&self) {
|
||||
unsafe {
|
||||
let s = self as *const Self as *mut Self;
|
||||
(*s).write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI.into(), 0);
|
||||
(*s).write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取版本号
|
||||
fn version(&self) -> u8 {
|
||||
unsafe {
|
||||
(self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version.into()) & 0xff) as u8
|
||||
}
|
||||
unsafe { (self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version) & 0xff) as u8 }
|
||||
}
|
||||
|
||||
fn support_eoi_broadcast_suppression(&self) -> bool {
|
||||
unsafe {
|
||||
((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version.into()) >> 24) & 1) == 1
|
||||
}
|
||||
unsafe { ((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version) >> 24) & 1) == 1 }
|
||||
}
|
||||
|
||||
fn max_lvt_entry(&self) -> u8 {
|
||||
unsafe {
|
||||
((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version.into()) >> 16) & 0xff)
|
||||
as u8
|
||||
+ 1
|
||||
((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version) >> 16) & 0xff) as u8 + 1
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取ID
|
||||
fn id(&self) -> ApicId {
|
||||
unsafe { ApicId::new(self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID.into()) >> 24) }
|
||||
unsafe { ApicId::new(self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID) >> 24) }
|
||||
}
|
||||
|
||||
/// 设置LVT寄存器的值
|
||||
@ -315,7 +302,7 @@ impl LocalAPIC for XApic {
|
||||
unsafe {
|
||||
LVT::new(
|
||||
reg,
|
||||
self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER.into()),
|
||||
self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
@ -334,23 +321,21 @@ impl LocalAPIC for XApic {
|
||||
fn write_icr(&self, icr: x86::apic::Icr) {
|
||||
unsafe {
|
||||
// Wait for any previous send to finish
|
||||
while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into()) & DELIVS != 0
|
||||
{
|
||||
while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & DELIVS != 0 {
|
||||
spin_loop();
|
||||
}
|
||||
|
||||
self.write(
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32.into(),
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32,
|
||||
icr.upper(),
|
||||
);
|
||||
self.write(
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into(),
|
||||
XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0,
|
||||
icr.lower(),
|
||||
);
|
||||
|
||||
// Wait for send to finish
|
||||
while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0.into()) & DELIVS != 0
|
||||
{
|
||||
while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & DELIVS != 0 {
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ impl Hpet {
|
||||
let freq = regs.frequency();
|
||||
kdebug!("HPET frequency: {} Hz", freq);
|
||||
let ticks = Self::HPET0_INTERVAL_USEC * freq / 1000000;
|
||||
if ticks <= 0 || ticks > freq * 8 {
|
||||
if ticks == 0 || ticks > freq * 8 {
|
||||
kerror!("HPET enable: ticks '{ticks}' is invalid");
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
@ -237,7 +237,7 @@ impl Hpet {
|
||||
/// 处理HPET的中断
|
||||
pub(super) fn handle_irq(&self, timer_num: u32) {
|
||||
if timer_num == 0 {
|
||||
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
||||
assert!(!CurrentIrqArch::is_irq_enabled());
|
||||
update_timer_jiffies(Self::HPET0_INTERVAL_USEC, Self::HPET0_INTERVAL_USEC as i64);
|
||||
|
||||
if let Ok(first_expire) = timer_get_first_expire() {
|
||||
|
@ -171,7 +171,7 @@ impl TSCManager {
|
||||
|
||||
// 如果误差在10%以内,那么认为测量成功
|
||||
// 返回参考值,因为它是更精确的
|
||||
if delta >= 90 && delta <= 110 {
|
||||
if (90..=110).contains(&delta) {
|
||||
kinfo!(
|
||||
"PIT calibration matches {}. {} loops",
|
||||
if hpet { "HPET" } else { "PMTIMER" },
|
||||
|
@ -49,9 +49,10 @@ unsafe extern "C" fn kernel_main(
|
||||
gdtp.base = gdt_vaddr.data() as *const usize;
|
||||
gdtp.limit = bsp_gdt_size as u16 - 1;
|
||||
|
||||
let mut idtp = DescriptorTablePointer::<usize>::default();
|
||||
idtp.base = idt_vaddr.data() as *const usize;
|
||||
idtp.limit = bsp_idt_size as u16 - 1;
|
||||
let idtp = DescriptorTablePointer::<usize> {
|
||||
base: idt_vaddr.data() as *const usize,
|
||||
limit: bsp_idt_size as u16 - 1,
|
||||
};
|
||||
|
||||
x86::dtables::lgdt(&gdtp);
|
||||
x86::dtables::lidt(&idtp);
|
||||
|
@ -7,7 +7,7 @@ use crate::{
|
||||
},
|
||||
exception::{irqdesc::irq_desc_manager, softirq::do_softirq, IrqNumber},
|
||||
process::{
|
||||
process::{current_pcb_flags, current_pcb_preempt_count},
|
||||
utils::{current_pcb_flags, current_pcb_preempt_count},
|
||||
ProcessFlags,
|
||||
},
|
||||
};
|
||||
@ -18,7 +18,7 @@ use super::TrapFrame;
|
||||
unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) {
|
||||
// swapgs
|
||||
|
||||
if trap_frame.from_user() {
|
||||
if trap_frame.is_from_user() {
|
||||
x86_64::registers::segmentation::GS::swap();
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,9 @@ impl From<IpiKind> for ArchIpiKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<u8> for ArchIpiKind {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
impl From<ArchIpiKind> for u8 {
|
||||
fn from(value: ArchIpiKind) -> Self {
|
||||
match value {
|
||||
ArchIpiKind::KickCpu => IPI_NUM_KICK_CPU.data() as u8,
|
||||
ArchIpiKind::FlushTLB => IPI_NUM_FLUSH_TLB.data() as u8,
|
||||
ArchIpiKind::SpecVector(vec) => (vec.data() & 0xFF) as u8,
|
||||
@ -76,16 +76,14 @@ impl From<IpiTarget> for ArchIpiTarget {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<ApicId> for ArchIpiTarget {
|
||||
fn into(self) -> ApicId {
|
||||
if let ArchIpiTarget::Specified(id) = self {
|
||||
impl From<ArchIpiTarget> for ApicId {
|
||||
fn from(val: ArchIpiTarget) -> Self {
|
||||
if let ArchIpiTarget::Specified(id) = val {
|
||||
return id;
|
||||
} else if CurrentApic.x2apic_enabled() {
|
||||
return x86::apic::ApicId::X2Apic(0);
|
||||
} else {
|
||||
if CurrentApic.x2apic_enabled() {
|
||||
return x86::apic::ApicId::X2Apic(0);
|
||||
} else {
|
||||
return x86::apic::ApicId::XApic(0);
|
||||
}
|
||||
return x86::apic::ApicId::XApic(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -104,16 +102,16 @@ impl ArchIpiTarget {
|
||||
#[inline(always)]
|
||||
fn cpu_id_to_apic_id(cpu_id: ProcessorId) -> x86::apic::ApicId {
|
||||
if CurrentApic.x2apic_enabled() {
|
||||
x86::apic::ApicId::X2Apic(cpu_id.data() as u32)
|
||||
x86::apic::ApicId::X2Apic(cpu_id.data())
|
||||
} else {
|
||||
x86::apic::ApicId::XApic(cpu_id.data() as u8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<x86::apic::DestinationShorthand> for ArchIpiTarget {
|
||||
fn into(self) -> x86::apic::DestinationShorthand {
|
||||
match self {
|
||||
impl From<ArchIpiTarget> for x86::apic::DestinationShorthand {
|
||||
fn from(val: ArchIpiTarget) -> Self {
|
||||
match val {
|
||||
ArchIpiTarget::Specified(_) => x86::apic::DestinationShorthand::NoShorthand,
|
||||
ArchIpiTarget::Current => x86::apic::DestinationShorthand::Myself,
|
||||
ArchIpiTarget::All => x86::apic::DestinationShorthand::AllIncludingSelf,
|
||||
|
@ -168,11 +168,7 @@ impl TrapFrame {
|
||||
}
|
||||
|
||||
/// 判断当前中断是否来自用户模式
|
||||
pub fn from_user(&self) -> bool {
|
||||
if (self.cs & 0x3) != 0 {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
pub fn is_from_user(&self) -> bool {
|
||||
return (self.cs & 0x3) != 0;
|
||||
}
|
||||
}
|
||||
|
@ -214,23 +214,20 @@ unsafe extern "C" fn do_invalid_TSS(regs: &'static TrapFrame, error_code: u64) {
|
||||
const ERR_MSG_3: &str = "Refers to a descriptor in the current LDT.\n";
|
||||
const ERR_MSG_4: &str = "Refers to a descriptor in the GDT.\n";
|
||||
|
||||
let msg1: &str;
|
||||
if (error_code & 0x1) != 0 {
|
||||
msg1 = ERR_MSG_1;
|
||||
let msg1: &str = if (error_code & 0x1) != 0 {
|
||||
ERR_MSG_1
|
||||
} else {
|
||||
msg1 = "";
|
||||
}
|
||||
""
|
||||
};
|
||||
|
||||
let msg2: &str;
|
||||
if (error_code & 0x02) != 0 {
|
||||
msg2 = ERR_MSG_2;
|
||||
let msg2: &str = if (error_code & 0x02) != 0 {
|
||||
ERR_MSG_2
|
||||
} else if (error_code & 0x04) != 0 {
|
||||
ERR_MSG_3
|
||||
} else {
|
||||
if (error_code & 0x04) != 0 {
|
||||
msg2 = ERR_MSG_3;
|
||||
} else {
|
||||
msg2 = ERR_MSG_4;
|
||||
}
|
||||
}
|
||||
ERR_MSG_4
|
||||
};
|
||||
|
||||
kerror!(
|
||||
"do_invalid_TSS(10), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}\n{}{}",
|
||||
error_code,
|
||||
@ -281,30 +278,27 @@ unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code:
|
||||
const ERR_MSG_4: &str = "Refers to a segment or gate descriptor in the LDT;\n";
|
||||
const ERR_MSG_5: &str = "Refers to a descriptor in the current GDT;\n";
|
||||
|
||||
let msg1: &str;
|
||||
if (error_code & 0x1) != 0 {
|
||||
msg1 = ERR_MSG_1;
|
||||
let msg1: &str = if (error_code & 0x1) != 0 {
|
||||
ERR_MSG_1
|
||||
} else {
|
||||
msg1 = "";
|
||||
}
|
||||
""
|
||||
};
|
||||
|
||||
let msg2: &str;
|
||||
if (error_code & 0x02) != 0 {
|
||||
msg2 = ERR_MSG_2;
|
||||
let msg2: &str = if (error_code & 0x02) != 0 {
|
||||
ERR_MSG_2
|
||||
} else {
|
||||
msg2 = ERR_MSG_3;
|
||||
}
|
||||
ERR_MSG_3
|
||||
};
|
||||
|
||||
let msg3: &str;
|
||||
if (error_code & 0x02) == 0 {
|
||||
let msg3: &str = if (error_code & 0x02) == 0 {
|
||||
if (error_code & 0x04) != 0 {
|
||||
msg3 = ERR_MSG_4;
|
||||
ERR_MSG_4
|
||||
} else {
|
||||
msg3 = ERR_MSG_5;
|
||||
ERR_MSG_5
|
||||
}
|
||||
} else {
|
||||
msg3 = "";
|
||||
}
|
||||
""
|
||||
};
|
||||
kerror!(
|
||||
"do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}
|
||||
{}{}{}
|
||||
|
@ -92,9 +92,9 @@ impl From<usize> for Signal {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<usize> for Signal {
|
||||
fn into(self) -> usize {
|
||||
self as usize
|
||||
impl From<Signal> for usize {
|
||||
fn from(val: Signal) -> Self {
|
||||
val as usize
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,10 +109,10 @@ impl From<i32> for Signal {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<SigSet> for Signal {
|
||||
fn into(self) -> SigSet {
|
||||
impl From<Signal> for SigSet {
|
||||
fn from(val: Signal) -> Self {
|
||||
SigSet {
|
||||
bits: (1 << (self as usize - 1) as u64),
|
||||
bits: (1 << (val as usize - 1) as u64),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -147,39 +147,39 @@ impl Signal {
|
||||
Signal::INVALID => {
|
||||
kerror!("attempting to handler an Invalid");
|
||||
}
|
||||
Signal::SIGHUP => sig_terminate(self.clone()),
|
||||
Signal::SIGINT => sig_terminate(self.clone()),
|
||||
Signal::SIGQUIT => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGILL => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGTRAP => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGABRT_OR_IOT => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGBUS => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGFPE => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGKILL => sig_terminate(self.clone()),
|
||||
Signal::SIGUSR1 => sig_terminate(self.clone()),
|
||||
Signal::SIGSEGV => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGUSR2 => sig_terminate(self.clone()),
|
||||
Signal::SIGPIPE => sig_terminate(self.clone()),
|
||||
Signal::SIGALRM => sig_terminate(self.clone()),
|
||||
Signal::SIGTERM => sig_terminate(self.clone()),
|
||||
Signal::SIGSTKFLT => sig_terminate(self.clone()),
|
||||
Signal::SIGCHLD => sig_ignore(self.clone()),
|
||||
Signal::SIGCONT => sig_continue(self.clone()),
|
||||
Signal::SIGSTOP => sig_stop(self.clone()),
|
||||
Signal::SIGTSTP => sig_stop(self.clone()),
|
||||
Signal::SIGTTIN => sig_stop(self.clone()),
|
||||
Signal::SIGTTOU => sig_stop(self.clone()),
|
||||
Signal::SIGURG => sig_ignore(self.clone()),
|
||||
Signal::SIGXCPU => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGXFSZ => sig_terminate_dump(self.clone()),
|
||||
Signal::SIGVTALRM => sig_terminate(self.clone()),
|
||||
Signal::SIGPROF => sig_terminate(self.clone()),
|
||||
Signal::SIGWINCH => sig_ignore(self.clone()),
|
||||
Signal::SIGIO_OR_POLL => sig_terminate(self.clone()),
|
||||
Signal::SIGPWR => sig_terminate(self.clone()),
|
||||
Signal::SIGSYS => sig_terminate(self.clone()),
|
||||
Signal::SIGRTMIN => sig_terminate(self.clone()),
|
||||
Signal::SIGRTMAX => sig_terminate(self.clone()),
|
||||
Signal::SIGHUP => sig_terminate(*self),
|
||||
Signal::SIGINT => sig_terminate(*self),
|
||||
Signal::SIGQUIT => sig_terminate_dump(*self),
|
||||
Signal::SIGILL => sig_terminate_dump(*self),
|
||||
Signal::SIGTRAP => sig_terminate_dump(*self),
|
||||
Signal::SIGABRT_OR_IOT => sig_terminate_dump(*self),
|
||||
Signal::SIGBUS => sig_terminate_dump(*self),
|
||||
Signal::SIGFPE => sig_terminate_dump(*self),
|
||||
Signal::SIGKILL => sig_terminate(*self),
|
||||
Signal::SIGUSR1 => sig_terminate(*self),
|
||||
Signal::SIGSEGV => sig_terminate_dump(*self),
|
||||
Signal::SIGUSR2 => sig_terminate(*self),
|
||||
Signal::SIGPIPE => sig_terminate(*self),
|
||||
Signal::SIGALRM => sig_terminate(*self),
|
||||
Signal::SIGTERM => sig_terminate(*self),
|
||||
Signal::SIGSTKFLT => sig_terminate(*self),
|
||||
Signal::SIGCHLD => sig_ignore(*self),
|
||||
Signal::SIGCONT => sig_continue(*self),
|
||||
Signal::SIGSTOP => sig_stop(*self),
|
||||
Signal::SIGTSTP => sig_stop(*self),
|
||||
Signal::SIGTTIN => sig_stop(*self),
|
||||
Signal::SIGTTOU => sig_stop(*self),
|
||||
Signal::SIGURG => sig_ignore(*self),
|
||||
Signal::SIGXCPU => sig_terminate_dump(*self),
|
||||
Signal::SIGXFSZ => sig_terminate_dump(*self),
|
||||
Signal::SIGVTALRM => sig_terminate(*self),
|
||||
Signal::SIGPROF => sig_terminate(*self),
|
||||
Signal::SIGWINCH => sig_ignore(*self),
|
||||
Signal::SIGIO_OR_POLL => sig_terminate(*self),
|
||||
Signal::SIGPWR => sig_terminate(*self),
|
||||
Signal::SIGSYS => sig_terminate(*self),
|
||||
Signal::SIGRTMIN => sig_terminate(*self),
|
||||
Signal::SIGRTMAX => sig_terminate(*self),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -275,7 +275,7 @@ bitflags! {
|
||||
const SIGSYS = 1<<30;
|
||||
const SIGRTMIN = 1<<31;
|
||||
// TODO 写上实时信号
|
||||
const SIGRTMAX = 1<<MAX_SIG_NUM-1;
|
||||
const SIGRTMAX = 1 << (MAX_SIG_NUM-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -309,9 +309,9 @@ pub enum SigChildCode {
|
||||
Continued = 6,
|
||||
}
|
||||
|
||||
impl Into<i32> for SigChildCode {
|
||||
fn into(self) -> i32 {
|
||||
self as i32
|
||||
impl From<SigChildCode> for i32 {
|
||||
fn from(value: SigChildCode) -> Self {
|
||||
value as i32
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,11 +363,11 @@ impl SigContext {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let mut archinfo_guard = pcb.arch_info_irqsave();
|
||||
self.oldmask = *mask;
|
||||
self.frame = frame.clone();
|
||||
self.frame = *frame;
|
||||
// context.trap_num = unsafe { (*current_thread).trap_num };
|
||||
// context.err_code = unsafe { (*current_thread).err_code };
|
||||
// context.cr2 = unsafe { (*current_thread).cr2 };
|
||||
self.reserved_for_x87_state = archinfo_guard.fp_state().clone();
|
||||
self.reserved_for_x87_state = *archinfo_guard.fp_state();
|
||||
|
||||
// 保存完毕后,清空fp_state,以免下次save的时候,出现SIMD exception
|
||||
archinfo_guard.clear_fp_state();
|
||||
@ -385,12 +385,12 @@ impl SigContext {
|
||||
pub fn restore_sigcontext(&mut self, frame: &mut TrapFrame) -> bool {
|
||||
let guard = ProcessManager::current_pcb();
|
||||
let mut arch_info = guard.arch_info_irqsave();
|
||||
(*frame) = self.frame.clone();
|
||||
(*frame) = self.frame;
|
||||
// (*current_thread).trap_num = (*context).trap_num;
|
||||
*arch_info.cr2_mut() = self.cr2 as usize;
|
||||
// (*current_thread).err_code = (*context).err_code;
|
||||
// 如果当前进程有fpstate,则将其恢复到pcb的fp_state中
|
||||
*arch_info.fp_state_mut() = self.reserved_for_x87_state.clone();
|
||||
*arch_info.fp_state_mut() = self.reserved_for_x87_state;
|
||||
arch_info.restore_fp_state();
|
||||
return true;
|
||||
}
|
||||
@ -425,7 +425,7 @@ impl SignalArch for X86_64SignalArch {
|
||||
let siginfo_read_guard = siginfo.unwrap();
|
||||
|
||||
// 检查sigpending是否为0
|
||||
if siginfo_read_guard.sig_pending().signal().bits() == 0 || !frame.from_user() {
|
||||
if siginfo_read_guard.sig_pending().signal().bits() == 0 || !frame.is_from_user() {
|
||||
// 若没有正在等待处理的信号,或者将要返回到的是内核态,则返回
|
||||
return;
|
||||
}
|
||||
@ -435,7 +435,7 @@ impl SignalArch for X86_64SignalArch {
|
||||
let mut sig_number: Signal;
|
||||
let mut info: Option<SigInfo>;
|
||||
let mut sigaction: Sigaction;
|
||||
let sig_block: SigSet = siginfo_read_guard.sig_block().clone();
|
||||
let sig_block: SigSet = *siginfo_read_guard.sig_block();
|
||||
drop(siginfo_read_guard);
|
||||
|
||||
let sig_guard = pcb.try_sig_struct_irqsave(5);
|
||||
@ -460,16 +460,16 @@ impl SignalArch for X86_64SignalArch {
|
||||
|
||||
match sigaction.action() {
|
||||
SigactionType::SaHandler(action_type) => match action_type {
|
||||
SaHandlerType::SigError => {
|
||||
SaHandlerType::Error => {
|
||||
kerror!("Trying to handle a Sigerror on Process:{:?}", pcb.pid());
|
||||
return;
|
||||
}
|
||||
SaHandlerType::SigDefault => {
|
||||
SaHandlerType::Default => {
|
||||
sigaction = Sigaction::default();
|
||||
break;
|
||||
}
|
||||
SaHandlerType::SigIgnore => continue,
|
||||
SaHandlerType::SigCustomized(_) => {
|
||||
SaHandlerType::Ignore => continue,
|
||||
SaHandlerType::Customized(_) => {
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -478,7 +478,7 @@ impl SignalArch for X86_64SignalArch {
|
||||
// 如果当前动作是忽略这个信号,就继续循环。
|
||||
}
|
||||
|
||||
let oldset = siginfo_mut_guard.sig_block().clone();
|
||||
let oldset = *siginfo_mut_guard.sig_block();
|
||||
//避免死锁
|
||||
drop(siginfo_mut_guard);
|
||||
drop(sig_guard);
|
||||
@ -557,11 +557,11 @@ fn setup_frame(
|
||||
let temp_handler: *mut c_void;
|
||||
match sigaction.action() {
|
||||
SigactionType::SaHandler(handler_type) => match handler_type {
|
||||
SaHandlerType::SigDefault => {
|
||||
SaHandlerType::Default => {
|
||||
sig.handle_default();
|
||||
return Ok(0);
|
||||
}
|
||||
SaHandlerType::SigCustomized(handler) => {
|
||||
SaHandlerType::Customized(handler) => {
|
||||
// 如果handler位于内核空间
|
||||
if handler >= MMArch::USER_END_VADDR {
|
||||
// 如果当前是SIGSEGV,则采用默认函数处理
|
||||
@ -602,7 +602,7 @@ fn setup_frame(
|
||||
temp_handler = handler.data() as *mut c_void;
|
||||
}
|
||||
}
|
||||
SaHandlerType::SigIgnore => {
|
||||
SaHandlerType::Ignore => {
|
||||
return Ok(0);
|
||||
}
|
||||
_ => {
|
||||
@ -615,7 +615,7 @@ fn setup_frame(
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
}
|
||||
let frame: *mut SigFrame = get_stack(&trap_frame, size_of::<SigFrame>());
|
||||
let frame: *mut SigFrame = get_stack(trap_frame, size_of::<SigFrame>());
|
||||
// kdebug!("frame=0x{:016x}", frame as usize);
|
||||
// 要求这个frame的地址位于用户空间,因此进行校验
|
||||
let r: Result<UserBufferWriter<'_>, SystemError> =
|
||||
@ -646,7 +646,7 @@ fn setup_frame(
|
||||
unsafe {
|
||||
(*frame)
|
||||
.context
|
||||
.setup_sigcontext(oldset, &trap_frame)
|
||||
.setup_sigcontext(oldset, trap_frame)
|
||||
.map_err(|e: SystemError| -> SystemError {
|
||||
let r = Syscall::kill(ProcessManager::current_pcb().pid(), Signal::SIGSEGV as i32);
|
||||
if r.is_err() {
|
||||
|
@ -52,13 +52,10 @@ impl X86_64KVMArch {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[deny(clippy::match_single_binding)]
|
||||
pub fn kvm_arch_dev_ioctl(cmd: u32, _arg: usize) -> Result<usize, SystemError> {
|
||||
match cmd {
|
||||
_ => {
|
||||
kerror!("unknown kvm ioctl cmd: {}", cmd);
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
}
|
||||
kerror!("unknown kvm ioctl cmd: {}", cmd);
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
pub fn kvm_arch_vcpu_create(id: u32) -> Result<Arc<Mutex<VmxVcpu>>, SystemError> {
|
||||
|
@ -53,7 +53,8 @@ pub struct KvmMmuPageRole {
|
||||
// num_objs: u32,
|
||||
// objs: [*mut u8; KVM_NR_MEM_OBJS as usize],
|
||||
// }
|
||||
|
||||
pub type KvmMmuPageFaultHandler =
|
||||
fn(vcpu: &mut VmxVcpu, gpa: u64, error_code: u32, prefault: bool) -> Result<(), SystemError>;
|
||||
#[derive(Default)]
|
||||
pub struct KvmMmu {
|
||||
pub root_hpa: u64,
|
||||
@ -62,14 +63,7 @@ pub struct KvmMmu {
|
||||
// ...还有一些变量不知道用来做什么
|
||||
pub get_cr3: Option<fn(&VmxVcpu) -> u64>,
|
||||
pub set_eptp: Option<fn(u64) -> Result<(), SystemError>>,
|
||||
pub page_fault: Option<
|
||||
fn(
|
||||
vcpu: &mut VmxVcpu,
|
||||
gpa: u64,
|
||||
error_code: u32,
|
||||
prefault: bool,
|
||||
) -> Result<(), SystemError>,
|
||||
>,
|
||||
pub page_fault: Option<KvmMmuPageFaultHandler>,
|
||||
// get_pdptr: Option<fn(& VmxVcpu, index:u32) -> u64>, // Page Directory Pointer Table Register?暂时不知道和CR3的区别是什么
|
||||
// inject_page_fault: Option<fn(&mut VmxVcpu, fault: &X86Exception)>,
|
||||
// gva_to_gpa: Option<fn(&mut VmxVcpu, gva: u64, access: u32, exception: &X86Exception) -> u64>,
|
||||
@ -97,7 +91,7 @@ fn tdp_get_cr3(_vcpu: &VmxVcpu) -> u64 {
|
||||
fn tdp_set_eptp(root_hpa: u64) -> Result<(), SystemError> {
|
||||
// 设置权限位,目前是写死的,可读可写可执行
|
||||
// EPT paging-structure memory type: Uncacheable
|
||||
let mut eptp = 0x0 as u64;
|
||||
let mut eptp = 0x0_u64;
|
||||
// This value is 1 less than the EPT page-walk length. 3 means 4-level paging.
|
||||
eptp |= 0x3 << 3;
|
||||
eptp |= root_hpa & (PAGE_MASK as u64);
|
||||
@ -121,7 +115,7 @@ fn tdp_page_fault(
|
||||
// fast_page_fault(vcpu, gpa, level, error_code)
|
||||
// gfn->pfn
|
||||
let mut map_writable = false;
|
||||
let write = error_code & ((1 as u32) << 1);
|
||||
let write = error_code & ((1_u32) << 1);
|
||||
let pfn = mmu_gfn_to_pfn_fast(vcpu, gpa, prefault, gfn, write == 0, &mut map_writable)?;
|
||||
// direct map就是映射ept页表的过程
|
||||
__direct_map(vcpu, gpa, write, map_writable, level, gfn, pfn, prefault)?;
|
||||
@ -206,6 +200,7 @@ pub fn init_kvm_tdp_mmu(vcpu: &Mutex<VmxVcpu>) {
|
||||
// }
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn __direct_map(
|
||||
vcpu: &mut VmxVcpu,
|
||||
gpa: u64,
|
||||
@ -223,11 +218,10 @@ pub fn __direct_map(
|
||||
}
|
||||
// 把gpa映射到hpa
|
||||
let mut ept_mapper = EptMapper::lock();
|
||||
let page_flags = PageFlags::from_prot_flags(ProtFlags::from_bits_truncate(0x7 as u64), false);
|
||||
let page_flags = PageFlags::from_prot_flags(ProtFlags::from_bits_truncate(0x7_u64), false);
|
||||
unsafe {
|
||||
assert!(ept_mapper.walk(gpa, pfn << PAGE_SHIFT, page_flags).is_ok());
|
||||
}
|
||||
drop(ept_mapper);
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
|
@ -67,9 +67,9 @@ pub struct VcpuContextFrame {
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub enum VcpuState {
|
||||
VcpuInv = 0,
|
||||
VcpuPend = 1,
|
||||
VcpuAct = 2,
|
||||
Inv = 0,
|
||||
Pend = 1,
|
||||
Act = 2,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -158,7 +158,7 @@ impl VmxVcpu {
|
||||
rip: 0,
|
||||
rflags: 0,
|
||||
},
|
||||
vcpu_state: VcpuState::VcpuInv,
|
||||
vcpu_state: VcpuState::Inv,
|
||||
mmu: KvmMmu::default(),
|
||||
data: VcpuData::alloc()?,
|
||||
parent_vm,
|
||||
@ -200,10 +200,10 @@ impl VmxVcpu {
|
||||
vmx_vmwrite(VmcsFields::GUEST_RFLAGS as u32, 2)?;
|
||||
|
||||
vmx_vmwrite(VmcsFields::GUEST_GDTR_BASE as u32, 0)?;
|
||||
vmx_vmwrite(VmcsFields::GUEST_GDTR_LIMIT as u32, 0x0000_FFFF as u64)?;
|
||||
vmx_vmwrite(VmcsFields::GUEST_GDTR_LIMIT as u32, 0x0000_FFFF_u64)?;
|
||||
|
||||
vmx_vmwrite(VmcsFields::GUEST_IDTR_BASE as u32, 0)?;
|
||||
vmx_vmwrite(VmcsFields::GUEST_IDTR_LIMIT as u32, 0x0000_FFFF as u64)?;
|
||||
vmx_vmwrite(VmcsFields::GUEST_IDTR_LIMIT as u32, 0x0000_FFFF_u64)?;
|
||||
|
||||
vmx_vmwrite(VmcsFields::GUEST_ACTIVITY_STATE as u32, 0)?; // State = Active
|
||||
vmx_vmwrite(VmcsFields::GUEST_INTERRUPTIBILITY_STATE as u32, 0)?;
|
||||
@ -312,7 +312,7 @@ impl VmxVcpu {
|
||||
vmx_vmwrite(
|
||||
VmcsFields::HOST_TR_BASE as u32,
|
||||
get_segment_base(pseudo_descriptpr.base, pseudo_descriptpr.limit, unsafe {
|
||||
x86::task::tr().bits().into()
|
||||
x86::task::tr().bits()
|
||||
}),
|
||||
)?;
|
||||
vmx_vmwrite(
|
||||
@ -534,7 +534,7 @@ pub fn adjust_vmx_exit_controls() -> u32 {
|
||||
}
|
||||
|
||||
pub fn adjust_vmx_pinbased_controls() -> u32 {
|
||||
let mut controls: u32 = 0000_0016;
|
||||
let mut controls: u32 = 16;
|
||||
adjust_vmx_controls(0, 0, msr::IA32_VMX_TRUE_PINBASED_CTLS, &mut controls);
|
||||
// kdebug!("adjust_vmx_pinbased_controls: {:x}", controls);
|
||||
return controls;
|
||||
|
@ -204,7 +204,7 @@ pub enum VmcsFields {
|
||||
GUEST_ACTIVITY_STATE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 19) as isize,
|
||||
GUEST_SMBASE = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 20) as isize,
|
||||
GUEST_SYSENTER_CS = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::BIT32, 21) as isize,
|
||||
GUEST_VMX_PREEMPT_TIMER_VALUE = 0x482E as isize,
|
||||
GUEST_VMX_PREEMPT_TIMER_VALUE = 0x482E_isize,
|
||||
// natural guest fields
|
||||
GUEST_CR0 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 0) as isize,
|
||||
GUEST_CR3 = encode_vmcs_field_full(VmcsType::GUEST, VmcsWidth::NATURAL, 1) as isize,
|
||||
@ -519,10 +519,8 @@ const fn encode_vmcs_field(
|
||||
index: u32,
|
||||
) -> u32 {
|
||||
let mut encoding: u32 = 0;
|
||||
encoding |= (access_type as u32)
|
||||
| (index as u32) << 1
|
||||
| (vmcs_type as u32) << 10
|
||||
| (vmcs_width as u32) << 13;
|
||||
encoding |=
|
||||
(access_type as u32) | (index) << 1 | (vmcs_type as u32) << 10 | (vmcs_width as u32) << 13;
|
||||
return encoding;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ extern "C" fn vmexit_handler() {
|
||||
}
|
||||
VmxExitReason::EPT_VIOLATION => {
|
||||
kdebug!("vmexit handler: ept violation!");
|
||||
let gpa = vmx_vmread(GUEST_PHYSICAL_ADDR_FULL as u32).unwrap();
|
||||
let gpa = vmx_vmread(GUEST_PHYSICAL_ADDR_FULL).unwrap();
|
||||
let exit_qualification = vmx_vmread(VmcsFields::VMEXIT_QUALIFICATION as u32).unwrap();
|
||||
/* It is a write fault? */
|
||||
let mut error_code = exit_qualification & (1 << 1);
|
||||
@ -240,7 +240,7 @@ extern "C" fn vmexit_handler() {
|
||||
let vcpu = kvm.vcpu[0].clone();
|
||||
// Use the data
|
||||
let kvm_ept_page_fault = vcpu.lock().mmu.page_fault.unwrap();
|
||||
kvm_ept_page_fault(&mut (*vcpu.lock()), gpa, error_code as u32, false)
|
||||
kvm_ept_page_fault(&mut vcpu.lock(), gpa, error_code as u32, false)
|
||||
.expect("ept page fault error");
|
||||
}
|
||||
_ => {
|
||||
|
@ -14,7 +14,7 @@ impl<MMA: MemoryManagementArch> BumpAllocator<MMA> {
|
||||
ret_areas: &mut [PhysMemoryArea],
|
||||
mut res_count: usize,
|
||||
) -> usize {
|
||||
let info: X86_64MMBootstrapInfo = BOOTSTRAP_MM_INFO.clone().unwrap();
|
||||
let info: X86_64MMBootstrapInfo = BOOTSTRAP_MM_INFO.unwrap();
|
||||
let load_base = info.kernel_load_base_paddr;
|
||||
let kernel_code_start = MMA::virt_2_phys(VirtAddr::new(info.kernel_code_start))
|
||||
.unwrap()
|
||||
|
@ -340,26 +340,26 @@ impl X86_64MMArch {
|
||||
let mb2_count = mb2_count as usize;
|
||||
let mut areas_count = 0usize;
|
||||
let mut total_mem_size = 0usize;
|
||||
for i in 0..mb2_count {
|
||||
for info_entry in mb2_mem_info.iter().take(mb2_count) {
|
||||
// Only use the memory area if its type is 1 (RAM)
|
||||
if mb2_mem_info[i].type_ == 1 {
|
||||
if info_entry.type_ == 1 {
|
||||
// Skip the memory area if its len is 0
|
||||
if mb2_mem_info[i].len == 0 {
|
||||
if info_entry.len == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
total_mem_size += mb2_mem_info[i].len as usize;
|
||||
total_mem_size += info_entry.len as usize;
|
||||
|
||||
mem_block_manager()
|
||||
.add_block(
|
||||
PhysAddr::new(mb2_mem_info[i].addr as usize),
|
||||
mb2_mem_info[i].len as usize,
|
||||
PhysAddr::new(info_entry.addr as usize),
|
||||
info_entry.len as usize,
|
||||
)
|
||||
.unwrap_or_else(|e| {
|
||||
kwarn!(
|
||||
"Failed to add memory block: base={:#x}, size={:#x}, error={:?}",
|
||||
mb2_mem_info[i].addr,
|
||||
mb2_mem_info[i].len,
|
||||
info_entry.addr,
|
||||
info_entry.len,
|
||||
e
|
||||
);
|
||||
});
|
||||
@ -521,7 +521,7 @@ pub fn test_buddy() {
|
||||
let mut random_size = 0u64;
|
||||
unsafe { x86::random::rdrand64(&mut random_size) };
|
||||
// 一次最多申请4M
|
||||
random_size = random_size % (1024 * 4096);
|
||||
random_size %= 1024 * 4096;
|
||||
if random_size == 0 {
|
||||
continue;
|
||||
}
|
||||
@ -551,19 +551,19 @@ pub fn test_buddy() {
|
||||
allocated_frame_count.data() * MMArch::PAGE_SIZE,
|
||||
)
|
||||
};
|
||||
for i in 0..slice.len() {
|
||||
slice[i] = ((i + unsafe { rdtsc() } as usize) % 256) as u8;
|
||||
for (i, item) in slice.iter_mut().enumerate() {
|
||||
*item = ((i + unsafe { rdtsc() } as usize) % 256) as u8;
|
||||
}
|
||||
|
||||
// 随机释放一个内存块
|
||||
if v.len() > 0 {
|
||||
if !v.is_empty() {
|
||||
let mut random_index = 0u64;
|
||||
unsafe { x86::random::rdrand64(&mut random_index) };
|
||||
// 70%概率释放
|
||||
if random_index % 10 > 7 {
|
||||
continue;
|
||||
}
|
||||
random_index = random_index % v.len() as u64;
|
||||
random_index %= v.len() as u64;
|
||||
let random_index = random_index as usize;
|
||||
let (paddr, allocated_frame_count) = v.remove(random_index);
|
||||
assert!(addr_set.remove(&paddr));
|
||||
@ -622,7 +622,7 @@ impl FrameAllocator for LockedFrameAllocator {
|
||||
|
||||
/// 获取内核地址默认的页面标志
|
||||
pub unsafe fn kernel_page_flags<A: MemoryManagementArch>(virt: VirtAddr) -> PageFlags<A> {
|
||||
let info: X86_64MMBootstrapInfo = BOOTSTRAP_MM_INFO.clone().unwrap();
|
||||
let info: X86_64MMBootstrapInfo = BOOTSTRAP_MM_INFO.unwrap();
|
||||
|
||||
if virt.data() >= info.kernel_code_start && virt.data() < info.kernel_code_end {
|
||||
// Remap kernel code execute
|
||||
@ -676,7 +676,7 @@ impl LowAddressRemapping {
|
||||
let (_, _, flusher) = mapper
|
||||
.unmap_phys(vaddr, true)
|
||||
.expect("Failed to unmap frame");
|
||||
if flush == false {
|
||||
if !flush {
|
||||
flusher.ignore();
|
||||
}
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod pci;
|
||||
|
@ -42,7 +42,7 @@ impl KernelThreadMechanism {
|
||||
frame.rip = kernel_thread_bootstrap_stage1 as usize as u64;
|
||||
|
||||
// fork失败的话,子线程不会执行。否则将导致内存安全问题。
|
||||
let pid = ProcessManager::fork(&mut frame, clone_flags).map_err(|e| {
|
||||
let pid = ProcessManager::fork(&frame, clone_flags).map_err(|e| {
|
||||
unsafe { KernelThreadCreateInfo::parse_unsafe_arc_ptr(create_info) };
|
||||
e
|
||||
})?;
|
||||
|
@ -257,8 +257,8 @@ impl ArchPCBInfo {
|
||||
cr2: self.cr2,
|
||||
fsbase: self.fsbase,
|
||||
gsbase: self.gsbase,
|
||||
fs: self.fs.clone(),
|
||||
gs: self.gs.clone(),
|
||||
fs: self.fs,
|
||||
gs: self.gs,
|
||||
gsdata: self.gsdata.clone(),
|
||||
fp_state: self.fp_state,
|
||||
}
|
||||
@ -320,7 +320,7 @@ impl ProcessManager {
|
||||
current_trapframe: &TrapFrame,
|
||||
) -> Result<(), SystemError> {
|
||||
let clone_flags = clone_args.flags;
|
||||
let mut child_trapframe = current_trapframe.clone();
|
||||
let mut child_trapframe = *current_trapframe;
|
||||
|
||||
// 子进程的返回值为0
|
||||
child_trapframe.set_return_value(0);
|
||||
@ -351,7 +351,7 @@ impl ProcessManager {
|
||||
new_arch_guard.gsbase = current_arch_guard.gsbase;
|
||||
new_arch_guard.fs = current_arch_guard.fs;
|
||||
new_arch_guard.gs = current_arch_guard.gs;
|
||||
new_arch_guard.fp_state = current_arch_guard.fp_state.clone();
|
||||
new_arch_guard.fp_state = current_arch_guard.fp_state;
|
||||
|
||||
// 拷贝浮点寄存器的状态
|
||||
if let Some(fp_state) = current_arch_guard.fp_state.as_ref() {
|
||||
@ -383,7 +383,7 @@ impl ProcessManager {
|
||||
/// - `prev`:上一个进程的pcb
|
||||
/// - `next`:下一个进程的pcb
|
||||
pub unsafe fn switch_process(prev: Arc<ProcessControlBlock>, next: Arc<ProcessControlBlock>) {
|
||||
assert!(CurrentIrqArch::is_irq_enabled() == false);
|
||||
assert!(!CurrentIrqArch::is_irq_enabled());
|
||||
|
||||
// 保存浮点寄存器
|
||||
prev.arch_info_irqsave().save_fp_state();
|
||||
|
@ -71,6 +71,6 @@ impl TSSManager {
|
||||
| (((vaddr >> 16) & 0xff) << 32)
|
||||
| (0x89 << 40)
|
||||
| (((vaddr >> 24) & 0xff) << 56);
|
||||
gdt[index as usize + 1] = ((vaddr >> 32) & 0xffffffff) | 0;
|
||||
gdt[index as usize + 1] = (vaddr >> 32) & 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
@ -120,14 +120,14 @@ impl SmpBootData {
|
||||
}
|
||||
|
||||
pub unsafe fn set_cpu_count(&self, cpu_count: u32) {
|
||||
if self.initialized.load(Ordering::SeqCst) == false {
|
||||
if !self.initialized.load(Ordering::SeqCst) {
|
||||
let p = self as *const SmpBootData as *mut SmpBootData;
|
||||
(*p).cpu_count = cpu_count.try_into().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn set_phys_id(&self, cpu_id: ProcessorId, phys_id: usize) {
|
||||
if self.initialized.load(Ordering::SeqCst) == false {
|
||||
if !self.initialized.load(Ordering::SeqCst) {
|
||||
let p = self as *const SmpBootData as *mut SmpBootData;
|
||||
(*p).phys_id[cpu_id.data() as usize] = phys_id;
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ macro_rules! syscall_return {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) -> () {
|
||||
pub extern "sysv64" fn syscall_handler(frame: &mut TrapFrame) {
|
||||
let syscall_num = frame.rax as usize;
|
||||
// 防止sys_sched由于超时无法退出导致的死锁
|
||||
if syscall_num == SYS_SCHED {
|
||||
@ -152,13 +152,13 @@ pub(super) unsafe fn init_syscall_64() {
|
||||
efer |= 0x1;
|
||||
x86::msr::wrmsr(x86::msr::IA32_EFER, efer);
|
||||
|
||||
let syscall_base = (1 as u16) << 3;
|
||||
let sysret_base = ((4 as u16) << 3) | 3;
|
||||
let syscall_base = (1_u16) << 3;
|
||||
let sysret_base = ((4_u16) << 3) | 3;
|
||||
let high = (u32::from(sysret_base) << 16) | u32::from(syscall_base);
|
||||
// 初始化STAR寄存器
|
||||
x86::msr::wrmsr(x86::msr::IA32_STAR, u64::from(high) << 32);
|
||||
|
||||
// 初始化LSTAR,该寄存器存储syscall指令入口
|
||||
x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as u64);
|
||||
x86::msr::wrmsr(x86::msr::IA32_LSTAR, syscall_64 as usize as u64);
|
||||
x86::msr::wrmsr(x86::msr::IA32_FMASK, 0xfffffffe);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl BlockIter {
|
||||
return BlockIter {
|
||||
begin: start_addr,
|
||||
end: end_addr,
|
||||
blk_size_log2: blk_size_log2,
|
||||
blk_size_log2,
|
||||
multiblock: false,
|
||||
};
|
||||
}
|
||||
@ -70,7 +70,8 @@ impl BlockIter {
|
||||
return BlockIter {
|
||||
begin: start_addr,
|
||||
end: end_addr,
|
||||
blk_size_log2: blk_size_log2,
|
||||
|
||||
blk_size_log2,
|
||||
multiblock: true,
|
||||
};
|
||||
}
|
||||
@ -92,9 +93,9 @@ impl BlockIter {
|
||||
return BlockRange {
|
||||
lba_start: lba_id,
|
||||
lba_end: lba_id + 1,
|
||||
begin: begin,
|
||||
end: end,
|
||||
blk_size_log2: blk_size_log2,
|
||||
begin,
|
||||
end,
|
||||
blk_size_log2,
|
||||
};
|
||||
}
|
||||
|
||||
@ -119,11 +120,11 @@ impl BlockIter {
|
||||
self.begin += end - begin;
|
||||
|
||||
return BlockRange {
|
||||
lba_start: lba_start,
|
||||
lba_end: lba_end,
|
||||
begin: begin,
|
||||
end: end,
|
||||
blk_size_log2: blk_size_log2,
|
||||
lba_start,
|
||||
lba_end,
|
||||
begin,
|
||||
end,
|
||||
blk_size_log2,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -252,7 +253,7 @@ pub trait BlockDevice: Device {
|
||||
let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
|
||||
let buf_end = range.origin_end() - offset;
|
||||
let buf_slice = &buf[buf_begin..buf_end];
|
||||
let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
|
||||
let count: usize = range.lba_end - range.lba_start;
|
||||
let full = multi && range.is_multi() || !multi && range.is_full();
|
||||
|
||||
if full {
|
||||
@ -262,12 +263,11 @@ pub trait BlockDevice: Device {
|
||||
return Err(SystemError::E2BIG);
|
||||
}
|
||||
|
||||
let mut temp = Vec::new();
|
||||
temp.resize(1usize << self.blk_size_log2(), 0);
|
||||
let mut temp = vec![0; 1usize << self.blk_size_log2()];
|
||||
// 由于块设备每次读写都是整块的,在不完整写入之前,必须把不完整的地方补全
|
||||
self.read_at(range.lba_start, 1, &mut temp[..])?;
|
||||
// 把数据从临时buffer复制到目标buffer
|
||||
temp[range.begin..range.end].copy_from_slice(&buf_slice);
|
||||
temp[range.begin..range.end].copy_from_slice(buf_slice);
|
||||
self.write_at(range.lba_start, 1, &temp[..])?;
|
||||
}
|
||||
}
|
||||
@ -293,7 +293,7 @@ pub trait BlockDevice: Device {
|
||||
let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
|
||||
let buf_end = range.origin_end() - offset;
|
||||
let buf_slice = &mut buf[buf_begin..buf_end];
|
||||
let count: usize = (range.lba_end - range.lba_start).try_into().unwrap();
|
||||
let count: usize = range.lba_end - range.lba_start;
|
||||
let full = multi && range.is_multi() || !multi && range.is_full();
|
||||
|
||||
// 读取整个block作为有效数据
|
||||
@ -306,8 +306,7 @@ pub trait BlockDevice: Device {
|
||||
return Err(SystemError::E2BIG);
|
||||
}
|
||||
|
||||
let mut temp = Vec::new();
|
||||
temp.resize(1usize << self.blk_size_log2(), 0);
|
||||
let mut temp = vec![0; 1usize << self.blk_size_log2()];
|
||||
self.read_at(range.lba_start, 1, &mut temp[..])?;
|
||||
|
||||
// 把数据从临时buffer复制到目标buffer
|
||||
@ -332,7 +331,7 @@ impl BlockDeviceOps {
|
||||
/// @return: 返回下标
|
||||
#[allow(dead_code)]
|
||||
fn major_to_index(major: Major) -> usize {
|
||||
return (major.data() % DEV_MAJOR_HASH_SIZE as u32) as usize;
|
||||
return (major.data() % DEV_MAJOR_HASH_SIZE) as usize;
|
||||
}
|
||||
|
||||
/// @brief: 动态获取主设备号
|
||||
@ -353,11 +352,10 @@ impl BlockDeviceOps {
|
||||
for index in
|
||||
((DEV_MAJOR_DYN_EXT_END.data() + 1)..(DEV_MAJOR_DYN_EXT_START.data() + 1)).rev()
|
||||
{
|
||||
if let Some(blockdevss) = blockdevs.get(Self::major_to_index(Major::new(index as u32)))
|
||||
{
|
||||
if let Some(blockdevss) = blockdevs.get(Self::major_to_index(Major::new(index))) {
|
||||
let mut flag = true;
|
||||
for item in blockdevss {
|
||||
if item.device_number().major() == Major::new(index as u32) {
|
||||
if item.device_number().major() == Major::new(index) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ impl dyn Class {
|
||||
let subsys = self.subsystem();
|
||||
let guard = subsys.devices();
|
||||
for dev in guard.iter() {
|
||||
if matcher.match_device(&dev, data) {
|
||||
if matcher.match_device(dev, data) {
|
||||
return Some(dev.clone());
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ impl dyn Bus {
|
||||
let subsys = self.subsystem();
|
||||
let guard = subsys.devices();
|
||||
for dev in guard.iter() {
|
||||
if matcher.match_device(&dev, data) {
|
||||
if matcher.match_device(dev, data) {
|
||||
return Some(dev.clone());
|
||||
}
|
||||
}
|
||||
@ -221,7 +221,7 @@ impl dyn Bus {
|
||||
let subsys = self.subsystem();
|
||||
let guard = subsys.drivers();
|
||||
for drv in guard.iter() {
|
||||
if matcher.match_driver(&drv, data) {
|
||||
if matcher.match_driver(drv, data) {
|
||||
return Some(drv.clone());
|
||||
}
|
||||
}
|
||||
@ -262,7 +262,7 @@ impl BusManager {
|
||||
///
|
||||
/// - `dev` - 要被添加的设备
|
||||
pub fn add_device(&self, dev: &Arc<dyn Device>) -> Result<(), SystemError> {
|
||||
let bus = dev.bus().map(|bus| bus.upgrade()).flatten();
|
||||
let bus = dev.bus().and_then(|bus| bus.upgrade());
|
||||
if let Some(bus) = bus {
|
||||
device_manager().add_groups(dev, bus.dev_groups())?;
|
||||
|
||||
@ -280,7 +280,7 @@ impl BusManager {
|
||||
)?;
|
||||
sysfs_instance().create_link(
|
||||
Some(&dev_kobj),
|
||||
&(&bus.subsystem().subsys().as_kobject()),
|
||||
&bus.subsystem().subsys().as_kobject(),
|
||||
"subsystem".to_string(),
|
||||
)?;
|
||||
bus.subsystem().add_device_to_vec(dev)?;
|
||||
@ -294,8 +294,7 @@ impl BusManager {
|
||||
pub fn add_driver(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> {
|
||||
let bus = driver
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
kdebug!("bus '{}' add driver '{}'", bus.name(), driver.name());
|
||||
|
||||
@ -314,25 +313,25 @@ impl BusManager {
|
||||
|
||||
driver_manager()
|
||||
.add_groups(driver, bus.drv_groups())
|
||||
.or_else(|e| {
|
||||
.map_err(|e| {
|
||||
kerror!(
|
||||
"BusManager::add_driver: driver '{:?}' add_groups failed, err: '{:?}",
|
||||
driver.name(),
|
||||
e
|
||||
);
|
||||
Err(e)
|
||||
e
|
||||
})
|
||||
.ok();
|
||||
|
||||
if !driver.suppress_bind_attrs() {
|
||||
self.add_bind_files(driver)
|
||||
.or_else(|e| {
|
||||
.map_err(|e| {
|
||||
kerror!(
|
||||
"BusManager::add_driver: driver '{:?}' add_bind_files failed, err: '{:?}",
|
||||
driver.name(),
|
||||
e
|
||||
);
|
||||
Err(e)
|
||||
e
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
@ -423,7 +422,7 @@ impl BusManager {
|
||||
|
||||
/// 根据bus的kset找到bus实例
|
||||
fn get_bus_by_kset(&self, kset: &Arc<KSet>) -> Option<Arc<dyn Bus>> {
|
||||
return self.kset_bus_map.read().get(kset).map(|bus| bus.clone());
|
||||
return self.kset_bus_map.read().get(kset).cloned();
|
||||
}
|
||||
|
||||
/// 为bus上的设备选择可能的驱动程序
|
||||
@ -445,7 +444,7 @@ impl BusManager {
|
||||
///
|
||||
/// Automatically probe for a driver if the bus allows it.
|
||||
pub fn probe_device(&self, dev: &Arc<dyn Device>) {
|
||||
let bus = dev.bus().map(|bus| bus.upgrade()).flatten();
|
||||
let bus = dev.bus().and_then(|bus| bus.upgrade());
|
||||
if bus.is_none() {
|
||||
return;
|
||||
}
|
||||
@ -498,7 +497,7 @@ fn rescan_devices_helper(dev: &Arc<dyn Device>) -> Result<(), SystemError> {
|
||||
// todo: lock device parent
|
||||
unimplemented!()
|
||||
}
|
||||
device_manager().device_attach(&dev)?;
|
||||
device_manager().device_attach(dev)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
@ -641,7 +640,7 @@ impl Attribute for BusAttrDriversAutoprobe {
|
||||
|
||||
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/bus.c?r=&mo=5649&fi=241#231
|
||||
fn store(&self, kobj: Arc<dyn KObject>, buf: &[u8]) -> Result<usize, SystemError> {
|
||||
if buf.len() == 0 {
|
||||
if buf.is_empty() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
@ -650,7 +649,7 @@ impl Attribute for BusAttrDriversAutoprobe {
|
||||
.get_bus_by_kset(&kset)
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
|
||||
if buf[0] == '0' as u8 {
|
||||
if buf[0] == b'0' {
|
||||
bus.subsystem().set_drivers_autoprobe(false);
|
||||
} else {
|
||||
bus.subsystem().set_drivers_autoprobe(true);
|
||||
@ -756,8 +755,7 @@ impl Attribute for DriverAttrUnbind {
|
||||
|
||||
let bus = driver
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.ok_or(SystemError::ENODEV)?;
|
||||
|
||||
let s = CStr::from_bytes_with_nul(buf)
|
||||
@ -806,8 +804,7 @@ impl Attribute for DriverAttrBind {
|
||||
|
||||
let bus = driver
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.ok_or(SystemError::ENODEV)?;
|
||||
let device = bus
|
||||
.find_device_by_name(
|
||||
|
@ -22,7 +22,7 @@ use super::{
|
||||
Device, DeviceManager,
|
||||
};
|
||||
|
||||
static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::INIT;
|
||||
static PROBE_WAIT_QUEUE: WaitQueue = WaitQueue::default();
|
||||
|
||||
impl DeviceManager {
|
||||
/// 尝试把一个设备与一个驱动匹配
|
||||
@ -84,21 +84,18 @@ impl DeviceManager {
|
||||
} else {
|
||||
let bus = dev
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
let mut data = DeviceAttachData::new(dev.clone(), allow_async, false);
|
||||
let mut flag = false;
|
||||
for driver in bus.subsystem().drivers().iter() {
|
||||
let r = self.do_device_attach_driver(&driver, &mut data);
|
||||
let r = self.do_device_attach_driver(driver, &mut data);
|
||||
if unlikely(r.is_err()) {
|
||||
flag = false;
|
||||
break;
|
||||
} else {
|
||||
if r.unwrap() == true {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
} else if r.unwrap() {
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,7 +142,7 @@ impl DeviceManager {
|
||||
driver: &Arc<dyn Driver>,
|
||||
data: &mut DeviceAttachData,
|
||||
) -> Result<bool, SystemError> {
|
||||
if let Some(bus) = driver.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
if let Some(bus) = driver.bus().and_then(|bus| bus.upgrade()) {
|
||||
let r = bus.match_device(&data.dev, driver);
|
||||
|
||||
if let Err(e) = r {
|
||||
@ -158,10 +155,8 @@ impl DeviceManager {
|
||||
);
|
||||
return Err(e);
|
||||
}
|
||||
} else {
|
||||
if r.unwrap() == false {
|
||||
return Ok(false);
|
||||
}
|
||||
} else if !r.unwrap() {
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,11 +180,7 @@ impl DeviceManager {
|
||||
///
|
||||
/// 如果传递的设备已成功完成对驱动程序的探测,则返回true,否则返回false。
|
||||
pub fn device_is_bound(&self, dev: &Arc<dyn Device>) -> bool {
|
||||
if dev.driver().is_some() {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return dev.driver().is_some();
|
||||
}
|
||||
|
||||
/// 把一个驱动绑定到设备上
|
||||
@ -211,14 +202,12 @@ impl DeviceManager {
|
||||
self.device_links_force_bind(dev);
|
||||
driver_manager().driver_bound(dev);
|
||||
return Err(e);
|
||||
} else {
|
||||
if let Some(bus) = dev.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
bus.subsystem().bus_notifier().call_chain(
|
||||
BusNotifyEvent::DriverNotBound,
|
||||
Some(dev),
|
||||
None,
|
||||
);
|
||||
}
|
||||
} else if let Some(bus) = dev.bus().and_then(|bus| bus.upgrade()) {
|
||||
bus.subsystem().bus_notifier().call_chain(
|
||||
BusNotifyEvent::DriverNotBound,
|
||||
Some(dev),
|
||||
None,
|
||||
);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@ -285,11 +274,10 @@ impl DriverManager {
|
||||
pub fn driver_attach(&self, driver: &Arc<dyn Driver>) -> Result<(), SystemError> {
|
||||
let bus = driver
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
for dev in bus.subsystem().devices().iter() {
|
||||
if self.do_driver_attach(&dev, &driver) {
|
||||
if self.do_driver_attach(dev, driver) {
|
||||
// 匹配成功
|
||||
return Ok(());
|
||||
}
|
||||
@ -301,7 +289,7 @@ impl DriverManager {
|
||||
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/dd.c?fi=driver_attach#1134
|
||||
fn do_driver_attach(&self, device: &Arc<dyn Device>, driver: &Arc<dyn Driver>) -> bool {
|
||||
let r = self.match_device(driver, device).unwrap_or(false);
|
||||
if r == false {
|
||||
if !r {
|
||||
// 不匹配
|
||||
return false;
|
||||
}
|
||||
@ -328,8 +316,7 @@ impl DriverManager {
|
||||
) -> Result<bool, SystemError> {
|
||||
return driver
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.unwrap()
|
||||
.match_device(device, driver);
|
||||
}
|
||||
@ -384,7 +371,7 @@ impl DriverManager {
|
||||
};
|
||||
|
||||
let sysfs_failed = || {
|
||||
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
|
||||
bus.subsystem().bus_notifier().call_chain(
|
||||
BusNotifyEvent::DriverNotBound,
|
||||
Some(device),
|
||||
@ -467,10 +454,10 @@ impl DriverManager {
|
||||
fn add_to_sysfs(&self, device: &Arc<dyn Device>) -> Result<(), SystemError> {
|
||||
let driver = device.driver().ok_or(SystemError::EINVAL)?;
|
||||
|
||||
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
|
||||
bus.subsystem().bus_notifier().call_chain(
|
||||
BusNotifyEvent::BindDriver,
|
||||
Some(&device),
|
||||
Some(device),
|
||||
None,
|
||||
);
|
||||
}
|
||||
@ -514,8 +501,7 @@ impl DriverManager {
|
||||
) -> Result<(), SystemError> {
|
||||
let bus = device
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.and_then(|bus| bus.upgrade())
|
||||
.ok_or(SystemError::EINVAL)?;
|
||||
let r = bus.probe(device);
|
||||
if r == Err(SystemError::EOPNOTSUPP_OR_ENOTSUP) {
|
||||
@ -566,7 +552,7 @@ impl DriverManager {
|
||||
let driver = device.driver().unwrap();
|
||||
driver.add_device(device.clone());
|
||||
|
||||
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
|
||||
bus.subsystem().bus_notifier().call_chain(
|
||||
BusNotifyEvent::BoundDriver,
|
||||
Some(device),
|
||||
|
@ -33,7 +33,7 @@ pub struct DeviceNumber {
|
||||
|
||||
impl DeviceNumber {
|
||||
pub const MINOR_BITS: u32 = 20;
|
||||
pub const MINOR_MASK: u32 = 1 << Self::MINOR_BITS - 1;
|
||||
pub const MINOR_MASK: u32 = (1 << Self::MINOR_BITS) - 1;
|
||||
|
||||
pub const fn new(major: Major, minor: u32) -> Self {
|
||||
Self {
|
||||
|
@ -24,9 +24,9 @@ pub enum DriverError {
|
||||
UnInitialized, // 未初始化
|
||||
}
|
||||
|
||||
impl Into<SystemError> for DriverError {
|
||||
fn into(self) -> SystemError {
|
||||
match self {
|
||||
impl From<DriverError> for SystemError {
|
||||
fn from(value: DriverError) -> Self {
|
||||
match value {
|
||||
DriverError::ProbeError => SystemError::ENODEV,
|
||||
DriverError::RegisterError => SystemError::ENODEV,
|
||||
DriverError::AllocateResourceError => SystemError::EIO,
|
||||
@ -138,13 +138,9 @@ impl dyn Driver {
|
||||
matcher: &dyn DeviceMatcher<T>,
|
||||
data: T,
|
||||
) -> Option<Arc<dyn Device>> {
|
||||
for dev in self.devices() {
|
||||
if matcher.match_device(&dev, data) {
|
||||
return Some(dev);
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
self.devices()
|
||||
.into_iter()
|
||||
.find(|dev| matcher.match_device(dev, data))
|
||||
}
|
||||
|
||||
/// 根据设备名称查找绑定到驱动的设备
|
||||
@ -174,17 +170,13 @@ impl DriverManager {
|
||||
///
|
||||
/// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/base/driver.c#222
|
||||
pub fn register(&self, driver: Arc<dyn Driver>) -> Result<(), SystemError> {
|
||||
let bus = driver
|
||||
.bus()
|
||||
.map(|bus| bus.upgrade())
|
||||
.flatten()
|
||||
.ok_or_else(|| {
|
||||
kerror!(
|
||||
"DriverManager::register() failed: driver.bus() is None. Driver: '{:?}'",
|
||||
driver.name()
|
||||
);
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
let bus = driver.bus().and_then(|bus| bus.upgrade()).ok_or_else(|| {
|
||||
kerror!(
|
||||
"DriverManager::register() failed: driver.bus() is None. Driver: '{:?}'",
|
||||
driver.name()
|
||||
);
|
||||
SystemError::EINVAL
|
||||
})?;
|
||||
|
||||
let drv_name = driver.name();
|
||||
let other = bus.find_driver_by_name(&drv_name);
|
||||
@ -287,9 +279,9 @@ impl DriverMatcher<&str> for DriverMatchName {
|
||||
}
|
||||
|
||||
/// enum probe_type - device driver probe type to try
|
||||
/// Device drivers may opt in for special handling of their
|
||||
/// respective probe routines. This tells the core what to
|
||||
/// expect and prefer.
|
||||
/// Device drivers may opt in for special handling of their
|
||||
/// respective probe routines. This tells the core what to
|
||||
/// expect and prefer.
|
||||
///
|
||||
/// Note that the end goal is to switch the kernel to use asynchronous
|
||||
/// probing by default, so annotating drivers with
|
||||
@ -297,26 +289,21 @@ impl DriverMatcher<&str> for DriverMatchName {
|
||||
/// to speed up boot process while we are validating the rest of the
|
||||
/// drivers.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub enum DriverProbeType {
|
||||
/// Used by drivers that work equally well
|
||||
/// whether probed synchronously or asynchronously.
|
||||
DefaultStrategy,
|
||||
|
||||
/// Drivers for "slow" devices which
|
||||
/// probing order is not essential for booting the system may
|
||||
/// opt into executing their probes asynchronously.
|
||||
/// probing order is not essential for booting the system may
|
||||
/// opt into executing their probes asynchronously.
|
||||
PreferAsync,
|
||||
|
||||
/// Use this to annotate drivers that need
|
||||
/// their probe routines to run synchronously with driver and
|
||||
/// device registration (with the exception of -EPROBE_DEFER
|
||||
/// handling - re-probing always ends up being done asynchronously).
|
||||
/// their probe routines to run synchronously with driver and
|
||||
/// device registration (with the exception of -EPROBE_DEFER
|
||||
/// handling - re-probing always ends up being done asynchronously).
|
||||
ForceSync,
|
||||
}
|
||||
|
||||
impl Default for DriverProbeType {
|
||||
fn default() -> Self {
|
||||
DriverProbeType::DefaultStrategy
|
||||
}
|
||||
#[default]
|
||||
/// Used by drivers that work equally well
|
||||
/// whether probed synchronously or asynchronously.
|
||||
DefaultStrategy,
|
||||
}
|
||||
|
@ -98,11 +98,11 @@ pub fn sys_dev_char_kset() -> Arc<KSet> {
|
||||
unsafe { DEV_CHAR_KSET_INSTANCE.as_ref().unwrap().clone() }
|
||||
}
|
||||
|
||||
pub(self) unsafe fn set_sys_dev_block_kset(kset: Arc<KSet>) {
|
||||
unsafe fn set_sys_dev_block_kset(kset: Arc<KSet>) {
|
||||
DEV_BLOCK_KSET_INSTANCE = Some(kset);
|
||||
}
|
||||
|
||||
pub(self) unsafe fn set_sys_dev_char_kset(kset: Arc<KSet>) {
|
||||
unsafe fn set_sys_dev_char_kset(kset: Arc<KSet>) {
|
||||
DEV_CHAR_KSET_INSTANCE = Some(kset);
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ pub fn sys_devices_virtual_kset() -> Arc<KSet> {
|
||||
unsafe { DEVICES_VIRTUAL_KSET_INSTANCE.as_ref().unwrap().clone() }
|
||||
}
|
||||
|
||||
pub(self) unsafe fn set_sys_devices_virtual_kset(kset: Arc<KSet>) {
|
||||
unsafe fn set_sys_devices_virtual_kset(kset: Arc<KSet>) {
|
||||
DEVICES_VIRTUAL_KSET_INSTANCE = Some(kset);
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ impl IdTable {
|
||||
}
|
||||
|
||||
pub fn device_number(&self) -> DeviceNumber {
|
||||
return self.id.unwrap_or(DeviceNumber::default());
|
||||
return self.id.unwrap_or_default();
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,9 +307,9 @@ pub enum DeviceError {
|
||||
UnsupportedOperation, // 不支持的操作
|
||||
}
|
||||
|
||||
impl Into<SystemError> for DeviceError {
|
||||
fn into(self) -> SystemError {
|
||||
match self {
|
||||
impl From<DeviceError> for SystemError {
|
||||
fn from(value: DeviceError) -> Self {
|
||||
match value {
|
||||
DeviceError::DriverExists => SystemError::EEXIST,
|
||||
DeviceError::DeviceExists => SystemError::EEXIST,
|
||||
DeviceError::InitializeFailed => SystemError::EIO,
|
||||
@ -431,10 +431,8 @@ impl DeviceManager {
|
||||
|
||||
let current_parent = device
|
||||
.parent()
|
||||
.map(|x| x.upgrade())
|
||||
.flatten()
|
||||
.map(|x| x.arc_any().cast::<dyn Device>().ok())
|
||||
.flatten();
|
||||
.and_then(|x| x.upgrade())
|
||||
.and_then(|x| x.arc_any().cast::<dyn Device>().ok());
|
||||
|
||||
let actual_parent = self.get_device_parent(&device, current_parent)?;
|
||||
if let Some(actual_parent) = actual_parent {
|
||||
@ -467,7 +465,7 @@ impl DeviceManager {
|
||||
}
|
||||
|
||||
// 通知客户端有关设备添加的信息。此调用必须在 dpm_sysfs_add() 之后且在 kobject_uevent() 之前执行。
|
||||
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
|
||||
bus.subsystem().bus_notifier().call_chain(
|
||||
bus::BusNotifyEvent::AddDevice,
|
||||
Some(&device),
|
||||
@ -509,19 +507,17 @@ impl DeviceManager {
|
||||
current_parent: Option<Arc<dyn Device>>,
|
||||
) -> Result<Option<Arc<dyn KObject>>, SystemError> {
|
||||
// kdebug!("get_device_parent() device:{:?}", device.name());
|
||||
if let Some(_) = device.class() {
|
||||
if device.class().is_some() {
|
||||
let parent_kobj: Arc<dyn KObject>;
|
||||
// kdebug!("current_parent:{:?}", current_parent);
|
||||
if current_parent.is_none() {
|
||||
parent_kobj = sys_devices_virtual_kset() as Arc<dyn KObject>;
|
||||
} else {
|
||||
let cp = current_parent.unwrap();
|
||||
|
||||
if let Some(cp) = current_parent {
|
||||
if cp.class().is_some() {
|
||||
return Ok(Some(cp.clone() as Arc<dyn KObject>));
|
||||
} else {
|
||||
parent_kobj = cp.clone() as Arc<dyn KObject>;
|
||||
}
|
||||
} else {
|
||||
parent_kobj = sys_devices_virtual_kset() as Arc<dyn KObject>;
|
||||
}
|
||||
|
||||
// 是否需要glue dir?
|
||||
@ -531,15 +527,15 @@ impl DeviceManager {
|
||||
|
||||
// subsystems can specify a default root directory for their devices
|
||||
if current_parent.is_none() {
|
||||
if let Some(bus) = device.bus().map(|bus| bus.upgrade()).flatten() {
|
||||
if let Some(root) = bus.root_device().map(|x| x.upgrade()).flatten() {
|
||||
if let Some(bus) = device.bus().and_then(|bus| bus.upgrade()) {
|
||||
if let Some(root) = bus.root_device().and_then(|x| x.upgrade()) {
|
||||
return Ok(Some(root as Arc<dyn KObject>));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if current_parent.is_some() {
|
||||
return Ok(Some(current_parent.unwrap().clone() as Arc<dyn KObject>));
|
||||
if let Some(current_parent) = current_parent {
|
||||
return Ok(Some(current_parent as Arc<dyn KObject>));
|
||||
}
|
||||
|
||||
return Ok(None);
|
||||
@ -599,10 +595,10 @@ impl DeviceManager {
|
||||
sysfs_instance().create_link(Some(&dev_kobj), &subsys_kobj, "subsystem".to_string())?;
|
||||
|
||||
// todo: 这里需要处理class的parent逻辑, 添加device链接
|
||||
if let Some(parent) = dev.parent().map(|x| x.upgrade()).flatten() {
|
||||
if let Some(parent) = dev.parent().and_then(|x| x.upgrade()) {
|
||||
let parent_kobj = parent.clone() as Arc<dyn KObject>;
|
||||
sysfs_instance()
|
||||
.create_link(Some(&dev_kobj), &&parent_kobj, "device".to_string())
|
||||
.create_link(Some(&dev_kobj), &parent_kobj, "device".to_string())
|
||||
.map_err(|e| {
|
||||
err_remove_subsystem(&dev_kobj);
|
||||
e
|
||||
@ -876,7 +872,7 @@ impl DeviceMatcher<&str> for DeviceMatchName {
|
||||
}
|
||||
|
||||
/// Cookie to identify the device
|
||||
#[derive(Debug, Clone, Hash)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DeviceId {
|
||||
data: Option<&'static str>,
|
||||
allocated: Option<String>,
|
||||
@ -918,6 +914,12 @@ impl PartialEq for DeviceId {
|
||||
}
|
||||
}
|
||||
|
||||
impl core::hash::Hash for DeviceId {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
self.id().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for DeviceId {}
|
||||
|
||||
impl IrqHandlerData for DeviceId {}
|
||||
|
@ -180,8 +180,7 @@ impl KObjectManager {
|
||||
kobj: Arc<dyn KObject>,
|
||||
join_kset: Option<Arc<KSet>>,
|
||||
) -> Result<(), SystemError> {
|
||||
if join_kset.is_some() {
|
||||
let kset = join_kset.unwrap();
|
||||
if let Some(kset) = join_kset {
|
||||
kset.join(&kobj);
|
||||
// 如果kobject没有parent,那么就将这个kset作为parent
|
||||
if kobj.parent().is_none() {
|
||||
|
@ -109,7 +109,7 @@ impl KSet {
|
||||
pub fn join(&self, kobj: &Arc<dyn KObject>) {
|
||||
assert!(kobj.kset().is_none());
|
||||
kobj.set_kset(self.self_ref.upgrade());
|
||||
self.kobjects.write().push(Arc::downgrade(&kobj));
|
||||
self.kobjects.write().push(Arc::downgrade(kobj));
|
||||
}
|
||||
|
||||
/// 把一个kobject从当前kset中移除。
|
||||
|
@ -91,11 +91,8 @@ pub fn kobj_unmap(domain: Arc<LockedKObjMap>, dev_t: DeviceNumber, range: usize)
|
||||
{
|
||||
for i in 0..range {
|
||||
let rm_dev_t = &DeviceNumber::new(dev_t.major(), dev_t.minor() + i as u32);
|
||||
match map.get(rm_dev_t) {
|
||||
Some(_) => {
|
||||
map.remove(rm_dev_t);
|
||||
}
|
||||
None => {}
|
||||
if map.get(rm_dev_t).is_some() {
|
||||
map.remove(rm_dev_t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ impl PlatformDeviceManager {
|
||||
let id = pdev.pdev_id().0;
|
||||
match id {
|
||||
PLATFORM_DEVID_NONE => {
|
||||
pdev.set_name(format!("{}", pdev.pdev_name()));
|
||||
pdev.set_name(pdev.pdev_name().to_string());
|
||||
}
|
||||
PLATFORM_DEVID_AUTO => {
|
||||
let id = PLATFORM_DEVID_IDA.alloc().ok_or(SystemError::EOVERFLOW)?;
|
||||
@ -158,10 +158,7 @@ impl PlatformBusDevice {
|
||||
#[allow(dead_code)]
|
||||
fn is_initialized(&self) -> bool {
|
||||
let state = self.inner.lock().state;
|
||||
match state {
|
||||
BusState::Initialized => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(state, BusState::Initialized)
|
||||
}
|
||||
|
||||
/// @brief: 设置总线状态
|
||||
@ -237,7 +234,7 @@ impl KObject for PlatformBusDevice {
|
||||
}
|
||||
|
||||
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
|
||||
self.inner.lock().ktype.clone()
|
||||
self.inner.lock().ktype
|
||||
}
|
||||
|
||||
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
|
||||
|
@ -39,7 +39,7 @@ impl LockedAhciInode {
|
||||
// uuid: Uuid::new_v5(),
|
||||
self_ref: Weak::default(),
|
||||
fs: Weak::default(),
|
||||
disk: disk,
|
||||
disk,
|
||||
metadata: Metadata {
|
||||
dev_id: 1,
|
||||
inode_id: generate_inode_id(),
|
||||
|
@ -71,7 +71,7 @@ impl AhciDisk {
|
||||
assert!((buf.len() & 511) == 0);
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
let check_length = ((count - 1) >> 4) + 1; // prdt length
|
||||
if count * 512 > buf.len() || check_length > 8 as usize {
|
||||
if count * 512 > buf.len() || check_length > 8_usize {
|
||||
kerror!("ahci read: e2big");
|
||||
// 不可能的操作
|
||||
return Err(SystemError::E2BIG);
|
||||
@ -91,8 +91,7 @@ impl AhciDisk {
|
||||
#[allow(unused_unsafe)]
|
||||
let cmdheader: &mut HbaCmdHeader = unsafe {
|
||||
(phys_2_virt(
|
||||
volatile_read!(port.clb) as usize
|
||||
+ slot as usize * size_of::<HbaCmdHeader>() as usize,
|
||||
volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(),
|
||||
) as *mut HbaCmdHeader)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
@ -109,10 +108,9 @@ impl AhciDisk {
|
||||
// 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
|
||||
// TODO:在内存管理重构后,可以直接使用用户空间的内存地址
|
||||
|
||||
let user_buf = verify_area(VirtAddr::new(buf_ptr as usize), buf.len()).is_ok();
|
||||
let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
|
||||
let mut kbuf = if user_buf {
|
||||
let mut x: Vec<u8> = Vec::new();
|
||||
x.resize(buf.len(), 0);
|
||||
let x: Vec<u8> = vec![0; buf.len()];
|
||||
Some(x)
|
||||
} else {
|
||||
None
|
||||
@ -220,7 +218,7 @@ impl AhciDisk {
|
||||
assert!((buf.len() & 511) == 0);
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
let check_length = ((count - 1) >> 4) + 1; // prdt length
|
||||
if count * 512 > buf.len() || check_length > 8 as usize {
|
||||
if count * 512 > buf.len() || check_length > 8 {
|
||||
// 不可能的操作
|
||||
return Err(SystemError::E2BIG);
|
||||
} else if count == 0 {
|
||||
@ -241,8 +239,7 @@ impl AhciDisk {
|
||||
#[allow(unused_unsafe)]
|
||||
let cmdheader: &mut HbaCmdHeader = unsafe {
|
||||
(phys_2_virt(
|
||||
volatile_read!(port.clb) as usize
|
||||
+ slot as usize * size_of::<HbaCmdHeader>() as usize,
|
||||
volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(),
|
||||
) as *mut HbaCmdHeader)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
@ -251,7 +248,7 @@ impl AhciDisk {
|
||||
|
||||
volatile_write_bit!(
|
||||
cmdheader.cfl,
|
||||
(1 << 5) - 1 as u8,
|
||||
(1 << 5) - 1_u8,
|
||||
(size_of::<FisRegH2D>() / size_of::<u32>()) as u8
|
||||
); // Command FIS size
|
||||
|
||||
@ -264,9 +261,9 @@ impl AhciDisk {
|
||||
|
||||
// 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
|
||||
// TODO:在内存管理重构后,可以直接使用用户空间的内存地址
|
||||
let user_buf = verify_area(VirtAddr::new(buf_ptr as usize), buf.len()).is_ok();
|
||||
let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
|
||||
let mut kbuf = if user_buf {
|
||||
let mut x: Vec<u8> = Vec::with_capacity(buf.len());
|
||||
let mut x: Vec<u8> = vec![0; buf.len()];
|
||||
x.resize(buf.len(), 0);
|
||||
x.copy_from_slice(buf);
|
||||
Some(x)
|
||||
@ -401,7 +398,7 @@ impl LockedAhciDisk {
|
||||
let mut table: MbrDiskPartionTable = Default::default();
|
||||
|
||||
// 数据缓冲区
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
let mut buf: Vec<u8> = vec![0; size_of::<MbrDiskPartionTable>()];
|
||||
buf.resize(size_of::<MbrDiskPartionTable>(), 0);
|
||||
|
||||
self.read_at(0, 1, &mut buf)?;
|
||||
|
@ -1,4 +1,3 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::{intrinsics::size_of, ptr};
|
||||
|
||||
use core::sync::atomic::compiler_fence;
|
||||
@ -179,17 +178,12 @@ impl HbaPort {
|
||||
/// @return: 返回一个空闲 cmd table 的 id; 如果没有,则返回 Option::None
|
||||
pub fn find_cmdslot(&self) -> Option<u32> {
|
||||
let slots = volatile_read!(self.sact) | volatile_read!(self.ci);
|
||||
for i in 0..32 {
|
||||
if slots & 1 << i == 0 {
|
||||
return Some(i);
|
||||
}
|
||||
}
|
||||
return None;
|
||||
(0..32).find(|&i| slots & 1 << i == 0)
|
||||
}
|
||||
|
||||
/// 初始化, 把 CmdList 等变量的地址赋值到 HbaPort 上 - 这些空间由操作系统分配且固定
|
||||
/// 等价于原C版本的 port_rebase 函数
|
||||
pub fn init(&mut self, clb: u64, fb: u64, ctbas: &Vec<u64>) {
|
||||
pub fn init(&mut self, clb: u64, fb: u64, ctbas: &[u64]) {
|
||||
self.stop(); // 先暂停端口
|
||||
|
||||
// 赋值 command list base address
|
||||
@ -217,13 +211,13 @@ impl HbaPort {
|
||||
// Command table offset: 40K + 8K*portno
|
||||
// Command table size = 256*32 = 8K per port
|
||||
let mut cmdheaders = phys_2_virt(clb as usize) as *mut u64 as *mut HbaCmdHeader;
|
||||
for i in 0..32 as usize {
|
||||
for ctbas_value in ctbas.iter().take(32) {
|
||||
volatile_write!((*cmdheaders).prdtl, 0); // 一开始没有询问,prdtl = 0(预留了8个PRDT项的空间)
|
||||
volatile_write!((*cmdheaders).ctba, ctbas[i]);
|
||||
volatile_write!((*cmdheaders).ctba, *ctbas_value);
|
||||
// 这里限制了 prdtl <= 8, 所以一共用了256bytes,如果需要修改,可以修改这里
|
||||
compiler_fence(core::sync::atomic::Ordering::SeqCst);
|
||||
unsafe {
|
||||
ptr::write_bytes(phys_2_virt(ctbas[i] as usize) as *mut u64, 0, 256);
|
||||
ptr::write_bytes(phys_2_virt(*ctbas_value as usize) as *mut u64, 0, 256);
|
||||
}
|
||||
cmdheaders = (cmdheaders as usize + size_of::<HbaCmdHeader>()) as *mut HbaCmdHeader;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ pub mod ahci_inode;
|
||||
pub mod ahcidisk;
|
||||
pub mod hba;
|
||||
|
||||
use crate::driver::base::block::block_device::BlockDevice;
|
||||
use crate::driver::base::block::disk_info::BLK_GF_AHCI;
|
||||
// 依赖的rust工具包
|
||||
use crate::driver::pci::pci::{
|
||||
@ -23,14 +22,7 @@ use crate::{
|
||||
kdebug,
|
||||
};
|
||||
use ahci_inode::LockedAhciInode;
|
||||
use alloc::{
|
||||
boxed::Box,
|
||||
collections::LinkedList,
|
||||
format,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use alloc::{boxed::Box, collections::LinkedList, format, string::String, sync::Arc, vec::Vec};
|
||||
use core::sync::atomic::compiler_fence;
|
||||
use system_error::SystemError;
|
||||
|
||||
@ -180,30 +172,3 @@ fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
|
||||
|
||||
return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() };
|
||||
}
|
||||
|
||||
/// @brief: 测试函数
|
||||
pub fn __test_ahci() {
|
||||
let _res = ahci_init();
|
||||
let disk: Arc<LockedAhciDisk> = get_disks_by_name("ahci_disk_0".to_string()).unwrap();
|
||||
#[deny(overflowing_literals)]
|
||||
let mut buf = [0u8; 3000usize];
|
||||
|
||||
for i in 0..2000 {
|
||||
buf[i] = i as u8;
|
||||
}
|
||||
|
||||
let _dd = disk;
|
||||
|
||||
// 测试1, 写两个块,读4个块
|
||||
// _dd.write_at(123, 2, &buf).unwrap();
|
||||
let mut read_buf = [0u8; 3000usize];
|
||||
_dd.read_at(122, 4, &mut read_buf).unwrap();
|
||||
|
||||
// 测试2, 只读写一个字节
|
||||
for i in 0..512 {
|
||||
buf[i] = 233;
|
||||
}
|
||||
// _dd.write_at(123, 2, &buf).unwrap();
|
||||
let mut read_buf2 = [0u8; 3000usize];
|
||||
_dd.read_at(122, 4, &mut read_buf2).unwrap();
|
||||
}
|
||||
|
@ -56,13 +56,13 @@ enum FdtPropType {
|
||||
impl FdtPropType {
|
||||
/// 获取属性对应的fdt属性名
|
||||
fn prop_name(&self) -> &'static str {
|
||||
self.clone().into()
|
||||
(*self).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<&'static str> for FdtPropType {
|
||||
fn into(self) -> &'static str {
|
||||
match self {
|
||||
impl From<FdtPropType> for &'static str {
|
||||
fn from(value: FdtPropType) -> Self {
|
||||
match value {
|
||||
FdtPropType::SystemTable => "linux,uefi-system-table",
|
||||
FdtPropType::MMBase => "linux,uefi-mmap-start",
|
||||
FdtPropType::MMSize => "linux,uefi-mmap-size",
|
||||
@ -159,12 +159,11 @@ impl EFIManager {
|
||||
prop: &fdt::node::NodeProperty<'_>,
|
||||
target: &mut EFIFdtParams,
|
||||
) -> Result<(), SystemError> {
|
||||
let val: u64;
|
||||
if prop.value.len() == 4 {
|
||||
val = u32::from_be_bytes(prop.value[0..4].try_into().unwrap()) as u64;
|
||||
let val = if prop.value.len() == 4 {
|
||||
u32::from_be_bytes(prop.value[0..4].try_into().unwrap()) as u64
|
||||
} else {
|
||||
val = u64::from_be_bytes(prop.value[0..8].try_into().unwrap());
|
||||
}
|
||||
u64::from_be_bytes(prop.value[0..8].try_into().unwrap())
|
||||
};
|
||||
|
||||
match prop_type {
|
||||
FdtPropType::SystemTable => {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use core::{intrinsics::unlikely, mem::size_of};
|
||||
use core::{hint::spin_loop, intrinsics::unlikely, mem::size_of};
|
||||
|
||||
use system_error::SystemError;
|
||||
use uefi_raw::table::boot::{MemoryAttribute, MemoryType};
|
||||
@ -37,7 +37,9 @@ pub fn efi_init() {
|
||||
// 所以如果我们无法访问它,那么继续进行下去就没有什么意义了
|
||||
|
||||
kerror!("Failed to initialize early memory map");
|
||||
loop {}
|
||||
loop {
|
||||
spin_loop();
|
||||
}
|
||||
}
|
||||
// kdebug!("NNNN");
|
||||
// kwarn!("BBBB, e:{:?}", SystemError::EINVAL);
|
||||
@ -76,7 +78,7 @@ pub fn efi_init() {
|
||||
.expect("Failed to reserve memory for EFI mmap table");
|
||||
|
||||
// 保留内核的内存
|
||||
if let Some(info) = efi_manager().inner.read().dragonstub_load_info.clone() {
|
||||
if let Some(info) = efi_manager().inner.read().dragonstub_load_info {
|
||||
mem_block_manager()
|
||||
.reserve_block(
|
||||
PhysAddr::new(info.paddr as usize),
|
||||
|
@ -25,7 +25,7 @@ use super::{
|
||||
};
|
||||
|
||||
/// 所有的要解析的表格的解析器
|
||||
static TABLE_PARSERS: &'static [&'static TableMatcher] = &[
|
||||
static TABLE_PARSERS: &[&TableMatcher] = &[
|
||||
&TableMatcher::new(&MatchTableDragonStubPayloadEFI),
|
||||
&TableMatcher::new(&MatchTableMemoryAttributes),
|
||||
&TableMatcher::new(&MatchTableMemReserve),
|
||||
@ -362,13 +362,13 @@ impl TableMatcher {
|
||||
/// 判断配置表与当前匹配器是否匹配
|
||||
#[inline(never)]
|
||||
fn match_table(&self, table: &ConfigurationTable) -> Option<Result<(), SystemError>> {
|
||||
if table.vendor_guid.equivalent(self.table.guid()) == false {
|
||||
if !table.vendor_guid.equivalent(self.table.guid()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let table_map_size = self.table.map_size();
|
||||
let vendor_table_vaddr: Option<VirtAddr>;
|
||||
if table_map_size > 0 {
|
||||
|
||||
let vendor_table_vaddr: Option<VirtAddr> = if table_map_size > 0 {
|
||||
let table_paddr: PhysAddr = PhysAddr::new(table.vendor_table as usize);
|
||||
let vaddr = EarlyIoRemap::map_not_aligned(table_paddr, table_map_size, true);
|
||||
|
||||
@ -376,10 +376,10 @@ impl TableMatcher {
|
||||
return Some(Err(e));
|
||||
}
|
||||
|
||||
vendor_table_vaddr = Some(vaddr.unwrap());
|
||||
Some(vaddr.unwrap())
|
||||
} else {
|
||||
vendor_table_vaddr = None;
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
let r = self.table.post_process(vendor_table_vaddr, table);
|
||||
|
||||
|
@ -95,14 +95,14 @@ enum PsMouseCommand {
|
||||
SetSampleRate,
|
||||
}
|
||||
|
||||
impl Into<u8> for PsMouseCommand {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
Self::SampleRate(x) => x,
|
||||
Self::EnablePacketStreaming => 0xf4,
|
||||
Self::InitKeyboard => 0x47,
|
||||
Self::GetMouseId => 0xf2,
|
||||
Self::SetSampleRate => 0xf3,
|
||||
impl From<PsMouseCommand> for u8 {
|
||||
fn from(val: PsMouseCommand) -> Self {
|
||||
match val {
|
||||
PsMouseCommand::SampleRate(x) => x,
|
||||
PsMouseCommand::EnablePacketStreaming => 0xf4,
|
||||
PsMouseCommand::InitKeyboard => 0x47,
|
||||
PsMouseCommand::GetMouseId => 0xf2,
|
||||
PsMouseCommand::SetSampleRate => 0xf3,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,13 +302,13 @@ impl Ps2MouseDevice {
|
||||
guard.current_state.flags = flags;
|
||||
}
|
||||
1 => {
|
||||
let flags = guard.current_state.flags.clone();
|
||||
let flags = guard.current_state.flags;
|
||||
if !flags.contains(MouseFlags::X_OVERFLOW) {
|
||||
guard.current_state.x = self.get_x_movement(packet, flags);
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
let flags = guard.current_state.flags.clone();
|
||||
let flags = guard.current_state.flags;
|
||||
if !flags.contains(MouseFlags::Y_OVERFLOW) {
|
||||
guard.current_state.y = self.get_y_movement(packet, flags);
|
||||
}
|
||||
@ -546,7 +546,7 @@ impl KObject for Ps2MouseDevice {
|
||||
}
|
||||
|
||||
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
|
||||
self.inner.lock_irqsave().kobj_type.clone()
|
||||
self.inner.lock_irqsave().kobj_type
|
||||
}
|
||||
|
||||
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
|
||||
@ -605,8 +605,8 @@ impl IndexNode for Ps2MouseDevice {
|
||||
let mut guard = self.inner.lock_irqsave();
|
||||
|
||||
if guard.buf.len() >= 3 {
|
||||
for i in 0..3 {
|
||||
buf[i] = guard.buf.dequeue().unwrap();
|
||||
for item in buf.iter_mut().take(3) {
|
||||
*item = guard.buf.dequeue().unwrap();
|
||||
}
|
||||
return Ok(3);
|
||||
} else {
|
||||
|
@ -48,7 +48,7 @@ pub unsafe fn dma_dealloc(paddr: usize, vaddr: NonNull<u8>, pages: usize) -> i32
|
||||
);
|
||||
|
||||
// 恢复页面属性
|
||||
let vaddr = VirtAddr::new(vaddr.as_ptr() as *mut u8 as usize);
|
||||
let vaddr = VirtAddr::new(vaddr.as_ptr() as usize);
|
||||
let mut kernel_mapper = KernelMapper::lock();
|
||||
let kernel_mapper = kernel_mapper.as_mut().unwrap();
|
||||
let flusher = kernel_mapper
|
||||
|
@ -155,7 +155,7 @@ impl E1000EBuffer {
|
||||
return self.length;
|
||||
}
|
||||
// 释放buffer内部的dma_pages,需要小心使用
|
||||
pub fn free_buffer(self) -> () {
|
||||
pub fn free_buffer(self) {
|
||||
if self.length != 0 {
|
||||
unsafe { dma_dealloc(self.paddr, self.buffer, E1000E_DMA_PAGES) };
|
||||
}
|
||||
@ -274,7 +274,7 @@ impl E1000EDevice {
|
||||
// close the interrupt
|
||||
volwrite!(interrupt_regs, imc, E1000E_IMC_CLEAR);
|
||||
let mut gcr = volread!(pcie_regs, gcr);
|
||||
gcr = gcr | (1 << 22);
|
||||
gcr |= 1 << 22;
|
||||
volwrite!(pcie_regs, gcr, gcr);
|
||||
compiler_fence(Ordering::AcqRel);
|
||||
// PHY Initialization 14.8.1
|
||||
@ -291,11 +291,11 @@ impl E1000EDevice {
|
||||
let ral = unsafe { volread!(ra_regs, ral0) };
|
||||
let rah = unsafe { volread!(ra_regs, rah0) };
|
||||
let mac: [u8; 6] = [
|
||||
((ral >> 0) & 0xFF) as u8,
|
||||
(ral & 0xFF) as u8,
|
||||
((ral >> 8) & 0xFF) as u8,
|
||||
((ral >> 16) & 0xFF) as u8,
|
||||
((ral >> 24) & 0xFF) as u8,
|
||||
((rah >> 0) & 0xFF) as u8,
|
||||
(rah & 0xFF) as u8,
|
||||
((rah >> 8) & 0xFF) as u8,
|
||||
];
|
||||
// 初始化receive和transimit descriptor环形队列
|
||||
@ -319,17 +319,17 @@ impl E1000EDevice {
|
||||
|
||||
// 初始化缓冲区与descriptor,descriptor 中的addr字典应当指向buffer的物理地址
|
||||
// Receive buffers of appropriate size should be allocated and pointers to these buffers should be stored in the descriptor ring.
|
||||
for i in 0..recv_ring_length {
|
||||
for ring in recv_desc_ring.iter_mut().take(recv_ring_length) {
|
||||
let buffer = E1000EBuffer::new(PAGE_SIZE);
|
||||
recv_desc_ring[i].addr = buffer.as_paddr() as u64;
|
||||
recv_desc_ring[i].status = 0;
|
||||
ring.addr = buffer.as_paddr() as u64;
|
||||
ring.status = 0;
|
||||
recv_buffers.push(buffer);
|
||||
}
|
||||
// Same as receive buffers
|
||||
for i in 0..trans_ring_length {
|
||||
for ring in trans_desc_ring.iter_mut().take(recv_ring_length) {
|
||||
let buffer = E1000EBuffer::new(PAGE_SIZE);
|
||||
trans_desc_ring[i].addr = buffer.as_paddr() as u64;
|
||||
trans_desc_ring[i].status = 1;
|
||||
ring.addr = buffer.as_paddr() as u64;
|
||||
ring.status = 1;
|
||||
trans_buffers.push(buffer);
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ impl E1000EDevice {
|
||||
while mta_adress != vaddress + E1000E_MTA_REGS_END_OFFSET {
|
||||
let mta: NonNull<MTARegs> = get_register_ptr(mta_adress, 0);
|
||||
unsafe { volwrite!(mta, mta, 0) };
|
||||
mta_adress = mta_adress + 4;
|
||||
mta_adress += 4;
|
||||
}
|
||||
// 连续的寄存器读-写操作,放在同一个unsafe块中
|
||||
unsafe {
|
||||
@ -491,8 +491,8 @@ impl E1000EDevice {
|
||||
pub fn e1000e_intr_set(&mut self, state: bool) {
|
||||
let mut ims = unsafe { volread!(self.interrupt_regs, ims) };
|
||||
match state {
|
||||
true => ims = ims | E1000E_IMS_RXT0,
|
||||
false => ims = ims & !E1000E_IMS_RXT0,
|
||||
true => ims |= E1000E_IMS_RXT0,
|
||||
false => ims &= !E1000E_IMS_RXT0,
|
||||
}
|
||||
unsafe { volwrite!(self.interrupt_regs, ims, ims) };
|
||||
}
|
||||
@ -512,8 +512,7 @@ impl E1000EDevice {
|
||||
// close interrupt
|
||||
self.e1000e_intr_set(false);
|
||||
loop {
|
||||
if self.napi_buffer_tail == self.napi_buffer_head && self.napi_buffer_empty == false
|
||||
{
|
||||
if self.napi_buffer_tail == self.napi_buffer_head && !self.napi_buffer_empty {
|
||||
// napi缓冲队列已满,停止收包
|
||||
// napi queue is full, stop
|
||||
break;
|
||||
@ -593,7 +592,7 @@ pub extern "C" fn rs_e1000e_init() {
|
||||
e1000e_init();
|
||||
}
|
||||
|
||||
pub fn e1000e_init() -> () {
|
||||
pub fn e1000e_init() {
|
||||
match e1000e_probe() {
|
||||
Ok(_code) => {
|
||||
kinfo!("Successfully init e1000e device!");
|
||||
|
@ -34,6 +34,8 @@ pub struct E1000ETxToken {
|
||||
pub struct E1000EDriver {
|
||||
pub inner: Arc<SpinLock<E1000EDevice>>,
|
||||
}
|
||||
unsafe impl Send for E1000EDriver {}
|
||||
unsafe impl Sync for E1000EDriver {}
|
||||
|
||||
/// @brief 网卡驱动的包裹器,这是为了获取网卡驱动的可变引用而设计的。
|
||||
/// 参阅virtio_net.rs
|
||||
@ -54,6 +56,7 @@ impl DerefMut for E1000EDriverWrapper {
|
||||
}
|
||||
|
||||
impl E1000EDriverWrapper {
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
fn force_get_mut(&self) -> &mut E1000EDriver {
|
||||
unsafe { &mut *self.0.get() }
|
||||
}
|
||||
@ -76,7 +79,7 @@ impl phy::RxToken for E1000ERxToken {
|
||||
where
|
||||
F: FnOnce(&mut [u8]) -> R,
|
||||
{
|
||||
let result = f(&mut self.0.as_mut_slice());
|
||||
let result = f(self.0.as_mut_slice());
|
||||
self.0.free_buffer();
|
||||
return result;
|
||||
}
|
||||
@ -97,6 +100,7 @@ impl phy::TxToken for E1000ETxToken {
|
||||
}
|
||||
|
||||
impl E1000EDriver {
|
||||
#[allow(clippy::arc_with_non_send_sync)]
|
||||
pub fn new(device: E1000EDevice) -> Self {
|
||||
let mut iface_config = smoltcp::iface::Config::new();
|
||||
|
||||
@ -253,11 +257,11 @@ impl NetDriver for E1000EInterface {
|
||||
|
||||
self.iface.lock().update_ip_addrs(|addrs| {
|
||||
let dest = addrs.iter_mut().next();
|
||||
if let None = dest {
|
||||
addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
|
||||
} else {
|
||||
let dest = dest.unwrap();
|
||||
|
||||
if let Some(dest) = dest {
|
||||
*dest = ip_addrs[0];
|
||||
} else {
|
||||
addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
|
||||
}
|
||||
});
|
||||
return Ok(());
|
||||
|
@ -1,2 +1,3 @@
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod e1000e;
|
||||
pub mod e1000e_driver;
|
||||
|
@ -61,6 +61,7 @@ impl<T: Transport> DerefMut for VirtioNICDriverWrapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
impl<T: Transport> VirtioNICDriverWrapper<T> {
|
||||
fn force_get_mut(&self) -> &mut VirtioNICDriver<T> {
|
||||
unsafe { &mut *self.0.get() }
|
||||
@ -160,7 +161,7 @@ pub struct VirtioNetToken<T: Transport> {
|
||||
rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
|
||||
}
|
||||
|
||||
impl<'a, T: Transport> VirtioNetToken<T> {
|
||||
impl<T: Transport> VirtioNetToken<T> {
|
||||
pub fn new(
|
||||
driver: VirtioNICDriver<T>,
|
||||
rx_buffer: Option<virtio_drivers::device::net::RxBuffer>,
|
||||
@ -322,11 +323,11 @@ impl<T: Transport + 'static> NetDriver for VirtioInterface<T> {
|
||||
|
||||
self.iface.lock().update_ip_addrs(|addrs| {
|
||||
let dest = addrs.iter_mut().next();
|
||||
if let None = dest {
|
||||
addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
|
||||
} else {
|
||||
let dest = dest.unwrap();
|
||||
|
||||
if let Some(dest) = dest {
|
||||
*dest = ip_addrs[0];
|
||||
} else {
|
||||
addrs.push(ip_addrs[0]).expect("Push ipCidr failed: full");
|
||||
}
|
||||
});
|
||||
return Ok(());
|
||||
|
@ -92,10 +92,10 @@ impl OpenFirmwareFdtDriver {
|
||||
|
||||
/// 扫描 `/chosen` 节点
|
||||
fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> {
|
||||
const CHOSEN_NAME1: &'static str = "/chosen";
|
||||
const CHOSEN_NAME1: &str = "/chosen";
|
||||
let mut node = fdt.find_node(CHOSEN_NAME1);
|
||||
if node.is_none() {
|
||||
const CHOSEN_NAME2: &'static str = "/chosen@0";
|
||||
const CHOSEN_NAME2: &str = "/chosen@0";
|
||||
node = fdt.find_node(CHOSEN_NAME2);
|
||||
if node.is_some() {
|
||||
FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2);
|
||||
|
@ -1,2 +1,3 @@
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod pci;
|
||||
pub mod pci_irq;
|
||||
|
@ -128,6 +128,7 @@ pub fn get_pci_device_structure_mut<'a>(
|
||||
/// @param class_code 寄存器值
|
||||
/// @param subclass 寄存器值,与class_code一起确定设备类型
|
||||
/// @return Vec<&'a Box<(dyn PciDeviceStructure) 包含链表中所有满足条件的PCI结构体的不可变引用的容器
|
||||
#[allow(clippy::borrowed_box)]
|
||||
pub fn get_pci_device_structure<'a>(
|
||||
list: &'a mut RwLockReadGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
||||
class_code: u8,
|
||||
@ -567,7 +568,7 @@ impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
|
||||
}
|
||||
#[inline(always)]
|
||||
fn as_pci_to_carbus_bridge_device(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
|
||||
Some(&self)
|
||||
Some(self)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn as_pci_to_carbus_bridge_device_mut(
|
||||
@ -634,7 +635,7 @@ impl PciRoot {
|
||||
let size = (bus_number_double as usize) * (PAGE_2M_SIZE as usize);
|
||||
unsafe {
|
||||
let space_guard = mmio_pool()
|
||||
.create_mmio(size as usize)
|
||||
.create_mmio(size)
|
||||
.map_err(|_| PciError::CreateMmioError)?;
|
||||
let space_guard = Arc::new(space_guard);
|
||||
self.mmio_guard = Some(space_guard.clone());
|
||||
|
@ -497,7 +497,7 @@ impl KObject for Serial8250ISADriver {
|
||||
}
|
||||
|
||||
fn kobj_type(&self) -> Option<&'static dyn KObjType> {
|
||||
self.inner.read().kobj_type.clone()
|
||||
self.inner.read().kobj_type
|
||||
}
|
||||
|
||||
fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) {
|
||||
|
@ -25,11 +25,9 @@ impl Serial8250Manager {
|
||||
uart_driver: &Arc<Serial8250ISADriver>,
|
||||
devs: &Arc<Serial8250ISADevices>,
|
||||
) {
|
||||
for i in 0..8 {
|
||||
if let Some(port) = unsafe { PIO_PORTS[i].as_ref() } {
|
||||
port.set_device(Some(devs));
|
||||
self.uart_add_one_port(uart_driver, port).ok();
|
||||
}
|
||||
for port in unsafe { &PIO_PORTS }.iter().flatten() {
|
||||
port.set_device(Some(devs));
|
||||
self.uart_add_one_port(uart_driver, port).ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -86,9 +84,7 @@ impl Serial8250PIOPort {
|
||||
inner: RwLock::new(Serial8250PIOPortInner::new()),
|
||||
};
|
||||
|
||||
if let Err(e) = r.check_baudrate(&baudrate) {
|
||||
return Err(e);
|
||||
}
|
||||
r.check_baudrate(&baudrate)?;
|
||||
|
||||
return Ok(r);
|
||||
}
|
||||
@ -112,10 +108,10 @@ impl Serial8250PIOPort {
|
||||
CurrentPortIOArch::out8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||
CurrentPortIOArch::out8(port + 4, 0x08); // IRQs enabled, RTS/DSR clear (现代计算机上一般都不需要hardware flow control,因此不需要置位RTS/DSR)
|
||||
CurrentPortIOArch::out8(port + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||
CurrentPortIOArch::out8(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||
CurrentPortIOArch::out8(port, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||
|
||||
// Check if serial is faulty (i.e: not same byte as sent)
|
||||
if CurrentPortIOArch::in8(port + 0) != 0xAE {
|
||||
if CurrentPortIOArch::in8(port) != 0xAE {
|
||||
self.initialized.store(false, Ordering::SeqCst);
|
||||
return Err(SystemError::ENODEV);
|
||||
}
|
||||
@ -149,19 +145,11 @@ impl Serial8250PIOPort {
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn serial_received(&self) -> bool {
|
||||
if self.serial_in(5) & 1 != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
self.serial_in(5) & 1 != 0
|
||||
}
|
||||
|
||||
fn is_transmit_empty(&self) -> bool {
|
||||
if self.serial_in(5) & 0x20 != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
self.serial_in(5) & 0x20 != 0
|
||||
}
|
||||
|
||||
/// 发送字节
|
||||
@ -170,7 +158,7 @@ impl Serial8250PIOPort {
|
||||
///
|
||||
/// - `s`:待发送的字节
|
||||
fn send_bytes(&self, s: &[u8]) {
|
||||
while self.is_transmit_empty() == false {
|
||||
while !self.is_transmit_empty() {
|
||||
spin_loop();
|
||||
}
|
||||
|
||||
@ -182,7 +170,7 @@ impl Serial8250PIOPort {
|
||||
/// 读取一个字节
|
||||
#[allow(dead_code)]
|
||||
fn read_one_byte(&self) -> u8 {
|
||||
while self.serial_received() == false {
|
||||
while !self.serial_received() {
|
||||
spin_loop();
|
||||
}
|
||||
return self.serial_in(0) as u8;
|
||||
@ -223,7 +211,7 @@ impl UartPort for Serial8250PIOPort {
|
||||
|
||||
let divisor = self.divisor(baud).0;
|
||||
|
||||
CurrentPortIOArch::out8(port + 0, (divisor & 0xff) as u8); // Set divisor (lo byte)
|
||||
CurrentPortIOArch::out8(port, (divisor & 0xff) as u8); // Set divisor (lo byte)
|
||||
CurrentPortIOArch::out8(port + 1, ((divisor >> 8) & 0xff) as u8); // (hi byte)
|
||||
CurrentPortIOArch::out8(port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
}
|
||||
@ -271,7 +259,7 @@ impl Serial8250PIOPortInner {
|
||||
}
|
||||
|
||||
fn set_device(&mut self, device: Option<&Arc<Serial8250ISADevices>>) {
|
||||
self.device = device.map(|d| Arc::downgrade(d));
|
||||
self.device = device.map(Arc::downgrade);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ impl HpetRegisters {
|
||||
|
||||
/// 获取 HPET 计数器的频率
|
||||
pub fn frequency(&self) -> u64 {
|
||||
10000_0000_0000_000 / self.counter_clock_period()
|
||||
1_000_000_000_000_000 / self.counter_clock_period()
|
||||
}
|
||||
|
||||
pub fn main_counter_value(&self) -> u64 {
|
||||
|
@ -1 +1,2 @@
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod rtc;
|
||||
|
@ -5,6 +5,7 @@ use crate::{
|
||||
exception::InterruptArch,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RtcTime {
|
||||
pub second: i32,
|
||||
pub minute: i32,
|
||||
@ -14,19 +15,6 @@ pub struct RtcTime {
|
||||
pub year: i32,
|
||||
}
|
||||
|
||||
impl Default for RtcTime {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
second: (0),
|
||||
minute: (0),
|
||||
hour: (0),
|
||||
day: (0),
|
||||
month: (0),
|
||||
year: (0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RtcTime {
|
||||
///@brief 从主板cmos中获取时间
|
||||
///
|
||||
@ -37,17 +25,10 @@ impl RtcTime {
|
||||
let irq_guard = unsafe { CurrentIrqArch::save_and_disable_irq() };
|
||||
//0x0B
|
||||
let status_register_b: u8 = read_cmos(0x0B); // 读取状态寄存器B
|
||||
let is_24h: bool = if (status_register_b & 0x02) != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}; // 判断是否启用24小时模式
|
||||
let is_24h: bool = (status_register_b & 0x02) != 0;
|
||||
// 判断是否启用24小时模式
|
||||
|
||||
let is_binary: bool = if (status_register_b & 0x04) != 0 {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}; // 判断是否为二进制码
|
||||
let is_binary: bool = (status_register_b & 0x04) != 0; // 判断是否为二进制码
|
||||
|
||||
loop {
|
||||
self.year = read_cmos(CMOSTimeSelector::Year as u8) as i32;
|
||||
|
@ -85,6 +85,7 @@ pub trait ConsoleSwitch: Sync + Send {
|
||||
/// - underline: 下划线
|
||||
/// - reverse: 颜色反转
|
||||
/// - italic: 斜体
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn con_build_attr(
|
||||
&self,
|
||||
_vc_data: &VirtualConsoleData,
|
||||
|
@ -50,8 +50,8 @@ fn tty_refresh_thread() -> i32 {
|
||||
continue;
|
||||
}
|
||||
let mut data = [0u8; TO_DEQUEUE_MAX];
|
||||
for i in 0..to_dequeue {
|
||||
data[i] = KEYBUF.pop().unwrap();
|
||||
for item in data.iter_mut().take(to_dequeue) {
|
||||
*item = KEYBUF.pop().unwrap();
|
||||
}
|
||||
|
||||
let _ = current_tty_port().receive_buf(&data[0..to_dequeue], &[], to_dequeue);
|
||||
@ -60,7 +60,7 @@ fn tty_refresh_thread() -> i32 {
|
||||
|
||||
/// 发送数据到tty刷新线程
|
||||
pub fn send_to_tty_refresh_thread(data: &[u8]) {
|
||||
for i in 0..data.len() {
|
||||
KEYBUF.push(data[i]).ok();
|
||||
for item in data {
|
||||
KEYBUF.push(*item).ok();
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ impl PosixTermios {
|
||||
c_oflag: termios.output_mode.bits,
|
||||
c_cflag: termios.control_mode.bits,
|
||||
c_lflag: termios.local_mode.bits,
|
||||
c_cc: termios.control_characters.clone(),
|
||||
c_cc: termios.control_characters,
|
||||
c_line: termios.line as u8,
|
||||
c_ispeed: termios.input_speed,
|
||||
c_ospeed: termios.output_speed,
|
||||
@ -53,14 +53,14 @@ impl PosixTermios {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn to_kernel_termios(&self) -> Termios {
|
||||
pub fn to_kernel_termios(self) -> Termios {
|
||||
// TODO:这里没有考虑非规范模式
|
||||
Termios {
|
||||
input_mode: InputMode::from_bits_truncate(self.c_iflag),
|
||||
output_mode: OutputMode::from_bits_truncate(self.c_oflag),
|
||||
control_mode: ControlMode::from_bits_truncate(self.c_cflag),
|
||||
local_mode: LocalMode::from_bits_truncate(self.c_lflag),
|
||||
control_characters: self.c_cc.clone(),
|
||||
control_characters: self.c_cc,
|
||||
line: LineDisciplineType::from_line(self.c_line),
|
||||
input_speed: self.c_ispeed,
|
||||
output_speed: self.c_ospeed,
|
||||
@ -126,7 +126,7 @@ lazy_static! {
|
||||
| LocalMode::ECHOCTL
|
||||
| LocalMode::ECHOKE
|
||||
| LocalMode::IEXTEN,
|
||||
control_characters: INIT_CONTORL_CHARACTERS.clone(),
|
||||
control_characters: INIT_CONTORL_CHARACTERS,
|
||||
line: LineDisciplineType::NTty,
|
||||
input_speed: 38400,
|
||||
output_speed: 38400,
|
||||
|
@ -142,18 +142,17 @@ impl TtyCore {
|
||||
}
|
||||
|
||||
pub fn tty_mode_ioctl(tty: Arc<TtyCore>, cmd: u32, arg: usize) -> Result<usize, SystemError> {
|
||||
let real_tty;
|
||||
let core = tty.core();
|
||||
if core.driver().tty_driver_type() == TtyDriverType::Pty
|
||||
let real_tty = if core.driver().tty_driver_type() == TtyDriverType::Pty
|
||||
&& core.driver().tty_driver_sub_type() == TtyDriverSubType::PtyMaster
|
||||
{
|
||||
real_tty = core.link().unwrap();
|
||||
core.link().unwrap()
|
||||
} else {
|
||||
real_tty = tty;
|
||||
}
|
||||
tty
|
||||
};
|
||||
match cmd {
|
||||
TtyIoctlCmd::TCGETS => {
|
||||
let termios = PosixTermios::from_kernel_termios(real_tty.core.termios().clone());
|
||||
let termios = PosixTermios::from_kernel_termios(*real_tty.core.termios());
|
||||
let mut user_writer = UserBufferWriter::new(
|
||||
VirtAddr::new(arg).as_ptr::<PosixTermios>(),
|
||||
core::mem::size_of::<PosixTermios>(),
|
||||
@ -190,7 +189,7 @@ impl TtyCore {
|
||||
) -> Result<usize, SystemError> {
|
||||
#[allow(unused_assignments)]
|
||||
// TERMIOS_TERMIO下会用到
|
||||
let mut tmp_termios = tty.core().termios().clone();
|
||||
let mut tmp_termios = *tty.core().termios();
|
||||
|
||||
if opt.contains(TtySetTermiosOpt::TERMIOS_TERMIO) {
|
||||
todo!()
|
||||
@ -223,7 +222,7 @@ impl TtyCore {
|
||||
pub fn set_termios_next(tty: Arc<TtyCore>, new_termios: Termios) -> Result<(), SystemError> {
|
||||
let mut termios = tty.core().termios_write();
|
||||
|
||||
let old_termios = termios.clone();
|
||||
let old_termios = *termios;
|
||||
*termios = new_termios;
|
||||
let tmp = termios.control_mode;
|
||||
termios.control_mode ^= (tmp ^ old_termios.control_mode) & ControlMode::ADDRB;
|
||||
@ -245,7 +244,7 @@ impl TtyCore {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TtyContorlInfo {
|
||||
/// 前台进程pid
|
||||
pub session: Option<Pid>,
|
||||
@ -257,17 +256,6 @@ pub struct TtyContorlInfo {
|
||||
pub packet: bool,
|
||||
}
|
||||
|
||||
impl Default for TtyContorlInfo {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
session: None,
|
||||
pgid: None,
|
||||
pktstatus: Default::default(),
|
||||
packet: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct TtyCoreWriteData {
|
||||
/// 写缓冲区
|
||||
@ -341,7 +329,7 @@ impl TtyCoreData {
|
||||
|
||||
#[inline]
|
||||
pub fn flags(&self) -> TtyFlag {
|
||||
self.flags.read_irqsave().clone()
|
||||
*self.flags.read_irqsave()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -117,8 +117,7 @@ impl IndexNode for TtyDevice {
|
||||
});
|
||||
|
||||
let ret = tty.open(tty.core());
|
||||
if ret.is_err() {
|
||||
let err = ret.unwrap_err();
|
||||
if let Err(err) = ret {
|
||||
if err == SystemError::ENOSYS {
|
||||
return Err(SystemError::ENODEV);
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
use core::{fmt::Debug, sync::atomic::Ordering};
|
||||
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
use alloc::{
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
vec::Vec,
|
||||
};
|
||||
use hashbrown::HashMap;
|
||||
use system_error::SystemError;
|
||||
|
||||
@ -109,6 +113,7 @@ pub struct TtyDriver {
|
||||
}
|
||||
|
||||
impl TtyDriver {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
count: u32,
|
||||
node_name: &'static str,
|
||||
@ -142,7 +147,7 @@ impl TtyDriver {
|
||||
.flags
|
||||
.contains(TtyDriverFlag::TTY_DRIVER_UNNUMBERED_NODE)
|
||||
{
|
||||
return format!("{}", self.name);
|
||||
return self.name.to_string();
|
||||
} else {
|
||||
return format!("{}{}", self.name, index + self.name_base);
|
||||
}
|
||||
@ -165,10 +170,7 @@ impl TtyDriver {
|
||||
#[inline]
|
||||
fn lockup_tty(&self, index: usize) -> Option<Arc<TtyCore>> {
|
||||
let device_guard = self.ttys.lock();
|
||||
return match device_guard.get(&index) {
|
||||
Some(tty) => Some(tty.clone()),
|
||||
None => None,
|
||||
};
|
||||
return device_guard.get(&index).cloned();
|
||||
}
|
||||
|
||||
fn standard_install(&self, tty_core: Arc<TtyCore>) -> Result<(), SystemError> {
|
||||
@ -178,7 +180,7 @@ impl TtyDriver {
|
||||
if !self.flags.contains(TtyDriverFlag::TTY_DRIVER_RESET_TERMIOS) {
|
||||
// 先查看是否有已经保存的termios
|
||||
if let Some(t) = self.saved_termios.get(tty_index) {
|
||||
let mut termios = t.clone();
|
||||
let mut termios = *t;
|
||||
termios.line = self.init_termios.line;
|
||||
tty.set_termios(termios);
|
||||
}
|
||||
@ -195,8 +197,7 @@ impl TtyDriver {
|
||||
fn driver_install_tty(driver: Arc<TtyDriver>, tty: Arc<TtyCore>) -> Result<(), SystemError> {
|
||||
let res = tty.install(driver.clone(), tty.clone());
|
||||
|
||||
if res.is_err() {
|
||||
let err = res.unwrap_err();
|
||||
if let Err(err) = res {
|
||||
if err == SystemError::ENOSYS {
|
||||
return driver.standard_install(tty);
|
||||
} else {
|
||||
@ -236,10 +237,8 @@ impl TtyDriver {
|
||||
// TODO: 暂时这么写,因为还没写TtyPort
|
||||
if tty.core().port().is_none() {
|
||||
kwarn!("{} port is None", tty.core().name());
|
||||
} else {
|
||||
if tty.core().port().unwrap().state() == TtyPortState::KOPENED {
|
||||
return Err(SystemError::EBUSY);
|
||||
}
|
||||
} else if tty.core().port().unwrap().state() == TtyPortState::KOPENED {
|
||||
return Err(SystemError::EBUSY);
|
||||
}
|
||||
|
||||
tty.reopen()?;
|
||||
|
@ -103,8 +103,7 @@ impl TtyLdiscManager {
|
||||
let ld = tty.ldisc();
|
||||
|
||||
let ret = ld.open(tty);
|
||||
if ret.is_err() {
|
||||
let err = ret.unwrap_err();
|
||||
if let Err(err) = ret {
|
||||
if err == SystemError::ENOSYS {
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -209,15 +209,10 @@ impl NTtyData {
|
||||
}
|
||||
|
||||
if !overflow {
|
||||
if flags.is_none() {
|
||||
self.receive_buf(tty.clone(), &buf[offset..], flags, n);
|
||||
if let Some(flags) = flags {
|
||||
self.receive_buf(tty.clone(), &buf[offset..], Some(&flags[offset..]), n);
|
||||
} else {
|
||||
self.receive_buf(
|
||||
tty.clone(),
|
||||
&buf[offset..],
|
||||
Some(&flags.unwrap()[offset..]),
|
||||
n,
|
||||
);
|
||||
self.receive_buf(tty.clone(), &buf[offset..], flags, n);
|
||||
}
|
||||
}
|
||||
|
||||
@ -792,8 +787,8 @@ impl NTtyData {
|
||||
// 先处理信号
|
||||
let mut ctrl_info = tty.core().contorl_info_irqsave();
|
||||
let pg = ctrl_info.pgid;
|
||||
if pg.is_some() {
|
||||
let _ = Syscall::kill(pg.unwrap(), signal as i32);
|
||||
if let Some(pg) = pg {
|
||||
let _ = Syscall::kill(pg, signal as i32);
|
||||
}
|
||||
|
||||
ctrl_info.pgid = None;
|
||||
@ -1023,7 +1018,7 @@ impl NTtyData {
|
||||
// 找到eol的坐标
|
||||
let tmp = self.read_flags.next_index(tail);
|
||||
// 找到的话即为坐标,未找到的话即为NTTY_BUFSIZE
|
||||
let mut eol = if tmp.is_none() { size } else { tmp.unwrap() };
|
||||
let mut eol = if let Some(tmp) = tmp { tmp } else { size };
|
||||
if eol > size {
|
||||
eol = size
|
||||
}
|
||||
@ -1035,8 +1030,7 @@ impl NTtyData {
|
||||
let found = if eol == NTTY_BUFSIZE && more > 0 {
|
||||
// 需要返回头部
|
||||
let ret = self.read_flags.first_index();
|
||||
if ret.is_some() {
|
||||
let tmp = ret.unwrap();
|
||||
if let Some(tmp) = ret {
|
||||
// 在头部范围内找到eol
|
||||
if tmp < more {
|
||||
eol = tmp;
|
||||
@ -1179,9 +1173,9 @@ impl NTtyData {
|
||||
}
|
||||
|
||||
let mut cnt = 0;
|
||||
for i in 0..nr {
|
||||
for (i, c) in buf.iter().enumerate().take(nr) {
|
||||
cnt = i;
|
||||
let c = buf[i];
|
||||
let c = *c;
|
||||
if c as usize == 8 {
|
||||
// 表示退格
|
||||
if self.cursor_column > 0 {
|
||||
@ -1247,7 +1241,7 @@ impl NTtyData {
|
||||
let echoed = self.echoes(tty.clone());
|
||||
|
||||
if echoed.is_ok() && echoed.unwrap() > 0 {
|
||||
let _ = tty.flush_chars(tty.core());
|
||||
tty.flush_chars(tty.core());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1345,8 +1339,8 @@ impl NTtyData {
|
||||
if tty.put_char(tty.core(), 8).is_err() {
|
||||
tty.write(core, &[8], 1)?;
|
||||
}
|
||||
if tty.put_char(tty.core(), ' ' as u8).is_err() {
|
||||
tty.write(core, &[' ' as u8], 1)?;
|
||||
if tty.put_char(tty.core(), b' ').is_err() {
|
||||
tty.write(core, &[b' '], 1)?;
|
||||
}
|
||||
self.cursor_column -= 1;
|
||||
space -= 1;
|
||||
@ -1490,18 +1484,18 @@ impl NTtyData {
|
||||
'\t' => {
|
||||
// 计算输出一个\t需要的空间
|
||||
let spaces = 8 - (self.cursor_column & 7) as usize;
|
||||
if termios.output_mode.contains(OutputMode::TABDLY) {
|
||||
if OutputMode::TABDLY.bits() == OutputMode::XTABS.bits() {
|
||||
// 配置的tab选项是真正输出空格到驱动
|
||||
if space < spaces {
|
||||
// 空间不够
|
||||
return Err(SystemError::ENOBUFS);
|
||||
}
|
||||
self.cursor_column += spaces as u32;
|
||||
// 写入sapces个空格
|
||||
tty.write(core, " ".as_bytes(), spaces)?;
|
||||
return Ok(spaces);
|
||||
if termios.output_mode.contains(OutputMode::TABDLY)
|
||||
&& OutputMode::TABDLY.bits() == OutputMode::XTABS.bits()
|
||||
{
|
||||
// 配置的tab选项是真正输出空格到驱动
|
||||
if space < spaces {
|
||||
// 空间不够
|
||||
return Err(SystemError::ENOBUFS);
|
||||
}
|
||||
self.cursor_column += spaces as u32;
|
||||
// 写入sapces个空格
|
||||
tty.write(core, " ".as_bytes(), spaces)?;
|
||||
return Ok(spaces);
|
||||
}
|
||||
self.cursor_column += spaces as u32;
|
||||
}
|
||||
@ -1598,10 +1592,8 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
||||
} else if ldata.canon_copy_from_read_buf(buf, &mut nr, &mut offset)? {
|
||||
return Ok(len - nr);
|
||||
}
|
||||
} else {
|
||||
if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? {
|
||||
return Ok(len - nr);
|
||||
}
|
||||
} else if ldata.copy_from_read_buf(termios, buf, &mut nr, &mut offset)? {
|
||||
return Ok(len - nr);
|
||||
}
|
||||
|
||||
// 没有数据可读
|
||||
@ -1723,7 +1715,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
||||
let pcb = ProcessManager::current_pcb();
|
||||
let binding = tty.clone();
|
||||
let core = binding.core();
|
||||
let termios = core.termios().clone();
|
||||
let termios = *core.termios();
|
||||
if termios.local_mode.contains(LocalMode::TOSTOP) {
|
||||
TtyJobCtrlManager::tty_check_change(tty.clone(), Signal::SIGTTOU)?;
|
||||
}
|
||||
@ -1769,7 +1761,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
||||
nr -= 1;
|
||||
}
|
||||
|
||||
let _ = tty.flush_chars(core);
|
||||
tty.flush_chars(core);
|
||||
} else {
|
||||
while nr > 0 {
|
||||
let write = tty.write(core, &buf[offset..], nr)?;
|
||||
@ -1876,8 +1868,8 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
||||
|
||||
// 第一次设置或者规范模式 (ICANON) 或者扩展处理 (EXTPROC) 标志发生变化
|
||||
let mut spec_mode_changed = false;
|
||||
if old.is_some() {
|
||||
let local_mode = old.clone().unwrap().local_mode.bitxor(termios.local_mode);
|
||||
if let Some(old) = old {
|
||||
let local_mode = old.local_mode.bitxor(termios.local_mode);
|
||||
spec_mode_changed =
|
||||
local_mode.contains(LocalMode::ICANON) || local_mode.contains(LocalMode::EXTPROC);
|
||||
}
|
||||
@ -2001,7 +1993,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
||||
// 原模式或real_raw
|
||||
ldata.raw = true;
|
||||
|
||||
if termios.input_mode.contains(InputMode::IGNBRK)
|
||||
ldata.real_raw = termios.input_mode.contains(InputMode::IGNBRK)
|
||||
|| (!termios.input_mode.contains(InputMode::BRKINT)
|
||||
&& !termios.input_mode.contains(InputMode::PARMRK))
|
||||
&& (termios.input_mode.contains(InputMode::IGNPAR)
|
||||
@ -2009,12 +2001,7 @@ impl TtyLineDiscipline for NTtyLinediscipline {
|
||||
&& (core
|
||||
.driver()
|
||||
.flags()
|
||||
.contains(TtyDriverFlag::TTY_DRIVER_REAL_RAW))
|
||||
{
|
||||
ldata.real_raw = true;
|
||||
} else {
|
||||
ldata.real_raw = false;
|
||||
}
|
||||
.contains(TtyDriverFlag::TTY_DRIVER_REAL_RAW));
|
||||
}
|
||||
|
||||
// if !termios.input_mode.contains(InputMode::IXON)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/// Latin-1 字符集到 Unicode 的映射表。在这个表格中,每个位置都存储了相应 Latin-1 字符的 Unicode 编码。
|
||||
pub const LAT1_MAP: &'static [u16] = &[
|
||||
pub const LAT1_MAP: &[u16] = &[
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b,
|
||||
0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
||||
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
|
||||
@ -25,7 +25,7 @@ pub const LAT1_MAP: &'static [u16] = &[
|
||||
];
|
||||
|
||||
/// 将 VT100 图形字符映射到 Unicode 的映射表
|
||||
pub const GRAF_MAP: &'static [u16] = &[
|
||||
pub const GRAF_MAP: &[u16] = &[
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b,
|
||||
0x000c, 0x000d, 0x000e, 0x000f, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
||||
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, 0x0021, 0x0022, 0x0023,
|
||||
@ -51,7 +51,7 @@ pub const GRAF_MAP: &'static [u16] = &[
|
||||
];
|
||||
|
||||
/// 将 IBM Codepage 437 字符集映射到 Unicode 的映射表
|
||||
pub const IBMPC_MAP: &'static [u16] = &[
|
||||
pub const IBMPC_MAP: &[u16] = &[
|
||||
0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 0x25d8, 0x25cb, 0x25d9, 0x2642,
|
||||
0x2640, 0x266a, 0x266b, 0x263c, 0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
|
||||
0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc, 0x0020, 0x0021, 0x0022, 0x0023,
|
||||
@ -77,7 +77,7 @@ pub const IBMPC_MAP: &'static [u16] = &[
|
||||
];
|
||||
|
||||
/// 默认直接映射表
|
||||
pub const USER_MAP: &'static [u16] = &[
|
||||
pub const USER_MAP: &[u16] = &[
|
||||
0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007, 0xf008, 0xf009, 0xf00a, 0xf00b,
|
||||
0xf00c, 0xf00d, 0xf00e, 0xf00f, 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
|
||||
0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f, 0xf020, 0xf021, 0xf022, 0xf023,
|
||||
@ -105,10 +105,10 @@ pub const USER_MAP: &'static [u16] = &[
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum TranslationMapType {
|
||||
Lat1Map,
|
||||
GrafMap,
|
||||
IbmpcMap,
|
||||
UserMap,
|
||||
Lat1,
|
||||
Graf,
|
||||
Ibmpc,
|
||||
User,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -120,10 +120,10 @@ pub struct TranslationMap {
|
||||
impl TranslationMap {
|
||||
pub const fn new(map_type: TranslationMapType) -> Self {
|
||||
let map = match map_type {
|
||||
TranslationMapType::Lat1Map => LAT1_MAP,
|
||||
TranslationMapType::GrafMap => GRAF_MAP,
|
||||
TranslationMapType::IbmpcMap => IBMPC_MAP,
|
||||
TranslationMapType::UserMap => USER_MAP,
|
||||
TranslationMapType::Lat1 => LAT1_MAP,
|
||||
TranslationMapType::Graf => GRAF_MAP,
|
||||
TranslationMapType::Ibmpc => IBMPC_MAP,
|
||||
TranslationMapType::User => USER_MAP,
|
||||
};
|
||||
|
||||
Self { map_type, map }
|
||||
|
@ -44,7 +44,7 @@ pub const DEFAULT_BLUE: [u16; 16] = [
|
||||
0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff,
|
||||
];
|
||||
|
||||
pub const COLOR_TABLE: &'static [u8] = &[0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15];
|
||||
pub const COLOR_TABLE: &[u8] = &[0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15];
|
||||
|
||||
lazy_static! {
|
||||
pub static ref VIRT_CONSOLES: Vec<Arc<SpinLock<VirtualConsoleData>>> = {
|
||||
@ -293,7 +293,7 @@ pub fn vty_init() -> Result<(), SystemError> {
|
||||
Major::TTY_MAJOR,
|
||||
0,
|
||||
TtyDriverType::Console,
|
||||
TTY_STD_TERMIOS.clone(),
|
||||
*TTY_STD_TERMIOS,
|
||||
Arc::new(TtyConsoleDriverInner::new()?),
|
||||
);
|
||||
|
||||
|
@ -187,13 +187,13 @@ impl VirtualConsoleData {
|
||||
autowrap: Default::default(),
|
||||
cursor_visible: Default::default(),
|
||||
insert_mode: Default::default(),
|
||||
private: Vt102_OP::EPecma,
|
||||
private: Vt102_OP::Pecma,
|
||||
need_wrap: Default::default(),
|
||||
report_mouse: Default::default(),
|
||||
utf: Default::default(),
|
||||
utf_count: Default::default(),
|
||||
utf_char: Default::default(),
|
||||
translate: TranslationMap::new(TranslationMapType::Lat1Map),
|
||||
translate: TranslationMap::new(TranslationMapType::Lat1),
|
||||
npar: Default::default(),
|
||||
tab_stop: StaticBitmap::new(),
|
||||
par: [0; 16],
|
||||
@ -206,11 +206,11 @@ impl VirtualConsoleData {
|
||||
}
|
||||
|
||||
pub(super) fn init(&mut self, rows: Option<usize>, cols: Option<usize>, clear: bool) {
|
||||
if rows.is_some() {
|
||||
self.rows = rows.unwrap();
|
||||
if let Some(rows) = rows {
|
||||
self.rows = rows;
|
||||
}
|
||||
if cols.is_some() {
|
||||
self.cols = cols.unwrap();
|
||||
if let Some(cols) = cols {
|
||||
self.cols = cols;
|
||||
}
|
||||
|
||||
self.pos = self.cols * self.state.y + self.state.x;
|
||||
@ -263,7 +263,7 @@ impl VirtualConsoleData {
|
||||
self.need_wrap = false;
|
||||
self.report_mouse = 0;
|
||||
self.utf_count = 0;
|
||||
self.translate = TranslationMap::new(TranslationMapType::Lat1Map);
|
||||
self.translate = TranslationMap::new(TranslationMapType::Lat1);
|
||||
self.utf = true;
|
||||
self.pid = None;
|
||||
self.vc_state = VirtualConsoleState::ESnormal;
|
||||
@ -321,8 +321,8 @@ impl VirtualConsoleData {
|
||||
if self.utf && !self.display_ctrl {
|
||||
// utf模式并且不显示控制字符
|
||||
let (ret, rescan) = self.translate_unicode(*c);
|
||||
if ret.is_some() {
|
||||
*c = ret.unwrap();
|
||||
if let Some(ret) = ret {
|
||||
*c = ret;
|
||||
}
|
||||
return (ret, rescan);
|
||||
}
|
||||
@ -425,7 +425,7 @@ impl VirtualConsoleData {
|
||||
/// 但是有一些特殊的代码点是无效的或者保留给特定用途的。
|
||||
/// 这个函数的主要目的是将无效的 Unicode 代码点替换为 U+FFFD,即 Unicode 替代字符。
|
||||
fn sanitize_unicode(c: u32) -> u32 {
|
||||
if (c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff {
|
||||
if (0xd800..=0xdfff).contains(&c) || c == 0xfffe || c == 0xffff {
|
||||
return 0xfffd;
|
||||
}
|
||||
return c;
|
||||
@ -502,7 +502,7 @@ impl VirtualConsoleData {
|
||||
}
|
||||
|
||||
let mut soft_cursor_guard = SOFTCURSOR_ORIGINAL.write_irqsave();
|
||||
*soft_cursor_guard = Some(unsafe { VcCursor::from_bits_unchecked(i as u32) });
|
||||
*soft_cursor_guard = Some(unsafe { VcCursor::from_bits_unchecked(i) });
|
||||
|
||||
let soft_cursor = soft_cursor_guard.unwrap();
|
||||
|
||||
@ -523,7 +523,7 @@ impl VirtualConsoleData {
|
||||
|
||||
let _ =
|
||||
self.driver_funcs()
|
||||
.con_putc(&self, i as u16, self.state.y as u32, self.state.x as u32);
|
||||
.con_putc(self, i as u16, self.state.y as u32, self.state.x as u32);
|
||||
}
|
||||
|
||||
pub fn hide_cursor(&mut self) {
|
||||
@ -538,7 +538,7 @@ impl VirtualConsoleData {
|
||||
if softcursor.is_some() {
|
||||
self.screen_buf[self.pos] = softcursor.unwrap().bits as u16;
|
||||
let _ = self.driver_funcs().con_putc(
|
||||
&self,
|
||||
self,
|
||||
softcursor.unwrap().bits as u16,
|
||||
self.state.y as u32,
|
||||
self.state.x as u32,
|
||||
@ -560,12 +560,10 @@ impl VirtualConsoleData {
|
||||
fn gotoxy(&mut self, x: i32, y: i32) {
|
||||
if x < 0 {
|
||||
self.state.x = 0;
|
||||
} else if x as usize >= self.cols {
|
||||
self.state.x = self.cols - 1;
|
||||
} else {
|
||||
if x as usize >= self.cols {
|
||||
self.state.x = self.cols - 1;
|
||||
} else {
|
||||
self.state.x = x as usize;
|
||||
}
|
||||
self.state.x = x as usize;
|
||||
}
|
||||
|
||||
let max_y;
|
||||
@ -579,9 +577,9 @@ impl VirtualConsoleData {
|
||||
}
|
||||
|
||||
if y < min_y as i32 {
|
||||
self.state.y = min_y as usize;
|
||||
self.state.y = min_y;
|
||||
} else if y >= max_y as i32 {
|
||||
self.state.y = max_y as usize;
|
||||
self.state.y = max_y;
|
||||
} else {
|
||||
self.state.y = y as usize;
|
||||
}
|
||||
@ -635,7 +633,7 @@ impl VirtualConsoleData {
|
||||
|
||||
/// ## 换行
|
||||
fn line_feed(&mut self) {
|
||||
if self.state.y + 1 == self.bottom as usize {
|
||||
if self.state.y + 1 == self.bottom {
|
||||
self.scroll(ScrollDir::Up, 1);
|
||||
} else if self.state.y < self.rows - 1 {
|
||||
self.state.y += 1;
|
||||
@ -661,7 +659,7 @@ impl VirtualConsoleData {
|
||||
|
||||
/// ## 向上滚动虚拟终端的内容,或者将光标上移一行
|
||||
fn reverse_index(&mut self) {
|
||||
if self.state.y == self.top as usize {
|
||||
if self.state.y == self.top {
|
||||
self.scroll(ScrollDir::Down, 1);
|
||||
} else if self.state.y > 0 {
|
||||
self.state.y -= 1;
|
||||
@ -686,7 +684,7 @@ impl VirtualConsoleData {
|
||||
/// ## 设置当前vt的各项属性
|
||||
fn set_mode(&mut self, on_off: bool) {
|
||||
for i in 0..self.npar as usize {
|
||||
if self.private == Vt102_OP::EPdec {
|
||||
if self.private == Vt102_OP::Pdec {
|
||||
match self.par[i] {
|
||||
1 => {
|
||||
todo!("kbd todo");
|
||||
@ -746,9 +744,9 @@ impl VirtualConsoleData {
|
||||
return;
|
||||
}
|
||||
|
||||
if c >= '0' && c <= '9' {
|
||||
if c.is_ascii_digit() {
|
||||
self.par[self.npar as usize] *= 10;
|
||||
self.par[self.npar as usize] += (c as u8 - '0' as u8) as u32;
|
||||
self.par[self.npar as usize] += (c as u8 - b'0') as u32;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -761,19 +759,19 @@ impl VirtualConsoleData {
|
||||
|
||||
match c {
|
||||
'h' => {
|
||||
if self.private <= Vt102_OP::EPdec {
|
||||
if self.private <= Vt102_OP::Pdec {
|
||||
self.set_mode(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
'l' => {
|
||||
if self.private <= Vt102_OP::EPdec {
|
||||
if self.private <= Vt102_OP::Pdec {
|
||||
self.set_mode(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
'c' => {
|
||||
if self.private == Vt102_OP::EPdec {
|
||||
if self.private == Vt102_OP::Pdec {
|
||||
if self.par[0] != 0 {
|
||||
self.cursor_type =
|
||||
VcCursor::make_cursor(self.par[0], self.par[1], self.par[2])
|
||||
@ -784,7 +782,7 @@ impl VirtualConsoleData {
|
||||
}
|
||||
}
|
||||
'm' => {
|
||||
if self.private == Vt102_OP::EPdec {
|
||||
if self.private == Vt102_OP::Pdec {
|
||||
if self.par[0] != 0 {
|
||||
self.complement_mask = (self.par[0] << 8 | self.par[1]) as u16;
|
||||
} else {
|
||||
@ -794,7 +792,7 @@ impl VirtualConsoleData {
|
||||
}
|
||||
}
|
||||
'n' => {
|
||||
if self.private == Vt102_OP::EPecma {
|
||||
if self.private == Vt102_OP::Pecma {
|
||||
if self.par[0] == 5 {
|
||||
send_to_default_serial8250_port("tty status report todo".as_bytes());
|
||||
panic!();
|
||||
@ -808,8 +806,8 @@ impl VirtualConsoleData {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if self.private != Vt102_OP::EPecma {
|
||||
self.private = Vt102_OP::EPecma;
|
||||
if self.private != Vt102_OP::Pecma {
|
||||
self.private = Vt102_OP::Pecma;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -930,7 +928,7 @@ impl VirtualConsoleData {
|
||||
}
|
||||
'g' => {
|
||||
if self.par[0] == 0 && self.state.x < 256 {
|
||||
self.tab_stop.set(self.state.x as usize, true);
|
||||
self.tab_stop.set(self.state.x, true);
|
||||
} else if self.par[0] == 3 {
|
||||
self.tab_stop.set_all(false);
|
||||
}
|
||||
@ -994,12 +992,12 @@ impl VirtualConsoleData {
|
||||
|
||||
1 => {
|
||||
// 设置粗体
|
||||
self.state.intensity = VirtualConsoleIntensity::VciBold;
|
||||
self.state.intensity = VirtualConsoleIntensity::Bold;
|
||||
}
|
||||
|
||||
2 => {
|
||||
// 设置半亮度(半明显
|
||||
self.state.intensity = VirtualConsoleIntensity::VciHalfBright;
|
||||
self.state.intensity = VirtualConsoleIntensity::HalfBright;
|
||||
}
|
||||
|
||||
3 => {
|
||||
@ -1041,7 +1039,7 @@ impl VirtualConsoleData {
|
||||
|
||||
22 => {
|
||||
// 关闭粗体和半亮度,恢复正常亮度
|
||||
self.state.intensity = VirtualConsoleIntensity::VciNormal;
|
||||
self.state.intensity = VirtualConsoleIntensity::Normal;
|
||||
}
|
||||
|
||||
23 => {
|
||||
@ -1068,8 +1066,7 @@ impl VirtualConsoleData {
|
||||
// 设置前景色
|
||||
let (idx, color) = self.t416_color(i);
|
||||
i = idx;
|
||||
if color.is_some() {
|
||||
let color = color.unwrap();
|
||||
if let Some(color) = color {
|
||||
let mut max = color.red.max(color.green);
|
||||
max = max.max(color.blue);
|
||||
|
||||
@ -1086,11 +1083,11 @@ impl VirtualConsoleData {
|
||||
|
||||
if hue == 7 && max <= 0x55 {
|
||||
hue = 0;
|
||||
self.state.intensity = VirtualConsoleIntensity::VciBold;
|
||||
self.state.intensity = VirtualConsoleIntensity::Bold;
|
||||
} else if max > 0xaa {
|
||||
self.state.intensity = VirtualConsoleIntensity::VciBold;
|
||||
self.state.intensity = VirtualConsoleIntensity::Bold;
|
||||
} else {
|
||||
self.state.intensity = VirtualConsoleIntensity::VciNormal;
|
||||
self.state.intensity = VirtualConsoleIntensity::Normal;
|
||||
}
|
||||
|
||||
self.state.color = (self.state.color & 0xf0) | hue;
|
||||
@ -1101,8 +1098,7 @@ impl VirtualConsoleData {
|
||||
// 设置背景色
|
||||
let (idx, color) = self.t416_color(i);
|
||||
i = idx;
|
||||
if color.is_some() {
|
||||
let color = color.unwrap();
|
||||
if let Some(color) = color {
|
||||
self.state.color = (self.state.color & 0x0f)
|
||||
| ((color.red as u8 & 0x80) >> 1)
|
||||
| ((color.green as u8 & 0x80) >> 2)
|
||||
@ -1123,7 +1119,7 @@ impl VirtualConsoleData {
|
||||
_ => {
|
||||
if self.par[i] >= 90 && self.par[i] <= 107 {
|
||||
if self.par[i] < 100 {
|
||||
self.state.intensity = VirtualConsoleIntensity::VciBold;
|
||||
self.state.intensity = VirtualConsoleIntensity::Bold;
|
||||
}
|
||||
self.par[i] -= 60;
|
||||
}
|
||||
@ -1241,16 +1237,18 @@ impl VirtualConsoleData {
|
||||
return (idx, None);
|
||||
}
|
||||
|
||||
if self.par[idx] == 5 && idx + 1 <= self.npar as usize {
|
||||
if self.par[idx] == 5 && idx < self.npar as usize {
|
||||
// 256色
|
||||
idx += 1;
|
||||
return (idx, Some(Color::from_256(self.par[idx])));
|
||||
} else if self.par[idx] == 2 && idx + 3 <= self.npar as usize {
|
||||
// 24位
|
||||
let mut color = Color::default();
|
||||
color.red = self.par[idx + 1] as u16;
|
||||
color.green = self.par[idx + 2] as u16;
|
||||
color.blue = self.par[idx + 3] as u16;
|
||||
let color = Color {
|
||||
red: self.par[idx + 1] as u16,
|
||||
green: self.par[idx + 2] as u16,
|
||||
blue: self.par[idx + 3] as u16,
|
||||
..Default::default()
|
||||
};
|
||||
idx += 3;
|
||||
return (idx, Some(color));
|
||||
} else {
|
||||
@ -1262,7 +1260,7 @@ impl VirtualConsoleData {
|
||||
#[inline(never)]
|
||||
pub(super) fn do_control(&mut self, ch: u32) {
|
||||
// 首先检查是否处于 ANSI 控制字符串状态
|
||||
if self.vc_state.is_ansi_control_string() && ch >= 8 && ch <= 13 {
|
||||
if self.vc_state.is_ansi_control_string() && (8..=13).contains(&ch) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1289,17 +1287,17 @@ impl VirtualConsoleData {
|
||||
|
||||
let ret = self.tab_stop.next_index(self.state.x + 1);
|
||||
|
||||
if ret.is_none() {
|
||||
self.state.x = self.cols - 1;
|
||||
if let Some(x) = ret {
|
||||
self.state.x = x;
|
||||
} else {
|
||||
self.state.x = ret.unwrap();
|
||||
self.state.x = self.cols - 1;
|
||||
}
|
||||
|
||||
self.pos += self.state.x;
|
||||
// TODO: notify
|
||||
return;
|
||||
}
|
||||
10 | 11 | 12 => {
|
||||
10..=12 => {
|
||||
// LD line feed
|
||||
self.line_feed();
|
||||
// TODO: 检查键盘模式
|
||||
@ -1416,25 +1414,25 @@ impl VirtualConsoleData {
|
||||
|
||||
match c {
|
||||
'?' => {
|
||||
self.private = Vt102_OP::EPdec;
|
||||
self.private = Vt102_OP::Pdec;
|
||||
return;
|
||||
}
|
||||
'>' => {
|
||||
self.private = Vt102_OP::EPgt;
|
||||
self.private = Vt102_OP::Pgt;
|
||||
return;
|
||||
}
|
||||
'=' => {
|
||||
self.private = Vt102_OP::EPeq;
|
||||
self.private = Vt102_OP::Peq;
|
||||
return;
|
||||
}
|
||||
'<' => {
|
||||
self.private = Vt102_OP::EPlt;
|
||||
self.private = Vt102_OP::Plt;
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
self.private = Vt102_OP::EPecma;
|
||||
self.private = Vt102_OP::Pecma;
|
||||
self.do_getpars(c);
|
||||
}
|
||||
VirtualConsoleState::ESgetpars => {
|
||||
@ -1478,7 +1476,7 @@ impl VirtualConsoleData {
|
||||
return;
|
||||
}
|
||||
VirtualConsoleState::EScsiignore => {
|
||||
if ch >= 20 && ch <= 0x3f {
|
||||
if (20..=0x3f).contains(&ch) {
|
||||
return;
|
||||
}
|
||||
self.vc_state = VirtualConsoleState::ESnormal;
|
||||
@ -1496,7 +1494,7 @@ impl VirtualConsoleData {
|
||||
} else if c == 'R' {
|
||||
self.reset_palette();
|
||||
self.vc_state = VirtualConsoleState::ESnormal;
|
||||
} else if c >= '0' && c <= '9' {
|
||||
} else if c.is_ascii_digit() {
|
||||
self.vc_state = VirtualConsoleState::ESosc;
|
||||
} else {
|
||||
self.vc_state = VirtualConsoleState::ESnormal;
|
||||
@ -1504,7 +1502,7 @@ impl VirtualConsoleData {
|
||||
}
|
||||
VirtualConsoleState::ESpalette => {
|
||||
let c = ch as u8 as char;
|
||||
if c.is_digit(16) {
|
||||
if c.is_ascii_hexdigit() {
|
||||
self.npar += 1;
|
||||
self.par[self.npar as usize] = c.to_digit(16).unwrap();
|
||||
|
||||
@ -1549,10 +1547,8 @@ impl VirtualConsoleData {
|
||||
let mut width = 1;
|
||||
// 表示需不需要反转
|
||||
let mut invert = false;
|
||||
if self.utf && !self.display_ctrl {
|
||||
if FontDesc::is_double_width(c) {
|
||||
width = 2;
|
||||
}
|
||||
if self.utf && !self.display_ctrl && FontDesc::is_double_width(c) {
|
||||
width = 2;
|
||||
}
|
||||
|
||||
let tmp = self.unicode_to_index(tc);
|
||||
@ -1597,7 +1593,7 @@ impl VirtualConsoleData {
|
||||
// TODO: 处理unicode screen buf
|
||||
|
||||
if himask != 0 {
|
||||
tc = ((if tc & 0x100 != 0 { himask as u32 } else { 0 }) | (tc & 0xff)) as u32;
|
||||
tc = (if tc & 0x100 != 0 { himask as u32 } else { 0 }) | (tc & 0xff);
|
||||
}
|
||||
|
||||
tc |= ((attr as u32) << 8) & (!himask as u32);
|
||||
@ -1665,12 +1661,11 @@ impl VirtualConsoleData {
|
||||
/// ## 更新虚拟控制台指定区域的显示
|
||||
fn do_update_region(&self, mut start: usize, mut count: usize) {
|
||||
let ret = self.driver_funcs().con_getxy(self, start);
|
||||
let (mut x, mut y) = if ret.is_err() {
|
||||
(start % self.cols, start / self.cols)
|
||||
} else {
|
||||
let (_, tmp_x, tmp_y) = ret.unwrap();
|
||||
let (mut x, mut y) = if let Ok((_, tmp_x, tmp_y)) = ret {
|
||||
// start = tmp_start;
|
||||
(tmp_x, tmp_y)
|
||||
} else {
|
||||
(start % self.cols, start / self.cols)
|
||||
};
|
||||
|
||||
loop {
|
||||
@ -1681,20 +1676,18 @@ impl VirtualConsoleData {
|
||||
|
||||
while count != 0 && x < self.cols {
|
||||
// 检查属性是否变化,如果属性变了,则将前一个字符先输出
|
||||
if attr != (self.screen_buf[start] & 0xff00) {
|
||||
if size > 0 {
|
||||
let _ = self.driver_funcs().con_putcs(
|
||||
self,
|
||||
&self.screen_buf[start..],
|
||||
size,
|
||||
y as u32,
|
||||
startx as u32,
|
||||
);
|
||||
startx = x;
|
||||
start += size;
|
||||
size = 0;
|
||||
attr = self.screen_buf[start] & 0xff00;
|
||||
}
|
||||
if attr != (self.screen_buf[start] & 0xff00) && size > 0 {
|
||||
let _ = self.driver_funcs().con_putcs(
|
||||
self,
|
||||
&self.screen_buf[start..],
|
||||
size,
|
||||
y as u32,
|
||||
startx as u32,
|
||||
);
|
||||
startx = x;
|
||||
start += size;
|
||||
size = 0;
|
||||
attr = self.screen_buf[start] & 0xff00;
|
||||
}
|
||||
size += 1;
|
||||
x += 1;
|
||||
@ -1719,8 +1712,8 @@ impl VirtualConsoleData {
|
||||
y += 1;
|
||||
|
||||
let ret = self.driver_funcs().con_getxy(self, start);
|
||||
if ret.is_ok() {
|
||||
start = ret.unwrap().0;
|
||||
if let Ok(ret) = ret {
|
||||
start = ret.0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -1738,7 +1731,7 @@ impl VirtualConsoleData {
|
||||
} else if ch < 0x20 {
|
||||
// 不可打印
|
||||
return -1;
|
||||
} else if ch == 0xfeff || (ch >= 0x200b && ch <= 0x200f) {
|
||||
} else if ch == 0xfeff || (0x200b..=0x200f).contains(&ch) {
|
||||
// 零长空格
|
||||
return -2;
|
||||
} else if (ch & !Self::UNI_DIRECT_MAKS) == Self::UNI_DIRECT_BASE {
|
||||
@ -1771,7 +1764,7 @@ impl VirtualConsoleData {
|
||||
&self.screen_buf[draw.offset..draw.offset + draw.size],
|
||||
draw.size,
|
||||
self.state.y as u32,
|
||||
draw.x.unwrap() as u32,
|
||||
draw.x.unwrap(),
|
||||
);
|
||||
|
||||
draw.x = None;
|
||||
@ -1791,8 +1784,8 @@ impl VirtualConsoleData {
|
||||
.driver_funcs()
|
||||
.con_build_attr(self, color, intensity, blink, underline, reverse, italic);
|
||||
|
||||
if ret.is_ok() {
|
||||
return ret.unwrap();
|
||||
if let Ok(ret) = ret {
|
||||
return ret;
|
||||
}
|
||||
|
||||
let mut ret = color;
|
||||
@ -1809,7 +1802,7 @@ impl VirtualConsoleData {
|
||||
ret = (ret & 0xf0) | self.italic_color as u8;
|
||||
} else if underline {
|
||||
ret = (ret & 0xf0) | self.underline_color as u8;
|
||||
} else if intensity == VirtualConsoleIntensity::VciHalfBright {
|
||||
} else if intensity == VirtualConsoleIntensity::HalfBright {
|
||||
ret = (ret & 0xf0) | self.half_color as u8;
|
||||
}
|
||||
|
||||
@ -1821,7 +1814,7 @@ impl VirtualConsoleData {
|
||||
ret ^= 0x80;
|
||||
}
|
||||
|
||||
if intensity == VirtualConsoleIntensity::VciBold {
|
||||
if intensity == VirtualConsoleIntensity::Bold {
|
||||
ret ^= 0x08;
|
||||
}
|
||||
|
||||
@ -1845,7 +1838,7 @@ impl VirtualConsoleData {
|
||||
self.erase_char = ' ' as u16
|
||||
| ((self.build_attr(
|
||||
self.state.color,
|
||||
VirtualConsoleIntensity::VciNormal,
|
||||
VirtualConsoleIntensity::Normal,
|
||||
self.state.blink,
|
||||
false,
|
||||
self.screen_mode,
|
||||
@ -1855,7 +1848,7 @@ impl VirtualConsoleData {
|
||||
}
|
||||
|
||||
fn default_attr(&mut self) {
|
||||
self.state.intensity = VirtualConsoleIntensity::VciNormal;
|
||||
self.state.intensity = VirtualConsoleIntensity::Normal;
|
||||
self.state.italic = false;
|
||||
self.state.underline = false;
|
||||
self.state.reverse = false;
|
||||
@ -1903,16 +1896,16 @@ impl VirtualConsoleInfo {
|
||||
#[derive(Debug, Clone, PartialEq, Copy)]
|
||||
pub enum VirtualConsoleIntensity {
|
||||
/// 暗淡
|
||||
VciHalfBright = 0,
|
||||
HalfBright = 0,
|
||||
/// 正常
|
||||
VciNormal = 1,
|
||||
Normal = 1,
|
||||
/// 粗体
|
||||
VciBold = 2,
|
||||
Bold = 2,
|
||||
}
|
||||
|
||||
impl Default for VirtualConsoleIntensity {
|
||||
fn default() -> Self {
|
||||
Self::VciNormal
|
||||
Self::Normal
|
||||
}
|
||||
}
|
||||
|
||||
@ -1972,11 +1965,11 @@ impl VirtualConsoleState {
|
||||
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Vt102_OP {
|
||||
EPecma,
|
||||
EPdec,
|
||||
EPeq,
|
||||
EPgt,
|
||||
EPlt,
|
||||
Pecma,
|
||||
Pdec,
|
||||
Peq,
|
||||
Pgt,
|
||||
Plt,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
|
@ -81,10 +81,10 @@ impl BlittingFbConsole {
|
||||
其中颜色0映射为黑色,颜色1到6映射为白色,
|
||||
颜色7到8映射为灰色,其他颜色映射为强烈的白色。
|
||||
*/
|
||||
if color >= 1 && color <= 6 {
|
||||
if (1..=6).contains(&color) {
|
||||
// 白色
|
||||
color = 2;
|
||||
} else if color >= 7 && color <= 8 {
|
||||
} else if (7..=8).contains(&color) {
|
||||
// 灰色
|
||||
color = 1;
|
||||
} else {
|
||||
@ -138,17 +138,16 @@ impl BlittingFbConsole {
|
||||
let byte_width = vc_data.font.width as usize / 8;
|
||||
let font_height = vc_data.font.height as usize;
|
||||
// let mut char_offset = 0;
|
||||
for char_offset in 0..cnt as usize {
|
||||
for (char_offset, char_item) in buf.iter().enumerate().take(cnt as usize) {
|
||||
// 在字符表中的index
|
||||
let ch = buf[char_offset] & charmask;
|
||||
let ch = char_item & charmask;
|
||||
// 计算出在font表中的偏移量
|
||||
let font_offset = ch as usize * cellsize as usize;
|
||||
let font_offset_end = font_offset + cellsize as usize;
|
||||
// 设置image的data
|
||||
|
||||
let src = &vc_data.font.data[font_offset..font_offset_end];
|
||||
let mut dst = Vec::new();
|
||||
dst.resize(src.len(), 0);
|
||||
let mut dst = vec![0; src.len()];
|
||||
dst.copy_from_slice(src);
|
||||
|
||||
if !attr.is_empty() {
|
||||
@ -255,18 +254,18 @@ impl ConsoleSwitch for BlittingFbConsole {
|
||||
}
|
||||
|
||||
let y_break = (fb_data.display.virt_rows - fb_data.display.yscroll) as usize;
|
||||
if sy < y_break && sy + height - 1 >= y_break {
|
||||
if sy < y_break && sy + height > y_break {
|
||||
// 分两次clear
|
||||
let b = y_break - sy;
|
||||
let _ = self.clear(
|
||||
&vc_data,
|
||||
vc_data,
|
||||
fb_data.display.real_y(sy as u32),
|
||||
sx as u32,
|
||||
b as u32,
|
||||
width as u32,
|
||||
);
|
||||
let _ = self.clear(
|
||||
&vc_data,
|
||||
vc_data,
|
||||
fb_data.display.real_y((sy + b) as u32),
|
||||
sx as u32,
|
||||
(height - b) as u32,
|
||||
@ -274,7 +273,7 @@ impl ConsoleSwitch for BlittingFbConsole {
|
||||
);
|
||||
} else {
|
||||
let _ = self.clear(
|
||||
&vc_data,
|
||||
vc_data,
|
||||
fb_data.display.real_y(sy as u32),
|
||||
sx as u32,
|
||||
height as u32,
|
||||
@ -337,6 +336,7 @@ impl ConsoleSwitch for BlittingFbConsole {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
fn con_cursor(
|
||||
&self,
|
||||
vc_data: &VirtualConsoleData,
|
||||
@ -671,7 +671,7 @@ impl FrameBufferConsole for BlittingFbConsole {
|
||||
let attr = FbConAttr::get_attr(c, fb_info.color_depth());
|
||||
let char_offset = (c as usize & charmask) * ((w * vc_data.font.height) as usize);
|
||||
|
||||
if fbcon_data.cursor_state.image.data != &vc_data.font.data[char_offset..]
|
||||
if fbcon_data.cursor_state.image.data != vc_data.font.data[char_offset..]
|
||||
|| fbcon_data.cursor_reset
|
||||
{
|
||||
fbcon_data.cursor_state.image.data = vc_data.font.data[char_offset..].to_vec();
|
||||
|
@ -367,6 +367,7 @@ pub trait FrameBufferConsole {
|
||||
/// ### dx: 目标位置的x坐标
|
||||
/// ### height: 位图高度
|
||||
/// ### width: 位图宽度
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn bmove(
|
||||
&self,
|
||||
vc_data: &VirtualConsoleData,
|
||||
@ -401,6 +402,7 @@ pub trait FrameBufferConsole {
|
||||
/// ### x: 起始位置的x坐标、
|
||||
/// ### fg: 前景色
|
||||
/// ### bg: 背景色
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn put_string(
|
||||
&self,
|
||||
vc_data: &VirtualConsoleData,
|
||||
|
@ -10,14 +10,14 @@ use crate::{
|
||||
|
||||
use self::fbmem::{FbDevice, FrameBufferManager};
|
||||
|
||||
const COLOR_TABLE_8: &'static [u32] = &[
|
||||
const COLOR_TABLE_8: &[u32] = &[
|
||||
0x00000000, 0xff000000, 0x00ff0000, 0xffff0000, 0x0000ff00, 0xff00ff00, 0x00ffff00, 0xffffff00,
|
||||
0x000000ff, 0xff0000ff, 0x00ff00ff, 0xffff00ff, 0x0000ffff, 0xff00ffff, 0x00ffffff, 0xffffffff,
|
||||
];
|
||||
|
||||
const COLOR_TABLE_16: &'static [u32] = &[0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff];
|
||||
const COLOR_TABLE_16: &[u32] = &[0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff];
|
||||
|
||||
const COLOR_TABLE_32: &'static [u32] = &[0x00000000, 0xffffffff];
|
||||
const COLOR_TABLE_32: &[u32] = &[0x00000000, 0xffffffff];
|
||||
|
||||
pub mod fbcon;
|
||||
pub mod fbmem;
|
||||
@ -80,7 +80,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
return;
|
||||
}
|
||||
let mut dst1 = dst1.unwrap();
|
||||
dst1 = dst1 + VirtAddr::new(bitstart as usize);
|
||||
dst1 += VirtAddr::new(bitstart as usize);
|
||||
|
||||
let _ = self.fb_sync();
|
||||
|
||||
@ -102,8 +102,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
&& start_index == 0
|
||||
&& pitch_index == 0
|
||||
&& image.width & (32 / bit_per_pixel - 1) == 0
|
||||
&& bit_per_pixel >= 8
|
||||
&& bit_per_pixel <= 32
|
||||
&& (8..=32).contains(&bit_per_pixel)
|
||||
{
|
||||
unsafe { self.fast_imageblit(image, dst1, fg, bg) }
|
||||
} else {
|
||||
@ -126,23 +125,16 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
let mut bgx = bg;
|
||||
let ppw = 32 / bpp;
|
||||
let spitch = (image.width + 7) / 8;
|
||||
let tab: &[u32];
|
||||
let mut color_tab: [u32; 16] = [0; 16];
|
||||
|
||||
match bpp {
|
||||
8 => {
|
||||
tab = COLOR_TABLE_8;
|
||||
}
|
||||
16 => {
|
||||
tab = COLOR_TABLE_16;
|
||||
}
|
||||
32 => {
|
||||
tab = COLOR_TABLE_32;
|
||||
}
|
||||
let tab: &[u32] = match bpp {
|
||||
8 => COLOR_TABLE_8,
|
||||
16 => COLOR_TABLE_16,
|
||||
32 => COLOR_TABLE_32,
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for _ in (0..(ppw - 1)).rev() {
|
||||
fgx <<= bpp;
|
||||
@ -175,7 +167,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
while j >= 2 {
|
||||
*dst = color_tab[(image.data[src] as usize >> 4) & bitmask];
|
||||
dst = dst.add(1);
|
||||
*dst = color_tab[(image.data[src] as usize >> 0) & bitmask];
|
||||
*dst = color_tab[(image.data[src] as usize) & bitmask];
|
||||
dst = dst.add(1);
|
||||
j -= 2;
|
||||
src += 1;
|
||||
@ -191,7 +183,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
dst = dst.add(1);
|
||||
*dst = color_tab[(image.data[src] as usize >> 2) & bitmask];
|
||||
dst = dst.add(1);
|
||||
*dst = color_tab[(image.data[src] as usize >> 0) & bitmask];
|
||||
*dst = color_tab[(image.data[src] as usize) & bitmask];
|
||||
dst = dst.add(1);
|
||||
src += 1;
|
||||
j -= 4;
|
||||
@ -215,7 +207,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
dst = dst.add(1);
|
||||
*dst = color_tab[(image.data[src] as usize >> 1) & bitmask];
|
||||
dst = dst.add(1);
|
||||
*dst = color_tab[(image.data[src] as usize >> 0) & bitmask];
|
||||
*dst = color_tab[(image.data[src] as usize) & bitmask];
|
||||
dst = dst.add(1);
|
||||
src += 1;
|
||||
j -= 8;
|
||||
@ -224,6 +216,11 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
/*
|
||||
* For image widths that are not a multiple of 8, there
|
||||
* are trailing pixels left on the current line. Print
|
||||
* them as well.
|
||||
*/
|
||||
while j != 0 {
|
||||
shift -= ppw;
|
||||
*dst = color_tab[(image.data[src] as usize >> shift) & bitmask];
|
||||
@ -232,6 +229,7 @@ pub trait FrameBuffer: FrameBufferInfo + FrameBufferOps + Device {
|
||||
shift = 8;
|
||||
src += 1;
|
||||
}
|
||||
j -= 1;
|
||||
}
|
||||
|
||||
dst1 += VirtAddr::new(self.current_fb_fix().line_length as usize);
|
||||
@ -441,7 +439,7 @@ pub trait FrameBufferOps {
|
||||
}
|
||||
}
|
||||
|
||||
let _ = self.fb_image_blit(&image);
|
||||
self.fb_image_blit(&image);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -660,22 +658,17 @@ impl Default for FbVarScreenInfo {
|
||||
///
|
||||
/// 默认为彩色
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub enum FbColorMode {
|
||||
/// 灰度
|
||||
GrayScale,
|
||||
/// 彩色
|
||||
#[default]
|
||||
Color,
|
||||
/// FOURCC
|
||||
FourCC,
|
||||
}
|
||||
|
||||
impl Default for FbColorMode {
|
||||
fn default() -> Self {
|
||||
FbColorMode::Color
|
||||
}
|
||||
}
|
||||
|
||||
/// `FbBitfield` 结构体用于描述颜色字段的位域。
|
||||
///
|
||||
/// 所有的偏移量都是从右边开始,位于一个精确为'bits_per_pixel'宽度的"像素"值内。
|
||||
@ -684,7 +677,7 @@ impl Default for FbColorMode {
|
||||
/// 对于伪颜色:所有颜色组件的偏移和长度应该相同。
|
||||
/// 偏移指定了调色板索引在像素值中的最低有效位的位置。
|
||||
/// 长度表示可用的调色板条目的数量(即条目数 = 1 << 长度)。
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub struct FbBitfield {
|
||||
/// 位域的起始位置
|
||||
pub offset: u32,
|
||||
@ -705,16 +698,6 @@ impl FbBitfield {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FbBitfield {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
offset: Default::default(),
|
||||
length: Default::default(),
|
||||
msb_right: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// `FbActivateFlags` 用于描述帧缓冲区的激活标志。
|
||||
///
|
||||
@ -750,8 +733,9 @@ impl Default for FbActivateFlags {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub enum FbPixelFormat {
|
||||
#[default]
|
||||
Standard,
|
||||
/// Hold And Modify
|
||||
HAM,
|
||||
@ -759,12 +743,6 @@ pub enum FbPixelFormat {
|
||||
Reserved,
|
||||
}
|
||||
|
||||
impl Default for FbPixelFormat {
|
||||
fn default() -> Self {
|
||||
FbPixelFormat::Standard
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
pub struct FbSyncFlags: u32 {
|
||||
/// 水平同步高电平有效
|
||||
@ -806,9 +784,10 @@ bitflags! {
|
||||
|
||||
/// 视频颜色空间
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub enum V4l2Colorspace {
|
||||
/// 默认颜色空间,即让驱动程序自行判断。只能用于视频捕获。
|
||||
#[default]
|
||||
Default = 0,
|
||||
/// SMPTE 170M:用于广播NTSC/PAL SDTV
|
||||
Smpte170m = 1,
|
||||
@ -840,12 +819,6 @@ pub enum V4l2Colorspace {
|
||||
Last,
|
||||
}
|
||||
|
||||
impl Default for V4l2Colorspace {
|
||||
fn default() -> Self {
|
||||
V4l2Colorspace::Default
|
||||
}
|
||||
}
|
||||
|
||||
/// `FixedScreenInfo` 结构体用于描述屏幕的固定属性。
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
@ -964,19 +937,14 @@ pub enum FbVisual {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub enum FbCapability {
|
||||
#[default]
|
||||
Default = 0,
|
||||
/// 设备支持基于FOURCC的格式。
|
||||
FourCC,
|
||||
}
|
||||
|
||||
impl Default for FbCapability {
|
||||
fn default() -> Self {
|
||||
FbCapability::Default
|
||||
}
|
||||
}
|
||||
|
||||
/// 视频模式
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
@ -1012,9 +980,10 @@ pub struct FbVideoMode {
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
||||
pub enum FbAccel {
|
||||
/// 没有硬件加速器
|
||||
#[default]
|
||||
None,
|
||||
|
||||
AtariBlitter = 1,
|
||||
@ -1078,12 +1047,6 @@ pub enum FbAccel {
|
||||
// Add other accelerators here
|
||||
}
|
||||
|
||||
impl Default for FbAccel {
|
||||
fn default() -> Self {
|
||||
FbAccel::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct BootTimeScreenInfo {
|
||||
pub origin_x: u8,
|
||||
|
@ -390,14 +390,14 @@ impl FrameBufferOps for VesaFb {
|
||||
.screen_info
|
||||
.lfb_virt_base
|
||||
.ok_or(SystemError::ENODEV)?;
|
||||
let fg;
|
||||
if self.current_fb_fix().visual == FbVisual::TrueColor
|
||||
|
||||
let fg = if self.current_fb_fix().visual == FbVisual::TrueColor
|
||||
|| self.current_fb_fix().visual == FbVisual::DirectColor
|
||||
{
|
||||
fg = self.fb_data.read().pesudo_palette[rect.color as usize];
|
||||
self.fb_data.read().pesudo_palette[rect.color as usize]
|
||||
} else {
|
||||
fg = rect.color;
|
||||
}
|
||||
rect.color
|
||||
};
|
||||
|
||||
let bpp = self.current_fb_var().bits_per_pixel;
|
||||
// 每行像素数
|
||||
@ -533,8 +533,7 @@ impl FrameBufferOps for VesaFb {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let mut tmp: Vec<u32> = Vec::with_capacity(size);
|
||||
tmp.resize(size, 0);
|
||||
let mut tmp: Vec<u32> = vec![0; size];
|
||||
let mut tmp_ptr = tmp.as_mut_ptr();
|
||||
|
||||
// 这里是一个可以优化的点,现在为了避免指针拷贝时覆盖,统一先拷贝进入buf再拷贝到dst
|
||||
@ -575,11 +574,11 @@ impl FrameBufferInfo for VesaFb {
|
||||
}
|
||||
|
||||
fn current_fb_var(&self) -> FbVarScreenInfo {
|
||||
VESAFB_DEFINED.read().clone()
|
||||
*VESAFB_DEFINED.read()
|
||||
}
|
||||
|
||||
fn current_fb_fix(&self) -> FixedScreenInfo {
|
||||
VESAFB_FIX_INFO.read().clone()
|
||||
*VESAFB_FIX_INFO.read()
|
||||
}
|
||||
|
||||
fn video_mode(&self) -> Option<&FbVideoMode> {
|
||||
|
@ -25,12 +25,12 @@ static mut __MAMAGER: Option<VideoRefreshManager> = None;
|
||||
|
||||
pub fn video_refresh_manager() -> &'static VideoRefreshManager {
|
||||
return unsafe {
|
||||
&__MAMAGER
|
||||
__MAMAGER
|
||||
.as_ref()
|
||||
.expect("Video refresh manager has not been initialized yet!")
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
///管理显示刷新变量的结构体
|
||||
pub struct VideoRefreshManager {
|
||||
device_buffer: RwLock<ScmBufferInfo>,
|
||||
@ -69,11 +69,7 @@ impl VideoRefreshManager {
|
||||
let res = self
|
||||
.running
|
||||
.compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst);
|
||||
if res.is_ok() {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,7 +148,7 @@ impl VideoRefreshManager {
|
||||
}
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
#[allow(dead_code)]
|
||||
pub fn refresh_target(&self) -> RwLockReadGuard<'_, Option<Arc<SpinLock<Box<[u32]>>>>> {
|
||||
let x = self.refresh_target.read();
|
||||
@ -244,6 +240,7 @@ impl TimerFunction for VideoRefreshExecutor {
|
||||
* @brief 交给定时器执行的任务,此方法不应手动调用
|
||||
* @return Ok(())
|
||||
*/
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn run(&mut self) -> Result<(), SystemError> {
|
||||
// 获得Manager
|
||||
let manager = video_refresh_manager();
|
||||
@ -276,7 +273,7 @@ impl TimerFunction for VideoRefreshExecutor {
|
||||
let refresh_target = refresh_target.unwrap();
|
||||
|
||||
if let ScmBuffer::DeviceBuffer(vaddr) = manager.device_buffer().buf {
|
||||
let p = vaddr.as_ptr() as *mut u8;
|
||||
let p: *mut u8 = vaddr.as_ptr();
|
||||
let mut target_guard = None;
|
||||
for _ in 0..2 {
|
||||
if let Ok(guard) = refresh_target.as_ref().unwrap().try_lock_irqsave() {
|
||||
|
@ -71,7 +71,7 @@ impl VirtIOIrqManager {
|
||||
|
||||
pub fn lookup_device(&self, dev_id: &Arc<DeviceId>) -> Option<Arc<dyn VirtIODevice>> {
|
||||
let map = self.map.read_irqsave();
|
||||
map.get(dev_id).map(|x| x.clone())
|
||||
map.get(dev_id).cloned()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ use super::base::device::DeviceId;
|
||||
|
||||
pub(super) mod irq;
|
||||
pub mod transport_pci;
|
||||
#[allow(clippy::module_inception)]
|
||||
pub mod virtio;
|
||||
pub mod virtio_impl;
|
||||
|
||||
|
@ -119,6 +119,7 @@ impl PciTransport {
|
||||
/// - `device` - The PCI device structure for the VirtIO device.
|
||||
/// - `irq_handler` - An optional handler for the device's interrupt. If `None`, a default
|
||||
/// handler `DefaultVirtioIrqHandler` will be used.
|
||||
#[allow(clippy::extra_unused_type_parameters)]
|
||||
pub fn new<H: Hal>(
|
||||
device: &mut PciDeviceStructureGeneralDevice,
|
||||
dev_id: Arc<DeviceId>,
|
||||
|
@ -59,7 +59,7 @@ unsafe impl Hal for HalImpl {
|
||||
);
|
||||
|
||||
// 恢复页面属性
|
||||
let vaddr = VirtAddr::new(vaddr.as_ptr() as *mut u8 as usize);
|
||||
let vaddr = VirtAddr::new(vaddr.as_ptr() as usize);
|
||||
let mut kernel_mapper = KernelMapper::lock();
|
||||
let kernel_mapper = kernel_mapper.as_mut().unwrap();
|
||||
let flusher = kernel_mapper
|
||||
|
@ -104,7 +104,7 @@ impl IrqFlowHandler for EdgeIrqHandler {
|
||||
.contains(IrqDescState::IRQS_PENDING)
|
||||
{
|
||||
let status = desc_inner_guard.common_data().status();
|
||||
if status.disabled() == false && status.masked() {
|
||||
if !status.disabled() && status.masked() {
|
||||
// kdebug!("re-enable irq");
|
||||
irq_manager().unmask_irq(&desc_inner_guard);
|
||||
}
|
||||
@ -124,10 +124,10 @@ impl IrqFlowHandler for EdgeIrqHandler {
|
||||
desc_inner_guard = irq_desc.inner();
|
||||
desc_inner_guard.common_data().clear_inprogress();
|
||||
|
||||
if !(desc_inner_guard
|
||||
if !desc_inner_guard
|
||||
.internal_state()
|
||||
.contains(IrqDescState::IRQS_PENDING)
|
||||
&& desc_inner_guard.common_data().disabled() == false)
|
||||
|| desc_inner_guard.common_data().disabled()
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -152,11 +152,11 @@ fn irq_may_run(desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) -> bool {
|
||||
pub(super) fn mask_ack_irq(irq_data: &Arc<IrqData>) {
|
||||
let chip = irq_data.chip_info_read_irqsave().chip();
|
||||
if chip.can_mask_ack() {
|
||||
chip.irq_mask_ack(&irq_data);
|
||||
chip.irq_mask_ack(irq_data);
|
||||
irq_data.common_data().set_masked();
|
||||
} else {
|
||||
irq_manager().mask_irq(irq_data);
|
||||
chip.irq_ack(&irq_data);
|
||||
chip.irq_ack(irq_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,13 +308,13 @@ pub struct IrqChipType {
|
||||
#[derive(Debug)]
|
||||
pub enum IrqChipSetMaskResult {
|
||||
/// core updates mask ok.
|
||||
SetMaskOk,
|
||||
Success,
|
||||
/// core updates mask ok. No change.
|
||||
SetMaskOkNoChange,
|
||||
NoChange,
|
||||
/// core updates mask ok. Done.(same as SetMaskOk)
|
||||
///
|
||||
/// 支持堆叠irq芯片的特殊代码, 表示跳过所有子irq芯片。
|
||||
SetMaskOkDone,
|
||||
Done,
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
@ -351,7 +351,7 @@ impl IrqManager {
|
||||
/// Acknowledge the parent interrupt
|
||||
#[allow(dead_code)]
|
||||
pub fn irq_chip_ack_parent(&self, irq_data: &Arc<IrqData>) {
|
||||
let parent_data = irq_data.parent_data().map(|p| p.upgrade()).flatten();
|
||||
let parent_data = irq_data.parent_data().and_then(|p| p.upgrade());
|
||||
|
||||
if let Some(parent_data) = parent_data {
|
||||
let parent_chip = parent_data.chip_info_read_irqsave().chip();
|
||||
@ -364,19 +364,15 @@ impl IrqManager {
|
||||
/// 遍历中断域的层次结构,并检查是否存在一个硬件重新触发函数。如果存在则调用它
|
||||
pub fn irq_chip_retrigger_hierarchy(&self, irq_data: &Arc<IrqData>) -> Result<(), SystemError> {
|
||||
let mut data: Option<Arc<IrqData>> = Some(irq_data.clone());
|
||||
loop {
|
||||
if let Some(d) = data {
|
||||
if let Err(e) = d.chip_info_read_irqsave().chip().retrigger(&d) {
|
||||
if e == SystemError::ENOSYS {
|
||||
data = d.parent_data().map(|p| p.upgrade()).flatten();
|
||||
} else {
|
||||
return Err(e);
|
||||
}
|
||||
while let Some(d) = data {
|
||||
if let Err(e) = d.chip_info_read_irqsave().chip().retrigger(&d) {
|
||||
if e == SystemError::ENOSYS {
|
||||
data = d.parent_data().and_then(|p| p.upgrade());
|
||||
} else {
|
||||
return Ok(());
|
||||
return Err(e);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,7 +441,7 @@ impl IrqManager {
|
||||
}
|
||||
|
||||
// try the parent
|
||||
let parent_data = dt.parent_data().map(|p| p.upgrade()).flatten();
|
||||
let parent_data = dt.parent_data().and_then(|p| p.upgrade());
|
||||
|
||||
irq_data = parent_data;
|
||||
}
|
||||
@ -462,27 +458,27 @@ impl IrqManager {
|
||||
}
|
||||
}
|
||||
let handler = handler.unwrap();
|
||||
if core::ptr::eq(handler, bad_irq_handler()) {
|
||||
if Arc::ptr_eq(
|
||||
if handler.type_id() == bad_irq_handler().type_id()
|
||||
&& Arc::ptr_eq(
|
||||
&desc_inner.irq_data().chip_info_read_irqsave().chip(),
|
||||
&no_irq_chip(),
|
||||
) {
|
||||
let irq_data = desc_inner.irq_data();
|
||||
mask_ack_irq(irq_data);
|
||||
)
|
||||
{
|
||||
let irq_data = desc_inner.irq_data();
|
||||
mask_ack_irq(irq_data);
|
||||
|
||||
irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
|
||||
irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
|
||||
|
||||
if is_chained {
|
||||
desc_inner.clear_actions();
|
||||
}
|
||||
desc_inner.set_depth(1);
|
||||
if is_chained {
|
||||
desc_inner.clear_actions();
|
||||
}
|
||||
desc_inner.set_depth(1);
|
||||
}
|
||||
let chip = desc_inner.irq_data().chip_info_read_irqsave().chip();
|
||||
desc.set_handler_no_lock_inner(handler, desc_inner.irq_data(), &chip);
|
||||
desc_inner.set_name(name);
|
||||
|
||||
if !core::ptr::eq(handler, bad_irq_handler()) && is_chained {
|
||||
if handler.type_id() != bad_irq_handler().type_id() && is_chained {
|
||||
let trigger_type = desc_inner.common_data().trigger_type();
|
||||
|
||||
/*
|
||||
|
@ -331,6 +331,7 @@ pub trait IrqHandlerData: Send + Sync + Any + Debug + CastFromSync {}
|
||||
bitflags! {
|
||||
/// 中断线状态
|
||||
/// https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h?fi=IRQ_TYPE_PROBE#77
|
||||
#[allow(clippy::bad_bit_mask)]
|
||||
pub struct IrqLineStatus: u32 {
|
||||
/// 默认,未指明类型
|
||||
const IRQ_TYPE_NONE = 0x00000000;
|
||||
@ -420,10 +421,12 @@ impl IrqLineStatus {
|
||||
self.contains(Self::IRQ_PER_CPU_DEVID)
|
||||
}
|
||||
}
|
||||
|
||||
bitflags! {
|
||||
/// 中断状态(存储在IrqCommonData)
|
||||
///
|
||||
/// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irq.h#227
|
||||
#[allow(clippy::bad_bit_mask)]
|
||||
pub struct IrqStatus: u32 {
|
||||
const IRQD_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
|
||||
const IRQD_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
|
||||
@ -493,7 +496,7 @@ impl IrqStatus {
|
||||
}
|
||||
|
||||
pub const fn can_balance(&self) -> bool {
|
||||
!((self.bits & (Self::IRQD_PER_CPU.bits | Self::IRQD_NO_BALANCING.bits)) != 0)
|
||||
(self.bits & (Self::IRQD_PER_CPU.bits | Self::IRQD_NO_BALANCING.bits)) == 0
|
||||
}
|
||||
|
||||
pub const fn affinity_was_set(&self) -> bool {
|
||||
|
@ -444,13 +444,12 @@ impl InnerIrqDesc {
|
||||
|
||||
/// 中断是否可以设置CPU亲和性
|
||||
pub fn can_set_affinity(&self) -> bool {
|
||||
if self.common_data.status().can_balance() == false
|
||||
|| self
|
||||
if !self.common_data.status().can_balance()
|
||||
|| !self
|
||||
.irq_data()
|
||||
.chip_info_read_irqsave()
|
||||
.chip()
|
||||
.can_set_affinity()
|
||||
== false
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -792,8 +791,10 @@ impl ThreadedHandlerFlags {
|
||||
}
|
||||
|
||||
// 定义IrqFlags位标志
|
||||
|
||||
bitflags! {
|
||||
/// 这些标志仅由内核在中断处理例程中使用。
|
||||
#[allow(clippy::bad_bit_mask)]
|
||||
pub struct IrqHandleFlags: u32 {
|
||||
|
||||
const IRQF_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
|
||||
@ -893,7 +894,7 @@ impl IrqDescManager {
|
||||
|
||||
/// 查找中断描述符
|
||||
pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
|
||||
self.irq_descs.get(&irq).map(|desc| desc.clone())
|
||||
self.irq_descs.get(&irq).cloned()
|
||||
}
|
||||
|
||||
/// 查找中断描述符并锁定总线(没有对irqdesc进行加锁)
|
||||
|
@ -198,7 +198,7 @@ impl IrqDomainManager {
|
||||
irq_data_guard.set_hwirq(hwirq);
|
||||
irq_data_guard.set_domain(Some(domain.clone()));
|
||||
drop(irq_data_guard);
|
||||
let r = domain.ops.map(&domain, hwirq, irq);
|
||||
let r = domain.ops.map(domain, hwirq, irq);
|
||||
if let Err(e) = r {
|
||||
if e != SystemError::ENOSYS {
|
||||
if e != SystemError::EPERM {
|
||||
@ -216,7 +216,7 @@ impl IrqDomainManager {
|
||||
domain.set_name(chip.name().to_string());
|
||||
}
|
||||
|
||||
self.irq_domain_set_mapping(&domain, hwirq, irq_data);
|
||||
self.irq_domain_set_mapping(domain, hwirq, irq_data);
|
||||
|
||||
irq_manager().irq_clear_status_flags(irq, IrqLineStatus::IRQ_NOREQUEST)?;
|
||||
|
||||
@ -249,7 +249,7 @@ impl IrqDomainManager {
|
||||
r = self.do_activate_irq(Some(irq_data.clone()), reserve);
|
||||
}
|
||||
|
||||
if !r.is_ok() {
|
||||
if r.is_err() {
|
||||
irq_data.common_data().status().set_activated();
|
||||
}
|
||||
|
||||
@ -264,21 +264,19 @@ impl IrqDomainManager {
|
||||
) -> Result<(), SystemError> {
|
||||
let mut r = Ok(());
|
||||
|
||||
if irq_data.is_some() && irq_data.as_ref().unwrap().domain().is_some() {
|
||||
let domain = irq_data.as_ref().unwrap().domain().unwrap();
|
||||
if let Some(irq_data) = irq_data {
|
||||
if let Some(domain) = irq_data.domain() {
|
||||
let parent_data = irq_data.parent_data().and_then(|x| x.upgrade());
|
||||
if let Some(parent_data) = parent_data.clone() {
|
||||
r = self.do_activate_irq(Some(parent_data), reserve);
|
||||
}
|
||||
|
||||
let irq_data = irq_data.unwrap();
|
||||
|
||||
let parent_data = irq_data.parent_data().map(|x| x.upgrade()).flatten();
|
||||
if let Some(parent_data) = parent_data.clone() {
|
||||
r = self.do_activate_irq(Some(parent_data), reserve);
|
||||
}
|
||||
|
||||
if r.is_err() {
|
||||
let tmpr = domain.ops.activate(&domain, &irq_data, reserve);
|
||||
if let Err(e) = tmpr {
|
||||
if e != SystemError::ENOSYS && parent_data.is_some() {
|
||||
self.do_deactivate_irq(parent_data);
|
||||
if r.is_err() {
|
||||
let tmpr = domain.ops.activate(&domain, &irq_data, reserve);
|
||||
if let Err(e) = tmpr {
|
||||
if e != SystemError::ENOSYS && parent_data.is_some() {
|
||||
self.do_deactivate_irq(parent_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -286,12 +284,12 @@ impl IrqDomainManager {
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#[allow(clippy::only_used_in_recursion)]
|
||||
fn do_deactivate_irq(&self, irq_data: Option<Arc<IrqData>>) {
|
||||
if let Some(irq_data) = irq_data {
|
||||
if let Some(domain) = irq_data.domain() {
|
||||
domain.ops.deactivate(&domain, &irq_data);
|
||||
let pp = irq_data.parent_data().map(|x| x.upgrade()).flatten();
|
||||
let pp = irq_data.parent_data().and_then(|x| x.upgrade());
|
||||
|
||||
if pp.is_some() {
|
||||
self.do_deactivate_irq(pp);
|
||||
@ -312,6 +310,7 @@ impl IrqDomainManager {
|
||||
/// - `handler`: 中断流处理器
|
||||
/// - `handler_data`: 中断流处理程序数据
|
||||
/// - `handler_name`: 中断处理程序名称
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn domain_set_info(
|
||||
&self,
|
||||
domain: &Arc<IrqDomain>,
|
||||
@ -385,7 +384,7 @@ impl IrqDomainManager {
|
||||
if dt.domain().is_some() && Arc::ptr_eq(dt.domain().as_ref().unwrap(), domain) {
|
||||
return Some(dt);
|
||||
}
|
||||
irq_data = dt.parent_data().map(|x| x.upgrade()).flatten();
|
||||
irq_data = dt.parent_data().and_then(|x| x.upgrade());
|
||||
}
|
||||
|
||||
return None;
|
||||
|
@ -251,10 +251,8 @@ impl IrqManager {
|
||||
}
|
||||
|
||||
action_guard.set_handler(Some(&IrqNestedPrimaryHandler));
|
||||
} else {
|
||||
if desc.can_thread() {
|
||||
self.setup_forced_threading(action_guard.deref_mut())?;
|
||||
}
|
||||
} else if desc.can_thread() {
|
||||
self.setup_forced_threading(action_guard.deref_mut())?;
|
||||
}
|
||||
|
||||
// 如果具有中断线程处理程序,并且中断不是嵌套的,则设置中断线程
|
||||
@ -322,7 +320,7 @@ impl IrqManager {
|
||||
|
||||
// 标记当前irq是否是共享的
|
||||
let mut irq_shared = false;
|
||||
if desc_inner_guard.actions().is_empty() == false {
|
||||
if !desc_inner_guard.actions().is_empty() {
|
||||
// 除非双方都同意并且是相同类型(级别、边沿、极性),否则不能共享中断。
|
||||
// 因此,两个标志字段都必须设置IRQF_SHARED,并且设置触发类型的位必须匹配。
|
||||
// 另外,所有各方都必须就ONESHOT达成一致。
|
||||
@ -364,11 +362,10 @@ impl IrqManager {
|
||||
let old = &desc_inner_guard.actions()[0].clone();
|
||||
let old_guard = old.inner();
|
||||
|
||||
if ((old_guard
|
||||
if (!(old_guard
|
||||
.flags()
|
||||
.intersection(*action_guard.flags())
|
||||
.contains(IrqHandleFlags::IRQF_SHARED))
|
||||
== false)
|
||||
.contains(IrqHandleFlags::IRQF_SHARED)))
|
||||
|| (old_trigger_type != (action_guard.flags().trigger_type()))
|
||||
|| ((old_guard.flags().bitxor(*action_guard.flags()))
|
||||
.contains(IrqHandleFlags::IRQF_ONESHOT))
|
||||
@ -402,13 +399,12 @@ impl IrqManager {
|
||||
// todo: oneshot
|
||||
} else if action_guard.handler().is_some_and(|h| {
|
||||
h.type_id() == (&DefaultPrimaryIrqHandler as &dyn IrqHandler).type_id()
|
||||
}) && desc_inner_guard
|
||||
}) && !desc_inner_guard
|
||||
.irq_data()
|
||||
.chip_info_read_irqsave()
|
||||
.chip()
|
||||
.flags()
|
||||
.contains(IrqChipFlags::IRQCHIP_ONESHOT_SAFE)
|
||||
== false
|
||||
{
|
||||
// 请求中断时 hander = NULL,因此我们为其使用默认的主处理程序。
|
||||
// 但它没有设置ONESHOT标志。与电平触发中断结合时,
|
||||
@ -510,15 +506,14 @@ impl IrqManager {
|
||||
// 共享中断可能在它仍然被禁用时请求它,然后永远等待中断。
|
||||
|
||||
static mut WARNED: bool = false;
|
||||
if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) {
|
||||
if unsafe { !WARNED } {
|
||||
kwarn!(
|
||||
"Shared interrupt {} for {} requested but not auto enabled",
|
||||
irq.data(),
|
||||
action_guard.name()
|
||||
);
|
||||
unsafe { WARNED = true };
|
||||
}
|
||||
if action_guard.flags().contains(IrqHandleFlags::IRQF_SHARED) && unsafe { !WARNED }
|
||||
{
|
||||
kwarn!(
|
||||
"Shared interrupt {} for {} requested but not auto enabled",
|
||||
irq.data(),
|
||||
action_guard.name()
|
||||
);
|
||||
unsafe { WARNED = true };
|
||||
}
|
||||
|
||||
desc_inner_guard.set_depth(1);
|
||||
@ -661,7 +656,7 @@ impl IrqManager {
|
||||
}
|
||||
}
|
||||
IrqStartupResult::Managed => {
|
||||
self.irq_do_set_affinity(&irq_data, &desc_inner_guard, &affinity, false)
|
||||
self.irq_do_set_affinity(&irq_data, desc_inner_guard, &affinity, false)
|
||||
.ok();
|
||||
ret = self.__irq_startup(desc_inner_guard);
|
||||
}
|
||||
@ -696,7 +691,7 @@ impl IrqManager {
|
||||
|
||||
let chip = desc_inner_guard.irq_data().chip_info_read_irqsave().chip();
|
||||
|
||||
if let Err(e) = chip.irq_enable(&desc_inner_guard.irq_data()) {
|
||||
if let Err(e) = chip.irq_enable(desc_inner_guard.irq_data()) {
|
||||
if e == SystemError::ENOSYS {
|
||||
self.unmask_irq(desc_inner_guard);
|
||||
}
|
||||
@ -744,7 +739,7 @@ impl IrqManager {
|
||||
|
||||
return self.irq_do_set_affinity(
|
||||
desc_inner_guard.irq_data(),
|
||||
&desc_inner_guard,
|
||||
desc_inner_guard,
|
||||
&to_set,
|
||||
false,
|
||||
);
|
||||
@ -765,22 +760,19 @@ impl IrqManager {
|
||||
// todo: 处理CPU中断隔离相关的逻辑
|
||||
|
||||
let common_data = desc_inner_guard.common_data();
|
||||
let r;
|
||||
if !force && !cpumask.is_empty() {
|
||||
r = chip.irq_set_affinity(irq_data, &cpumask, force);
|
||||
} else if force {
|
||||
r = chip.irq_set_affinity(irq_data, &cpumask, force);
|
||||
let r = if force || !cpumask.is_empty() {
|
||||
chip.irq_set_affinity(irq_data, cpumask, force)
|
||||
} else {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
};
|
||||
|
||||
let mut ret = Ok(());
|
||||
if let Ok(rs) = r {
|
||||
match rs {
|
||||
IrqChipSetMaskResult::SetMaskOk | IrqChipSetMaskResult::SetMaskOkDone => {
|
||||
IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
|
||||
common_data.set_affinity(cpumask.clone());
|
||||
}
|
||||
IrqChipSetMaskResult::SetMaskOkNoChange => {
|
||||
IrqChipSetMaskResult::NoChange => {
|
||||
|
||||
// irq_validate_effective_affinity(data);
|
||||
// irq_set_thread_affinity(desc);
|
||||
@ -900,10 +892,10 @@ impl IrqManager {
|
||||
}
|
||||
|
||||
if chip.flags().contains(IrqChipFlags::IRQCHIP_SET_TYPE_MASKED) {
|
||||
if desc_inner_guard.common_data().status().masked() == false {
|
||||
if !desc_inner_guard.common_data().status().masked() {
|
||||
self.mask_irq(desc_inner_guard.irq_data());
|
||||
}
|
||||
if desc_inner_guard.common_data().status().disabled() == false {
|
||||
if !desc_inner_guard.common_data().status().disabled() {
|
||||
to_unmask = true;
|
||||
}
|
||||
}
|
||||
@ -914,14 +906,14 @@ impl IrqManager {
|
||||
let ret;
|
||||
if let Ok(rs) = r {
|
||||
match rs {
|
||||
IrqChipSetMaskResult::SetMaskOk | IrqChipSetMaskResult::SetMaskOkDone => {
|
||||
IrqChipSetMaskResult::Success | IrqChipSetMaskResult::Done => {
|
||||
let common_data = desc_inner_guard.common_data();
|
||||
common_data.clear_status(IrqStatus::IRQD_TRIGGER_MASK);
|
||||
let mut irqstatus = IrqStatus::empty();
|
||||
irqstatus.set_trigger_type(trigger_type);
|
||||
common_data.insert_status(irqstatus);
|
||||
}
|
||||
IrqChipSetMaskResult::SetMaskOkNoChange => {
|
||||
IrqChipSetMaskResult::NoChange => {
|
||||
let flags = desc_inner_guard.common_data().trigger_type();
|
||||
desc_inner_guard.set_trigger_type(flags);
|
||||
desc_inner_guard
|
||||
@ -929,7 +921,7 @@ impl IrqManager {
|
||||
.clear_status(IrqStatus::IRQD_LEVEL);
|
||||
desc_inner_guard.clear_level();
|
||||
|
||||
if (flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() == false {
|
||||
if !(flags & IrqLineStatus::IRQ_TYPE_LEVEL_MASK).is_empty() {
|
||||
desc_inner_guard.set_level();
|
||||
desc_inner_guard
|
||||
.common_data()
|
||||
@ -1008,7 +1000,7 @@ impl IrqManager {
|
||||
|
||||
/// 解除屏蔽中断
|
||||
pub(super) fn unmask_irq(&self, desc_inner_guard: &SpinLockGuard<'_, InnerIrqDesc>) {
|
||||
if desc_inner_guard.common_data().status().masked() == false {
|
||||
if !desc_inner_guard.common_data().status().masked() {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1016,7 +1008,7 @@ impl IrqManager {
|
||||
.irq_data()
|
||||
.chip_info_read_irqsave()
|
||||
.chip()
|
||||
.irq_unmask(&desc_inner_guard.irq_data());
|
||||
.irq_unmask(desc_inner_guard.irq_data());
|
||||
|
||||
if let Err(e) = r {
|
||||
if e != SystemError::ENOSYS {
|
||||
|
@ -40,11 +40,10 @@ impl IrqManager {
|
||||
return Err(SystemError::EBUSY);
|
||||
}
|
||||
|
||||
if desc_inner_guard
|
||||
if !desc_inner_guard
|
||||
.internal_state()
|
||||
.contains(IrqDescState::IRQS_PENDING)
|
||||
== false
|
||||
&& inject == false
|
||||
&& !inject
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -305,8 +305,7 @@ impl Attribute for AttrActions {
|
||||
len += sysfs_emit_str(&mut buf[len..], &format!(",{}", action.inner().name()))
|
||||
.unwrap();
|
||||
} else {
|
||||
len +=
|
||||
sysfs_emit_str(&mut buf[len..], &format!("{}", action.inner().name())).unwrap();
|
||||
len += sysfs_emit_str(&mut buf[len..], &action.inner().name().to_string()).unwrap();
|
||||
}
|
||||
|
||||
if len >= buf.len() {
|
||||
|
@ -114,7 +114,7 @@ impl DevFS {
|
||||
match metadata.file_type {
|
||||
// 字节设备挂载在 /dev/char
|
||||
FileType::CharDevice => {
|
||||
if let Err(_) = dev_root_inode.find("char") {
|
||||
if dev_root_inode.find("char").is_err() {
|
||||
dev_root_inode.create(
|
||||
"char",
|
||||
FileType::Dir,
|
||||
@ -137,7 +137,7 @@ impl DevFS {
|
||||
device.set_fs(dev_char_inode.0.lock().fs.clone());
|
||||
}
|
||||
FileType::BlockDevice => {
|
||||
if let Err(_) = dev_root_inode.find("block") {
|
||||
if dev_root_inode.find("block").is_err() {
|
||||
dev_root_inode.create(
|
||||
"block",
|
||||
FileType::Dir,
|
||||
@ -182,7 +182,7 @@ impl DevFS {
|
||||
match device.metadata().unwrap().file_type {
|
||||
// 字节设备挂载在 /dev/char
|
||||
FileType::CharDevice => {
|
||||
if let Err(_) = dev_root_inode.find("char") {
|
||||
if dev_root_inode.find("char").is_err() {
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ impl DevFS {
|
||||
dev_char_inode.remove(name)?;
|
||||
}
|
||||
FileType::BlockDevice => {
|
||||
if let Err(_) = dev_root_inode.find("block") {
|
||||
if dev_root_inode.find("block").is_err() {
|
||||
return Err(SystemError::ENOENT);
|
||||
}
|
||||
|
||||
@ -247,7 +247,7 @@ impl DevFSInode {
|
||||
data_: usize,
|
||||
) -> Self {
|
||||
return DevFSInode {
|
||||
parent: parent,
|
||||
parent,
|
||||
self_ref: Weak::default(),
|
||||
children: BTreeMap::new(),
|
||||
metadata: Metadata {
|
||||
|
@ -115,8 +115,8 @@ impl IndexNode for LockedZeroInode {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
for i in 0..len {
|
||||
buf[i] = 0;
|
||||
for itr in buf.iter_mut().take(len) {
|
||||
*itr = 0;
|
||||
}
|
||||
|
||||
return Ok(len);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#![allow(dead_code)]
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use alloc::sync::Arc;
|
||||
use system_error::SystemError;
|
||||
|
||||
use crate::{
|
||||
@ -220,8 +220,7 @@ impl BiosParameterBlockFAT32 {
|
||||
|
||||
impl BiosParameterBlock {
|
||||
pub fn new(partition: Arc<Partition>) -> Result<BiosParameterBlock, SystemError> {
|
||||
let mut v = Vec::with_capacity(LBA_SIZE);
|
||||
v.resize(LBA_SIZE, 0);
|
||||
let mut v = vec![0; LBA_SIZE];
|
||||
|
||||
// 读取分区的引导扇区
|
||||
partition
|
||||
@ -248,19 +247,20 @@ impl BiosParameterBlock {
|
||||
bpb.hidden_sectors = cursor.read_u32()?;
|
||||
bpb.total_sectors_32 = cursor.read_u32()?;
|
||||
|
||||
let mut bpb32 = BiosParameterBlockFAT32::default();
|
||||
bpb32.fat_size_32 = cursor.read_u32()?;
|
||||
bpb32.ext_flags = cursor.read_u16()?;
|
||||
bpb32.fs_version = cursor.read_u16()?;
|
||||
bpb32.root_cluster = cursor.read_u32()?;
|
||||
bpb32.fs_info = cursor.read_u16()?;
|
||||
bpb32.backup_boot_sec = cursor.read_u16()?;
|
||||
|
||||
let mut bpb32 = BiosParameterBlockFAT32 {
|
||||
fat_size_32: cursor.read_u32()?,
|
||||
ext_flags: cursor.read_u16()?,
|
||||
fs_version: cursor.read_u16()?,
|
||||
root_cluster: cursor.read_u32()?,
|
||||
fs_info: cursor.read_u16()?,
|
||||
backup_boot_sec: cursor.read_u16()?,
|
||||
drive_num: cursor.read_u8()?,
|
||||
reserved1: cursor.read_u8()?,
|
||||
boot_sig: cursor.read_u8()?,
|
||||
volume_id: cursor.read_u32()?,
|
||||
..Default::default()
|
||||
};
|
||||
cursor.read_exact(&mut bpb32.reserved0)?;
|
||||
bpb32.drive_num = cursor.read_u8()?;
|
||||
bpb32.reserved1 = cursor.read_u8()?;
|
||||
bpb32.boot_sig = cursor.read_u8()?;
|
||||
bpb32.volume_id = cursor.read_u32()?;
|
||||
cursor.read_exact(&mut bpb32.volume_label)?;
|
||||
cursor.read_exact(&mut bpb32.filesystem_type)?;
|
||||
|
||||
|
@ -111,7 +111,7 @@ impl FATFile {
|
||||
loop {
|
||||
// 当前簇已经读取完,尝试读取下一个簇
|
||||
if in_cluster_offset >= fs.bytes_per_cluster() {
|
||||
if let Some(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster).ok() {
|
||||
if let Ok(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster) {
|
||||
current_cluster = c;
|
||||
in_cluster_offset %= fs.bytes_per_cluster();
|
||||
} else {
|
||||
@ -182,9 +182,9 @@ impl FATFile {
|
||||
// 循环写入数据
|
||||
loop {
|
||||
if in_cluster_bytes_offset >= fs.bytes_per_cluster() {
|
||||
if let Some(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster).ok() {
|
||||
if let Ok(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster) {
|
||||
current_cluster = c;
|
||||
in_cluster_bytes_offset = in_cluster_bytes_offset % fs.bytes_per_cluster();
|
||||
in_cluster_bytes_offset %= fs.bytes_per_cluster();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -388,7 +388,7 @@ impl FATDir {
|
||||
current_cluster: self.first_cluster,
|
||||
offset: self.root_offset.unwrap_or(0),
|
||||
is_root: self.is_root(),
|
||||
fs: fs,
|
||||
fs,
|
||||
};
|
||||
}
|
||||
|
||||
@ -425,10 +425,10 @@ impl FATDir {
|
||||
// 如果当前簇没有空间了,并且当前不是FAT12和FAT16的根目录,那么就读取下一个簇。
|
||||
if offset >= fs.bytes_per_cluster() && !self.is_root() {
|
||||
// 成功读取下一个簇
|
||||
if let Some(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster).ok() {
|
||||
if let Ok(FATEntry::Next(c)) = fs.get_fat_entry(current_cluster) {
|
||||
current_cluster = c;
|
||||
// 计算簇内偏移量
|
||||
offset = offset % fs.bytes_per_cluster();
|
||||
offset %= fs.bytes_per_cluster();
|
||||
} else {
|
||||
// 读取失败,当前已经是最后一个簇,退出循环
|
||||
break;
|
||||
@ -555,8 +555,7 @@ impl FATDir {
|
||||
let r: Result<FATDirEntryOrShortName, SystemError> =
|
||||
self.check_existence(name, Some(false), fs.clone());
|
||||
// 检查错误码,如果能够表明目录项已经存在,则返回-EEXIST
|
||||
if r.is_err() {
|
||||
let err_val = r.unwrap_err();
|
||||
if let Err(err_val) = r {
|
||||
if err_val == (SystemError::EISDIR) || err_val == (SystemError::ENOTDIR) {
|
||||
return Err(SystemError::EEXIST);
|
||||
} else {
|
||||
@ -595,8 +594,7 @@ impl FATDir {
|
||||
self.check_existence(name, Some(true), fs.clone());
|
||||
// kdebug!("check existence ok");
|
||||
// 检查错误码,如果能够表明目录项已经存在,则返回-EEXIST
|
||||
if r.is_err() {
|
||||
let err_val = r.unwrap_err();
|
||||
if let Err(err_val) = r {
|
||||
if err_val == (SystemError::EISDIR) || err_val == (SystemError::ENOTDIR) {
|
||||
return Err(SystemError::EEXIST);
|
||||
} else {
|
||||
@ -617,25 +615,29 @@ impl FATDir {
|
||||
// === 接下来在子目录中创建'.'目录项和'..'目录项
|
||||
let mut offset = 0;
|
||||
// '.'目录项
|
||||
let mut dot_entry = ShortDirEntry::default();
|
||||
dot_entry.name = ShortNameGenerator::new(".").generate().unwrap();
|
||||
dot_entry.attributes.value = FileAttributes::DIRECTORY;
|
||||
let mut dot_entry = ShortDirEntry {
|
||||
name: ShortNameGenerator::new(".").generate().unwrap(),
|
||||
attributes: FileAttributes::new(FileAttributes::DIRECTORY),
|
||||
..Default::default()
|
||||
};
|
||||
dot_entry.set_first_cluster(first_cluster);
|
||||
|
||||
// todo: 设置创建、访问时间
|
||||
dot_entry.flush(&fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
|
||||
dot_entry.flush(fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
|
||||
|
||||
// 偏移量加上一个目录项的长度
|
||||
offset += FATRawDirEntry::DIR_ENTRY_LEN;
|
||||
|
||||
// '..'目录项
|
||||
let mut dot_dot_entry = ShortDirEntry::default();
|
||||
dot_dot_entry.name = ShortNameGenerator::new("..").generate().unwrap();
|
||||
dot_dot_entry.attributes.value = FileAttributes::DIRECTORY;
|
||||
let mut dot_dot_entry = ShortDirEntry {
|
||||
name: ShortNameGenerator::new("..").generate().unwrap(),
|
||||
attributes: FileAttributes::new(FileAttributes::DIRECTORY),
|
||||
..Default::default()
|
||||
};
|
||||
dot_dot_entry.set_first_cluster(self.first_cluster);
|
||||
// todo: 设置创建、访问时间
|
||||
|
||||
dot_dot_entry.flush(&fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
|
||||
dot_dot_entry.flush(fs, fs.cluster_bytes_offset(first_cluster) + offset)?;
|
||||
|
||||
// kdebug!("to create dentries");
|
||||
// 在当前目录下创建目标目录项
|
||||
@ -720,8 +722,8 @@ impl FATDir {
|
||||
attrs: FileAttributes,
|
||||
fs: Arc<FATFileSystem>,
|
||||
) -> Result<FATDirEntry, SystemError> {
|
||||
let mut short_dentry: ShortDirEntry = short_dentry.unwrap_or(ShortDirEntry::default());
|
||||
short_dentry.name = short_name.clone();
|
||||
let mut short_dentry: ShortDirEntry = short_dentry.unwrap_or_default();
|
||||
short_dentry.name = *short_name;
|
||||
short_dentry.attributes = attrs;
|
||||
|
||||
// todo: 设置创建时间、修改时间
|
||||
@ -756,7 +758,9 @@ impl FATDir {
|
||||
let offset = fs.cluster_bytes_offset(end.0) + end.1;
|
||||
short_dentry.flush(&fs, offset)?;
|
||||
|
||||
return Ok(short_dentry.to_dir_entry_with_long_name(long_name.to_string(), (start, end)));
|
||||
return Ok(
|
||||
short_dentry.convert_to_dir_entry_with_long_name(long_name.to_string(), (start, end))
|
||||
);
|
||||
}
|
||||
|
||||
/// @brief 判断当前目录是否为空
|
||||
@ -1037,14 +1041,16 @@ impl LongDirEntry {
|
||||
///
|
||||
/// @return Self 初始化好的长目录项对象
|
||||
fn new(ord: u8, name_part: &[u16], check_sum: u8) -> Self {
|
||||
let mut result = LongDirEntry::default();
|
||||
result.ord = ord;
|
||||
let mut result = LongDirEntry {
|
||||
ord,
|
||||
file_attrs: FileAttributes::new(FileAttributes::LONG_NAME),
|
||||
dirent_type: 0,
|
||||
checksum: check_sum,
|
||||
..Default::default()
|
||||
};
|
||||
result
|
||||
.insert_name(name_part)
|
||||
.expect("Name part's len should be equal to 13.");
|
||||
result.file_attrs.value = FileAttributes::LONG_NAME;
|
||||
result.dirent_type = 0;
|
||||
result.checksum = check_sum;
|
||||
// 该字段需要外层的代码手动赋值
|
||||
result.first_clus_low = 0;
|
||||
return result;
|
||||
@ -1095,7 +1101,7 @@ impl LongDirEntry {
|
||||
name = name.trim();
|
||||
|
||||
// 名称不能为0
|
||||
if name.len() == 0 {
|
||||
if name.is_empty() {
|
||||
return Err(SystemError::EINVAL);
|
||||
}
|
||||
|
||||
@ -1133,11 +1139,10 @@ impl LongDirEntry {
|
||||
let lba = fs.get_lba_from_offset(
|
||||
fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)),
|
||||
);
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(1 * fs.lba_per_sector() * LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; fs.lba_per_sector() * LBA_SIZE];
|
||||
fs.partition
|
||||
.disk()
|
||||
.read_at(lba, 1 * fs.lba_per_sector(), &mut v)?;
|
||||
.read_at(lba, fs.lba_per_sector(), &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
// 切换游标到对应位置
|
||||
@ -1166,7 +1171,7 @@ impl LongDirEntry {
|
||||
// 把修改后的长目录项刷入磁盘
|
||||
fs.partition
|
||||
.disk()
|
||||
.write_at(lba, 1 * fs.lba_per_sector(), cursor.as_slice())?;
|
||||
.write_at(lba, fs.lba_per_sector(), cursor.as_slice())?;
|
||||
fs.partition.disk().sync()?;
|
||||
|
||||
return Ok(());
|
||||
@ -1174,7 +1179,7 @@ impl LongDirEntry {
|
||||
}
|
||||
|
||||
impl ShortDirEntry {
|
||||
const PADDING: u8 = ' ' as u8;
|
||||
const PADDING: u8 = b' ';
|
||||
|
||||
/// @brief 判断当前目录项是否为文件夹
|
||||
///
|
||||
@ -1225,7 +1230,7 @@ impl ShortDirEntry {
|
||||
|
||||
// 拷贝扩展名,并计算总的长度
|
||||
let total_len = if ext_len > 0 {
|
||||
name[base_len] = '.' as u8;
|
||||
name[base_len] = b'.';
|
||||
name[base_len + 1..base_len + 1 + ext_len].copy_from_slice(&self.name[8..8 + ext_len]);
|
||||
// 总长度为基础名长度+点号+扩展名长度
|
||||
base_len + 1 + ext_len
|
||||
@ -1246,19 +1251,19 @@ impl ShortDirEntry {
|
||||
///
|
||||
/// @param loc 当前文件的起始、终止簇。格式:(簇,簇内偏移量)
|
||||
/// @return 生成的FATDirENtry枚举类型
|
||||
pub fn to_dir_entry(&self, loc: (Cluster, u64)) -> FATDirEntry {
|
||||
pub fn convert_to_dir_entry(&self, loc: (Cluster, u64)) -> FATDirEntry {
|
||||
// 当前文件的第一个簇
|
||||
let first_cluster =
|
||||
Cluster::new(((self.fst_clus_hi as u64) << 16) | (self.fst_clus_lo as u64));
|
||||
|
||||
// 当前是文件或卷号
|
||||
if self.is_file() || self.is_volume_id() {
|
||||
let mut file: FATFile = FATFile::default();
|
||||
|
||||
file.file_name = self.name_to_string();
|
||||
file.first_cluster = first_cluster;
|
||||
file.short_dir_entry = self.clone();
|
||||
file.loc = (loc, loc);
|
||||
let file: FATFile = FATFile {
|
||||
file_name: self.name_to_string(),
|
||||
first_cluster,
|
||||
short_dir_entry: *self,
|
||||
loc: (loc, loc),
|
||||
};
|
||||
|
||||
// 根据当前短目录项的类型的不同,返回对应的枚举类型。
|
||||
if self.is_file() {
|
||||
@ -1268,12 +1273,13 @@ impl ShortDirEntry {
|
||||
}
|
||||
} else {
|
||||
// 当前是文件夹
|
||||
let mut dir = FATDir::default();
|
||||
dir.dir_name = self.name_to_string();
|
||||
dir.first_cluster = first_cluster;
|
||||
dir.root_offset = None;
|
||||
dir.short_dir_entry = Some(self.clone());
|
||||
dir.loc = Some((loc, loc));
|
||||
let dir = FATDir {
|
||||
dir_name: self.name_to_string(),
|
||||
first_cluster,
|
||||
root_offset: None,
|
||||
short_dir_entry: Some(*self),
|
||||
loc: Some((loc, loc)),
|
||||
};
|
||||
|
||||
return FATDirEntry::Dir(dir);
|
||||
}
|
||||
@ -1285,7 +1291,7 @@ impl ShortDirEntry {
|
||||
/// @param name 从长目录项获取的完整文件名
|
||||
/// @param loc 当前文件的起始、终止簇。格式:(簇,簇内偏移量)
|
||||
/// @return 生成的FATDirENtry枚举类型
|
||||
pub fn to_dir_entry_with_long_name(
|
||||
pub fn convert_to_dir_entry_with_long_name(
|
||||
&self,
|
||||
name: String,
|
||||
loc: ((Cluster, u64), (Cluster, u64)),
|
||||
@ -1295,12 +1301,12 @@ impl ShortDirEntry {
|
||||
Cluster::new(((self.fst_clus_hi as u64) << 16) | (self.fst_clus_lo as u64));
|
||||
|
||||
if self.is_file() || self.is_volume_id() {
|
||||
let mut file = FATFile::default();
|
||||
|
||||
file.first_cluster = first_cluster;
|
||||
file.file_name = name;
|
||||
file.loc = loc;
|
||||
file.short_dir_entry = self.clone();
|
||||
let file = FATFile {
|
||||
first_cluster,
|
||||
file_name: name,
|
||||
loc,
|
||||
short_dir_entry: *self,
|
||||
};
|
||||
|
||||
if self.is_file() {
|
||||
return FATDirEntry::File(file);
|
||||
@ -1308,13 +1314,13 @@ impl ShortDirEntry {
|
||||
return FATDirEntry::VolId(file);
|
||||
}
|
||||
} else {
|
||||
let mut dir = FATDir::default();
|
||||
|
||||
dir.first_cluster = first_cluster;
|
||||
dir.dir_name = name;
|
||||
dir.loc = Some(loc);
|
||||
dir.short_dir_entry = Some(self.clone());
|
||||
dir.root_offset = None;
|
||||
let dir = FATDir {
|
||||
first_cluster,
|
||||
dir_name: name,
|
||||
loc: Some(loc),
|
||||
short_dir_entry: Some(*self),
|
||||
root_offset: None,
|
||||
};
|
||||
|
||||
return FATDirEntry::Dir(dir);
|
||||
}
|
||||
@ -1347,11 +1353,10 @@ impl ShortDirEntry {
|
||||
let lba = fs.get_lba_from_offset(
|
||||
fs.bytes_to_sector(fs.get_in_partition_bytes_offset(disk_bytes_offset)),
|
||||
);
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(1 * fs.lba_per_sector() * LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; fs.lba_per_sector() * LBA_SIZE];
|
||||
fs.partition
|
||||
.disk()
|
||||
.read_at(lba, 1 * fs.lba_per_sector(), &mut v)?;
|
||||
.read_at(lba, fs.lba_per_sector(), &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
// 切换游标到对应位置
|
||||
@ -1372,7 +1377,7 @@ impl ShortDirEntry {
|
||||
// 把修改后的长目录项刷入磁盘
|
||||
fs.partition
|
||||
.disk()
|
||||
.write_at(lba, 1 * fs.lba_per_sector(), cursor.as_slice())?;
|
||||
.write_at(lba, fs.lba_per_sector(), cursor.as_slice())?;
|
||||
fs.partition.disk().sync()?;
|
||||
|
||||
return Ok(());
|
||||
@ -1404,11 +1409,11 @@ impl FATRawDirEntry {
|
||||
|
||||
/// @brief 判断当前目录项是否为这个文件的最后一个目录项
|
||||
fn is_last(&self) -> bool {
|
||||
match self {
|
||||
&Self::Short(_) => {
|
||||
match *self {
|
||||
Self::Short(_) => {
|
||||
return true;
|
||||
}
|
||||
&Self::Long(l) => {
|
||||
Self::Long(l) => {
|
||||
return l.is_last();
|
||||
}
|
||||
_ => {
|
||||
@ -1501,7 +1506,7 @@ impl FATDirIter {
|
||||
return Ok((
|
||||
self.current_cluster,
|
||||
self.offset,
|
||||
Some(s.to_dir_entry((
|
||||
Some(s.convert_to_dir_entry((
|
||||
self.current_cluster,
|
||||
self.offset - FATRawDirEntry::DIR_ENTRY_LEN,
|
||||
))),
|
||||
@ -1664,7 +1669,9 @@ impl FATDirEntry {
|
||||
// 检验校验和是否正确
|
||||
if extractor.validate_checksum(&short_dentry) {
|
||||
// 校验和正确,返回一个长目录项
|
||||
return Ok(short_dentry.to_dir_entry_with_long_name(extractor.to_string(), loc));
|
||||
return Ok(
|
||||
short_dentry.convert_to_dir_entry_with_long_name(extractor.extracted_name(), loc)
|
||||
);
|
||||
} else {
|
||||
// 校验和不相同,认为文件系统出错
|
||||
return Err(SystemError::EROFS);
|
||||
@ -1747,7 +1754,7 @@ impl FATDirEntry {
|
||||
// 是根目录项
|
||||
None => {
|
||||
let mut s = [0x20u8; 11];
|
||||
s[0] = '/' as u8;
|
||||
s[0] = b'/';
|
||||
return s;
|
||||
}
|
||||
},
|
||||
@ -1777,26 +1784,17 @@ impl FATDirEntry {
|
||||
|
||||
/// @brief 判断目录项是否为文件
|
||||
pub fn is_file(&self) -> bool {
|
||||
match self {
|
||||
&FATDirEntry::File(_) | &FATDirEntry::VolId(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self, &FATDirEntry::File(_) | &FATDirEntry::VolId(_))
|
||||
}
|
||||
|
||||
/// @brief 判断目录项是否为文件夹
|
||||
pub fn is_dir(&self) -> bool {
|
||||
match &self {
|
||||
&FATDirEntry::Dir(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self, &FATDirEntry::Dir(_))
|
||||
}
|
||||
|
||||
/// @brief 判断目录项是否为Volume id
|
||||
pub fn is_vol_id(&self) -> bool {
|
||||
match self {
|
||||
&FATDirEntry::VolId(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
matches!(self, &FATDirEntry::VolId(_))
|
||||
}
|
||||
|
||||
/// @brief 判断FAT目录项的名字与给定的是否相等
|
||||
@ -1821,7 +1819,7 @@ impl FATDirEntry {
|
||||
|
||||
/// @brief 将FATDirEntry转换为FATFile对象
|
||||
pub fn to_file(&self) -> Result<FATFile, SystemError> {
|
||||
if self.is_file() == false {
|
||||
if !self.is_file() {
|
||||
return Err(SystemError::EISDIR);
|
||||
}
|
||||
|
||||
@ -1835,7 +1833,7 @@ impl FATDirEntry {
|
||||
|
||||
/// @brief 将FATDirEntry转换为FATDir对象
|
||||
pub fn to_dir(&self) -> Result<FATDir, SystemError> {
|
||||
if self.is_dir() == false {
|
||||
if !self.is_dir() {
|
||||
return Err(SystemError::ENOTDIR);
|
||||
}
|
||||
match &self {
|
||||
@ -1882,12 +1880,12 @@ impl ShortNameGenerator {
|
||||
|
||||
let mut short_name: [u8; 11] = [0x20u8; 11];
|
||||
if name == "." {
|
||||
short_name[0] = '.' as u8;
|
||||
short_name[0] = b'.';
|
||||
}
|
||||
|
||||
if name == ".." {
|
||||
short_name[0] = '.' as u8;
|
||||
short_name[1] = '.' as u8;
|
||||
short_name[0] = b'.';
|
||||
short_name[1] = b'.';
|
||||
}
|
||||
|
||||
// @name_fits: 名称是否被完全拷贝
|
||||
@ -1911,7 +1909,7 @@ impl ShortNameGenerator {
|
||||
None => {
|
||||
// 文件名中,不存在"."
|
||||
let (b_len, fits, b_lossy) =
|
||||
Self::copy_part(&mut short_name[..Self::SHORT_NAME_LEN], &name);
|
||||
Self::copy_part(&mut short_name[..Self::SHORT_NAME_LEN], name);
|
||||
(fits, b_len, b_lossy)
|
||||
}
|
||||
};
|
||||
@ -1934,8 +1932,8 @@ impl ShortNameGenerator {
|
||||
|
||||
return ShortNameGenerator {
|
||||
name: short_name,
|
||||
flags: flags,
|
||||
basename_len: basename_len,
|
||||
flags,
|
||||
basename_len,
|
||||
checksum: Self::fletcher_16_checksum(name),
|
||||
..Default::default()
|
||||
};
|
||||
@ -2017,8 +2015,9 @@ impl ShortNameGenerator {
|
||||
&& ext_matches
|
||||
// 扩展名相匹配
|
||||
{
|
||||
let num = num_suffix.unwrap();
|
||||
self.suffix_bitmask |= 1 << num;
|
||||
if let Some(num) = num_suffix {
|
||||
self.suffix_bitmask |= 1 << num;
|
||||
}
|
||||
}
|
||||
|
||||
// === 检查是否存在短前缀+校验和的冲突,文件名形如:(TE021F~1.TXT)
|
||||
@ -2038,9 +2037,10 @@ impl ShortNameGenerator {
|
||||
.map(|s| u16::from_str_radix(s, 16));
|
||||
// 如果校验码相同
|
||||
if checksum_result == Ok(Ok(self.checksum)) {
|
||||
let num = num_suffix.unwrap();
|
||||
// 置位checksum_bitmask中,基础名末尾数字的对应位
|
||||
self.checksum_bitmask |= 1 << num;
|
||||
if let Some(num) = num_suffix {
|
||||
self.checksum_bitmask |= 1 << num;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2099,7 +2099,7 @@ impl ShortNameGenerator {
|
||||
prefix_len
|
||||
};
|
||||
|
||||
buf[prefix_len] = '~' as u8;
|
||||
buf[prefix_len] = b'~';
|
||||
buf[prefix_len + 1] = char::from_digit(num, 10).unwrap() as u8;
|
||||
buf[8..].copy_from_slice(&self.name[8..]);
|
||||
return buf;
|
||||
@ -2117,7 +2117,7 @@ impl ShortNameGenerator {
|
||||
let c3 = char::from_digit((x as u32 >> 4) & 0xf, 16)
|
||||
.unwrap()
|
||||
.to_ascii_uppercase() as u8;
|
||||
let c4 = char::from_digit((x as u32 >> 0) & 0xf, 16)
|
||||
let c4 = char::from_digit((x as u32) & 0xf, 16)
|
||||
.unwrap()
|
||||
.to_ascii_uppercase() as u8;
|
||||
return [c1, c2, c3, c4];
|
||||
@ -2203,14 +2203,14 @@ impl LongNameExtractor {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// @brief 返回名称的长度
|
||||
/// 返回名称的长度
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
return self.name.len();
|
||||
}
|
||||
|
||||
/// @brief 返回抽取得到的名称字符串
|
||||
fn to_string(&self) -> String {
|
||||
/// 返回抽取得到的名称字符串
|
||||
fn extracted_name(&self) -> String {
|
||||
let mut s = String::from_utf16_lossy(self.name.as_slice());
|
||||
// 计算字符串的长度。如果字符串中有\0,那么就截取字符串的前面部分
|
||||
if let Some(len) = s.find('\u{0}') {
|
||||
@ -2261,8 +2261,8 @@ impl LongNameEntryGenerator {
|
||||
// 先从最后一个长目录项开始生成
|
||||
let start_index = (name.len() / 13) as u8;
|
||||
return LongNameEntryGenerator {
|
||||
name: name,
|
||||
checksum: checksum,
|
||||
name,
|
||||
checksum,
|
||||
idx: start_index,
|
||||
last_index: start_index,
|
||||
};
|
||||
@ -2411,8 +2411,7 @@ pub fn get_raw_dir_entry(
|
||||
// let step2 = fs.bytes_to_sector(step1);
|
||||
// let lba = fs.get_lba_from_offset(step2);
|
||||
// kdebug!("step1={step1}, step2={step2}, lba={lba}");
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(1 * LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; LBA_SIZE];
|
||||
|
||||
fs.partition.disk().read_at(lba, 1, &mut v)?;
|
||||
|
||||
@ -2438,9 +2437,10 @@ pub fn get_raw_dir_entry(
|
||||
|
||||
if file_attr.contains(FileAttributes::LONG_NAME) {
|
||||
// 当前目录项是一个长目录项
|
||||
let mut long_dentry = LongDirEntry::default();
|
||||
|
||||
long_dentry.ord = cursor.read_u8()?;
|
||||
let mut long_dentry = LongDirEntry {
|
||||
ord: cursor.read_u8()?,
|
||||
..Default::default()
|
||||
};
|
||||
cursor.read_u16_into(&mut long_dentry.name1)?;
|
||||
long_dentry.file_attrs = FileAttributes::new(cursor.read_u8()?);
|
||||
long_dentry.dirent_type = cursor.read_u8()?;
|
||||
|
@ -1,3 +1,4 @@
|
||||
use core::cmp::Ordering;
|
||||
use core::intrinsics::unlikely;
|
||||
use core::{any::Any, fmt::Debug};
|
||||
use system_error::SystemError;
|
||||
@ -177,11 +178,11 @@ impl LockedFATInode {
|
||||
};
|
||||
|
||||
let inode: Arc<LockedFATInode> = Arc::new(LockedFATInode(SpinLock::new(FATInode {
|
||||
parent: parent,
|
||||
parent,
|
||||
self_ref: Weak::default(),
|
||||
children: BTreeMap::new(),
|
||||
fs: Arc::downgrade(&fs),
|
||||
inode_type: inode_type,
|
||||
inode_type,
|
||||
metadata: Metadata {
|
||||
dev_id: 0,
|
||||
inode_id: generate_inode_id(),
|
||||
@ -195,7 +196,7 @@ impl LockedFATInode {
|
||||
atime: TimeSpec::default(),
|
||||
mtime: TimeSpec::default(),
|
||||
ctime: TimeSpec::default(),
|
||||
file_type: file_type,
|
||||
file_type,
|
||||
mode: ModeType::from_bits_truncate(0o777),
|
||||
nlinks: 1,
|
||||
uid: 0,
|
||||
@ -330,11 +331,11 @@ impl FATFileSystem {
|
||||
})));
|
||||
|
||||
let result: Arc<FATFileSystem> = Arc::new(FATFileSystem {
|
||||
partition: partition,
|
||||
partition,
|
||||
bpb,
|
||||
first_data_sector,
|
||||
fs_info: Arc::new(LockedFATFsInfo::new(fs_info)),
|
||||
root_inode: root_inode,
|
||||
root_inode,
|
||||
});
|
||||
|
||||
// 对root inode加锁,并继续完成初始化工作
|
||||
@ -384,11 +385,10 @@ impl FATFileSystem {
|
||||
// FAT表项在逻辑块内的字节偏移量
|
||||
let blk_offset = self.get_in_block_offset(fat_bytes_offset);
|
||||
|
||||
let mut v = Vec::<u8>::new();
|
||||
v.resize(self.bpb.bytes_per_sector as usize, 0);
|
||||
let mut v: Vec<u8> = vec![0; self.bpb.bytes_per_sector as usize];
|
||||
self.partition
|
||||
.disk()
|
||||
.read_at(fat_ent_lba as usize, 1 * self.lba_per_sector(), &mut v)?;
|
||||
.read_at(fat_ent_lba as usize, self.lba_per_sector(), &mut v)?;
|
||||
|
||||
let mut cursor = VecCursor::new(v);
|
||||
cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
|
||||
@ -436,7 +436,7 @@ impl FATFileSystem {
|
||||
let entry = cursor.read_u32()? & 0x0fffffff;
|
||||
|
||||
match entry {
|
||||
_n if (current_cluster >= 0x0ffffff7 && current_cluster <= 0x0fffffff) => {
|
||||
_n if (0x0ffffff7..=0x0fffffff).contains(¤t_cluster) => {
|
||||
// 当前簇号不是一个能被获得的簇(可能是文件系统出错了)
|
||||
kerror!("FAT32 get fat entry: current cluster number [{}] is not an allocatable cluster number.", current_cluster);
|
||||
FATEntry::Bad
|
||||
@ -478,11 +478,10 @@ impl FATFileSystem {
|
||||
// FAT表项在逻辑块内的字节偏移量
|
||||
let blk_offset = self.get_in_block_offset(fat_bytes_offset);
|
||||
|
||||
let mut v = Vec::<u8>::new();
|
||||
v.resize(self.bpb.bytes_per_sector as usize, 0);
|
||||
let mut v: Vec<u8> = vec![0; self.bpb.bytes_per_sector as usize];
|
||||
self.partition
|
||||
.disk()
|
||||
.read_at(fat_ent_lba, 1 * self.lba_per_sector(), &mut v)?;
|
||||
.read_at(fat_ent_lba, self.lba_per_sector(), &mut v)?;
|
||||
|
||||
let mut cursor = VecCursor::new(v);
|
||||
cursor.seek(SeekFrom::SeekSet(blk_offset as i64))?;
|
||||
@ -565,10 +564,7 @@ impl FATFileSystem {
|
||||
let end_cluster: Cluster = self.max_cluster_number();
|
||||
let start_cluster: Cluster = match self.bpb.fat_type {
|
||||
FATType::FAT32(_) => {
|
||||
let next_free: u64 = match self.fs_info.0.lock().next_free() {
|
||||
Some(x) => x,
|
||||
None => 0xffffffff,
|
||||
};
|
||||
let next_free: u64 = self.fs_info.0.lock().next_free().unwrap_or(0xffffffff);
|
||||
if next_free < end_cluster.cluster_num {
|
||||
Cluster::new(next_free)
|
||||
} else {
|
||||
@ -771,7 +767,7 @@ impl FATFileSystem {
|
||||
/// @brief 获取从start_cluster开始的簇链中,第n个簇的信息。(请注意,下标从0开始)
|
||||
#[inline]
|
||||
pub fn get_cluster_by_relative(&self, start_cluster: Cluster, n: usize) -> Option<Cluster> {
|
||||
return self.cluster_iter(start_cluster).skip(n).next();
|
||||
return self.cluster_iter(start_cluster).nth(n);
|
||||
}
|
||||
|
||||
/// @brief 获取整个簇链的最后一个簇
|
||||
@ -947,8 +943,7 @@ impl FATFileSystem {
|
||||
|
||||
// 由于FAT12的FAT表不大于6K,因此直接读取6K
|
||||
let num_lba = (6 * 1024) / LBA_SIZE;
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(num_lba * LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; num_lba * LBA_SIZE];
|
||||
self.partition.disk().read_at(lba, num_lba, &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
@ -962,7 +957,7 @@ impl FATFileSystem {
|
||||
packed_val & 0x0fff
|
||||
};
|
||||
if val == 0 {
|
||||
return Ok(Cluster::new(cluster as u64));
|
||||
return Ok(Cluster::new(cluster));
|
||||
}
|
||||
|
||||
cluster += 1;
|
||||
@ -993,8 +988,7 @@ impl FATFileSystem {
|
||||
|
||||
let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset));
|
||||
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(self.lba_per_sector() * LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; self.lba_per_sector() * LBA_SIZE];
|
||||
self.partition
|
||||
.disk()
|
||||
.read_at(lba, self.lba_per_sector(), &mut v)?;
|
||||
@ -1025,8 +1019,7 @@ impl FATFileSystem {
|
||||
|
||||
let lba = self.get_lba_from_offset(self.bytes_to_sector(part_bytes_offset));
|
||||
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(self.lba_per_sector() * LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; self.lba_per_sector() * LBA_SIZE];
|
||||
self.partition
|
||||
.disk()
|
||||
.read_at(lba, self.lba_per_sector(), &mut v)?;
|
||||
@ -1074,8 +1067,7 @@ impl FATFileSystem {
|
||||
|
||||
let lba = self.get_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset));
|
||||
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; LBA_SIZE];
|
||||
self.partition.disk().read_at(lba, 1, &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
@ -1107,8 +1099,7 @@ impl FATFileSystem {
|
||||
|
||||
let lba = self.get_lba_from_offset(self.bytes_to_sector(fat_part_bytes_offset));
|
||||
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; LBA_SIZE];
|
||||
self.partition.disk().read_at(lba, 1, &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
@ -1134,8 +1125,7 @@ impl FATFileSystem {
|
||||
let lba = self.get_lba_from_offset(self.bytes_to_sector(f_offset));
|
||||
|
||||
// kdebug!("set entry, lba={lba}, in_block_offset={in_block_offset}");
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; LBA_SIZE];
|
||||
self.partition.disk().read_at(lba, 1, &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
@ -1222,8 +1212,7 @@ impl FATFsInfo {
|
||||
in_disk_fs_info_offset: u64,
|
||||
bytes_per_sec: usize,
|
||||
) -> Result<Self, SystemError> {
|
||||
let mut v = Vec::<u8>::new();
|
||||
v.resize(bytes_per_sec, 0);
|
||||
let mut v = vec![0; bytes_per_sec];
|
||||
|
||||
// 计算fs_info扇区在磁盘上的字节偏移量,从磁盘读取数据
|
||||
partition
|
||||
@ -1231,9 +1220,10 @@ impl FATFsInfo {
|
||||
.read_at(in_disk_fs_info_offset as usize / LBA_SIZE, 1, &mut v)?;
|
||||
let mut cursor = VecCursor::new(v);
|
||||
|
||||
let mut fsinfo = FATFsInfo::default();
|
||||
|
||||
fsinfo.lead_sig = cursor.read_u32()?;
|
||||
let mut fsinfo = FATFsInfo {
|
||||
lead_sig: cursor.read_u32()?,
|
||||
..Default::default()
|
||||
};
|
||||
cursor.seek(SeekFrom::SeekCurrent(480))?;
|
||||
fsinfo.struc_sig = cursor.read_u32()?;
|
||||
fsinfo.free_count = cursor.read_u32()?;
|
||||
@ -1318,8 +1308,7 @@ impl FATFsInfo {
|
||||
|
||||
let lba = off as usize / LBA_SIZE;
|
||||
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; LBA_SIZE];
|
||||
partition.disk().read_at(lba, 1, &mut v)?;
|
||||
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
@ -1347,8 +1336,7 @@ impl FATFsInfo {
|
||||
|
||||
let lba = off as usize / LBA_SIZE;
|
||||
|
||||
let mut v: Vec<u8> = Vec::new();
|
||||
v.resize(LBA_SIZE, 0);
|
||||
let mut v: Vec<u8> = vec![0; LBA_SIZE];
|
||||
partition.disk().read_at(lba, 1, &mut v)?;
|
||||
let mut cursor: VecCursor = VecCursor::new(v);
|
||||
cursor.seek(SeekFrom::SeekSet(in_block_offset as i64))?;
|
||||
@ -1473,25 +1461,29 @@ impl IndexNode for LockedFATInode {
|
||||
match &mut guard.inode_type {
|
||||
FATDirEntry::File(file) | FATDirEntry::VolId(file) => {
|
||||
// 如果新的长度和旧的长度相同,那么就直接返回
|
||||
if len == old_size {
|
||||
return Ok(());
|
||||
} else if len > old_size {
|
||||
// 如果新的长度比旧的长度大,那么就在文件末尾添加空白
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
let mut remain_size = len - old_size;
|
||||
let buf_size = remain_size;
|
||||
// let buf_size = core::cmp::min(remain_size, 512 * 1024);
|
||||
buf.resize(buf_size, 0);
|
||||
|
||||
let mut offset = old_size;
|
||||
while remain_size > 0 {
|
||||
let write_size = core::cmp::min(remain_size, buf_size);
|
||||
file.write(fs, &buf[0..write_size], offset as u64)?;
|
||||
remain_size -= write_size;
|
||||
offset += write_size;
|
||||
match len.cmp(&old_size) {
|
||||
Ordering::Equal => {
|
||||
return Ok(());
|
||||
}
|
||||
Ordering::Greater => {
|
||||
// 如果新的长度比旧的长度大,那么就在文件末尾添加空白
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
let mut remain_size = len - old_size;
|
||||
let buf_size = remain_size;
|
||||
// let buf_size = core::cmp::min(remain_size, 512 * 1024);
|
||||
buf.resize(buf_size, 0);
|
||||
|
||||
let mut offset = old_size;
|
||||
while remain_size > 0 {
|
||||
let write_size = core::cmp::min(remain_size, buf_size);
|
||||
file.write(fs, &buf[0..write_size], offset as u64)?;
|
||||
remain_size -= write_size;
|
||||
offset += write_size;
|
||||
}
|
||||
}
|
||||
Ordering::Less => {
|
||||
file.truncate(fs, len as u64)?;
|
||||
}
|
||||
} else {
|
||||
file.truncate(fs, len as u64)?;
|
||||
}
|
||||
guard.update_metadata();
|
||||
return Ok(());
|
||||
@ -1533,7 +1525,7 @@ impl IndexNode for LockedFATInode {
|
||||
let name: String = ent.name();
|
||||
// kdebug!("name={name}");
|
||||
|
||||
if guard.children.contains_key(&name.to_uppercase()) == false
|
||||
if !guard.children.contains_key(&name.to_uppercase())
|
||||
&& name != "."
|
||||
&& name != ".."
|
||||
{
|
||||
@ -1581,7 +1573,7 @@ impl IndexNode for LockedFATInode {
|
||||
let nod = guard.children.remove(&name.to_uppercase());
|
||||
|
||||
// 若删除缓存中为管道的文件,则不需要再到磁盘删除
|
||||
if let Some(_) = nod {
|
||||
if nod.is_some() {
|
||||
let file_type = target_guard.metadata.file_type;
|
||||
if file_type == FileType::Pipe {
|
||||
return Ok(());
|
||||
@ -1631,16 +1623,16 @@ impl IndexNode for LockedFATInode {
|
||||
// 再从磁盘删除
|
||||
let r: Result<(), SystemError> =
|
||||
dir.remove(guard.fs.upgrade().unwrap().clone(), name, true);
|
||||
if r.is_ok() {
|
||||
return r;
|
||||
} else {
|
||||
let r = r.unwrap_err();
|
||||
if r == SystemError::ENOTEMPTY {
|
||||
// 如果要删除的是目录,且不为空,则删除动作未发生,重新加入缓存
|
||||
guard.children.insert(name.to_uppercase(), target.clone());
|
||||
drop(target_guard);
|
||||
match r {
|
||||
Ok(_) => return r,
|
||||
Err(r) => {
|
||||
if r == SystemError::ENOTEMPTY {
|
||||
// 如果要删除的是目录,且不为空,则删除动作未发生,重新加入缓存
|
||||
guard.children.insert(name.to_uppercase(), target.clone());
|
||||
drop(target_guard);
|
||||
}
|
||||
return Err(r);
|
||||
}
|
||||
return Err(r);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1771,7 +1763,7 @@ impl IndexNode for LockedFATInode {
|
||||
// 判断需要创建的类型
|
||||
if unlikely(mode.contains(ModeType::S_IFREG)) {
|
||||
// 普通文件
|
||||
return Ok(self.create(filename, FileType::File, mode)?);
|
||||
return self.create(filename, FileType::File, mode);
|
||||
}
|
||||
|
||||
let nod = LockedFATInode::new(
|
||||
|
@ -297,7 +297,6 @@ impl IndexNode for KernFSInode {
|
||||
self.children
|
||||
.lock()
|
||||
.keys()
|
||||
.into_iter()
|
||||
.for_each(|x| keys.push(x.clone()));
|
||||
|
||||
return Ok(keys);
|
||||
@ -641,9 +640,9 @@ pub enum KernInodeType {
|
||||
SymLink,
|
||||
}
|
||||
|
||||
impl Into<FileType> for KernInodeType {
|
||||
fn into(self) -> FileType {
|
||||
match self {
|
||||
impl From<KernInodeType> for FileType {
|
||||
fn from(val: KernInodeType) -> Self {
|
||||
match val {
|
||||
KernInodeType::Dir => FileType::Dir,
|
||||
KernInodeType::File => FileType::File,
|
||||
KernInodeType::SymLink => FileType::SymLink,
|
||||
|
@ -3,7 +3,7 @@ use core::default::Default;
|
||||
|
||||
/// @brief MBR硬盘分区表项的结构
|
||||
#[repr(packed)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct MbrDiskPartitionTableEntry {
|
||||
pub flags: u8, // 引导标志符,标记此分区为活动分区
|
||||
pub starting_head: u8, // 起始磁头号
|
||||
@ -39,21 +39,6 @@ pub struct MbrDiskPartionTable {
|
||||
pub bs_trailsig: u16,
|
||||
}
|
||||
|
||||
impl Default for MbrDiskPartitionTableEntry {
|
||||
fn default() -> Self {
|
||||
MbrDiskPartitionTableEntry {
|
||||
flags: 0,
|
||||
starting_head: 0,
|
||||
starting_sector_cylinder: 0,
|
||||
part_type: 0,
|
||||
ending_head: 0,
|
||||
ending_sector_cylingder: 0,
|
||||
starting_lba: 0,
|
||||
total_sectors: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for MbrDiskPartionTable {
|
||||
fn default() -> Self {
|
||||
MbrDiskPartionTable {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user