A10 mmu configuration and INTC register definitions

This commit is contained in:
Gregory Nutt 2013-12-08 09:11:52 -06:00
parent ae044a485c
commit c661c4014f
5 changed files with 639 additions and 39 deletions

View File

@ -6175,3 +6175,6 @@
(2013-12-7).
* configs/pcduino-a10: Directory structure for the pcDuino board. This
board is based on the Allwinner A10 (2013-12-7).
* arch/arm/src/a1x/a1x_boot.c and chip/a1x_intc.h: More A10 logic
(2013-12-8).

View File

@ -93,4 +93,4 @@ CHIP_ASRCS =
# A1x-specific C source files
CHIP_CSRCS =
CHIP_CSRCS = a1x_boot.c

377
arch/arm/src/a1x/a1x_boot.c Normal file
View File

@ -0,0 +1,377 @@
/****************************************************************************
* arch/arm/src/a1x/a1x_boot.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdint.h>
#include <assert.h>
#ifdef CONFIG_PAGING
# include <nuttx/page.h>
#endif
#include <arch/board/board.h>
#include "chip.h"
#include "arm.h"
#include "mmu.h"
#include "fpu.h"
#include "up_internal.h"
#include "up_arch.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* The vectors are, by default, positioned at the beginning of the text
* section. They will always have to be copied to the correct location.
*
* If we are using high vectors (CONFIG_ARCH_LOWVECTORS=n). In this case,
* the vectors will lie at virtual address 0xffff:000 and we will need
* to a) copy the vectors to another location, and b) map the vectors
* to that address, and
*
* For the case of CONFIG_ARCH_LOWVECTORS=y, defined. Vectors will be
* copied to SRAM A1 at address 0x0000:0000
*/
#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_ARCH_ROMPGTABLE)
# error High vector remap cannot be performed if we are using a ROM page table
#endif
/* if SDRAM is used, then it will be configured twice: It will first be
* configured to a temporary state to support low-level ininitialization.
* After the SDRAM has been fully initialized, SRAM be used to
* set the SDRM in its final, fully cache-able state.
*/
#undef NEED_SDRAM_REMAPPING
#if defined(CONFIG_SAMA5_DDRCS) && !defined(CONFIG_SAMA5_BOOT_SDRAM) && \
!defined(CONFIG_ARCH_ROMPGTABLE)
# define NEED_SDRAM_REMAPPING 1
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Public Variables
****************************************************************************/
extern uint32_t _vector_start; /* Beginning of vector block */
extern uint32_t _vector_end; /* End+1 of vector block */
/****************************************************************************
* Private Variables
****************************************************************************/
/* This table describes how to map a set of 1Mb pages to space the physical
* address space of the A1X.
*/
#ifndef CONFIG_ARCH_ROMPGTABLE
static const struct section_mapping_s section_mapping[] =
{
{ A1X_INTMEM_PSECTION, A1X_INTMEM_VSECTION,
A1X_INTMEM_MMUFLAGS, A1X_INTMEM_NSECTIONS
},
{ A1X_PERIPH_PSECTION, A1X_PERIPH_VSECTION,
A1X_PERIPH_MMUFLAGS, A1X_PERIPH_NSECTIONS
},
{ A1X_SRAMC_PSECTION, A1X_SRAMC_VSECTION,
A1X_SRAMC_MMUFLAGS, A1X_SRAMC_NSECTIONS
},
{ A1X_DE_PSECTION, A1X_DE_VSECTION,
A1X_DE_MMUFLAGS, A1X_DE_NSECTIONS
},
{ A1X_DDR_PSECTION, A1X_DDR_VSECTION,
A1X_DDR_MMUFLAGS, A1X_DDR_NSECTIONS
},
{ A1X_BROM_PSECTION, A1X_BROM_VSECTION,
A1X_BROM_MMUFLAGS, A1X_BROM_NSECTIONS
}
};
#define NMAPPINGS \
(sizeof(section_mapping) / sizeof(struct section_mapping_s))
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: a1x_setupmappings
*
* Description
* Map all of the initial memory regions defined in section_mapping[]
*
****************************************************************************/
#ifndef CONFIG_ARCH_ROMPGTABLE
static inline void a1x_setupmappings(void)
{
int i;
for (i = 0; i < NMAPPINGS; i++)
{
mmu_l1_map_region(&section_mapping[i]);
}
}
#endif
/****************************************************************************
* Name: a1x_vectorpermissions
*
* Description:
* Set permissions on the vector mapping.
*
****************************************************************************/
#if !defined(CONFIG_ARCH_ROMPGTABLE) && defined(CONFIG_ARCH_LOWVECTORS) && \
defined(CONFIG_PAGING)
static void a1x_vectorpermissions(uint32_t mmuflags)
{
/* The PTE for the beginning of ISRAM is at the base of the L2 page table */
uint32_t pte = mmu_l2_getentry(PG_L2_VECT_VADDR, 0);
/* String the MMU flags from the page table entry.
*
* The pte might be zero the first time this function is called.
*/
if (pte == 0)
{
pte = PG_VECT_PBASE;
}
else
{
pte &= PG_L1_PADDRMASK;
}
/* Update the page table entry with the MMU flags and save */
mmu_l2_setentry(PG_L2_VECT_VADDR, pte, 0, mmuflags);
}
#endif
/****************************************************************************
* Name: a1x_vectormapping
*
* Description:
* Setup a special mapping for the interrupt vectors when (1) the
* interrupt vectors are not positioned in ROM, and when (2) the interrupt
* vectors are located at the high address, 0xffff0000. When the
* interrupt vectors are located in ROM, we just have to assume that they
* were set up correctly; When vectors are located in low memory,
* 0x00000000, the mapping for the ROM memory region will be suppressed.
*
****************************************************************************/
#if !defined(CONFIG_ARCH_ROMPGTABLE) && !defined(CONFIG_ARCH_LOWVECTORS)
static void a1x_vectormapping(void)
{
uint32_t vector_paddr = A1X_VECTOR_PADDR & PTE_SMALL_PADDR_MASK;
uint32_t vector_vaddr = A1X_VECTOR_VADDR & PTE_SMALL_PADDR_MASK;
uint32_t vector_size = (uint32_t)&_vector_end - (uint32_t)&_vector_start;
uint32_t end_paddr = A1X_VECTOR_PADDR + vector_size;
/* REVISIT: Cannot really assert in this context */
DEBUGASSERT (vector_size <= VECTOR_TABLE_SIZE);
/* We want to keep our interrupt vectors and interrupt-related logic in
* zero-wait state internal SRAM (ISRAM). The A1X has 128Kb of ISRAM
* positioned at physical address 0x0300:0000; we need to map this to
* 0xffff:0000.
*/
while (vector_paddr < end_paddr)
{
mmu_l2_setentry(VECTOR_L2_VBASE, vector_paddr, vector_vaddr,
MMU_L2_VECTORFLAGS);
vector_paddr += 4096;
vector_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,
A1X_VECTOR_VADDR & PMD_PTE_PADDR_MASK,
MMU_L1_VECTORFLAGS);
}
#else
/* No vector remap */
# define a1x_vectormapping()
#endif
/****************************************************************************
* Name: a1x_copyvectorblock
*
* Description:
* Copy the interrupt block to its final destination. Vectors are already
* positioned at the beginning of the text region and only need to be
* copied in the case where we are using high vectors.
*
* NOTE: We don't actually have to copy the vector block. We could simply
* set the the INTC vector address.
*
****************************************************************************/
static void a1x_copyvectorblock(void)
{
uint32_t *src;
uint32_t *end;
uint32_t *dest;
/* If we are using re-mapped vectors in an area that has been marked
* read only, then temparily mark the mapping write-able (non-buffered).
*/
#ifdef CONFIG_PAGING
a1x_vectorpermissions(MMU_L2_VECTRWFLAGS);
#endif
/* Copy the vectors into ISRAM at the address that will be mapped to the vector
* address:
*
* A1X_VECTOR_PADDR - Unmapped, physical address of vector table in SRAM
* A1X_VECTOR_VSRAM - Virtual address of vector table in SRAM
* A1X_VECTOR_VADDR - Virtual address of vector table (0x00000000 or
* 0xffff0000)
*/
src = (uint32_t*)&_vector_start;
end = (uint32_t*)&_vector_end;
dest = (uint32_t*)A1X_VECTOR_VSRAM;
while (src < end)
{
*dest++ = *src++;
}
/* Make the vectors read-only, cacheable again */
#if !defined(CONFIG_ARCH_LOWVECTORS) && defined(CONFIG_PAGING)
a1x_vectorpermissions(MMU_L2_VECTORFLAGS);
#endif
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_boot
*
* Description:
* Complete boot operations started in arm_head.S
*
* This logic will be executing in SDRAM. This boot logic was started by
* the A10 boot logic. At this point in time, clocking and SDRAM have
* already be initialized (they must be because we are executing out of
* SDRAM). So all that must be done here is to:
*
* 1) Refine the memory mapping,
* 2) Configure the serial console, and
* 3) Perform board-specific initializations.
*
****************************************************************************/
void up_boot(void)
{
#ifndef CONFIG_ARCH_ROMPGTABLE
/* __start provided the basic MMU mappings for SRAM. Now provide mappings
* for all IO regions (Including the vector region).
*/
a1x_setupmappings();
/* Provide a special mapping for the IRAM interrupt vector positioned in
* high memory.
*/
a1x_vectormapping();
#endif /* CONFIG_ARCH_ROMPGTABLE */
/* Setup up vector block. _vector_start and _vector_end are exported from
* arm_vector.S
*/
a1x_copyvectorblock();
/* Initialize the FPU */
#ifdef CONFIG_ARCH_FPU
arm_fpuconfig();
#endif
/* Perform common, low-level chip initialization (might do nothing) */
a1x_lowsetup();
/* Perform early serial initialization if we are going to use the serial
* driver.
*/
#ifdef USE_EARLYSERIALINIT
a1x_earlyserialinit();
#endif
/* For the case of the separate user-/kernel-space build, perform whatever
* platform specific initialization of the user memory is required.
* Normally this just means initializing the user space .data and .bss
* segments.
*/
#ifdef CONFIG_NUTTX_KERNEL
a1x_userspace();
#endif
/* Perform board-specific initialization, This must include:
*
* - Initialization of board-specific memory resources (e.g., SDRAM)
* - Configuration of board specific resources (PIOs, LEDs, etc).
*/
a1x_boardinitialize();
}

