reset.c 3.6 KB
Newer Older
A
ArcherChang 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
#include "nds32_intrinsic.h"
#include "nds32.h"

#ifndef VECTOR_BASE
#define VECTOR_BASE	0x00000000
#endif

#define PSW_MSK                                         \
        (PSW_mskGIE | PSW_mskINTL | PSW_mskPOM | PSW_mskIFCON | PSW_mskCPL)
#define PSW_INIT                                        \
        (0x0UL << PSW_offGIE                            \
         | 0x0UL << PSW_offINTL                         \
         | 0x1UL << PSW_offPOM                          \
         | 0x0UL << PSW_offIFCON                        \
         | 0x7UL << PSW_offCPL)

#define IVB_MSK                                         \
        (IVB_mskEVIC | IVB_mskESZ | IVB_mskIVBASE)
#define IVB_INIT                                        \
        ((VECTOR_BASE >> IVB_offIVBASE) << IVB_offIVBASE\
         | 0x1UL << IVB_offESZ                          \
         | 0x0UL << IVB_offEVIC)


#pragma weak c_startup = c_startup_common

void c_startup(void);

/*
 * Default c_startup() function which used for those relocation from LMA to VMA.
 */
static void c_startup_common(void)
{
#ifdef XIP_MODE
	/* Data section initialization */
#define MEMCPY(des, src, n)     __builtin_memcpy ((des), (src), (n))
	extern char __rw_lma_start, __rw_lma_end, __rw_vma_start;
	unsigned int size = &__rw_lma_end - &__rw_lma_start;

	/* Copy data section from LMA to VMA */
	MEMCPY(&__rw_vma_start, &__rw_lma_start, size);
#else
	/* We do nothing for those LMA equal to VMA */
#endif
}

static void cpu_init(void)
{
	unsigned int reg;

	/* Set PSW GIE/INTL to 0, superuser & CPL to 7 */
	reg = (__nds32__mfsr(NDS32_SR_PSW) & ~PSW_MSK) | PSW_INIT;
	__nds32__mtsr(reg, NDS32_SR_PSW);
	__nds32__isb();

	/* Set vector size: 16 byte, base: VECTOR_BASE, mode: IVIC */
	reg = (__nds32__mfsr(NDS32_SR_IVB) & ~IVB_MSK) | IVB_INIT;
	__nds32__mtsr(reg, NDS32_SR_IVB);

	/*
	* Check interrupt priority programmable (IVB.PROG_PRI_LVL)
	* 0: Fixed priority, 1: Programmable priority
	*/
	if (reg & IVB_mskPROG_PRI_LVL)
	{
		/* Set PPL2FIX_EN to 0 to enable Programmable Priority Level */
		__nds32__mtsr(0x0, NDS32_SR_INT_CTRL);
	}

	/* Mask and clear hardware interrupts */
	if (reg & IVB_mskIVIC_VER)
	{
		/* IVB.IVIC_VER >= 1*/
		__nds32__mtsr(0x0, NDS32_SR_INT_MASK2);
		__nds32__mtsr(-1, NDS32_SR_INT_PEND2);
	}
	else
	{
		__nds32__mtsr(__nds32__mfsr(NDS32_SR_INT_MASK) & ~0xFFFF, NDS32_SR_INT_MASK);
	}
}

/*
 * Vectors initialization. This means to copy exception handler code to
 * vector entry base address.
 */
static void vector_init(void)
{
	extern unsigned int OS_Int_Vectors, OS_Int_Vectors_End;

	if ((unsigned int)&OS_Int_Vectors != VECTOR_BASE)
	{
		volatile unsigned int *vector_srcptr = &OS_Int_Vectors;
		volatile unsigned int *vector_dstptr = (unsigned int *)VECTOR_BASE;

		/* copy vector table to VECTOR_BASE */
		while (vector_srcptr != &OS_Int_Vectors_End)
			*vector_dstptr++ = *vector_srcptr++;
	}
}

/*
 * NDS32 reset handler to reset all devices sequentially and call application
 * entry function.
 */
void reset(void)
{
	extern void hardware_init(void);
	extern void bsp_init(void);
	extern void rtthread_startup(void);

	/*
	 * Initialize CPU to a post-reset state, ensuring the ground doesn't
	 * shift under us while we try to set things up.
	*/
	cpu_init();

	/*
	 * Initialize LMA/VMA sections.
	 * Relocation for any sections that need to be copied from LMA to VMA.
	 */
	c_startup();

	/* Copy vector table to vector base address */
	vector_init();

	/* Call platform specific hardware initialization */
	hardware_init();

	/* Setup the OS system required initialization */
	bsp_init();

	/* Application enrty function */
	rtthread_startup();

	/* Never go back here! */
	while(1);
}