summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sotoudeh <matthew@masot.net>2024-02-25 17:00:59 -0800
committerMatthew Sotoudeh <matthew@masot.net>2024-02-25 17:00:59 -0800
commitb9c2cccd8baa60533ce82c59ef5e084b847bf336 (patch)
treeb8a55be9e99aa28cb799f8f8dde3833b69cbd89e
parent92e159e83514cba3bff7139f1bb1b59baafe1dc4 (diff)
minor
-rw-r--r--.gitignore2
-rw-r--r--Makefile5
-rw-r--r--blink/Makefile41
-rw-r--r--blink/blink.c20
-rw-r--r--blink/gpio.c55
-rw-r--r--blink/gpio.h37
-rw-r--r--blink/memmap.ld72
-rw-r--r--blink/memory.h18
-rw-r--r--blink/start.S30
-rw-r--r--blink/types.h20
-rw-r--r--blink/uart.c72
-rw-r--r--blink/uart.h8
-rw-r--r--bootloader/Makefile5
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
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback