Remove TLS on aarch64 too.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -16,6 +16,9 @@ pub mod interrupt;
|
||||
/// Inter-processor interrupts
|
||||
pub mod ipi;
|
||||
|
||||
/// Miscellaneous
|
||||
pub mod misc;
|
||||
|
||||
/// Paging
|
||||
pub mod paging;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user