View File

@ -103,7 +103,7 @@
#define A1X_ACE_OFFSET 0x0001a000 /* ACE 0x01c1:A000-0x01c1:afff 4K */
#define A1X_TVE1_OFFSET 0x0001b000 /* TVE 1 0x01c1:B000-0x01c1:bfff 4K */
#define A1X_USB2_OFFSET 0x0001c000 /* USB 2 0x01c1:C000-0x01c1:cfff 4K */
#define A1X_CSI1_OFFSET 0x0001d000 /* CSI 1 0x01c1:D000-0x01c1:dfff 4K */
#define A1X_CSI1_OFFSET 0x0001d000 /* CSI 1 0x01c1:D000-0x01c1:dfff 4K */
#define A1X_TZASC_OFFSET 0x0001e000 /* TZASC 0x01c1:E000-0x01c1:efff 4K */
#define A1X_SPI3_OFFSET 0x0001f000 /* SPI3 0x01c1:F000-0x01c1:ffff 4K */
#define A1X_CCM_OFFSET 0x00020000 /* CCM 0x01c2:0000-0x01c2:03ff 1K */
@ -159,7 +159,7 @@
#define A1X_SRAMA2_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA2_OFFSET)
#define A1X_SRAMA3_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA3_OFFSET)
#define A1X_SRAMA4_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMA4_OFFSET)
#define A1X_SRAMNAND_PADDR
#define A1X_SRAMNAND_PADDR
#define A1X_SRAMD_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMD_OFFSET)
#define A1X_SRAMDSEC_PADDR (A1X_INTMEM_PSECTION+A1X_SRAMDSEC_OFFSET)
@ -273,13 +273,16 @@
* span the entire physical address space. The definitions below specify
* the number of 1Mb entries that are required to span a particular address
* region.
*
* NOTE: the size of the mapped SDRAM region depends on the configured size
* of DRAM, not on the size of the address space assigned to DRAM.
*/
#define A1X_INTMEM_NSECTIONS _NSECTIONS(A1X_INTMEM_SIZE)
#define A1X_PERIPH_NSECTIONS _NSECTIONS(A1X_PERIPH_SIZE)
#define A1X_SRAMC_NSECTIONS _NSECTIONS(A1X_SRAMC_SIZE)
#define A1X_DE_NSECTIONS _NSECTIONS(A1X_DE_SIZE)
#define A1X_DDR_NSECTIONS _NSECTIONS(A1X_DDR_SIZE)
#define A1X_DDR_NSECTIONS _NSECTIONS(CONFIG_RAM_SIZE)
#define A1X_BROM_NSECTIONS _NSECTIONS(A1X_BROM_SIZE)
/* Section MMU Flags */
@ -325,7 +328,7 @@
#define A1X_SRAMA2_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA2_OFFSET)
#define A1X_SRAMA3_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA3_OFFSET)
#define A1X_SRAMA4_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMA4_OFFSET)
#define A1X_SRAMNAND_VADDR
#define A1X_SRAMNAND_VADDR
#define A1X_SRAMD_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMD_OFFSET)
#define A1X_SRAMDSEC_VADDR (A1X_INTMEM_VSECTION+A1X_SRAMDSEC_OFFSET)
@ -410,7 +413,7 @@
#define A1X_BROM_VADDR (A1X_BROM_VSECTION+A1X_BROM_OFFSET)
/* NuttX vitual base address
/* NuttX virtual base address
*
* The boot logic will create a temporarily mapping based on where NuttX is
* executing in memory. In this case, NuttX will be running from either
@ -478,37 +481,45 @@
*
* 16Kb of memory is reserved hold the page table for the virtual mappings. A
* portion of this table is not accessible in the virtual address space (for
* normal operation). There is this large whole in the physcal address space
* for which there will never be level 1 mappings:
* normal operation). There are several large holes in the physical address
* space for which there will never be level 1 mappings:
*
* 0x80000000-0xefffffff: Undefined (1.75 GB)
* LI PAGE TABLE
* ADDRESS RANGE SIZE ENTRIES SECTIONS
* ----------------------- ------- -------------- ---------
* 0x0003:0000-0x01eb:ffff 275MB 0x0004-0x006c 26
* *(none usable) 0
* 0x01ec:0000-0x3fff:ffff 993MB 0x0078-0x0ffc 993
* *0x0400-0x0ffc 767
*
* That is the offset where the main L2 page tables will be positioned. This
* corresponds to page table offsets 0x000002000 up to 0x000003c00. That
* is 1792 entries, each mapping 4KB of address for a total of 7MB of virtual
* address space)
* And the largest is probably from the end of SDRAM through 0xfff0:0000.
* But the size of that region varies with the size of the installed SDRAM.
* It is at least:
*
* Up to two L2 page tables may be used:
* LI PAGE TABLE
* ADDRESS RANGE SIZE ENTRIES SECTIONS
* ----------------------- ------- -------------- ---------
* 0xc000:0000-0xffef:ffff 1022MB *0x3000-0x3ff8 1022
*
* 1) One mapping the vector table. However, L2 page tables must be aligned
* to 1KB address boundaries, so the minimum L2 page table size is then
* 1KB, mapping up a full megabyte of virtual address space.
* And probably much larger.
*
* This L2 page table is only allocated if CONFIG_ARCH_LOWVECTORS is *not*
* defined. The A1X boot-up logic will map the beginning of the boot
* memory to address 0x0000:0000 using both the MMU and the AXI matrix
* REMAP register. So no L2 page table is required.
* * NOTE that the L2 page table entries must be aligned 1KB address
* boundaries.
*
* These two larger regions is where L2 page tables will positioned. Up to
* two L2 page tables may be used:
*
* 1) One mapping the vector table (only when CONFIG_ARCH_LOWVECTORS is not
* defined).
* 2) If on-demand paging is supported (CONFIG_PAGING=y), than an additional
* L2 page table is needed. This page table will use the remainder of
* the address space.
* L2 page table is needed.
*/
#ifndef CONFIG_ARCH_LOWVECTORS
/* Vector L2 page table offset/size */
# define VECTOR_L2_OFFSET 0x000002000
# define VECTOR_L2_SIZE 0x000000400
# define VECTOR_L2_OFFSET 0x000000400
# define VECTOR_L2_SIZE 0x000000bfc
/* Vector L2 page table base addresses */
@ -519,19 +530,16 @@
# 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 */
# define PGTABLE_L2_OFFSET 0x000002400
# define PGTABLE_L2_SIZE 0x000001800
#else
/* Paging L2 page table offset/size */
# define PGTABLE_L2_OFFSET 0x000002000
# define PGTABLE_L2_SIZE 0x000001c00
#endif
/* Paging L2 page table offset/size */
#define PGTABLE_START_PADDR (A1X_DDR_PSECTION+CONFIG_RAM_SIZE)
#define PGTABLE_BROM_OFFSET 0x3ffc
#define PGTABLE_L2_OFFSET ((PGTABLE_START_PADDR >> 18) & ~3)
#define PGTABLE_L2_SIZE (PGTABLE_BROM_OFFSET - PGTABLE_L2_OFFSET)
/* Paging L2 page table base addresses
*
* NOTE: If CONFIG_PAGING is defined, mmu.h will re-assign the virtual
@ -556,15 +564,15 @@
#define VECTOR_TABLE_SIZE 0x00010000
#ifdef CONFIG_ARCH_LOWVECTORS /* Vectors located at 0x0000:0000 */
# define A1X_VECTOR_PADDR A1X_SRAMA1_PADDR
# define A1X_VECTOR_VSRAM A1X_ISRAM0_VADDR
# define A1X_VECTOR_VSRAM A1X_SRAMA1_VADDR
# define A1X_VECTOR_VADDR 0x00000000
#else /* Vectors located at 0xffff:0000 -- this probably does not work */
# ifdef A1X_ISRAM1_SIZE >= VECTOR_TABLE_SIZE
# define A1X_VECTOR_PADDR (A1X_SRAMA1_PADDR+A1X_ISRAM1_SIZE-VECTOR_TABLE_SIZE)
# define A1X_VECTOR_VSRAM (A1X_ISRAM1_VADDR+A1X_ISRAM1_SIZE-VECTOR_TABLE_SIZE)
# define A1X_VECTOR_VSRAM (A1X_SRAMA1_VADDR+A1X_ISRAM1_SIZE-VECTOR_TABLE_SIZE)
# else
# define A1X_VECTOR_PADDR (A1X_SRAMA1_PADDR+A1X_ISRAM0_SIZE-VECTOR_TABLE_SIZE)
# define A1X_VECTOR_VSRAM (A1X_ISRAM0_VADDR+A1X_ISRAM0_SIZE-VECTOR_TABLE_SIZE)
# define A1X_VECTOR_VSRAM (A1X_SRAMA1_VADDR+A1X_ISRAM0_SIZE-VECTOR_TABLE_SIZE)
# endif
# define A1X_VECTOR_VADDR 0xffff0000
#endif

