Alternative library and kernel for add-in development on fx-9860G and fx-CG50 under Linux.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
gint/src/core/hardware.c

115 lines
2.8 KiB

//---
// gint:core:hardware - Platform information and hardware detection
//---
#include <gint/hardware.h>
#include <gint/defs/attributes.h>
#include <gint/defs/types.h>
#include <gint/defs/util.h>
#include <gint/mpu/pfc.h>
/* 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 */