ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_flash_config.c
Go to the documentation of this file.
1
34
35#include <stdint.h>
36
37#include "ra8_attributes.h"
38#include "ra8_check.h"
39#include "ra8_err.h"
40#include "ra8_flash.h"
41#include "ra8_flash_internal.h"
42#include "ra8_flash_regs.h"
43#include "ra8_hw_err.h"
44#include "ra8_log.h"
45
47typedef enum : uint32_t {
51
68
69/* =============================================================================
70 * Internal helpers: anti-rollback counter math
71 * =============================================================================
72 */
73
94{
95 switch (id) {
97 return k_ra8_mcntselr_sec;
103 return (uint8_t)(k_ra8_mcntselr_nsec_0 + 1U);
105 return (uint8_t)(k_ra8_mcntselr_nsec_0 + 2U);
107 return (uint8_t)(k_ra8_mcntselr_nsec_0 + 3U);
108 default:
109 return 0U;
110 }
111 /* unreachable */
112}
113
134{
135 if (id == k_ra8_flash_arc_sec) {
137 }
138 if (id == k_ra8_flash_arc_oembl) {
140 }
141 /* NSEC: read ARCCS.ARCNS to decide single vs multiple. */
142 /* HUM Ch 7.2.21 "ARCCS Anti-Rollback Counter Configuration" p 296 */
143 const uint16_t arccs = *(volatile const uint16_t*)k_ra8_flash_ofs_arccs_addr;
144 const uint8_t arcns = (uint8_t)(arccs & (uint16_t)k_ra8_arc_arccs_mask);
145 if (arcns == (uint8_t)k_ra8_arc_arcns_single) {
147 }
149}
150
171RA8_INTERNAL static uint32_t internal_popcount32(uint32_t x)
172{
173 /* Avoid relying on __builtin_popcount so the off-target build
174 * does not pick up a different implementation than the firmware
175 * target. NASA Rule 2 -- bounded loop. */
176 uint32_t count = 0U;
177 for (uint32_t i = 0U; i < 32U; ++i) {
178 if ((x & (uint32_t)(1UL << i)) != 0U) {
179 count++;
180 }
181 }
182 return count;
183}
184
185/* =============================================================================
186 * Public API: start-up area control
187 * =============================================================================
188 */
189
191{
192 if (target > k_ra8_flash_startup_btflg) {
194 }
196 if (err != k_ra8_ok) {
197 return err;
198 }
199
200 if (temporary) {
201 /* HUM Ch 59 "MSUACR : Start-Up Area Control Register" p 3574 */
202 const uint16_t swap_bit = (target == k_ra8_flash_startup_alternate)
205 *ra8_mram_reg16(k_ra8_mram_off_msuacr) = (uint16_t)(k_ra8_msuacr_key | swap_bit);
206 } else {
207 /* Permanent: configuration-set write to BTFLG. */
208 /* HUM Ch 7 "Option-Setting Memory" p 278 */
209 uint16_t cfg_words[k_ra8_mram_config_set_word_count];
210 for (uint32_t i = 0U; i < k_ra8_mram_config_set_word_count; ++i) {
211 cfg_words[i] = k_ra8_flash_cfg_word_all_ones;
212 }
213 /* BTFLG occupies bit 15 of word index 3 (FSP MRAM_PRV_CONFIG_SET_BTFLG_OFFSET).
214 * 0 selects alternate, 1 selects default (HUM Ch 7 p 278). */
215 uint16_t btflg_bit = k_ra8_flash_btflg_alternate;
216 if (target == k_ra8_flash_startup_default) {
217 btflg_bit = k_ra8_flash_btflg_default;
218 }
219 /* HUM Ch 7 "OFS SAS region" p 278 */
220 cfg_words[3] = (uint16_t)(btflg_bit | k_ra8_flash_btflg_word_keep);
222 }
223
225 if (err != k_ra8_ok) {
226 return err;
227 }
228 return exit_err;
229}
230
231ra8_err_t ra8_flash_get_startup_area(uint8_t* out_btflg, uint8_t* out_fspr)
232{
233 RA8_CHECK_NULL_PTR(out_btflg, g_flash_tag, "out_btflg must not be nullptr");
234 RA8_CHECK_NULL_PTR(out_fspr, g_flash_tag, "out_fspr must not be nullptr");
235 /* HUM Ch 59 "MSUASMON : Start-Up Area Monitor" p 3573 */
236 const uint32_t v = *ra8_mram_reg32(k_ra8_mram_off_msuasmon);
237 *out_btflg = (uint8_t)((v & k_ra8_msuasmon_mask_btflg) != 0U);
238 *out_fspr = (uint8_t)((v & k_ra8_msuasmon_mask_fspr) != 0U);
239 return k_ra8_ok;
240}
241
242/* =============================================================================
243 * Public API: configuration-set write (low-level OFS update)
244 * =============================================================================
245 */
246
247ra8_err_t ra8_flash_config_set_write(uint32_t target_addr, const uint16_t* words)
248{
249 RA8_CHECK_NULL_PTR(words, g_flash_tag, "words must not be nullptr");
250 /* One MACI byte-stream shape -- ``<opener>, N, 8 halfwords, 0xD0`` -- serves
251 * two target regions, and the opener opcode is chosen per region below:
252 * - OFS configuration area (HUM Ch 7 "Option-Setting Memory" p 278) at
253 * 0x02C9F000: the Configuration Set command (HUM Ch 59.7.4.8 p 3594).
254 * - Extra-MRAM option-setting / OTP area (HUM Ch 59.7.4.5 Table 59.15
255 * p 3592) at 0x02E07600: the Program command (HUM Ch 59.7.4.5 "Program
256 * Command" Fig 59.13 p 3591). Config-Set is NOT valid for the data area
257 * -- it raises
258 * MSTATR.CFGSETERR and leaves the target blank, so a later read of the
259 * un-programmed cells bus-faults on the blank-MRAM ECC error.
260 * Accept both ranges; reject everything else. */
261 const uint32_t ofs_end = (uint32_t)k_ra8_flash_ofs_start + (uint32_t)k_ra8_flash_ofs_size;
262 const uint32_t extra_end = (uint32_t)k_ra8_flash_extra_start + (uint32_t)k_ra8_flash_extra_size;
263 const bool in_ofs =
264 (bool)((target_addr >= (uint32_t)k_ra8_flash_ofs_start) && (target_addr < ofs_end));
265 const bool in_extra =
266 (bool)((target_addr >= (uint32_t)k_ra8_flash_extra_start) && (target_addr < extra_end));
267 if (!in_ofs && !in_extra) {
269 }
270
271 /* HUM Ch 59.5.19 "MSADDR : MACI Command Start Address Register" p 3564 */
273 /* Opener: Program (0xE8) for the extra-MRAM data area, else Configuration
274 * Set (0x40) for the OFS config area. HUM Ch 59.7.4.5 Fig 59.13 p 3591 /
275 * HUM Ch 59.7.4.8 p 3594. */
276 const uint8_t opener =
277 in_extra ? (uint8_t)k_ra8_maci_cmd_program : (uint8_t)k_ra8_maci_cmd_config_set;
280
281 /* N = k_ra8_mram_config_set_word_count halfwords of payload.
282 * HUM Ch 59.7.4.5 Fig 59.13 p 3592 / HUM Ch 59.7.4.8 p 3595. */
283 for (uint32_t i = 0U; i < k_ra8_mram_config_set_word_count; ++i) {
285 }
286 /* Trailer 0xD0 starts command processing. HUM Ch 59.7.4.5 Fig 59.13 p 3592. */
288
290 if (err != k_ra8_ok) {
291 return err;
292 }
293
294 /* HUM Ch 59 "MSTATR : Extra MRAM Status Register" p 3568 */
295 const uint32_t s = *ra8_mram_reg32(k_ra8_mram_off_mstatr);
296 if ((s & k_ra8_mstatr_mask_any_err) != 0U) {
297 return k_ra8_err_hw_error;
298 }
299 return k_ra8_ok;
300}
301
302/* =============================================================================
303 * Public API: anti-rollback counters
304 * =============================================================================
305 */
306
327RA8_INTERNAL static ra8_err_t internal_arc_cmd(uint8_t mcntselr, uint8_t cmd)
328{
329 /* HUM Ch 59 "MCNTSELR : MRAM Counter Select Register" p 3565 */
334 if (err != k_ra8_ok) {
335 return err;
336 }
337 /* HUM Ch 59 "MASTAT : Extra MRAM Access Status Register" p 3562 */
338 const uint8_t mastat = *ra8_mram_reg8(k_ra8_mram_off_mastat);
339 if ((mastat & k_ra8_mastat_mask_cmdlk) != 0U) {
340 return k_ra8_err_hw_error;
341 }
342 return k_ra8_ok;
343}
344
369{
370 /* HUM Ch 7.2.21 "ARCCS" p 296 */
371 const uint16_t arccs = *(volatile const uint16_t*)k_ra8_flash_ofs_arccs_addr;
372 const uint8_t arcns = (uint8_t)(arccs & (uint16_t)k_ra8_arc_arccs_mask);
373 /* HUM Ch 7.2.23 "ARC_NSEC" p 297 */
374 const volatile uint32_t* base = (const volatile uint32_t*)k_ra8_flash_ofs_arc_nsec_addr;
375 uint32_t words_per = (arcns == (uint8_t)k_ra8_arc_arcns_single) ? 16U : 2U;
376 if (words_per > k_ra8_mram_arc_max_words) {
377 words_per = k_ra8_mram_arc_max_words;
378 }
379 uint32_t base_idx = words_per * 3U;
380 if (id == k_ra8_flash_arc_nsec_0) {
381 base_idx = 0U;
382 } else if (id == k_ra8_flash_arc_nsec_1) {
383 base_idx = words_per;
384 } else if (id == k_ra8_flash_arc_nsec_2) {
385 base_idx = words_per * 2U;
386 } else {
387 /* falls through to 3*words_per default. */
388 }
389 uint32_t count = 0U;
390 for (uint32_t w = 0U; w < words_per; ++w) {
391 count += internal_popcount32(base[base_idx + w]);
392 }
393 return count;
394}
395
396/* internal_arc_read_locked -- see header for full description. */
398{
399 uint8_t mcntselr = internal_arc_to_mcntselr(id);
400 uint32_t count = 0U;
401
402 if (id == k_ra8_flash_arc_oembl) {
403 /* OEMBL needs the MACI read so RSIP-E50D can intercept. */
405 if (err != k_ra8_ok) {
406 return err;
407 }
408 /* HUM Ch 59 "MCNTDTR0 : MRAM Counter Data 0" p 3576 */
409 const uint32_t lo = *ra8_mram_reg32(k_ra8_mram_off_mcntdtr0);
410 /* HUM Ch 59 "MCNTDTR1 : MRAM Counter Data 1" p 3577 */
411 const uint32_t hi = *ra8_mram_reg32(k_ra8_mram_off_mcntdtr1);
413 } else if (id == k_ra8_flash_arc_sec) {
414 /* HUM Ch 7.2.22 "ARC_SEC" p 296: ARC_SEC is a 64-bit unary counter, i.e.
415 * 2 x uint32_t words. FSP r_mram.c L1196 derives the same count via
416 * BSP_FEATURE_FLASH_ARC_SEC_MAX_COUNT (64) >> 5. The previous loop walked
417 * 8 words, which over-counted into adjacent OFS state. */
418 const volatile uint32_t* p = (const volatile uint32_t*)k_ra8_flash_ofs_arc_sec_addr;
419 const uint32_t sec_words = k_ra8_arc_sec_max_bits >> k_flash_bits_to_words_shift;
420 for (uint32_t w = 0U; w < sec_words; ++w) {
421 count += internal_popcount32(p[w]);
422 }
423 } else {
424 count = internal_arc_nsec_count(id);
425 }
426
427 *out_count = count;
428 (void)mcntselr; /* used in OEMBL branch only */
429 return k_ra8_ok;
430}
431
433{
434 if (counter >= k_ra8_flash_arc_count) {
436 }
437 RA8_VALIDATE_INIT(g_flash_rt.initialized, g_flash_tag, "arc_inc before init");
438
440 if (err != k_ra8_ok) {
441 return err;
442 }
443
444 /* NASA Power-of-10 Rule 1 forbids goto, so the read-bound-check-increment
445 * sequence is expressed as a short-circuit chain: each step runs only if
446 * the previous one returned k_ra8_ok, and the unconditional exit-PE step
447 * replaces the prior goto-out label.
448 * HUM Ch 59.4.4 "MACI Increment Counter" p 3550. */
449 uint32_t cur = 0U;
450 err = internal_arc_read_locked(counter, &cur);
451 if (err == k_ra8_ok) {
452 const uint32_t max = internal_arc_max_count(counter);
453 if (cur + 1U > max) {
455 } else {
457 }
458 }
459
460 const ra8_err_t exit_err = ra8_flash_exit_pe_mode();
461 if (err == k_ra8_ok) {
462 err = exit_err;
463 }
464 return err;
465}
466
468{
469 RA8_CHECK_NULL_PTR(out_count, g_flash_tag, "out_count must not be nullptr");
470 if (counter >= k_ra8_flash_arc_count) {
472 }
473 RA8_VALIDATE_INIT(g_flash_rt.initialized, g_flash_tag, "arc_read before init");
474
475 if (counter == k_ra8_flash_arc_oembl) {
477 if (err != k_ra8_ok) {
478 return err;
479 }
480 ra8_err_t r = internal_arc_read_locked(counter, out_count);
482 if (r != k_ra8_ok) {
483 return r;
484 }
485 return exit_err;
486 }
487 return internal_arc_read_locked(counter, out_count);
488}
489
490/* =============================================================================
491 * Public API: zeroize, MSAR, MSUINITR, ECC controls
492 * =============================================================================
493 */
494
496{
497 RA8_VALIDATE_INIT(g_flash_rt.initialized, g_flash_tag, "zeroize before init");
498 /* HUM Ch 59 "MREZC : Extra MRAM Zeroization Control" p 3561 */
500
501 for (uint32_t i = 0U; i < k_ra8_flash_zeroize_spin; ++i) {
502 /* HUM Ch 59 "MREZS : Extra MRAM Zeroization Status" p 3561 */
503 const uint8_t s = *ra8_mram_reg8(k_ra8_mram_off_mrezs);
504 if ((s & k_ra8_mrezs_mask_whukexe) == 0U) {
505 return k_ra8_ok;
506 }
507 }
509}
510
512{
513 /* HUM Ch 59.5.13 "MSAR : MRAM Security Attribution Register" p 3559 */
515 return k_ra8_ok;
516}
517
519{
520 /* HUM Ch 59 "MSUINITR : Extra MRAM Sequencer Set-Up Init" p 3572 */
522
523 for (uint32_t i = 0U; i < k_ra8_flash_pe_spin_limit; ++i) {
524 /* HUM Ch 59 "MSUINITR : Extra MRAM Sequencer Set-Up Init" p 3572 */
525 const uint16_t v = *ra8_mram_reg16(k_ra8_mram_off_msuinitr);
526#if defined(RA8_OFF_TARGET) && defined(UNIT_TEST)
527 /* Host MMIO fault seam: on real HW the sequencer auto-clears
528 * SUINIT once the init completes; host RAM cannot, so the seam
529 * owns the loop-exit decision (first-poll success unless a test
530 * arms a fault to drive the retry / timeout legs). */
531 if (ra8_fake_mmio_wait_eval(ra8_mram_reg16(k_ra8_mram_off_msuinitr),
532 i,
533 ((v & k_ra8_msuinitr_mask_suinit) == 0U))) {
534 return k_ra8_ok;
535 }
536#else
537 if ((v & k_ra8_msuinitr_mask_suinit) == 0U) {
538 return k_ra8_ok;
539 }
540#endif
541 }
543}
544
546{
547 /* HUM Ch 59 "MRCEECC : Code MRAM ECC Encoder Control" p 3580 */
548 uint16_t enc_bit = 0U;
549 if (enable) {
550 enc_bit = k_ra8_mrceecc_mask_eccen;
551 }
553 return k_ra8_ok;
554}
555
557{
558 /* HUM Ch 59 "MRCDECC : Code MRAM ECC Decoder Control" p 3554 */
559 uint16_t dec_bit = 0U;
560 if (enable) {
562 }
564 return k_ra8_ok;
565}
566
568 uint32_t* out_code_dec,
569 uint32_t* out_extra_ted,
570 uint32_t* out_extra_dec)
571{
572 RA8_CHECK_NULL_PTR(out_code_ted, g_flash_tag, "out_code_ted null");
573 RA8_CHECK_NULL_PTR(out_code_dec, g_flash_tag, "out_code_dec null");
574 RA8_CHECK_NULL_PTR(out_extra_ted, g_flash_tag, "out_extra_ted null");
575 RA8_CHECK_NULL_PTR(out_extra_dec, g_flash_tag, "out_extra_dec null");
576
577 /* HUM Ch 59 "MRCRTEA : Code MRAM TED Error Address" p 3555 */
578 *out_code_ted = *ra8_mram_reg32(k_ra8_mram_off_mrcrtea);
579 /* HUM Ch 59 "MRCRDEA : Code MRAM DEC Error Address" p 3556 */
580 *out_code_dec = *ra8_mram_reg32(k_ra8_mram_off_mrcrdea);
581 /* HUM Ch 59 "MRERTEA : Extra MRAM TED Error Address" p 3558 */
582 *out_extra_ted = *ra8_mram_reg32(k_ra8_mram_off_mrertea);
583 /* HUM Ch 59 "MRERDEA : Extra MRAM DEC Error Address" p 3559 */
584 *out_extra_dec = *ra8_mram_reg32(k_ra8_mram_off_mrerdea);
585 return k_ra8_ok;
586}
587
589{
590 RA8_CHECK_NULL_PTR(out_addr, g_flash_tag, "out_addr must not be nullptr");
591 /* HUM Ch 59 "MRCPEA : Code MRAM Program Error Address" p 3579 */
593 return k_ra8_ok;
594}
595
596ra8_err_t ra8_flash_update_clock_freq(uint16_t mrcfreq_mhz, uint8_t mrefreq_mhz)
597{
598 if (mrcfreq_mhz > (uint16_t)k_ra8_flash_max_mrcfreq_mhz) {
600 }
601 if (mrefreq_mhz > (uint8_t)k_ra8_flash_max_mrefreq_mhz) {
603 }
604 const bool prefetch_was = g_flash_rt.prefetch_on;
606
607 /* HUM Ch 59.5.2 "MRCFREQ : Code MRAM Frequency Notifications Register" p 3551 */
609 (k_ra8_flash_mrcfreq_key << k_ra8_flash_freq_key_shift) | (uint32_t)mrcfreq_mhz;
610 /* HUM Ch 59.5.3 "MREFREQ : Extra MRAM Frequency Notifications Register" p 3552 */
612 (k_ra8_flash_mrefreq_key << k_ra8_flash_freq_key_shift) | (uint32_t)mrefreq_mhz;
613
615 return k_ra8_ok;
616}
617
618/* =============================================================================
619 * Public API: update transfer
620 * =============================================================================
621 */
622
624{
625 if (list_select > (uint8_t)k_ra8_flash_max_list_select) {
627 }
628 /* HUM Ch 59 "MCTRLSR : MRAM Update Transfer List Select" p 3567 */
630 /* HUM Ch 59 "MCTRCNTR : MRAM Update Transfer Control" p 3566 */
633 return k_ra8_ok;
634}
635
636ra8_err_t ra8_flash_get_update_status(uint8_t* out_busy, uint8_t* out_done, uint8_t* out_err)
637{
638 RA8_CHECK_NULL_PTR(out_busy, g_flash_tag, "out_busy null");
639 RA8_CHECK_NULL_PTR(out_done, g_flash_tag, "out_done null");
640 RA8_CHECK_NULL_PTR(out_err, g_flash_tag, "out_err null");
641 /* HUM Ch 59 "MCTRSTATR : MRAM Update Transfer Status" p 3568 */
642 const uint16_t v = *ra8_mram_reg16(k_ra8_mram_off_mctrstatr);
643 *out_busy = (uint8_t)((v & k_ra8_mctrstatr_mask_busy) != 0U);
644 *out_done = (uint8_t)((v & k_ra8_mctrstatr_mask_done) != 0U);
645 *out_err = (uint8_t)((v & k_ra8_mctrstatr_mask_err) != 0U);
646 return k_ra8_ok;
647}
648
649/* =============================================================================
650 * Public API: extra-MRAM (data flash) program / erase
651 * =============================================================================
652 */
653
681RA8_INTERNAL static void
682internal_pack_config_words(const uint8_t* src,
683 uint32_t len,
684 uint32_t done,
685 uint16_t words[k_ra8_mram_config_set_word_count])
686{
687 for (uint32_t i = 0U; i < k_ra8_mram_config_set_word_count; ++i) {
688 const uint32_t base = done + (i * 2U);
689 const uint8_t lo = (base < len) ? src[base] : k_flash_blank_byte;
690 const uint8_t hi = (base + 1U < len) ? src[base + 1U] : k_flash_blank_byte;
691 words[i] = (uint16_t)((uint16_t)lo | ((uint16_t)hi << 8U));
692 }
693}
694
695ra8_err_t ra8_flash_extra_mram_write(uint32_t mram_addr, const uint8_t* src, uint32_t len)
696{
697 RA8_CHECK_NULL_PTR(src, g_flash_tag, "src must not be nullptr");
698 if (len == 0U || len > k_ra8_mram_write_size_bytes) {
700 }
701 if (mram_addr < (uint32_t)k_ra8_flash_extra_start) {
703 }
704 const uint32_t end_excl = (uint32_t)((uint64_t)mram_addr + (uint64_t)len);
705 /* OTP-misuse guard (#397): cap the general-purpose write path at
706 * k_ra8_flash_extra_locked_start. The permanent / irreversible option-setting
707 * structures (PBPS, POFSPS, REVOKE, Zeroization-HUK enable, anti-rollback)
708 * begin there; programming any of them can brick the part or destroy the
709 * wrapped HUK, so they require the deliberate, separately-named
710 * ra8_flash_config_set_write. This bound is stricter than the full window end
711 * (k_ra8_flash_extra_start + k_ra8_flash_extra_size), so the single check also
712 * rejects an overrun past the window. HUM Ch 59.7.4.5 Table 59.15 p 3592. */
713 if (end_excl > (uint32_t)k_ra8_flash_extra_locked_start) {
715 }
716 const uint32_t page_mask = k_ra8_mram_write_size_bytes - 1U;
717 if ((mram_addr & ~page_mask) != ((end_excl - 1U) & ~page_mask)) {
719 }
720
722 if (err != k_ra8_ok) {
723 return err;
724 }
725
726 /* The extra-MRAM data area is programmed with the MACI Program command (HUM
727 * Ch 59.7.4.5 "Program Command" Fig 59.13 p 3591) -- NOT the Configuration
728 * Set command, which is only valid for the OFS config area. One Program
729 * command carries ``k_ra8_mram_config_set_word_count`` halfwords (16 bytes),
730 * so a write spanning more than that issues back-to-back Program commands,
731 * each retargeting MSADDR ``k_ra8_mram_config_set_bytes`` further on, until the
732 * whole ``len`` is programmed. ``ra8_flash_config_set_write`` picks the Program
733 * opener for this extra-MRAM range and sets MSADDR per call, so no separate
734 * MSADDR write is needed here. Tail bytes pad to 0xFFFF. */
735 for (uint32_t done = 0U; done < len; done += (uint32_t)k_ra8_mram_config_set_bytes) {
736 uint16_t cfg_words[k_ra8_mram_config_set_word_count] = {};
737 internal_pack_config_words(src, len, done, cfg_words);
738 err = ra8_flash_config_set_write(mram_addr + done, cfg_words);
739 if (err != k_ra8_ok) {
740 break;
741 }
742 }
743
745 if (err == k_ra8_ok) {
746 err = exit_err;
747 }
748 return err;
749}
750
752{
753 if ((mram_addr & (k_ra8_mram_block_size_bytes - 1U)) != 0U) {
755 }
756 static const uint8_t local_ones[k_ra8_mram_block_size_bytes] = {
757 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
758 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
759 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
760 };
761 return ra8_flash_extra_mram_write(mram_addr, local_ones, k_ra8_mram_block_size_bytes);
762}
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_VALIDATE_INIT(initialized, tag, message)
Precondition: module must be initialized.
Definition ra8_check.h:334
#define RA8_CHECK_NULL_PTR(ptr, tag, message)
Reject nullptr pointer, returning k_ra8_err_null_ptr.
Definition ra8_check.h:243
Error Code Definitions for ra8-firmware.
@ k_ra8_err_out_of_range
Sensor or peripheral output out of valid range.
Definition ra8_err.h:337
@ k_ra8_err_invalid_arg
Invalid function argument.
Definition ra8_err.h:152
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
Definition ra8_err.h:304
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
Definition ra8_err.h:119
@ k_ra8_err_hw_error
Generic hardware fault detected (error flag set, fault interrupt).
Definition ra8_err.h:310
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
void priv_ra8_flash_internal_maci_cmd8(uint8_t byte)
Send a single byte through the MACI command-issuing area.
Definition ra8_flash.c:341
ra8_flash_runtime_t g_flash_rt
Single shared ra8_flash runtime-state instance.
Definition ra8_flash.c:67
void priv_ra8_flash_internal_set_prefetch(bool enable)
Set MRCPFB.MPFBEN to enable/disable the prefetch buffer.
Definition ra8_flash.c:296
ra8_err_t priv_ra8_flash_internal_wait_mrdy(uint32_t limit)
Spin until MSTATR.MRDY rises or limit elapses.
Definition ra8_flash.c:203
void priv_ra8_flash_internal_maci_cmd16(uint16_t half)
Send a halfword through the MACI command-issuing area.
Definition ra8_flash.c:369
const char * g_flash_tag
Shared log tag string for the ra8_flash module.
Definition ra8_flash.c:50
Code MRAM + Extra MRAM + Option-Setting driver – DANGEROUS, brick-capable.
static void internal_pack_config_words(const uint8_t *src, uint32_t len, uint32_t done, uint16_t words[k_ra8_mram_config_set_word_count])
Pack one config-set's worth of source bytes into 8 halfwords.
ra8_err_t ra8_flash_set_ecc_decoder_enable(bool enable)
Toggle MRCDECC.DECECEN (read-side ECC decoder).
ra8_err_t ra8_flash_arc_read(ra8_flash_arc_id_t counter, uint32_t *out_count)
Read the current value of an anti-rollback counter.
ra8_err_t ra8_flash_set_security_attribution(uint16_t new_msar)
Update MSAR (MRAM Security Attribution).
static uint32_t internal_arc_nsec_count(ra8_flash_arc_id_t id)
Sum the population count of one of the four ARC_NSEC slots.
ra8_err_t ra8_flash_get_startup_area(uint8_t *out_btflg, uint8_t *out_fspr)
Read the current start-up area selection.
flash_const_t
ARC bit-to-word shift and blank-flash fill byte.
@ k_flash_blank_byte
Erased-flash fill byte.
@ k_flash_bits_to_words_shift
Divide a bit count by 32 -> words.
ra8_err_t ra8_flash_set_ecc_encoder_enable(bool enable)
Toggle MRCEECC.ECCEN (program-side ECC encoder).
ra8_err_t ra8_flash_extra_mram_erase(uint32_t mram_addr)
Erase one 32-byte block of extra-MRAM via MACI.
ra8_err_t ra8_flash_get_ecc_error_addr(uint32_t *out_code_ted, uint32_t *out_code_dec, uint32_t *out_extra_ted, uint32_t *out_extra_dec)
Snapshot the latched ECC fault addresses.
ra8_err_t ra8_flash_set_update_transfer(uint8_t list_select)
Trigger the MRAM update transfer (MCTRCNTR).
ra8_err_t ra8_flash_zeroize_huk(void)
Trigger the W-HUK zeroize via MREZC.
ra8_flash_cfg_word_const_t
Bit patterns for the configuration-set word vector.
@ k_ra8_flash_btflg_alternate
BTFLG cleared selects alternate.
@ k_ra8_flash_cfg_word_all_ones
Word filler when no bits drive low.
@ k_ra8_flash_btflg_word_keep
Bits 12:0 kept as ones (unused).
@ k_ra8_flash_btflg_default
BTFLG bit 15 selects default boot.
ra8_err_t ra8_flash_update_clock_freq(uint16_t mrcfreq_mhz, uint8_t mrefreq_mhz)
Re-issue the keyed MRCFREQ / MREFREQ to track a clock change.
ra8_err_t ra8_flash_config_set_write(uint32_t target_addr, const uint16_t *words)
Issue an 8-halfword MACI program command to the OFS or extra-MRAM area.
static uint32_t internal_popcount32(uint32_t x)
Pop-count helper for 32-bit words used by the ARC reader.
ra8_err_t ra8_flash_get_program_error_addr(uint32_t *out_addr)
Snapshot the program-error address (MRCPEA).
static uint8_t internal_arc_to_mcntselr(ra8_flash_arc_id_t id)
Translate logical ARC id to MCNTSELR field value.
ra8_err_t ra8_flash_get_update_status(uint8_t *out_busy, uint8_t *out_done, uint8_t *out_err)
Poll the MRAM update-transfer status.
ra8_err_t ra8_flash_arc_increment(ra8_flash_arc_id_t counter)
Increment the selected anti-rollback counter.
ra8_err_t ra8_flash_set_startup_area(ra8_flash_startup_t target, bool temporary)
Switch the start-up area between default and alternate banks.
static ra8_err_t internal_arc_cmd(uint8_t mcntselr, uint8_t cmd)
Issue a single MACI counter command (read or increment).
ra8_err_t ra8_flash_msuinitr_kick(void)
Kick MSUINITR to re-load the OFS sequencer.
ra8_err_t ra8_flash_extra_mram_write(uint32_t mram_addr, const uint8_t *src, uint32_t len)
Program 1..32 contiguous bytes into the general-purpose extra-MRAM window.
static ra8_err_t internal_arc_read_locked(ra8_flash_arc_id_t id, uint32_t *out_count)
static uint32_t internal_arc_max_count(ra8_flash_arc_id_t id)
Compute the maximum count for an ARC id.
ra8_err_t ra8_flash_enter_pe_mode(void)
Enter MRAM P/E mode.
Definition ra8_flash.c:793
ra8_err_t ra8_flash_exit_pe_mode(void)
Exit MRAM P/E mode (return to read mode).
Definition ra8_flash.c:814
Test-access surface for ra8_flash internal helpers (MC/DC).
@ k_ra8_flash_mrefreq_key
RA8 flash mrefreq key.
@ k_ra8_flash_mrcfreq_key
RA8 flash mrcfreq key.
@ k_ra8_flash_freq_key_shift
KEY[7:0] @ [31:24] in MRCFREQ/MREFREQ.
@ k_ra8_flash_pe_spin_limit
P/E entry spin limit.
@ k_ra8_flash_max_mrcfreq_mhz
MRCMHZ <= 250.
@ k_ra8_flash_max_list_select
MCTRLSR.LIST max value.
@ k_ra8_flash_maci_spin_limit
MACI command spin limit.
@ k_ra8_flash_zeroize_spin
W-HUK zeroize spin.
@ k_ra8_flash_max_mrefreq_mhz
MREMHZ <= 125.
Flash / MRAM controller register layout for the Renesas RA8D2.
static volatile uint8_t * ra8_mram_reg8(uint16_t off)
Pointer to a byte-wide MRMS register at offset off.
@ k_ra8_mctrstatr_mask_done
TRMD.
@ k_ra8_mctrstatr_mask_busy
TRBUSY.
@ k_ra8_mctrstatr_mask_err
Reserved-future error.
@ k_ra8_mrceecc_mask_eccen
Encoder enable bit.
@ k_ra8_mrceecc_key_shift
Pre-shifted KEY[15:8]=0xC0.
@ k_ra8_mastat_mask_cmdlk
Command lock latched.
@ k_ra8_mctrcntr_mask_start
RA8 mctrcntr mask start.
@ k_ra8_mctrcntr_key
RA8 mctrcntr key.
@ k_ra8_flash_extra_start
First legal Program target (FSBL setting).
@ k_ra8_flash_extra_size
Covers through 0x02E179F0 (last, reserved).
@ k_ra8_flash_ofs_start
Start of OFS config_set window.
@ k_ra8_flash_extra_locked_start
First permanent-OTP structure.
@ k_ra8_flash_ofs_size
4 KiB OFS block.
@ k_ra8_flash_ofs_arc_nsec_addr
RA8 flash ofs arc nsec address.
@ k_ra8_flash_ofs_arccs_addr
RA8 flash ofs arccs address.
@ k_ra8_flash_ofs_arc_sec_addr
RA8 flash ofs arc sec address.
@ k_ra8_mctrlsr_mask_list_sel
RA8 mctrlsr mask list sel.
static volatile uint16_t * ra8_mram_reg16(uint16_t off)
Pointer to a halfword-wide MRMS register at offset off.
@ k_ra8_arc_nsec_single
RA8 arc nsec single.
@ k_ra8_arc_arccs_mask
RA8 arc arccs mask.
@ k_ra8_arc_sec_max_bits
RA8 arc sec maximum bits.
@ k_ra8_arc_nsec_multiple
RA8 arc nsec multiple.
@ k_ra8_arc_oembl_max_bits
RA8 arc oembl maximum bits.
@ k_ra8_arc_arcns_single
RA8 arc arcns single.
@ k_ra8_mrezs_mask_whukexe
W-HUK Zeroization Executing.
@ k_ra8_mcntselr_oembl
ARC_OEMBL (OEM bootloader).
@ k_ra8_mcntselr_nsec_0
ARC_NSEC index 0; +1/+2/+3 follow.
@ k_ra8_mcntselr_sec
ARC_SEC.
@ k_ra8_mcntselr_mask
CNTSEL[2:0].
@ k_ra8_msuasmon_mask_btflg
Boot-swap flag.
@ k_ra8_msuasmon_mask_fspr
Protection flag.
@ k_ra8_mstatr_mask_any_err
Composite error mask.
@ k_ra8_msuinitr_full_init
KEY=0xAA, SUINIT=1.
@ k_ra8_msuinitr_mask_suinit
SUINIT status bit.
static volatile uint32_t * ra8_mram_reg32(uint16_t off)
Pointer to a word-wide MRMS register at offset off.
@ k_ra8_mrezc_full_zero
RA8 mrezc full zero.
@ k_ra8_maci_cmd_word_count_n
N = 8 halfwords (one 16-byte unit).
@ k_ra8_maci_cmd_increment_counter
Increment an anti-rollback count.
@ k_ra8_maci_cmd_final
Trailer byte: starts command processing.
@ k_ra8_maci_cmd_program
Program opener: extra-MRAM DATA area.
@ k_ra8_maci_cmd_read_counter
Read an anti-rollback counter.
@ k_ra8_maci_cmd_config_set
Config-Set opener: OFS config area.
@ k_ra8_msuacr_swap_default
RA8 msuacr swap default.
@ k_ra8_msuacr_key
RA8 msuacr key.
@ k_ra8_msuacr_swap_alternate
RA8 msuacr swap alternate.
@ k_ra8_mram_arc_max_words
Max 32-bit words per ARC.
@ k_ra8_mram_block_size_bytes
One programmable block.
@ k_ra8_mram_config_set_word_count
8 halfwords per MACI write.
@ k_ra8_mram_write_size_bytes
Minimum programmable unit.
@ k_ra8_mram_config_set_bytes
Bytes per config-set (8 halfwords).
@ k_ra8_mram_off_mrcrtea
RA8 MRAM off mrcrtea.
@ k_ra8_mram_off_msuinitr
RA8 MRAM off msuinitr.
@ k_ra8_mram_off_mrcfreq
RA8 MRAM off mrcfreq.
@ k_ra8_mram_off_mrefreq
RA8 MRAM off mrefreq.
@ k_ra8_mram_off_mrceecc
RA8 MRAM off mrceecc.
@ k_ra8_mram_off_mcntdtr0
RA8 MRAM off mcntdtr0.
@ k_ra8_mram_off_mrertea
RA8 MRAM off mrertea.
@ k_ra8_mram_off_mctrstatr
RA8 MRAM off mctrstatr.
@ k_ra8_mram_off_msuacr
RA8 MRAM off msuacr.
@ k_ra8_mram_off_msar
RA8 MRAM off msar.
@ k_ra8_mram_off_mrcpea
RA8 MRAM off mrcpea.
@ k_ra8_mram_off_mctrlsr
RA8 MRAM off mctrlsr.
@ k_ra8_mram_off_mctrcntr
RA8 MRAM off mctrcntr.
@ k_ra8_mram_off_mcntdtr1
RA8 MRAM off mcntdtr1.
@ k_ra8_mram_off_mrcdecc
RA8 MRAM off mrcdecc.
@ k_ra8_mram_off_mrezc
RA8 MRAM off mrezc.
@ k_ra8_mram_off_mrerdea
RA8 MRAM off mrerdea.
@ k_ra8_mram_off_mrezs
RA8 MRAM off mrezs.
@ k_ra8_mram_off_mastat
RA8 MRAM off mastat.
@ k_ra8_mram_off_msaddr
RA8 MRAM off msaddr.
@ k_ra8_mram_off_mcntselr
RA8 MRAM off mcntselr.
@ k_ra8_mram_off_mstatr
RA8 MRAM off mstatr.
@ k_ra8_mram_off_msuasmon
RA8 MRAM off msuasmon.
@ k_ra8_mram_off_mrcrdea
RA8 MRAM off mrcrdea.
@ k_ra8_mrcdecc_mask_dececen
Decoder enable (ECCSELC).
@ k_ra8_mrcdecc_key_shift
Pre-shifted KEY[15:8]=0x8C.
@ k_ra8_msaddr_config_set_startup
RA8 msaddr config set startup.
ra8_flash_arc_id_t
Anti-rollback counter identifier.
@ k_ra8_flash_arc_nsec_3
Non-secure ARC #3.
@ k_ra8_flash_arc_nsec_0
Non-secure ARC #0.
@ k_ra8_flash_arc_sec
Secure ARC.
@ k_ra8_flash_arc_nsec_2
Non-secure ARC #2.
@ k_ra8_flash_arc_oembl
OEM bootloader ARC.
@ k_ra8_flash_arc_count
Sentinel.
@ k_ra8_flash_arc_nsec_1
Non-secure ARC #1.
ra8_flash_startup_t
Boot-area selection for ra8_flash_set_startup_area.
@ k_ra8_flash_startup_btflg
Validation sentinel.
@ k_ra8_flash_startup_alternate
Alternate startup area (BTFLG=0).
@ k_ra8_flash_startup_default
Default startup area (BTFLG=1).
Bounded wait-flag primitives for RA8D2 HAL drivers.
Lightweight Logging Interface for ra8-firmware.