Intel® Quark™ Microcontroller Software Interface  1.4.0
Intel® Quark™ Microcontroller BSP
qm_fpr.c
1 /*
2  * {% copyright %}
3  */
4 
5 #include "qm_fpr.h"
6 #include "qm_interrupt.h"
7 #include "qm_interrupt_router.h"
8 
9 static void (*callback[QM_FLASH_NUM])(void *);
10 static void *callback_data[QM_FLASH_NUM];
11 
12 QM_ISR_DECLARE(qm_flash_mpr_0_isr)
13 {
14  if (callback[QM_FLASH_0]) {
15  (*callback[QM_FLASH_0])(callback_data[QM_FLASH_0]);
16  }
17  QM_FLASH[QM_FLASH_0]->mpr_vsts = QM_FPR_MPR_VSTS_VALID;
18 
19  QM_ISR_EOI(QM_IRQ_FLASH_MPR_0_INT_VECTOR);
20 }
21 
22 #if (QUARK_SE)
23 QM_ISR_DECLARE(qm_flash_mpr_1_isr)
24 {
25  if (callback[QM_FLASH_1]) {
26  (*callback[QM_FLASH_1])(callback_data[QM_FLASH_1]);
27  }
28  QM_FLASH[QM_FLASH_1]->mpr_vsts = QM_FPR_MPR_VSTS_VALID;
29 
30  QM_ISR_EOI(QM_IRQ_FLASH_MPR_1_INT_VECTOR);
31 }
32 #endif
33 
34 int qm_fpr_set_config(const qm_flash_t flash, const qm_fpr_id_t id,
35  const qm_fpr_config_t *const cfg,
36  const qm_flash_region_type_t region)
37 {
38  QM_CHECK(flash < QM_FLASH_NUM, -EINVAL);
39  QM_CHECK(id < QM_FPR_NUM, -EINVAL);
40  QM_CHECK(region < QM_MAIN_FLASH_NUM, -EINVAL);
41  QM_CHECK(cfg != NULL, -EINVAL);
42  QM_CHECK(cfg->low_bound <= cfg->up_bound, -EINVAL);
43 
44  qm_flash_reg_t *const controller = QM_FLASH[flash];
45 
46  controller->fpr_rd_cfg[id] &= ~QM_FPR_LOCK;
47 
48  if (region == QM_MAIN_FLASH_SYSTEM) {
49  controller->fpr_rd_cfg[id] =
50  (cfg->allow_agents << QM_FPR_RD_ALLOW_OFFSET) |
51  ((cfg->up_bound + QM_FLASH_REGION_DATA_BASE_OFFSET)
52  << QM_FPR_UPPER_BOUND_OFFSET) |
53  (cfg->low_bound + QM_FLASH_REGION_DATA_BASE_OFFSET);
54  }
55 #if (QUARK_D2000)
56  else if (region == QM_MAIN_FLASH_DATA) {
57  controller->fpr_rd_cfg[id] =
58  (cfg->allow_agents << QM_FPR_RD_ALLOW_OFFSET) |
59  (cfg->up_bound << QM_FPR_UPPER_BOUND_OFFSET) |
60  cfg->low_bound;
61  }
62 #endif
63  /* qm_fpr_id_t enable/lock */
64  controller->fpr_rd_cfg[id] |= (cfg->en_mask << QM_FPR_ENABLE_OFFSET);
65 
66  return 0;
67 }
68 
69 #if (QM_SENSOR)
71  const qm_flash_t flash,
72  qm_fpr_callback_t callback_fn, void *data)
73 {
74  QM_CHECK(mode <= FPR_VIOL_MODE_PROBE, -EINVAL);
75  QM_CHECK(flash < QM_FLASH_NUM, -EINVAL);
76  volatile uint32_t *int_flash_controller_mask =
77  &QM_INTERRUPT_ROUTER->flash_mpr_0_int_mask;
78 
79  /* interrupt mode */
80  if (FPR_VIOL_MODE_INTERRUPT == mode) {
81 
82  callback[flash] = callback_fn;
83  callback_data[flash] = data;
84 
85  QM_IR_UNMASK_INTERRUPTS(int_flash_controller_mask[flash]);
86 
87  QM_IR_MASK_HALTS(int_flash_controller_mask[flash]);
88 
89  QM_SCSS_SS->ss_cfg &= ~QM_SS_STS_HALT_INTERRUPT_REDIRECTION;
90  }
91 
92  /* probe or reset mode */
93  else {
94  QM_IR_MASK_INTERRUPTS(int_flash_controller_mask[flash]);
95 
96  QM_IR_UNMASK_HALTS(int_flash_controller_mask[flash]);
97 
98  if (FPR_VIOL_MODE_PROBE == mode) {
99 
100  /* When an enabled host halt interrupt occurs, this bit
101  * determines if the interrupt event triggers a warm
102  * reset
103  * or an entry into Probe Mode.
104  * 0b : Warm Reset
105  * 1b : Probe Mode Entry
106  */
107  QM_SCSS_SS->ss_cfg |=
108  QM_SS_STS_HALT_INTERRUPT_REDIRECTION;
109  } else {
110  QM_SCSS_SS->ss_cfg &=
111  ~QM_SS_STS_HALT_INTERRUPT_REDIRECTION;
112  }
113  }
114  return 0;
115 }
116 
117 #else /* QM_SENSOR */
118 
120  const qm_flash_t flash,
121  qm_fpr_callback_t callback_fn, void *data)
122 {
123  QM_CHECK(mode <= FPR_VIOL_MODE_PROBE, -EINVAL);
124  QM_CHECK(flash < QM_FLASH_NUM, -EINVAL);
125  volatile uint32_t *int_flash_controller_mask =
126  &QM_INTERRUPT_ROUTER->flash_mpr_0_int_mask;
127 
128  /* interrupt mode */
129  if (FPR_VIOL_MODE_INTERRUPT == mode) {
130 
131  callback[flash] = callback_fn;
132  callback_data[flash] = data;
133 
134  /* unmask interrupt */
135  if (flash == QM_FLASH_0) {
136  QM_IR_UNMASK_INT(QM_IRQ_FLASH_MPR_0_INT);
137 #if (QUARK_SE)
138  } else {
139  QM_IR_UNMASK_INT(QM_IRQ_FLASH_MPR_1_INT);
140 #endif
141  }
142 
143  QM_IR_MASK_HALTS(int_flash_controller_mask[flash]);
144 
145  QM_SCSS_PMU->p_sts &= ~QM_P_STS_HALT_INTERRUPT_REDIRECTION;
146  }
147 
148  /* probe or reset mode */
149  else {
150  /* mask interrupt */
151  if (flash == QM_FLASH_0) {
152  QM_IR_MASK_INT(QM_IRQ_FLASH_MPR_0_INT);
153 #if (QUARK_SE)
154  } else {
155  QM_IR_MASK_INT(QM_IRQ_FLASH_MPR_1_INT);
156 #endif
157  }
158 
159  QM_IR_UNMASK_HALTS(int_flash_controller_mask[flash]);
160 
161  if (FPR_VIOL_MODE_PROBE == mode) {
162 
163  /* When an enabled host halt interrupt occurs, this bit
164  * determines if the interrupt event triggers a warm
165  * reset
166  * or an entry into Probe Mode.
167  * 0b : Warm Reset
168  * 1b : Probe Mode Entry
169  */
170  QM_SCSS_PMU->p_sts |=
171  QM_P_STS_HALT_INTERRUPT_REDIRECTION;
172  } else {
173  QM_SCSS_PMU->p_sts &=
174  ~QM_P_STS_HALT_INTERRUPT_REDIRECTION;
175  }
176  }
177  return 0;
178 }
179 #endif /* QM_SENSOR */
180 
181 #if (ENABLE_RESTORE_CONTEXT)
182 int qm_fpr_save_context(const qm_flash_t flash, qm_fpr_context_t *const ctx)
183 {
184  QM_CHECK(flash < QM_FLASH_NUM, -EINVAL);
185  QM_CHECK(ctx != NULL, -EINVAL);
186  uint8_t i;
187 
188  qm_flash_reg_t *const controller = QM_FLASH[flash];
189 
190  for (i = 0; i < QM_FPR_NUM; i++) {
191  ctx->fpr_rd_cfg[i] = controller->fpr_rd_cfg[i];
192  }
193 
194  return 0;
195 }
196 
198  const qm_fpr_context_t *const ctx)
199 {
200  QM_CHECK(flash < QM_FLASH_NUM, -EINVAL);
201  QM_CHECK(ctx != NULL, -EINVAL);
202  uint8_t i;
203 
204  qm_flash_reg_t *const controller = QM_FLASH[flash];
205 
206  for (i = 0; i < QM_FPR_NUM; i++) {
207  controller->fpr_rd_cfg[i] = ctx->fpr_rd_cfg[i];
208  }
209 
210  return 0;
211 }
212 #else
213 int qm_fpr_save_context(const qm_flash_t flash, qm_fpr_context_t *const ctx)
214 {
215  (void)flash;
216  (void)ctx;
217 
218  return 0;
219 }
220 
221 int qm_fpr_restore_context(const qm_flash_t flash,
222  const qm_fpr_context_t *const ctx)
223 {
224  (void)flash;
225  (void)ctx;
226 
227  return 0;
228 }
229 #endif
System flash region.
Definition: qm_fpr.h:42
int qm_fpr_set_violation_policy(const qm_fpr_viol_mode_t mode, const qm_flash_t flash, qm_fpr_callback_t callback_fn, void *data)
Configure FPR violation behaviour.
Definition: qm_fpr.c:70
uint8_t low_bound
1KB-aligned lower Flash phys addr.
Definition: qm_fpr.h:73
Flash Protection Region configuration structure.
Definition: qm_fpr.h:69
int qm_fpr_restore_context(const qm_flash_t flash, const qm_fpr_context_t *const ctx)
Restore FPR context.
Definition: qm_fpr.c:197
qm_fpr_read_allow_t allow_agents
Per-agent read enable bitmask.
Definition: qm_fpr.h:71
Enter probe mode on violation.
Definition: qm_fpr.h:35
qm_flash_t
Number of Flash controllers.
Definition: qm_soc_regs.h:1141
uint8_t up_bound
1KB-aligned upper Flash phys addr.
Definition: qm_fpr.h:72
uint32_t fpr_rd_cfg[QM_FPR_NUM]
Flash Protection Region Read Control Register.
Definition: qm_soc_regs.h:1593
int qm_fpr_set_config(const qm_flash_t flash, const qm_fpr_id_t id, const qm_fpr_config_t *const cfg, const qm_flash_region_type_t region)
Configure a Flash controller's Flash Protection Region.
Definition: qm_fpr.c:34
FPR context type.
Definition: qm_soc_regs.h:1591
qm_fpr_en_t en_mask
Enable/lock bitmask.
Definition: qm_fpr.h:70
Generate interrupt on violation.
Definition: qm_fpr.h:33
QM_ISR_DECLARE(qm_flash_mpr_0_isr)
ISR for FPR 0 interrupt.
Definition: qm_fpr.c:12
QM_RW uint32_t fpr_rd_cfg[4]
4 FPR_RD_CFG registers
Definition: qm_soc_regs.h:1152
Flash register map.
Definition: qm_soc_regs.h:1144
Number of flash regions.
Definition: qm_fpr.h:46
Data flash region.
Definition: qm_fpr.h:44
int qm_fpr_save_context(const qm_flash_t flash, qm_fpr_context_t *const ctx)
Save FPR context.
Definition: qm_fpr.c:182
qm_fpr_id_t
FPR register map.
Definition: qm_soc_regs.h:1265
qm_fpr_viol_mode_t
FPR violation mode type.
Definition: qm_fpr.h:32
qm_flash_region_type_t
FPR region type.
Definition: qm_fpr.h:41