/**************************************************************************** * boards/arm/sama5/sama5d4-ek/src/dram_main.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. The * ASF licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #include #include "arm_internal.h" #include "mmu.h" #include "cp15_cacheops.h" #include "sama5d4-ek.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ #define DRAM_ENTRY ((dram_entry_t)SAM_DDRCS_VSECTION) #define DRAM_WAIT 1 #define DRAM_NOWAIT 0 #ifdef CONFIG_SAMA5D4EK_DRAM_START # define DRAM_BOOT_MODE DRAM_NOWAIT #else # define DRAM_BOOT_MODE DRAM_WAIT #endif /**************************************************************************** * Private Types ****************************************************************************/ typedef void (*dram_entry_t)(void); /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** * Name: dram_main * * Description: * dram_main is a tiny program that runs in ISRAM. dram_main will * configure DRAM, present a prompt, load an Intel HEX file into DRAM, * and either start that program or wait for you to break in with the * debugger. * ****************************************************************************/ int dram_main(int argc, char *argv[]) { /* Here we have a in memory value we can change in the debugger * to begin booting in NOR Flash */ static volatile uint32_t wait = DRAM_BOOT_MODE; int ret; /* Disable the PMC. This is necessary on the SAMA5D4-MB Rev C. board. On * that board, the PMIC can lock up the I2C bus. The work around is * awkward: * * 1. Open JP23 (disabling the WM8904 data line) * 2. Execute DRAMBOOT. The WM8904 will be disabled while JP23 is open. * 3. At the prompt to "Send the Intel HEX file now", close JP23, * enabling the WM8904. * 4. Send the NuttX file. When NuttX starts, the WM8904 is initialized, * JP23 will be closed and the PMIC will be initialized. */ sam_pmic_initialize(); /* DRAM was already initialized at boot time, so we are ready to load the * Intel HEX stream into DRAM. * * Hmm.. With no hardware handshake, there is a possibility of data loss * to overrunning incoming data buffer. So far I have not seen this at * 115200 8N1, but still it is a possibility. */ printf("Send Intel HEX file now\n"); fflush(stdout); ret = hex2mem(0, /* Accept Intel HEX on stdin */ (uint32_t)SAM_DDRCS_VSECTION, (uint32_t)(SAM_DDRCS_VSECTION + CONFIG_SAMA5_DDRCS_SIZE), 0); if (ret < 0) { /* We failed the load */ printf("ERROR: Intel HEX file load failed: %d\n", ret); fflush(stdout); for (; ; ); } /* No success indication.. The following cache/MMU operations will clobber * any I/O that we attempt (Hmm.. unless, perhaps, if we delayed. But who * wants a delay?). */ /* Flush the entire data cache assure that everything is in memory before * we disable caching. */ up_clean_dcache((uintptr_t)SAM_DDRCS_VSECTION, (uintptr_t)(SAM_DDRCS_VSECTION + CONFIG_SAMA5_DDRCS_SIZE)); /* Interrupts must be disabled through the following. In this * configuration, there should only be timer interrupts. Your NuttX * configuration must use CONFIG_SERIAL_LOWCONSOLE=y or printf() will * hang when the interrupts are disabled! */ up_irq_save(); /* Disable the caches and the MMU. Disabling the MMU should be safe here * because there is a 1-to-1 identity mapping between the physical and * virtual addressing. */ cp15_disable_mmu(); up_disable_icache(); up_disable_dcache(); /* Invalidate caches and TLBs */ cp15_invalidate_icache_all(); cp15_invalidate_dcache_all(); cp15_invalidate_tlbs(); /* Then jump into NOR flash */ while (wait) { } DRAM_ENTRY(); return 0; /* We should not get here in either case */ }