73 lines
1.7 KiB
C
73 lines
1.7 KiB
C
#include <stdint.h>
|
|
#include <kernel/bits/mpu.h>
|
|
|
|
// Internal symbols
|
|
mpu_t current_mpu = MPU_UNKNOWN;
|
|
|
|
/* check_sh3 - Detecting sh3-based MPU */
|
|
static mpu_t check_sh3(uint16_t tplcr)
|
|
{
|
|
if (tplcr == 0x0fff)
|
|
return (MPU_SH7337);
|
|
if (tplcr == 0x00ff)
|
|
return (MPU_SH7355);
|
|
return (MPU_UNKNOWN);
|
|
}
|
|
|
|
/* check_sh3 - Detecting sh4-based MPU */
|
|
static mpu_t check_sh4(void)
|
|
{
|
|
volatile uint32_t *pvr = (void *)0xff000030;
|
|
volatile uint32_t *prr = (void *)0xff000044;
|
|
uint32_t product;
|
|
|
|
if ((*pvr & 0xffffff00) != 0x10300b00)
|
|
return (MPU_UNKNOWN);
|
|
product = *prr & 0xfffffff0;
|
|
if (product == 0x00002c00)
|
|
return (MPU_SH7305);
|
|
if (product == 0x00002200)
|
|
return (MPU_SH7724);
|
|
return (MPU_UNKNOWN);
|
|
}
|
|
|
|
//
|
|
// get_mpu()
|
|
//
|
|
// Return the MPU identifier of the calculator.
|
|
// Thanks to SimonLothar and Lephenixnoir for this function
|
|
// and related information.
|
|
//
|
|
// Processor version register (PVR) and product control register (PRR)
|
|
// hold information about the MPU version, they but are only accessible on
|
|
// SH-4-based MPUs.
|
|
// To detect SH-3-based MPUs, this function uses port L control register
|
|
// (PLCR), whose bits 8 to 15 cannot be set with SH7337 where bits 8 to 11
|
|
// can be set with SH7355.
|
|
//
|
|
// Additionally, the CPU core ID register (CPIDR) at 0xff000048 returns 1
|
|
// on SH7305.
|
|
//
|
|
mpu_t mpu_get(void)
|
|
{
|
|
volatile uint16_t *plcr = (void *)0xa4000114;
|
|
uint16_t splcr;
|
|
uint16_t tplcr;
|
|
|
|
// Check if the MPU is already find
|
|
if (current_mpu != MPU_UNKNOWN)
|
|
return (current_mpu);
|
|
|
|
// Check port L control register.
|
|
splcr = *plcr;
|
|
*plcr = 0xffff;
|
|
tplcr = *plcr;
|
|
*plcr = splcr;
|
|
|
|
// Check MPU arch
|
|
current_mpu = check_sh3(tplcr);
|
|
if (current_mpu == MPU_UNKNOWN)
|
|
current_mpu = check_sh4();
|
|
return (current_mpu);
|
|
}
|