From 97d1dc0821fe963fd0813a2a3e15ccd2c179749d Mon Sep 17 00:00:00 2001 From: kenrabold Date: Tue, 25 Jun 2019 10:13:15 -0700 Subject: [PATCH] cpu/fe310: Add support for FE310_G002 Added support for FE310_G002 CPU variant that is on new HiFive1B board --- cpu/fe310/include/vendor/i2c.h | 33 ++++ cpu/fe310/include/vendor/platform.h | 17 +- .../ldscripts/{fe310.ld => fe310_g000.ld} | 10 +- cpu/fe310/ldscripts/fe310_g002.ld | 184 ++++++++++++++++++ 4 files changed, 236 insertions(+), 8 deletions(-) create mode 100644 cpu/fe310/include/vendor/i2c.h rename cpu/fe310/ldscripts/{fe310.ld => fe310_g000.ld} (92%) create mode 100644 cpu/fe310/ldscripts/fe310_g002.ld diff --git a/cpu/fe310/include/vendor/i2c.h b/cpu/fe310/include/vendor/i2c.h new file mode 100644 index 000000000..01e61eb12 --- /dev/null +++ b/cpu/fe310/include/vendor/i2c.h @@ -0,0 +1,33 @@ +// See LICENSE for license details. + +#ifndef _SIFIVE_I2C_H +#define _SIFIVE_I2C_H + +/* Register offsets */ +#define I2C_PRESCALE_LO (0x00) +#define I2C_PRESCALE_HI (0x04) +#define I2C_CONTROL (0x08) +#define I2C_DATA (0x0C) +#define I2C_CMD (0x10) +#define I2C_STATUS (0x10) + +/* CONTROL register */ +#define I2C_CONTROL_EN (1 << 7) +#define I2C_CONTROL_IE (1 << 6) + +/* CMD register */ +#define I2C_CMD_STA (1 << 7) +#define I2C_CMD_STO (1 << 6) +#define I2C_CMD_RD (1 << 5) +#define I2C_CMD_WR (1 << 4) +#define I2C_CMD_ACK (1 << 3) +#define I2C_CMD_IACK (1 << 0) + +/* STATUS register */ +#define I2C_STATUS_RXACK (1 << 7) +#define I2C_STATUS_BUSY (1 << 6) +#define I2C_STATUS_ALOST (1 << 5) +#define I2C_STATUS_TIP (1 << 1) +#define I2C_STATUS_IF (1 << 0) + +#endif /* _SIFIVE_I2C_H */ diff --git a/cpu/fe310/include/vendor/platform.h b/cpu/fe310/include/vendor/platform.h index dfb585e48..d440727d8 100644 --- a/cpu/fe310/include/vendor/platform.h +++ b/cpu/fe310/include/vendor/platform.h @@ -12,6 +12,7 @@ #include "vendor/aon.h" #include "vendor/clint.h" #include "vendor/gpio.h" +#include "vendor/i2c.h" #include "vendor/otp.h" #include "vendor/plic.h" #include "vendor/prci.h" @@ -29,6 +30,7 @@ #define TRAPVEC_TABLE_CTRL_ADDR (0x00001010) #define OTP_MEM_ADDR (0x00020000) #define CLINT_CTRL_ADDR (0x02000000) +#define ITIM_MEM_ADDR (0x08000000) #define PLIC_CTRL_ADDR (0x0C000000) #define AON_CTRL_ADDR (0x10000000) #define PRCI_CTRL_ADDR (0x10008000) @@ -37,6 +39,7 @@ #define UART0_CTRL_ADDR (0x10013000) #define SPI0_CTRL_ADDR (0x10014000) #define PWM0_CTRL_ADDR (0x10015000) +#define I2C0_CTRL_ADDR (0x10016000) #define UART1_CTRL_ADDR (0x10023000) #define SPI1_CTRL_ADDR (0x10024000) #define PWM1_CTRL_ADDR (0x10025000) @@ -71,15 +74,17 @@ #define IOF_SPI2_DQ2 (30u) #define IOF_SPI2_DQ3 (31u) -//#define IOF0_I2C_MASK (0x00003000) +#define IOF0_I2C_MASK (0x00003000) +#define IOF_I2C0_SDA (12u) +#define IOF_I2C0_SCL (13u) #define IOF0_UART0_MASK (0x00030000) #define IOF_UART0_RX (16u) #define IOF_UART0_TX (17u) -#define IOF0_UART1_MASK (0x03000000) -#define IOF_UART1_RX (24u) -#define IOF_UART1_TX (25u) +#define IOF0_UART1_MASK (0x00840000) +#define IOF_UART1_RX (18u) +#define IOF_UART1_TX (23u) #define IOF1_PWM0_MASK (0x0000000F) #define IOF1_PWM1_MASK (0x00780000) @@ -98,6 +103,7 @@ #define INT_PWM0_BASE 40 #define INT_PWM1_BASE 44 #define INT_PWM2_BASE 48 +#define INT_I2C_BASE 52 // Helper functions #define _REG32(p, i) (*(volatile uint32_t *) ((p) + (i))) @@ -105,6 +111,7 @@ #define AON_REG(offset) _REG32(AON_CTRL_ADDR, offset) #define CLINT_REG(offset) _REG32(CLINT_CTRL_ADDR, offset) #define GPIO_REG(offset) _REG32(GPIO_CTRL_ADDR, offset) +#define I2C0_REG(offset) _REG32(I2C0_CTRL_ADDR, offset) #define OTP_REG(offset) _REG32(OTP_CTRL_ADDR, offset) #define PLIC_REG(offset) _REG32(PLIC_CTRL_ADDR, offset) #define PRCI_REG(offset) _REG32(PRCI_CTRL_ADDR, offset) @@ -126,4 +133,6 @@ #define RTC_FREQ 32768 +#define ITIM_MEM_LEN 8192 + #endif /* _SIFIVE_PLATFORM_H */ diff --git a/cpu/fe310/ldscripts/fe310.ld b/cpu/fe310/ldscripts/fe310_g000.ld similarity index 92% rename from cpu/fe310/ldscripts/fe310.ld rename to cpu/fe310/ldscripts/fe310_g000.ld index 85181789e..56c73cd12 100644 --- a/cpu/fe310/ldscripts/fe310.ld +++ b/cpu/fe310/ldscripts/fe310_g000.ld @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Ken Rabold + * Copyright (C) 2017, 2019 Ken Rabold * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -11,7 +11,7 @@ * @{ * * @file - * @brief Memory definitions for the SiFive FE310 + * @brief Memory definitions for the SiFive FE310_G000 * * @author Ken Rabold * @@ -24,8 +24,9 @@ ENTRY( _start ) MEMORY { - flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 512M - ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 16K + flash (rxai!w) : ORIGIN = 0x20400000, LENGTH = 0x1fc00000 + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x00004000 + itim (wxa!ri) : ORIGIN = 0x08000000, LENGTH = 0x00002000 } PHDRS @@ -138,6 +139,7 @@ SECTIONS .data : { + *(.ramfunc .ramfunc.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); diff --git a/cpu/fe310/ldscripts/fe310_g002.ld b/cpu/fe310/ldscripts/fe310_g002.ld new file mode 100644 index 000000000..58317fbb8 --- /dev/null +++ b/cpu/fe310/ldscripts/fe310_g002.ld @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2017, 2019 Ken Rabold + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @addtogroup cpu_fe310 + * @{ + * + * @file + * @brief Memory definitions for the SiFive FE310_G002 + * + * @author Ken Rabold + * + * @} + */ + +OUTPUT_ARCH( "riscv" ) + +ENTRY( _start ) + +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x20010000, LENGTH = 0x0006a120 + ram (wxa!ri) : ORIGIN = 0x80000000, LENGTH = 0x00004000 + itim (wxa!ri) : ORIGIN = 0x08000000, LENGTH = 0x00002000 +} + +PHDRS +{ + flash PT_LOAD; + ram_init PT_LOAD; + ram PT_NULL; +} + +SECTIONS +{ + __stack_size = DEFINED(__stack_size) ? __stack_size : 1K; + + .init : + { + KEEP (*(SORT_NONE(.init))) + } >flash AT>flash :flash + + .text : + { + *(.text.unlikely .text.unlikely.*) + *(.text.startup .text.startup.*) + *(.text .text.*) + *(.gnu.linkonce.t.*) + } >flash AT>flash :flash + + .fini : + { + KEEP (*(SORT_NONE(.fini))) + } >flash AT>flash :flash + + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + + .rodata : + { + *(.rdata) + *(.rodata .rodata.*) + *(.gnu.linkonce.r.*) + } >flash AT>flash :flash + + . = ALIGN(4); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >flash AT>flash :flash + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >flash AT>flash :flash + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >flash AT>flash :flash + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >flash AT>flash :flash + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >flash AT>flash :flash + + .lalign : + { + . = ALIGN(4); + PROVIDE( _data_lma = . ); + } >flash AT>flash :flash + + .dalign : + { + . = ALIGN(4); + PROVIDE( _data = . ); + } >ram AT>flash :ram_init + + .data : + { + *(.ramfunc .ramfunc.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + } >ram AT>flash :ram_init + + . = ALIGN(4); + PROVIDE( _edata = . ); + PROVIDE( edata = . ); + + PROVIDE( _fbss = . ); + PROVIDE( __bss_start = . ); + .bss : + { + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + } >ram AT>ram :ram + + . = ALIGN(8); + PROVIDE( _end = . ); + PROVIDE( end = . ); + PROVIDE( _heap_start = . ); + + .stack ORIGIN(ram) + LENGTH(ram) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = __stack_size; + PROVIDE( _sp = . ); + } >ram AT>ram :ram +}