vxGOS - v0.7.0-13 : RaspberryPi3b bootstrap and MiniUART driver
*add* > [boards] | [raspi3b] add auxiliary hardware module bitfields (power, IRQ and UART1) | [raspi3b] add gpio hardware module bitfields | [raspi3b] add bootloader fake entry (test entry) | [raspi3b] add bootloader stack *fix* > [boards] | [raspi3b] patch missing image size in image header | [raspi3b] add missing "dfont()" BIOS build request > [bootloader] | [linker] move bootloader stack
This commit is contained in:
parent
4ea5758074
commit
b316b98004
1
.nvimrc
1
.nvimrc
|
@ -8,6 +8,7 @@ let g:ale_cpp_gcc_executable = 'sh-elf-vhex-gcc'
|
|||
let s:_hdrflags = [
|
||||
\ '-I./vxgos/bootloader/include',
|
||||
\ '-I./vxgos/bootloader/boards/fxcg50/include/',
|
||||
\ '-I./vxgos/bootloader/boards/raspi3b/include/',
|
||||
\ ]
|
||||
let s:_cflags = [
|
||||
\ '-DFXCG50',
|
||||
|
|
|
@ -106,7 +106,6 @@ def generate_image(prefix_build, bootloader_path, _):
|
|||
# (todo) os/kernel
|
||||
image_size = len(image)
|
||||
|
||||
print(image_size)
|
||||
mov0 = 0xd2800000 | (((image_size & 0x000000000000ffff) >> 0) << 5)
|
||||
mov1 = 0xf2a00000 | (((image_size & 0x00000000ffff0000) >> 16) << 5)
|
||||
mov2 = 0xf2c00000 | (((image_size & 0x0000ffff00000000) >> 32) << 5)
|
||||
|
@ -117,6 +116,8 @@ def generate_image(prefix_build, bootloader_path, _):
|
|||
image[0x48:0x4c] = mov2.to_bytes(4, 'little')
|
||||
image[0x4c:0x50] = mov3.to_bytes(4, 'little')
|
||||
|
||||
image[0x0c:0x14] = image_size.to_bytes(8, 'little')
|
||||
|
||||
bzimage = f"{prefix_build}/vxgos.bzImage"
|
||||
if os.path.exists(bzimage):
|
||||
os.remove(bzimage)
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
#ifndef VXGOS_BOOTLOADER_RASPI3B_AUXILIARY_H
|
||||
#define VXGOS_BOOTLOADER_RASPI3B_AUXILIARY_H
|
||||
|
||||
#include "raspi3b/utils.h"
|
||||
|
||||
//---
|
||||
// BCM2837 Auxiliary peripheral
|
||||
//
|
||||
// @note
|
||||
// <> all of theses bits is based on the documentation on
|
||||
// https://cs140e.sergio.bz/docs/BCM2837-ARM-Peripherals.pdf
|
||||
// <> we use MSB instead of LSB packed struct because of the architecture
|
||||
// note that this cannot be modified with compiler flags.
|
||||
//---
|
||||
|
||||
struct __bcm2837_aux
|
||||
{
|
||||
/* [0x00215000] pending interrupt flags */
|
||||
const u32_union(AUX_IRQ,
|
||||
uint32_t MiniUART :1; /* Enable Mini UART */
|
||||
uint32_t SPI1 :1; /* Enable SPI1 */
|
||||
uint32_t SPI2 :1; /* Enable SPI2 */
|
||||
uint32_t :29;
|
||||
);
|
||||
/* [0x00215004] enable auxialiary modules */
|
||||
u32_union(AUX_ENABLE,
|
||||
uint32_t MiniUART :1; /* Enable Mini UART */
|
||||
uint32_t SPI1 :1; /* Enable SPI1 */
|
||||
uint32_t SPI2 :1; /* Enable SPI2 */
|
||||
uint32_t :29;
|
||||
);
|
||||
pad(0x38);
|
||||
|
||||
//---
|
||||
// Mini UART register
|
||||
//---
|
||||
|
||||
/* [0x00215040] used to write or write data from the FIFOs. */
|
||||
u32_union(AUX_MU_IO,
|
||||
uint32_t DATA : 8;
|
||||
uint32_t :24;
|
||||
);
|
||||
/* [0x00215044] used to enable interrupts */
|
||||
u32_union(AUX_MU_IER,
|
||||
uint32_t RIE :1; /* Receive Interrupt Enable */
|
||||
uint32_t TIE :1; /* Transmit Interrupt Enable */
|
||||
uint32_t :30;
|
||||
);
|
||||
/* [0x00215048] Interrupt Status */
|
||||
u32_union(AUX_MU_IIR,
|
||||
uint32_t PENDING :1; /* =0 if pending interrupts */
|
||||
uint32_t TXFLUSH :1; /* Receiver holds valid byte */
|
||||
uint32_t RXFLUSH :1; /* Transmit holding register empty */
|
||||
uint32_t :3;
|
||||
uint32_t FIFO :2; /* FIFO enabled (TODO: check RX/TX) */
|
||||
uint32_t :24;
|
||||
);
|
||||
/* [0x0021504c] Control Line Data */
|
||||
u32_union(AUX_MU_LCR,
|
||||
uint32_t CHR :2; /* Character Length */
|
||||
uint32_t :4;
|
||||
uint32_t BREAK :1; /* Pull down the UART1_TX line */
|
||||
uint32_t DLAB :1; /* Give access to the Baudrate reg */
|
||||
uint32_t :24;
|
||||
);
|
||||
/* [0x00215050] Control the 'modem' signals */
|
||||
u32_union(AUX_MU_MCR,
|
||||
uint32_t :1;
|
||||
uint32_t RTS :1; /* Pull down the UART1_RTS line */
|
||||
uint32_t :30;
|
||||
);
|
||||
/* [0x00215054] Data Status */
|
||||
const u32_union(AUX_MU_LSR,
|
||||
uint32_t DRIE :1; /* Received Data Ready */
|
||||
uint32_t ORER :1; /* Overrrun Error */
|
||||
uint32_t :3;
|
||||
uint32_t TDFE :1; /* Transmitter Empty */
|
||||
uint32_t TDFI :1; /* Transmitter Idle */
|
||||
uint32_t :25;
|
||||
);
|
||||
/* [0x00215058] Data 'modem' status */
|
||||
const u32_union(AUX_MU_MSR,
|
||||
uint32_t :4;
|
||||
uint32_t CTS :1; /* Inverse of the UART1_CTS input */
|
||||
uint32_t :27;
|
||||
);
|
||||
/* [0x0021505c] Single Byte Storage */
|
||||
u32_union(AUX_MU_SCRATCH,
|
||||
uint32_t SCRATCH :8; /* SDC byte extra */
|
||||
uint32_t :24;
|
||||
);
|
||||
/* [0x00215060] Access to Extra features */
|
||||
u32_union(AUX_MU_CNTL,
|
||||
uint32_t RE :1; /* Receiver Enable */
|
||||
uint32_t TE :1; /* Transmitter Enable */
|
||||
uint32_t ERAF :1; /* Enable Rx Auto Flow-control */
|
||||
uint32_t ETAF :1; /* Enable Tx Auto Flow-control */
|
||||
uint32_t RTS_AUTO :2; /* Rx Auto Flow Level */
|
||||
uint32_t RTS_ASSERT :1; /* Rx RTS invert */
|
||||
uint32_t CTS_ASSERT :1; /* CTS invert */
|
||||
uint32_t :24;
|
||||
);
|
||||
/* [0x00215064] Internal Status */
|
||||
const u32_union(AUX_MU_STAT,
|
||||
uint32_t SYMA :1; /* Symbol Available */
|
||||
uint32_t SPCA :1; /* Tx can accept a least one byte */
|
||||
uint32_t RII :1; /* Rx is idle */
|
||||
uint32_t TII :1; /* Tx is idle */
|
||||
uint32_t ROVRE :1; /* Rx overrun */
|
||||
uint32_t TDFF :1; /* Tx FIFO is full */
|
||||
uint32_t RTS :1; /* status of the UART1_RTS line */
|
||||
uint32_t CTS :1; /* status of the UART1_CTS line */
|
||||
uint32_t TDFE :1; /* Tx FIFO is empty */
|
||||
uint32_t TEND :1; /* Tx End */
|
||||
uint32_t :6;
|
||||
uint32_t RFFL :4; /* Rx FIFO fill level */
|
||||
uint32_t :4;
|
||||
uint32_t TFFL :4; /* Tx FIFO fill level */
|
||||
uint32_t :4;
|
||||
);
|
||||
/* [0x00215068] baudrate counter */
|
||||
u32_union(AUX_MU_BAUD,
|
||||
uint32_t BAUD :16; /* Baudrate */
|
||||
uint32_t :16;
|
||||
);
|
||||
} VPACKED(4);
|
||||
|
||||
#define BCM2837_AUXILIARY (*((volatile struct __bcm2837_aux *)0x3f215000))
|
||||
|
||||
#endif /* VXGOS_BOOTLOADER_RASPI3B_AUXILIARY_H */
|
|
@ -0,0 +1,227 @@
|
|||
#ifndef VXGOS_BOOTLOADER_RASPI3B_GPIO_H
|
||||
#define VXGOS_BOOTLOADER_RASPI3B_GPIO_H
|
||||
|
||||
#include "raspi3b/utils.h"
|
||||
|
||||
//---
|
||||
// Macros helpers
|
||||
//---
|
||||
|
||||
#define u32_pin0(name) \
|
||||
u32_union(name, \
|
||||
uint32_t PIN0 :1; \
|
||||
uint32_t PIN1 :1; \
|
||||
uint32_t PIN2 :1; \
|
||||
uint32_t PIN3 :1; \
|
||||
uint32_t PIN4 :1; \
|
||||
uint32_t PIN5 :1; \
|
||||
uint32_t PIN6 :1; \
|
||||
uint32_t PIN7 :1; \
|
||||
uint32_t PIN8 :1; \
|
||||
uint32_t PIN9 :1; \
|
||||
uint32_t PIN10 :1; \
|
||||
uint32_t PIN11 :1; \
|
||||
uint32_t PIN12 :1; \
|
||||
uint32_t PIN13 :1; \
|
||||
uint32_t PIN14 :1; \
|
||||
uint32_t PIN15 :1; \
|
||||
uint32_t PIN16 :1; \
|
||||
uint32_t PIN17 :1; \
|
||||
uint32_t PIN18 :1; \
|
||||
uint32_t PIN19 :1; \
|
||||
uint32_t PIN20 :1; \
|
||||
uint32_t PIN21 :1; \
|
||||
uint32_t PIN22 :1; \
|
||||
uint32_t PIN23 :1; \
|
||||
uint32_t PIN24 :1; \
|
||||
uint32_t PIN25 :1; \
|
||||
uint32_t PIN26 :1; \
|
||||
uint32_t PIN27 :1; \
|
||||
uint32_t PIN28 :1; \
|
||||
uint32_t PIN29 :1; \
|
||||
uint32_t PIN30 :1; \
|
||||
uint32_t PIN31 :1; \
|
||||
);
|
||||
|
||||
#define u32_pin1(name) \
|
||||
u32_union(name, \
|
||||
uint32_t PIN32 :1; \
|
||||
uint32_t PIN33 :1; \
|
||||
uint32_t PIN34 :1; \
|
||||
uint32_t PIN35 :1; \
|
||||
uint32_t PIN36 :1; \
|
||||
uint32_t PIN37 :1; \
|
||||
uint32_t PIN38 :1; \
|
||||
uint32_t PIN39 :1; \
|
||||
uint32_t PIN40 :1; \
|
||||
uint32_t PIN41 :1; \
|
||||
uint32_t PIN42 :1; \
|
||||
uint32_t PIN43 :1; \
|
||||
uint32_t PIN44 :1; \
|
||||
uint32_t PIN45 :1; \
|
||||
uint32_t PIN46 :1; \
|
||||
uint32_t PIN47 :1; \
|
||||
uint32_t PIN48 :1; \
|
||||
uint32_t PIN49 :1; \
|
||||
uint32_t PIN50 :1; \
|
||||
uint32_t PIN51 :1; \
|
||||
uint32_t PIN52 :1; \
|
||||
uint32_t PIN53 :1; \
|
||||
uint32_t :10;\
|
||||
);
|
||||
|
||||
//---
|
||||
//
|
||||
//---
|
||||
|
||||
struct __bcm2837_gpio
|
||||
{
|
||||
/* [0x00200000-0x00200014] GPIO Function Selection */
|
||||
u32_union(GPFSEL0,
|
||||
uint32_t FSEL0 :3;
|
||||
uint32_t FSEL1 :3;
|
||||
uint32_t FSEL2 :3;
|
||||
uint32_t FSEL3 :3;
|
||||
uint32_t FSEL4 :3;
|
||||
uint32_t FSEL5 :3;
|
||||
uint32_t FSEL6 :3;
|
||||
uint32_t FSEL7 :3;
|
||||
uint32_t FSEL8 :3;
|
||||
uint32_t FSEL9 :3;
|
||||
uint32_t :2;
|
||||
);
|
||||
u32_union(GPFSEL1,
|
||||
uint32_t FSEL10 :3;
|
||||
uint32_t FSEL11 :3;
|
||||
uint32_t FSEL12 :3;
|
||||
uint32_t FSEL13 :3;
|
||||
uint32_t FSEL14 :3;
|
||||
uint32_t FSEL15 :3;
|
||||
uint32_t FSEL16 :3;
|
||||
uint32_t FSEL17 :3;
|
||||
uint32_t FSEL18 :3;
|
||||
uint32_t FSEL19 :3;
|
||||
uint32_t :2;
|
||||
);
|
||||
u32_union(GPFSEL2,
|
||||
uint32_t FSEL20 :3;
|
||||
uint32_t FSEL21 :3;
|
||||
uint32_t FSEL22 :3;
|
||||
uint32_t FSEL23 :3;
|
||||
uint32_t FSEL24 :3;
|
||||
uint32_t FSEL25 :3;
|
||||
uint32_t FSEL26 :3;
|
||||
uint32_t FSEL27 :3;
|
||||
uint32_t FSEL28 :3;
|
||||
uint32_t FSEL29 :3;
|
||||
uint32_t :2;
|
||||
);
|
||||
u32_union(GPFSEL3,
|
||||
uint32_t FSEL30 :3;
|
||||
uint32_t FSEL31 :3;
|
||||
uint32_t FSEL32 :3;
|
||||
uint32_t FSEL33 :3;
|
||||
uint32_t FSEL34 :3;
|
||||
uint32_t FSEL35 :3;
|
||||
uint32_t FSEL36 :3;
|
||||
uint32_t FSEL37 :3;
|
||||
uint32_t FSEL38 :3;
|
||||
uint32_t FSEL39 :3;
|
||||
uint32_t :2;
|
||||
);
|
||||
u32_union(GPFSEL4,
|
||||
uint32_t FSEL40 :3;
|
||||
uint32_t FSEL41 :3;
|
||||
uint32_t FSEL42 :3;
|
||||
uint32_t FSEL43 :3;
|
||||
uint32_t FSEL44 :3;
|
||||
uint32_t FSEL45 :3;
|
||||
uint32_t FSEL46 :3;
|
||||
uint32_t FSEL47 :3;
|
||||
uint32_t FSEL48 :3;
|
||||
uint32_t FSEL49 :3;
|
||||
uint32_t :2;
|
||||
);
|
||||
u32_union(GPFSEL5,
|
||||
uint32_t FSEL50 :3;
|
||||
uint32_t FSEL51 :3;
|
||||
uint32_t FSEL52 :3;
|
||||
uint32_t FSEL53 :3;
|
||||
uint32_t FSEL54 :3;
|
||||
uint32_t FSEL55 :3;
|
||||
uint32_t FSEL56 :3;
|
||||
uint32_t FSEL57 :3;
|
||||
uint32_t FSEL58 :3;
|
||||
uint32_t FSEL59 :3;
|
||||
uint32_t :2;
|
||||
);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x0020001c-0x00200020] Pin Output Set Register */
|
||||
u32_pin0(GPSET0);
|
||||
u32_pin1(GPSET1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200028-0x0020030] Pin Output Clear */
|
||||
u32_pin0(GPCLR0);
|
||||
u32_pin1(GPCLR1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200034-0x00200038] Pin Level */
|
||||
const u32_pin0(GPLEV0);
|
||||
const u32_pin1(GPLEV1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200040-0x00200040] Pin Event Detect Status */
|
||||
u32_pin0(GPEDS0);
|
||||
u32_pin1(GPEDS1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x0020004c-0x00200050] Pin Rising Edge Detect Enable */
|
||||
u32_pin0(GPREN0);
|
||||
u32_pin1(GPREN1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200058-0x0020005c] Pin Falling Edge Detect Enable */
|
||||
u32_pin0(GPFEN0);
|
||||
u32_pin1(GPFEN1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200064-0x00200068] Pin High Detect Enable */
|
||||
u32_pin0(GPHEN0);
|
||||
u32_pin1(GPHEN1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200070-0x00200074] Pin Low Detect Enable */
|
||||
u32_pin0(GPLEN0);
|
||||
u32_pin1(GPLEN1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x0020007c-0x00200080] Pin Async. Rising Edge Detect */
|
||||
u32_pin0(GPAREN0);
|
||||
u32_pin1(GPAREN1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200088-0x0020008c] Pin Async. Rising Edge Detect */
|
||||
u32_pin0(GPAFEN0);
|
||||
u32_pin1(GPAFEN1);
|
||||
pad(0x04);
|
||||
|
||||
/* [0x00200094] GPIO Pin Pull-up/down Enable */
|
||||
u32_union(GPPUD,
|
||||
uint32_t PUD :2; /* GPIO Pin Pull-up/down */
|
||||
uint32_t :30;
|
||||
);
|
||||
|
||||
/* [0x00200098-0x0020009c] Pin Pull-up/down Enable Clock */
|
||||
u32_pin0(GPPUDCLK0);
|
||||
u32_pin1(GPPUDCLK1);
|
||||
pad(0x14);
|
||||
|
||||
/* [0x002000b0] Test (unknown) */
|
||||
uint32_t _test;
|
||||
} VPACKED(4);
|
||||
|
||||
#define BCM2837_GPIO (*((volatile struct __bcm2837_gpio*)0x3f200000))
|
||||
|
||||
#endif /* VXGOS_BOOTLOADER_RASPI3B_GPIO_H */
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef VXGOS_BOOTLOADER_RASPI3B_UTILS_H
|
||||
#define VXGOS_BOOTLOADER_RASPI3B_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
//---
|
||||
// macros helpers
|
||||
//---
|
||||
|
||||
/* Giving a type to padding bytes is misguiding, let's hide it in a macro */
|
||||
#define pad_nam2(c) _ ## c
|
||||
#define pad_name(c) pad_nam2(c)
|
||||
#define pad(bytes) uint8_t pad_name(__COUNTER__)[bytes]
|
||||
|
||||
/* Packed structures.
|
||||
* I require explicit alignment because if it's unspecified, GCC cannot
|
||||
* optimize access size, and reads to memory-mapped I/O with invalid access
|
||||
* sizes silently fail - honestly you don't want this to happen */
|
||||
#define VPACKED(x) __attribute__((packed, aligned(x)))
|
||||
|
||||
/* uint32_t union helper */
|
||||
#define u32_union(name, fields) \
|
||||
union { \
|
||||
uint32_t lword; \
|
||||
struct { fields } VPACKED(4); \
|
||||
} VPACKED(4) name
|
||||
|
||||
/* UTIL_SPINWAIT_CYCLES() : wait at least X cycles */
|
||||
//TODO : handle superscalar behaviour
|
||||
//TODO : handle over/under clock
|
||||
#define UTIL_SPINWAIT_CYCLES(x) \
|
||||
for(int r = x ; r > 0 ; r--) { \
|
||||
__asm__ volatile ("nop"); \
|
||||
}
|
||||
|
||||
#endif /* VXGOS_BOOTLOADER_RASPI3B_UTILS_H */
|
|
@ -0,0 +1,14 @@
|
|||
#include "bootloader/display.h"
|
||||
#include "bootloader/bios.h"
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* _bios_dfont_get() : get font information */
|
||||
int _bios_dfont_get(struct font **font)
|
||||
{
|
||||
if (*font != NULL)
|
||||
font = NULL;
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,151 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "raspi3b/auxiliary.h"
|
||||
#include "raspi3b/gpio.h"
|
||||
|
||||
|
||||
//---
|
||||
// Internals
|
||||
//---
|
||||
|
||||
// driver-level primitives
|
||||
|
||||
/* uart_init() : initialize the MiniUART1 module */
|
||||
static void uart_init(void)
|
||||
{
|
||||
/* initialize UART
|
||||
*
|
||||
* @note
|
||||
* <> disalbe UART interruption
|
||||
* <> enable UART module
|
||||
* <> clear Tx and Rx FIFOs
|
||||
* <> setup to 115200 baud
|
||||
* baudrate = system_clk_freq / (8 * (baud_reg + 1))
|
||||
* baud_reg = ((system_clk_freq / baudrate) / 8) - 1 */
|
||||
BCM2837_AUXILIARY.AUX_ENABLE.MiniUART = 1;
|
||||
|
||||
/* disable as soon as possible Tx and Rx */
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.RE = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.TE = 0;
|
||||
|
||||
/* disable Tx or Rx interrupts */
|
||||
BCM2837_AUXILIARY.AUX_MU_IER.TIE = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_IER.RIE = 0;
|
||||
|
||||
/* clear FIFOs (FIFOs are always enabled) */
|
||||
//FIXME : be sure to not force enable FIFO channels
|
||||
BCM2837_AUXILIARY.AUX_MU_IIR.TXFLUSH = 1;
|
||||
BCM2837_AUXILIARY.AUX_MU_IIR.RXFLUSH = 1;
|
||||
|
||||
/* Configure data format */
|
||||
BCM2837_AUXILIARY.AUX_MU_LCR.DLAB = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_LCR.BREAK = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_LCR.CHR = 0b11;
|
||||
BCM2837_AUXILIARY.AUX_MU_MCR.RTS = 0;
|
||||
|
||||
/* Configure extra features */
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.ERAF = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.ETAF = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.RTS_AUTO = 0b00;
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.RTS_ASSERT = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.CTS_ASSERT = 0;
|
||||
|
||||
/* Setup baudrate */
|
||||
//FIXME : find module freq, for now assum that is 250MHz
|
||||
BCM2837_AUXILIARY.AUX_MU_LCR.DLAB = 1;
|
||||
BCM2837_AUXILIARY.AUX_MU_BAUD.BAUD = 270;
|
||||
BCM2837_AUXILIARY.AUX_MU_LCR.DLAB = 0;
|
||||
|
||||
/* map UART1 to GPOI pins
|
||||
*
|
||||
* @note
|
||||
* <> map GPIO15 to alternate function 5 (RXD1 UART1 Transmit Data)
|
||||
* <> map GPIO14 to alternate function 5 (TXD1 UART1 Receive Data)
|
||||
* <> alternante function 5 is the only way to map the UART1
|
||||
* */
|
||||
BCM2837_GPIO.GPFSEL1.FSEL15 = 0b011;
|
||||
BCM2837_GPIO.GPFSEL1.FSEL14 = 0b011;
|
||||
|
||||
/* link GPIO15 and GPIO14 pins to the UART1
|
||||
*
|
||||
* Now, we want the GPIO15 and GPIO14 to be completly controlled by the
|
||||
* UART1 module. So, we shall "disable" the current pins behaviour to
|
||||
* avoid conflict with the module.
|
||||
*
|
||||
* @note
|
||||
* <> we first need to disable pull-up/down for all GPIO pins
|
||||
* <> we MUST wait at least 150 cycles (CPPUDCLKn, page 101)
|
||||
* <> specify that only GPIO14 and GPIO15 must be modified
|
||||
* <> we MUST wait at least 150 cycles (CPPUDCLKn, page 101)
|
||||
* <> reset PUD (in our case, we already in reset mode)
|
||||
* <> reset CLK to "flush" the "new" GPIO configuration
|
||||
* */
|
||||
BCM2837_GPIO.GPPUD.PUD = 0b00;
|
||||
UTIL_SPINWAIT_CYCLES(150);
|
||||
BCM2837_GPIO.GPPUDCLK0.PIN14 = 1;
|
||||
BCM2837_GPIO.GPPUDCLK0.PIN15 = 1;
|
||||
UTIL_SPINWAIT_CYCLES(150);
|
||||
BCM2837_GPIO.GPPUDCLK0.lword = 0x00000000;
|
||||
UTIL_SPINWAIT_CYCLES(150);
|
||||
|
||||
/* enable Tx and disable Rx */
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.RE = 0;
|
||||
BCM2837_AUXILIARY.AUX_MU_CNTL.TE = 1;
|
||||
}
|
||||
|
||||
/* uart_send() : send a 8-bit information (char in our case) */
|
||||
static void uart_send(unsigned int c)
|
||||
{
|
||||
/* wait until we can send */
|
||||
do{
|
||||
__asm__ volatile("nop");
|
||||
} while(BCM2837_AUXILIARY.AUX_MU_LSR.TDFE == 0);
|
||||
|
||||
/* write the character to the buffer */
|
||||
BCM2837_AUXILIARY.AUX_MU_IO.DATA = c;
|
||||
}
|
||||
|
||||
// high-level primtives
|
||||
|
||||
/* uart_puts() : send string through the UART line (convert new line) */
|
||||
static void uart_puts(char const * s)
|
||||
{
|
||||
while(s[0] != '\0')
|
||||
{
|
||||
if(s[0] == '\n')
|
||||
uart_send('\r');
|
||||
uart_send(s[0]);
|
||||
s = &s[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* uart_putf() : printf-like puts */
|
||||
static void uart_putf(char *format, ...)
|
||||
{
|
||||
char buffer[128];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vsnprintf(buffer, 64, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
uart_puts(buffer);
|
||||
}
|
||||
|
||||
//---
|
||||
// Public
|
||||
//---
|
||||
|
||||
/* bootloader_fake_entry() : debug / fake bootloader entry */
|
||||
void bootloader_fake_entry(void)
|
||||
{
|
||||
uart_init();
|
||||
uart_puts("vxGOS fake bootloader entry!!\n");
|
||||
uart_putf("AUX_IRQ = %p\n", &BCM2837_AUXILIARY.AUX_IRQ);
|
||||
uart_putf("AUX_ENABLE = %p\n", &BCM2837_AUXILIARY.AUX_ENABLE);
|
||||
uart_putf("AUX_MU_IO = %p\n", &BCM2837_AUXILIARY.AUX_MU_IO);
|
||||
uart_putf("AUX_MU_ENB = %p\n", BCM2837_AUXILIARY.AUX_ENABLE.lword);
|
||||
uart_putf("AUX_MU_IER = %p\n", BCM2837_AUXILIARY.AUX_MU_IER.lword);
|
||||
while (1) { }
|
||||
}
|
|
@ -61,6 +61,7 @@ _primary_continue:
|
|||
// - check if we are already in RAM
|
||||
// - detect RAM geometry (size, start and end)
|
||||
// - ramdom translation offset
|
||||
// - request mailboxs hardware information
|
||||
// ---
|
||||
|
||||
adr x3, patch_aslr_symbols
|
||||
|
@ -68,7 +69,7 @@ _primary_continue:
|
|||
mov rom_base_addr, x3
|
||||
mov ram_base_addr, 0x00000000
|
||||
|
||||
// for now, assume that we will always be loaded in RAM
|
||||
// FIXME : for now, assume that we will always be loaded in RAM
|
||||
mov ram_base_addr, rom_base_addr
|
||||
|
||||
#if 0
|
||||
|
@ -98,37 +99,46 @@ _ram_translation_validate:
|
|||
// ---
|
||||
|
||||
patch_aslr_symbols:
|
||||
|
||||
// The table symbol is not aready resolved (its our job), we must manually
|
||||
// calculate the real address of the symbols table
|
||||
adr x4, __bootloader_code_end
|
||||
add x4, ram_base_address
|
||||
// @note
|
||||
// <> the symbol is defined by the linker script
|
||||
// <> this symbols don't need to perform ROM_BASE address subtraction
|
||||
// since its content is based on the linker script provided address
|
||||
// 0x00000000000000000
|
||||
adr x4, ___bootloader_code_end
|
||||
add x4, x4, ram_base_addr
|
||||
_aslr_symbol_patch_loop:
|
||||
ldr x5, [x4], #8
|
||||
cbz x5, _bootloader_panik
|
||||
cbz x5, stack_setup
|
||||
ldr x6, [x5]
|
||||
add x6, ram_base_address
|
||||
add x6, x6, ram_base_addr
|
||||
str x6, [x5]
|
||||
b patch_aslr_symbols
|
||||
// TODO
|
||||
|
||||
// ---
|
||||
// RAM translation
|
||||
// ---
|
||||
|
||||
// TODO : invalidate cache
|
||||
// FIXME : invalidate cache
|
||||
// TODO : jump to the relocalized RAM
|
||||
|
||||
// ---
|
||||
// Setup stack
|
||||
// ---
|
||||
|
||||
// TODO
|
||||
stack_setup:
|
||||
adr x4, __bootloader_stack
|
||||
sub x4, x4, rom_base_addr
|
||||
add x4, x4, ram_base_addr
|
||||
mov sp, x4
|
||||
|
||||
// ---
|
||||
// High-level bootloader invokation
|
||||
// ---
|
||||
|
||||
high_level_bootloader_entry:
|
||||
b bootloader_fake_entry
|
||||
// TODO
|
||||
|
||||
// ---
|
||||
|
|
|
@ -40,10 +40,8 @@ SECTIONS
|
|||
|
||||
. = ALIGN(16) ;
|
||||
|
||||
__bootloader_stack = . ;
|
||||
. = . + (16 * 1024) ;
|
||||
|
||||
. = ALIGN(16);
|
||||
__bootloader_stack = ALIGN(16) ;
|
||||
}
|
||||
|
||||
/* readable / writable data (must be 16-aligned) */
|
||||
|
|
Loading…
Reference in New Issue