Skip to content

Commit 72a28bd

Browse files
committed
add flush_broadcast
1 parent 0e2193f commit 72a28bd

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

src/instructions/tlb.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
//! Functions to flush the translation lookaside buffer (TLB).
22
3-
use crate::VirtAddr;
3+
use bit_field::BitField;
4+
5+
use crate::{
6+
structures::paging::{page::NotGiantPageSize, Page, PageSize, Size2MiB},
7+
VirtAddr,
8+
};
49
use core::arch::asm;
510

611
/// Invalidate the given address in the TLB using the `invlpg` instruction.
@@ -97,3 +102,57 @@ pub unsafe fn flush_pcid(command: InvPicdCommand) {
97102
asm!("invpcid {0}, [{1}]", in(reg) kind, in(reg) &desc, options(nostack, preserves_flags));
98103
}
99104
}
105+
106+
/// Invalidates TLB entry(s) with Broadcast.
107+
///
108+
/// # Safety
109+
///
110+
/// This function is unsafe as it requires CPUID.(EAX=8000_0008H, ECX=0H):EBX.INVLPGB
111+
/// to be 1 and count to be less than or equal to CPUID.(EAX=8000_0008H, ECX=0H):EDX[0..=15].
112+
#[inline]
113+
pub unsafe fn flush_broadcast<S>(
114+
va_and_count: Option<(Page<S>, u16)>,
115+
pcid: Option<Pcid>,
116+
asid: Option<u16>,
117+
include_global: bool,
118+
final_translation_only: bool,
119+
include_nested_translations: bool,
120+
) where
121+
S: NotGiantPageSize,
122+
{
123+
let mut rax = 0;
124+
let mut ecx = 0;
125+
let mut edx = 0;
126+
127+
if let Some((va, count)) = va_and_count {
128+
rax.set_bit(0, true);
129+
rax.set_bits(12.., va.start_address().as_u64().get_bits(12..));
130+
131+
ecx.set_bits(0..=15, u32::from(count));
132+
ecx.set_bit(31, S::SIZE == Size2MiB::SIZE);
133+
}
134+
135+
if let Some(pcid) = pcid {
136+
rax.set_bit(1, true);
137+
edx.set_bits(16..=27, u32::from(pcid.value()));
138+
}
139+
140+
if let Some(asid) = asid {
141+
rax.set_bit(2, true);
142+
edx.set_bits(0..=15, u32::from(asid));
143+
}
144+
145+
rax.set_bit(3, include_global);
146+
rax.set_bit(4, final_translation_only);
147+
rax.set_bit(5, include_nested_translations);
148+
149+
unsafe {
150+
asm!(
151+
"invlpgb",
152+
in("rax") rax,
153+
in("ecx") ecx,
154+
in("edx") edx,
155+
options(nomem, preserves_flags),
156+
);
157+
}
158+
}

0 commit comments

Comments
 (0)