📄 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) * * SH7727-dependent definitions */#ifndef _PM_CPU_H_#define _PM_CPU_H_#include <tk/sysdef.h>#include "cpu_asm.h"/* * Page directory entry */typedef union PageDirectryEntry { struct pde { UW rsv1:8; /* Not used (always 0) */ UW p:1; /* present */ UW rsv2:3; /* Not used (always 0) */ UW pfa:20; /* page frame address */ } c; UW w;} PDE;/* * 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 = 0 Page is present and locked * p = 1 va = 1 Page is present * * Combine copy-on-write and writable to indicate the following states: * cow = 1 w = 0 Before copy-on-write processing * cow = 1 w = 1 After copy-on-write processing * * 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 * * Page size is fixed at 4KB * * (*)The mark is not used in the same manner as in hardware-related definitions. * When written into TLB, they are changed according to hardware-related * definitions. */typedef union PageTablEntry { struct pte { UW wt:1; /* Write-through (SH4) */ UW a:1; /* (*) Accessed */ UW d:1; /* Dirty */ UW c:1; /* Cacheable */ UW rsv1:1; /* (*) Not used (always 0) */ UW w:1; /* Writable */ UW u:1; /* User accessible */ UW rsv2:1; /* (*) Not used (always 0) */ UW p:1; /* Page is valid. */ UW clr:1; /* (*) Cleared at the time of page-in */ UW cow:1; /* (*) Copy-on-write */ UW va:1; /* (*) pfa is valid */ UW pfa:20; /* Physical page number */ } c; struct tlb { /* TLB bit structure in hardware */ UW wt:1; /* Write-through (SH4) */ UW sh:1; /* (*) Shared state */ UW d:1; /* Dirty */ UW c:1; /* Cacheable */ UW sz:1; /* (*) Page size */ UW w:1; /* Writable */ UW u:1; /* User accessible */ UW sz1:1; /* (*) Page size (SH4) */ UW p:1; /* Page is valid. */ UW rsv:1; /* (*) Reserved */ UW ppn11_10:2; /* (*) Physical page number */ UW ppn31_12:20; /* Physical page number */ } h; UW w;} PTE;#define PB_BASE ( 0x00080000U )#define MAX_PFA ( 0x00100000U )/* PDE,PTE bits */#define PT_WriteThrough 0x00000001 /* SH4 only */#define PT_Accessed 0x00000002 /* (*) */#define PT_Update 0x00000004#define PT_Cachable 0x00000008#define PT_Writable 0x00000020#define PT_User 0x00000040#define PT_Present 0x00000100#define PT_Clear 0x00000200 /* (*) */#define PT_CopyOnWrite 0x00000400 /* (*) */#define PT_Valid 0x00000800 /* (*) */#define PT_Address 0xfffff000#define PT_PB_BASE ((PB_BASE) << 12U)#define PT_TLBMASK 0xfffff16dU#define isPresentP(pte) ( ((UW)(pte) & (UW)PT_Present) != 0U )#define isValidP(pte) ( ((UW)(pte) & (UW)PT_Valid) != 0U )#define isClearP(pte) ( ((UW)(pte) & (UW)PT_Clear) != 0U )#define isAccessedP(pte) ( ((UW)(pte) & (UW)PT_Accessed) != 0U )#define isUpdateP(pte) ( ((UW)(pte) & (UW)PT_Update) != 0U )#define isCopyOnWriteP(pte) ( ((UW)(pte) & (UW)PT_CopyOnWrite) != 0U )#define isWritableP(pte) ( ((UW)(pte) & (UW)PT_Writable) != 0U )#define isLockedP(pte) ( ((UW)(pte) & (UW)PT_Present|(UW)PT_Valid)) \ == ((UW)PT_Present) )#define CopyOnWriteP_done(pte) ( ((UW)(pte) & ((UW)PT_CopyOnWrite|(UW)PT_Writable)) \ == ((UW)PT_CopyOnWrite|(UW)PT_Writable) )/* * 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 ( PT_Present )/* * Page table setting value * PTE_NONE Invalid page table 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 )#define PTE_SMEM_NC ( PTE_SMEM_RO|PT_Writable )#define PTE_SMEM_CL ( PTE_SMEM_NC|PT_Clear )#define PTE_SMEM_CW ( PT_CopyOnWrite )#define PTE_UMEM_RO ( PT_PB_BASE|PT_Cachable|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 )#define PTE_DISKIO ( PT_Present|PT_Writable|PT_Cachable)/* * Set cache off */Inline UW PTE_CacheOff( UW pte ){ return pte & ~PT_Cachable;}/* * PTE setting value for disk map * SH4: 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. * SH3: When the page size is 4KB, there is no problem related to coherence. */Inline PTE PTE_DiskMap( ID mid, UW level ){ PTE pte; pte.w = ((level & 3U) << 5U) | PT_Cachable; 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) << 5U) | (PT_Present|PT_Cachable); return pte;}/* * Logical address mask */#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 */IMPORT PDE *UATB; /* Unique space page directory */IMPORT UW MaxLSID; /* Maximum number of unique spaces *//* * TLB */#define TLB_VPN(addr, lsid) ( (UW)(addr) & 0x0001f000 )#define TLB_ADR(vpn, way) ( *(_UW*)(TLB_ADR_TOP | (vpn) | TLB_WAY(way)) )#define TLB_DAT(vpn, way) ( *(_UW*)(TLB_DAT_TOP | (vpn) | TLB_WAY(way)) )/* * Exception block (SR.BL=1) * It is necessary to prevent access to virtual memory while exception block exist. * Note that a stack is virtual memory. * Specify registers in such a way that _save_sr_ does not become a stack. */#define DISEXC(reg) \ { register UW _save_sr_ asm(reg); \ Asm(" stc sr, r0 \n" \ " or %1, r0 \n" \ " stc sr, %0 \n" \ " ldc r0, sr " \ : "=r"(_save_sr_) \ : "r"(SR_BL) \ : "r0");#define ENAEXC Asm(" ldc %0, sr" :: "r"(_save_sr_)); \ }/* * Unique space: TRUE */Inline BOOL isLocalSpace( VP laddr ){ return ( (UW)laddr < (NUM_PDIR_ENTRIES * N_PTE * PAGESIZE) );}/* * Area for loading system program: TRUE */Inline BOOL isSysLoadSpace( VP laddr ){ return ( (laddr >= (VP)SYSPRGSPACE_TOP) && (laddr < (VP)SYSPRGSPACE_END) );}/* * Page table access handle */typedef struct PageTableHandle { UW lsid; /* Intended logical space ID */ 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 */IMPORT void PurgeAllTLB( void );/* * Purge TLB that contains specified logical address. */IMPORT void PurgePageTLB( VP laddr, UW lsid );/* * Update TLB * SH3: If there is an entry whose logical address matches the current TLB, update TLB; * if not, do not update TLB. * SH4: Always register in TLB. */IMPORT void UpdateTLB( VP laddr, UW lsid, UW pte );/* * Load into TLB */IMPORT void _LoadTLB( VP laddr, UW lsid, UW pte, UW mmucr );/* ------------------------------------------------------------------------ *//* * Cache-related (SH3) *//* * Flush memory cache (both instruction/data caches) * Flush (write back) a page (4KB) that contains laddr and cancel it. * Do not specify an invalid page (PTE.p=0). */IMPORT void _ExtFlushCache( VP laddr, UW lsid );#define ExtFlushCache(laddr, lsid, pte) _ExtFlushCache(laddr, lsid)/* ------------------------------------------------------------------------ */#include <sys/sysinfo.h>/* * TLB-related exception codes */#define EXC_TLBINV_R 0x040 /* TLB invalid (read) */#define EXC_TLBINV_W 0x060 /* TLB invalid (write) */#define EXC_TLBINV_REP 0x070 /* TLB invalid (repeat loop) [unrestorable] */#define EXC_FIRSTWRITE 0x080 /* First writing to page */#define EXC_TLBPRO_R 0x0a0 /* TLB protection (read) */#define EXC_TLBPRO_W 0x0c0 /* TLB protection (write) */#define EXC_TLBPRO_REP 0x0d0 /* TLB protection (repeat loop) [unrestorable] *//* * Set low-level handler */Inline void define_inthdr( UW code, FP inthdr ){ SCArea->intvec[code >> 5] = inthdr;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -