~increscent/rk3128-brom

fa29de59579d123e2d47f6938bb41cb818e548f3 — Robert Williams 2 months ago 73661af
Created DRAM version
4 files changed, 104 insertions(+), 8 deletions(-)

M uart/Makefile
M uart/entry.S
M uart/uart.rs
A uart/uart_dram.lds
M uart/Makefile => uart/Makefile +14 -0
@@ 5,6 5,14 @@ OBJCOPY=$(CROSS_COMPILE)objcopy
OBJDUMP=$(CROSS_COMPILE)objdump
ARM_ELF_FLAGS = -Og -g -marm -Wall -nostdlib -mcpu=cortex-a7

all: uart.bin uart_dram.bin

uart_dram.bin: uart_dram.elf uart_dram.list
	$(OBJCOPY) -O binary \
		--only-section .text \
		--only-section .rodata \
		uart_dram.elf uart_dram.bin

uart.bin: uart.elf uart.list
	$(OBJCOPY) -O binary \
		--only-section .text \


@@ 14,12 22,18 @@ uart.bin: uart.elf uart.list
uart.list: uart.elf
	$(OBJDUMP) -D uart.elf > uart.list

uart_dram.list: uart_dram.elf
	$(OBJDUMP) -D uart_dram.elf > uart_dram.list

uart.o: uart.rs bits.rs
	rustc --emit obj -C opt-level=2 --target=armv7a-none-eabi -o uart.o uart.rs

uart.elf: uart.o entry.S uart.lds
	$(CC) $(ARM_ELF_FLAGS) uart.o entry.S -o uart.elf -T uart.lds

uart_dram.elf: uart.o entry.S uart_dram.lds
	$(CC) $(ARM_ELF_FLAGS) uart.o entry.S -o uart_dram.elf -T uart_dram.lds

.PHONY: reset
reset:
	nrfjprog --family nrf52 -r

M uart/entry.S => uart/entry.S +3 -1
@@ 26,4 26,6 @@ stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}

b main

ldmia sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
ldmia sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}

bx lr

M uart/uart.rs => uart/uart.rs +46 -7
@@ 24,12 24,31 @@ const UART_LCR: *mut u32 = (UART_BASE + 0x0C) as *mut u32;
const UART_LSR: *mut u32 = (UART_BASE + 0x14) as *mut u32;
const UART_USR: *mut u32 = (UART_BASE + 0x7C) as *mut u32;

const DRAM_BASE: u32 = 0x6000_0000;
const DRAM_TEST_BASE: u32 = DRAM_BASE + 0x0000_2000; // So we don't overwrite our DRAM code

#[no_mangle]
pub extern "C" fn main() {
    uart_init();

    uart_puts("Hello, world!\n");

    const WORDS: u32 = 0x1_0000;
    const VALUE: u32 = 0x5C5C5C5C;

    for i in 0..WORDS {
        bits::write((DRAM_TEST_BASE + i * 4) as *mut u32, VALUE);
    }

    busy_wait();

    for i in 0..WORDS {
        let val = bits::read((DRAM_TEST_BASE + i * 4) as *mut u32);
        if val != VALUE {
            uart_putsx("Oh No! ", val);
        }
    }

    loop {
        let c = uart_getc();
        if c == '\r' {


@@ 98,10 117,30 @@ fn uart_getc() -> char {
    return ((bits::read(UART_RBR) & 0xFF) as u8) as char;
}

//fn busy_wait() {
//    for _ in 0..0x00FF {
//        unsafe {
//            core::arch::asm!("nop");
//        }
//    }
//}
fn uart_putx(x: u32) {
    uart_putc('0');
    uart_putc('x');
    for i in 0..8 {
        let b: u8 = ((x >> ((7 - i) * 4)) & 0xF) as u8;
        let c: char = if b < 0xA {
            (b + '0' as u8) as char
        } else {
            ((b - 0xA) + 'A' as u8) as char
        };
        uart_putc(c);
    }
}

fn uart_putsx(s: &str, x: u32) {
    uart_puts(s);
    uart_putx(x);
    uart_puts("\n");
}

fn busy_wait() {
    for _ in 0..0xFFFF {
        unsafe {
            core::arch::asm!("nop");
        }
    }
}

A uart/uart_dram.lds => uart/uart_dram.lds +41 -0
@@ 0,0 1,41 @@
MEMORY
{
    DRAM  : ORIGIN = 0x60000000, LENGTH = 0x00002000
}

SECTIONS
{
    . = 0x0000;
    .text     : {
        . = ALIGN(4);
        *(.entry)
        *(.text)
        *(.text*)
        . = ALIGN(4);
    } > DRAM
    .rodata   : {
        . = ALIGN(4);
        *(.rodata)
        *(.rodata*)
        . = ALIGN(4);
    } > DRAM
    .bss   : {
        . = ALIGN(4);
        _sbss = .;

        *(.bss)
        *(.bss*)

        . = ALIGN(4);
        _ebss = .;
    } > DRAM
    /DISCARD/ : { *(.dynstr*) }
    /DISCARD/ : { *(.dynamic*) }
    /DISCARD/ : { *(.plt*) }
    /DISCARD/ : { *(.interp*) }
    /DISCARD/ : { *(.gnu*) }
    /DISCARD/ : { *(.note*) }
    /DISCARD/ : { *(.debug*) }
    /DISCARD/ : { *(.comment*) }
    /DISCARD/ : { *(.ARM*) }
}