Implement thread-locals for per-CPU data
This commit is contained in:
@@ -21,6 +21,12 @@ SECTIONS {
|
|||||||
*(.dynamic*)
|
*(.dynamic*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tdata : ALIGN(4K) {
|
||||||
|
PROVIDE(__tdata_start = .);
|
||||||
|
*(.tdata*)
|
||||||
|
PROVIDE(__tdata_end = .);
|
||||||
|
}
|
||||||
|
|
||||||
.rela : ALIGN(4K) {
|
.rela : ALIGN(4K) {
|
||||||
PROVIDE(__rela_start = .);
|
PROVIDE(__rela_start = .);
|
||||||
*(.rela*)
|
*(.rela*)
|
||||||
@@ -42,6 +48,12 @@ SECTIONS {
|
|||||||
PROVIDE(__bss_end = .);
|
PROVIDE(__bss_end = .);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tbss : {
|
||||||
|
PROVIDE(__tbss_start = .);
|
||||||
|
*(.tbss*)
|
||||||
|
PROVIDE(__tbss_end = .);
|
||||||
|
}
|
||||||
|
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
PROVIDE(__kernel_end = .);
|
PROVIDE(__kernel_end = .);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ extern fn __rv64_task_enter_kernel() callconv(.C) noreturn;
|
|||||||
|
|
||||||
pub fn arch() type {
|
pub fn arch() type {
|
||||||
return struct {
|
return struct {
|
||||||
|
pub threadlocal var tHartId: u32 = 0;
|
||||||
|
|
||||||
pub const Context = extern struct {
|
pub const Context = extern struct {
|
||||||
const STACK_SIZE: usize = 8192;
|
const STACK_SIZE: usize = 8192;
|
||||||
|
|
||||||
@@ -101,5 +103,9 @@ pub fn arch() type {
|
|||||||
}
|
}
|
||||||
asm volatile ("":::"memory");
|
asm volatile ("":::"memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub inline fn setThreadPointer(tp: usize) void {
|
||||||
|
asm volatile ("mv tp, %[tp]"::[tp]"r"(tp):"memory");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ extern const __kernel_start: u8;
|
|||||||
extern const __kernel_end: u8;
|
extern const __kernel_end: u8;
|
||||||
|
|
||||||
var gDtbAddress: usize = 0;
|
var gDtbAddress: usize = 0;
|
||||||
var gBspHartId: usize = 0;
|
var gBspHartId: u32 = 0;
|
||||||
|
|
||||||
pub export fn rv64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) void {
|
pub export fn rv64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) void {
|
||||||
const elf = @import("std").elf;
|
const elf = @import("std").elf;
|
||||||
@@ -27,11 +27,15 @@ pub export fn rv64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: us
|
|||||||
const relaCount = (relaEnd - relaStart) / @sizeOf(elf.Rela);
|
const relaCount = (relaEnd - relaStart) / @sizeOf(elf.Rela);
|
||||||
const relaTable = relaTablePtr[0..relaCount];
|
const relaTable = relaTablePtr[0..relaCount];
|
||||||
for (relaTable) |entry| {
|
for (relaTable) |entry| {
|
||||||
if (entry.r_type() == 0x03) {
|
const relaType: elf.R_RISCV = @enumFromInt(entry.r_type());
|
||||||
const value = @as(*isize, @ptrFromInt(imageBase + entry.r_offset));
|
switch (relaType) {
|
||||||
value.* = @as(isize, @bitCast(imageBase)) + entry.r_addend;
|
.RELATIVE => {
|
||||||
} else {
|
const value = @as(*isize, @ptrFromInt(imageBase + entry.r_offset));
|
||||||
arch.halt();
|
value.* = @as(isize, @bitCast(imageBase)) + entry.r_addend;
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
arch.halt();
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,6 +98,9 @@ fn bspUpperEntry(realAddress: usize, unused: usize) callconv(.C) noreturn {
|
|||||||
// Setup physical memory management
|
// Setup physical memory management
|
||||||
setupMemoryFromFdt(realAddress);
|
setupMemoryFromFdt(realAddress);
|
||||||
|
|
||||||
|
kernel.thread.setupCurrentCpu();
|
||||||
|
arch.tHartId = gBspHartId;
|
||||||
|
|
||||||
kernel.kernel_main();
|
kernel.kernel_main();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +122,7 @@ pub export fn rv64BspLowerEntry(realAddress: usize, bspHartId: usize, dtbAddress
|
|||||||
debug.log.setWriteFn(&sbi.debugPrintByte);
|
debug.log.setWriteFn(&sbi.debugPrintByte);
|
||||||
|
|
||||||
gDtbAddress = dtbAddress;
|
gDtbAddress = dtbAddress;
|
||||||
gBspHartId = bspHartId;
|
gBspHartId = @truncate(bspHartId);
|
||||||
|
|
||||||
vmm.mapEarly(realAddress);
|
vmm.mapEarly(realAddress);
|
||||||
|
|
||||||
|
|||||||
@@ -34,12 +34,6 @@ pub export fn kernel_main() callconv(.C) noreturn {
|
|||||||
thread.addThread(t);
|
thread.addThread(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const ptr: *const u32 = @ptrFromInt(0x1111111111111114);
|
|
||||||
const z = ptr.*;
|
|
||||||
_ = z;
|
|
||||||
while (true) {}
|
|
||||||
|
|
||||||
thread.enter();
|
thread.enter();
|
||||||
|
|
||||||
arch.halt();
|
arch.halt();
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
const arena = @import("arena.zig");
|
const arena = @import("arena.zig");
|
||||||
const arch = @import("kernel.zig").arch;
|
const arch = @import("kernel.zig").arch;
|
||||||
const log = @import("debug.zig").log;
|
const log = @import("debug.zig").log;
|
||||||
@@ -90,3 +92,33 @@ pub fn yield() void {
|
|||||||
next.switchFrom(curr);
|
next.switchFrom(curr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern var __tdata_start: u8;
|
||||||
|
extern var __tdata_end: u8;
|
||||||
|
extern var __tbss_start: u8;
|
||||||
|
extern var __tbss_end: u8;
|
||||||
|
|
||||||
|
pub fn setupCurrentCpu() void {
|
||||||
|
// Assume .tbss follows .tdata
|
||||||
|
const tdataStart = @intFromPtr(&__tdata_start);
|
||||||
|
const tdataEnd = @intFromPtr(&__tdata_end);
|
||||||
|
const tdataSize = tdataEnd - tdataStart;
|
||||||
|
const tbssStart = @intFromPtr(&__tbss_start);
|
||||||
|
const tbssEnd = @intFromPtr(&__tbss_end);
|
||||||
|
const tbssSize = tbssEnd - tbssStart;
|
||||||
|
|
||||||
|
const tdataData = @as([*]u8, @ptrFromInt(tdataStart))[0..tdataSize];
|
||||||
|
|
||||||
|
const tlsSize = tdataSize + tbssSize;
|
||||||
|
const tlsPageCount = (tlsSize + mem.vmm.PAGE_SIZE - 1) / mem.vmm.PAGE_SIZE;
|
||||||
|
// Variant I: TLS block 0 follows TP after a certain displacement
|
||||||
|
const tlsAddress = mem.phys.alloc_pages(tlsPageCount).?.virtualize();
|
||||||
|
const tlsData = @as([*]u8, @ptrFromInt(tlsAddress))[0..tlsSize];
|
||||||
|
|
||||||
|
log.info("Allocated TLS @ {*}", .{ tlsData });
|
||||||
|
|
||||||
|
@memcpy(tlsData[0..tdataSize], tdataData);
|
||||||
|
@memset(tlsData[tdataSize..], 0);
|
||||||
|
|
||||||
|
arch.setThreadPointer(tlsAddress);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user