summaryrefslogtreecommitdiff
path: root/rtl/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/gfx')
-rw-r--r--rtl/gfx/firmware/gfx_bootrom.S2
-rw-r--r--rtl/gfx/firmware/link.ld217
-rw-r--r--rtl/gfx/firmware/main.c78
-rw-r--r--rtl/gfx/firmware/mod.mk20
-rw-r--r--rtl/gfx/firmware/start.S64
5 files changed, 379 insertions, 2 deletions
diff --git a/rtl/gfx/firmware/gfx_bootrom.S b/rtl/gfx/firmware/gfx_bootrom.S
index 75f5826..9079e31 100644
--- a/rtl/gfx/firmware/gfx_bootrom.S
+++ b/rtl/gfx/firmware/gfx_bootrom.S
@@ -52,7 +52,7 @@ _start:
and t2, t2, a6
beq t2, zero, .write_done
- andi t0, t0, ~0b11
+ andi t0, t0, 0b111100 # Entendemos words 0-15
bne t0, a3, .wait_axi
sw zero, 0(a0)
# Pass magic & hardware version
diff --git a/rtl/gfx/firmware/link.ld b/rtl/gfx/firmware/link.ld
new file mode 100644
index 0000000..50ac46b
--- /dev/null
+++ b/rtl/gfx/firmware/link.ld
@@ -0,0 +1,217 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright © 2019 Keith Packard
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+ENTRY(_start)
+
+/*
+ * These values should be provided by the application. We'll include
+ * some phony values here to make things link for testing
+ */
+
+MEMORY
+{
+ ram (rwx) :
+ ORIGIN = DEFINED(__ram) ? __ram : 0x00000000,
+ LENGTH = DEFINED(__ram_size) ? __ram_size : 0x00002000
+}
+
+PHDRS
+{
+ ram PT_LOAD;
+}
+
+SECTIONS
+{
+ PROVIDE(__stack = ORIGIN(ram) + LENGTH(ram));
+
+ .init : {
+ KEEP (*(.text.init.enter))
+ KEEP (*(.data.init.enter))
+ KEEP (*(SORT_BY_NAME(.init) SORT_BY_NAME(.init.*)))
+ } >ram AT>ram :ram
+
+ PROVIDE(__img_start = ADDR(.init));
+
+ .text : {
+
+ /* code */
+ *(.text.unlikely .text.unlikely.*)
+ *(.text.startup .text.startup.*)
+ *(.text .text.* .opd .opd.*)
+ *(.gnu.linkonce.t.*)
+ KEEP (*(.fini .fini.*))
+ __text_end = .;
+
+ PROVIDE (__etext = __text_end);
+ PROVIDE (_etext = __text_end);
+ PROVIDE (etext = __text_end);
+
+ /* Need to pre-align so that the symbols come after padding */
+ . = ALIGN(8);
+ } >ram AT>ram :ram
+
+ .rodata : {
+
+ /* read-only data */
+ *(.rdata)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.r.*)
+
+ *(.srodata.cst16)
+ *(.srodata.cst8)
+ *(.srodata.cst4)
+ *(.srodata.cst2)
+ *(.srodata .srodata.*)
+
+ } >ram AT>ram :ram
+
+ .data.rel.ro : {
+
+ /* data that needs relocating */
+ *(.data.rel.ro .data.rel.ro.*)
+
+ } >ram AT>ram :ram
+
+ .data : ALIGN_WITH_INPUT {
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+
+ /* Need to pre-align so that the symbols come after padding */
+ . = ALIGN(8);
+
+ PROVIDE( __global_pointer$ = . + 0x800 );
+ PROVIDE( _gp = . + 0x8000);
+ *(.sdata .sdata.* .sdata2.*)
+ *(.gnu.linkonce.s.*)
+ PROVIDE(__data_end = .);
+
+ . = ALIGN(8);
+ } >ram AT>ram :ram
+
+ PROVIDE(__data_start = ADDR(.data));
+ PROVIDE(__data_source = LOADADDR(.data));
+
+ PROVIDE( __edata = __data_end );
+ PROVIDE( _edata = __data_end );
+ PROVIDE( edata = __data_end );
+ PROVIDE( __data_size = __data_end - __data_start );
+
+ PROVIDE(__img_end = __data_end);
+ PROVIDE(__img_size = __img__end - __img_start);
+
+ .bss (NOLOAD) : {
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+
+ /* Align the heap */
+ . = ALIGN(8);
+ __bss_end = .;
+ } >ram AT>ram :ram
+
+ PROVIDE( __bss_start = ADDR(.bss) );
+ PROVIDE( __end = __bss_end );
+ _end = __bss_end;
+ PROVIDE( end = __bss_end );
+ PROVIDE( __bss_size = __bss_end - __bss_start );
+
+ /* Define a stack region to make sure it fits in memory */
+ .stack (NOLOAD) : {
+ . += (DEFINED(__stack_size) ? __stack_size : 0x00001000);
+ } >ram :ram
+
+ /* Throw away C++ exception handling information */
+
+
+
+ /DISCARD/ : {
+ *(.note .note.*)
+ *(.eh_frame .eh_frame.*)
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ *(.ARM.exidx*)
+ }
+
+
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1. */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions. */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2. */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2. */
+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions. */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* DWARF 3. */
+ .debug_pubtypes 0 : { *(.debug_pubtypes) }
+ .debug_ranges 0 : { *(.debug_ranges) }
+ /* DWARF 5. */
+ .debug_addr 0 : { *(.debug_addr) }
+ .debug_line_str 0 : { *(.debug_line_str) }
+ .debug_loclists 0 : { *(.debug_loclists) }
+ .debug_macro 0 : { *(.debug_macro) }
+ .debug_names 0 : { *(.debug_names) }
+ .debug_rnglists 0 : { *(.debug_rnglists) }
+ .debug_str_offsets 0 : { *(.debug_str_offsets) }
+ .debug_sup 0 : { *(.debug_sup) }
+ .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+}
diff --git a/rtl/gfx/firmware/main.c b/rtl/gfx/firmware/main.c
new file mode 100644
index 0000000..f75a9cb
--- /dev/null
+++ b/rtl/gfx/firmware/main.c
@@ -0,0 +1,78 @@
+struct hostif_ctrl
+{
+ unsigned arint : 1;
+ unsigned awint : 1;
+ unsigned rsvd2 : 6;
+ unsigned arvalid : 1;
+ unsigned awvalid : 1;
+ unsigned rdone : 1;
+ unsigned wvalid : 1;
+ unsigned bdone : 1;
+ unsigned rsvd13 : 19;
+};
+
+struct hostif_ar
+{
+ unsigned valid : 1;
+ unsigned rsvd1 : 1;
+ unsigned addr : 30;
+};
+
+struct hostif_aw
+{
+ unsigned valid : 1;
+ unsigned rsvd1 : 1;
+ unsigned addr : 30;
+};
+
+struct hostif_r
+{
+ unsigned data : 32;
+};
+
+struct hostif_w
+{
+ unsigned data : 32;
+};
+
+struct hostif_b0
+{
+ unsigned valid : 1;
+ unsigned rsvd1 : 31;
+};
+
+#define HOSTIF_BASE 0x00300000
+#define HOSTIF_CTRL (*(volatile struct hostif_ctrl *)(HOSTIF_BASE + 0x00))
+#define HOSTIF_AR (*(volatile struct hostif_ar *) (HOSTIF_BASE + 0x04))
+#define HOSTIF_AW (*(volatile struct hostif_aw *) (HOSTIF_BASE + 0x08))
+#define HOSTIF_R (*(volatile struct hostif_r *) (HOSTIF_BASE + 0x0c))
+#define HOSTIF_W (*(volatile struct hostif_w *) (HOSTIF_BASE + 0x10))
+#define HOSTIF_B (*(volatile struct hostif_b *) (HOSTIF_BASE + 0x14))
+
+int main(unsigned magic, unsigned hw_rev)
+{
+ while (1) {
+ struct hostif_ar ar;
+ while (!(ar = HOSTIF_AR).valid);
+
+ switch (ar.addr & 3) {
+ case 0b00:
+ HOSTIF_R.data = magic;
+ break;
+
+ case 0b01:
+ HOSTIF_R.data = hw_rev;
+ break;
+
+ case 0b10:
+ HOSTIF_R.data = hw_rev;
+ break;
+
+ case 0b11:
+ HOSTIF_R.data = 1;
+ break;
+ }
+
+ while (!HOSTIF_CTRL.rdone);
+ }
+}
diff --git a/rtl/gfx/firmware/mod.mk b/rtl/gfx/firmware/mod.mk
index 2a37a9c..087aadc 100644
--- a/rtl/gfx/firmware/mod.mk
+++ b/rtl/gfx/firmware/mod.mk
@@ -1,4 +1,4 @@
-cores := gfx_bootrom
+cores := gfx_bootrom gfx_firmware
define core/gfx_bootrom
$(this)/cross := riscv32-none-elf-
@@ -15,3 +15,21 @@ define core/gfx_bootrom
$(this)/makehex_src := gfx_bootrom.bin
$(this)/makehex_obj := gfx_bootrom.hex
endef
+
+define core/gfx_firmware
+ $(this)/cross := riscv32-none-elf-
+ $(this)/hooks := cc objcopy bin2rel obj
+
+ $(this)/obj_deps := /$(here)link.ld
+
+ $(this)/cc_files := start.S main.c
+ $(this)/cc_flags = -g -O3 -march=rv32imc -mabi=ilp32
+ $(this)/ld_flags := -nostartfiles -nostdlib -T$(here)link.ld
+ $(this)/ld_binary := gfx_fw
+
+ $(this)/objcopy_src := gfx_fw
+ $(this)/objcopy_obj := gfx_fw.bin
+
+ $(this)/bin2rel_src := gfx_fw.bin
+ $(this)/bin2rel_obj := gfx_fw_payload.o
+endef
diff --git a/rtl/gfx/firmware/start.S b/rtl/gfx/firmware/start.S
new file mode 100644
index 0000000..c696119
--- /dev/null
+++ b/rtl/gfx/firmware/start.S
@@ -0,0 +1,64 @@
+.section .text.init.enter
+.global _start
+
+_start:
+ li t0, 0x4a7a7b0c
+ beq a0, t0, _magic_ok
+ ret
+
+_magic_ok:
+ lui t0, %hi(__img_start)
+ addi t0, t0, %lo(__img_start)
+ la t1, __img_start
+ la t2, _early_copy_end
+ sub t2, t2, t1
+
+_early_copy_loop:
+ lw t3, 0(t1)
+ sw t3, 0(t0)
+ addi t0, t0, 4
+ addi t1, t1, 4
+ addi t2, t2, -4
+ bgtz t2, _early_copy_loop
+
+ lui t2, %hi(_running_on_ram)
+ addi t2, t2, %lo(_running_on_ram)
+ jr t2
+
+_running_on_ram:
+ la t2, __img_end
+ sub t2, t2, t0
+
+_full_copy_loop:
+ lw t3, 0(t1)
+ lw t4, 4(t1)
+ lw t5, 8(t1)
+ lw t6, 12(t1)
+ sw t3, 0(t0)
+ sw t4, 4(t0)
+ sw t5, 8(t0)
+ sw t6, 12(t0)
+ addi t0, t0, 16
+ addi t1, t1, 16
+ addi t2, t2, -16
+ bgtz t2, _full_copy_loop
+
+.balign 4
+_early_copy_end:
+ la t0, __bss_start
+ la t2, __bss_end
+ sub t2, t2, t0
+
+_clear_bss_loop:
+ sw zero, 0(t0)
+ sw zero, 4(t0)
+ sw zero, 8(t0)
+ sw zero, 12(t0)
+ addi t0, t0, 16
+ addi t2, t2, -16
+ bgtz t2, _clear_bss_loop
+
+_start_done:
+ la sp, __stack
+ call main
+ j .