gint/include/gint/hardware.h
Lephe c9264a06d5
kernel: driver and world system overhaul
Changes in the driver and world system:

* Rewrite driver logic to include more advanced concepts. The notion of
  binding a driver to a device is introduced to formalize wait(); power
  management is now built-in instead of being handled by the drivers
  (for instance DMA). The new driver model is described in great detail
  in <gint/drivers.h>

* Formalized the concept of "world switch" where the hardware state is
  saved and later restored. As a tool, the world switch turns out to be
  very stable, and allows a lot of hardware manipulation that would be
  edgy at best when running in the OS world.

* Added a GINT_DRV_SHARED flag for drivers to specify that their state
  is shared between worlds and not saved/restored. This has a couple of
  uses.

* Exposed a lot more of the internal driver/world system as their is no
  particular downside to it. This includes stuff in <gint/drivers.h>
  and the driver's state structures in <gint/drivers/states.h>. This is
  useful for debugging and for cracked concepts, but there is no
  API stability guarantee.

* Added a more flexible driver level system that allows any 2-digit
  level to be used.

Feature changes:

* Added a CPU driver that provides the VBR change as its state save.
  Because the whole context switch relied on interrupts being disabled
  anyway, there is no longer an inversion of control when setting the
  VBR; this is just part of the CPU driver's configuration. The CPU
  driver may also support other features such as XYRAM block transfer
  in the future.

* Moved gint_inthandler() to the INTC driver under the name
  intc_handler(), pairing up again with intc_priority().

* Added a reentrant atomic lock based on the test-and-set primitive.
  Interrupts are disabled with IMASK=15 for the duration of atomic
  operations.

* Enabled the DMA driver on SH7305-based fx-9860G. The DMA provides
  little benefit on this platform because the RAM is generally faster
  and buffers are ultimately small. The DMA is still not available on
  SH3-based fx-9860G models.

* Solved an extremely obnoxious bug in timer_spin_wait() where the
  timer is not freed, causing the callback to be called when interrupts
  are re-enabled. This increments a random value on the stack. As a
  consequence of the change, removed the long delays in the USB driver
  since they are not actually needed.

Minor changes:

* Deprecated some of the elements in <gint/hardware.h>. There really is
  no good way to "enumerate" devices yet.

* Deprecated gint_switch() in favor of a new function
  gint_world_switch() which uses the GINT_CALL abstraction.

* Made the fx-9860G VRAM 32-aligned so that it can be used for tests
  with the DMA.

Some features of the driver and world systems have not been implemented
yet, but may be in the future:

* Some driver flags should be per-world in order to create multiple
  gint worlds. This would be useful in Yatis' hypervisor.
* A GINT_DRV_LAZY flag would be useful for drivers that don't want to
  be started up automatically during a world switch. This is relevant
  for drivers that have a slow start/stop sequence. However, this is
  tricky to do correctly as it requires dynamic start/stop and also
  tracking which world the current hardware state belongs to.
2021-04-23 20:44:08 +02:00

118 lines
3.7 KiB
C

//---
// gint:hardware - Platform information and hardware detection
//
// This components centralizes detected information about the runtime
// hardware, including MPU version, peripheral modules, and how drivers
// configured them.
//
// The most common use of this header is for the isSH3() and isSH4()
// macros that let you run MPU-dependent jobs and are used like this:
// if(isSH3()) do_sh3();
// else do_sh4();
//---
#ifndef GINT_HARDWARE
#define GINT_HARDWARE
/* For compatibility with ASM, include the following bits only in C code */
#ifndef CPP_ASM
#include <gint/defs/types.h>
/* Most of the information here is going to be stored in (key, value) pairs for
predetermined keys and 32-bits values that are often integers or a set of
flags. The data will be filled by gint or its drivers. */
#define HW_KEYS 16
extern uint32_t gint[HW_KEYS];
/* hw_detect(): Basic hardware detection
This function probes the hardware and fills in the HWMPU, HWCPUVR and
HWCPUPR fields. */
void hw_detect(void);
#endif /* CPP_ASM */
/* MPU detection macros, with a faster version on fx-CG 50 and a generic
dual-platform version for libraries.
Warning: this macro is also used hardcoded in exch.s. */
#if defined(FX9860G) || (!defined(FX9860G) && !defined(FXCG50))
#define isSH3() (gint[HWMPU] & 1)
#define isSH4() (!isSH3())
#endif
#ifdef FXCG50
#define isSH3() 0
#define isSH4() 1
#endif
/* This bit should be set in all data longwords except HWMPU, HWCPUVR, HWCPUPR
and HWCALC which are guaranteed to always be loaded. If not set then the
information must be treated as invalid. */
#define HW_LOADED 0x80000000
/*
** Key list
*/
#define HWMPU 0 /* MPU type */
#define HWCPUVR 1 /* CPU Version Register */
#define HWCPUPR 2 /* CPU Product Register */
#define HWCALC 3 /* Calculator model, hardcoded in kernel/inth.S */
#define HWRAM 4 /* Amount of RAM */
#define HWROM 5 /* Amount of ROM */
#define HWURAM 6 /* Userspace RAM */
#define HWETMU /* Deprecated: use timer_count() (ETMU always load) */
#define HWKBD 8 /* Keyboard */
#define HWKBDSF /* Deprecated: use keysc_scan_frequency() */
#define HWDD /* Deprecated: use the T6K11/R61524 API */
/*
** MPU type
*/
/* Unknown MPUs are all assumed to be SH-4A-based */
#define HWMPU_UNKNOWN 0
/* Used on original fx-9860G, SH-3-based */
#define HWMPU_SH7337 1
/* Used on recent fx-9860G derivatives such as the fx-9750G II, and also on the
fx-CG 10/20/50. SH-4A-based */
#define HWMPU_SH7305 2
/* Used on the fx-9860G II, SH-3-based */
#define HWMPU_SH7355 3
/* Closest documented match to the SH7305, not used in any known calculator.
Detected and included for reference only */
#define HWMPU_SH7724 4
/*
** Calculator type
*/
/* SH-3-based fx-9860G-family */
#define HWCALC_FX9860G_SH3 1
/* Other SH-4A-based fx-9860G-family */
#define HWCALC_FX9860G_SH4 2
/* Graph 35+E II, an SH-4A French extension of the fx-9860G family */
#define HWCALC_G35PE2 3
/* fx-CG 10/20, also known as the "Prizm" family */
#define HWCALC_PRIZM 4
/* fx-CG 50, a late extension to the Prizm family */
#define HWCALC_FXCG50 5
/* fx-CG 50 emulator, hardcoded in kernel/inth.S */
#define HWCALC_FXCG_MANAGER 6
/*
** Keyboard
*/
/* The keyboard uses an I/O-port-based scan method. This is possible on both
SH3 and SH4, but gint will normally do it only on SH3. */
#define HWKBD_IO 0x01
/* When using the I/O-port scanning method on SH3, whether the watchdog is used
to delay I/O operations. */
#define HWKBD_WDD 0x02
/* The keyboard uses a KEYSC-based scan method. This is only possible on SH4 */
#define HWKBD_KSI 0x04
#endif /* GINT_HARDWARE */