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.

91 lines
2.3KB

  1. //---
  2. // gint:core:mpu - Runtime MPU detection
  3. //---
  4. #include <gint/mpu.h>
  5. #include <gint/defs/attributes.h>
  6. #include <gint/defs/types.h>
  7. #include <gint/defs/util.h>
  8. /* Holds information about the current MPU */
  9. GBSS const platform_t gint_platform;
  10. /* This function is only used on fx9860g because all fxcg50 are SH4 */
  11. #ifdef FX9860G
  12. /* mpu_detect() - detect the underlying MPU
  13. Many thanks to Simon Lothar for relevant documentation.
  14. Processor Version Register (PVR) and Product Version Register (PRR) provide
  15. info for SH-4-based MPUS; SH-3 based boards are detected and distinguished
  16. by testing writable bits in the Port L Control Register (PLCR).
  17. Returns the detected MPU type, falling back on mpu_unknown */
  18. GSECTION(".pretext")
  19. static mpu_t mpu_detect(void)
  20. {
  21. /* Processor Version Register */
  22. volatile uint32_t *pvr = (void *)0xff000030;
  23. /* Product Version Register */
  24. volatile uint32_t *prr = (void *)0xff000044;
  25. /* Port L Control Register */
  26. volatile uint16_t *plcr = (void *)0xa4000114;
  27. /* Detecting SH-3-based MPUs by testing writable bits in PLCR */
  28. uint16_t old = *plcr;
  29. *plcr = 0xffff;
  30. uint16_t tested = *plcr;
  31. *plcr = old;
  32. if(tested == 0x00ff) return mpu_sh7337;
  33. if(tested == 0x0fff) return mpu_sh7355;
  34. /* Check that we're dealing with an SH-4-based MPU */
  35. if((*pvr & 0xffffff00) != 0x10300b00) return mpu_unknown;
  36. /* Tell SH-4 MPUs by testing the product version register */
  37. uint32_t ver = *prr & 0xfffffff0;
  38. if(ver == 0x00002c00) return mpu_sh7305;
  39. if(ver == 0x00002200) return mpu_sh7724;
  40. return mpu_unknown;
  41. }
  42. /* mpu_init() - detect and save information about the underlying MPU */
  43. GSECTION(".pretext")
  44. void mpu_init(GUNUSED uint32_t stack)
  45. {
  46. const_cast(gint_platform.mpu, mpu_t) = mpu_detect();
  47. /* Detect additional RAM */
  48. volatile uint8_t *after_ram = (void *)0x88040000;
  49. volatile uint8_t *start_ram = (void *)0x88000000;
  50. uint8_t backup = *after_ram;
  51. *after_ram = ~backup;
  52. int ext = (*start_ram == backup);
  53. *after_ram = backup;
  54. const_cint(gint_platform.extended_ram) = ext;
  55. }
  56. #endif /* FX9860G */
  57. #ifdef FXCG50
  58. /* mpu_init() - detect and save information about the underlying MPU */
  59. GSECTION(".pretext")
  60. void mpu_init(uint32_t stack)
  61. {
  62. const_cast(gint_platform.mpu, mpu_t) = mpu_sh7305;
  63. /* Detect Prizm models */
  64. int prizm = (stack < 0x8c160000);
  65. const_cint(gint_platform.prizm) = prizm;
  66. }
  67. #endif /* FXCG50 */