diff options
author | Matthew Sotoudeh <matthew@masot.net> | 2024-02-25 17:00:59 -0800 |
---|---|---|
committer | Matthew Sotoudeh <matthew@masot.net> | 2024-02-25 17:00:59 -0800 |
commit | b9c2cccd8baa60533ce82c59ef5e084b847bf336 (patch) | |
tree | b8a55be9e99aa28cb799f8f8dde3833b69cbd89e | |
parent | 92e159e83514cba3bff7139f1bb1b59baafe1dc4 (diff) |
minor
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | blink/Makefile | 41 | ||||
-rw-r--r-- | blink/blink.c | 20 | ||||
-rw-r--r-- | blink/gpio.c | 55 | ||||
-rw-r--r-- | blink/gpio.h | 37 | ||||
-rw-r--r-- | blink/memmap.ld | 72 | ||||
-rw-r--r-- | blink/memory.h | 18 | ||||
-rw-r--r-- | blink/start.S | 30 | ||||
-rw-r--r-- | blink/types.h | 20 | ||||
-rw-r--r-- | blink/uart.c | 72 | ||||
-rw-r--r-- | blink/uart.h | 8 | ||||
-rw-r--r-- | bootloader/Makefile | 5 |
13 files changed, 381 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7fbd128 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.*.sw* +build diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..64f908d --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +.PHONY: flash-blink + +flash-blink: + make -B -C blink + ./ox-flash/ox-flash -payload blink/build/blink.bin diff --git a/blink/Makefile b/blink/Makefile new file mode 100644 index 0000000..87d82d3 --- /dev/null +++ b/blink/Makefile @@ -0,0 +1,41 @@ +# adapted from +# https://github.com/Akshay-Srivatsan/ox64-baremetal-setup/blob/main/examples/Makefile + +MEMMAP=memmap.ld + +RV=riscv64-unknown-elf +CC=$(RV)-gcc +AS=$(RV)-as +LD=$(RV)-ld +OBJCOPY=$(RV)-objcopy +OBJDUMP=$(RV)-objdump + +CFLAGS += -ffreestanding -nostdlib -nostartfiles -Wall -Werror \ + -Wno-unused-function -march=rv64imac -mabi=lp64 -Iinc -mcmodel=medany +ASFLAGS += -ffreestanding -nostdlib -nostartfiles -Wall -Werror \ + -Wno-unused-function -march=rv64imac -mabi=lp64 -Iinc -mcmodel=medany +LDFLAGS += -march=rv64imac -mabi=lp64 -nostdlib -nostartfiles -mcmodel=medany + +OBJECTS = build/blink.o \ + build/start.o \ + build/gpio.o \ + build/uart.o + +all: build/blink.bin + +build/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $< $(CFLAGS) -c -o $@ + +build/%.o: %.S + @mkdir -p $(dir $@) + $(CC) $< $(ASFLAGS) -c -o $@ + +build/%.elf: $(OBJECTS) $(MEMMAP) + @mkdir -p $(dir $@) + $(CC) $(LDFLAGS) -T$(MEMMAP) $(SHARED) $(OBJECTS) -o $@ + +build/%.bin build/%.list: build/%.elf + @mkdir -p $(dir $@) + $(OBJCOPY) $< -Obinary $@ + $(OBJDUMP) $< -D > $(@:.bin=.list) diff --git a/blink/blink.c b/blink/blink.c new file mode 100644 index 0000000..b59c950 --- /dev/null +++ b/blink/blink.c @@ -0,0 +1,20 @@ +#include "gpio.h" +#include "uart.h" + +extern unsigned __bss_start__; +extern unsigned __bss_end__; + +int notmain() { + unsigned *bss = &__bss_start__; + unsigned *bss_end = &__bss_end__; + while (bss < bss_end) { + *bss++ = 0; + } + + size_t pin = 29; + gpio_set_function(pin, GPIO_GPIO); + gpio_set_input(pin, 0); + gpio_set_output(pin, 1); + + return 0; +} diff --git a/blink/gpio.c b/blink/gpio.c new file mode 100644 index 0000000..39c5d51 --- /dev/null +++ b/blink/gpio.c @@ -0,0 +1,55 @@ +#include "gpio.h" +#include "memory.h" + +struct PACKED gpio_config { + bool input_enable: 1; + bool schmitt_trigger_enable: 1; + unsigned drive_strength: 2; + bool pullup_enable: 1; + bool pulldown_enable: 1; + bool output_enable: 1; + unsigned : 1; + unsigned alternate_function: 5; + unsigned : 3; + unsigned interrupt_mode: 4; + bool interrupt_clear: 1; + bool interrupt_state: 1; + bool interrupt_mask: 1; + unsigned: 1; + bool output_value: 1; + bool output_set: 1; + bool output_clear: 1; + unsigned: 1; + bool input_value: 1; + unsigned: 1; + unsigned io_mode: 2; +}; + +static volatile struct gpio_config *const GPIO_CONFIG = (volatile struct gpio_config *)0x200008c4; + +enum gpio_io_mode { + IO_MODE_NORMAL, + IO_MODE_SET_CLEAR, + IO_MODE_BUFFER, + IO_MODE_CACHE, +}; + +void gpio_set_input(gpio_t pin, bool enable) { + struct gpio_config x = get32_type(struct gpio_config, GPIO_CONFIG + pin); + x.io_mode = IO_MODE_SET_CLEAR; + x.input_enable = enable; + put32_type(struct gpio_config, GPIO_CONFIG + pin, x); +} + +void gpio_set_output(gpio_t pin, bool enable) { + struct gpio_config x = get32_type(struct gpio_config, GPIO_CONFIG + pin); + x.io_mode = IO_MODE_SET_CLEAR; + x.output_enable = enable; + put32_type(struct gpio_config, GPIO_CONFIG + pin, x); +} + +void gpio_set_function(gpio_t pin, enum gpio_alternate_function function) { + struct gpio_config x = get32_type(struct gpio_config, GPIO_CONFIG + pin); + x.alternate_function = function; + put32_type(struct gpio_config, GPIO_CONFIG + pin, x); +} diff --git a/blink/gpio.h b/blink/gpio.h new file mode 100644 index 0000000..1f0d651 --- /dev/null +++ b/blink/gpio.h @@ -0,0 +1,37 @@ +#pragma once + +#include "types.h" + +enum gpio_alternate_function { + GPIO_SDH, + GPIO_SPI0, + GPIO_FLASH, + GPIO_I2S, + GPIO_PDM, + GPIO_I2C0, + GPIO_I2C1, + GPIO_UART, + GPIO_EMAC, + GPIO_CAM, + GPIO_ANALOG, + GPIO_GPIO, + GPIO_PWM0, + GPIO_PWM1, + GPIO_SPI1, + GPIO_I2C2, + GPIO_I2C3, + GPIO_MM_UART, + GPIO_DBI_B, + GPIO_DBI_C, + GPIO_DPI, + GPIO_JTAG_LP, + GPIO_JTAG_M0, + GPIO_JTAG_D0, + GPIO_CLOCK_OUT, +}; + +typedef size_t gpio_t; + +void gpio_set_input(gpio_t pin, bool enable); +void gpio_set_output(gpio_t pin, bool enable); +void gpio_set_function(gpio_t pin, enum gpio_alternate_function function); diff --git a/blink/memmap.ld b/blink/memmap.ld new file mode 100644 index 0000000..1aacaf3 --- /dev/null +++ b/blink/memmap.ld @@ -0,0 +1,72 @@ +OUTPUT_ARCH(riscv) +OUTPUT_FORMAT(elf64-littleriscv) + +ENTRY (_start) + +MEMORY +{ + OCRAM (rwx) : ORIGIN = 0x22020000, LENGTH = 64K + WRAM (rwx) : ORIGIN = 0x22030000, LENGTH = 160K + DRAM (rwx) : ORIGIN = 0x3ef80000, LENGTH = 16K + VRAM (rwx) : ORIGIN = 0x3f000000, LENGTH = 16K + XRAM (rwx) : ORIGIN = 0x40000000, LENGTH = 16K + + PSRAM (rwx) : ORIGIN = 0x50000000, LENGTH = 64M + FLASH (rx) : ORIGIN = 0x58000000, LENGTH = 64M + + ROM (rx) : ORIGIN = 0x90000000, LENGTH = 128K +} + +SECTIONS { + . = ORIGIN(PSRAM); + __stack_size = 2K; + + .text : { + __code_start__ = .; + KEEP(*(.text.boot)) + *(.text*) + . = ALIGN(4); + __code_end__ = .; + } + + .rodata . : { + . = ALIGN(4); + __global_pointer$ = . + 0x800; + *(.rodata*) + *(.srodata*) + . = ALIGN(8); + } + + .sdata : { + . = ALIGN(4); + __global_pointer$ = . + 0x800; + *(.sdata*) + *(.srodata*) + } + + .data : { + __data_start__ = .; + *(.data*) + __data_end__ = .; + } + + .bss : { + __bss_start__ = .; + *(.bss*) + *(.sbss*) + *(COMMON) + __bss_end__ = .; + . = ALIGN(8); + } + + .kstack (NOLOAD) : { + . = ALIGN(16), + . += 4K, + __stack_start = .; + } + + /DISCARD/ : { + *(.comment) + *(.riscv.attributes) + } +} diff --git a/blink/memory.h b/blink/memory.h new file mode 100644 index 0000000..a4f204c --- /dev/null +++ b/blink/memory.h @@ -0,0 +1,18 @@ +#pragma once +#include <stdint.h> + +extern void put32(volatile uint32_t *addr, uint32_t value); +extern uint32_t get32(volatile uint32_t *addr); + +#define get32_type(T, addr) \ + ({ \ + _Static_assert(sizeof(T) == 4); \ + uint32_t raw = get32((volatile uint32_t *)addr); \ + *(T *)&raw; \ + }) +#define put32_type(T, addr, val) \ + ({ \ + _Static_assert(sizeof(T) == 4); \ + uint32_t raw = *(uint32_t *)&val; \ + put32((volatile uint32_t *)addr, raw); \ + }) diff --git a/blink/start.S b/blink/start.S new file mode 100644 index 0000000..1d3eb47 --- /dev/null +++ b/blink/start.S @@ -0,0 +1,30 @@ +// based on dddrrree's fork based on dwelch's start for bootloader. + +// To keep this in the first portion of the binary. +.section ".text.boot" + +// give ourselves a stack +.globl _start +_start: + .option push + .option norelax + la gp, __global_pointer$ + .option pop + la sp, __stack_start + call notmain +halt: + nop + j halt + +.globl put32 +put32: + fence rw,rw + sw a1, 0(a0) + fence rw,rw + ret + +.globl get32 +get32: + fence rw,rw + lw a0, 0(a0) + ret diff --git a/blink/types.h b/blink/types.h new file mode 100644 index 0000000..a043494 --- /dev/null +++ b/blink/types.h @@ -0,0 +1,20 @@ +#pragma once + +#define PACKED __attribute__((packed)) + +#include <stdbool.h> +#include <stdint.h> +#include <stddef.h> + +#define i8 int8_t +#define i16 int16_t +#define i32 int32_t +#define i64 int64_t +#define isize ssize_t + +#define u8 uint8_t +#define u16 uint16_t +#define u32 uint32_t +#define u64 uint64_t +#define usize size_t +#define uint unsigned diff --git a/blink/uart.c b/blink/uart.c new file mode 100644 index 0000000..f4f6732 --- /dev/null +++ b/blink/uart.c @@ -0,0 +1,72 @@ +#include <stdbool.h> + +#include "types.h" +#include "uart.h" +#include "memory.h" + +// from the bl808 reference manual +struct uart { + u32 tx_config; + u32 rx_config; + u32 bit_prd; + u32 data_config; + u32 tx_ir_position; + u32 rx_ir_position; + u32 rx_rto_timer; + u32 sw_mode; + u32 int_sts; + u32 int_mask; + u32 int_clear; + u32 int_en; + u32 status; + u32 sts_urx_abr_prd; + u32 rx_abr_prd_b01; + u32 rx_abr_prd_b23; + u32 rx_abr_prd_b45; + u32 rx_abr_prd_b67; + u32 rx_abr_pw_tol; + u32 rx_bcr_int_cfg; + u32 unknown; + u32 tx_rs485_cfg; + u32 reserved[10]; + u32 fifo_config_0; + u32 fifo_config_1; + u32 fifo_wdata; + u32 fifo_rdata; +}; + +static volatile struct uart *const UART0 = (volatile struct uart *)0x2000A000; +#define UART_CLOCK 40000000UL + +bool uart_can_putc(void) { + return true; + return (get32(&UART0->fifo_config_1) & 0x3f) != 0; +} + +void uart_putc(char c) { + while (!uart_can_putc()) + ; + put32(&UART0->fifo_wdata, c); +} + +void uart_puts(const char *c) { + while (*c) { + uart_putc(*c++); + } +} + +void uart_init(unsigned baud) { + // p302 + uint32_t val = 0; + val |= 1 << 0; // enable + val |= 1 << 2; // freerun mode + val |= 7 << 8; // 8 data bits + val |= 2 << 11; // 1 stop bit + put32(&UART0->tx_config, val); + + uint32_t bit_period_value = + (2 * UART_CLOCK / baud) - 1; // for some reason the uart clock seems to be + // off by a factor of 2 from what we expect + val = bit_period_value << 16 | bit_period_value; + put32(&UART0->bit_prd, val); +} diff --git a/blink/uart.h b/blink/uart.h new file mode 100644 index 0000000..dd9721a --- /dev/null +++ b/blink/uart.h @@ -0,0 +1,8 @@ +#pragma once +#include <stdbool.h> +#include <stdint.h> + +bool uart_can_putc(void); +void uart_putc(char c); +void uart_puts(const char *c); +void uart_init(unsigned baud); diff --git a/bootloader/Makefile b/bootloader/Makefile index c2ef1f4..3576608 100644 --- a/bootloader/Makefile +++ b/bootloader/Makefile @@ -19,14 +19,11 @@ CFLAGS=$(COMMON_FLAGS) -O$(OPT) ASFLAGS=$(COMMON_FLAGS) LDFLAGS=-nostdlib -flto -all: tags $(TARGET) +all: $(TARGET) clean: rm -f *.o *.elf *.bin *.d tags -tags: $(wildcard *.[chS]) - ctags *.[chS] - ifneq ($(MAKECMDGOALS),clean) -include $(wildcard *.d) endif |