Commit 9a4a14e5 authored by Yuri Tikhonov's avatar Yuri Tikhonov
Browse files

RT72064. Cortex-M3: refactor code for A2F SOC



These are the preparations for support for another Cortex-M3 based
processor, STM32F2.

Signed-off-by: default avatarYuri Tikhonov <yur@emcraft.com>
parent b17199cc
......@@ -3190,15 +3190,15 @@ smdkc100_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 smdkc100 samsung s5pc1xx
a2f-lnx-evb_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexm3 a2f-lnx-evb emcraft NULL
@$(MKCONFIG) $(@:_config=) arm arm_cortexm3 a2f-lnx-evb emcraft a2f
a2f-actel-dev-brd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexm3 a2f-actel-dev-brd \
actel NULL
actel a2f
a2f-hoermann-brd_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexm3 a2f-hoermann-brd \
hoermann NULL
hoermann a2f
#########################################################################
## XScale Systems
......
......@@ -30,7 +30,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(CPU).a
START := start.o
COBJS := cpu.o timer.o envm.o wdt.o cmd_cptf.o clock.o
COBJS := cpu.o cmd_cptf.o
SRCS := $(START:.o=.c) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
......
#
# (C) Copyright 2000-2003
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# (C) Copyright 2010,2011
# Port to A2F
# Vladimir Khusainov, Emcraft Systems, vlad@emcraft.com.
#
# See file CREDITS for list of people who contributed to this
# project.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
COBJS := clock.o cpu.o envm.o timer.o wdt.o
SOBJS :=
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
SOBJS := $(addprefix $(obj),$(SOBJS))
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
clean:
rm -f $(SOBJS) $(OBJS)
distclean:
rm -f $(LIB) core *.bak $(obj).depend
#########################################################################
# defines $(obj).depend target
include $(SRCTREE)/rules.mk
sinclude $(obj).depend
#########################################################################
/*
* (C) Copyright 2011
* Yuri Tikhonov, Emcraft Systems, yur@emcraft.com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include "clock.h"
#include "asm/arch-a2f/a2f.h"
/*
* Print the CPU specific information
*/
int print_cpuinfo(void)
{
printf("CPU: %s\n", "SmartFusion FPGA (Cortex-M3 Hard IP)");
#if defined(DEBUG)
printf("Frequencies: FCLK=%d, PCLK0=%d, PCLK1=%d, ACE=%d, FPGA=%d\n",
clock_get(CLOCK_FCLK), clock_get(CLOCK_PCLK0),
clock_get(CLOCK_PCLK1), clock_get(CLOCK_ACE),
clock_get(CLOCK_FPGA));
#endif
return 0;
}
/*
* Perform the low-level reset.
* Note that we need for this function to reside in RAM since it
* will be used to self-upgrade U-boot in eNMV.
*/
void __attribute__((section(".ramcode")))
__attribute__ ((long_call))
reset_cpu(ulong addr)
{
/*
* Perform reset but keep priority group unchanged.
*/
A2F_SCB->aircr = (0x5FA << 16) |
(A2F_SCB->aircr & (7<<8)) |
(1<<2);
}
/*
* Dump the registers on an exception we don't know how to process.
*/
unsigned char cortex_m3_irq_vec_get(void)
{
return A2F_SCB->icsr & 0xFF;
}
......@@ -46,7 +46,7 @@ struct mss_envm {
#define MSS_ENVM_BASE 0x60000000
/*
* eNVM Flash size.
* eNVM Flash size.
* TO-DO: this needs to be made a function of some build-time,
* perhaps even run-time, parameter defining a SmartFusion chip model.
*/
......@@ -86,12 +86,12 @@ void envm_init(void)
MSS_ENVM->status = 0;
}
/*
/*
* Execute an eNVM command.
* Note that we need for this function to reside in RAM since it
* will be used to self-upgrade U-boot in eNMV.
*/
static int __attribute__((section(".ramcode")))
static int __attribute__((section(".ramcode")))
mss_envm_exec_cmd(unsigned int addr, unsigned int cmd)
{
unsigned int status;
......@@ -108,11 +108,11 @@ static int __attribute__((section(".ramcode")))
MSS_ENVM->status = 0xFFFFFFFF;
/*
* Start the command
*/
* Start the command
*/
MSS_ENVM->control = addr | cmd;
/*
/*
* Wait for the command to finish
*/
for (wait = 0; wait < MSS_ENVM_MAX_WAIT_CNT; wait++) {
......@@ -139,25 +139,25 @@ static int __attribute__((section(".ramcode")))
if (status & MSS_ENVM_STATUS_ERROR_MASK) {
/*
* This code below is a workaround for an occurance
* of the write count has exceeded the 10-year retention
* threshold error for some page.
* Apparently, that error is persistently set for some
* pages on the boards we have here (supposedly due to
* a power-off while programming the board using FlashPro.)
* ... Supposedly, FlashPro uses the same workaround.
* The bit value in the code below doesn't correspond to
* the value in the Actel SmartFusion DataSheet.
* It has been figured out experimentally (the same page
* on the board I have has that problem, and the code below
* allows to actually program that page with new content.
*/
* This code below is a workaround for an occurance
* of the write count has exceeded the 10-year retention
* threshold error for some page.
* Apparently, that error is persistently set for some
* pages on the boards we have here (supposedly due to
* a power-off while programming the board using FlashPro.)
* ... Supposedly, FlashPro uses the same workaround.
* The bit value in the code below doesn't correspond to
* the value in the Actel SmartFusion DataSheet.
* It has been figured out experimentally (the same page
* on the board I have has that problem, and the code below
* allows to actually program that page with new content.
*/
if ((status & 0x180) == 0x180) {
/*
* Assume the page has been programmed successfully
*/
* Assume the page has been programmed successfully
*/
return 0;
}
}
return -1;
}
......@@ -182,32 +182,32 @@ unsigned int __attribute__((section(".ramcode")))
int ret = 0;
/*
* Check the sanity of the request.
*/
* Check the sanity of the request.
*/
if (offset > MSS_ENVM_FLASH_SIZE) {
return 0;
}
for (i = 0; i < size; i++) {
if (i == 0 || (addr & MSS_ENVM_PAGE_OFFSET_MASK) == 0) {
/*
/*
* We need to unprotect the Flash for the first byte
*/
ret = mss_envm_exec_cmd(addr,
ret = mss_envm_exec_cmd(addr,
MSS_ENVM_CONTROL_CC_UNPROTECT);
if (ret < 0) {
break;
}
}
/*
/*
* Copy a byte of the data
*/
*(unsigned char *)addr++ = *src++;
/*
* Commit the page to NVM on the last byte write
*/
* Commit the page to NVM on the last byte write
*/
if (i == size - 1 || (addr & MSS_ENVM_PAGE_OFFSET_MASK) == 0) {
ret = mss_envm_exec_cmd(addr - 1,
MSS_ENVM_CONTROL_CC_PROGRAM);
......
......@@ -23,8 +23,8 @@
#include <string.h>
#include "envm.h"
#define A2F_RAM_BUFFER_BASE 0x20004000
#define A2F_RAM_BUFFER_SIZE 0x8000
#define SOC_RAM_BUFFER_BASE 0x20004000
#define SOC_RAM_BUFFER_SIZE 0x8000
/*
* Write the eNVM and, optionally, reset the CPU.
......@@ -69,8 +69,8 @@ static int __attribute__((section(".ramcode")))
int do_cptf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
ulong dst;
ulong src = A2F_RAM_BUFFER_BASE;
ulong size = A2F_RAM_BUFFER_SIZE;
ulong src = SOC_RAM_BUFFER_BASE;
ulong size = SOC_RAM_BUFFER_SIZE;
int do_reset = 0;
int ret = 0;
......@@ -113,6 +113,6 @@ int do_cptf(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
U_BOOT_CMD(
cptf, 5, 0, do_cptf,
"copy memory buffer to internal Flash of the A2F",
"copy memory buffer to internal Flash of Cortex-M3",
"dst [[src] [[size] [do_reset]]]"
);
......@@ -20,6 +20,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307 USA
#
PLATFORM_RELFLAGS += -g2 -mthumb -mcpu=cortex-m3 -fsigned-char -O2 -fno-builtin-puts -fno-common -ffixed-r8
PLATFORM_CPPFLAGS += -I$(TOPDIR)/cpu/$(CPU)
PLATFORM_RELFLAGS += -g2 -mthumb -mcpu=cortex-m3 -fsigned-char -O2 -fno-builtin-puts -fno-common -ffixed-r8
......@@ -20,6 +20,7 @@
#include <common.h>
#include <command.h>
#include "envm.h"
#include "wdt.h"
#include "clock.h"
......@@ -49,7 +50,11 @@ int arch_cpu_init(void)
/*
* Architecture number; used by the Linux kernel.
*/
#if defined(CONFIG_SYS_A2F)
gd->bd->bi_arch_number = MACH_TYPE_A2F;
#else
# error "Unknown Cortex-M3 SOC."
#endif
/*
* Address of the kernel boot parameters.
......@@ -61,21 +66,6 @@ int arch_cpu_init(void)
return 0;
}
/*
* Print the CPU specific information
*/
int print_cpuinfo(void)
{
printf("CPU: %s\n", "SmartFusion FPGA (Cortex-M3 Hard IP)");
#if defined(DEBUG)
printf("Frequencies: FCLK=%d, PCLK0=%d, PCLK1=%d, ACE=%d, FPGA=%d\n",
clock_get(CLOCK_FCLK), clock_get(CLOCK_PCLK0),
clock_get(CLOCK_PCLK1), clock_get(CLOCK_ACE),
clock_get(CLOCK_FPGA));
#endif
return 0;
}
/*
* This is called right before passing control to
* the Linux kernel point.
......@@ -85,23 +75,6 @@ int cleanup_before_linux(void)
return 0;
}
/*
* Perform the low-level reset.
* Note that we need for this function to reside in RAM since it
* will be used to self-upgrade U-boot in eNMV.
*/
void __attribute__((section(".ramcode")))
__attribute__ ((long_call))
reset_cpu(ulong addr)
{
/*
* Perform reset but keep priority group unchanged.
*/
A2F_SCB->aircr = (0x5FA << 16) |
(A2F_SCB->aircr & (7<<8)) |
(1<<2);
}
/*
* H/w WDT strobe routine
*/
......
......@@ -18,7 +18,6 @@
* MA 02111-1307 USA
*/
#include <string.h>
#include <asm/arch-a2f/a2f.h>
#include "wdt.h"
/*
......@@ -40,8 +39,23 @@ extern char _bss_end;
void _start(void);
void default_isr(void);
unsigned char cortex_m3_irq_vec_get(void);
extern void start_armboot(void);
/*
* Control IRQs
*/
static inline void __attribute__((used)) __enable_irq(void)
{
asm volatile ("cpsie i");
}
static inline void __attribute__((used)) __disable_irq(void)
{
asm volatile ("cpsid i");
}
/*
* Exception-processing vectors:
*/
......@@ -88,7 +102,7 @@ void _start(void)
* Copy data and initialize BSS
* This is in lieu of the U-boot "conventional" relocation
* of code & data from Flash to RAM.
* With the A2F, we execute from NVRAM (internal Flash),
* With Cortex-M3, we execute from NVRAM (internal Flash),
* having relocated data to internal RAM (and having cleared the BSS
* area in internal RAM as well)
* Stack grows downwards; the stack base is set-up by the first
......@@ -105,7 +119,7 @@ void _start(void)
* Note initialization of _armboot_start below. The ARM generic
* code expects that this variable is set to the upper boundary of
* the malloc pool area.
* For A2F, where we do not relocate the code to RAM, I set
* For Cortex-M3, where we do not relocate the code to RAM, I set
* the malloc pool right behind the stack. See how armboot_start
* is defined in the CPU specific .lds file.
*/
......@@ -156,7 +170,7 @@ static void __attribute__((used)) dump_ctx(unsigned int *ctx)
"PENDSV",
"SYSTICK",
};
unsigned char vec = A2F_SCB->icsr & 0xFF;
unsigned char vec = cortex_m3_irq_vec_get();
int i;
printf("UNHANDLED EXCEPTION: ");
......
......@@ -113,9 +113,6 @@ struct a2f_timer
#define A2F_TIMER_BASE 0x40005000
#define A2F_TIMER ((volatile struct a2f_timer *)(A2F_TIMER_BASE))
static inline void __enable_irq(void) { asm volatile ("cpsie i"); }
static inline void __disable_irq(void) { asm volatile ("cpsid i"); }
/*
* Clocks enumeration.
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment