aboutsummaryrefslogtreecommitdiff
path: root/src/boot/psr.h
blob: f300a7aeb1ab6b6afafba690644a1111549b4449 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#ifndef PSR_H
#define PSR_H

#include <stdint.h>

enum execution_mode {
  MODE_USER       = 0b10000,
  MODE_FIQ        = 0b10001,
  MODE_IRQ        = 0b10010,
  MODE_SUPERVISOR = 0b10011,
  MODE_MONITOR    = 0b10110,
  MODE_ABORT      = 0b10111,
  MODE_HYPERVISOR = 0b11010,
  MODE_UNDEFINED  = 0b11011,
  MODE_SYSTEM     = 0b11111,
};

typedef union
{
  uint32_t raw;
  struct
  {
    uint32_t M_4_0      : 5; // bits 4:0
    uint32_t T          : 1; // bit  5
    uint32_t F          : 1; // bit  6
    uint32_t I          : 1; // bit  7
    uint32_t A          : 1; // bit  8
    uint32_t E          : 1; // bit  9
    uint32_t IT_7_2     : 6; // bits 15:10
    uint32_t GE_3_0     : 4; // bits 19:16
    uint32_t Bits_23_20 : 4; // bits 23:20
    uint32_t J          : 1; // bit  24
    uint32_t IT_1_0     : 2; // bits 26:25
    uint32_t Q          : 1; // bit  27
    uint32_t V          : 1; // bit  28
    uint32_t C          : 1; // bit  29
    uint32_t Z          : 1; // bit  30
    uint32_t N          : 1; // bit  31
#define PSR_MODE_4_0                    M_4_0
#define PSR_THUMB_BIT                   T
#define PSR_FIQ_MASKK_BIT               F
#define PSR_IRQ_MASK_BIT                I
#define PSR_ASYNC_ABORT_MASK_BIT        A
#define PSR_ENDIANNESS_BIT              E
#define PSR_IF_THEN_STATE_7_2           IT_7_2
#define PSR_GREATER_THAN_OR_EQUAL_FLAGS GE_3_0
    // bits 23:20 are reserved
#define PSR_JAZELLE_BIT                 J
#define PSR_IF_THEN_STATE_1_0           IT_1_0
#define PSR_CUMULATIVE_SATURATION_BIT   Q
#define PSR_OVERFLOW_CONDITION_BIT      V
#define PSR_CARRY_CONDITION_BIT         C
#define PSR_ZERO_CONDITION_BIT          Z
#define PSR_NEGATIVE_CONDITION_BIT      N
  } fields;
} PSR_t;

inline static PSR_t read_CPSR(void)
{
  PSR_t CPSR;
  // get content of current program status register
  asm("mrs %0, cpsr" : "=r" (CPSR.raw) :: "memory");

  return CPSR;
}

inline static void write_CPSR(PSR_t CPSR)
{
  // set content of current program status register
  asm("msr cpsr, %0" :: "r" (CPSR.raw) : "memory");
}

inline static PSR_t read_SPSR(void)
{
  PSR_t SPSR;
  // get content of saved program status register
  asm("mrs %0, spsr" : "=r" (SPSR.raw) :: "memory");
  
  return SPSR;
}

inline static void write_SPSR(PSR_t SPSR)
{
  // set content of saved program status register
  asm("msr spsr, %0" :: "r" (SPSR.raw));
}

#endif // PSR_H