From 54eb12b2c63763691f4578bac6d8831c9b38fc21 Mon Sep 17 00:00:00 2001 From: N00byEdge Date: Wed, 6 Jan 2021 16:13:13 +0100 Subject: [PATCH 1/4] Initial work on fruity devices --- .gitmodules | 3 ++ debug_ecore.sh | 15 ++++++ ipwndfu | 1 + src/platform/fruity/fruity.zig | 73 +++++++++++++++++++++++++++ src/platform/t8010_aarch64/entry.asm | 75 ++++++++++++++++++++++++++++ src/platform/t8010_aarch64/linker.ld | 34 +++++++++++++ src/platform/t8010_aarch64/main.zig | 1 + 7 files changed, 202 insertions(+) create mode 100644 .gitmodules create mode 100755 debug_ecore.sh create mode 160000 ipwndfu create mode 100644 src/platform/fruity/fruity.zig create mode 100644 src/platform/t8010_aarch64/entry.asm create mode 100644 src/platform/t8010_aarch64/linker.ld create mode 100644 src/platform/t8010_aarch64/main.zig diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..af4c24c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ipwndfu"] + path = ipwndfu + url = https://github.com/N00byEdge/ipwndfu.git diff --git a/debug_ecore.sh b/debug_ecore.sh new file mode 100755 index 0000000..37555bc --- /dev/null +++ b/debug_ecore.sh @@ -0,0 +1,15 @@ +#!/usr/bin/expect +set timeout 2 +spawn telnet 127.0.0.1 4444 +expect "> " +send "targets iphone.ecore0\r" +expect "> " +send "halt\r" +expect "> " +send "targets\r" +expect "> " +send "gdb_breakpoint_override hard\r" +expect "> " +send "exit\r" +spawn gdb-multiarch -ex "target remote :3333" -ex "file zig-cache/Sabaton_t8010_aarch64.elf" -ex "restore zig-cache/Sabaton_t8010_aarch64.elf.bin binary _start" -ex "set \$pc = _start" +interact diff --git a/ipwndfu b/ipwndfu new file mode 160000 index 0000000..feedc79 --- /dev/null +++ b/ipwndfu @@ -0,0 +1 @@ +Subproject commit feedc79fbdfde0f9f9f92c4e9f88b380f8459ad8 diff --git a/src/platform/fruity/fruity.zig b/src/platform/fruity/fruity.zig new file mode 100644 index 0000000..71beb54 --- /dev/null +++ b/src/platform/fruity/fruity.zig @@ -0,0 +1,73 @@ +pub const sabaton = @import("../../sabaton.zig"); +pub const io = sabaton.io_impl.status_uart_mmio_32; +pub const ElfType = [*]u8; +pub const panic = sabaton.panic; + +const std = @import("std"); + +comptime { + asm( + \\.section .data + \\uart_tag: + \\ .8byte 0xf77485dbfeb260f9 // u32 MMIO UART with status + \\ .8byte 0 + \\uart_reg: + \\ .8byte __uart_base + 0x20 + \\uart_status: + \\ .8byte __uart_base + 0x10 + \\uart_status_mask: + \\ .4byte 0x00000004 + \\uart_status_value: + \\ .4byte 0x00000004 + ); + +} + +// We know the page size is 0x4000 +pub fn get_page_size() u64 { + return 0x4000; +} + +export fn _main() void { + const root_tbl = @ptrCast([*]u64, sabaton.pmm.alloc_aligned(get_page_size(), .ReclaimableData).ptr); + @memset(@ptrCast([*]u8, root_tbl), 0, 0x4000); + var root: sabaton.paging.Root = .{ + .ttbr0 = root_tbl, + .ttbr1 = root_tbl, + }; + sabaton.paging.map(0x180000000, 0x180000000, 0x180100000 - 0x180000000, .rwx, .memory, &root, .CanOverlap); + sabaton.paging.apply_paging(&root); + const uart_base = sabaton.near("uart_reg").read(u64) & ~(get_page_size() - 1); + sabaton.paging.map(uart_base, uart_base, get_page_size(), .rw, .mmio, &root, .CannotOverlap); + + // Init uart + asm volatile( + \\uart_init: + \\ // rULCON0 + \\ MOV W1, 0x00000003 // 8 data bits, no parity, no stop bit + \\ STR W1, [%[uart_base], #0x00] + \\ + \\ // rUCON0 + \\ MOV W1, 0x00000005 | (1 << 10) // int/poll mode, no interrupts enabled, NCLK + \\ STR W1, [%[uart_base], #0x04] + \\ + \\ // rUFCON0 + \\ MOV W1, 0x00000000 // Disable fifos + \\ STR W1, [%[uart_base], #0x08] + \\ + \\ // rUMCON0 + \\ MOV W1, 0x00000000 // No flow control + \\ STR W1, [%[uart_base], #0x0C] + \\ + \\ // rUBRDIV0 + \\ MOV W1, 0x0000000C + \\ STR W1, [%[uart_base], #0x28] + : + : [uart_base] "r" (uart_base) + : "X1", "memory" + ); + + sabaton.puts("Hello world!\n"); + //sabaton.paging.detect_page_size(); + //@call(.{.modifier = .always_inline}, sabaton.main, .{}); +} diff --git a/src/platform/t8010_aarch64/entry.asm b/src/platform/t8010_aarch64/entry.asm new file mode 100644 index 0000000..5c20ad5 --- /dev/null +++ b/src/platform/t8010_aarch64/entry.asm @@ -0,0 +1,75 @@ +.global _start + +// SCTLR_EL1 is 0x3050198d on entry + +.section .text.entry +_start: + // Disable interrupts + MSR DAIFSET, #0xF + + ADR X0, _start + ADD X0, X0, #0x80000 + MOV SP, X0 + +// // Disable cache +// MRS X0, SCTLR_EL1 +// AND X0, X0, #~4 +// MSR SCTLR_EL1, X0 + +// LDR X0, =__timer_base +// BL map_device_memory +// MOV W1, 0xA +// STR W1, [X0, 0x88] + +// MOV W1, 0xFFFFFFFF +// STP W1, W1, [X0, 0x8C] +// STP W1, W1, [X0, 0x94] + + MOV X0, #0x100F + MSR SCTLR_EL1, X0 + +// LDR X0, =__timer_base +// BL map_device_memory + +// // Enable UART +// LDR X0, =__uart_base +// BL map_device_memory + +// // rULCON0 +// MOV W1, 0x00000003 // 8 data bits, no parity, no stop bit +// STR W1, [X0, #0x00] + +// // rUCON0 +// MOV W1, 0x00000005 | (1 << 10) // int/poll mode, no interrupts enabled, NCLK +// STR W1, [X0, #0x04] + +// // rUFCON0 +// MOV W1, 0x00000000 // Disable fifos +// STR W1, [X0, #0x08] + +// // rUMCON0 +// MOV W1, 0x00000000 // No flow control +// STR W1, [X0, #0x0C] + +// // rUBRDIV0 +// MOV W1, 0x0000000C +// STR W1, [X0, #0x28] + +// 1: +// DSB ST +// MOV W1, 0x21 +// STR W1, [X0, #0x20] +// B 1b + + B _main + +// map_device_memory: +// LSR X1, X0, #22 +// ADD X2, X1, #0xA0000 +// LSL X1, X1, #22 +// ADD X1, X1, #0x621 +// MOV X3, #0x180000000 +// STR X1, [X3, X2] +// DSB SY +// ISB +// RET diff --git a/src/platform/t8010_aarch64/linker.ld b/src/platform/t8010_aarch64/linker.ld new file mode 100644 index 0000000..1214836 --- /dev/null +++ b/src/platform/t8010_aarch64/linker.ld @@ -0,0 +1,34 @@ +ENTRY(_start) +OUTPUT_FORMAT(elf64-littleaarch64) +OUTPUT_ARCH(aarch64) + +PHDRS { + none PT_NULL FLAGS(0); +} + +__io_base = 0x200000000; +__uart_base = __io_base + 0xA0C0000; +__timer_base = __io_base + 0xF140000; + +__dram_base = 0x800000000; + +SECTIONS { + . = 0x180000000; + .blob : { + __blob_base = .; + *(.text.entry) + *(.text*) + *(.data*) + *(.rodata*) + *(.bss*) + . = ALIGN(16); + __blob_end = .; + } + + . = ALIGN(16K); + __pmm_base = .; + + .eh_frame : { + *(.eh_frame*) + } +} diff --git a/src/platform/t8010_aarch64/main.zig b/src/platform/t8010_aarch64/main.zig new file mode 100644 index 0000000..5040728 --- /dev/null +++ b/src/platform/t8010_aarch64/main.zig @@ -0,0 +1 @@ +usingnamespace @import("../fruity/fruity.zig"); From abd05b0a4b11ba2b7c0b131c021cb1764d4b625a Mon Sep 17 00:00:00 2001 From: N00byEdge Date: Wed, 6 Jan 2021 16:18:51 +0100 Subject: [PATCH 2/4] Change how different targets are built --- build.zig | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 81585d1..9903296 100644 --- a/build.zig +++ b/build.zig @@ -130,7 +130,7 @@ fn qemu_aarch64(b: *Builder, board_name: []const u8, desc: []const u8, dep_elf: "-M", board_name, "-cpu", "cortex-a57", "-drive", b.fmt("if=pflash,format=raw,file={},readonly=on", .{dep.output_path}), - "-drive", "if=pflash,format=raw,file=Zigger.elf,readonly=on", + "-drive", "if=pflash,format=raw,file=test.elf,readonly=on", "-m", "4G", "-serial", "stdio", //"-S", "-s", @@ -144,6 +144,11 @@ fn qemu_aarch64(b: *Builder, board_name: []const u8, desc: []const u8, dep_elf: command_step.dependOn(&run_step.step); } +const Device = struct { + name: []const u8, + arch: builtin.Arch, +}; + pub fn build(b: *Builder) !void { //make_source_blob(b); @@ -153,6 +158,27 @@ pub fn build(b: *Builder) !void { try build_elf(b, builtin.Arch.aarch64, "virt"), ); + { + const elf_devices = &[_]Device{ + }; + + for(elf_devices) |dev| + _ = try build_elf(b, builtin.Arch.aarch64, dev.name); + } + + { + const blob_devices = &[_]Device{ + }; + + for(blob_devices) |dev| { + const elf_file = try build_elf(b, builtin.Arch.aarch64, dev.name); + const blob_file = try blob(b, elf_file, .NotPadded); + var s = b.step(dev.name, b.fmt("Build the blob for {}", .{dev.name})); + s.dependOn(&blob_file.step); + b.default_step.dependOn(s); + } + } + // qemu_riscv(b, // "virt", // "Run riscv64 sabaton on for the qemu virt board", From e075c73019784a4468b8ac33d272ecc07b570053 Mon Sep 17 00:00:00 2001 From: N00byEdge Date: Wed, 6 Jan 2021 16:21:21 +0100 Subject: [PATCH 3/4] Add t8010 target --- build.zig | 1 + 1 file changed, 1 insertion(+) diff --git a/build.zig b/build.zig index 9903296..a875432 100644 --- a/build.zig +++ b/build.zig @@ -168,6 +168,7 @@ pub fn build(b: *Builder) !void { { const blob_devices = &[_]Device{ + .{.name = "t8010", .arch = builtin.Arch.aarch64}, }; for(blob_devices) |dev| { From cadcc73c18cc36068ce3bf1a101cfa725e970176 Mon Sep 17 00:00:00 2001 From: N00byEdge Date: Sun, 4 Apr 2021 19:29:11 +0200 Subject: [PATCH 4/4] Getting stuck... --- build.zig | 2 + src/platform/fruity/fruity.zig | 62 ++++++++++------------ src/platform/t8010_aarch64/entry.S | 79 ++++++++++++++++++++++++++++ src/platform/t8010_aarch64/entry.asm | 75 -------------------------- src/platform/t8010_aarch64/linker.ld | 2 +- src/platform/t8010_aarch64/main.zig | 42 +++++++++++++++ src/sabaton.zig | 1 + 7 files changed, 154 insertions(+), 109 deletions(-) create mode 100644 src/platform/t8010_aarch64/entry.S delete mode 100644 src/platform/t8010_aarch64/entry.asm diff --git a/build.zig b/build.zig index a2c7824..0d5b637 100644 --- a/build.zig +++ b/build.zig @@ -81,6 +81,8 @@ pub fn board_supported(arch: builtin.Arch, target_name: []const u8) bool { return true; if(std.mem.eql(u8, target_name, "pine")) return true; + if(std.mem.eql(u8, target_name, "t8010")) + return true; return false; }, else => return false, diff --git a/src/platform/fruity/fruity.zig b/src/platform/fruity/fruity.zig index 71beb54..4c665c6 100644 --- a/src/platform/fruity/fruity.zig +++ b/src/platform/fruity/fruity.zig @@ -5,40 +5,29 @@ pub const panic = sabaton.panic; const std = @import("std"); -comptime { - asm( - \\.section .data - \\uart_tag: - \\ .8byte 0xf77485dbfeb260f9 // u32 MMIO UART with status - \\ .8byte 0 - \\uart_reg: - \\ .8byte __uart_base + 0x20 - \\uart_status: - \\ .8byte __uart_base + 0x10 - \\uart_status_mask: - \\ .4byte 0x00000004 - \\uart_status_value: - \\ .4byte 0x00000004 - ); +export fn _main() noreturn { + // const root_tbl = @ptrCast([*]u64, sabaton.pmm.alloc_aligned(sabaton.get_page_size(), .ReclaimableData).ptr); + // @memset(@ptrCast([*]u8, root_tbl), 0, 0x4000); + // var root: sabaton.paging.Root = .{ + // .ttbr0 = root_tbl, + // .ttbr1 = root_tbl, + // }; -} + // const sram = @import("root").get_sram(); + // const sram_base = @ptrToInt(sram.ptr); -// We know the page size is 0x4000 -pub fn get_page_size() u64 { - return 0x4000; -} + // const dram = @import("root").get_dram(); + // const dram_base = @ptrToInt(dram.ptr); -export fn _main() void { - const root_tbl = @ptrCast([*]u64, sabaton.pmm.alloc_aligned(get_page_size(), .ReclaimableData).ptr); - @memset(@ptrCast([*]u8, root_tbl), 0, 0x4000); - var root: sabaton.paging.Root = .{ - .ttbr0 = root_tbl, - .ttbr1 = root_tbl, - }; - sabaton.paging.map(0x180000000, 0x180000000, 0x180100000 - 0x180000000, .rwx, .memory, &root, .CanOverlap); - sabaton.paging.apply_paging(&root); - const uart_base = sabaton.near("uart_reg").read(u64) & ~(get_page_size() - 1); - sabaton.paging.map(uart_base, uart_base, get_page_size(), .rw, .mmio, &root, .CannotOverlap); + // // Map SRAM region + // sabaton.paging.map(sram_base, sram_base, sram.len, .rwx, .memory, &root); + // // Map MMIO region + // sabaton.paging.map(0, 0, sram_base, .rw, .mmio, &root); + // // Map DRAM region + // sabaton.paging.map(dram_base, dram_base, dram.len, .rwx, .memory, &root); + + // sabaton.paging.apply_paging(&root); + const uart_base = sabaton.near("uart_reg").read(u64) & ~(sabaton.get_page_size() - 1); // Init uart asm volatile( @@ -46,7 +35,7 @@ export fn _main() void { \\ // rULCON0 \\ MOV W1, 0x00000003 // 8 data bits, no parity, no stop bit \\ STR W1, [%[uart_base], #0x00] - \\ + \\ \\ // rUCON0 \\ MOV W1, 0x00000005 | (1 << 10) // int/poll mode, no interrupts enabled, NCLK \\ STR W1, [%[uart_base], #0x04] @@ -62,12 +51,19 @@ export fn _main() void { \\ // rUBRDIV0 \\ MOV W1, 0x0000000C \\ STR W1, [%[uart_base], #0x28] + \\ + \\ 1: + \\ DSB ST + \\ MOV W1, 0x21 + \\ STR W1, [%[uart_base], #0x20] + \\ B 1b : : [uart_base] "r" (uart_base) : "X1", "memory" ); - sabaton.puts("Hello world!\n"); + while(true) + sabaton.puts("Hello world!\n"); //sabaton.paging.detect_page_size(); //@call(.{.modifier = .always_inline}, sabaton.main, .{}); } diff --git a/src/platform/t8010_aarch64/entry.S b/src/platform/t8010_aarch64/entry.S new file mode 100644 index 0000000..3f07079 --- /dev/null +++ b/src/platform/t8010_aarch64/entry.S @@ -0,0 +1,79 @@ +.global _start + +// SCTLR_EL1 is 0x3050198d on entry + +.section .text.entry +_start: + //B . + + // Disable interrupts + MSR DAIFSET, #0xF + + //ADR X0, _start + //ADD X0, X0, #0x80000 + //MOV SP, X0 + +// // Disable cache +// MRS X0, SCTLR_EL1 +// AND X0, X0, #~4 +// MSR SCTLR_EL1, X0 + +// LDR X0, =__timer_base +// BL map_device_memory +// MOV W1, 0xA +// STR W1, [X0, 0x88] + +// MOV W1, 0xFFFFFFFF +// STP W1, W1, [X0, 0x8C] +// STP W1, W1, [X0, 0x94] + + //MOV X0, #0x1 + +// MOV X0, #0x100F + //MSR SCTLR_EL1, X0 + +// LDR X0, =__timer_base +// BL map_device_memory + +// // // Enable UART +// LDR X0, =__uart_base +// // BL map_device_memory + +// // // rULCON0 +// MOV W1, 0x00000003 // 8 data bits, no parity, no stop bit +// STR W1, [X0, #0x00] + +// // // rUCON0 +// MOV W1, 0x00000005 | (1 << 10) // int/poll mode, no interrupts enabled, NCLK +// STR W1, [X0, #0x04] + +// // // rUFCON0 +// MOV W1, 0x00000000 // Disable fifos +// STR W1, [X0, #0x08] + +// // // rUMCON0 +// MOV W1, 0x00000000 // No flow control +// STR W1, [X0, #0x0C] + +// // // rUBRDIV0 +// MOV W1, 0x0000000C +// STR W1, [X0, #0x28] + +// 1: +// DSB ST +// MOV W1, 0x21 +// STR W1, [X0, #0x20] +// B 1b + + B _main + +// map_device_memory: +// LSR X1, X0, #22 +// ADD X2, X1, #0xA0000 +// LSL X1, X1, #22 +// ADD X1, X1, #0x621 +// MOV X3, #0x180000000 +// STR X1, [X3, X2] +// DSB SY +// ISB +// RET diff --git a/src/platform/t8010_aarch64/entry.asm b/src/platform/t8010_aarch64/entry.asm deleted file mode 100644 index 5c20ad5..0000000 --- a/src/platform/t8010_aarch64/entry.asm +++ /dev/null @@ -1,75 +0,0 @@ -.global _start - -// SCTLR_EL1 is 0x3050198d on entry - -.section .text.entry -_start: - // Disable interrupts - MSR DAIFSET, #0xF - - ADR X0, _start - ADD X0, X0, #0x80000 - MOV SP, X0 - -// // Disable cache -// MRS X0, SCTLR_EL1 -// AND X0, X0, #~4 -// MSR SCTLR_EL1, X0 - -// LDR X0, =__timer_base -// BL map_device_memory -// MOV W1, 0xA -// STR W1, [X0, 0x88] - -// MOV W1, 0xFFFFFFFF -// STP W1, W1, [X0, 0x8C] -// STP W1, W1, [X0, 0x94] - - MOV X0, #0x100F - MSR SCTLR_EL1, X0 - -// LDR X0, =__timer_base -// BL map_device_memory - -// // Enable UART -// LDR X0, =__uart_base -// BL map_device_memory - -// // rULCON0 -// MOV W1, 0x00000003 // 8 data bits, no parity, no stop bit -// STR W1, [X0, #0x00] - -// // rUCON0 -// MOV W1, 0x00000005 | (1 << 10) // int/poll mode, no interrupts enabled, NCLK -// STR W1, [X0, #0x04] - -// // rUFCON0 -// MOV W1, 0x00000000 // Disable fifos -// STR W1, [X0, #0x08] - -// // rUMCON0 -// MOV W1, 0x00000000 // No flow control -// STR W1, [X0, #0x0C] - -// // rUBRDIV0 -// MOV W1, 0x0000000C -// STR W1, [X0, #0x28] - -// 1: -// DSB ST -// MOV W1, 0x21 -// STR W1, [X0, #0x20] -// B 1b - - B _main - -// map_device_memory: -// LSR X1, X0, #22 -// ADD X2, X1, #0xA0000 -// LSL X1, X1, #22 -// ADD X1, X1, #0x621 -// MOV X3, #0x180000000 -// STR X1, [X3, X2] -// DSB SY -// ISB -// RET diff --git a/src/platform/t8010_aarch64/linker.ld b/src/platform/t8010_aarch64/linker.ld index 1214836..88ffe26 100644 --- a/src/platform/t8010_aarch64/linker.ld +++ b/src/platform/t8010_aarch64/linker.ld @@ -13,7 +13,7 @@ __timer_base = __io_base + 0xF140000; __dram_base = 0x800000000; SECTIONS { - . = 0x180000000; + . = 0x180018000; .blob : { __blob_base = .; *(.text.entry) diff --git a/src/platform/t8010_aarch64/main.zig b/src/platform/t8010_aarch64/main.zig index 5040728..9879750 100644 --- a/src/platform/t8010_aarch64/main.zig +++ b/src/platform/t8010_aarch64/main.zig @@ -1 +1,43 @@ usingnamespace @import("../fruity/fruity.zig"); + +comptime { + asm( + \\.section .data + \\uart_tag: + \\ .8byte 0xf77485dbfeb260f9 // u32 MMIO UART with status + \\ .8byte 0 + \\uart_reg: + \\ .8byte __uart_base + 0x20 + \\uart_status: + \\ .8byte __uart_base + 0x10 + \\uart_status_mask: + \\ .4byte 0x00000004 + \\uart_status_value: + \\ .4byte 0x00000004 + ); +} + +// We know the page size is 0x4000 +pub fn get_page_size() u64 { + return 0x4000; +} + +pub fn get_sram() []u8 { + // 0x200000 bytes of sram at 0x180000000 + return @intToPtr([*]u8, 0x180000000)[0..0x200000]; +} + +pub fn get_dram() []u8 { + // 2G of dram at 0x800000000 + return @intToPtr([*]u8, 0x800000000)[0..(2 * 1024 * 1024 * 1024)]; +} + +pub fn get_uart_info() io.Info { + const base = 0x20A0C0000; + return .{ + .uart = @intToPtr(*volatile u32, base + 0x20), + .status = @intToPtr(*volatile u32, base + 0x10), + .mask = 0x00000004, + .value = 0x00000004, + }; +} diff --git a/src/sabaton.zig b/src/sabaton.zig index 84cb685..66be0ca 100644 --- a/src/sabaton.zig +++ b/src/sabaton.zig @@ -25,6 +25,7 @@ pub const debug = @import("builtin").mode == .Debug; pub const safety = std.debug.runtime_safety; pub const upper_half_phys_base = 0xFFFF800000000000; +pub const get_page_size = @import("root").get_page_size; const std = @import("std");