View File

@ -0,0 +1,212 @@
/************************************************************************************
* arch/arm/src/a1x/chip/a1x_intc.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H
#define __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H
/************************************************************************************
* Included Files
************************************************************************************/
#include <nuttx/config.h>
#include <arch/a1x/chip.h>
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* Register offsets *****************************************************************/
#define A1X_INTC_VECTOR_OFFSET 0x0000 /* Interrupt Vector */
#define A1X_INTC_BASEADDR_OFFSET 0x0004 /* Interrupt Base Address */
#define A1X_INTC_PROTECT_OFFSET 0x0008 /* Interrupt Protection Register */
#define A1X_INTC_NMICTRL_OFFSET 0x000c /* Interrupt Control */
#define A1X_INTC_IRQ_PEND0_OFFSET 0x0010 /* Interrupt IRQ Pending 0 Status */
#define A1X_INTC_IRQ_PEND1_OFFSET 0x0014 /* Interrupt IRQ Pending 1 Status */
#define A1X_INTC_IRQ_PEND2_OFFSET 0x0018 /* Interrupt IRQ Pending 2 Status */
#define A1X_INTC_FIQ_PEND0_OFFSET 0x0020 /* Interrupt FIQ Pending 0 Status */
#define A1X_INTC_FIQ_PEND1_OFFSET 0x0024 /* Interrupt FIQ Pending 1 Status */
#define A1X_INTC_FIQ_PEND2_OFFSET 0x0028 /* Interrupt FIQ Pending 2 Status */
#define A1X_INTC_IRQ_SEL0_OFFSET 0x0030 /* Interrupt Select 0 */
#define A1X_INTC_IRQ_SEL1_OFFSET 0x0034 /* Interrupt Select 1 */
#define A1X_INTC_IRQ_SEL2_OFFSET 0x0038 /* Interrupt Select 2 */
#define A1X_INTC_EN0_OFFSET 0x0040 /* Interrupt Enable 0 */
#define A1X_INTC_EN1_OFFSET 0x0044 /* Interrupt Enable 1 */
#define A1X_INTC_EN2_OFFSET 0x0048 /* Interrupt Enable 2 */
#define A1X_INTC_MASK0_OFFSET 0x0050 /* Interrupt Mask 0 */
#define A1X_INTC_MASK1_OFFSET 0x0054 /* Interrupt Mask 1 */
#define A1X_INTC_MASK2_OFFSET 0x0058 /* Interrupt Mask 2 */
#define A1X_INTC_RESP0_OFFSET 0x0060 /* Interrupt Response 0 */
#define A1X_INTC_RESP1_OFFSET 0x0064 /* Interrupt Response 1 */
#define A1X_INTC_RESP2_OFFSET 0x0068 /* Interrupt Response 2 */
#define A1X_INTC_FF0_OFFSET 0x0070 /* Interrupt Fast Forcing 0 */
#define A1X_INTC_FF1_OFFSET 0x0074 /* Interrupt Fast Forcing 1 */
#define A1X_INTC_FF2_OFFSET 0x0078 /* Interrupt Fast Forcing 2 */
#define A1X_INTC_PRIO0_OFFSET 0x0080 /* Interrupt Source Priority 0 */
#define A1X_INTC_PRIO1_OFFSET 0x0084 /* Interrupt Source Priority 1 */
#define A1X_INTC_PRIO2_OFFSET 0x0088 /* Interrupt Source Priority 2 */
#define A1X_INTC_PRIO3_OFFSET 0x008c /* Interrupt Source Priority 3 */
#define A1X_INTC_PRIO4_OFFSET 0x0090 /* Interrupt Source Priority 4 */
/* Register virtual addresses *******************************************************/
#define A1X_INTC_VECTOR (A1X_INTC_VADDR+A1X_INTC_VECTOR_OFFSET)
#define A1X_INTC_BASEADDR (A1X_INTC_VADDR+A1X_INTC_BASEADDR_OFFSET)
#define A1X_INTC_PROTECT (A1X_INTC_VADDR+A1X_INTC_PROTECT_OFFSET)
#define A1X_INTC_NMICTRL (A1X_INTC_VADDR+A1X_INTC_NMICTRL_OFFSET)
#define A1X_INTC_IRQ_PEND0 (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND0_OFFSET)
#define A1X_INTC_IRQ_PEND1 (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND1_OFFSET)
#define A1X_INTC_IRQ_PEND2 (A1X_INTC_VADDR+A1X_INTC_IRQ_PEND2_OFFSET)
#define A1X_INTC_FIQ_PEND0 (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND0_OFFSET)
#define A1X_INTC_FIQ_PEND1 (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND1_OFFSET)
#define A1X_INTC_FIQ_PEND2 (A1X_INTC_VADDR+A1X_INTC_FIQ_PEND2_OFFSET)
#define A1X_INTC_IRQ_SEL0 (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL0_OFFSET)
#define A1X_INTC_IRQ_SEL1 (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL1_OFFSET)
#define A1X_INTC_IRQ_SEL2 (A1X_INTC_VADDR+A1X_INTC_IRQ_SEL2_OFFSET)
#define A1X_INTC_EN0 (A1X_INTC_VADDR+A1X_INTC_EN0_OFFSET)
#define A1X_INTC_EN1 (A1X_INTC_VADDR+A1X_INTC_EN1_OFFSET)
#define A1X_INTC_EN2 (A1X_INTC_VADDR+A1X_INTC_EN2_OFFSET)
#define A1X_INTC_MASK0 (A1X_INTC_VADDR+A1X_INTC_MASK0_OFFSET)
#define A1X_INTC_MASK1 (A1X_INTC_VADDR+A1X_INTC_MASK1_OFFSET)
#define A1X_INTC_MASK2 (A1X_INTC_VADDR+A1X_INTC_MASK2_OFFSET)
#define A1X_INTC_RESP0 (A1X_INTC_VADDR+A1X_INTC_RESP0_OFFSET)
#define A1X_INTC_RESP1 (A1X_INTC_VADDR+A1X_INTC_RESP1_OFFSET)
#define A1X_INTC_RESP2 (A1X_INTC_VADDR+A1X_INTC_RESP2_OFFSET)
#define A1X_INTC_FF0 (A1X_INTC_VADDR+A1X_INTC_FF0_OFFSET)
#define A1X_INTC_FF1 (A1X_INTC_VADDR+A1X_INTC_FF1_OFFSET)
#define A1X_INTC_FF2 (A1X_INTC_VADDR+A1X_INTC_FF2_OFFSET)
#define A1X_INTC_PRIO0 (A1X_INTC_VADDR+A1X_INTC_PRIO0_OFFSET)
#define A1X_INTC_PRIO1 (A1X_INTC_VADDR+A1X_INTC_PRIO1_OFFSET)
#define A1X_INTC_PRIO2 (A1X_INTC_VADDR+A1X_INTC_PRIO2_OFFSET)
#define A1X_INTC_PRIO3 (A1X_INTC_VADDR+A1X_INTC_PRIO3_OFFSET)
#define A1X_INTC_PRIO4 (A1X_INTC_VADDR+A1X_INTC_PRIO4_OFFSET)
/* Register bit field definitions ***************************************************/
/* Interrupt Vector */
#define INTC_VECTOR_MASK 0xfffffffc /* Bits 2-31: Vector address */
/* Interrupt Base Address */
#define INTC_BASEADDR_MASK 0xfffffffc /* Bits 2-31: Base address */
/* Interrupt Control */
#define INTC_PROTECT_PROTEN (1 << 0) /* Bit 0: Enabled protected register access */
/* Interrupt Control */
#define INTC_NMICTRL_SRCTYPE_SHIFT (0) /* Bits 0-1: External NMI Interrupt Source Type */
#define INTC_NMICTRL_SRCTYPE_MASK (3 << INTC_NMICTRL_SRCTYPE_SHIFT)
# define INTC_NMICTRL_SRCTYPE_LOW (0 << INTC_NMICTRL_SRCTYPE_SHIFT) /* Low level sensitive */
# define INTC_NMICTRL_SRCTYPE_NEDGE (1 << INTC_NMICTRL_SRCTYPE_SHIFT) /* Negative edge trigged */
/* Interrupt IRQ Pending 0-2 Status */
#define INTC_IRQ_PEND(n) (1 << (n)) /* n=0-31: Interrupt pending */
# define INTC_IRQ_PEND0(n) (1 << (n)) /* n=0-31: Interrupt pending */
# define INTC_IRQ_PEND1(n) (1 << ((n) - 32)) /* n=32-63: Interrupt pending */
# define INTC_IRQ_PEND2(n) (1 << ((n) - 64)) /* n=64-95: Interrupt pending */
/* Interrupt FIQ Pending 0-2 Status */
#define INTC_FIQ_PEND(n) (1 << (n)) /* n=0-31: Interrupt pending */
# define INTC_FIQ_PEND0(n) (1 << (n)) /* n=0-31: Interrupt pending */
# define INTC_FIQ_PEND1(n) (1 << ((n) - 32)) /* n=32-63: Interrupt pending */
# define INTC_FIQ_PEND2(n) (1 << ((n) - 64)) /* n=64-95: Interrupt pending */
/* Interrupt Select 0-2 */
#define INTC_IRQ_SEL(n) (1 << (n)) /* n=0-31: FIQ (vs IRQ) */
# define INTC_IRQ_SEL0(n) (1 << (n)) /* n=0-31: FIQ (vs IRQ) */
# define INTC_IRQ_SEL1(n) (1 << ((n) - 32)) /* n=32-63: FIQ (vs IRQ) */
# define INTC_IRQ_SEL2(n) (1 << ((n) - 64)) /* n=64-95: FIQ (vs IRQ) */
/* Interrupt Enable 0-2 */
#define INTC_EN(n) (1 << (n)) /* n=0-31: Interrupt enable */
# define INTC_EN0(n) (1 << (n)) /* n=0-31: Interrupt enable */
# define INTC_EN1(n) (1 << ((n) - 32)) /* n=32-63: Interrupt enable */
# define INTC_EN2(n) (1 << ((n) - 64)) /* n=64-95: Interrupt enable */
/* Interrupt Mask 0-2 */
#define INTC_MASK(n) (1 << (n)) /* n=0-31: Interrupt mask */
# define INTC_MASK0(n) (1 << (n)) /* n=0-31: Interrupt mask */
# define INTC_MASK1(n) (1 << ((n) - 32)) /* n=32-63: Interrupt mask */
# define INTC_MASK2(n) (1 << ((n) - 64)) /* n=64-95: Interrupt mask */
/* Interrupt Response 0-2 */
#define INTC_RESP(n) (1 << (n)) /* n=0-31: Interrupt level mask */
# define INTC_RESP0(n) (1 << (n)) /* n=0-31: Interrupt level mask */
# define INTC_RESP1(n) (1 << ((n) - 32)) /* n=32-63: Interrupt level mask */
# define INTC_RESP2(n) (1 << ((n) - 64)) /* n=64-95: Interrupt level mask */
/* Interrupt Fast Forcing 0-2 */
#define INTC_FF(n) (1 << (n)) /* n=0-31: Enable fast forcing feature */
# define INTC_FF0(n) (1 << (n)) /* n=0-31: Enable fast forcing feature */
# define INTC_FF1(n) (1 << ((n) - 32)) /* n=32-63: Enable fast forcing feature */
# define INTC_FF2(n) (1 << ((n) - 64)) /* n=64-95: Enable fast forcing feature */
/* Interrupt Source Priority 0-4 */
#define INTC_PRIO_SHIFT(n) ((n) << 1) /* n=0-15: Priority level */
#define INTC_PRIO_MASK(n) (3 << INTC_PRIO_SHIFT(n))
# define INTC_PRIO(n,p) ((uint32_t)(p) << INTC_PRIO_SHIFT(n))
#define INTC_PRIO0_SHIFT(n) ((n) << 1) /* n=0-15: Priority level */
#define INTC_PRIO0_MASK(n) (3 << INTC_PRIO0_SHIFT(n))
# define INTC_PRIO0(n,p) ((uint32_t)(p) << INTC_PRIO0_SHIFT(n))
#define INTC_PRIO1_SHIFT(n) (((n) - 16) << 1) /* n=16-31: Priority level */
#define INTC_PRIO1_MASK(n) (3 << INTC_PRIO1_SHIFT(n))
# define INTC_PRIO1(n,p) ((uint32_t)(p) << INTC_PRIO1_SHIFT(n))
#define INTC_PRIO2_SHIFT(n) (((n) - 32) << 1) /* n=32-47: Priority level */
#define INTC_PRIO2_MASK(n) (3 << INTC_PRIO2_SHIFT(n))
# define INTC_PRIO2(n,p) ((uint32_t)(p) << INTC_PRIO2_SHIFT(n))
#define INTC_PRIO3_SHIFT(n) (((n) - 48) << 1) /* n=48-63: Priority level */
#define INTC_PRIO3_MASK(n) (3 << INTC_PRIO3_SHIFT(n))
# define INTC_PRIO3(n,p) ((uint32_t)(p) << INTC_PRIO3_SHIFT(n))
#define INTC_PRIO4_SHIFT(n) (((n) - 64) << 1) /* n=64-79: Priority level */
#define INTC_PRIO4_MASK(n) (3 << INTC_PRIO4_SHIFT(n))
# define INTC_PRIO4(n,p) ((uint32_t)(p) << INTC_PRIO4_SHIFT(n))
#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H */