//--- // gint:core:hardware - Platform information and hardware detection //--- #include #include #include #include #include /* Holds information about the current platform */ GBSS uint32_t gint[HW_KEYS]; /* Processor Version Register */ #define PVR (*((volatile uint32_t *)0xff000030)) /* Product Register */ #define PRR (*((volatile uint32_t *)0xff000044)) #if defined(FX9860G) || (!defined(FX9860G) && !defined(FXCG50)) /* mpu_detect() - detect the underlying MPU Many thanks to Simon Lothar for relevant documentation. Processor Version Register (PVR) and Product Version Register (PRR) provide info for SH-4-based MPUS; SH-3 based boards are detected and distinguished by testing writable bits in the Port L Control Register (PLCR). Returns the detected MPU type, falling back on mpu_unknown */ GSECTION(".pretext") static int mpu_detect(void) { #define PLCR SH7705_PFC.PLCR /* Detect SH-3-based MPUs by testing writable bits in PLCR */ uint16_t old = PLCR; PLCR = 0xffff; uint16_t tested = PLCR; PLCR = old; if(tested == 0x00ff) return HWMPU_SH7337; if(tested == 0x0fff) return HWMPU_SH7355; /* Check that we're dealing with an SH-4-based MPU */ if((PVR & 0xffffff00) != 0x10300b00) return HWMPU_UNKNOWN; /* Tell SH-4 MPUs by testing the product version register */ uint32_t ver = PRR & 0xfffffff0; if(ver == 0x00002c00) return HWMPU_SH7305; if(ver == 0x00002200) return HWMPU_SH7724; return HWMPU_UNKNOWN; #undef PLCR } /* hw_detect(): Basic hardware detection */ GSECTION(".pretext") void hw_detect(void) { gint[HWMPU] = mpu_detect(); if(isSH4()) { gint[HWCPUVR] = PVR; gint[HWCPUPR] = PRR; } /* Detect RAM by checking if 8804'0000 is the same as 8800'0000. */ volatile uint8_t *R4 = (void *)0x88040000; volatile uint8_t *R0 = (void *)0x88000000; /* Make backups */ uint8_t b0 = *R0; uint8_t b4 = *R4; /* Check if setting a different value in *R4 affects *R0. If not, then we have extended RAM. */ *R4 = ~b0; int ext = (*R0 == b0); /* Restore backups */ *R0 = b0; *R4 = b4; gint[HWRAM] = ext ? (512 << 10) : (256 << 10); /* Will be detected later on */ gint[HWURAM] = -1; /* Traditionally 4 MiB, Graph 35+E II has 8 MiB */ gint[HWROM] = (gint[HWCALC] == HWCALC_G35PE2) ? (4 << 20) : (8 << 20); } #endif /* FX9860G and platform-agnostic */ #ifdef FXCG50 /* hw_detect(): Basic hardware detection */ GSECTION(".pretext") void hw_detect(void) { gint[HWMPU] = HWMPU_SH7305; gint[HWCPUVR] = PVR; gint[HWCPUPR] = PRR; /* Tell Prizms apart from fx-CG 50 by checking the stack address*/ uint32_t stack; __asm__("mov r15, %0" : "=r"(stack)); gint[HWCALC] = (stack < 0x8c160000) ? HWCALC_PRIZM : HWCALC_FXCG50; /* Basic memory information */ gint[HWRAM] = (2 << 20); gint[HWROM] = (32 << 20); } #endif /* FXCG50 */