📄 ep93xx_misc.c
字号:
//==========================================================================//// ep93xx_misc.c//// HAL misc board support code for ARM9/EP93XX////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Red Hat eCos Public License// Version 1.1 (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.redhat.com///// Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License. //// The Original Code is eCos - Embedded Configurable Operating System,// released September 30, 1998.//// The Initial Developer of the Original Code is Red Hat.// Portions created by Red Hat are// Copyright (C) 1998, 1999, 2000, 2001 Red Hat, Inc.// All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): gthomas// Contributors: hmt, Travis C. Furrer <furrer@mit.edu>, jskov// Date: 2001-04-23// Purpose: HAL board support// Description: Implementations of HAL board interfaces////####DESCRIPTIONEND####////========================================================================*/#include <pkgconf/hal.h>#include <pkgconf/system.h>#include CYGBLD_HAL_PLATFORM_H#include <cyg/infra/cyg_type.h> // base types#include <cyg/infra/cyg_trac.h> // tracing macros#include <cyg/infra/cyg_ass.h> // assertion macros#include <cyg/hal/hal_io.h> // IO macros#include <cyg/hal/hal_arch.h> // Register state info#include <cyg/hal/hal_diag.h>#include <cyg/hal/hal_intr.h> // Interrupt names#include <cyg/hal/hal_cache.h>#include <cyg/hal/ep93xx.h> // Platform specifics#include <cyg/hal/regs_VIC.h>#include <cyg/infra/diag.h> // diag_printf// -------------------------------------------------------------------------// MMU initialization:// // These structures are laid down in memory to define the translation// table.// /* * SA-1100 Translation Table Base Bit Masks */#define ARM_TRANSLATION_TABLE_MASK 0xFFFFC000/* * SA-1100 Domain Access Control Bit Masks */#define ARM_ACCESS_TYPE_NO_ACCESS(domain_num) (0x0 << (domain_num)*2)#define ARM_ACCESS_TYPE_CLIENT(domain_num) (0x1 << (domain_num)*2)#define ARM_ACCESS_TYPE_MANAGER(domain_num) (0x3 << (domain_num)*2)struct ARM_MMU_FIRST_LEVEL_FAULT { int id : 2; int sbz : 30;};#define ARM_MMU_FIRST_LEVEL_FAULT_ID 0x0struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE { int id : 2; int imp : 2; int domain : 4; int sbz : 1; int base_address : 23;};#define ARM_MMU_FIRST_LEVEL_PAGE_TABLE_ID 0x1struct ARM_MMU_FIRST_LEVEL_SECTION { int id : 2; int b : 1; int c : 1; int imp : 1; int domain : 4; int sbz0 : 1; int ap : 2; int sbz1 : 8; int base_address : 12;};#define ARM_MMU_FIRST_LEVEL_SECTION_ID 0x2struct ARM_MMU_FIRST_LEVEL_RESERVED { int id : 2; int sbz : 30;};#define ARM_MMU_FIRST_LEVEL_RESERVED_ID 0x3#define ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, table_index) \ (unsigned long *)((unsigned long)(ttb_base) + ((table_index) << 2))#define ARM_FIRST_LEVEL_PAGE_TABLE_SIZE 0x4000#define ARM_MMU_SECTION(ttb_base, actual_base, virtual_base, \ cacheable, bufferable, perm) \ CYG_MACRO_START \ register union ARM_MMU_FIRST_LEVEL_DESCRIPTOR desc; \ \ desc.word = 0; \ desc.section.id = ARM_MMU_FIRST_LEVEL_SECTION_ID; \ desc.section.imp = 1; \ desc.section.domain = 0; \ desc.section.c = (cacheable); \ desc.section.b = (bufferable); \ desc.section.ap = (perm); \ desc.section.base_address = (actual_base); \ *ARM_MMU_FIRST_LEVEL_DESCRIPTOR_ADDRESS(ttb_base, (virtual_base)) \ = desc.word; \ CYG_MACRO_END#define X_ARM_MMU_SECTION(abase,vbase,size,cache,buff,access) \ { int i; int j = abase; int k = vbase; \ for (i = size; i > 0 ; i--,j++,k++) \ { \ ARM_MMU_SECTION(ttb_base, j, k, cache, buff, access); \ } \ }union ARM_MMU_FIRST_LEVEL_DESCRIPTOR { unsigned long word; struct ARM_MMU_FIRST_LEVEL_FAULT fault; struct ARM_MMU_FIRST_LEVEL_PAGE_TABLE page_table; struct ARM_MMU_FIRST_LEVEL_SECTION section; struct ARM_MMU_FIRST_LEVEL_RESERVED reserved;};#define ARM_UNCACHEABLE 0#define ARM_CACHEABLE 1#define ARM_UNBUFFERABLE 0#define ARM_BUFFERABLE 1#define ARM_ACCESS_PERM_NONE_NONE 0#define ARM_ACCESS_PERM_RO_NONE 0#define ARM_ACCESS_PERM_RO_RO 0#define ARM_ACCESS_PERM_RW_NONE 1#define ARM_ACCESS_PERM_RW_RO 2#define ARM_ACCESS_PERM_RW_RW 3extern int memset( void *, int, size_t );voidhal_mmu_init(void){ unsigned long ttb_base = EP9312_SDRAM_PHYS_BASE + 0x4000; unsigned long i; /* * Set the TTB register */ asm volatile ("mcr p15,0,%0,c2,c0,0" : : "r"(ttb_base) /*:*/); /* * Set the Domain Access Control Register */ i = ARM_ACCESS_TYPE_MANAGER(0) | ARM_ACCESS_TYPE_NO_ACCESS(1) | ARM_ACCESS_TYPE_NO_ACCESS(2) | ARM_ACCESS_TYPE_NO_ACCESS(3) | ARM_ACCESS_TYPE_NO_ACCESS(4) | ARM_ACCESS_TYPE_NO_ACCESS(5) | ARM_ACCESS_TYPE_NO_ACCESS(6) | ARM_ACCESS_TYPE_NO_ACCESS(7) | ARM_ACCESS_TYPE_NO_ACCESS(8) | ARM_ACCESS_TYPE_NO_ACCESS(9) | ARM_ACCESS_TYPE_NO_ACCESS(10) | ARM_ACCESS_TYPE_NO_ACCESS(11) | ARM_ACCESS_TYPE_NO_ACCESS(12) | ARM_ACCESS_TYPE_NO_ACCESS(13) | ARM_ACCESS_TYPE_NO_ACCESS(14) | ARM_ACCESS_TYPE_NO_ACCESS(15); asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/); /* * First clear all Page Table entries - ie Set them to Faulting */ memset((void *)ttb_base, 0, ARM_FIRST_LEVEL_PAGE_TABLE_SIZE);#ifdef HAL_PLATFORM_EP9301 // EDB9301 Memory Map // Actual Virtual Size Attributes // Base Base MB cached? buffered? access permissions // xxx00000 xxx00000 // // SDRAM is physically located in 8MB blocks at 0x00000000, 0x01000000, 0x04000000, 0x05000000 // X_ARM_MMU_SECTION(0x000, 0x000, 8, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x010, 0x008, 8, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x040, 0x010, 8, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x050, 0x018, 8, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); // // There is a 16MB Intel Flash on this board at 0x60000000 // X_ARM_MMU_SECTION(0x600, 0x600, 16, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RO_RO); // // The EP9301 registers are located at 0x80000000 in a 256MB block // X_ARM_MMU_SECTION(0x800, 0x800, 256,ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // // This is an uncached/unbuffered mapping of the SDRAM // X_ARM_MMU_SECTION(0x000, 0xC00, 8, ARM_UNCACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x010, 0xC08, 8, ARM_UNCACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x040, 0xC10, 8, ARM_UNCACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x050, 0xC18, 8, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // // This is an uncached/unbuffered mapping of the FLASH // X_ARM_MMU_SECTION(0x600, 0xE00, 16, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW);#else // EDB9312 Memory Map // Actual Virtual Size Attributes // Base Base MB cached? buffered? access permissions // xxx00000 xxx00000 // // SDRAM is physically located in 8MB blocks at 0x00000000, 0x01000000, 0x04000000, 0x05000000 // X_ARM_MMU_SECTION(0x000, 0x000, 32, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x040, 0x020, 32, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); // // There is a 32MB Intel Flash on this board at 0x60000000 // X_ARM_MMU_SECTION(0x600, 0x600, 32, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RO_RO); // // The EP9312 registers are located at 0x80000000 in a 256MB block // X_ARM_MMU_SECTION(0x800, 0x800, 256, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // // This is an uncached/unbuffered mapping of the SDRAM // X_ARM_MMU_SECTION(0x000, 0xC00, 32, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); X_ARM_MMU_SECTION(0x040, 0xC20, 32, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // // This is an uncached/unbuffered mapping of the FLASH // X_ARM_MMU_SECTION(0x600, 0xE00, 32, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW);#endif // HAL_PLATFORM_EP9301 // Enable MMU asm volatile ( "mcr p15,0,%0,c1,c0,0;" "nop;nop;nop;nop;nop;nop;nop;nop;" : : "r"(MMU_Control_Init|MMU_Control_M) /* : */ );}//=============================================================================// hal_virt_to_phys_address//=============================================================================// Returns a physical address given a virtual address.//#ifdef HAL_PLATFORM_EP9301cyg_uint32 hal_virt_to_phys_address(cyg_uint32 vaddr){ cyg_uint32 paddr; // // If the Virtual Address two physical mapping is as follows for EDB9301 // Virtual Physical // 0x00000000-0x007fffff 0x00000000-0x007fffff // 0x00800000-0x00ffffff 0x01000000-0x017fffff // 0x01000000-0x017fffff 0x04000000-0x047fffff // 0x01800000-0x01ffffff 0x05000000-0x057fffff // // 0xc0000000-0xc07fffff 0x00000000-0x007fffff // 0xc0800000-0xc0ffffff 0x01000000-0x017fffff // 0xc1000000-0xc17fffff 0x04000000-0x047fffff // 0xc1800000-0xc1ffffff 0x05000000-0x057fffff // // // If the memory is in SDRAM then it is mapped to the physical memory at // 0x00000000 in the strange way that memory is mapped. // if ((((0xC00u * SZ_1M) <= vaddr) && (vaddr <= (0xC20u * SZ_1M ))) || (((0x000u * SZ_1M) <= vaddr) && (vaddr <= (0x020u * SZ_1M )))) { vaddr &= 0x0fffffff; if (vaddr < 0x007fffff) { paddr = vaddr; } else if (vaddr < 0x00ffffff) { paddr = vaddr + (0x008u * SZ_1M); } else if (vaddr < 0x017fffff) { paddr = vaddr + (0x030u * SZ_1M); } else if (vaddr < 0x01ffffff) { paddr = vaddr + (0x038u * SZ_1M); } } else if (((0xe00u * SZ_1M) <= vaddr) && (vaddr <= (0xe20u * SZ_1M ))) { // // Physical address of the Flash is at 0x60000000 // paddr = vaddr - 0x80000000; } else { // // Otherwise virtual == physical // paddr = vaddr; } return(paddr);}cyg_uint32 hal_virt_to_uncached_address(cyg_uint32 vaddr){ if ( vaddr <= (0x020u * SZ_1M )) { vaddr += (0xC00u * SZ_1M); } else { vaddr = 0xBAD0ADD8u; /* nothing there; uncached unavailable */ } return (vaddr);}cyg_uint32 hal_phys_to_virt_address(cyg_uint32 paddr) { if ( ((0x010u * SZ_1M) <= paddr) && (paddr < (0x018u * SZ_1M ))) { return (paddr - ((0x010u - 0x008u)* SZ_1M )); } if ( ((0x040u * SZ_1M) <= paddr) && (paddr < (0x048u * SZ_1M ))) { return (paddr - ((0x040u - 0x010u)* SZ_1M )); } if ( ((0x050u * SZ_1M) <= paddr) && (paddr < (0x058u * SZ_1M ))) { return (paddr - ((0x050u - 0x018u)* SZ_1M )); } return (paddr);}#elsecyg_uint32 hal_virt_to_uncached_address(cyg_uint32 vaddr){ if ( vaddr <= (0x040 * SZ_1M )) { vaddr += (0xC00u * SZ_1M); } else { vaddr = 0xBAD0ADD8u; /* nothing there; uncached unavailable */ } return (vaddr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -