Remove TLS on aarch64 too.

This commit is contained in:
4lDO2
2023-07-11 16:39:07 +02:00
parent ed2febb289
commit ca92eda5e6
7 changed files with 37 additions and 153 deletions
-12
View File
@@ -39,18 +39,6 @@ SECTIONS {
__bss_end = .;
}
.tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) {
__tdata_start = .;
*(.tdata*)
. = ALIGN(4096);
__tdata_end = .;
__tbss_start = .;
*(.tbss*)
. += 8;
. = ALIGN(4096);
__tbss_end = .;
}
__end = .;
/DISCARD/ : {
@@ -50,6 +50,12 @@ pub unsafe fn tpidr_el0_write(val: u64) {
asm!("msr tpidr_el0, {}", in(reg) val);
}
pub unsafe fn tpidr_el1() -> u64 {
let ret: u64;
asm!("mrs {}, tpidr_el1", out(reg) ret);
ret
}
pub unsafe fn tpidr_el1_write(val: u64) {
asm!("msr tpidr_el1, {}", in(reg) val);
}
+21
View File
@@ -0,0 +1,21 @@
use crate::paging::{RmmA, RmmArch};
use crate::percpu::PercpuBlock;
impl PercpuBlock {
pub fn current() -> &'static Self {
unsafe { &*(crate::device::cpu::registers::control_regs::tpidr_el1() as *const Self) }
}
}
#[cold]
pub unsafe fn init(cpu_id: usize) {
let frame = crate::memory::allocate_frames(1).expect("failed to allocate percpu memory");
let virt = RmmA::phys_to_virt(frame.start_address()).data() as *mut PercpuBlock;
virt.write(PercpuBlock {
cpu_id,
switch_internals: crate::context::switch::ContextSwitchPercpu::default(),
});
crate::device::cpu::registers::control_regs::tpidr_el1_write(virt as u64);
}
+3
View File
@@ -16,6 +16,9 @@ pub mod interrupt;
/// Inter-processor interrupts
pub mod ipi;
/// Miscellaneous
pub mod misc;
/// Paging
pub mod paging;
+4 -123
View File
@@ -29,6 +29,7 @@ pub const ENTRY_COUNT: usize = RmmA::PAGE_ENTRIES;
pub const PAGE_SIZE: usize = RmmA::PAGE_SIZE;
/// Setup Memory Access Indirection Register
#[cold]
unsafe fn init_mair() {
let mut val: control_regs::MairEl1 = control_regs::mair_el1();
@@ -39,130 +40,10 @@ unsafe fn init_mair() {
control_regs::mair_el1_write(val);
}
/// Map percpu
unsafe fn map_percpu(cpu_id: usize, mapper: &mut PageMapper) -> PageFlushAll<RmmA> {
extern "C" {
/// The starting byte of the thread data segment
static mut __tdata_start: u8;
/// The ending byte of the thread data segment
static mut __tdata_end: u8;
/// The starting byte of the thread BSS segment
static mut __tbss_start: u8;
/// The ending byte of the thread BSS segment
static mut __tbss_end: u8;
}
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
let end = start + size;
let mut flush_all = PageFlushAll::new();
let start_page = Page::containing_address(VirtualAddress::new(start));
let end_page = Page::containing_address(VirtualAddress::new(end - 1));
for page in Page::range_inclusive(start_page, end_page) {
let result = mapper.map(
page.start_address(),
PageFlags::new().write(true).global(cfg!(not(feature = "pti"))),
)
.expect("failed to allocate page table frames while mapping percpu");
flush_all.consume(result);
}
flush_all
}
/// Copy tdata, clear tbss, set TCB self pointer
unsafe fn init_tcb(cpu_id: usize) -> usize {
extern "C" {
/// The starting byte of the thread data segment
static mut __tdata_start: u8;
/// The ending byte of the thread data segment
static mut __tdata_end: u8;
/// The starting byte of the thread BSS segment
static mut __tbss_start: u8;
/// The ending byte of the thread BSS segment
static mut __tbss_end: u8;
}
let tcb_offset;
{
let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize;
let tbss_offset = &__tbss_start as *const _ as usize - &__tdata_start as *const _ as usize;
let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id;
println!("SET TPIDR_EL1 TO {:X}", start - 0x10);
// FIXME: Empirically initializing tpidr to 16 bytes below start works. I do not know
// whether this is the correct way to handle TLS. Will need to revisit.
control_regs::tpidr_el1_write((start - 0x10) as u64);
println!("SET TPIDR_EL1 DONE");
let end = start + size;
tcb_offset = end - mem::size_of::<usize>();
ptr::copy(&__tdata_start as *const u8, start as *mut u8, tbss_offset);
ptr::write_bytes((start + tbss_offset) as *mut u8, 0, size - tbss_offset);
*(tcb_offset as *mut usize) = end;
}
tcb_offset
}
/// Initialize paging
///
/// Returns page table and thread control block offset
pub unsafe fn init(
cpu_id: usize,
) -> usize {
extern "C" {
/// The starting byte of the text (code) data segment.
static mut __text_start: u8;
/// The ending byte of the text (code) data segment.
static mut __text_end: u8;
/// The starting byte of the _.rodata_ (read-only data) segment.
static mut __rodata_start: u8;
/// The ending byte of the _.rodata_ (read-only data) segment.
static mut __rodata_end: u8;
/// The starting byte of the _.data_ segment.
static mut __data_start: u8;
/// The ending byte of the _.data_ segment.
static mut __data_end: u8;
/// The starting byte of the thread data segment
static mut __tdata_start: u8;
/// The ending byte of the thread data segment
static mut __tdata_end: u8;
/// The starting byte of the thread BSS segment
static mut __tbss_start: u8;
/// The ending byte of the thread BSS segment
static mut __tbss_end: u8;
/// The starting byte of the _.bss_ (uninitialized data) segment.
static mut __bss_start: u8;
/// The ending byte of the _.bss_ (uninitialized data) segment.
static mut __bss_end: u8;
}
/// Initialize MAIR
#[cold]
pub unsafe fn init() {
init_mair();
let flush_all = map_percpu(cpu_id, KernelMapper::lock_manually(cpu_id).get_mut().expect("expected KernelMapper not to be locked re-entrant in paging::init"));
flush_all.flush();
return init_tcb(cpu_id);
}
pub unsafe fn init_ap(
cpu_id: usize,
bsp_table: &mut KernelMapper,
) -> usize {
init_mair();
{
let flush_all = map_percpu(cpu_id, bsp_table.get_mut().expect("KernelMapper locked re-entrant for AP"));
// The flush can be ignored as this is not the active table. See later make_current().
flush_all.ignore();
};
bsp_table.make_current();
init_tcb(cpu_id)
}
/// Page
+2 -16
View File
@@ -22,12 +22,6 @@ use crate::paging::{self, KernelMapper};
static BSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in data.
static DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
/// Test of zero values in thread BSS
#[thread_local]
static mut TBSS_TEST_ZERO: usize = 0;
/// Test of non-zero values in thread data.
#[thread_local]
static mut TDATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF;
pub static KERNEL_BASE: AtomicUsize = AtomicUsize::new(0);
pub static KERNEL_SIZE: AtomicUsize = AtomicUsize::new(0);
@@ -138,17 +132,9 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! {
);
// Initialize paging
let tcb_offset = paging::init(0);
paging::init();
// Test tdata and tbss
{
assert_eq!(TBSS_TEST_ZERO, 0);
TBSS_TEST_ZERO += 1;
assert_eq!(TBSS_TEST_ZERO, 1);
assert_eq!(TDATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF);
TDATA_TEST_NONZERO -= 1;
assert_eq!(TDATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFE);
}
crate::misc::init(0);
// Reset AP variables
CPU_COUNT.store(1, Ordering::SeqCst);
+1 -2
View File
@@ -22,6 +22,5 @@
"exe-suffix": "",
"has-rpath": false,
"no-default-libraries": true,
"position-independent-executables": false,
"tls-model": "global-dynamic"
"position-independent-executables": false
}