i.MX6 SMP: Beginning of non-cacheable region (incomplete)

This commit is contained in:
Gregory Nutt 2016-11-26 10:37:06 -06:00
parent e3fe320e08
commit 2fba04f752
2 changed files with 139 additions and 21 deletions

View File

@ -897,7 +897,7 @@
* 0x80000000-0xefffffff: Undefined (1.75 GB)
*
* That is the offset where the main L2 page tables will be positioned. This
* corresponds to page table offsets 0x000002000 up to 0x000003c00. That
* corresponds to page table offsets 0x00002000 up to 0x00003c00. That
* is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual
* address space)
*
@ -917,7 +917,21 @@
* the address space.
*/
#define INTERCPU_L2_PAGES 1 /* Pages allowed for inter-processor communications */
#ifndef CONFIG_ARCH_LOWVECTORS
/* Memory map
* VIRTUAL ADDRESS RANGE L1 PG TABLE L2 PG TABLE DESCRIPTION
* START END OFFSET SIZE
* ---------- ---------- ------------ ----------------------------
* 0x80000000 0x803fffff 0x000002000 0x000000400 Vectors (1MiB)
* 0x80100000 0x806fffff 0x000002400 0x000001800 Paging (6MiB)
*
* If SMP is enabled, then INTERCPU_L2_PAGES pages are taken from the end
* of the Paging L2 page table to hold non-cacheable, inter-processor
* communication data.
*/
/* Vector L2 page table offset/size */
# define VECTOR_L2_OFFSET 0x000002000
@ -933,16 +947,44 @@
# define VECTOR_L2_END_PADDR (VECTOR_L2_PBASE + VECTOR_L2_SIZE)
# define VECTOR_L2_END_VADDR (VECTOR_L2_VBASE + VECTOR_L2_SIZE)
/* Paging L2 page table offset/size */
# ifdef CONFIG_SMP
/* Paging L2 page table offset/size */
# define PGTABLE_L2_OFFSET 0x000002400
# define PGTABLE_L2_SIZE 0x000001800
# define PGTABLE_L2_OFFSET 0x000002400
# define PGTABLE_L2_SIZE (0x000001800 - 4*INTERCPU_L2_PAGES)
# else
/* Paging L2 page table offset/size */
# define PGTABLE_L2_OFFSET 0x000002400
# define PGTABLE_L2_SIZE 0x000001800
# endif
#else
/* Paging L2 page table offset/size */
/* Memory map
* VIRTUAL ADDRESS RANGE L1 PG TABLE L2 PG TABLE DESCRIPTION
* START END OFFSET SIZE
* ---------- ---------- ------------ ----------------------------
* 0x80000000 0x806fffff 0x000002000 0x000001c00 Paging (7MiB)
*
* If SMP is enabled, then INTERCPU_L2_PAGES pages are taken from the end
* of the Paging L2 page table to hold non-cacheable, inter-processor
* communication data.
*/
# ifdef CONFIG_SMP
/* Paging L2 page table offset/size */
# define PGTABLE_L2_OFFSET 0x000002000
# define PGTABLE_L2_SIZE (0x000001c00 - 4*INTERCPU_L2_PAGES)
# else
/* Paging L2 page table offset/size */
# define PGTABLE_L2_OFFSET 0x000002000
# define PGTABLE_L2_SIZE 0x000001c00
# endif
# define PGTABLE_L2_OFFSET 0x000002000
# define PGTABLE_L2_SIZE 0x000001c00
#endif
/* Paging L2 page table base addresses
@ -959,6 +1001,17 @@
#define PGTABLE_L2_END_PADDR (PGTABLE_L2_PBASE + PGTABLE_L2_SIZE)
#define PGTABLE_L2_END_VADDR (PGTABLE_L2_VBASE + PGTABLE_L2_SIZE)
#ifdef CONFIG_SMP
/* Non-cached inter-processor communication data */
# define INTERCPU_L2_OFFSET (PGTABLE_L2_OFFSET + PGTABLE_L2_SIZE)
# define INTERCPU_L2_SIZE (4*INTERCPU_L2_PAGES)
/* Inter-processor communications L2 page table virtual base addresse */
# define INTERCPU_L2_VBASE (PGTABLE_BASE_VADDR + INTERCPU_L2_OFFSET)
#endif
/* Base address of the interrupt vector table.
*
* IMX_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM
@ -974,19 +1027,35 @@
*/
#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */
/* Vectors will always lie at the beginnin of OCRAM */
/* Vectors will always lie at the beginning of OCRAM */
# define IMX_VECTOR_PADDR IMX_OCRAM_PBASE
# define IMX_VECTOR_VSRAM IMX_OCRAM_VBASE
# define IMX_VECTOR_VADDR 0x00000000
#ifdef CONFIG_SMP
/* Inter-processor communications */
# define INTERCPU_PADDR (IMX_VECTOR_PADDR + VECTOR_TABLE_SIZE)
# define INTERCPU_VADDR (INTERCPU_L2_VBASE << 18)
# define INTERCPU_SIZE (INTERCPU_L2_PAGES << 12)
# define INTERCPU_VSRAM (IMX_VECTOR_VSRAM + VECTOR_TABLE_SIZE)
#endif
#else /* Vectors located at 0xffff:0000 -- this probably does not work */
# define IMX_VECTOR_PADDR (IMX_OCRAM_PBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE)
# define IMX_VECTOR_VSRAM (IMX_OCRAM_VBASE + IMX_OCRAM_SIZE - VECTOR_TABLE_SIZE)
# define IMX_VECTOR_VADDR 0xffff0000
#ifdef CONFIG_SMP
/* Inter-processor communications */
# define INTERCPU_PADDR (IMX_VECTOR_PADDR - INTERCPU_L2_SIZE)
# define INTERCPU_VADDR (INTERCPU_L2_VBASE << 18)
# define INTERCPU_SIZE (INTERCPU_L2_PAGES << 12)
# define INTERCPU_VSRAM (IMX_VECTOR_VSRAM - INTERCPU_L2_SIZE)
#endif
#endif
/************************************************************************************

View File

@ -224,6 +224,46 @@ static void imx_vectormapping(void)
# define imx_vectormapping()
#endif
/****************************************************************************
* Name: imx_intercpu_mapping
*
* Description:
* Setup a special mapping for the non-cached, inter-cpu communications
* area.
*
****************************************************************************/
#ifndef CONFIG_SMP
static void imx_intercpu_mapping(void)
{
uint32_t intercpu_paddr = INTERCPU_PADDR & PTE_SMALL_PADDR_MASK;
uint32_t intercpu_vaddr = INTERCPU_VADDR & PTE_SMALL_PADDR_MASK;
uint32_t end_paddr = INTERCPU_PADDR + INTERCPU_SIZE;
/* We want to keep the inter-cpu region in on-chip RAM (OCRAM). The
* i.MX6 has 256Kb of OCRAM positioned at physical address 0x0090:0000.
*/
while (intercpu_paddr < end_paddr)
{
mmu_l2_setentry(INTERCPU_L2_VBASE, intercpu_paddr, intercpu_vaddr,
MMU_L2_INTERCPUFLAGS);
intercpu_paddr += 4096;
intercpu_vaddr += 4096;
}
/* Now set the level 1 descriptor to refer to the level 2 page table. */
mmu_l1_setentry(VECTOR_L2_PBASE & PMD_PTE_PADDR_MASK,
INTERCPU_VADDR & PMD_PTE_PADDR_MASK,
MMU_L1_PGTABFLAGS);
}
#else
/* No inter-cpu communications area */
# define imx_intercpu_mapping()
#endif
/****************************************************************************
* Name: imx_copyvectorblock
*
@ -414,6 +454,15 @@ void arm_boot(void)
imx_vectormapping();
imx_lowputc('B');
#ifdef CONFIG_SMP
/* Provide a special mapping for the OCRAM interrupt vector positioned in
* high memory.
*/
imx_intercpu_mapping();
imx_lowputc('C');
#endif
#ifdef CONFIG_ARCH_RAMFUNCS
/* Copy any necessary code sections from FLASH to RAM. The correct
* destination in OCRAM is given by _sramfuncs and _eramfuncs. The
@ -426,14 +475,14 @@ void arm_boot(void)
*dest++ = *src++;
}
imx_lowputc('C');
imx_lowputc('D');
/* Flush the copied RAM functions into physical RAM so that will
* be available when fetched into the I-Cache.
*/
arch_clean_dcache((uintptr_t)&_sramfuncs, (uintptr_t)&_eramfuncs)
imx_lowputc('D');
imx_lowputc('E');
#endif
/* Setup up vector block. _vector_start and _vector_end are exported from
@ -441,23 +490,23 @@ void arm_boot(void)
*/
imx_copyvectorblock();
imx_lowputc('E');
imx_lowputc('F');
/* Disable the watchdog timer */
imx_wdtdisable();
imx_lowputc('F');
imx_lowputc('G');
/* Initialize clocking to settings provided by board-specific logic */
imx_clockconfig();
imx_lowputc('G');
imx_lowputc('H');
#ifdef CONFIG_ARCH_FPU
/* Initialize the FPU */
arm_fpuconfig();
imx_lowputc('H');
imx_lowputc('I');
#endif
/* Perform board-specific initialization, This must include:
@ -471,7 +520,7 @@ void arm_boot(void)
*/
imx_board_initialize();
imx_lowputc('I');
imx_lowputc('J');
#ifdef NEED_SDRAM_REMAPPING
/* SDRAM was configured in a temporary state to support low-level
@ -480,7 +529,7 @@ void arm_boot(void)
*/
imx_remap();
imx_lowputc('J');
imx_lowputc('K');
#endif
#ifdef CONFIG_BOOT_SDRAM_DATA
@ -489,13 +538,13 @@ void arm_boot(void)
*/
arm_data_initialize();
imx_lowputc('K');
imx_lowputc('L');
#endif
/* Perform common, low-level chip initialization (might do nothing) */
imx_lowsetup();
imx_lowputc('L');
imx_lowputc('M');
#ifdef USE_EARLYSERIALINIT
/* Perform early serial initialization if we are going to use the serial
@ -503,7 +552,7 @@ void arm_boot(void)
*/
imx_earlyserialinit();
imx_lowputc('M');
imx_lowputc('N');
#endif
/* Now we can enable all other CPUs. The enabled CPUs will start execution
@ -512,6 +561,6 @@ void arm_boot(void)
*/
imx_cpu_enable();
imx_lowputc('N');
imx_lowputc('O');
imx_lowputc('\n');
}