aarch64: physical memory setup
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
[1;36mHello, dtb is at 0x48000000[0m
|
||||
[1;36mMemory: 'memory@40000000', base 0x40000000, size 0x10000000[0m
|
||||
[1;36mReserved: 'kernel', base 0x40080000, size 0x1d000[0m
|
||||
[1;36mReserved: 'fdt', base 0x48000000, size 0x100000[0m
|
||||
[1;36mReserved: 'page-array', base 0x4009d000, size 0x100000[0m
|
||||
[1;36mAvailable memory: 253 MiB, page array mem.phys.Page@4009d000[0m
|
||||
QEMU: Terminated
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
const kernel = @import("../../kernel.zig");
|
||||
const vmm = @import("vmm.zig");
|
||||
const dtb = @import("../../util/dtb.zig");
|
||||
|
||||
const arch = kernel.arch;
|
||||
const mem = kernel.mem;
|
||||
const log = kernel.debug.log;
|
||||
const physMemory = mem.phys;
|
||||
|
||||
extern const __aa64_bsp_stack_top: u8;
|
||||
|
||||
@@ -22,6 +25,15 @@ fn relocAddressToUpper(ptr: *const anyopaque) usize {
|
||||
}
|
||||
}
|
||||
|
||||
fn relocAddressToLower(ptr: *const anyopaque) usize {
|
||||
const p = @intFromPtr(ptr);
|
||||
if (p >= vmm.KERNEL_VIRTUAL_BASE) {
|
||||
return p - vmm.KERNEL_VIRTUAL_BASE;
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
fn aa64BspUpperEntry(realAddress: u64) callconv(.C) noreturn {
|
||||
// Relocate the kernel yet again
|
||||
const relaStart = relocAddressToUpper(&__rela_start);
|
||||
@@ -33,7 +45,12 @@ fn aa64BspUpperEntry(realAddress: u64) callconv(.C) noreturn {
|
||||
arch.barrier(.acq_rel);
|
||||
|
||||
log.setWriteFn(&earlyDebugPrint);
|
||||
log.info("Hello, dtb is at 0x{x}", .{ gDtbAddress });
|
||||
log.info("Hello, dtb is at 0x{x}", .{gDtbAddress});
|
||||
|
||||
mem.PhysicalAddress.gVirtualizeBase = 0;
|
||||
mem.PhysicalAddress.gVirtualizeSize = 16 << 30;
|
||||
|
||||
setupMemoryFromFdt(realAddress);
|
||||
|
||||
arch.halt();
|
||||
}
|
||||
@@ -53,6 +70,8 @@ pub export fn aa64BspLowerEntry(realAddress: u64, dtbAddress: u64) callconv(.C)
|
||||
|
||||
extern const __rela_start: u8;
|
||||
extern const __rela_end: u8;
|
||||
extern var __kernel_start: u8;
|
||||
extern var __kernel_end: u8;
|
||||
|
||||
export fn aa64RelocateKernel(imageBase: usize, relaStart: usize, relaEnd: usize) void {
|
||||
const elf = @import("std").elf;
|
||||
@@ -79,10 +98,27 @@ inline fn longJump(pc: usize, sp: usize, a0: usize) noreturn {
|
||||
\\ mov sp, %[sp]
|
||||
\\ br %[pc]
|
||||
:
|
||||
: [sp]"r"(sp),
|
||||
[pc]"r"(pc),
|
||||
[a0]"{x0}"(a0),
|
||||
:"memory"
|
||||
: [sp] "r" (sp),
|
||||
[pc] "r" (pc),
|
||||
[a0] "{x0}" (a0),
|
||||
: "memory"
|
||||
);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
fn setupMemoryFromFdt(realAddress: usize) void {
|
||||
_ = realAddress;
|
||||
|
||||
const kernelStart = relocAddressToLower(&__kernel_start); // 0
|
||||
const kernelEnd = relocAddressToLower(&__kernel_end); // whatever
|
||||
|
||||
const fdt = dtb.Fdt.fromPhysicalAddress(.{ .raw = gDtbAddress }) catch |err| {
|
||||
log.panic("Cannot initialize raw DTB: {}", .{err});
|
||||
};
|
||||
fdt.addPhysicalMemoryToSystem();
|
||||
|
||||
physMemory.addReservedRegion("kernel", kernelStart, kernelEnd - kernelStart);
|
||||
physMemory.addReservedRegion("fdt", gDtbAddress, vmm.L3.align_up(fdt.bytes.len));
|
||||
|
||||
physMemory.init();
|
||||
}
|
||||
|
||||
@@ -14,8 +14,6 @@ const log = debug.log;
|
||||
const arch = kernel.arch;
|
||||
|
||||
extern const __rv64_bsp_stack_top: u8;
|
||||
extern const __kernel_start: u8;
|
||||
extern const __kernel_end: u8;
|
||||
|
||||
var gDtbAddress: usize = 0;
|
||||
var gBspHartId: u32 = 0;
|
||||
@@ -81,6 +79,8 @@ extern var __tdata_start: u8;
|
||||
extern var __tdata_end: u8;
|
||||
extern var __tbss_start: u8;
|
||||
extern var __tbss_end: u8;
|
||||
extern var __kernel_start: u8;
|
||||
extern var __kernel_end: u8;
|
||||
|
||||
fn setupPerCpu() void {
|
||||
// Assume .tbss follows .tdata
|
||||
@@ -131,29 +131,10 @@ fn setupMemoryFromFdt(realAddress: usize) void {
|
||||
const kernelStart = @intFromPtr(&__kernel_start);
|
||||
const kernelEnd = @intFromPtr(&__kernel_end);
|
||||
|
||||
var cells: [2]u64 = undefined;
|
||||
|
||||
const fdt = dtb.Fdt.fromPhysicalAddress(.{ .raw = gDtbAddress }) catch |err| {
|
||||
log.panic("Cannot initialize raw DTB: {}", .{err});
|
||||
};
|
||||
|
||||
var memoryRegions = fdt.memoryRegionIterator();
|
||||
|
||||
while (memoryRegions.next()) |region| {
|
||||
physMemory.addMemoryRegion(region.name, region.base, region.size);
|
||||
}
|
||||
const reservedRegions = fdt.rootNode().child("reserved-memory");
|
||||
if (reservedRegions) |resv| {
|
||||
var children = resv.children();
|
||||
while (children.next()) |region| {
|
||||
if (region.property("reg")) |reg| {
|
||||
// TODO #address-cells, #size-cells
|
||||
if (reg.readCells(0, &cells, &.{ 2, 2 })) {
|
||||
physMemory.addReservedRegion(region.name, cells[0], cells[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fdt.addPhysicalMemoryToSystem();
|
||||
|
||||
physMemory.addReservedRegion("kernel", kernelStart - (vmm.KERNEL_VIRTUAL_BASE + vmm.L1.offset(realAddress)) + realAddress, kernelEnd - kernelStart);
|
||||
physMemory.addReservedRegion("fdt", gDtbAddress, vmm.L3.align_up(fdt.bytes.len));
|
||||
|
||||
+96
-37
@@ -2,6 +2,8 @@ const mem = @import("../mem.zig");
|
||||
const log = @import("../debug.zig").log;
|
||||
const std = @import("std");
|
||||
|
||||
const physMemory = mem.phys;
|
||||
|
||||
const fdt_header = extern struct {
|
||||
magic: u32,
|
||||
totalsize: u32,
|
||||
@@ -359,50 +361,107 @@ pub const Fdt = struct {
|
||||
return @ptrCast(raw[0..len]);
|
||||
}
|
||||
|
||||
pub fn dump(self: *const @This()) void {
|
||||
const root = self.rootNode();
|
||||
pub fn addPhysicalMemoryToSystem(self: *const @This()) void {
|
||||
var memoryRegions = self.memoryRegionIterator();
|
||||
var cells: [2]u64 = undefined;
|
||||
if (root.child("reserved-memory")) |resv| {
|
||||
var regions = resv.children();
|
||||
while (regions.next()) |region| {
|
||||
|
||||
while (memoryRegions.next()) |region| {
|
||||
physMemory.addMemoryRegion(region.name, region.base, region.size);
|
||||
}
|
||||
const reservedRegions = self.rootNode().child("reserved-memory");
|
||||
if (reservedRegions) |resv| {
|
||||
var children = resv.children();
|
||||
while (children.next()) |region| {
|
||||
if (region.property("reg")) |reg| {
|
||||
// TODO #address-cells, #size-cells
|
||||
if (reg.readCells(0, &cells, &.{ 2, 2 })) {
|
||||
log.info("Reserved memory region {s}: base=0x{x}, size=0x{x}", .{ region.name, cells[0], cells[1] });
|
||||
physMemory.addReservedRegion(region.name, cells[0], cells[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// var memIter = self.memoryRegionIterator();
|
||||
// while (memIter.next()) |region| {
|
||||
// log.info("base=0x{x}, size=0x{x}", .{ region.base, region.size });
|
||||
// }
|
||||
}
|
||||
|
||||
// var nodeIter = self.nodeIterator();
|
||||
// while (nodeIter.next()) |node| {
|
||||
// for (0..node.depth) |_| {
|
||||
// log.writeRaw(" ");
|
||||
// }
|
||||
// if (node.name.len == 0) {
|
||||
// log.info("Root node, depth = {}", .{ node.depth });
|
||||
// } else {
|
||||
// log.info("Node {s}, depth {}", .{ node.name, node.depth });
|
||||
// }
|
||||
// var nodePropIter = node.propIterator();
|
||||
// while (nodePropIter.next()) |prop| {
|
||||
// for (0..node.depth + 1) |_| {
|
||||
// log.writeRaw(" ");
|
||||
// }
|
||||
// log.info("Prop {s}", .{ prop.name });
|
||||
// if (std.mem.eql(u8, prop.name, "compatible")) {
|
||||
// var strings = prop.getStringArray();
|
||||
// while (strings.next()) |s| {
|
||||
// for (0..node.depth + 2) |_| {
|
||||
// log.writeRaw(" ");
|
||||
// }
|
||||
// log.info("= {s}", .{ s });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
fn dump_property(property: *const FdtNodeProp, depth: usize, allStrings: bool) void {
|
||||
for (0..depth) |_| {
|
||||
log.writeRaw(" ");
|
||||
}
|
||||
log.write("{s}", .{property.name});
|
||||
|
||||
if (std.mem.eql(u8, property.name, "#size-cells") //
|
||||
or std.mem.eql(u8, property.name, "#address-cells") //
|
||||
or std.mem.eql(u8, property.name, "#interrupt-cells") //
|
||||
or std.mem.eql(u8, property.name, "phandle") //
|
||||
or std.mem.eql(u8, property.name, "interrupt-parent") //
|
||||
) {
|
||||
// Dump as a single cell
|
||||
const v = property.getU32(0) orelse 0;
|
||||
log.write(" = {}", .{v});
|
||||
} else if (allStrings //
|
||||
or std.mem.eql(u8, property.name, "compatible") //
|
||||
or std.mem.eql(u8, property.name, "model") //
|
||||
or std.mem.endsWith(u8, property.name, "-names") //
|
||||
or std.mem.endsWith(u8, property.name, "stdout-path") //
|
||||
) {
|
||||
var v = property.getStringArray();
|
||||
var f = true;
|
||||
while (v.next()) |s| {
|
||||
if (f) {
|
||||
log.writeRaw(" = ");
|
||||
} else {
|
||||
log.writeRaw(", ");
|
||||
}
|
||||
f = false;
|
||||
log.write("\"{s}\"", .{s});
|
||||
}
|
||||
} else {
|
||||
// Dump the rest as a cell array
|
||||
const len = property.lenU32();
|
||||
log.writeRaw(" = <");
|
||||
for (0..len) |i| {
|
||||
if (i != 0) {
|
||||
log.writeRaw(", ");
|
||||
}
|
||||
log.write("0x{x}", .{property.getU32Unchecked(i)});
|
||||
}
|
||||
log.writeRaw(">");
|
||||
}
|
||||
|
||||
log.writeRaw(";\r\n");
|
||||
}
|
||||
|
||||
fn dump_node(node: *const FdtNode, depth: usize) void {
|
||||
var anyProperties = false;
|
||||
var firstChild = true;
|
||||
|
||||
for (0..depth) |_| {
|
||||
log.writeRaw(" ");
|
||||
}
|
||||
if (node.name.len != 0) {
|
||||
log.write("{s} ", .{node.name});
|
||||
}
|
||||
log.writeRaw("{\r\n");
|
||||
var properties = node.propIterator();
|
||||
const allStrings = std.mem.eql(u8, node.name, "aliases");
|
||||
while (properties.next()) |property| {
|
||||
dump_property(&property, depth + 1, allStrings);
|
||||
anyProperties = true;
|
||||
}
|
||||
var children = node.children();
|
||||
while (children.next()) |child| {
|
||||
if (anyProperties and firstChild) {
|
||||
log.writeRaw("\r\n");
|
||||
}
|
||||
firstChild = false;
|
||||
dump_node(&child, depth + 1);
|
||||
}
|
||||
for (0..depth) |_| {
|
||||
log.writeRaw(" ");
|
||||
}
|
||||
log.write("}},\r\n", .{});
|
||||
}
|
||||
|
||||
pub fn dump(self: *const @This()) void {
|
||||
dump_node(&self.rootNode(), 0);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user