From 19951ccf620d3dd9426801dee2398210eebd8eff Mon Sep 17 00:00:00 2001 From: Lephe Date: Wed, 21 Oct 2020 14:44:02 +0200 Subject: [PATCH] mmu: add MMU registers with a driver context for PASCR and IRMCR --- include/gint/mpu/mmu.h | 75 +++++++++++++++++++++++++++++++++++++++ src/{kernel => mmu}/mmu.c | 54 +++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 1 deletion(-) rename src/{kernel => mmu}/mmu.c (78%) diff --git a/include/gint/mpu/mmu.h b/include/gint/mpu/mmu.h index 9b60333..1acc214 100644 --- a/include/gint/mpu/mmu.h +++ b/include/gint/mpu/mmu.h @@ -77,4 +77,79 @@ typedef struct } GPACKED(4) utlb_data_t; +typedef volatile struct +{ + lword_union(PTEH, + uint32_t VPN :22; /* Virtual Page Number */ + uint32_t :2; + uint32_t ASID :8; /* Address Space Identifier */ + ); + + lword_union(PTEL, + uint32_t :3; + uint32_t PPN :19; /* Phusical Page Number */ + uint32_t :1; + uint32_t V :1; /* Valid */ + uint32_t SZ1 :1; /* Size (bit 1) */ + uint32_t PR :2; /* Protection */ + uint32_t SZ0 :1; /* Size (bit 0) */ + uint32_t C :1; /* Cacheable */ + uint32_t D :1; /* Dirty */ + uint32_t SH :1; /* Shared */ + uint32_t WT :1; /* Write-through */ + ); + + uint32_t TTB; + uint32_t TEA; + + lword_union(MMUCR, + uint32_t LRUI :6; /* Least-Recently Used ITLB */ + uint32_t :2; + uint32_t URB :6; /* UTLB Replace Boundary */ + uint32_t :2; + uint32_t URC :6; /* UTLB Replace Counter */ + uint32_t SQMD :1; /* Store Queue Mode */ + uint32_t SV :1; /* Single Virtual Memory Mode */ + uint32_t ME :1; /* TLB Extended Mode */ + uint32_t :4; + uint32_t TI :1; /* TLB Invalidate */ + uint32_t :1; + uint32_t AT :1; /* Address Translation */ + ); + pad(0x20); + + lword_union(PTEA, + uint32_t :18; + uint32_t EPR :6; + uint32_t ESZ :4; + uint32_t :4; + ); + pad(0x38); + + lword_union(PASCR, + uint32_t :24; + uint32_t UBC :1; /* Control register area */ + uint32_t UB6 :1; /* Area 6 */ + uint32_t UB5 :1; /* Area 5 */ + uint32_t UB4 :1; /* Area 4 */ + uint32_t UB3 :1; /* Area 3 */ + uint32_t UB2 :1; /* Area 2 */ + uint32_t UB1 :1; /* Area 1 */ + uint32_t UB0 :1; /* Area 0 */ + ); + pad(4); + + lword_union(IRMCR, + uint32_t :27; + uint32_t R2 :1; /* Re-fetch after Register 2 change */ + uint32_t R1 :1; /* Re-fetch after Register 1 change */ + uint32_t LT :1; /* Re-fetch after LDTLB */ + uint32_t MT :1; /* Re-fetch after writing TLB */ + uint32_t MC :1; /* Re-fetch after writing insn cache */ + ); + +} GPACKED(4) sh7305_mmu_t; + +#define SH7305_MMU (*(sh7305_mmu_t *)0xff000000) + #endif /* GINT_MPU_MMU */ diff --git a/src/kernel/mmu.c b/src/mmu/mmu.c similarity index 78% rename from src/kernel/mmu.c rename to src/mmu/mmu.c index 1c25c27..e302003 100644 --- a/src/kernel/mmu.c +++ b/src/mmu/mmu.c @@ -1,8 +1,9 @@ //--- -// gint:core:mmu - MMU-related definitions +// gint:mmu:mmu - MMU driver definition and context management //--- #include +#include #include //--- @@ -148,3 +149,54 @@ uint32_t utlb_translate(uint32_t page) } return -1; } + +//--- +// Initialization +//--- + +static void init(void) +{ + /* Make writes to the control register area synchronous; this is needed + for the SPU to operate properly */ + if(isSH4()) SH7305_MMU.PASCR.UBC = 1; +} + +//--- +// Context management +//--- + +typedef struct { + uint32_t PASCR; + uint32_t IRMCR; +} ctx_t; + +GBSS static ctx_t sys_ctx, gint_ctx; + +static void ctx_save(void *buf) +{ + if(isSH3()) return; + + ctx_t *ctx = buf; + ctx->PASCR = SH7305_MMU.PASCR.lword; + ctx->IRMCR = SH7305_MMU.IRMCR.lword; +} + +static void ctx_restore(void *buf) +{ + if(isSH3()) return; + + ctx_t *ctx = buf; + SH7305_MMU.PASCR.lword = ctx->PASCR; + SH7305_MMU.IRMCR.lword = ctx->IRMCR; +} + +gint_driver_t drv_mmu = { + .name = "MMU", + .init = init, + .sys_ctx = &sys_ctx, + .gint_ctx = &gint_ctx, + .ctx_save = ctx_save, + .ctx_restore = ctx_restore, +}; + +GINT_DECLARE_DRIVER(1, drv_mmu);