📄 cpu.h
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * cpu.h (memory) * * S1C38000 (ARM7)-dependent definitions */#ifndef _PM_CPU_H_#define _PM_CPU_H_#define RESIDENT_ONLY 1 /* Handle all as resident. *//* * Page directory entry * s p * 0 0 Page is absent * 0 1 Page table definition * 1 0 Section definition * 1 1 (Invalid) * * Handle entries in sets of four. * Therefore, handle page tables on a 4KB basis. */typedef union PageDirectryEntry { struct pde { /* Page table definition */ UW p:1; /* Page is valid. */ UW s:1; /* Section is valid. */ UW rsv1:3; /* Reserved (always 100) */ UW domain:4; /* Domain */ UW rsv2:1; /* Reserved (always 0) */ UW pfal:2; /* Page table low-level address */ UW pfa:20; /* Page table address */ } c[4]; struct sce { /* Section definition */ UW p:1; /* Page is valid. */ UW s:1; /* Section is valid. */ UW b:1; /* Write buffer enabled */ UW c:1; /* Cacheable */ UW rsv1:1; /* Reserved (always 1) */ UW domain:4; /* Domain */ UW rsv2:1; /* Reserved (always 0) */ UW w:1; /* Writable */ UW u:1; /* User accessible */ UW rsv3:8; /* Reserved (always 0) */ UW sba:12; /* Section base address */ } s[4]; UW w[4];} PDE;#define MAX_SECTION 0x1000 /* Number of sections */#define SECTION_SIZE 0x100000 /* Section size (1MB) */#define SECTION_NO(laddr) ( (UW)(laddr) >> 20U )#define SECTION_OFS(laddr) ( (UW)(laddr) & 0xfffffU )/* * Page table entry * * Combine present and valid to indicate the following states: * p = 0 va = 0 Page is absent * p = 0 va = 1 Page is suspended (see below) * p = 1 va = X Page is present * * The states of pfa are as follows according to the situation: * * When page is present (p = 1) * pfa = physical page address * * When page is absent (p = 0) * * va = 1: * pfa = physical page address * * va = 0 : * pfa = 0 Invalid PTE * pfa = 1 - PB_BASE-1 Disk map (map ID) * pfa = PB_BASE - 0xfffff Page file (block number) * * pb = pfa - PB_BASE * pb = 0 Page file not allocated * pb > 0 Page file block number * * (*)The mark is used by OS when pages are absent; cannot be used when pages are present. */typedef union PageTablEntry { struct pte { UW rsv1:1; /* (Fixed at 0) */ UW p:1; /* Page is valid. */ UW b:1; /* Write buffer enabled */ UW c:1; /* Cacheable */ UW w:1; /* Writable */ UW u:1; /* User accessible */ UW rsv2:4; /* (*) (Not used) */ UW clr:1; /* (*) Cleared at the time of page-in */ UW va:1; /* (*) pfa is valid */ UW pfa:20; /* Physical page address */ } c; struct ape { UW rsv1:1; /* (Fixed at 0) */ UW p:1; /* Page is valid. */ UW b:1; /* Write buffer enabled */ UW c:1; /* Cacheable */ UW ap0:2; /* Access right 0 */ UW ap1:2; /* Access right 1 */ UW ap2:2; /* Access right 2 */ UW ap3:2; /* Access right 3 */ UW pfa:20; /* Physical page address */ } a; UW w;} PTE;#define PB_BASE ( 0x00080000U )#define MAX_PFA ( 0x00100000U )/* PTE bits */#define PT_Present 0x00000002U#define PT_Bufferable 0x00000004U#define PT_Cachable 0x00000008U#define PT_Writable 0x00000010U#define PT_User 0x00000020U#define PT_Clear 0x00000400U#define PT_Valid 0x00000800U#define PT_Address 0xfffff000U#define PT_Accessed 0 /* No corresponding bit */#define PT_Update 0 /* No corresponding bit */#define PT_CopyOnWrite 0 /* Unable to support: Not supported */#define PT_PB_BASE (PB_BASE << 12U)#define isPresentP(pte) ( ((UW)(pte) & PT_Present) != 0U )#define isValidP(pte) ( isPresentP(pte) || (((UW)(pte) & PT_Valid) != 0U) )#define isClearP(pte) ( (!isPresentP(pte)) && (((UW)(pte) & PT_Clear) != 0U) )#define isWritableP(pte) ( ((UW)(pte) & PT_Writable) != 0U )#define isAccessedP(pte) 0 /* Unable to support: Always no access */#define isUpdateP(pte) 0 /* Unable to support: Always no update */#define isCopyOnWriteP(pte) 0 /* Unable to support: Not supported */#define CopyOnWriteP_done(pte) 0 /* Unable to support: Not supported *//* * Set page directory entry */Inline void SetPDE( PDE *pde, UW ent ){ pde->w[0] = ent; pde->w[1] = ent + 0x400; pde->w[2] = ent + 0x800; pde->w[3] = ent + 0xc00;}/* * Set mode of access to page table */Inline void SetPTE_AP( PTE *pte, UW ap ){ pte->a.ap1 = ap; pte->a.ap2 = ap; pte->a.ap3 = ap;}/* * Convert page table entry format for internal processing. */Inline PTE CnvGetPTE( PTE pte ){ if ( pte.c.p != 0 ) { pte.c.va = 1; pte.c.clr = 0; pte.c.rsv2 = 0; } return pte;}/* * Convert page table entry format for page table setting. */Inline PTE CnvSetPTE( PTE pte ){ if ( pte.c.p != 0 ) { SetPTE_AP(&pte, pte.a.ap0); } return pte;}/* * Number of PTEs per page table */#define N_PTE ( PAGESIZE / sizeof(PTE) )/* * Page directory setting value * PDE_NONE Invalid page directory entry * PDE_NORM Valid page directory entry */#define PDE_NONE ( 0 )#define PDE_NORM ( 0x011 )/* * Page table setting value * PTE_NONE Invalid page directory entry * * System memory initial entry * PTE_SMEM_RO Not writable * PTE_SMEM_NC Not cleared * PTE_SMEM_CL Cleared * PTE_SMEM_CW Copy-on-write (for change by disk map) * User memory initial entry * PTE_UMEM_RO Not writable * PTE_UMEM_NC Not cleared * PTE_UMEM_CL Cleared * PTE_UMEM_CW Copy-on-write (for change by disk map) * * PTE_DISKIO Disk I/O entry */#define PTE_NONE ( 0 )#define PTE_SMEM_RO ( PT_PB_BASE|PT_Cachable|PT_Bufferable )#define PTE_SMEM_NC ( PTE_SMEM_RO|PT_Writable )#define PTE_SMEM_CL ( PTE_SMEM_NC|PT_Clear )#define PTE_SMEM_CW ( PT_CopyOnWrite ) /* Not supported */#define PTE_UMEM_RO ( PT_PB_BASE|PT_Cachable|PT_Bufferable|PT_User )#define PTE_UMEM_NC ( PTE_UMEM_RO|PT_Writable )#define PTE_UMEM_CL ( PTE_UMEM_NC|PT_Clear )#define PTE_UMEM_CW ( PT_CopyOnWrite|PT_User ) /* Not supported */#define PTE_DISKIO ( PT_Present|PT_Writable|PT_Cachable|PT_Bufferable )/* * Set cache off */Inline UW PTE_CacheOff( UW pte ){ return pte & ~PT_Cachable;}/* * PTE setting value for disk map * ARM720T caching is performed with logical address. If multiple mapping (use several * different logical addresses to map the same physical address) is performed, cache * coherence is not maintained. * Therefore, turn off the cache if pages are writable. */Inline PTE PTE_DiskMap( ID mid, UW level ){ PTE pte; pte.w = (level & 3U) << 4U; pte.w |= ( pte.c.w == 0U )? PT_Cachable|PT_Bufferable: PT_Bufferable; pte.c.pfa = mid; return pte;}/* * PTE setting value for memory disk map */Inline PTE PTE_MemDiskMap( UW level ){ PTE pte; pte.w = (level & 3U) << 4U; pte.w |= ( pte.c.w == 0U )? PT_Present|PT_Bufferable|PT_Cachable: PT_Present|PT_Bufferable; return CnvSetPTE(pte);}/* * Logical address mask * Handle page tables in sets of four. * Therefore, handle page tables on a 4KB basis. */#define PDIR_MASK 0xffc00000U /* Page directory */#define PTBL_MASK 0x003ff000U /* Page table */#define POFS_MASK 0x00000fffU /* Page offset */#define PDIR_NUM(laddr) ( (UW)(laddr) >> 22U )#define PTBL_NUM(laddr) ( ((UW)(laddr) & PTBL_MASK) >> 12U )#define POFS_NUM(laddr) ( (UW)(laddr) & POFS_MASK )/* * Page frame address */#define PFAtoLADR(pfa) ( toLogicalAddress((UW)(pfa) << 12U) )#define LADRtoPFA(laddr) ( (UW)toPhysicalAddress(laddr) >> 12U )#define PFAtoPADR(pfa) ( (VP)((UW)(pfa) << 12U) )#define PADRtoPFA(paddr) ( (UW)(paddr) >> 12U )/* ------------------------------------------------------------------------ */IMPORT PDE *SATB; /* Shared space page directory *//* * Unique space: TRUE */Inline BOOL isLocalSpace( VP laddr ){ return ( ((UW)laddr >= LOCALSPACE_TOP) && ((UW)laddr < LOCALSPACE_END) );}/* * Area for loading system program: TRUE */Inline BOOL isSysLoadSpace( VP laddr ){ return ( ((UW)laddr >= SYSPRGSPACE_TOP) && ((UW)laddr < SYSPRGSPACE_END) );}/* * Page table access handle */typedef struct PageTableHandle { BOOL curspc; /* Performed in the current logical space: TRUE */ VP uatb; /* Intended logical space UATB */ VP laddr; /* Current logical address */ PDE *pde; /* Current page directory */ PTE *pte; /* Start of current page table */ W i; /* Index in current page table */} PTH;/* ------------------------------------------------------------------------ *//* * TLB-related *//* * Purge the whole TLB */Inline void PurgeAllTLB( void ){ Asm("mcr p15, 0, %0, cr8, c7, 0":: "r"(0));}/* * Write back page tables to the main memory. */Inline void WriteBackPageTable( VP ptbl ){}/* * Purge TLB that contains specified logical address. * For pte, specify the position of page table corresponding to TLB to be purged. * Write back page tables to the main memory. */Inline void PurgePageTLB( VP laddr, PTE *pte ){ Asm("mcr p15, 0, %0, cr8, c7, 1":: "r"(laddr));}/* ------------------------------------------------------------------------ *//* * Cache-related (ARM720T) * Write-through system where instruction and data caches are combined *//* * Flush the entire memory cache. * Since this cache is based on logical addresses, it is necessary to flush the cache * each time there is a change in mapping between logical and physical addresses. * (Cache coherence on the hardware is not guaranteed.) */Inline void ExtFlushCacheWT( void ){ Asm("mcr p15, 0, %0, cr7, c7, 0":: "r"(0));}#define ExtFlushCacheWB(laddr, lsid) /* NOP *//* * Common cache control functions for segment management are shown below: *//* * Cancel cache (one page) * void InvalidateCachePage( VP laddr, UW lsid ) * * Cancel cache content of one page that includes a logical * address laddr in lsid logical space. * Cancel the entire cache content because it cannot be canceled on a page basis. */#undef InvalidateCachePage#define InvalidateCachePage(laddr, lsid) ExtFlushCacheWT()/* ------------------------------------------------------------------------ */#include <sys/sysinfo.h>/* * Set low-level handler */Inline void define_inthdr( INT vecno, FP inthdr ){ SCArea->intvec[vecno] = inthdr;}/* * Structure of stack at exception handler entry */typedef struct { UW spsr; UW ip; UW lr;} ExcStack;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -