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/build.zig b/build.zig index bdb535e..c82a88e 100644 --- a/build.zig +++ b/build.zig @@ -83,6 +83,8 @@ pub fn board_supported(arch: 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, @@ -251,6 +253,7 @@ pub fn build(b: *Builder) !void { { const blob_devices = &[_]Device{ + .{.name = "t8010", .arch = .aarch64}, .{.name = "pine", .arch = .aarch64}, }; 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..4c665c6 --- /dev/null +++ b/src/platform/fruity/fruity.zig @@ -0,0 +1,69 @@ +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"); + +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); + + // const dram = @import("root").get_dram(); + // const dram_base = @ptrToInt(dram.ptr); + + // // 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( + \\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] + \\ + \\ 1: + \\ DSB ST + \\ MOV W1, 0x21 + \\ STR W1, [%[uart_base], #0x20] + \\ B 1b + : + : [uart_base] "r" (uart_base) + : "X1", "memory" + ); + + 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/linker.ld b/src/platform/t8010_aarch64/linker.ld new file mode 100644 index 0000000..88ffe26 --- /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 { + . = 0x180018000; + .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..9879750 --- /dev/null +++ b/src/platform/t8010_aarch64/main.zig @@ -0,0 +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 06d6b06..87df097 100644 --- a/src/sabaton.zig +++ b/src/sabaton.zig @@ -29,6 +29,7 @@ pub const arch = if(@hasField(std.builtin, "arch")) std.builtin.arch else std.Ta pub const endian = if(@hasField(std.builtin, "endian")) std.builtin.endian else arch.endian(); pub const upper_half_phys_base = 0xFFFF800000000000; +pub const get_page_size = @import("root").get_page_size; const std = @import("std");