Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 19 additions & 10 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -230,16 +230,16 @@ pub fn build(b: *std.Build) void {
};

const apps: []const AppDef = &.{
.{ .name = "init.ashex", .exe = get_named_file(os_files, "apps/init.elf") },
.{ .name = "hello-world.ashex", .exe = get_named_file(os_files, "apps/hello-world.elf") },
.{ .name = "mtg-counter.ashex", .exe = get_named_file(os_files, "apps/mtg-counter.elf") },
.{ .name = "hello-fb.ashex", .exe = get_named_file(os_files, "apps/hello-fb.elf") },
.{ .name = "classic.ashex", .exe = get_named_file(os_files, "apps/desktop/classic.elf") },
.{ .name = "dungeon.ashex", .exe = get_named_file(os_files, "apps/dungeon.elf") },
.{ .name = "ntp-client.ashex", .exe = get_named_file(os_files, "apps/ntp-client.elf") },
.{ .name = "i2c-scan.ashex", .exe = get_named_file(os_files, "apps/i2c-scan.elf") },
.{ .name = "widgets.ashex", .exe = get_named_file(os_files, "apps/widgets.elf") },
.{ .name = "2048.ashex", .exe = get_named_file(os_files, "apps/2048.elf") },
// .{ .name = "init.ashex", .exe = get_named_file(os_files, "apps/init.elf") },
// .{ .name = "hello-world.ashex", .exe = get_named_file(os_files, "apps/hello-world.elf") },
// .{ .name = "mtg-counter.ashex", .exe = get_named_file(os_files, "apps/mtg-counter.elf") },
// .{ .name = "hello-fb.ashex", .exe = get_named_file(os_files, "apps/hello-fb.elf") },
// .{ .name = "classic.ashex", .exe = get_named_file(os_files, "apps/desktop/classic.elf") },
// .{ .name = "dungeon.ashex", .exe = get_named_file(os_files, "apps/dungeon.elf") },
// .{ .name = "ntp-client.ashex", .exe = get_named_file(os_files, "apps/ntp-client.elf") },
// .{ .name = "i2c-scan.ashex", .exe = get_named_file(os_files, "apps/i2c-scan.elf") },
// .{ .name = "widgets.ashex", .exe = get_named_file(os_files, "apps/widgets.elf") },
// .{ .name = "2048.ashex", .exe = get_named_file(os_files, "apps/2048.elf") },
};

