source: rtems/c/src/lib/libbsp/arm/tms570/hwinit/bspstarthooks-hwinit.c @ b2ed712

Last change on this file since b2ed712 was 29430a3, checked in by Pavel Pisa <pisa@…>, on Sep 22, 2016 at 7:50:59 AM

arm/tms570: include hardware initialization and selftest based on Ti HalCoGen? generated files.

The configuration is specific for TMS570LS3137 based HDK.
Pins configuration can be easily changed in

rtems/c/src/lib/libbsp/arm/tms570/hwinit/init_pinmux.c

file.

The list tms570_selftest_par_list in the file

rtems/c/src/lib/libbsp/arm/tms570/hwinit/bspstarthooks-hwinit.c

specifies peripherals which health status is examined
by parity self-test at BSP start-up. It can be easily
modified for other TMS570 family members variants same
as the selection of other tests in bspstarthooks-hwinit.c.

  • Property mode set to 100644
File size: 16.1 KB
Line 
1#include <stdint.h>
2#include <bsp.h>
3#include <bsp/start.h>
4#include <bsp/tms570.h>
5
6#include "tms570_selftest.h"
7#include "tms570_selftest_parity.h"
8#include "tms570_hwinit.h"
9
10void bsp_start_hook_0_done( void );
11
12static inline
13int tms570_running_from_tcram( void )
14{
15  void *fncptr = (void*)bsp_start_hook_0;
16  return ( fncptr >= (void*)TMS570_TCRAM_START_PTR ) &&
17         ( fncptr < (void*)TMS570_TCRAM_WINDOW_END_PTR );
18}
19
20static inline
21int tms570_running_from_sdram( void )
22{
23  void *fncptr = (void*)bsp_start_hook_0;
24  return ( ( (void*)fncptr >= (void*)TMS570_SDRAM_START_PTR ) &&
25           ( (void*)fncptr < (void*)TMS570_SDRAM_WINDOW_END_PTR ) );
26}
27
28#define PBIST_March13N_SP        0x00000008U  /**< March13 N Algo for 1 Port mem */
29
30BSP_START_TEXT_SECTION void bsp_start_hook_0( void )
31{
32  /*
33   * Work Around for Errata DEVICE#140: ( Only on Rev A silicon)
34   *
35   * Errata Description:
36   *            The Core Compare Module(CCM-R4) may cause nERROR to be asserted after a cold power-on
37   * Workaround:
38   *            Clear ESM Group2 Channel 2 error in ESMSR2 and Compare error in CCMSR register
39   */
40  if ( TMS570_SYS1.DEVID == 0x802AAD05U ) {
41    _esmCcmErrorsClear_();
42  }
43
44  /* Enable CPU Event Export */
45  /* This allows the CPU to signal any single-bit or double-bit errors detected
46   * by its ECC logic for accesses to program flash or data RAM.
47   */
48  _coreEnableEventBusExport_();
49
50  /* Workaround for Errata CORTEXR4 66 */
51  _errata_CORTEXR4_66_();
52
53  /* Workaround for Errata CORTEXR4 57 */
54  _errata_CORTEXR4_57_();
55
56  /* check for power-on reset condition */
57  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
58  if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_PORST ) != 0U ) {
59    /* clear all reset status flags */
60    TMS570_SYS1.SYSESR = 0xFFFFU;
61
62    /* continue with normal start-up sequence */
63  }
64  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
65  else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_OSCRST ) != 0U ) {
66    /* Reset caused due to oscillator failure.
67       Add user code here to handle oscillator failure */
68  }
69  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
70  else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_WDRST ) != 0U ) {
71    /* Reset caused due
72     *  1) windowed watchdog violation - Add user code here to handle watchdog violation.
73     *  2) ICEPICK Reset - After loading code via CCS / System Reset through CCS
74     */
75    /* Check the WatchDog Status register */
76    if ( TMS570_RTI.WDSTATUS != 0U ) {
77      /* Add user code here to handle watchdog violation. */
78      /* Clear the Watchdog reset flag in Exception Status register */
79      TMS570_SYS1.SYSESR = TMS570_SYS1_SYSESR_WDRST;
80    } else {
81      /* Clear the ICEPICK reset flag in Exception Status register */
82      TMS570_SYS1.SYSESR = TMS570_SYS1_SYSESR_WDRST;
83    }
84  }
85  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
86  else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_CPURST ) != 0U ) {
87    /* Reset caused due to CPU reset.
88       CPU reset can be caused by CPU self-test completion, or
89       by toggling the "CPU RESET" bit of the CPU Reset Control Register. */
90
91    /* clear all reset status flags */
92    TMS570_SYS1.SYSESR = TMS570_SYS1_SYSESR_CPURST;
93  }
94  /*SAFETYMCUSW 139 S MR:13.7 <APPROVED> "Hardware status bit read check" */
95  else if ( ( TMS570_SYS1.SYSESR & TMS570_SYS1_SYSESR_SWRST ) != 0U ) {
96    /* Reset caused due to software reset.
97       Add user code to handle software reset. */
98  } else {
99    /* Reset caused by nRST being driven low externally.
100       Add user code to handle external reset. */
101  }
102
103  /*
104   * Check if there were ESM group3 errors during power-up.
105   * These could occur during eFuse auto-load or during reads from flash OTP
106   * during power-up. Device operation is not reliable and not recommended
107   * in this case.
108   * An ESM group3 error only drives the nERROR pin low. An external circuit
109   * that monitors the nERROR pin must take the appropriate action to ensure that
110   * the system is placed in a safe state, as determined by the application.
111   */
112  if ( ( TMS570_ESM.SR[ 2 ] ) != 0U ) {
113    /*SAFETYMCUSW 5 C MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
114    /*SAFETYMCUSW 26 S MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
115    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "for(;;) can be removed by adding "# if 0" and "# endif" in the user codes above and below" */
116    for (;; ) {
117    }           /* Wait */
118  }
119
120  /* Initialize System - Clock, Flash settings with Efuse self check */
121  tms570_system_hw_init();
122
123  /* Workaround for Errata PBIST#4 */
124  /* FIXME */
125  //errata_PBIST_4();
126
127  /*
128   * Run a diagnostic check on the memory self-test controller.
129   * This function chooses a RAM test algorithm and runs it on an on-chip ROM.
130   * The memory self-test is expected to fail. The function ensures that the PBIST controller
131   * is capable of detecting and indicating a memory self-test failure.
132   */
133  tms570_pbist_self_check();
134
135  /* Run PBIST on STC ROM */
136  tms570_pbist_run( (uint32_t) STC_ROM_PBIST_RAM_GROUP,
137    ( (uint32_t) PBIST_TripleReadSlow | (uint32_t) PBIST_TripleReadFast ) );
138
139  /* Wait for PBIST for STC ROM to be completed */
140  /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
141  while ( tms570_pbist_is_test_completed() != TRUE ) {
142  }                                                  /* Wait */
143
144  /* Check if PBIST on STC ROM passed the self-test */
145  if ( tms570_pbist_is_test_passed() != TRUE ) {
146    /* PBIST and STC ROM failed the self-test.
147     * Need custom handler to check the memory failure
148     * and to take the appropriate next step.
149     */
150    tms570_pbist_fail();
151  }
152
153  /* Disable PBIST clocks and disable memory self-test mode */
154  tms570_pbist_stop();
155
156  /* Run PBIST on PBIST ROM */
157  tms570_pbist_run( (uint32_t) PBIST_ROM_PBIST_RAM_GROUP,
158    ( (uint32_t) PBIST_TripleReadSlow | (uint32_t) PBIST_TripleReadFast ) );
159
160  /* Wait for PBIST for PBIST ROM to be completed */
161  /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
162  while ( tms570_pbist_is_test_completed() != TRUE ) {
163  }                                                  /* Wait */
164
165  /* Check if PBIST ROM passed the self-test */
166  if ( tms570_pbist_is_test_passed() != TRUE ) {
167    /* PBIST and STC ROM failed the self-test.
168     * Need custom handler to check the memory failure
169     * and to take the appropriate next step.
170     */
171    tms570_pbist_fail();
172  }
173
174  /* Disable PBIST clocks and disable memory self-test mode */
175  tms570_pbist_stop();
176
177  if ( !tms570_running_from_tcram() ) {
178    /*
179     * The next sequence tests TCRAM, main TMS570 system operation RAM area.
180     * The tests are destructive, lead the first to fill memory by 0xc5c5c5c5
181     * and then to clear it to zero. The sequence is obliviously incompatible
182     * with RTEMS image running from TCRAM area (code clears itself).
183     *
184     * But TCRAM clear leads to overwrite of stack which is used to store
185     * value of bsp_start_hook_0 call return address from link register.
186     *
187     * If the bsp_start_hook_0 by jump to bsp_start_hook_0_done
188     * then generated C code does not use any variable which
189     * is stores on stack and code works OK even that memory
190     * is cleared during bsp_start_hook_0 execution.
191     *
192     * The last assumption is a little fragile in respect to
193     * code and compiler changes.
194     */
195
196    /* Disable RAM ECC before doing PBIST for Main RAM */
197    _coreDisableRamEcc_();
198
199    /* Run PBIST on CPU RAM.
200     * The PBIST controller needs to be configured separately for single-port and dual-port SRAMs.
201     * The CPU RAM is a single-port memory. The actual "RAM Group" for all on-chip SRAMs is defined in the
202     * device datasheet.
203     */
204    tms570_pbist_run( 0x08300020U,   /* ESRAM Single Port PBIST */
205      (uint32_t) PBIST_March13N_SP );
206
207    /* Wait for PBIST for CPU RAM to be completed */
208    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
209    while ( tms570_pbist_is_test_completed() != TRUE ) {
210    }                                                  /* Wait */
211
212    /* Check if CPU RAM passed the self-test */
213    if ( tms570_pbist_is_test_passed() != TRUE ) {
214      /* CPU RAM failed the self-test.
215       * Need custom handler to check the memory failure
216       * and to take the appropriate next step.
217       */
218      tms570_pbist_fail();
219    }
220
221    /* Disable PBIST clocks and disable memory self-test mode */
222    tms570_pbist_stop();
223
224    /*
225     * Initialize CPU RAM.
226     * This function uses the system module's hardware for auto-initialization of memories and their
227     * associated protection schemes. The CPU RAM is initialized by setting bit 0 of the MSIENA register.
228     * Hence the value 0x1 passed to the function.
229     * This function will initialize the entire CPU RAM and the corresponding ECC locations.
230     */
231    tms570_memory_init( 0x1U );
232
233    /*
234     * Enable ECC checking for TCRAM accesses.
235     * This function enables the CPU's ECC logic for accesses to B0TCM and B1TCM.
236     */
237    _coreEnableRamEcc_();
238  } /* end of the code skipped for tms570_running_from_tcram() */
239
240  /* Start PBIST on all dual-port memories */
241  /* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Dual port Memories.
242     PBIST test performed only on the user selected memories in HALCoGen's GUI SAFETY INIT tab.
243   */
244  tms570_pbist_run( (uint32_t) 0x00000000U | /* EMAC RAM */
245    (uint32_t) 0x00000000U |                 /* USB RAM */
246    (uint32_t) 0x00000800U |                 /* DMA RAM */
247    (uint32_t) 0x00000200U |                 /* VIM RAM */
248    (uint32_t) 0x00000040U |                 /* MIBSPI1 RAM */
249    (uint32_t) 0x00000080U |                 /* MIBSPI3 RAM */
250    (uint32_t) 0x00000100U |                 /* MIBSPI5 RAM */
251    (uint32_t) 0x00000004U |                 /* CAN1 RAM */
252    (uint32_t) 0x00000008U |                 /* CAN2 RAM */
253    (uint32_t) 0x00000010U |                 /* CAN3 RAM */
254    (uint32_t) 0x00000400U |                 /* ADC1 RAM */
255    (uint32_t) 0x00020000U |                 /* ADC2 RAM */
256    (uint32_t) 0x00001000U |                 /* HET1 RAM */
257    (uint32_t) 0x00040000U |                 /* HET2 RAM */
258    (uint32_t) 0x00002000U |                 /* HTU1 RAM */
259    (uint32_t) 0x00080000U |                 /* HTU2 RAM */
260    (uint32_t) 0x00004000U |                 /* RTP RAM */
261    (uint32_t) 0x00008000U,                  /* FRAY RAM */
262    (uint32_t) PBIST_March13N_DP );
263
264  if ( !tms570_running_from_tcram() ) {
265
266    /* Test the CPU ECC mechanism for RAM accesses.
267     * The checkBxRAMECC functions cause deliberate single-bit and double-bit errors in TCRAM accesses
268     * by corrupting 1 or 2 bits in the ECC. Reading from the TCRAM location with a 2-bit error
269     * in the ECC causes a data abort exception. The data abort handler is written to look for
270     * deliberately caused exception and to return the code execution to the instruction
271     * following the one that caused the abort.
272     */
273    tms570_check_tcram_ecc();
274
275    /* Wait for PBIST for CPU RAM to be completed */
276    /*SAFETYMCUSW 28 D MR:NA <APPROVED> "Hardware status bit read check" */
277    while ( tms570_pbist_is_test_completed() != TRUE ) {
278    }                                                  /* Wait */
279
280    /* Check if CPU RAM passed the self-test */
281    if ( tms570_pbist_is_test_passed() != TRUE ) {
282      /* CPU RAM failed the self-test.
283       * Need custom handler to check the memory failure
284       * and to take the appropriate next step.
285       */
286      tms570_pbist_fail();
287    }
288
289  } /* end of the code skipped for tms570_running_from_tcram() */
290
291  /* Disable PBIST clocks and disable memory self-test mode */
292  tms570_pbist_stop();
293
294  /* Release the MibSPI1 modules from local reset.
295   * This will cause the MibSPI1 RAMs to get initialized along with the parity memory.
296   */
297  TMS570_SPI1.GCR0 = TMS570_SPI_GCR0_nRESET;
298
299  /* Release the MibSPI3 modules from local reset.
300   * This will cause the MibSPI3 RAMs to get initialized along with the parity memory.
301   */
302  TMS570_SPI3.GCR0 = TMS570_SPI_GCR0_nRESET;
303
304  /* Release the MibSPI5 modules from local reset.
305   * This will cause the MibSPI5 RAMs to get initialized along with the parity memory.
306   */
307  TMS570_SPI5.GCR0 = TMS570_SPI_GCR0_nRESET;
308
309  /* Enable parity on selected RAMs */
310  tms570_enable_parity();
311
312  /* Initialize all on-chip SRAMs except for MibSPIx RAMs
313   * The MibSPIx modules have their own auto-initialization mechanism which is triggered
314   * as soon as the modules are brought out of local reset.
315   */
316  /* The system module auto-init will hang on the MibSPI RAM if the module is still in local reset.
317   */
318  /* NOTE : Please Refer DEVICE DATASHEET for the list of Supported Memories and their channel numbers.
319            Memory Initialization is perfomed only on the user selected memories in HALCoGen's GUI SAFETY INIT tab.
320   */
321  tms570_memory_init( (uint32_t) ( (uint32_t) 1U << 1U ) |  /* DMA RAM */
322    (uint32_t) ( (uint32_t) 1U << 2U ) |                /* VIM RAM */
323    (uint32_t) ( (uint32_t) 1U << 5U ) |                /* CAN1 RAM */
324    (uint32_t) ( (uint32_t) 1U << 6U ) |                /* CAN2 RAM */
325    (uint32_t) ( (uint32_t) 1U << 10U ) |               /* CAN3 RAM */
326    (uint32_t) ( (uint32_t) 1U << 8U ) |                /* ADC1 RAM */
327    (uint32_t) ( (uint32_t) 1U << 14U ) |               /* ADC2 RAM */
328    (uint32_t) ( (uint32_t) 1U << 3U ) |                /* HET1 RAM */
329    (uint32_t) ( (uint32_t) 1U << 4U ) |                /* HTU1 RAM */
330    (uint32_t) ( (uint32_t) 1U << 15U ) |               /* HET2 RAM */
331    (uint32_t) ( (uint32_t) 1U << 16U )                 /* HTU2 RAM */
332  );
333
334  /* Disable parity */
335  tms570_disable_parity();
336
337  /*
338   * Test the parity protection mechanism for peripheral RAMs
339   * Refer DEVICE DATASHEET for the list of Supported Memories
340   * with parity.
341   */
342
343  tms570_selftest_par_run( tms570_selftest_par_list,
344    tms570_selftest_par_list_size );
345
346#if 0
347  /*
348   * RTEMS VIM initialization is implemented by the function
349   * bsp_interrupt_facility_initialize(). RTEMS does not
350   * gain performance from use of vectors targets provided
351   * directly by VIM. RTEMS require to route all interrupts
352   * through _ARMV4_Exception_interrupt handler.
353   *
354   * But actual RTEMS VIM initialization lefts some registers
355   * default values untouched. All registers values should be
356   * ensured/configured in future probably.
357   */
358
359  /* Enable IRQ offset via Vic controller */
360  _coreEnableIrqVicOffset_();
361
362  /* Initialize VIM table */
363  vimInit();
364#endif
365
366  /* Configure system response to error conditions signaled to the ESM group1 */
367  tms570_esm_init();
368
369#if 1
370  /*
371   * Do not depend on link register to be restored to
372   * correct value from stack. If TCRAM self test is enabled
373   * the all stack content is zeroed there.
374   */
375  bsp_start_hook_0_done();
376#endif
377}
378
379BSP_START_TEXT_SECTION void bsp_start_hook_1( void )
380{
381  /* At this point we can use objects outside the .start section  */
382#if 0
383  /* Do not run attempt to initialize MPU when code is running from SDRAM */
384  if ( !tms570_running_from_sdram() ) {
385    /*
386     * MPU background areas setting has to be overlaid
387     * if execution of code is required from external memory/SDRAM.
388     * This region is non executable by default.
389     */
390    _mpuInit_();
391  }
392#endif
393  tms570_emif_sdram_init();
394
395  bsp_start_copy_sections();
396  bsp_start_clear_bss();
397}
398
399/*
400 * Chip specific list of peripherals which should be tested
401 * for functional RAM parity reporting
402 */
403const tms570_selftest_par_desc_t *const
404tms570_selftest_par_list[] = {
405  &tms570_selftest_par_het1_desc,
406  &tms570_selftest_par_htu1_desc,
407  &tms570_selftest_par_het2_desc,
408  &tms570_selftest_par_htu2_desc,
409  &tms570_selftest_par_adc1_desc,
410  &tms570_selftest_par_adc2_desc,
411  &tms570_selftest_par_can1_desc,
412  &tms570_selftest_par_can2_desc,
413  &tms570_selftest_par_can3_desc,
414  &tms570_selftest_par_vim_desc,
415  &tms570_selftest_par_dma_desc,
416  &tms570_selftest_par_spi1_desc,
417  &tms570_selftest_par_spi3_desc,
418  &tms570_selftest_par_spi5_desc,
419};
420
421const int tms570_selftest_par_list_size =
422  RTEMS_ARRAY_SIZE( tms570_selftest_par_list );
Note: See TracBrowser for help on using the repository browser.