var variables = Variables{
Expand Down Expand Up @@ -410,6 +410,9 @@ const platform_info_map = std.EnumArray(Platform, PlatformStartupConfig).init(.{
.rv32 = .{
.qemu_exe = "qemu-system-riscv32",
},
.ppc = .{
.qemu_exe = "qemu-system-ppc",
},
});

const machine_info_map = std.EnumArray(RunTarget, MachineStartupConfig).init(.{
Expand Down Expand Up @@ -535,6 +538,10 @@ const machine_info_map = std.EnumArray(RunTarget, MachineStartupConfig).init(.{
}),
},

.@"ppc-nintendo-gc" = .{
// TODO
},

// .@"pc-efi" = .{
// .qemu_cli = &.{
// "-cpu", "qemu64",
Expand Down Expand Up @@ -637,6 +644,8 @@ pub const RunTarget = enum {
@"x86-pc-generic-bios",
@"x86-pc-generic-uefi",

@"ppc-nintendo-gc",

pub fn get_machine(rt: RunTarget) Machine {
return switch (rt) {
.@"x86-pc-generic-bios" => .@"x86-pc-generic",
Expand Down
11 changes: 11 additions & 0 deletions src/abi/src/platforms.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub const Platform = enum {
x86,
arm,
rv32,
ppc,

/// Returns the display name for the current platform.
pub fn get_display_name(target: Platform) []const u8 {
Expand All @@ -21,6 +22,7 @@ const app_display_name_map = std.EnumArray(Platform, []const u8).init(.{
.x86 = "Intel x86",
.arm = "Arm 32-bit",
.rv32 = "RISC-V 32-bit",
.ppc = "PowerPC 32-bit",
});

const build = struct {
Expand Down Expand Up @@ -90,5 +92,14 @@ const build = struct {
.reserve_x4, // Don't allow LLVM to use the "tp" register. We want that for our own purposes
}),
}),

.ppc = constructTargetQuery(.{
.cpu_arch = .powerpc,
.abi = .eabihf,
.cpu_model = .{ .explicit = &std.Target.powerpc.cpu.generic },
.cpu_features_add = std.Target.powerpc.featureSet(&.{
.hard_float,
}),
}),
});
};
18 changes: 18 additions & 0 deletions src/kernel/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,9 @@ const platform_info_map = std.EnumArray(Platform, PlatformConfig).init(.{
.rv32 = .{
.source_file = "port/platform/riscv.zig",
},
.ppc = .{
.source_file = "port/platform/ppc.zig",
},
});

const machine_info_map = std.EnumArray(Machine, MachineConfig).init(.{
Expand Down Expand Up @@ -471,6 +474,21 @@ const machine_info_map = std.EnumArray(Machine, MachineConfig).init(.{
.source_file = "port/machine/x86/hosted-windows/hosted-windows.zig",
.linker_script = "port/machine/x86/hosted-windows/linker.ld",
},

.@"ppc-nintendo-gc" = .{
.target = constructTargetQuery(.{
.cpu_arch = .powerpc,
.abi = .eabihf,
.cpu_model = .{ .explicit = &std.Target.powerpc.cpu.@"750" },
.cpu_features_add = std.Target.powerpc.featureSet(&.{
.hard_float,
// .privileged,
}),
}),

.source_file = "port/machine/ppc/nintendo-gc/nintendo-gc.zig",
.linker_script = "port/machine/ppc/nintendo-gc/linker.ld",
},
});

const generic_x86: std.Target.Query = .{
Expand Down
1 change: 1 addition & 0 deletions src/kernel/components/loader/ashex.zig
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ fn parse_header(header_chunk: *const [512]u8) !ashex.Header {
.riscv32 => .{ .machine32_le, .riscv32 },
.x86 => .{ .machine32_le, .x86 },
.arm, .thumb => .{ .machine32_le, .arm32 },
.powerpc => .{ .machine32_be, .ppc },
else => @compileError("Unsupported machine type: " ++ @tagName(system_arch)),
};

Expand Down
19 changes: 19 additions & 0 deletions src/kernel/components/scheduler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const scheduler_cc: std.builtin.CallingConvention = switch (builtin.cpu.arch) {
.{ .x86_sysv = .{} },
.thumb => .{ .arm_aapcs = .{} },
.riscv32 => .{ .riscv32_ilp32 = .{} },
.powerpc => .{ .powerpc_sysv = .{} },
else => @compileError("unsupported platform"),
};

Expand Down Expand Up @@ -359,6 +360,10 @@ pub const Thread = struct {
thread.push(@intFromPtr(arg)); // r0
},

.powerpc => {
@panic("OH SHIT");
},

else => @compileError(std.fmt.comptimePrint("{s} is not a supported platform", .{@tagName(target)})),
}

Expand Down Expand Up @@ -1058,6 +1063,20 @@ comptime {
\\ .word ashet_scheduler_restore_thread
),

.powerpc => (
// TODO
\\
\\.global ashet_scheduler_threadTrampoline
\\.type ashet_scheduler_threadTrampoline, %function
\\ashet_scheduler_threadTrampoline:
\\ trap
\\
\\.global ashet_scheduler_switchTasks
\\.type ashet_scheduler_switchTasks, %function
\\ashet_scheduler_switchTasks:
\\ trap
),

else => @compileError(std.fmt.comptimePrint("{s} is not a supported platform", .{@tagName(target)})),
};

Expand Down
2 changes: 2 additions & 0 deletions src/kernel/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ else switch (platform_id) {
.rv32 => @import("port/platform/rv32.zig"),
.arm => @import("port/platform/arm.zig"),
.x86 => @import("port/platform/x86.zig"),
.ppc => @import("port/platform/ppc.zig"),
};

pub const machine = switch (machine_id) {
Expand All @@ -50,6 +51,7 @@ pub const machine = switch (machine_id) {
.@"arm-ashet-hc" => @import("port/machine/arm/ashet-hc/ashet-hc.zig"),
.@"arm-ashet-vhc" => @import("port/machine/arm/ashet-vhc/ashet-vhc.zig"),
.@"arm-qemu-virt" => @import("port/machine/arm/qemu-virt/arm-qemu-virt.zig"),
.@"ppc-nintendo-gc" => @import("port/machine/ppc/nintendo-gc/nintendo-gc.zig"),
.@"x86-hosted-linux" => @import("port/machine/x86/hosted-linux/hosted-linux.zig"),
.@"x86-hosted-windows" => @import("port/machine/x86/hosted-windows/hosted-windows.zig"),
};
Expand Down
120 changes: 120 additions & 0 deletions src/kernel/port/machine/ppc/nintendo-gc/linker.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@

/*
* Linkscript for GC
*
*/

OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc");
OUTPUT_ARCH(powerpc:common);
EXTERN(_start);
ENTRY(_start);

PHDRS
{
stub PT_LOAD FLAGS(5);
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
bss PT_LOAD;
}


/* MEMORY
{
sram (RWX) : ORIGIN = 0x00000000, LENGTH = 32M
dram (RWX) : ORIGIN = 0x80000000, LENGTH = 2M
} */

SECTIONS
{
. = 0x80003100;

__kernel_flash_start = .;

/* Program */
.init :
{
KEEP (*(.zgc_bootstrap))
KEEP (*(.init))
} :text = 0

.text :
{
*(.text*)
} :text = 0

. = ALIGN(4096);

.rodata :
{
*(.rodata*)
*(.rodata1)
} :data

__kernel_flash_end = .;

. = ALIGN(4096);

.data :
{
__kernel_data_start = .;
*(.data*)
__sdata_start = .;
*(.sdata) *(.sdata.*)
__sdata2_start = .;
*(.sdata2*)
*(.data1)
__kernel_data_end = .;
}

.eh_frame :
{
KEEP (*(.eh_frame))
}

.got :
{
*(.got*)
}

. = ALIGN(4096);

.bss ALIGN(32) :
{
__kernel_bss_start = .;
*(.sbss2*)
*(.dynsbss)
*(.sbss) *(.sbss.*)
*(.scommon)
. = ALIGN(4); /* Ensure section size is multiple of 4 bytes */
*(.dynbss)
*(.bss) *(.bss.*)
*(COMMON)
. = ALIGN(4096);
__kernel_bss_end = .;
} :bss

. = ALIGN(4096);

__kernel_stack_start = .;
. += 0x20000;
__kernel_stack_end = .;

. = ALIGN(4096);

__machine_linmem_start = .;
__machine_linmem_end = 0x817FE000;

__machine_linmem_length = __machine_linmem_end - __machine_linmem_start;

/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_str 0 : { *(.debug_str) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_line 0 : { *(.debug_line) }
/* These must appear regardless of . */
}

50 changes: 50 additions & 0 deletions src/kernel/port/machine/ppc/nintendo-gc/nintendo-gc.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const std = @import("std");
const ashet = @import("../../../../main.zig");
const ppc = ashet.ports.platforms.ppc;
const logger = std.log.scoped(.@"nintendo-gc");

pub const machine_config = ashet.ports.MachineConfig{
.load_sections = .{ .data = false, .bss = false },
.memory_protection = null,
.initialize = initialize,
.early_initialize = null,
.debug_write = debug_write,
.get_linear_memory_region = get_linear_memory_region,
.get_tick_count_ms = get_tick_count_ms,
.halt = null,
};

const hw = struct {
//! list of fixed hardware components

var rtc: ashet.drivers.rtc.Dummy_RTC = undefined;
};

fn get_tick_count_ms() u64 { // return value in ms
return 0; // TODO
}

fn initialize() !void {
// TODO: Setup machine

hw.rtc = .init(1778338669 * std.time.ns_per_s);

// Finally install all drivers:
ashet.drivers.install(&hw.rtc.driver);
}

noinline fn debug_write(msg: []const u8) void {
for (msg) |c| {
_ = c; //TODO
}
}

extern const __machine_linmem_start: anyopaque align(4);
extern const __machine_linmem_length: anyopaque align(4);

fn get_linear_memory_region() ashet.memory.Range {
return .{
.base = @intFromPtr(&__machine_linmem_start),
.length = @intFromPtr(&__machine_linmem_length),
};
}
7 changes: 6 additions & 1 deletion src/kernel/port/machine_id.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub const MachineID = enum {
@"x86-pc-generic",
// @"x86-pc-uefi", // TODO: Find better name for the UEFI executable kernel

// @"ppc-nintendo-gamecube",
@"ppc-nintendo-gc",

pub fn is_hosted(target: MachineID) bool {
return switch (target) {
Expand All @@ -34,6 +34,7 @@ pub const MachineID = enum {
.@"rv32-qemu-virt",
.@"rv32-ashet-base",
.@"x86-pc-generic",
.@"ppc-nintendo-gc",
=> false,

.@"x86-hosted-linux",
Expand All @@ -52,6 +53,7 @@ pub const MachineID = enum {
.@"x86-hosted-linux" => "OS Hosted (x86, Linux)",
.@"x86-hosted-windows" => "OS Hosted (x86, Windows)",
.@"x86-pc-generic" => "Generic PC (x86)",
.@"ppc-nintendo-gc" => "Nintendo GameCube",
};
}

Expand All @@ -70,6 +72,9 @@ pub const MachineID = enum {
.@"x86-hosted-windows",
.@"x86-pc-generic",
=> .x86,

.@"ppc-nintendo-gc",
=> .ppc,
};
}

Expand Down
Loading
Loading